📄 mbuf.c
字号:
/************************************************************Copyright (c) 1989 X ConsortiumPermission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included inall copies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER INAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR INCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.Except as contained in this notice, the name of the X Consortium shall not beused in advertising or otherwise to promote the sale, use or other dealingsin this Software without prior written authorization from the X Consortium.********************************************************//* $XConsortium: mbuf.c /main/25 1996/12/02 10:19:23 lehors $ *//* $XFree86: xc/programs/Xserver/Xext/mbuf.c,v 3.3 1997/01/18 06:52:58 dawes Exp $ */#define NEED_REPLIES#define NEED_EVENTS#include <stdio.h>#include "X.h"#include "Xproto.h"#include "window.h"#include "os.h"#include "windowstr.h"#include "scrnintstr.h"#include "pixmapstr.h"#include "extnsionst.h"#include "dixstruct.h"#include "resource.h"#include "opaque.h"#define _MULTIBUF_SERVER_ /* don't want Xlib structures */#include "regionstr.h"#include "gcstruct.h"#include "inputstr.h"#include "multibufst.h"#if !defined(WIN32) && !defined(MINIX) && !defined(Lynx)#include <sys/time.h>#endif/* given an OtherClientPtr obj, get the ClientPtr */#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])/* given a MultibufferPtr b, get the ClientPtr */#define bClient(b) (clients[CLIENT_ID(b->pPixmap->drawable.id)])#define ValidEventMasks (ExposureMask|MultibufferClobberNotifyMask|MultibufferUpdateNotifyMask)static unsigned char MultibufferReqCode;static int MultibufferEventBase;static int MultibufferErrorBase;int MultibufferScreenIndex = -1;int MultibufferWindowIndex = -1;static void PerformDisplayRequest (#if NeedFunctionPrototypes MultibuffersPtr * /* ppMultibuffers */, MultibufferPtr * /* pMultibuffer */, int /* nbuf */#endif );static Bool QueueDisplayRequest (#if NeedFunctionPrototypes ClientPtr /* client */, TimeStamp /* activateTime */#endif );static void BumpTimeStamp (#if NeedFunctionPrototypes TimeStamp * /* ts */, CARD32 /* inc */#endif );static void AliasMultibuffer (#if NeedFunctionPrototypes MultibuffersPtr /* pMultibuffers */, int /* i */#endif );static void RecalculateMultibufferOtherEvents (#if NeedFunctionPrototypes MultibufferPtr /* pMultibuffer */#endif );static int EventSelectForMultibuffer(#if NeedFunctionPrototypes MultibufferPtr /* pMultibuffer */, ClientPtr /* client */, Mask /* mask */#endif );/* * The Pixmap associated with a buffer can be found as a resource * with this type */RESTYPE MultibufferDrawableResType;static int MultibufferDrawableDelete (#if NeedFunctionPrototypes pointer /* value */, XID /* id */#endif );/* * The per-buffer data can be found as a resource with this type. * the resource id of the per-buffer data is the same as the resource * id of the pixmap */static RESTYPE MultibufferResType;static int MultibufferDelete (#if NeedFunctionPrototypes pointer /* value */, XID /* id */#endif );/* * The per-window data can be found as a resource with this type, * using the window resource id */static RESTYPE MultibuffersResType;static int MultibuffersDelete (#if NeedFunctionPrototypes pointer /* value */, XID /* id */#endif );/* * Clients other than the buffer creator attach event masks in * OtherClient structures; each has a resource of this type. */static RESTYPE OtherClientResType;static int OtherClientDelete (#if NeedFunctionPrototypes pointer /* value */, XID /* id */#endif );/**************** * MultibufferExtensionInit * * Called from InitExtensions in main() * ****************/extern DISPATCH_PROC(ProcGetBufferAttributes);static DISPATCH_PROC(ProcClearImageBufferArea);static DISPATCH_PROC(ProcCreateImageBuffers);static DISPATCH_PROC(ProcDestroyImageBuffers);static DISPATCH_PROC(ProcDisplayImageBuffers);static DISPATCH_PROC(ProcGetBufferInfo);static DISPATCH_PROC(ProcGetBufferVersion);static DISPATCH_PROC(ProcGetMBufferAttributes);static DISPATCH_PROC(ProcMultibufferDispatch);static DISPATCH_PROC(ProcSetBufferAttributes);static DISPATCH_PROC(ProcSetMBufferAttributes);static DISPATCH_PROC(SProcClearImageBufferArea);static DISPATCH_PROC(SProcCreateImageBuffers);static DISPATCH_PROC(SProcDestroyImageBuffers);static DISPATCH_PROC(SProcDisplayImageBuffers);static DISPATCH_PROC(SProcGetBufferAttributes);static DISPATCH_PROC(SProcGetBufferInfo);static DISPATCH_PROC(SProcGetBufferVersion);static DISPATCH_PROC(SProcGetMBufferAttributes);static DISPATCH_PROC(SProcMultibufferDispatch);static DISPATCH_PROC(SProcSetBufferAttributes);static DISPATCH_PROC(SProcSetMBufferAttributes);static void MultibufferResetProc(#if NeedFunctionPrototypes ExtensionEntry * /* extEntry */#endif );static void SClobberNotifyEvent(#if NeedFunctionPrototypes xMbufClobberNotifyEvent * /* from */, xMbufClobberNotifyEvent * /* to */# endif );static void SUpdateNotifyEvent(#if NeedFunctionPrototypes xMbufUpdateNotifyEvent * /* from */, xMbufUpdateNotifyEvent * /* to */#endif );static Bool MultibufferPositionWindow(#if NeedFunctionPrototypes WindowPtr /* pWin */, int /* x */, int /* y */#endif );static void SetupBackgroundPainter (#if NeedFunctionPrototypes WindowPtr /* pWin */, GCPtr /* pGC */#endif );static int DeliverEventsToMultibuffer (#if NeedFunctionPrototypes MultibufferPtr /* pMultibuffer */, xEvent * /* pEvents */, int /* count */, Mask /* filter */#endif );voidMultibufferExtensionInit(){ ExtensionEntry *extEntry; int i, j; ScreenPtr pScreen; MultibufferScreenPtr pMultibufferScreen; /* * allocate private pointers in windows and screens. Allocating * window privates may seem like an unnecessary expense, but every * PositionWindow call must check to see if the window is * multi-buffered; a resource lookup is too expensive. */ MultibufferScreenIndex = AllocateScreenPrivateIndex (); if (MultibufferScreenIndex < 0) return; MultibufferWindowIndex = AllocateWindowPrivateIndex (); for (i = 0; i < screenInfo.numScreens; i++) { pScreen = screenInfo.screens[i]; if (!AllocateWindowPrivate (pScreen, MultibufferWindowIndex, 0) || !(pMultibufferScreen = (MultibufferScreenPtr) xalloc (sizeof (MultibufferScreenRec)))) { for (j = 0; j < i; j++) xfree (screenInfo.screens[j]->devPrivates[MultibufferScreenIndex].ptr); return; } pScreen->devPrivates[MultibufferScreenIndex].ptr = (pointer) pMultibufferScreen; /* * wrap PositionWindow to resize the pixmap when the window * changes size */ pMultibufferScreen->PositionWindow = pScreen->PositionWindow; pScreen->PositionWindow = MultibufferPositionWindow; } /* * create the resource types */ MultibufferDrawableResType = CreateNewResourceType(MultibufferDrawableDelete)|RC_CACHED|RC_DRAWABLE; MultibufferResType = CreateNewResourceType(MultibufferDelete); MultibuffersResType = CreateNewResourceType(MultibuffersDelete); OtherClientResType = CreateNewResourceType(OtherClientDelete); if (MultibufferDrawableResType && MultibufferResType && MultibuffersResType && OtherClientResType && (extEntry = AddExtension(MULTIBUFFER_PROTOCOL_NAME, MultibufferNumberEvents, MultibufferNumberErrors, ProcMultibufferDispatch, SProcMultibufferDispatch, MultibufferResetProc, StandardMinorOpcode))) { MultibufferReqCode = (unsigned char)extEntry->base; MultibufferEventBase = extEntry->eventBase; MultibufferErrorBase = extEntry->errorBase; EventSwapVector[MultibufferEventBase + MultibufferClobberNotify] = (EventSwapPtr) SClobberNotifyEvent; EventSwapVector[MultibufferEventBase + MultibufferUpdateNotify] = (EventSwapPtr) SUpdateNotifyEvent; }}/*ARGSUSED*/static voidMultibufferResetProc (extEntry)ExtensionEntry *extEntry;{ int i; ScreenPtr pScreen; MultibufferScreenPtr pMultibufferScreen; if (MultibufferScreenIndex < 0) return; for (i = 0; i < screenInfo.numScreens; i++) { pScreen = screenInfo.screens[i]; if (pScreen->devPrivates[MultibufferScreenIndex].ptr) { pMultibufferScreen = (MultibufferScreenPtr) pScreen->devPrivates[MultibufferScreenIndex].ptr; pScreen->PositionWindow = pMultibufferScreen->PositionWindow; xfree (pMultibufferScreen); } }}static intProcGetBufferVersion (client) register ClientPtr client;{ xMbufGetBufferVersionReply rep; register int n; REQUEST_SIZE_MATCH (xMbufGetBufferVersionReq); rep.type = X_Reply; rep.length = 0; rep.sequenceNumber = client->sequence; rep.majorVersion = MULTIBUFFER_MAJOR_VERSION; rep.minorVersion = MULTIBUFFER_MINOR_VERSION; if (client->swapped) { swaps(&rep.sequenceNumber, n); swapl(&rep.length, n); } WriteToClient(client, sizeof (xMbufGetBufferVersionReply), (char *)&rep); return (client->noClientException);}static voidSetupBackgroundPainter (pWin, pGC) WindowPtr pWin; GCPtr pGC;{ pointer gcvalues[4]; int ts_x_origin, ts_y_origin; PixUnion background; int backgroundState; Mask gcmask; /* * First take care of any ParentRelative stuff by altering the * tile/stipple origin to match the coordinates of the upper-left * corner of the first ancestor without a ParentRelative background. * This coordinate is, of course, negative. */ ts_x_origin = ts_y_origin = 0; while (pWin->backgroundState == ParentRelative) { ts_x_origin -= pWin->origin.x; ts_y_origin -= pWin->origin.y; pWin = pWin->parent; } backgroundState = pWin->backgroundState; background = pWin->background; switch (backgroundState) { case BackgroundPixel: gcvalues[0] = (pointer) background.pixel; gcvalues[1] = (pointer) FillSolid; gcmask = GCForeground|GCFillStyle; break; case BackgroundPixmap: gcvalues[0] = (pointer) FillTiled; gcvalues[1] = (pointer) background.pixmap; gcvalues[2] = (pointer) ts_x_origin; gcvalues[3] = (pointer) ts_y_origin; gcmask = GCFillStyle|GCTile|GCTileStipXOrigin|GCTileStipYOrigin; break; default: gcvalues[0] = (pointer) GXnoop; gcmask = GCFunction; } DoChangeGC(pGC, gcmask, (XID *)gcvalues, TRUE);}intCreateImageBuffers (pWin, nbuf, ids, action, hint) WindowPtr pWin; int nbuf; XID *ids; int action; int hint;{ MultibuffersPtr pMultibuffers; MultibufferPtr pMultibuffer; ScreenPtr pScreen; int width, height, depth; int i; GCPtr pClearGC = NULL; xRectangle clearRect; DestroyImageBuffers(pWin); pMultibuffers = (MultibuffersPtr) xalloc (sizeof (MultibuffersRec) + nbuf * sizeof (MultibufferRec)); if (!pMultibuffers) return BadAlloc; pMultibuffers->pWindow = pWin; pMultibuffers->buffers = (MultibufferPtr) (pMultibuffers + 1); pMultibuffers->refcnt = pMultibuffers->numMultibuffer = 0; if (!AddResource (pWin->drawable.id, MultibuffersResType, (pointer) pMultibuffers)) return BadAlloc; width = pWin->drawable.width; height = pWin->drawable.height; depth = pWin->drawable.depth; pScreen = pWin->drawable.pScreen; if (pWin->backgroundState != None) { pClearGC = GetScratchGC (pWin->drawable.depth, pScreen); SetupBackgroundPainter (pWin, pClearGC); clearRect.x = clearRect.y = 0; clearRect.width = width; clearRect.height = height; } for (i = 0; i < nbuf; i++) { pMultibuffer = &pMultibuffers->buffers[i]; pMultibuffer->eventMask = 0L; pMultibuffer->otherEventMask = 0L; pMultibuffer->otherClients = (OtherClientsPtr) NULL; pMultibuffer->number = i; pMultibuffer->side = MultibufferSideMono; pMultibuffer->clobber = MultibufferUnclobbered; pMultibuffer->pMultibuffers = pMultibuffers; if (!AddResource (ids[i], MultibufferResType, (pointer) pMultibuffer)) break; pMultibuffer->pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, depth); if (!pMultibuffer->pPixmap) break; if (!AddResource (ids[i], MultibufferDrawableResType, (pointer) pMultibuffer->pPixmap)) { FreeResource (ids[i], MultibufferResType); (*pScreen->DestroyPixmap) (pMultibuffer->pPixmap); break; } pMultibuffer->pPixmap->drawable.id = ids[i]; if (i > 0 && pClearGC) { ValidateGC((DrawablePtr)pMultibuffer->pPixmap, pClearGC); (*pClearGC->ops->PolyFillRect)((DrawablePtr)pMultibuffer->pPixmap, pClearGC, 1, &clearRect); } } pMultibuffers->numMultibuffer = i; pMultibuffers->refcnt = i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -