📄 mbufbf.c
字号:
xfree(pDrawable);}/*ARGSUSED*/static intbufCreateImageBuffers (pWin, nbuf, ids, action, hint) WindowPtr pWin; int nbuf; XID *ids; int action; int hint;{ ScreenPtr pScreen; mbufScreenPtr pMBScreen; mbufWindowPtr pMBWindow; mbufBufferPtr pMBBuffer; int i; pScreen = pWin->drawable.pScreen; pMBScreen = MB_SCREEN_PRIV(pScreen); pMBWindow = MB_WINDOW_PRIV(pWin); pMBWindow->devPrivate.ptr = (pointer) REGION_CREATE(pScreen, 0,0); if (!pMBWindow->devPrivate.ptr) return(0); REGION_COPY(pScreen, (RegionPtr) pMBWindow->devPrivate.ptr, &pWin->clipList); for (i = 0; i < nbuf; i++) { pMBBuffer = pMBWindow->buffers + i; pMBBuffer->pDrawable = (DrawablePtr) bufCreateBuffer(pScreen,pWin,i); if (!pMBBuffer->pDrawable) break; if (!AddResource (ids[i], MultibufferDrawableResType, (pointer) pMBBuffer->pDrawable)) { bufDestroyBuffer((BufferPtr) pMBBuffer->pDrawable); break; } pMBBuffer->pDrawable->id = ids[i]; /* * If window is already mapped, generate exposures and * clear the area of the newly buffers. */ if ((pWin->realized) && (i != pMBWindow->displayedMultibuffer)) (* pMBScreen->ClearImageBufferArea)(pMBBuffer, 0,0, 0,0, TRUE); } return i;}static voidbufDestroyImageBuffers(pWin) WindowPtr pWin;{ ScreenPtr pScreen; mbufWindowPtr pMBWindow; pScreen = pWin->drawable.pScreen; if (pMBWindow = MB_WINDOW_PRIV(pWin)) { mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen); /* * if the backbuffer is currently being displayed, move the bits * to the frontbuffer and display it instead. */ if (pWin->realized && (pMBWindow->displayedMultibuffer == BACK_BUFFER)) { (* pMBPriv->CopyBufferBits)(pMBWindow, BACK_BUFFER, FRONT_BUFFER); REGION_SUBTRACT(pScreen, &pMBPriv->backBuffer, &pMBPriv->backBuffer, &pWin->clipList); (* pMBPriv->DrawSelectPlane)(pScreen, pMBPriv->selectPlane, &pWin->clipList, FRONT_BUFFER); } /* Switch window rendering to front buffer */ pWin->devPrivates[frameWindowPrivateIndex] = pMBPriv->frameBuffer[FRONT_BUFFER]; REGION_DESTROY(pScreen, (RegionPtr) pMBWindow->devPrivate.ptr); pMBWindow->devPrivate.ptr = NULL; }}/* * Can be replaced by pScreen->ClearToBackground if pBuffer->eventMask * and wOtherEventsMasks(pBuffer) were setup. */static voidbufClearImageBufferArea(pMBBuffer, x,y, w,h, generateExposures) mbufBufferPtr pMBBuffer; short x,y; unsigned short w,h; Bool generateExposures;{ BoxRec box; RegionRec reg; RegionPtr pBSReg = NullRegion; ScreenPtr pScreen; BoxPtr extents; int x1, y1, x2, y2; BufferPtr pBuffer; pBuffer = (BufferPtr) pMBBuffer->pDrawable; /* compute everything using ints to avoid overflow */ x1 = pBuffer->drawable.x + x; y1 = pBuffer->drawable.y + y; if (w) x2 = x1 + (int) w; else x2 = x1 + (int) pBuffer->drawable.width - (int) x; if (h) y2 = y1 + h; else y2 = y1 + (int) pBuffer->drawable.height - (int) y; extents = &pBuffer->clipList.extents; /* clip the resulting rectangle to the window clipList extents. This * makes sure that the result will fit in a box, given that the * screen is < 32768 on a side. */ if (x1 < extents->x1) x1 = extents->x1; if (x2 > extents->x2) x2 = extents->x2; if (y1 < extents->y1) y1 = extents->y1; if (y2 > extents->y2) y2 = extents->y2; if (x2 <= x1 || y2 <= y1) { x2 = x1 = 0; y2 = y1 = 0; } box.x1 = x1; box.x2 = x2; box.y1 = y1; box.y2 = y2; pScreen = pBuffer->drawable.pScreen; REGION_INIT(pScreen, ®, &box, 1); if (pBuffer->backStorage) { /* * If the window has backing-store on, call through the * ClearToBackground vector to handle the special semantics * (i.e. things backing store is to be cleared out and * an Expose event is to be generated for those areas in backing * store if generateExposures is TRUE). */ pBSReg = (* pScreen->ClearBackingStore)(pBuffer, x, y, w, h, generateExposures); } REGION_INTERSECT(pScreen, ®, ®, &pBuffer->clipList); if (pBuffer->backgroundState != None) (*pScreen->PaintWindowBackground)(pBuffer, ®, PW_BACKGROUND); if (generateExposures) MultibufferExpose(pMBBuffer, ®);#ifdef _notdef /* XXBS - This is the original miClearToBackground code. * WindowExposures needs to be called (or the functionality emulated) * in order for backingStore to work, but first, pBuffer->eventMask * and wOtherEventsMasks(pBuffer) need to be setup correctly. */ if (generateExposures) (*pScreen->WindowExposures)(pBuffer, ®, pBSReg); else if (pBuffer->backgroundState != None) (*pScreen->PaintWindowBackground)(pBuffer, ®, PW_BACKGROUND);#endif REGION_UNINIT(pScreen, ®); if (pBSReg) REGION_DESTROY(pScreen, pBSReg);}static voidbufWrapScreenFuncs(pScreen) ScreenPtr pScreen;{ mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen); WRAP_SCREEN_FUNC(pScreen,pMBPriv,PostValidateTree, bufPostValidateTree); WRAP_SCREEN_FUNC(pScreen,pMBPriv,ClipNotify, bufClipNotify); WRAP_SCREEN_FUNC(pScreen,pMBPriv,WindowExposures,bufWindowExposures); WRAP_SCREEN_FUNC(pScreen,pMBPriv,ChangeWindowAttributes, bufChangeWindowAttributes); WRAP_SCREEN_FUNC(pScreen,pMBPriv,ClearToBackground,bufClearToBackground); WRAP_SCREEN_FUNC(pScreen,pMBPriv,CopyWindow,bufCopyWindow);}static voidbufResetProc(pScreen) ScreenPtr pScreen;{ mbufBufferPrivPtr pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen); /* * frameBuffer, selectPlane, and pInfo should be freed by * whoever called RegisterDoubleBufferHardware */ REGION_UNINIT(pScreen, &pMBPriv->backBuffer); REGION_UNINIT(pScreen, &pMBPriv->subtractRgn); REGION_UNINIT(pScreen, &pMBPriv->unionRgn); xfree(pMBPriv);}/*---------------------------------------------------------------------------*//* * Used if CopyBufferBitsFunc is not provided when registering. * This should work for everybody since CopyArea needs to support * copying between buffers anyway. */static voidbufCopyBufferBits(pMBWindow, srcBufferNum, dstBufferNum) mbufWindowPtr pMBWindow; int srcBufferNum, dstBufferNum;{ DrawablePtr pSrcBuffer, pDstBuffer; GCPtr pGC; pSrcBuffer = pMBWindow->buffers[srcBufferNum].pDrawable; pDstBuffer = pMBWindow->buffers[dstBufferNum].pDrawable; pGC = GetScratchGC (pDstBuffer->depth, pDstBuffer->pScreen); if (!pGC) return; ValidateGC (pDstBuffer, pGC); (* pGC->ops->CopyArea) (pSrcBuffer, pDstBuffer, pGC, 0,0, pDstBuffer->width, pDstBuffer->height, 0,0); FreeScratchGC (pGC);}/* * Used if DrawSelectPlanFunc is not provided for when registering. * However, it only works if selectPlane.ptr is a drawable. Also * assumes that painting with color 0 selects the front buffer, * while color 1 selects the back buffer. */static voidbufDrawSelectPlane(pScreen, selectPlane, prgn, bufferNum) ScreenPtr pScreen; DevUnion selectPlane; RegionPtr prgn; long bufferNum;{ DrawablePtr pDrawable; GCPtr pGC; register int i; register BoxPtr pbox; register xRectangle *prect; int numRects; XID value; if (REGION_NUM_RECTS(prgn) == 0) return; pDrawable = (DrawablePtr) selectPlane.ptr; pGC = GetScratchGC (pDrawable->depth, pScreen); if (!pGC) return; prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(prgn) * sizeof(xRectangle)); if (!prect) { FreeScratchGC(pGC); return; } value = (XID) bufferNum; DoChangeGC(pGC, GCForeground, &value, 0); ValidateGC(pDrawable, pGC); numRects = REGION_NUM_RECTS(prgn); pbox = REGION_RECTS(prgn); for (i= numRects; --i >= 0; pbox++, prect++) { prect->x = pbox->x1; prect->y = pbox->y1; prect->width = pbox->x2 - pbox->x1; prect->height = pbox->y2 - pbox->y1; } prect -= numRects; (* pGC->ops->PolyFillRect)(pDrawable, pGC, numRects, prect); DEALLOCATE_LOCAL(prect); FreeScratchGC (pGC);}static voidbufDisplayImageBuffers(pScreen, ppMBWindow, ppMBBuffer, nbuf) ScreenPtr pScreen; mbufBufferPtr *ppMBBuffer; mbufWindowPtr *ppMBWindow; int nbuf;{ WindowPtr pWin; BufferPtr pPrevBuffer, pNewBuffer; int i, number; mbufBufferPrivPtr pMBPriv; mbufBufferPtr pPrevMBBuffer; pMBPriv = MB_SCREEN_PRIV_BUFFER(pScreen); for (i = 0; i < nbuf; i++) { number = ppMBBuffer[i]->number; /* 0=frontbuffer, 1=backbuffer */ pWin = ppMBWindow[i]->pWindow; pPrevMBBuffer = MB_DISPLAYED_BUFFER(ppMBWindow[i]); pPrevBuffer = (BufferPtr) pPrevMBBuffer->pDrawable; pNewBuffer = (BufferPtr) ppMBBuffer[i]->pDrawable; if (pPrevBuffer != pNewBuffer) { RegionPtr backBuffer = &pMBPriv->backBuffer; /* * Update the select plane and the backBuffer region. */ (* pMBPriv->DrawSelectPlane)(pScreen, pMBPriv->selectPlane, &pWin->clipList, number); if (number == BACK_BUFFER) REGION_UNION(pScreen, backBuffer, backBuffer, &pWin->clipList); else REGION_SUBTRACT(pScreen, backBuffer, backBuffer, &pWin->clipList); /* Switch which framebuffer the window draws into */ pWin->devPrivates[frameWindowPrivateIndex] =
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -