📄 client.c
字号:
static int_GrPeekEvent(GR_EVENT * ep){ int ret; AllocReq(PeekEvent); TypedReadBlock(ep, sizeof(*ep),GrNumPeekEvent); CheckForClientData(ep); ret = ReadByte(); CheckErrorEvent(ep); return (ret > 0); /* -1 ReadByte counts as 0 (no event)*/}/** * Wait until an event is available for a client, and then peek at it. * * @param ep Pointer to the GR_EVENT structure to return the event in. * * @ingroup nanox_event */voidGrPeekWaitEvent(GR_EVENT *ep){ EVENT_LIST * elp; ACCESS_PER_THREAD_DATA() LOCK(&nxGlobalLock); if (evlist) { *ep = evlist->event; CheckErrorEvent(ep); UNLOCK(&nxGlobalLock); return; } /* wait for next event*/ GrGetNextEvent(ep); /* add event back on head of list*/ elp = malloc(sizeof(EVENT_LIST)); if (elp) { elp->event = *ep; elp->next = evlist; } /* peek at it*/ GrPeekEvent(ep); UNLOCK(&nxGlobalLock);}/** * Gets the next event from the event queue if there is one. Returns * immediately with an event type of GR_EVENT_TYPE_NONE if the queue * is empty. * * @param ep Pointer to the GR_EVENT structure to return the event in. * * @ingroup nanox_event */void GrCheckNextEvent(GR_EVENT *ep){ ACCESS_PER_THREAD_DATA() LOCK(&nxGlobalLock); if (evlist) { /*DPRINTF("nxclient %d: Returning queued event\n",getpid());*/ GetNextQueuedEvent(ep); CheckErrorEvent(ep); UNLOCK(&nxGlobalLock); return; } AllocReq(CheckNextEvent); TypedReadBlock(ep, sizeof(*ep),GrNumGetNextEvent); CheckForClientData(ep); CheckErrorEvent(ep); UNLOCK(&nxGlobalLock);}/* builtin callback function for GrGetTypedEvent*/static GR_BOOLGetTypedEventCallback(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;}/** * 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 */intGrGetTypedEvent(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);}/** * 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 */intGrGetTypedEventPred(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){ EVENT_LIST *elp, *prevelp; GR_EVENT event; ACCESS_PER_THREAD_DATA(); LOCK(&nxGlobalLock); /* First, suck up all events and place them into the event queue */ while(_GrPeekEvent(&event)) {getevent: _GrGetNextEventTimeout(&event, 0L); QueueEvent(&event); } /* Now, run through the event queue, looking for matches of the type * info that was passed. */ prevelp = NULL; elp = evlist; while (elp) { if (matchfn(wid, mask, update, &elp->event, arg)) { /* remove event from queue, return it*/ if (prevelp == NULL) evlist = elp->next; else prevelp->next = elp->next; *ep = elp->event; UNLOCK(&nxGlobalLock); 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; UNLOCK(&nxGlobalLock); return GR_EVENT_TYPE_NONE;} /** * Select the event types which should be returned for the specified window. * * @param wid The ID of the window to set the event mask of. * @param eventmask A bit field specifying the desired event mask. * * @ingroup nanox_event */void GrSelectEvents(GR_WINDOW_ID wid, GR_EVENT_MASK eventmask){ nxSelectEventsReq *req; LOCK(&nxGlobalLock); req = AllocReq(SelectEvents); req->windowid = wid; req->eventmask = eventmask; UNLOCK(&nxGlobalLock);}/** * Create a new window. * * @param parent The ID of the parent window. * @param x The X coordinate of the new window relative to the parent window. * @param y The Y coordinate of the new window relative to the parent window. * @param width The width of the new window. * @param height The height of the new window. * @param bordersize The width of the window border. * @param background The color of the window background. * @param bordercolor The color of the window border. * @return The ID of the newly created window. * * @ingroup nanox_window */GR_WINDOW_IDGrNewWindow(GR_WINDOW_ID parent, GR_COORD x, GR_COORD y, GR_SIZE width, GR_SIZE height, GR_SIZE bordersize, GR_COLOR background, GR_COLOR bordercolor){ nxNewWindowReq *req; GR_WINDOW_ID wid; LOCK(&nxGlobalLock); req = AllocReq(NewWindow); req->parentid = parent; req->x = x; req->y = y; req->width = width; req->height = height; req->backgroundcolor = background; req->bordercolor = bordercolor; req->bordersize = bordersize; if(TypedReadBlock(&wid, sizeof(wid),GrNumNewWindow) == -1) wid = 0; UNLOCK(&nxGlobalLock); return wid;} /** * Create a new server side pixmap. This is an offscreen drawing area which * can be copied into a window using a GrCopyArea call. * * @param width The width of the pixmap. * @param height The height of the pixmap. * @param pixels Currently unused in client/server mode. * @return The ID of the newly created pixmap. * * @todo FIXME Add support for shared memory... * * @ingroup nanox_window */GR_WINDOW_IDGrNewPixmap(GR_SIZE width, GR_SIZE height, void *pixels){ nxNewPixmapReq *req; GR_WINDOW_ID wid; LOCK(&nxGlobalLock); req = AllocReq(NewPixmap); req->width = width; req->height = height; if(TypedReadBlock(&wid, sizeof(wid), GrNumNewPixmap) == -1) wid = 0; UNLOCK(&nxGlobalLock); return wid;}/** * Create a new input-only window with the specified dimensions which is a * child of the specified parent window. * * @param parent The ID of the window to use as the parent of the new window. * @param x The X coordinate of the new window relative to the parent window. * @param y The Y coordinate of the new window relative to the parent window. * @param width The width of the new window. * @param height The height of the new window. * @return The ID of the newly created window. * * @ingroup nanox_window */GR_WINDOW_IDGrNewInputWindow(GR_WINDOW_ID parent, GR_COORD x, GR_COORD y, GR_SIZE width, GR_SIZE height){ nxNewInputWindowReq *req; GR_WINDOW_ID wid; LOCK(&nxGlobalLock); req = AllocReq(NewInputWindow); req->parentid = parent; req->x = x; req->y = y; req->width = width; req->height = height; if(TypedReadBlock(&wid, sizeof(wid), GrNumNewInputWindow) == -1) wid = 0; UNLOCK(&nxGlobalLock); return wid;}/** * Destroys a window and all of it's children. * * Recursively unmaps and frees the data structures associated with the * specified window and all of its children. * * @param wid The ID of the window to destroy. * * @ingroup nanox_window */void GrDestroyWindow(GR_WINDOW_ID wid){ nxDestroyWindowReq *req; LOCK(&nxGlobalLock); req = AllocReq(DestroyWindow); req->windowid = wid; UNLOCK(&nxGlobalLock);}/** * Fills in a GR_WINDOW_INFO structure with information regarding a window. * * @param wid The ID of the window to retrieve information about. * @param infoptr Pointer to a GR_WINDOW_INFO structure to return the information in. * * @ingroup nanox_window */void GrGetWindowInfo(GR_WINDOW_ID wid, GR_WINDOW_INFO *infoptr){ nxGetWindowInfoReq *req; LOCK(&nxGlobalLock); req = AllocReq(GetWindowInfo); req->windowid = wid; TypedReadBlock(infoptr, sizeof(GR_WINDOW_INFO), GrNumGetWindowInfo); UNLOCK(&nxGlobalLock);}/** * Creates a new graphics context structure. The structure is initialised * with a set of default parameters. * * @return The ID of the newly created graphics context or 0 on error. * * @ingroup nanox_draw */GR_GC_ID GrNewGC(void){ GR_GC_ID gc; LOCK(&nxGlobalLock); AllocReq(NewGC); if(TypedReadBlock(&gc, sizeof(gc),GrNumNewGC) == -1) gc = 0; UNLOCK(&nxGlobalLock); return gc;}/** * Creates a new graphics context structure and copies the settings * from an already existing graphics context. * * @param gc The already existing graphics context to copy the parameters from. * @return The ID of the newly created graphics context or 0 on error. * * @ingroup nanox_draw */GR_GC_ID GrCopyGC(GR_GC_ID gc){ nxCopyGCReq *req; GR_GC_ID newgc; LOCK(&nxGlobalLock); req = AllocReq(CopyGC); req->gcid = gc; if(TypedReadBlock(&newgc, sizeof(newgc),GrNumCopyGC) == -1) newgc = 0; UNLOCK(&nxGlobalLock); return newgc;}/** * Destroys a graphics context structure. * * @param gc the ID of the graphics context structure to destroy * * @ingroup nanox_draw */voidGrDestroyGC(GR_GC_ID gc){ nxDestroyGCReq *req; LOCK(&nxGlobalLock); req = AllocReq(DestroyGC); req->gcid = gc; UNLOCK(&nxGlobalLock);}/** * Creates a new region structure. * The structure is initialised with a set of default parameters. * * @return the ID of the newly created region * * @ingroup nanox_region */GR_REGION_ID GrNewRegion(void){ GR_REGION_ID region; LOCK(&nxGlobalLock); AllocReq(NewRegion); if(TypedReadBlock(®ion, sizeof(region),GrNumNewRegion) == -1) region = 0; UNLOCK(&nxGlobalLock); return region;}/** * Destroys a region structure. * * @param region The ID of the region structure to destroy. * * @ingroup nanox_region */voidGrDestroyRegion(GR_REGION_ID region){ nxDestroyRegionReq *req; LOCK(&nxGlobalLock); req = AllocReq(DestroyRegion); req->regionid = region; UNLOCK(&nxGlobalLock);}/** * Makes a union of the specified region and the specified rectangle. * Places the result back in the source region. * * @param region The ID of the region to modify. * @param rect A pointer to the rectangle to add to the region. * * @ingroup nanox_region */voidGrUnionRectWithRegion(GR_REGION_ID region, GR_RECT *rect){ nxUnionRectWithRegionReq *req; LOCK(&nxGlobalLock); req = AllocReq(UnionRectWithRegion); if(rect) memcpy(&req->rect, rect, sizeof(*rect)); req->regionid = region; UNLOCK(&nxGlobalLock);}/** * Makes a union of two regions. Places the result in the * specified destination region. * * @param dst_rgn The ID of the destination region. * @param src_rgn1 The ID of the first source region. * @param src_rgn2 The ID of the second source region. * * @ingroup nanox_region */voidGrUnionRegion(GR_REGION_ID dst_rgn, GR_REGION_ID src_rgn1, GR_REGION_ID src_rgn2){ nxUnionRegionReq *req; LOCK(&nxGlobalLock); req = AllocReq(UnionRegion); req->regionid = dst_rgn; req->srcregionid1 = src_rgn1; req->srcregionid2 = src_rgn2; UNLOCK(&nxGlobalLock);}/** * Subtracts the second source region from the first source region and places * the result in the specified destination region. * * @param dst_rgn The ID of the destination region. * @param src_rgn1 The ID of the first source region. * @param src_rgn2 The ID of the second source region. * * @ingroup nanox_region */voidGrSubtractRegion(GR_REGION_ID dst_rgn, GR_REGION_ID src_rgn1, GR_REGION_ID src_rgn2){ nxSubtractRegionReq *req; LOCK(&nxGlobalLock); req = AllocReq(SubtractRegion); req->regionid = dst_rgn; req->srcregionid1 = src_rgn1; req->srcregionid2 = src_rgn2; UNLOCK(&nxGlobalLock);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -