/* Flush request buffer if required, possibly reallocate buffer size*/ void nxFlushReq(long newsize, int reply_needed) { ACCESS_PER_THREAD_DATA(); LOCK(&nxGlobalLock); /* handle one-time initialization case*/ if(reqbuf.buffer == NULL) { nxAllocReqbuffer(newsize); UNLOCK(&nxGlobalLock); return; } /* flush buffer if required*/ if(reqbuf.bufptr > reqbuf.buffer) { char * buf = (char*)reqbuf.buffer; int todo = reqbuf.bufptr - reqbuf.buffer; #if HAVE_SHAREDMEM_SUPPORT if ( nxSharedMem != 0 ) { /* There is a shared memory segment used for the * request buffer. Make up a flush command and * send it over the socket, to tell the server to * process the shared memory segment. * The 'reply_needed' argument should be non-zero * when a confirmation is needed that all commands * are flushed, so new ones can be filled into the * request buffer. NOTE: This is *only* needed * when explicitely flushing the request buffer, or * when flushing it to make space for new commands. * DO NOT REQUEST A REPLY when flushing the request * buffer because the last command in the buffer * will send a response: This response would be * queued up first and had to be drained before the * response to the flush command itsel.... * So the GrReadBlock used to read replys to commands * must not specify a nonzero 'reply_needed'. * Not requesting a reply in this case is * safe, since the command executed will wait for * the reply *it* is waiting for, and thus make * sure the request buffer is flushed before * continuing. * * We have to make the protocol request by hand, * as it has to be sent over the socket to wake * up the Nano-X server. */ char c; nxShmCmdsFlushReq req; req.reqType = GrNumShmCmdsFlush; req.hilength = 0; req.length = sizeof(req); req.size = todo; req.reply = reply_needed; nxWriteSocket((char *)&req,sizeof(req)); if ( reply_needed ) #if !HELLOOS while ( read(nxSocket, &c, 1) != 1 ) ; #else while ( bucket_recv(nxSocket, &c, 1) != 1 ) ; #endif reqbuf.bufptr = reqbuf.buffer; if ( reqbuf.buffer + newsize > reqbuf.bufmax ) { /* Shared memory too small, critical */ EPRINTF("nxFlushReq: shm region too small\n"); exit(1); } UNLOCK(&nxGlobalLock); return; } #endif /* HAVE_SHAREDMEM_SUPPORT*/ /* Standard Socket transfer */ nxWriteSocket(buf,todo); reqbuf.bufptr = reqbuf.buffer; } /* allocate larger buffer for current request, if needed*/ if(reqbuf.bufptr + newsize >= reqbuf.bufmax) { reqbuf.buffer = GdRealloc(reqbuf.buffer, reqbuf.bufmax - reqbuf.buffer, newsize); if(!reqbuf.buffer) { EPRINTF("nxFlushReq: Can't reallocate request buffer\n"); exit(1); } reqbuf.bufptr = reqbuf.buffer; reqbuf.bufmax = reqbuf.buffer + newsize; } UNLOCK(&nxGlobalLock); }
/* * REGION_PtsToRegion * * Create an array of rectangles from a list of points. */ static int REGION_PtsToRegion(int numFullPtBlocks, int iCurPtBlock, POINTBLOCK *FirstPtBlock, MWCLIPREGION *reg) { MWRECT *rects; MWPOINT *pts; POINTBLOCK *CurPtBlock; int i; MWRECT *extents; int numRects; extents = ®->extents; numRects = ((numFullPtBlocks * NUMPTSTOBUFFER) + iCurPtBlock) >> 1; if (!(reg->rects = GdRealloc( reg->rects, sizeof(MWRECT) * reg->size, sizeof(MWRECT) * numRects ))) return(0); reg->size = numRects; CurPtBlock = FirstPtBlock; rects = reg->rects - 1; numRects = 0; extents->left = LARGE_COORDINATE, extents->right = SMALL_COORDINATE; for ( ; numFullPtBlocks >= 0; numFullPtBlocks--) { /* the loop uses 2 points per iteration */ i = NUMPTSTOBUFFER >> 1; if (!numFullPtBlocks) i = iCurPtBlock >> 1; for (pts = CurPtBlock->pts; i--; pts += 2) { if (pts->x == pts[1].x) continue; if (numRects && pts->x == rects->left && pts->y == rects->bottom && pts[1].x == rects->right && (numRects == 1 || rects[-1].top != rects->top) && (i && pts[2].y > pts[1].y)) { rects->bottom = pts[1].y + 1; continue; } numRects++; rects++; rects->left = pts->x; rects->top = pts->y; rects->right = pts[1].x; rects->bottom = pts[1].y + 1; if (rects->left < extents->left) extents->left = rects->left; if (rects->right > extents->right) extents->right = rects->right; } CurPtBlock = CurPtBlock->next; } if (numRects) { extents->top = reg->rects->top; extents->bottom = rects->bottom; } else { extents->left = 0; extents->top = 0; extents->right = 0; extents->bottom = 0; } reg->numRects = numRects; return(TRUE); }