📄 mbuf.c
字号:
bClient(pMultibuffer), pEvents, count, pMultibuffer->eventMask, filter, (GrabPtr) 0)) != 0) { if (attempt > 0) deliveries++; else nondeliveries--; } /* maybe send event to other clients */ for (other = pMultibuffer->otherClients; other; other=other->next) { if ((attempt = TryClientEvents( rClient(other), pEvents, count, other->mask, filter, (GrabPtr) 0)) != 0) { if (attempt > 0) deliveries++; else nondeliveries--; } } if (deliveries) return deliveries; return nondeliveries;}/* * Send Expose events to interested clients */voidMultibufferExpose (pMultibuffer, pRegion) MultibufferPtr pMultibuffer; RegionPtr pRegion;{ if (pRegion && !REGION_NIL(pRegion)) { xEvent *pEvent; PixmapPtr pPixmap; register xEvent *pe; register BoxPtr pBox; register int i; int numRects; pPixmap = pMultibuffer->pPixmap; REGION_TRANSLATE(pPixmap->drawable.pScreen, pRegion, -pPixmap->drawable.x, -pPixmap->drawable.y); /* XXX MultibufferExpose "knows" the region representation */ numRects = REGION_NUM_RECTS(pRegion); pBox = REGION_RECTS(pRegion); pEvent = (xEvent *) ALLOCATE_LOCAL(numRects * sizeof(xEvent)); if (pEvent) { pe = pEvent; for (i=1; i<=numRects; i++, pe++, pBox++) { pe->u.u.type = Expose; pe->u.expose.window = pPixmap->drawable.id; pe->u.expose.x = pBox->x1; pe->u.expose.y = pBox->y1; pe->u.expose.width = pBox->x2 - pBox->x1; pe->u.expose.height = pBox->y2 - pBox->y1; pe->u.expose.count = (numRects - i); } (void) DeliverEventsToMultibuffer (pMultibuffer, pEvent, numRects, ExposureMask); DEALLOCATE_LOCAL(pEvent); } }}/* send UpdateNotify event */voidMultibufferUpdate (pMultibuffer, time2) MultibufferPtr pMultibuffer; CARD32 time2;{ xMbufUpdateNotifyEvent event; event.type = MultibufferEventBase + MultibufferUpdateNotify; event.buffer = pMultibuffer->pPixmap->drawable.id; event.timeStamp = time2; (void) DeliverEventsToMultibuffer (pMultibuffer, (xEvent *)&event, 1, (Mask)MultibufferUpdateNotifyMask);}/* * The sample implementation will never generate MultibufferClobberNotify * events */voidMultibufferClobber (pMultibuffer) MultibufferPtr pMultibuffer;{ xMbufClobberNotifyEvent event; event.type = MultibufferEventBase + MultibufferClobberNotify; event.buffer = pMultibuffer->pPixmap->drawable.id; event.state = pMultibuffer->clobber; (void) DeliverEventsToMultibuffer (pMultibuffer, (xEvent *)&event, 1, (Mask)MultibufferClobberNotifyMask);}/* * make the resource id for buffer i refer to the window * drawable instead of the pixmap; */static voidAliasMultibuffer (pMultibuffers, i) MultibuffersPtr pMultibuffers; int i;{ MultibufferPtr pMultibuffer; if (i == pMultibuffers->displayedMultibuffer) return; /* * remove the old association */ if (pMultibuffers->displayedMultibuffer >= 0) { pMultibuffer = &pMultibuffers->buffers[pMultibuffers->displayedMultibuffer]; ChangeResourceValue (pMultibuffer->pPixmap->drawable.id, MultibufferDrawableResType, (pointer) pMultibuffer->pPixmap); } /* * make the new association */ pMultibuffer = &pMultibuffers->buffers[i]; ChangeResourceValue (pMultibuffer->pPixmap->drawable.id, MultibufferDrawableResType, (pointer) pMultibuffers->pWindow); pMultibuffers->displayedMultibuffer = i;}/* * free everything associated with multibuffering for this * window */voidDestroyImageBuffers (pWin) WindowPtr pWin;{ FreeResourceByType (pWin->drawable.id, MultibuffersResType, FALSE); /* Zero out the window's pointer to the buffers so they won't be reused */ pWin->devPrivates[MultibufferWindowIndex].ptr = NULL;}/* * resize the buffers when the window is resized */ static BoolMultibufferPositionWindow (pWin, x, y) WindowPtr pWin; int x, y;{ ScreenPtr pScreen; MultibufferScreenPtr pMultibufferScreen; MultibuffersPtr pMultibuffers; MultibufferPtr pMultibuffer; int width, height; int i; int dx, dy, dw, dh; int sourcex, sourcey; int destx, desty; PixmapPtr pPixmap; GCPtr pGC; int savewidth, saveheight; xRectangle clearRect; Bool clear; pScreen = pWin->drawable.pScreen; pMultibufferScreen = (MultibufferScreenPtr) pScreen->devPrivates[MultibufferScreenIndex].ptr; (*pMultibufferScreen->PositionWindow) (pWin, x, y); /* if this window is not multibuffered, we're done */ if (!(pMultibuffers = (MultibuffersPtr) pWin->devPrivates[MultibufferWindowIndex].ptr)) return TRUE; /* if new size is same as old, we're done */ if (pMultibuffers->width == pWin->drawable.width && pMultibuffers->height == pWin->drawable.height) return TRUE; width = pWin->drawable.width; height = pWin->drawable.height; dx = pWin->drawable.x - pMultibuffers->x; dy = pWin->drawable.x - pMultibuffers->y; dw = width - pMultibuffers->width; dh = height - pMultibuffers->height; GravityTranslate (0, 0, -dx, -dy, dw, dh, pWin->bitGravity, &destx, &desty); /* if the window grew, remember to paint the window background, * and maybe send expose events, for the new areas of the buffers */ clear = pMultibuffers->width < width || pMultibuffers->height < height || pWin->bitGravity == ForgetGravity; sourcex = 0; sourcey = 0; savewidth = pMultibuffers->width; saveheight = pMultibuffers->height; /* clip rectangle to source and destination */ if (destx < 0) { savewidth += destx; sourcex -= destx; destx = 0; } if (destx + savewidth > width) savewidth = width - destx; if (desty < 0) { saveheight += desty; sourcey -= desty; desty = 0; } if (desty + saveheight > height) saveheight = height - desty; pMultibuffers->width = width; pMultibuffers->height = height; pMultibuffers->x = pWin->drawable.x; pMultibuffers->y = pWin->drawable.y; pGC = GetScratchGC (pWin->drawable.depth, pScreen); if (clear) { SetupBackgroundPainter (pWin, pGC); clearRect.x = 0; clearRect.y = 0; clearRect.width = width; clearRect.height = height; } for (i = 0; i < pMultibuffers->numMultibuffer; i++) { pMultibuffer = &pMultibuffers->buffers[i]; pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, pWin->drawable.depth); if (!pPixmap) { DestroyImageBuffers (pWin); break; } ValidateGC ((DrawablePtr)pPixmap, pGC); /* * I suppose this could avoid quite a bit of work if * it computed the minimal area required. */ if (clear) (*pGC->ops->PolyFillRect) ((DrawablePtr)pPixmap, pGC, 1, &clearRect); if (pWin->bitGravity != ForgetGravity) { (*pGC->ops->CopyArea) ((DrawablePtr)pMultibuffer->pPixmap, (DrawablePtr)pPixmap, pGC, sourcex, sourcey, savewidth, saveheight, destx, desty); } pPixmap->drawable.id = pMultibuffer->pPixmap->drawable.id; (*pScreen->DestroyPixmap) (pMultibuffer->pPixmap); pMultibuffer->pPixmap = pPixmap; if (i != pMultibuffers->displayedMultibuffer) { ChangeResourceValue (pPixmap->drawable.id, MultibufferDrawableResType, (pointer) pPixmap); } } FreeScratchGC (pGC); return TRUE;}/* Resource delete func for MultibufferDrawableResType *//*ARGSUSED*/static intMultibufferDrawableDelete (value, id) pointer value; XID id;{ DrawablePtr pDrawable = (DrawablePtr)value; WindowPtr pWin; MultibuffersPtr pMultibuffers; PixmapPtr pPixmap; if (pDrawable->type == DRAWABLE_WINDOW) { pWin = (WindowPtr) pDrawable; pMultibuffers = (MultibuffersPtr) pWin->devPrivates[MultibufferWindowIndex].ptr; pPixmap = pMultibuffers->buffers[pMultibuffers->displayedMultibuffer].pPixmap; } else { pPixmap = (PixmapPtr) pDrawable; } (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap); return Success;}/* Resource delete func for MultibufferResType *//*ARGSUSED*/static intMultibufferDelete (value, id) pointer value; XID id;{ MultibufferPtr pMultibuffer = (MultibufferPtr)value; MultibuffersPtr pMultibuffers; pMultibuffers = pMultibuffer->pMultibuffers; if (--pMultibuffers->refcnt == 0) { FreeResourceByType (pMultibuffers->pWindow->drawable.id, MultibuffersResType, TRUE); xfree (pMultibuffers); } return Success;}/* Resource delete func for MultibuffersResType *//*ARGSUSED*/static intMultibuffersDelete (value, id) pointer value; XID id;{ MultibuffersPtr pMultibuffers = (MultibuffersPtr)value; int i; if (pMultibuffers->refcnt == pMultibuffers->numMultibuffer) { for (i = pMultibuffers->numMultibuffer; --i >= 0; ) FreeResource (pMultibuffers->buffers[i].pPixmap->drawable.id, 0); } return Success;}/* Resource delete func for OtherClientResType */static intOtherClientDelete (value, id) pointer value; XID id;{ MultibufferPtr pMultibuffer = (MultibufferPtr)value; register OtherClientsPtr other, prev; prev = 0; for (other = pMultibuffer->otherClients; other; other = other->next) { if (other->resource == id) { if (prev) prev->next = other->next; else pMultibuffer->otherClients = other->next; xfree (other); RecalculateMultibufferOtherEvents (pMultibuffer); break; } prev = other; } return Success;}static intEventSelectForMultibuffer (pMultibuffer, client, mask) MultibufferPtr pMultibuffer; ClientPtr client; Mask mask;{ OtherClientsPtr other; if (mask & ~ValidEventMasks) { client->errorValue = mask; return BadValue; } if (bClient (pMultibuffer) == client) { pMultibuffer->eventMask = mask; } else /* some other client besides the creator wants events */ { for (other = pMultibuffer->otherClients; other; other = other->next) { if (SameClient (other, client)) { if (mask == 0) { FreeResource (other->resource, RT_NONE); break; } other->mask = mask; break; } } if (!other) { /* new client that never selected events on this buffer before */ other = (OtherClients *) xalloc (sizeof (OtherClients)); if (!other) return BadAlloc; other->mask = mask; other->resource = FakeClientID (client->index); if (!AddResource (other->resource, OtherClientResType, (pointer) pMultibuffer)) { xfree (other); return BadAlloc; } other->next = pMultibuffer->otherClients; pMultibuffer->otherClients = other; } RecalculateMultibufferOtherEvents (pMultibuffer); } return (client->noClientException);}/* or together all the otherClients event masks */static voidRecalculateMultibufferOtherEvents (pMultibuffer) MultibufferPtr pMultibuffer;{ Mask otherEventMask; OtherClients *other; otherEventMask = 0L; for (other = pMultibuffer->otherClients; other; other = other->next) otherEventMask |= other->mask; pMultibuffer->otherEventMask = otherEventMask;}/* add milliseconds to a timestamp, handling overflow */static voidBumpTimeStamp (ts, inc)TimeStamp *ts;CARD32 inc;{ CARD32 newms; newms = ts->milliseconds + inc; if (newms < ts->milliseconds) ts->months++; ts->milliseconds = newms;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -