Date: Fri, 13 Aug 2004 14:45:24 +0800 From: "wilson loi" Subject: [nanogui] Patch for NONNETWORK NxLib Hi, Here is a patch for NxLib running on NONNETWORK. However, I don't know if it is correct or not. Can someone give me some comment ??? I found that the GrPeekEvent will block if there is no event on the list. So I change the GsSelect(-1) to GsSelect(0); It is valid or not ? @@ -169,7 +169,8 @@ #if NONETWORK /* if no events on queue, force select() event check*/ if (elp == NULL) { - GsSelect(-1L); /* poll*/ + GsSelect(0); /* poll */ elp = curclient->eventhead; } #endif @@ -4214,3 +4217,158 @@ SERVER_UNLOCK(); } + +/** + * Returns the current length of the client side queue. + * + * @return The current length of the client side queue. + * + * @ingroup nanox_event + */ +#if NONETWORK +int +GrQueueLength(void) +{ + int count = 0; + GR_EVENT_LIST * p; + SERVER_LOCK(); + + p = curclient->eventhead; + /* if no events on queue, force select() event check*/ + if (p == NULL) { + GsSelect(0); /* poll*/ + } + + for(p = curclient->eventhead; p!=curclient->eventtail; p = p->next) + ++count; + + SERVER_UNLOCK(); + return count; +} + +/* builtin callback function for GrGetTypedEvent*/ +static GR_BOOL +GetTypedEventCallback(GR_WINDOW_ID wid, GR_EVENT_MASK mask, GR_UPDATE_TYPE update, + GR_EVENT *ep, void *arg) +{ + GR_EVENT_MASK emask = GR_EVENTMASK(ep->type); + +DPRINTF("GetTypedEventCallback: wid %d mask %x update %d from %d type %d\n", wid, (unsigned)mask, update, ep->general.wid, ep->type); + + /* FIXME: not all events have wid field here... */ + if (wid && (wid != ep->general.wid)) + return 0; + + if (mask) { + if ((mask & emask) == 0) + return 0; + + if (update && ((mask & emask) == GR_EVENT_MASK_UPDATE)) + if (update != ep->update.utype) + return 0; + } + + return 1; +} + + +/** + * The specified callback function is called with the passed event type parameters + * for each event on the queue, until the callback function CheckFunction + * returns GR_TRUE. The event is then removed from the queue and returned. + * If block is GR_TRUE, the call will block until a matching event is found. + * Otherwise, only the local queue is searched, and an event type of + * GR_EVENT_TYPE_NONE is returned if the a match is not found. + * + * @param wid Window id for which to check events. 0 means no window. + * @param mask Event mask of events for which to check. 0 means no check for mask. + * @param update Update event subtype when event mask is GR_EVENT_MASK_UPDATE. + * @param ep Pointer to the GR_EVENT structure to return the event in. + * @param block Specifies whether or not to block, GR_TRUE blocks, GR_FALSE does not. + * @param matchfn Specifies the callback function called for matching. + * @param arg A programmer-specified argument passed to the callback function. + * @return GR_EVENT_TYPE if an event was returned, or GR_EVENT_TYPE_NONE + * if no events match. + * + * @ingroup nanox_event + */ +int +GrGetTypedEventPred(GR_WINDOW_ID wid, GR_EVENT_MASK mask, GR_UPDATE_TYPE update, + GR_EVENT *ep, GR_BOOL block, GR_TYPED_EVENT_CALLBACK matchfn, void *arg) +{ + GR_EVENT_LIST *elp, *prevelp; + GR_EVENT event; + GR_EVENT *queueEvt; + + ACCESS_PER_THREAD_DATA(); + + SERVER_LOCK(); + /* First, suck up all events and place them into the event queue */ + while(GrPeekEvent(&event)) { +getevent: + GrGetNextEventTimeout(&event, 0L); + queueEvt = GsAllocEvent(curclient); + if (queueEvt) + { + memcpy(queueEvt, &event, sizeof(event)); + } + //QueueEvent(&event); + } + + /* Now, run through the event queue, looking for matches of the type + * info that was passed. + */ + prevelp = NULL; + elp = curclient->eventhead; + while (elp) { + if (matchfn(wid, mask, update, &elp->event, arg)) { + /* remove event from queue, return it*/ + if (prevelp == NULL) + curclient->eventhead = elp->next; + else prevelp->next = elp->next; + *ep = elp->event; + + SERVER_UNLOCK(); + return ep->type; + } + prevelp = elp; + elp = elp->next; + } + + /* if event still not found and waiting ok, then wait*/ + if (block) + goto getevent; + + /* return no event*/ + ep->type = GR_EVENT_TYPE_NONE; + SERVER_UNLOCK(); + return GR_EVENT_TYPE_NONE; +} + +/** + * Fills in the specified event structure with a copy of the next event on the + * queue that matches the type parameters passed and removes it from the queue. + * If block is GR_TRUE, the call will block until a matching event is found. + * Otherwise, only the local queue is searched, and an event type of + * GR_EVENT_TYPE_NONE is returned if the a match is not found. + * + * @param wid Window id for which to check events. 0 means no window. + * @param mask Event mask of events for which to check. 0 means no check for mask. + * @param update Update event subtype when event mask is GR_EVENT_MASK_UPDATE. + * @param ep Pointer to the GR_EVENT structure to return the event in. + * @param block Specifies whether or not to block, GR_TRUE blocks, GR_FALSE does not. + * @return GR_EVENT_TYPE if an event was returned, or GR_EVENT_TYPE_NONE + * if no events match. + * + * @ingroup nanox_event + */ +int +GrGetTypedEvent(GR_WINDOW_ID wid, GR_EVENT_MASK mask, GR_UPDATE_TYPE update, + GR_EVENT *ep, GR_BOOL block) +{ + return GrGetTypedEventPred(wid, mask, update, ep, block, + GetTypedEventCallback, NULL); +} +#endif /* NONETWORK*/ + + --------------------------------------------------------------------- To unsubscribe, e-mail: nanogui-unsubscribe@linuxhacker.org For additional commands, e-mail: nanogui-help@linuxhacker.org