From f81bb3160c5f39d8f7ad329e99865af88f02b96a Mon Sep 17 00:00:00 2001 From: marha Date: Thu, 10 Mar 2011 09:49:29 +0000 Subject: xserver mesa git update 10 Mar 2011 --- xorg-server/Xext/panoramiX.c | 2598 ++++---- xorg-server/Xext/panoramiXsrv.h | 108 +- xorg-server/Xext/xvdix.h | 550 +- xorg-server/Xext/xvmain.c | 2368 ++++--- xorg-server/Xext/xvmc.c | 1578 ++--- xorg-server/Xi/exglobals.h | 168 +- xorg-server/Xi/extinit.c | 2 +- xorg-server/dix/Makefile.am | 149 +- xorg-server/dix/deprecated.c | 165 - xorg-server/exa/exa.h | 2 +- xorg-server/exa/exa_classic.c | 532 +- xorg-server/exa/exa_driver.c | 6 +- xorg-server/exa/exa_migration_mixed.c | 4 +- xorg-server/exa/exa_mixed.c | 4 +- xorg-server/exa/exa_priv.h | 1450 ++--- xorg-server/fb/fb.h | 4180 ++++++------ xorg-server/fb/fb24_32.c | 1270 ++-- xorg-server/fb/fbpixmap.c | 782 ++- xorg-server/glx/glapi.c | 205 +- xorg-server/glx/glapi.h | 22 - xorg-server/glx/glthread.c | 162 - xorg-server/glx/glthread.h | 69 +- xorg-server/hw/dmx/dmxpixmap.c | 501 +- xorg-server/hw/dmx/dmxpixmap.h | 128 +- xorg-server/hw/xfree86/common/xf86Config.c | 4 +- xorg-server/hw/xfree86/common/xf86VGAarbiter.c | 2254 +++---- xorg-server/hw/xfree86/common/xf86VGAarbiterPriv.h | 506 +- xorg-server/hw/xfree86/vbe/vbe.c | 2178 +++---- xorg-server/hw/xfree86/xaa/xaaInit.c | 1270 ++-- xorg-server/hw/xnest/Pixmap.c | 273 +- xorg-server/hw/xnest/XNPixmap.h | 74 +- xorg-server/hw/xwin/win.h | 2 +- xorg-server/hw/xwin/winpixmap.c | 463 +- xorg-server/include/dix.h | 31 - xorg-server/include/misc.h | 582 +- xorg-server/include/pixmapstr.h | 1 - xorg-server/include/resource.h | 539 +- xorg-server/include/scrnintstr.h | 2 +- xorg-server/render/render.c | 6788 ++++++++++---------- 39 files changed, 15644 insertions(+), 16326 deletions(-) delete mode 100644 xorg-server/dix/deprecated.c (limited to 'xorg-server') diff --git a/xorg-server/Xext/panoramiX.c b/xorg-server/Xext/panoramiX.c index 489224221..391346a6b 100644 --- a/xorg-server/Xext/panoramiX.c +++ b/xorg-server/Xext/panoramiX.c @@ -1,1299 +1,1299 @@ -/***************************************************************** -Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, -BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of Digital Equipment Corporation -shall not be used in advertising or otherwise to promote the sale, use or other -dealings in this Software without prior written authorization from Digital -Equipment Corporation. -******************************************************************/ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#ifdef HAVE_DMX_CONFIG_H -#include -#endif - -#include -#include -#include -#include -#include "misc.h" -#include "cursor.h" -#include "cursorstr.h" -#include "extnsionst.h" -#include "dixstruct.h" -#include "gc.h" -#include "gcstruct.h" -#include "scrnintstr.h" -#include "window.h" -#include "windowstr.h" -#include "pixmapstr.h" -#include "panoramiX.h" -#include -#include "panoramiXsrv.h" -#include "globals.h" -#include "servermd.h" -#include "resource.h" -#include "picturestr.h" -#ifdef XFIXES -#include "xfixesint.h" -#endif -#ifdef COMPOSITE -#include "compint.h" -#endif -#include "modinit.h" -#include "protocol-versions.h" - -#ifdef GLXPROXY -extern VisualPtr glxMatchVisual(ScreenPtr pScreen, - VisualPtr pVisual, - ScreenPtr pMatchScreen); -#endif - -/* - * PanoramiX data declarations - */ - -int PanoramiXPixWidth = 0; -int PanoramiXPixHeight = 0; -int PanoramiXNumScreens = 0; - -static RegionRec PanoramiXScreenRegion = {{0, 0, 0, 0}, NULL}; - -static int PanoramiXNumDepths; -static DepthPtr PanoramiXDepths; -static int PanoramiXNumVisuals; -static VisualPtr PanoramiXVisuals; - -unsigned long XRC_DRAWABLE; -unsigned long XRT_WINDOW; -unsigned long XRT_PIXMAP; -unsigned long XRT_GC; -unsigned long XRT_COLORMAP; - -static Bool VisualsEqual(VisualPtr, ScreenPtr, VisualPtr); -XineramaVisualsEqualProcPtr XineramaVisualsEqualPtr = &VisualsEqual; - -/* - * Function prototypes - */ - -static int panoramiXGeneration; -static int ProcPanoramiXDispatch(ClientPtr client); - -static void PanoramiXResetProc(ExtensionEntry*); - -/* - * External references for functions and data variables - */ - -#include "panoramiXh.h" - -int (* SavedProcVector[256]) (ClientPtr client) = { NULL, }; - -static DevPrivateKeyRec PanoramiXGCKeyRec; -#define PanoramiXGCKey (&PanoramiXGCKeyRec) -static DevPrivateKeyRec PanoramiXScreenKeyRec; -#define PanoramiXScreenKey (&PanoramiXScreenKeyRec) - -typedef struct { - DDXPointRec clipOrg; - DDXPointRec patOrg; - GCFuncs *wrapFuncs; -} PanoramiXGCRec, *PanoramiXGCPtr; - -typedef struct { - CreateGCProcPtr CreateGC; - CloseScreenProcPtr CloseScreen; -} PanoramiXScreenRec, *PanoramiXScreenPtr; - -static void XineramaValidateGC(GCPtr, unsigned long, DrawablePtr); -static void XineramaChangeGC(GCPtr, unsigned long); -static void XineramaCopyGC(GCPtr, unsigned long, GCPtr); -static void XineramaDestroyGC(GCPtr); -static void XineramaChangeClip(GCPtr, int, pointer, int); -static void XineramaDestroyClip(GCPtr); -static void XineramaCopyClip(GCPtr, GCPtr); - -static GCFuncs XineramaGCFuncs = { - XineramaValidateGC, XineramaChangeGC, XineramaCopyGC, XineramaDestroyGC, - XineramaChangeClip, XineramaDestroyClip, XineramaCopyClip -}; - -#define Xinerama_GC_FUNC_PROLOGUE(pGC)\ - PanoramiXGCPtr pGCPriv = (PanoramiXGCPtr) \ - dixLookupPrivate(&(pGC)->devPrivates, PanoramiXGCKey); \ - (pGC)->funcs = pGCPriv->wrapFuncs; - -#define Xinerama_GC_FUNC_EPILOGUE(pGC)\ - pGCPriv->wrapFuncs = (pGC)->funcs;\ - (pGC)->funcs = &XineramaGCFuncs; - - -static Bool -XineramaCloseScreen (int i, ScreenPtr pScreen) -{ - PanoramiXScreenPtr pScreenPriv = (PanoramiXScreenPtr) - dixLookupPrivate(&pScreen->devPrivates, PanoramiXScreenKey); - - pScreen->CloseScreen = pScreenPriv->CloseScreen; - pScreen->CreateGC = pScreenPriv->CreateGC; - - if (pScreen->myNum == 0) - RegionUninit(&PanoramiXScreenRegion); - - free((pointer) pScreenPriv); - - return (*pScreen->CloseScreen) (i, pScreen); -} - -static Bool -XineramaCreateGC(GCPtr pGC) -{ - ScreenPtr pScreen = pGC->pScreen; - PanoramiXScreenPtr pScreenPriv = (PanoramiXScreenPtr) - dixLookupPrivate(&pScreen->devPrivates, PanoramiXScreenKey); - Bool ret; - - pScreen->CreateGC = pScreenPriv->CreateGC; - if((ret = (*pScreen->CreateGC)(pGC))) { - PanoramiXGCPtr pGCPriv = (PanoramiXGCPtr) - dixLookupPrivate(&pGC->devPrivates, PanoramiXGCKey); - - pGCPriv->wrapFuncs = pGC->funcs; - pGC->funcs = &XineramaGCFuncs; - - pGCPriv->clipOrg.x = pGC->clipOrg.x; - pGCPriv->clipOrg.y = pGC->clipOrg.y; - pGCPriv->patOrg.x = pGC->patOrg.x; - pGCPriv->patOrg.y = pGC->patOrg.y; - } - pScreen->CreateGC = XineramaCreateGC; - - return ret; -} - -static void -XineramaValidateGC( - GCPtr pGC, - unsigned long changes, - DrawablePtr pDraw -){ - Xinerama_GC_FUNC_PROLOGUE (pGC); - - if((pDraw->type == DRAWABLE_WINDOW) && !(((WindowPtr)pDraw)->parent)) { - /* the root window */ - int x_off = pGC->pScreen->x; - int y_off = pGC->pScreen->y; - int new_val; - - new_val = pGCPriv->clipOrg.x - x_off; - if(pGC->clipOrg.x != new_val) { - pGC->clipOrg.x = new_val; - changes |= GCClipXOrigin; - } - new_val = pGCPriv->clipOrg.y - y_off; - if(pGC->clipOrg.y != new_val) { - pGC->clipOrg.y = new_val; - changes |= GCClipYOrigin; - } - new_val = pGCPriv->patOrg.x - x_off; - if(pGC->patOrg.x != new_val) { - pGC->patOrg.x = new_val; - changes |= GCTileStipXOrigin; - } - new_val = pGCPriv->patOrg.y - y_off; - if(pGC->patOrg.y != new_val) { - pGC->patOrg.y = new_val; - changes |= GCTileStipYOrigin; - } - } else { - if(pGC->clipOrg.x != pGCPriv->clipOrg.x) { - pGC->clipOrg.x = pGCPriv->clipOrg.x; - changes |= GCClipXOrigin; - } - if(pGC->clipOrg.y != pGCPriv->clipOrg.y) { - pGC->clipOrg.y = pGCPriv->clipOrg.y; - changes |= GCClipYOrigin; - } - if(pGC->patOrg.x != pGCPriv->patOrg.x) { - pGC->patOrg.x = pGCPriv->patOrg.x; - changes |= GCTileStipXOrigin; - } - if(pGC->patOrg.y != pGCPriv->patOrg.y) { - pGC->patOrg.y = pGCPriv->patOrg.y; - changes |= GCTileStipYOrigin; - } - } - - (*pGC->funcs->ValidateGC)(pGC, changes, pDraw); - Xinerama_GC_FUNC_EPILOGUE (pGC); -} - -static void -XineramaDestroyGC(GCPtr pGC) -{ - Xinerama_GC_FUNC_PROLOGUE (pGC); - (*pGC->funcs->DestroyGC)(pGC); - Xinerama_GC_FUNC_EPILOGUE (pGC); -} - -static void -XineramaChangeGC ( - GCPtr pGC, - unsigned long mask -){ - Xinerama_GC_FUNC_PROLOGUE (pGC); - - if(mask & GCTileStipXOrigin) - pGCPriv->patOrg.x = pGC->patOrg.x; - if(mask & GCTileStipYOrigin) - pGCPriv->patOrg.y = pGC->patOrg.y; - if(mask & GCClipXOrigin) - pGCPriv->clipOrg.x = pGC->clipOrg.x; - if(mask & GCClipYOrigin) - pGCPriv->clipOrg.y = pGC->clipOrg.y; - - (*pGC->funcs->ChangeGC) (pGC, mask); - Xinerama_GC_FUNC_EPILOGUE (pGC); -} - -static void -XineramaCopyGC ( - GCPtr pGCSrc, - unsigned long mask, - GCPtr pGCDst -){ - PanoramiXGCPtr pSrcPriv = (PanoramiXGCPtr) - dixLookupPrivate(&pGCSrc->devPrivates, PanoramiXGCKey); - Xinerama_GC_FUNC_PROLOGUE (pGCDst); - - if(mask & GCTileStipXOrigin) - pGCPriv->patOrg.x = pSrcPriv->patOrg.x; - if(mask & GCTileStipYOrigin) - pGCPriv->patOrg.y = pSrcPriv->patOrg.y; - if(mask & GCClipXOrigin) - pGCPriv->clipOrg.x = pSrcPriv->clipOrg.x; - if(mask & GCClipYOrigin) - pGCPriv->clipOrg.y = pSrcPriv->clipOrg.y; - - (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); - Xinerama_GC_FUNC_EPILOGUE (pGCDst); -} - -static void -XineramaChangeClip ( - GCPtr pGC, - int type, - pointer pvalue, - int nrects -){ - Xinerama_GC_FUNC_PROLOGUE (pGC); - (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); - Xinerama_GC_FUNC_EPILOGUE (pGC); -} - -static void -XineramaCopyClip(GCPtr pgcDst, GCPtr pgcSrc) -{ - Xinerama_GC_FUNC_PROLOGUE (pgcDst); - (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); - Xinerama_GC_FUNC_EPILOGUE (pgcDst); -} - -static void -XineramaDestroyClip(GCPtr pGC) -{ - Xinerama_GC_FUNC_PROLOGUE (pGC); - (* pGC->funcs->DestroyClip)(pGC); - Xinerama_GC_FUNC_EPILOGUE (pGC); -} - -int -XineramaDeleteResource(pointer data, XID id) -{ - free(data); - return 1; -} - -typedef struct { - int screen; - int id; -} PanoramiXSearchData; - -static Bool -XineramaFindIDByScrnum(pointer resource, XID id, pointer privdata) -{ - PanoramiXRes *res = (PanoramiXRes*)resource; - PanoramiXSearchData *data = (PanoramiXSearchData*)privdata; - - return res->info[data->screen].id == data->id; -} - -PanoramiXRes * -PanoramiXFindIDByScrnum(RESTYPE type, XID id, int screen) -{ - PanoramiXSearchData data; - pointer val; - - if(!screen) { - dixLookupResourceByType(&val, id, type, serverClient, DixReadAccess); - return val; - } - - data.screen = screen; - data.id = id; - - return LookupClientResourceComplex(clients[CLIENT_ID(id)], type, - XineramaFindIDByScrnum, &data); -} - -typedef struct _connect_callback_list { - void (*func)(void); - struct _connect_callback_list *next; -} XineramaConnectionCallbackList; - -static XineramaConnectionCallbackList *ConnectionCallbackList = NULL; - -Bool -XineramaRegisterConnectionBlockCallback(void (*func)(void)) -{ - XineramaConnectionCallbackList *newlist; - - if(!(newlist = malloc(sizeof(XineramaConnectionCallbackList)))) - return FALSE; - - newlist->next = ConnectionCallbackList; - newlist->func = func; - ConnectionCallbackList = newlist; - - return TRUE; -} - -static void XineramaInitData(ScreenPtr pScreen) -{ - int i, w, h; - - RegionNull(&PanoramiXScreenRegion); - for (i = 0; i < PanoramiXNumScreens; i++) { - BoxRec TheBox; - RegionRec ScreenRegion; - - pScreen = screenInfo.screens[i]; - - TheBox.x1 = pScreen->x; - TheBox.x2 = TheBox.x1 + pScreen->width; - TheBox.y1 = pScreen->y; - TheBox.y2 = TheBox.y1 + pScreen->height; - - RegionInit(&ScreenRegion, &TheBox, 1); - RegionUnion(&PanoramiXScreenRegion, &PanoramiXScreenRegion, - &ScreenRegion); - RegionUninit(&ScreenRegion); - } - - PanoramiXPixWidth = screenInfo.screens[0]->x + screenInfo.screens[0]->width; - PanoramiXPixHeight = screenInfo.screens[0]->y + screenInfo.screens[0]->height; - - for (i = 1; i < PanoramiXNumScreens; i++) { - pScreen = screenInfo.screens[i]; - w = pScreen->x + pScreen->width; - h = pScreen->y + pScreen->height; - - if (PanoramiXPixWidth < w) - PanoramiXPixWidth = w; - if (PanoramiXPixHeight < h) - PanoramiXPixHeight = h; - } -} - -void XineramaReinitData(ScreenPtr pScreen) -{ - RegionUninit(&PanoramiXScreenRegion); - XineramaInitData(pScreen); -} - -/* - * PanoramiXExtensionInit(): - * Called from InitExtensions in main(). - * Register PanoramiXeen Extension - * Initialize global variables. - */ - -void PanoramiXExtensionInit(int argc, char *argv[]) -{ - int i; - Bool success = FALSE; - ExtensionEntry *extEntry; - ScreenPtr pScreen = screenInfo.screens[0]; - PanoramiXScreenPtr pScreenPriv; - - if (noPanoramiXExtension) - return; - - if (!dixRegisterPrivateKey(&PanoramiXScreenKeyRec, PRIVATE_SCREEN, 0)) { - noPanoramiXExtension = TRUE; - return; - } - - if (!dixRegisterPrivateKey(&PanoramiXGCKeyRec, PRIVATE_GC, sizeof(PanoramiXGCRec))) { - noPanoramiXExtension = TRUE; - return; - } - - PanoramiXNumScreens = screenInfo.numScreens; - if (PanoramiXNumScreens == 1) { /* Only 1 screen */ - noPanoramiXExtension = TRUE; - return; - } - - while (panoramiXGeneration != serverGeneration) { - extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0, - ProcPanoramiXDispatch, - SProcPanoramiXDispatch, PanoramiXResetProc, - StandardMinorOpcode); - if (!extEntry) - break; - - /* - * First make sure all the basic allocations succeed. If not, - * run in non-PanoramiXeen mode. - */ - - for (i = 0; i < PanoramiXNumScreens; i++) { - pScreen = screenInfo.screens[i]; - pScreenPriv = malloc(sizeof(PanoramiXScreenRec)); - dixSetPrivate(&pScreen->devPrivates, PanoramiXScreenKey, - pScreenPriv); - if(!pScreenPriv) { - noPanoramiXExtension = TRUE; - return; - } - - pScreenPriv->CreateGC = pScreen->CreateGC; - pScreenPriv->CloseScreen = pScreen->CloseScreen; - - pScreen->CreateGC = XineramaCreateGC; - pScreen->CloseScreen = XineramaCloseScreen; - } - - XRC_DRAWABLE = CreateNewResourceClass(); - XRT_WINDOW = CreateNewResourceType(XineramaDeleteResource, - "XineramaWindow"); - if (XRT_WINDOW) - XRT_WINDOW |= XRC_DRAWABLE; - XRT_PIXMAP = CreateNewResourceType(XineramaDeleteResource, - "XineramaPixmap"); - if (XRT_PIXMAP) - XRT_PIXMAP |= XRC_DRAWABLE; - XRT_GC = CreateNewResourceType(XineramaDeleteResource, - "XineramaGC"); - XRT_COLORMAP = CreateNewResourceType(XineramaDeleteResource, - "XineramaColormap"); - - if (XRT_WINDOW && XRT_PIXMAP && XRT_GC && XRT_COLORMAP) { - panoramiXGeneration = serverGeneration; - success = TRUE; - } - SetResourceTypeErrorValue(XRT_WINDOW, BadWindow); - SetResourceTypeErrorValue(XRT_PIXMAP, BadPixmap); - SetResourceTypeErrorValue(XRT_GC, BadGC); - SetResourceTypeErrorValue(XRT_COLORMAP, BadColor); - } - - if (!success) { - noPanoramiXExtension = TRUE; - ErrorF(PANORAMIX_PROTOCOL_NAME " extension failed to initialize\n"); - return; - } - - XineramaInitData(pScreen); - - /* - * Put our processes into the ProcVector - */ - - for (i = 256; i--; ) - SavedProcVector[i] = ProcVector[i]; - - ProcVector[X_CreateWindow] = PanoramiXCreateWindow; - ProcVector[X_ChangeWindowAttributes] = PanoramiXChangeWindowAttributes; - ProcVector[X_DestroyWindow] = PanoramiXDestroyWindow; - ProcVector[X_DestroySubwindows] = PanoramiXDestroySubwindows; - ProcVector[X_ChangeSaveSet] = PanoramiXChangeSaveSet; - ProcVector[X_ReparentWindow] = PanoramiXReparentWindow; - ProcVector[X_MapWindow] = PanoramiXMapWindow; - ProcVector[X_MapSubwindows] = PanoramiXMapSubwindows; - ProcVector[X_UnmapWindow] = PanoramiXUnmapWindow; - ProcVector[X_UnmapSubwindows] = PanoramiXUnmapSubwindows; - ProcVector[X_ConfigureWindow] = PanoramiXConfigureWindow; - ProcVector[X_CirculateWindow] = PanoramiXCirculateWindow; - ProcVector[X_GetGeometry] = PanoramiXGetGeometry; - ProcVector[X_TranslateCoords] = PanoramiXTranslateCoords; - ProcVector[X_CreatePixmap] = PanoramiXCreatePixmap; - ProcVector[X_FreePixmap] = PanoramiXFreePixmap; - ProcVector[X_CreateGC] = PanoramiXCreateGC; - ProcVector[X_ChangeGC] = PanoramiXChangeGC; - ProcVector[X_CopyGC] = PanoramiXCopyGC; - ProcVector[X_SetDashes] = PanoramiXSetDashes; - ProcVector[X_SetClipRectangles] = PanoramiXSetClipRectangles; - ProcVector[X_FreeGC] = PanoramiXFreeGC; - ProcVector[X_ClearArea] = PanoramiXClearToBackground; - ProcVector[X_CopyArea] = PanoramiXCopyArea; - ProcVector[X_CopyPlane] = PanoramiXCopyPlane; - ProcVector[X_PolyPoint] = PanoramiXPolyPoint; - ProcVector[X_PolyLine] = PanoramiXPolyLine; - ProcVector[X_PolySegment] = PanoramiXPolySegment; - ProcVector[X_PolyRectangle] = PanoramiXPolyRectangle; - ProcVector[X_PolyArc] = PanoramiXPolyArc; - ProcVector[X_FillPoly] = PanoramiXFillPoly; - ProcVector[X_PolyFillRectangle] = PanoramiXPolyFillRectangle; - ProcVector[X_PolyFillArc] = PanoramiXPolyFillArc; - ProcVector[X_PutImage] = PanoramiXPutImage; - ProcVector[X_GetImage] = PanoramiXGetImage; - ProcVector[X_PolyText8] = PanoramiXPolyText8; - ProcVector[X_PolyText16] = PanoramiXPolyText16; - ProcVector[X_ImageText8] = PanoramiXImageText8; - ProcVector[X_ImageText16] = PanoramiXImageText16; - ProcVector[X_CreateColormap] = PanoramiXCreateColormap; - ProcVector[X_FreeColormap] = PanoramiXFreeColormap; - ProcVector[X_CopyColormapAndFree] = PanoramiXCopyColormapAndFree; - ProcVector[X_InstallColormap] = PanoramiXInstallColormap; - ProcVector[X_UninstallColormap] = PanoramiXUninstallColormap; - ProcVector[X_AllocColor] = PanoramiXAllocColor; - ProcVector[X_AllocNamedColor] = PanoramiXAllocNamedColor; - ProcVector[X_AllocColorCells] = PanoramiXAllocColorCells; - ProcVector[X_AllocColorPlanes] = PanoramiXAllocColorPlanes; - ProcVector[X_FreeColors] = PanoramiXFreeColors; - ProcVector[X_StoreColors] = PanoramiXStoreColors; - ProcVector[X_StoreNamedColor] = PanoramiXStoreNamedColor; - - PanoramiXRenderInit (); -#ifdef XFIXES - PanoramiXFixesInit (); -#endif -#ifdef COMPOSITE - PanoramiXCompositeInit (); -#endif - -} - -extern Bool CreateConnectionBlock(void); - -Bool PanoramiXCreateConnectionBlock(void) -{ - int i, j, length; - Bool disableBackingStore = FALSE; - int old_width, old_height; - float width_mult, height_mult; - xWindowRoot *root; - xVisualType *visual; - xDepth *depth; - VisualPtr pVisual; - ScreenPtr pScreen; - - /* - * Do normal CreateConnectionBlock but faking it for only one screen - */ - - if(!PanoramiXNumDepths) { - ErrorF("Xinerama error: No common visuals\n"); - return FALSE; - } - - for(i = 1; i < screenInfo.numScreens; i++) { - pScreen = screenInfo.screens[i]; - if(pScreen->rootDepth != screenInfo.screens[0]->rootDepth) { - ErrorF("Xinerama error: Root window depths differ\n"); - return FALSE; - } - if(pScreen->backingStoreSupport != screenInfo.screens[0]->backingStoreSupport) - disableBackingStore = TRUE; - } - - if (disableBackingStore) { - for (i = 0; i < screenInfo.numScreens; i++) { - pScreen = screenInfo.screens[i]; - pScreen->backingStoreSupport = NotUseful; - } - } - - i = screenInfo.numScreens; - screenInfo.numScreens = 1; - if (!CreateConnectionBlock()) { - screenInfo.numScreens = i; - return FALSE; - } - - screenInfo.numScreens = i; - - root = (xWindowRoot *) (ConnectionInfo + connBlockScreenStart); - length = connBlockScreenStart + sizeof(xWindowRoot); - - /* overwrite the connection block */ - root->nDepths = PanoramiXNumDepths; - - for (i = 0; i < PanoramiXNumDepths; i++) { - depth = (xDepth *) (ConnectionInfo + length); - depth->depth = PanoramiXDepths[i].depth; - depth->nVisuals = PanoramiXDepths[i].numVids; - length += sizeof(xDepth); - visual = (xVisualType *)(ConnectionInfo + length); - - for (j = 0; j < depth->nVisuals; j++, visual++) { - visual->visualID = PanoramiXDepths[i].vids[j]; - - for (pVisual = PanoramiXVisuals; - pVisual->vid != visual->visualID; - pVisual++) - ; - - visual->class = pVisual->class; - visual->bitsPerRGB = pVisual->bitsPerRGBValue; - visual->colormapEntries = pVisual->ColormapEntries; - visual->redMask = pVisual->redMask; - visual->greenMask = pVisual->greenMask; - visual->blueMask = pVisual->blueMask; - } - - length += (depth->nVisuals * sizeof(xVisualType)); - } - - connSetupPrefix.length = bytes_to_int32(length); - - for (i = 0; i < PanoramiXNumDepths; i++) - free(PanoramiXDepths[i].vids); - free(PanoramiXDepths); - PanoramiXDepths = NULL; - - /* - * OK, change some dimensions so it looks as if it were one big screen - */ - - old_width = root->pixWidth; - old_height = root->pixHeight; - - root->pixWidth = PanoramiXPixWidth; - root->pixHeight = PanoramiXPixHeight; - width_mult = (1.0 * root->pixWidth) / old_width; - height_mult = (1.0 * root->pixHeight) / old_height; - root->mmWidth *= width_mult; - root->mmHeight *= height_mult; - - while(ConnectionCallbackList) { - pointer tmp; - - tmp = (pointer)ConnectionCallbackList; - (*ConnectionCallbackList->func)(); - ConnectionCallbackList = ConnectionCallbackList->next; - free(tmp); - } - - return TRUE; -} - -/* - * This isn't just memcmp(), bitsPerRGBValue is skipped. markv made that - * change way back before xf86 4.0, but the comment for _why_ is a bit - * opaque, so I'm not going to question it for now. - * - * This is probably better done as a screen hook so DBE/EVI/GLX can add - * their own tests, and adding privates to VisualRec so they don't have to - * do their own back-mapping. - */ -static Bool -VisualsEqual(VisualPtr a, ScreenPtr pScreenB, VisualPtr b) -{ - return ((a->class == b->class) && - (a->ColormapEntries == b->ColormapEntries) && - (a->nplanes == b->nplanes) && - (a->redMask == b->redMask) && - (a->greenMask == b->greenMask) && - (a->blueMask == b->blueMask) && - (a->offsetRed == b->offsetRed) && - (a->offsetGreen == b->offsetGreen) && - (a->offsetBlue == b->offsetBlue)); -} - -static void -PanoramiXMaybeAddDepth(DepthPtr pDepth) -{ - ScreenPtr pScreen; - int j, k; - Bool found = FALSE; - - for (j = 1; j < PanoramiXNumScreens; j++) { - pScreen = screenInfo.screens[j]; - for (k = 0; k < pScreen->numDepths; k++) { - if (pScreen->allowedDepths[k].depth == pDepth->depth) { - found = TRUE; - break; - } - } - } - - if (!found) - return; - - j = PanoramiXNumDepths; - PanoramiXNumDepths++; - PanoramiXDepths = realloc(PanoramiXDepths, - PanoramiXNumDepths * sizeof(DepthRec)); - PanoramiXDepths[j].depth = pDepth->depth; - PanoramiXDepths[j].numVids = 0; - /* XXX suboptimal, should grow these dynamically */ - if(pDepth->numVids) - PanoramiXDepths[j].vids = malloc(sizeof(VisualID) * pDepth->numVids); - else - PanoramiXDepths[j].vids = NULL; -} - -static void -PanoramiXMaybeAddVisual(VisualPtr pVisual) -{ - ScreenPtr pScreen; - int j, k; - Bool found = FALSE; - - for (j = 1; j < PanoramiXNumScreens; j++) { - pScreen = screenInfo.screens[j]; - found = FALSE; - - for (k = 0; k < pScreen->numVisuals; k++) { - VisualPtr candidate = &pScreen->visuals[k]; - - if ((*XineramaVisualsEqualPtr)(pVisual, pScreen, candidate) -#ifdef GLXPROXY - && glxMatchVisual(screenInfo.screens[0], pVisual, pScreen) -#endif - ) { - found = TRUE; - break; - } - } - - if (!found) - return; - } - - /* found a matching visual on all screens, add it to the subset list */ - j = PanoramiXNumVisuals; - PanoramiXNumVisuals++; - PanoramiXVisuals = realloc(PanoramiXVisuals, - PanoramiXNumVisuals * sizeof(VisualRec)); - - memcpy(&PanoramiXVisuals[j], pVisual, sizeof(VisualRec)); - - for (k = 0; k < PanoramiXNumDepths; k++) { - if (PanoramiXDepths[k].depth == pVisual->nplanes) { - PanoramiXDepths[k].vids[PanoramiXDepths[k].numVids] = pVisual->vid; - PanoramiXDepths[k].numVids++; - break; - } - } -} - -extern void -PanoramiXConsolidate(void) -{ - int i; - PanoramiXRes *root, *defmap, *saver; - ScreenPtr pScreen = screenInfo.screens[0]; - DepthPtr pDepth = pScreen->allowedDepths; - VisualPtr pVisual = pScreen->visuals; - - PanoramiXNumDepths = 0; - PanoramiXNumVisuals = 0; - - for (i = 0; i < pScreen->numDepths; i++) - PanoramiXMaybeAddDepth(pDepth++); - - for (i = 0; i < pScreen->numVisuals; i++) - PanoramiXMaybeAddVisual(pVisual++); - - root = malloc(sizeof(PanoramiXRes)); - root->type = XRT_WINDOW; - defmap = malloc(sizeof(PanoramiXRes)); - defmap->type = XRT_COLORMAP; - saver = malloc(sizeof(PanoramiXRes)); - saver->type = XRT_WINDOW; - - for (i = 0; i < PanoramiXNumScreens; i++) { - ScreenPtr pScreen = screenInfo.screens[i]; - root->info[i].id = pScreen->root->drawable.id; - root->u.win.class = InputOutput; - root->u.win.root = TRUE; - saver->info[i].id = pScreen->screensaver.wid; - saver->u.win.class = InputOutput; - saver->u.win.root = TRUE; - defmap->info[i].id = pScreen->defColormap; - } - - AddResource(root->info[0].id, XRT_WINDOW, root); - AddResource(saver->info[0].id, XRT_WINDOW, saver); - AddResource(defmap->info[0].id, XRT_COLORMAP, defmap); -} - -VisualID -PanoramiXTranslateVisualID(int screen, VisualID orig) -{ - ScreenPtr pOtherScreen = screenInfo.screens[screen]; - VisualPtr pVisual = NULL; - int i; - - for (i = 0; i < PanoramiXNumVisuals; i++) { - if (orig == PanoramiXVisuals[i].vid) { - pVisual = &PanoramiXVisuals[i]; - break; - } - } - - if (!pVisual) - return 0; - - /* if screen is 0, orig is already the correct visual ID */ - if (screen == 0) - return orig; - - /* found the original, now translate it relative to the backend screen */ - for (i = 0; i < pOtherScreen->numVisuals; i++) { - VisualPtr pOtherVisual = &pOtherScreen->visuals[i]; - - if ((*XineramaVisualsEqualPtr)(pVisual, pOtherScreen, pOtherVisual)) - return pOtherVisual->vid; - } - - return 0; -} - - -/* - * PanoramiXResetProc() - * Exit, deallocating as needed. - */ - -static void PanoramiXResetProc(ExtensionEntry* extEntry) -{ - int i; - - PanoramiXRenderReset (); -#ifdef XFIXES - PanoramiXFixesReset (); -#endif - screenInfo.numScreens = PanoramiXNumScreens; - for (i = 256; i--; ) - ProcVector[i] = SavedProcVector[i]; -} - - -int -ProcPanoramiXQueryVersion (ClientPtr client) -{ - /* REQUEST(xPanoramiXQueryVersionReq); */ - xPanoramiXQueryVersionReply rep; - register int n; - - REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.majorVersion = SERVER_PANORAMIX_MAJOR_VERSION; - rep.minorVersion = SERVER_PANORAMIX_MINOR_VERSION; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.majorVersion, n); - swaps(&rep.minorVersion, n); - } - WriteToClient(client, sizeof (xPanoramiXQueryVersionReply), (char *)&rep); - return Success; -} - -int -ProcPanoramiXGetState(ClientPtr client) -{ - REQUEST(xPanoramiXGetStateReq); - WindowPtr pWin; - xPanoramiXGetStateReply rep; - int n, rc; - - REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.state = !noPanoramiXExtension; - rep.window = stuff->window; - if (client->swapped) { - swaps (&rep.sequenceNumber, n); - swapl (&rep.length, n); - swapl (&rep.window, n); - } - WriteToClient (client, sizeof (xPanoramiXGetStateReply), (char *) &rep); - return Success; - -} - -int -ProcPanoramiXGetScreenCount(ClientPtr client) -{ - REQUEST(xPanoramiXGetScreenCountReq); - WindowPtr pWin; - xPanoramiXGetScreenCountReply rep; - int n, rc; - - REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.ScreenCount = PanoramiXNumScreens; - rep.window = stuff->window; - if (client->swapped) { - swaps (&rep.sequenceNumber, n); - swapl (&rep.length, n); - swapl (&rep.window, n); - } - WriteToClient (client, sizeof (xPanoramiXGetScreenCountReply), (char *) &rep); - return Success; -} - -int -ProcPanoramiXGetScreenSize(ClientPtr client) -{ - REQUEST(xPanoramiXGetScreenSizeReq); - WindowPtr pWin; - xPanoramiXGetScreenSizeReply rep; - int n, rc; - - if (stuff->screen >= PanoramiXNumScreens) - return BadMatch; - - REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - /* screen dimensions */ - rep.width = screenInfo.screens[stuff->screen]->width; - rep.height = screenInfo.screens[stuff->screen]->height; - rep.window = stuff->window; - rep.screen = stuff->screen; - if (client->swapped) { - swaps (&rep.sequenceNumber, n); - swapl (&rep.length, n); - swapl (&rep.width, n); - swapl (&rep.height, n); - swapl (&rep.window, n); - swapl (&rep.screen, n); - } - WriteToClient (client, sizeof (xPanoramiXGetScreenSizeReply), (char *) &rep); - return Success; -} - - -int -ProcXineramaIsActive(ClientPtr client) -{ - /* REQUEST(xXineramaIsActiveReq); */ - xXineramaIsActiveReply rep; - - REQUEST_SIZE_MATCH(xXineramaIsActiveReq); - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; -#if 1 - { - /* The following hack fools clients into thinking that Xinerama - * is disabled even though it is not. */ - rep.state = !noPanoramiXExtension && !PanoramiXExtensionDisabledHack; - } -#else - rep.state = !noPanoramiXExtension; -#endif - if (client->swapped) { - int n; - swaps (&rep.sequenceNumber, n); - swapl (&rep.length, n); - swapl (&rep.state, n); - } - WriteToClient (client, sizeof (xXineramaIsActiveReply), (char *) &rep); - return Success; -} - - -int -ProcXineramaQueryScreens(ClientPtr client) -{ - /* REQUEST(xXineramaQueryScreensReq); */ - xXineramaQueryScreensReply rep; - - REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.number = (noPanoramiXExtension) ? 0 : PanoramiXNumScreens; - rep.length = bytes_to_int32(rep.number * sz_XineramaScreenInfo); - if (client->swapped) { - int n; - swaps (&rep.sequenceNumber, n); - swapl (&rep.length, n); - swapl (&rep.number, n); - } - WriteToClient (client, sizeof (xXineramaQueryScreensReply), (char *) &rep); - - if(!noPanoramiXExtension) { - xXineramaScreenInfo scratch; - int i; - - for(i = 0; i < PanoramiXNumScreens; i++) { - scratch.x_org = screenInfo.screens[i]->x; - scratch.y_org = screenInfo.screens[i]->y; - scratch.width = screenInfo.screens[i]->width; - scratch.height = screenInfo.screens[i]->height; - - if(client->swapped) { - int n; - swaps (&scratch.x_org, n); - swaps (&scratch.y_org, n); - swaps (&scratch.width, n); - swaps (&scratch.height, n); - } - WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch); - } - } - - return Success; -} - - -static int -ProcPanoramiXDispatch (ClientPtr client) -{ REQUEST(xReq); - switch (stuff->data) - { - case X_PanoramiXQueryVersion: - return ProcPanoramiXQueryVersion(client); - case X_PanoramiXGetState: - return ProcPanoramiXGetState(client); - case X_PanoramiXGetScreenCount: - return ProcPanoramiXGetScreenCount(client); - case X_PanoramiXGetScreenSize: - return ProcPanoramiXGetScreenSize(client); - case X_XineramaIsActive: - return ProcXineramaIsActive(client); - case X_XineramaQueryScreens: - return ProcXineramaQueryScreens(client); - } - return BadRequest; -} - - -#if X_BYTE_ORDER == X_LITTLE_ENDIAN -#define SHIFT_L(v,s) (v) << (s) -#define SHIFT_R(v,s) (v) >> (s) -#else -#define SHIFT_L(v,s) (v) >> (s) -#define SHIFT_R(v,s) (v) << (s) -#endif - -static void -CopyBits(char *dst, int shiftL, char *src, int bytes) -{ - /* Just get it to work. Worry about speed later */ - int shiftR = 8 - shiftL; - - while(bytes--) { - *dst |= SHIFT_L(*src, shiftL); - *(dst + 1) |= SHIFT_R(*src, shiftR); - dst++; src++; - } -} - - -/* Caution. This doesn't support 2 and 4 bpp formats. We expect - 1 bpp and planar data to be already cleared when presented - to this function */ - -void -XineramaGetImageData( - DrawablePtr *pDrawables, - int left, - int top, - int width, - int height, - unsigned int format, - unsigned long planemask, - char *data, - int pitch, - Bool isRoot -){ - RegionRec SrcRegion, ScreenRegion, GrabRegion; - BoxRec SrcBox, *pbox; - int x, y, w, h, i, j, nbox, size, sizeNeeded, ScratchPitch, inOut, depth; - DrawablePtr pDraw = pDrawables[0]; - char *ScratchMem = NULL; - - size = 0; - - /* find box in logical screen space */ - SrcBox.x1 = left; - SrcBox.y1 = top; - if(!isRoot) { - SrcBox.x1 += pDraw->x + screenInfo.screens[0]->x; - SrcBox.y1 += pDraw->y + screenInfo.screens[0]->y; - } - SrcBox.x2 = SrcBox.x1 + width; - SrcBox.y2 = SrcBox.y1 + height; - - RegionInit(&SrcRegion, &SrcBox, 1); - RegionNull(&GrabRegion); - - depth = (format == XYPixmap) ? 1 : pDraw->depth; - - for(i = 0; i < PanoramiXNumScreens; i++) { - BoxRec TheBox; - ScreenPtr pScreen; - pDraw = pDrawables[i]; - pScreen = pDraw->pScreen; - - TheBox.x1 = pScreen->x; - TheBox.x2 = TheBox.x1 + pScreen->width; - TheBox.y1 = pScreen->y; - TheBox.y2 = TheBox.y1 + pScreen->height; - - RegionInit(&ScreenRegion, &TheBox, 1); - inOut = RegionContainsRect(&ScreenRegion, &SrcBox); - if(inOut == rgnPART) - RegionIntersect(&GrabRegion, &SrcRegion, &ScreenRegion); - RegionUninit(&ScreenRegion); - - if(inOut == rgnIN) { - (*pScreen->GetImage)(pDraw, - SrcBox.x1 - pDraw->x - screenInfo.screens[i]->x, - SrcBox.y1 - pDraw->y - screenInfo.screens[i]->y, - width, height, format, planemask, data); - break; - } else if (inOut == rgnOUT) - continue; - - nbox = RegionNumRects(&GrabRegion); - - if(nbox) { - pbox = RegionRects(&GrabRegion); - - while(nbox--) { - w = pbox->x2 - pbox->x1; - h = pbox->y2 - pbox->y1; - ScratchPitch = PixmapBytePad(w, depth); - sizeNeeded = ScratchPitch * h; - - if(sizeNeeded > size) { - char *tmpdata = ScratchMem; - ScratchMem = realloc(ScratchMem, sizeNeeded); - if(ScratchMem) - size = sizeNeeded; - else { - ScratchMem = tmpdata; - break; - } - } - - x = pbox->x1 - pDraw->x - screenInfo.screens[i]->x; - y = pbox->y1 - pDraw->y - screenInfo.screens[i]->y; - - (*pScreen->GetImage)(pDraw, x, y, w, h, - format, planemask, ScratchMem); - - /* copy the memory over */ - - if(depth == 1) { - int k, shift, leftover, index, index2; - - x = pbox->x1 - SrcBox.x1; - y = pbox->y1 - SrcBox.y1; - shift = x & 7; - x >>= 3; - leftover = w & 7; - w >>= 3; - - /* clean up the edge */ - if(leftover) { - int mask = (1 << leftover) - 1; - for(j = h, k = w; j--; k += ScratchPitch) - ScratchMem[k] &= mask; - } - - for(j = 0, index = (pitch * y) + x, index2 = 0; j < h; - j++, index += pitch, index2 += ScratchPitch) - { - if(w) { - if(!shift) - memcpy(data + index, ScratchMem + index2, w); - else - CopyBits(data + index, shift, - ScratchMem + index2, w); - } - - if(leftover) { - data[index + w] |= - SHIFT_L(ScratchMem[index2 + w], shift); - if((shift + leftover) > 8) - data[index + w + 1] |= - SHIFT_R(ScratchMem[index2 + w],(8 - shift)); - } - } - } else { - j = BitsPerPixel(depth) >> 3; - x = (pbox->x1 - SrcBox.x1) * j; - y = pbox->y1 - SrcBox.y1; - w *= j; - - for(j = 0; j < h; j++) { - memcpy(data + (pitch * (y + j)) + x, - ScratchMem + (ScratchPitch * j), w); - } - } - pbox++; - } - - RegionSubtract(&SrcRegion, &SrcRegion, &GrabRegion); - if(!RegionNotEmpty(&SrcRegion)) - break; - } - - } - - free(ScratchMem); - - RegionUninit(&SrcRegion); - RegionUninit(&GrabRegion); -} +/***************************************************************** +Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, +BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of Digital Equipment Corporation +shall not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from Digital +Equipment Corporation. +******************************************************************/ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#ifdef HAVE_DMX_CONFIG_H +#include +#endif + +#include +#include +#include +#include +#include "misc.h" +#include "cursor.h" +#include "cursorstr.h" +#include "extnsionst.h" +#include "dixstruct.h" +#include "gc.h" +#include "gcstruct.h" +#include "scrnintstr.h" +#include "window.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "panoramiX.h" +#include +#include "panoramiXsrv.h" +#include "globals.h" +#include "servermd.h" +#include "resource.h" +#include "picturestr.h" +#ifdef XFIXES +#include "xfixesint.h" +#endif +#ifdef COMPOSITE +#include "compint.h" +#endif +#include "modinit.h" +#include "protocol-versions.h" + +#ifdef GLXPROXY +extern VisualPtr glxMatchVisual(ScreenPtr pScreen, + VisualPtr pVisual, + ScreenPtr pMatchScreen); +#endif + +/* + * PanoramiX data declarations + */ + +int PanoramiXPixWidth = 0; +int PanoramiXPixHeight = 0; +int PanoramiXNumScreens = 0; + +static RegionRec PanoramiXScreenRegion = {{0, 0, 0, 0}, NULL}; + +static int PanoramiXNumDepths; +static DepthPtr PanoramiXDepths; +static int PanoramiXNumVisuals; +static VisualPtr PanoramiXVisuals; + +RESTYPE XRC_DRAWABLE; +RESTYPE XRT_WINDOW; +RESTYPE XRT_PIXMAP; +RESTYPE XRT_GC; +RESTYPE XRT_COLORMAP; + +static Bool VisualsEqual(VisualPtr, ScreenPtr, VisualPtr); +XineramaVisualsEqualProcPtr XineramaVisualsEqualPtr = &VisualsEqual; + +/* + * Function prototypes + */ + +static int panoramiXGeneration; +static int ProcPanoramiXDispatch(ClientPtr client); + +static void PanoramiXResetProc(ExtensionEntry*); + +/* + * External references for functions and data variables + */ + +#include "panoramiXh.h" + +int (* SavedProcVector[256]) (ClientPtr client) = { NULL, }; + +static DevPrivateKeyRec PanoramiXGCKeyRec; +#define PanoramiXGCKey (&PanoramiXGCKeyRec) +static DevPrivateKeyRec PanoramiXScreenKeyRec; +#define PanoramiXScreenKey (&PanoramiXScreenKeyRec) + +typedef struct { + DDXPointRec clipOrg; + DDXPointRec patOrg; + GCFuncs *wrapFuncs; +} PanoramiXGCRec, *PanoramiXGCPtr; + +typedef struct { + CreateGCProcPtr CreateGC; + CloseScreenProcPtr CloseScreen; +} PanoramiXScreenRec, *PanoramiXScreenPtr; + +static void XineramaValidateGC(GCPtr, unsigned long, DrawablePtr); +static void XineramaChangeGC(GCPtr, unsigned long); +static void XineramaCopyGC(GCPtr, unsigned long, GCPtr); +static void XineramaDestroyGC(GCPtr); +static void XineramaChangeClip(GCPtr, int, pointer, int); +static void XineramaDestroyClip(GCPtr); +static void XineramaCopyClip(GCPtr, GCPtr); + +static GCFuncs XineramaGCFuncs = { + XineramaValidateGC, XineramaChangeGC, XineramaCopyGC, XineramaDestroyGC, + XineramaChangeClip, XineramaDestroyClip, XineramaCopyClip +}; + +#define Xinerama_GC_FUNC_PROLOGUE(pGC)\ + PanoramiXGCPtr pGCPriv = (PanoramiXGCPtr) \ + dixLookupPrivate(&(pGC)->devPrivates, PanoramiXGCKey); \ + (pGC)->funcs = pGCPriv->wrapFuncs; + +#define Xinerama_GC_FUNC_EPILOGUE(pGC)\ + pGCPriv->wrapFuncs = (pGC)->funcs;\ + (pGC)->funcs = &XineramaGCFuncs; + + +static Bool +XineramaCloseScreen (int i, ScreenPtr pScreen) +{ + PanoramiXScreenPtr pScreenPriv = (PanoramiXScreenPtr) + dixLookupPrivate(&pScreen->devPrivates, PanoramiXScreenKey); + + pScreen->CloseScreen = pScreenPriv->CloseScreen; + pScreen->CreateGC = pScreenPriv->CreateGC; + + if (pScreen->myNum == 0) + RegionUninit(&PanoramiXScreenRegion); + + free((pointer) pScreenPriv); + + return (*pScreen->CloseScreen) (i, pScreen); +} + +static Bool +XineramaCreateGC(GCPtr pGC) +{ + ScreenPtr pScreen = pGC->pScreen; + PanoramiXScreenPtr pScreenPriv = (PanoramiXScreenPtr) + dixLookupPrivate(&pScreen->devPrivates, PanoramiXScreenKey); + Bool ret; + + pScreen->CreateGC = pScreenPriv->CreateGC; + if((ret = (*pScreen->CreateGC)(pGC))) { + PanoramiXGCPtr pGCPriv = (PanoramiXGCPtr) + dixLookupPrivate(&pGC->devPrivates, PanoramiXGCKey); + + pGCPriv->wrapFuncs = pGC->funcs; + pGC->funcs = &XineramaGCFuncs; + + pGCPriv->clipOrg.x = pGC->clipOrg.x; + pGCPriv->clipOrg.y = pGC->clipOrg.y; + pGCPriv->patOrg.x = pGC->patOrg.x; + pGCPriv->patOrg.y = pGC->patOrg.y; + } + pScreen->CreateGC = XineramaCreateGC; + + return ret; +} + +static void +XineramaValidateGC( + GCPtr pGC, + unsigned long changes, + DrawablePtr pDraw +){ + Xinerama_GC_FUNC_PROLOGUE (pGC); + + if((pDraw->type == DRAWABLE_WINDOW) && !(((WindowPtr)pDraw)->parent)) { + /* the root window */ + int x_off = pGC->pScreen->x; + int y_off = pGC->pScreen->y; + int new_val; + + new_val = pGCPriv->clipOrg.x - x_off; + if(pGC->clipOrg.x != new_val) { + pGC->clipOrg.x = new_val; + changes |= GCClipXOrigin; + } + new_val = pGCPriv->clipOrg.y - y_off; + if(pGC->clipOrg.y != new_val) { + pGC->clipOrg.y = new_val; + changes |= GCClipYOrigin; + } + new_val = pGCPriv->patOrg.x - x_off; + if(pGC->patOrg.x != new_val) { + pGC->patOrg.x = new_val; + changes |= GCTileStipXOrigin; + } + new_val = pGCPriv->patOrg.y - y_off; + if(pGC->patOrg.y != new_val) { + pGC->patOrg.y = new_val; + changes |= GCTileStipYOrigin; + } + } else { + if(pGC->clipOrg.x != pGCPriv->clipOrg.x) { + pGC->clipOrg.x = pGCPriv->clipOrg.x; + changes |= GCClipXOrigin; + } + if(pGC->clipOrg.y != pGCPriv->clipOrg.y) { + pGC->clipOrg.y = pGCPriv->clipOrg.y; + changes |= GCClipYOrigin; + } + if(pGC->patOrg.x != pGCPriv->patOrg.x) { + pGC->patOrg.x = pGCPriv->patOrg.x; + changes |= GCTileStipXOrigin; + } + if(pGC->patOrg.y != pGCPriv->patOrg.y) { + pGC->patOrg.y = pGCPriv->patOrg.y; + changes |= GCTileStipYOrigin; + } + } + + (*pGC->funcs->ValidateGC)(pGC, changes, pDraw); + Xinerama_GC_FUNC_EPILOGUE (pGC); +} + +static void +XineramaDestroyGC(GCPtr pGC) +{ + Xinerama_GC_FUNC_PROLOGUE (pGC); + (*pGC->funcs->DestroyGC)(pGC); + Xinerama_GC_FUNC_EPILOGUE (pGC); +} + +static void +XineramaChangeGC ( + GCPtr pGC, + unsigned long mask +){ + Xinerama_GC_FUNC_PROLOGUE (pGC); + + if(mask & GCTileStipXOrigin) + pGCPriv->patOrg.x = pGC->patOrg.x; + if(mask & GCTileStipYOrigin) + pGCPriv->patOrg.y = pGC->patOrg.y; + if(mask & GCClipXOrigin) + pGCPriv->clipOrg.x = pGC->clipOrg.x; + if(mask & GCClipYOrigin) + pGCPriv->clipOrg.y = pGC->clipOrg.y; + + (*pGC->funcs->ChangeGC) (pGC, mask); + Xinerama_GC_FUNC_EPILOGUE (pGC); +} + +static void +XineramaCopyGC ( + GCPtr pGCSrc, + unsigned long mask, + GCPtr pGCDst +){ + PanoramiXGCPtr pSrcPriv = (PanoramiXGCPtr) + dixLookupPrivate(&pGCSrc->devPrivates, PanoramiXGCKey); + Xinerama_GC_FUNC_PROLOGUE (pGCDst); + + if(mask & GCTileStipXOrigin) + pGCPriv->patOrg.x = pSrcPriv->patOrg.x; + if(mask & GCTileStipYOrigin) + pGCPriv->patOrg.y = pSrcPriv->patOrg.y; + if(mask & GCClipXOrigin) + pGCPriv->clipOrg.x = pSrcPriv->clipOrg.x; + if(mask & GCClipYOrigin) + pGCPriv->clipOrg.y = pSrcPriv->clipOrg.y; + + (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); + Xinerama_GC_FUNC_EPILOGUE (pGCDst); +} + +static void +XineramaChangeClip ( + GCPtr pGC, + int type, + pointer pvalue, + int nrects +){ + Xinerama_GC_FUNC_PROLOGUE (pGC); + (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); + Xinerama_GC_FUNC_EPILOGUE (pGC); +} + +static void +XineramaCopyClip(GCPtr pgcDst, GCPtr pgcSrc) +{ + Xinerama_GC_FUNC_PROLOGUE (pgcDst); + (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); + Xinerama_GC_FUNC_EPILOGUE (pgcDst); +} + +static void +XineramaDestroyClip(GCPtr pGC) +{ + Xinerama_GC_FUNC_PROLOGUE (pGC); + (* pGC->funcs->DestroyClip)(pGC); + Xinerama_GC_FUNC_EPILOGUE (pGC); +} + +int +XineramaDeleteResource(pointer data, XID id) +{ + free(data); + return 1; +} + +typedef struct { + int screen; + int id; +} PanoramiXSearchData; + +static Bool +XineramaFindIDByScrnum(pointer resource, XID id, pointer privdata) +{ + PanoramiXRes *res = (PanoramiXRes*)resource; + PanoramiXSearchData *data = (PanoramiXSearchData*)privdata; + + return res->info[data->screen].id == data->id; +} + +PanoramiXRes * +PanoramiXFindIDByScrnum(RESTYPE type, XID id, int screen) +{ + PanoramiXSearchData data; + pointer val; + + if(!screen) { + dixLookupResourceByType(&val, id, type, serverClient, DixReadAccess); + return val; + } + + data.screen = screen; + data.id = id; + + return LookupClientResourceComplex(clients[CLIENT_ID(id)], type, + XineramaFindIDByScrnum, &data); +} + +typedef struct _connect_callback_list { + void (*func)(void); + struct _connect_callback_list *next; +} XineramaConnectionCallbackList; + +static XineramaConnectionCallbackList *ConnectionCallbackList = NULL; + +Bool +XineramaRegisterConnectionBlockCallback(void (*func)(void)) +{ + XineramaConnectionCallbackList *newlist; + + if(!(newlist = malloc(sizeof(XineramaConnectionCallbackList)))) + return FALSE; + + newlist->next = ConnectionCallbackList; + newlist->func = func; + ConnectionCallbackList = newlist; + + return TRUE; +} + +static void XineramaInitData(ScreenPtr pScreen) +{ + int i, w, h; + + RegionNull(&PanoramiXScreenRegion); + for (i = 0; i < PanoramiXNumScreens; i++) { + BoxRec TheBox; + RegionRec ScreenRegion; + + pScreen = screenInfo.screens[i]; + + TheBox.x1 = pScreen->x; + TheBox.x2 = TheBox.x1 + pScreen->width; + TheBox.y1 = pScreen->y; + TheBox.y2 = TheBox.y1 + pScreen->height; + + RegionInit(&ScreenRegion, &TheBox, 1); + RegionUnion(&PanoramiXScreenRegion, &PanoramiXScreenRegion, + &ScreenRegion); + RegionUninit(&ScreenRegion); + } + + PanoramiXPixWidth = screenInfo.screens[0]->x + screenInfo.screens[0]->width; + PanoramiXPixHeight = screenInfo.screens[0]->y + screenInfo.screens[0]->height; + + for (i = 1; i < PanoramiXNumScreens; i++) { + pScreen = screenInfo.screens[i]; + w = pScreen->x + pScreen->width; + h = pScreen->y + pScreen->height; + + if (PanoramiXPixWidth < w) + PanoramiXPixWidth = w; + if (PanoramiXPixHeight < h) + PanoramiXPixHeight = h; + } +} + +void XineramaReinitData(ScreenPtr pScreen) +{ + RegionUninit(&PanoramiXScreenRegion); + XineramaInitData(pScreen); +} + +/* + * PanoramiXExtensionInit(): + * Called from InitExtensions in main(). + * Register PanoramiXeen Extension + * Initialize global variables. + */ + +void PanoramiXExtensionInit(int argc, char *argv[]) +{ + int i; + Bool success = FALSE; + ExtensionEntry *extEntry; + ScreenPtr pScreen = screenInfo.screens[0]; + PanoramiXScreenPtr pScreenPriv; + + if (noPanoramiXExtension) + return; + + if (!dixRegisterPrivateKey(&PanoramiXScreenKeyRec, PRIVATE_SCREEN, 0)) { + noPanoramiXExtension = TRUE; + return; + } + + if (!dixRegisterPrivateKey(&PanoramiXGCKeyRec, PRIVATE_GC, sizeof(PanoramiXGCRec))) { + noPanoramiXExtension = TRUE; + return; + } + + PanoramiXNumScreens = screenInfo.numScreens; + if (PanoramiXNumScreens == 1) { /* Only 1 screen */ + noPanoramiXExtension = TRUE; + return; + } + + while (panoramiXGeneration != serverGeneration) { + extEntry = AddExtension(PANORAMIX_PROTOCOL_NAME, 0,0, + ProcPanoramiXDispatch, + SProcPanoramiXDispatch, PanoramiXResetProc, + StandardMinorOpcode); + if (!extEntry) + break; + + /* + * First make sure all the basic allocations succeed. If not, + * run in non-PanoramiXeen mode. + */ + + for (i = 0; i < PanoramiXNumScreens; i++) { + pScreen = screenInfo.screens[i]; + pScreenPriv = malloc(sizeof(PanoramiXScreenRec)); + dixSetPrivate(&pScreen->devPrivates, PanoramiXScreenKey, + pScreenPriv); + if(!pScreenPriv) { + noPanoramiXExtension = TRUE; + return; + } + + pScreenPriv->CreateGC = pScreen->CreateGC; + pScreenPriv->CloseScreen = pScreen->CloseScreen; + + pScreen->CreateGC = XineramaCreateGC; + pScreen->CloseScreen = XineramaCloseScreen; + } + + XRC_DRAWABLE = CreateNewResourceClass(); + XRT_WINDOW = CreateNewResourceType(XineramaDeleteResource, + "XineramaWindow"); + if (XRT_WINDOW) + XRT_WINDOW |= XRC_DRAWABLE; + XRT_PIXMAP = CreateNewResourceType(XineramaDeleteResource, + "XineramaPixmap"); + if (XRT_PIXMAP) + XRT_PIXMAP |= XRC_DRAWABLE; + XRT_GC = CreateNewResourceType(XineramaDeleteResource, + "XineramaGC"); + XRT_COLORMAP = CreateNewResourceType(XineramaDeleteResource, + "XineramaColormap"); + + if (XRT_WINDOW && XRT_PIXMAP && XRT_GC && XRT_COLORMAP) { + panoramiXGeneration = serverGeneration; + success = TRUE; + } + SetResourceTypeErrorValue(XRT_WINDOW, BadWindow); + SetResourceTypeErrorValue(XRT_PIXMAP, BadPixmap); + SetResourceTypeErrorValue(XRT_GC, BadGC); + SetResourceTypeErrorValue(XRT_COLORMAP, BadColor); + } + + if (!success) { + noPanoramiXExtension = TRUE; + ErrorF(PANORAMIX_PROTOCOL_NAME " extension failed to initialize\n"); + return; + } + + XineramaInitData(pScreen); + + /* + * Put our processes into the ProcVector + */ + + for (i = 256; i--; ) + SavedProcVector[i] = ProcVector[i]; + + ProcVector[X_CreateWindow] = PanoramiXCreateWindow; + ProcVector[X_ChangeWindowAttributes] = PanoramiXChangeWindowAttributes; + ProcVector[X_DestroyWindow] = PanoramiXDestroyWindow; + ProcVector[X_DestroySubwindows] = PanoramiXDestroySubwindows; + ProcVector[X_ChangeSaveSet] = PanoramiXChangeSaveSet; + ProcVector[X_ReparentWindow] = PanoramiXReparentWindow; + ProcVector[X_MapWindow] = PanoramiXMapWindow; + ProcVector[X_MapSubwindows] = PanoramiXMapSubwindows; + ProcVector[X_UnmapWindow] = PanoramiXUnmapWindow; + ProcVector[X_UnmapSubwindows] = PanoramiXUnmapSubwindows; + ProcVector[X_ConfigureWindow] = PanoramiXConfigureWindow; + ProcVector[X_CirculateWindow] = PanoramiXCirculateWindow; + ProcVector[X_GetGeometry] = PanoramiXGetGeometry; + ProcVector[X_TranslateCoords] = PanoramiXTranslateCoords; + ProcVector[X_CreatePixmap] = PanoramiXCreatePixmap; + ProcVector[X_FreePixmap] = PanoramiXFreePixmap; + ProcVector[X_CreateGC] = PanoramiXCreateGC; + ProcVector[X_ChangeGC] = PanoramiXChangeGC; + ProcVector[X_CopyGC] = PanoramiXCopyGC; + ProcVector[X_SetDashes] = PanoramiXSetDashes; + ProcVector[X_SetClipRectangles] = PanoramiXSetClipRectangles; + ProcVector[X_FreeGC] = PanoramiXFreeGC; + ProcVector[X_ClearArea] = PanoramiXClearToBackground; + ProcVector[X_CopyArea] = PanoramiXCopyArea; + ProcVector[X_CopyPlane] = PanoramiXCopyPlane; + ProcVector[X_PolyPoint] = PanoramiXPolyPoint; + ProcVector[X_PolyLine] = PanoramiXPolyLine; + ProcVector[X_PolySegment] = PanoramiXPolySegment; + ProcVector[X_PolyRectangle] = PanoramiXPolyRectangle; + ProcVector[X_PolyArc] = PanoramiXPolyArc; + ProcVector[X_FillPoly] = PanoramiXFillPoly; + ProcVector[X_PolyFillRectangle] = PanoramiXPolyFillRectangle; + ProcVector[X_PolyFillArc] = PanoramiXPolyFillArc; + ProcVector[X_PutImage] = PanoramiXPutImage; + ProcVector[X_GetImage] = PanoramiXGetImage; + ProcVector[X_PolyText8] = PanoramiXPolyText8; + ProcVector[X_PolyText16] = PanoramiXPolyText16; + ProcVector[X_ImageText8] = PanoramiXImageText8; + ProcVector[X_ImageText16] = PanoramiXImageText16; + ProcVector[X_CreateColormap] = PanoramiXCreateColormap; + ProcVector[X_FreeColormap] = PanoramiXFreeColormap; + ProcVector[X_CopyColormapAndFree] = PanoramiXCopyColormapAndFree; + ProcVector[X_InstallColormap] = PanoramiXInstallColormap; + ProcVector[X_UninstallColormap] = PanoramiXUninstallColormap; + ProcVector[X_AllocColor] = PanoramiXAllocColor; + ProcVector[X_AllocNamedColor] = PanoramiXAllocNamedColor; + ProcVector[X_AllocColorCells] = PanoramiXAllocColorCells; + ProcVector[X_AllocColorPlanes] = PanoramiXAllocColorPlanes; + ProcVector[X_FreeColors] = PanoramiXFreeColors; + ProcVector[X_StoreColors] = PanoramiXStoreColors; + ProcVector[X_StoreNamedColor] = PanoramiXStoreNamedColor; + + PanoramiXRenderInit (); +#ifdef XFIXES + PanoramiXFixesInit (); +#endif +#ifdef COMPOSITE + PanoramiXCompositeInit (); +#endif + +} + +extern Bool CreateConnectionBlock(void); + +Bool PanoramiXCreateConnectionBlock(void) +{ + int i, j, length; + Bool disableBackingStore = FALSE; + int old_width, old_height; + float width_mult, height_mult; + xWindowRoot *root; + xVisualType *visual; + xDepth *depth; + VisualPtr pVisual; + ScreenPtr pScreen; + + /* + * Do normal CreateConnectionBlock but faking it for only one screen + */ + + if(!PanoramiXNumDepths) { + ErrorF("Xinerama error: No common visuals\n"); + return FALSE; + } + + for(i = 1; i < screenInfo.numScreens; i++) { + pScreen = screenInfo.screens[i]; + if(pScreen->rootDepth != screenInfo.screens[0]->rootDepth) { + ErrorF("Xinerama error: Root window depths differ\n"); + return FALSE; + } + if(pScreen->backingStoreSupport != screenInfo.screens[0]->backingStoreSupport) + disableBackingStore = TRUE; + } + + if (disableBackingStore) { + for (i = 0; i < screenInfo.numScreens; i++) { + pScreen = screenInfo.screens[i]; + pScreen->backingStoreSupport = NotUseful; + } + } + + i = screenInfo.numScreens; + screenInfo.numScreens = 1; + if (!CreateConnectionBlock()) { + screenInfo.numScreens = i; + return FALSE; + } + + screenInfo.numScreens = i; + + root = (xWindowRoot *) (ConnectionInfo + connBlockScreenStart); + length = connBlockScreenStart + sizeof(xWindowRoot); + + /* overwrite the connection block */ + root->nDepths = PanoramiXNumDepths; + + for (i = 0; i < PanoramiXNumDepths; i++) { + depth = (xDepth *) (ConnectionInfo + length); + depth->depth = PanoramiXDepths[i].depth; + depth->nVisuals = PanoramiXDepths[i].numVids; + length += sizeof(xDepth); + visual = (xVisualType *)(ConnectionInfo + length); + + for (j = 0; j < depth->nVisuals; j++, visual++) { + visual->visualID = PanoramiXDepths[i].vids[j]; + + for (pVisual = PanoramiXVisuals; + pVisual->vid != visual->visualID; + pVisual++) + ; + + visual->class = pVisual->class; + visual->bitsPerRGB = pVisual->bitsPerRGBValue; + visual->colormapEntries = pVisual->ColormapEntries; + visual->redMask = pVisual->redMask; + visual->greenMask = pVisual->greenMask; + visual->blueMask = pVisual->blueMask; + } + + length += (depth->nVisuals * sizeof(xVisualType)); + } + + connSetupPrefix.length = bytes_to_int32(length); + + for (i = 0; i < PanoramiXNumDepths; i++) + free(PanoramiXDepths[i].vids); + free(PanoramiXDepths); + PanoramiXDepths = NULL; + + /* + * OK, change some dimensions so it looks as if it were one big screen + */ + + old_width = root->pixWidth; + old_height = root->pixHeight; + + root->pixWidth = PanoramiXPixWidth; + root->pixHeight = PanoramiXPixHeight; + width_mult = (1.0 * root->pixWidth) / old_width; + height_mult = (1.0 * root->pixHeight) / old_height; + root->mmWidth *= width_mult; + root->mmHeight *= height_mult; + + while(ConnectionCallbackList) { + pointer tmp; + + tmp = (pointer)ConnectionCallbackList; + (*ConnectionCallbackList->func)(); + ConnectionCallbackList = ConnectionCallbackList->next; + free(tmp); + } + + return TRUE; +} + +/* + * This isn't just memcmp(), bitsPerRGBValue is skipped. markv made that + * change way back before xf86 4.0, but the comment for _why_ is a bit + * opaque, so I'm not going to question it for now. + * + * This is probably better done as a screen hook so DBE/EVI/GLX can add + * their own tests, and adding privates to VisualRec so they don't have to + * do their own back-mapping. + */ +static Bool +VisualsEqual(VisualPtr a, ScreenPtr pScreenB, VisualPtr b) +{ + return ((a->class == b->class) && + (a->ColormapEntries == b->ColormapEntries) && + (a->nplanes == b->nplanes) && + (a->redMask == b->redMask) && + (a->greenMask == b->greenMask) && + (a->blueMask == b->blueMask) && + (a->offsetRed == b->offsetRed) && + (a->offsetGreen == b->offsetGreen) && + (a->offsetBlue == b->offsetBlue)); +} + +static void +PanoramiXMaybeAddDepth(DepthPtr pDepth) +{ + ScreenPtr pScreen; + int j, k; + Bool found = FALSE; + + for (j = 1; j < PanoramiXNumScreens; j++) { + pScreen = screenInfo.screens[j]; + for (k = 0; k < pScreen->numDepths; k++) { + if (pScreen->allowedDepths[k].depth == pDepth->depth) { + found = TRUE; + break; + } + } + } + + if (!found) + return; + + j = PanoramiXNumDepths; + PanoramiXNumDepths++; + PanoramiXDepths = realloc(PanoramiXDepths, + PanoramiXNumDepths * sizeof(DepthRec)); + PanoramiXDepths[j].depth = pDepth->depth; + PanoramiXDepths[j].numVids = 0; + /* XXX suboptimal, should grow these dynamically */ + if(pDepth->numVids) + PanoramiXDepths[j].vids = malloc(sizeof(VisualID) * pDepth->numVids); + else + PanoramiXDepths[j].vids = NULL; +} + +static void +PanoramiXMaybeAddVisual(VisualPtr pVisual) +{ + ScreenPtr pScreen; + int j, k; + Bool found = FALSE; + + for (j = 1; j < PanoramiXNumScreens; j++) { + pScreen = screenInfo.screens[j]; + found = FALSE; + + for (k = 0; k < pScreen->numVisuals; k++) { + VisualPtr candidate = &pScreen->visuals[k]; + + if ((*XineramaVisualsEqualPtr)(pVisual, pScreen, candidate) +#ifdef GLXPROXY + && glxMatchVisual(screenInfo.screens[0], pVisual, pScreen) +#endif + ) { + found = TRUE; + break; + } + } + + if (!found) + return; + } + + /* found a matching visual on all screens, add it to the subset list */ + j = PanoramiXNumVisuals; + PanoramiXNumVisuals++; + PanoramiXVisuals = realloc(PanoramiXVisuals, + PanoramiXNumVisuals * sizeof(VisualRec)); + + memcpy(&PanoramiXVisuals[j], pVisual, sizeof(VisualRec)); + + for (k = 0; k < PanoramiXNumDepths; k++) { + if (PanoramiXDepths[k].depth == pVisual->nplanes) { + PanoramiXDepths[k].vids[PanoramiXDepths[k].numVids] = pVisual->vid; + PanoramiXDepths[k].numVids++; + break; + } + } +} + +extern void +PanoramiXConsolidate(void) +{ + int i; + PanoramiXRes *root, *defmap, *saver; + ScreenPtr pScreen = screenInfo.screens[0]; + DepthPtr pDepth = pScreen->allowedDepths; + VisualPtr pVisual = pScreen->visuals; + + PanoramiXNumDepths = 0; + PanoramiXNumVisuals = 0; + + for (i = 0; i < pScreen->numDepths; i++) + PanoramiXMaybeAddDepth(pDepth++); + + for (i = 0; i < pScreen->numVisuals; i++) + PanoramiXMaybeAddVisual(pVisual++); + + root = malloc(sizeof(PanoramiXRes)); + root->type = XRT_WINDOW; + defmap = malloc(sizeof(PanoramiXRes)); + defmap->type = XRT_COLORMAP; + saver = malloc(sizeof(PanoramiXRes)); + saver->type = XRT_WINDOW; + + for (i = 0; i < PanoramiXNumScreens; i++) { + ScreenPtr pScreen = screenInfo.screens[i]; + root->info[i].id = pScreen->root->drawable.id; + root->u.win.class = InputOutput; + root->u.win.root = TRUE; + saver->info[i].id = pScreen->screensaver.wid; + saver->u.win.class = InputOutput; + saver->u.win.root = TRUE; + defmap->info[i].id = pScreen->defColormap; + } + + AddResource(root->info[0].id, XRT_WINDOW, root); + AddResource(saver->info[0].id, XRT_WINDOW, saver); + AddResource(defmap->info[0].id, XRT_COLORMAP, defmap); +} + +VisualID +PanoramiXTranslateVisualID(int screen, VisualID orig) +{ + ScreenPtr pOtherScreen = screenInfo.screens[screen]; + VisualPtr pVisual = NULL; + int i; + + for (i = 0; i < PanoramiXNumVisuals; i++) { + if (orig == PanoramiXVisuals[i].vid) { + pVisual = &PanoramiXVisuals[i]; + break; + } + } + + if (!pVisual) + return 0; + + /* if screen is 0, orig is already the correct visual ID */ + if (screen == 0) + return orig; + + /* found the original, now translate it relative to the backend screen */ + for (i = 0; i < pOtherScreen->numVisuals; i++) { + VisualPtr pOtherVisual = &pOtherScreen->visuals[i]; + + if ((*XineramaVisualsEqualPtr)(pVisual, pOtherScreen, pOtherVisual)) + return pOtherVisual->vid; + } + + return 0; +} + + +/* + * PanoramiXResetProc() + * Exit, deallocating as needed. + */ + +static void PanoramiXResetProc(ExtensionEntry* extEntry) +{ + int i; + + PanoramiXRenderReset (); +#ifdef XFIXES + PanoramiXFixesReset (); +#endif + screenInfo.numScreens = PanoramiXNumScreens; + for (i = 256; i--; ) + ProcVector[i] = SavedProcVector[i]; +} + + +int +ProcPanoramiXQueryVersion (ClientPtr client) +{ + /* REQUEST(xPanoramiXQueryVersionReq); */ + xPanoramiXQueryVersionReply rep; + register int n; + + REQUEST_SIZE_MATCH (xPanoramiXQueryVersionReq); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.majorVersion = SERVER_PANORAMIX_MAJOR_VERSION; + rep.minorVersion = SERVER_PANORAMIX_MINOR_VERSION; + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swaps(&rep.majorVersion, n); + swaps(&rep.minorVersion, n); + } + WriteToClient(client, sizeof (xPanoramiXQueryVersionReply), (char *)&rep); + return Success; +} + +int +ProcPanoramiXGetState(ClientPtr client) +{ + REQUEST(xPanoramiXGetStateReq); + WindowPtr pWin; + xPanoramiXGetStateReply rep; + int n, rc; + + REQUEST_SIZE_MATCH(xPanoramiXGetStateReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.state = !noPanoramiXExtension; + rep.window = stuff->window; + if (client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swapl (&rep.window, n); + } + WriteToClient (client, sizeof (xPanoramiXGetStateReply), (char *) &rep); + return Success; + +} + +int +ProcPanoramiXGetScreenCount(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenCountReq); + WindowPtr pWin; + xPanoramiXGetScreenCountReply rep; + int n, rc; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.ScreenCount = PanoramiXNumScreens; + rep.window = stuff->window; + if (client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swapl (&rep.window, n); + } + WriteToClient (client, sizeof (xPanoramiXGetScreenCountReply), (char *) &rep); + return Success; +} + +int +ProcPanoramiXGetScreenSize(ClientPtr client) +{ + REQUEST(xPanoramiXGetScreenSizeReq); + WindowPtr pWin; + xPanoramiXGetScreenSizeReply rep; + int n, rc; + + if (stuff->screen >= PanoramiXNumScreens) + return BadMatch; + + REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq); + rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); + if (rc != Success) + return rc; + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + /* screen dimensions */ + rep.width = screenInfo.screens[stuff->screen]->width; + rep.height = screenInfo.screens[stuff->screen]->height; + rep.window = stuff->window; + rep.screen = stuff->screen; + if (client->swapped) { + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swapl (&rep.width, n); + swapl (&rep.height, n); + swapl (&rep.window, n); + swapl (&rep.screen, n); + } + WriteToClient (client, sizeof (xPanoramiXGetScreenSizeReply), (char *) &rep); + return Success; +} + + +int +ProcXineramaIsActive(ClientPtr client) +{ + /* REQUEST(xXineramaIsActiveReq); */ + xXineramaIsActiveReply rep; + + REQUEST_SIZE_MATCH(xXineramaIsActiveReq); + + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; +#if 1 + { + /* The following hack fools clients into thinking that Xinerama + * is disabled even though it is not. */ + rep.state = !noPanoramiXExtension && !PanoramiXExtensionDisabledHack; + } +#else + rep.state = !noPanoramiXExtension; +#endif + if (client->swapped) { + int n; + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swapl (&rep.state, n); + } + WriteToClient (client, sizeof (xXineramaIsActiveReply), (char *) &rep); + return Success; +} + + +int +ProcXineramaQueryScreens(ClientPtr client) +{ + /* REQUEST(xXineramaQueryScreensReq); */ + xXineramaQueryScreensReply rep; + + REQUEST_SIZE_MATCH(xXineramaQueryScreensReq); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.number = (noPanoramiXExtension) ? 0 : PanoramiXNumScreens; + rep.length = bytes_to_int32(rep.number * sz_XineramaScreenInfo); + if (client->swapped) { + int n; + swaps (&rep.sequenceNumber, n); + swapl (&rep.length, n); + swapl (&rep.number, n); + } + WriteToClient (client, sizeof (xXineramaQueryScreensReply), (char *) &rep); + + if(!noPanoramiXExtension) { + xXineramaScreenInfo scratch; + int i; + + for(i = 0; i < PanoramiXNumScreens; i++) { + scratch.x_org = screenInfo.screens[i]->x; + scratch.y_org = screenInfo.screens[i]->y; + scratch.width = screenInfo.screens[i]->width; + scratch.height = screenInfo.screens[i]->height; + + if(client->swapped) { + int n; + swaps (&scratch.x_org, n); + swaps (&scratch.y_org, n); + swaps (&scratch.width, n); + swaps (&scratch.height, n); + } + WriteToClient (client, sz_XineramaScreenInfo, (char *) &scratch); + } + } + + return Success; +} + + +static int +ProcPanoramiXDispatch (ClientPtr client) +{ REQUEST(xReq); + switch (stuff->data) + { + case X_PanoramiXQueryVersion: + return ProcPanoramiXQueryVersion(client); + case X_PanoramiXGetState: + return ProcPanoramiXGetState(client); + case X_PanoramiXGetScreenCount: + return ProcPanoramiXGetScreenCount(client); + case X_PanoramiXGetScreenSize: + return ProcPanoramiXGetScreenSize(client); + case X_XineramaIsActive: + return ProcXineramaIsActive(client); + case X_XineramaQueryScreens: + return ProcXineramaQueryScreens(client); + } + return BadRequest; +} + + +#if X_BYTE_ORDER == X_LITTLE_ENDIAN +#define SHIFT_L(v,s) (v) << (s) +#define SHIFT_R(v,s) (v) >> (s) +#else +#define SHIFT_L(v,s) (v) >> (s) +#define SHIFT_R(v,s) (v) << (s) +#endif + +static void +CopyBits(char *dst, int shiftL, char *src, int bytes) +{ + /* Just get it to work. Worry about speed later */ + int shiftR = 8 - shiftL; + + while(bytes--) { + *dst |= SHIFT_L(*src, shiftL); + *(dst + 1) |= SHIFT_R(*src, shiftR); + dst++; src++; + } +} + + +/* Caution. This doesn't support 2 and 4 bpp formats. We expect + 1 bpp and planar data to be already cleared when presented + to this function */ + +void +XineramaGetImageData( + DrawablePtr *pDrawables, + int left, + int top, + int width, + int height, + unsigned int format, + unsigned long planemask, + char *data, + int pitch, + Bool isRoot +){ + RegionRec SrcRegion, ScreenRegion, GrabRegion; + BoxRec SrcBox, *pbox; + int x, y, w, h, i, j, nbox, size, sizeNeeded, ScratchPitch, inOut, depth; + DrawablePtr pDraw = pDrawables[0]; + char *ScratchMem = NULL; + + size = 0; + + /* find box in logical screen space */ + SrcBox.x1 = left; + SrcBox.y1 = top; + if(!isRoot) { + SrcBox.x1 += pDraw->x + screenInfo.screens[0]->x; + SrcBox.y1 += pDraw->y + screenInfo.screens[0]->y; + } + SrcBox.x2 = SrcBox.x1 + width; + SrcBox.y2 = SrcBox.y1 + height; + + RegionInit(&SrcRegion, &SrcBox, 1); + RegionNull(&GrabRegion); + + depth = (format == XYPixmap) ? 1 : pDraw->depth; + + for(i = 0; i < PanoramiXNumScreens; i++) { + BoxRec TheBox; + ScreenPtr pScreen; + pDraw = pDrawables[i]; + pScreen = pDraw->pScreen; + + TheBox.x1 = pScreen->x; + TheBox.x2 = TheBox.x1 + pScreen->width; + TheBox.y1 = pScreen->y; + TheBox.y2 = TheBox.y1 + pScreen->height; + + RegionInit(&ScreenRegion, &TheBox, 1); + inOut = RegionContainsRect(&ScreenRegion, &SrcBox); + if(inOut == rgnPART) + RegionIntersect(&GrabRegion, &SrcRegion, &ScreenRegion); + RegionUninit(&ScreenRegion); + + if(inOut == rgnIN) { + (*pScreen->GetImage)(pDraw, + SrcBox.x1 - pDraw->x - screenInfo.screens[i]->x, + SrcBox.y1 - pDraw->y - screenInfo.screens[i]->y, + width, height, format, planemask, data); + break; + } else if (inOut == rgnOUT) + continue; + + nbox = RegionNumRects(&GrabRegion); + + if(nbox) { + pbox = RegionRects(&GrabRegion); + + while(nbox--) { + w = pbox->x2 - pbox->x1; + h = pbox->y2 - pbox->y1; + ScratchPitch = PixmapBytePad(w, depth); + sizeNeeded = ScratchPitch * h; + + if(sizeNeeded > size) { + char *tmpdata = ScratchMem; + ScratchMem = realloc(ScratchMem, sizeNeeded); + if(ScratchMem) + size = sizeNeeded; + else { + ScratchMem = tmpdata; + break; + } + } + + x = pbox->x1 - pDraw->x - screenInfo.screens[i]->x; + y = pbox->y1 - pDraw->y - screenInfo.screens[i]->y; + + (*pScreen->GetImage)(pDraw, x, y, w, h, + format, planemask, ScratchMem); + + /* copy the memory over */ + + if(depth == 1) { + int k, shift, leftover, index, index2; + + x = pbox->x1 - SrcBox.x1; + y = pbox->y1 - SrcBox.y1; + shift = x & 7; + x >>= 3; + leftover = w & 7; + w >>= 3; + + /* clean up the edge */ + if(leftover) { + int mask = (1 << leftover) - 1; + for(j = h, k = w; j--; k += ScratchPitch) + ScratchMem[k] &= mask; + } + + for(j = 0, index = (pitch * y) + x, index2 = 0; j < h; + j++, index += pitch, index2 += ScratchPitch) + { + if(w) { + if(!shift) + memcpy(data + index, ScratchMem + index2, w); + else + CopyBits(data + index, shift, + ScratchMem + index2, w); + } + + if(leftover) { + data[index + w] |= + SHIFT_L(ScratchMem[index2 + w], shift); + if((shift + leftover) > 8) + data[index + w + 1] |= + SHIFT_R(ScratchMem[index2 + w],(8 - shift)); + } + } + } else { + j = BitsPerPixel(depth) >> 3; + x = (pbox->x1 - SrcBox.x1) * j; + y = pbox->y1 - SrcBox.y1; + w *= j; + + for(j = 0; j < h; j++) { + memcpy(data + (pitch * (y + j)) + x, + ScratchMem + (ScratchPitch * j), w); + } + } + pbox++; + } + + RegionSubtract(&SrcRegion, &SrcRegion, &GrabRegion); + if(!RegionNotEmpty(&SrcRegion)) + break; + } + + } + + free(ScratchMem); + + RegionUninit(&SrcRegion); + RegionUninit(&GrabRegion); +} diff --git a/xorg-server/Xext/panoramiXsrv.h b/xorg-server/Xext/panoramiXsrv.h index d177df28d..9751feb54 100644 --- a/xorg-server/Xext/panoramiXsrv.h +++ b/xorg-server/Xext/panoramiXsrv.h @@ -1,54 +1,54 @@ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#ifndef _PANORAMIXSRV_H_ -#define _PANORAMIXSRV_H_ - -#include "panoramiX.h" - -extern _X_EXPORT int PanoramiXNumScreens; -extern _X_EXPORT int PanoramiXPixWidth; -extern _X_EXPORT int PanoramiXPixHeight; - -extern _X_EXPORT VisualID PanoramiXTranslateVisualID(int screen, VisualID orig); -extern _X_EXPORT void PanoramiXConsolidate(void); -extern _X_EXPORT Bool PanoramiXCreateConnectionBlock(void); -extern _X_EXPORT PanoramiXRes * PanoramiXFindIDByScrnum(RESTYPE, XID, int); -extern _X_EXPORT Bool XineramaRegisterConnectionBlockCallback(void (*func)(void)); -extern _X_EXPORT int XineramaDeleteResource(pointer, XID); - -extern _X_EXPORT void XineramaReinitData(ScreenPtr); - -extern _X_EXPORT unsigned long XRC_DRAWABLE; -extern _X_EXPORT unsigned long XRT_WINDOW; -extern _X_EXPORT unsigned long XRT_PIXMAP; -extern _X_EXPORT unsigned long XRT_GC; -extern _X_EXPORT unsigned long XRT_COLORMAP; -extern _X_EXPORT unsigned long XRT_PICTURE; - -/* - * Drivers are allowed to wrap this function. Each wrapper can decide that the - * two visuals are unequal, but if they are deemed equal, the wrapper must call - * down and return FALSE if the wrapped function does. This ensures that all - * layers agree that the visuals are equal. The first visual is always from - * screen 0. - */ -typedef Bool (*XineramaVisualsEqualProcPtr)(VisualPtr, ScreenPtr, VisualPtr); -extern _X_EXPORT XineramaVisualsEqualProcPtr XineramaVisualsEqualPtr; - -extern _X_EXPORT void XineramaGetImageData( - DrawablePtr *pDrawables, - int left, - int top, - int width, - int height, - unsigned int format, - unsigned long planemask, - char *data, - int pitch, - Bool isRoot -); - -#endif /* _PANORAMIXSRV_H_ */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#ifndef _PANORAMIXSRV_H_ +#define _PANORAMIXSRV_H_ + +#include "panoramiX.h" + +extern _X_EXPORT int PanoramiXNumScreens; +extern _X_EXPORT int PanoramiXPixWidth; +extern _X_EXPORT int PanoramiXPixHeight; + +extern _X_EXPORT VisualID PanoramiXTranslateVisualID(int screen, VisualID orig); +extern _X_EXPORT void PanoramiXConsolidate(void); +extern _X_EXPORT Bool PanoramiXCreateConnectionBlock(void); +extern _X_EXPORT PanoramiXRes * PanoramiXFindIDByScrnum(RESTYPE, XID, int); +extern _X_EXPORT Bool XineramaRegisterConnectionBlockCallback(void (*func)(void)); +extern _X_EXPORT int XineramaDeleteResource(pointer, XID); + +extern _X_EXPORT void XineramaReinitData(ScreenPtr); + +extern _X_EXPORT RESTYPE XRC_DRAWABLE; +extern _X_EXPORT RESTYPE XRT_WINDOW; +extern _X_EXPORT RESTYPE XRT_PIXMAP; +extern _X_EXPORT RESTYPE XRT_GC; +extern _X_EXPORT RESTYPE XRT_COLORMAP; +extern _X_EXPORT RESTYPE XRT_PICTURE; + +/* + * Drivers are allowed to wrap this function. Each wrapper can decide that the + * two visuals are unequal, but if they are deemed equal, the wrapper must call + * down and return FALSE if the wrapped function does. This ensures that all + * layers agree that the visuals are equal. The first visual is always from + * screen 0. + */ +typedef Bool (*XineramaVisualsEqualProcPtr)(VisualPtr, ScreenPtr, VisualPtr); +extern _X_EXPORT XineramaVisualsEqualProcPtr XineramaVisualsEqualPtr; + +extern _X_EXPORT void XineramaGetImageData( + DrawablePtr *pDrawables, + int left, + int top, + int width, + int height, + unsigned int format, + unsigned long planemask, + char *data, + int pitch, + Bool isRoot +); + +#endif /* _PANORAMIXSRV_H_ */ diff --git a/xorg-server/Xext/xvdix.h b/xorg-server/Xext/xvdix.h index 5104a4def..e9c22bf65 100644 --- a/xorg-server/Xext/xvdix.h +++ b/xorg-server/Xext/xvdix.h @@ -1,275 +1,275 @@ -/*********************************************************** -Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, -and the Massachusetts Institute of Technology, Cambridge, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the names of Digital or MIT not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -#ifndef XVDIX_H -#define XVDIX_H -/* -** File: -** -** xvdix.h --- Xv device independent header file -** -** Author: -** -** David Carver (Digital Workstation Engineering/Project Athena) -** -** Revisions: -** -** 29.08.91 Carver -** - removed UnrealizeWindow wrapper unrealizing windows no longer -** preempts video -** -** 11.06.91 Carver -** - changed SetPortControl to SetPortAttribute -** - changed GetPortControl to GetPortAttribute -** - changed QueryBestSize -** -** 15.05.91 Carver -** - version 2.0 upgrade -** -** 24.01.91 Carver -** - version 1.4 upgrade -** -*/ - -#include "scrnintstr.h" -#include - -#ifndef XorgLoader -extern _X_EXPORT unsigned long XvExtensionGeneration; -extern _X_EXPORT unsigned long XvScreenGeneration; -extern _X_EXPORT unsigned long XvResourceGeneration; - -extern _X_EXPORT int XvReqCode; -extern _X_EXPORT int XvEventBase; -extern _X_EXPORT int XvErrorBase; - -extern _X_EXPORT unsigned long XvRTPort; -extern _X_EXPORT unsigned long XvRTEncoding; -extern _X_EXPORT unsigned long XvRTGrab; -extern _X_EXPORT unsigned long XvRTVideoNotify; -extern _X_EXPORT unsigned long XvRTVideoNotifyList; -extern _X_EXPORT unsigned long XvRTPortNotify; -#endif - -typedef struct { - int numerator; - int denominator; -} XvRationalRec, *XvRationalPtr; - -typedef struct { - char depth; - unsigned long visual; -} XvFormatRec, *XvFormatPtr; - -typedef struct { - unsigned long id; - ClientPtr client; -} XvGrabRec, *XvGrabPtr; - -typedef struct _XvVideoNotifyRec { - struct _XvVideoNotifyRec *next; - ClientPtr client; - unsigned long id; - unsigned long mask; -} XvVideoNotifyRec, *XvVideoNotifyPtr; - -typedef struct _XvPortNotifyRec { - struct _XvPortNotifyRec *next; - ClientPtr client; - unsigned long id; -} XvPortNotifyRec, *XvPortNotifyPtr; - -typedef struct { - int id; - ScreenPtr pScreen; - char *name; - unsigned short width, height; - XvRationalRec rate; -} XvEncodingRec, *XvEncodingPtr; - -typedef struct _XvAttributeRec { - int flags; - int min_value; - int max_value; - char *name; -} XvAttributeRec, *XvAttributePtr; - -typedef struct { - int id; - int type; - int byte_order; - char guid[16]; - int bits_per_pixel; - int format; - int num_planes; - - /* for RGB formats only */ - int depth; - unsigned int red_mask; - unsigned int green_mask; - unsigned int blue_mask; - - /* for YUV formats only */ - unsigned int y_sample_bits; - unsigned int u_sample_bits; - unsigned int v_sample_bits; - unsigned int horz_y_period; - unsigned int horz_u_period; - unsigned int horz_v_period; - unsigned int vert_y_period; - unsigned int vert_u_period; - unsigned int vert_v_period; - char component_order[32]; - int scanline_order; -} XvImageRec, *XvImagePtr; - -typedef struct { - unsigned long base_id; - unsigned char type; - char *name; - int nEncodings; - XvEncodingPtr pEncodings; - int nFormats; - XvFormatPtr pFormats; - int nAttributes; - XvAttributePtr pAttributes; - int nImages; - XvImagePtr pImages; - int nPorts; - struct _XvPortRec *pPorts; - ScreenPtr pScreen; - int (* ddAllocatePort)(unsigned long, struct _XvPortRec*, - struct _XvPortRec**); - int (* ddFreePort)(struct _XvPortRec*); - int (* ddPutVideo)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr, - INT16, INT16, CARD16, CARD16, - INT16, INT16, CARD16, CARD16); - int (* ddPutStill)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr, - INT16, INT16, CARD16, CARD16, - INT16, INT16, CARD16, CARD16); - int (* ddGetVideo)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr, - INT16, INT16, CARD16, CARD16, - INT16, INT16, CARD16, CARD16); - int (* ddGetStill)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr, - INT16, INT16, CARD16, CARD16, - INT16, INT16, CARD16, CARD16); - int (* ddStopVideo)(ClientPtr, struct _XvPortRec*, DrawablePtr); - int (* ddSetPortAttribute)(ClientPtr, struct _XvPortRec*, Atom, INT32); - int (* ddGetPortAttribute)(ClientPtr, struct _XvPortRec*, Atom, INT32*); - int (* ddQueryBestSize)(ClientPtr, struct _XvPortRec*, CARD8, - CARD16, CARD16,CARD16, CARD16, - unsigned int*, unsigned int*); - int (* ddPutImage)(ClientPtr, DrawablePtr, struct _XvPortRec*, GCPtr, - INT16, INT16, CARD16, CARD16, - INT16, INT16, CARD16, CARD16, - XvImagePtr, unsigned char*, Bool, - CARD16, CARD16); - int (* ddQueryImageAttributes)(ClientPtr, struct _XvPortRec*, XvImagePtr, - CARD16*, CARD16*, int*, int*); - DevUnion devPriv; -} XvAdaptorRec, *XvAdaptorPtr; - -typedef struct _XvPortRec { - unsigned long id; - XvAdaptorPtr pAdaptor; - XvPortNotifyPtr pNotify; - DrawablePtr pDraw; - ClientPtr client; - XvGrabRec grab; - TimeStamp time; - DevUnion devPriv; -} XvPortRec, *XvPortPtr; - -#define VALIDATE_XV_PORT(portID, pPort, mode)\ - {\ - int rc = dixLookupResourceByType((pointer *)&(pPort), portID,\ - XvRTPort, client, mode);\ - if (rc != Success)\ - return rc;\ - } - -typedef struct { - int version, revision; - int nAdaptors; - XvAdaptorPtr pAdaptors; - DestroyWindowProcPtr DestroyWindow; - DestroyPixmapProcPtr DestroyPixmap; - CloseScreenProcPtr CloseScreen; - Bool (* ddCloseScreen)(int, ScreenPtr); - int (* ddQueryAdaptors)(ScreenPtr, XvAdaptorPtr*, int*); - DevUnion devPriv; -} XvScreenRec, *XvScreenPtr; - -#define SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = ((XvScreenPtr) \ - dixLookupPrivate(&(pScreen)->devPrivates, XvScreenKey))->field) - -#define SCREEN_EPILOGUE(pScreen, field, wrapper)\ - ((pScreen)->field = wrapper) - -/* Errors */ - -#define _XvBadPort (XvBadPort+XvErrorBase) -#define _XvBadEncoding (XvBadEncoding+XvErrorBase) - -#ifndef XorgLoader -extern _X_EXPORT int ProcXvDispatch(ClientPtr); -extern _X_EXPORT int SProcXvDispatch(ClientPtr); - -extern _X_EXPORT void XvExtensionInit(void); -extern _X_EXPORT int XvScreenInit(ScreenPtr); -extern _X_EXPORT DevPrivateKey XvGetScreenKey(void); -extern _X_EXPORT unsigned long XvGetRTPort(void); -extern _X_EXPORT int XvdiSendPortNotify(XvPortPtr, Atom, INT32); -extern _X_EXPORT int XvdiVideoStopped(XvPortPtr, int); - -extern _X_EXPORT int XvdiPutVideo(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, - INT16, INT16, CARD16, CARD16, - INT16, INT16, CARD16, CARD16); -extern _X_EXPORT int XvdiPutStill(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, - INT16, INT16, CARD16, CARD16, - INT16, INT16, CARD16, CARD16); -extern _X_EXPORT int XvdiGetVideo(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, - INT16, INT16, CARD16, CARD16, - INT16, INT16, CARD16, CARD16); -extern _X_EXPORT int XvdiGetStill(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, - INT16, INT16, CARD16, CARD16, - INT16, INT16, CARD16, CARD16); -extern _X_EXPORT int XvdiPutImage(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, - INT16, INT16, CARD16, CARD16, - INT16, INT16, CARD16, CARD16, - XvImagePtr, unsigned char*, Bool, - CARD16, CARD16); -extern _X_EXPORT int XvdiSelectVideoNotify(ClientPtr, DrawablePtr, BOOL); -extern _X_EXPORT int XvdiSelectPortNotify(ClientPtr, XvPortPtr, BOOL); -extern _X_EXPORT int XvdiSetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32); -extern _X_EXPORT int XvdiGetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32*); -extern _X_EXPORT int XvdiStopVideo(ClientPtr, XvPortPtr, DrawablePtr); -extern _X_EXPORT int XvdiPreemptVideo(ClientPtr, XvPortPtr, DrawablePtr); -extern _X_EXPORT int XvdiMatchPort(XvPortPtr, DrawablePtr); -extern _X_EXPORT int XvdiGrabPort(ClientPtr, XvPortPtr, Time, int *); -extern _X_EXPORT int XvdiUngrabPort( ClientPtr, XvPortPtr, Time); -#endif /* XorgLoader */ - -#endif /* XVDIX_H */ - +/*********************************************************** +Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef XVDIX_H +#define XVDIX_H +/* +** File: +** +** xvdix.h --- Xv device independent header file +** +** Author: +** +** David Carver (Digital Workstation Engineering/Project Athena) +** +** Revisions: +** +** 29.08.91 Carver +** - removed UnrealizeWindow wrapper unrealizing windows no longer +** preempts video +** +** 11.06.91 Carver +** - changed SetPortControl to SetPortAttribute +** - changed GetPortControl to GetPortAttribute +** - changed QueryBestSize +** +** 15.05.91 Carver +** - version 2.0 upgrade +** +** 24.01.91 Carver +** - version 1.4 upgrade +** +*/ + +#include "scrnintstr.h" +#include + +#ifndef XorgLoader +extern _X_EXPORT unsigned long XvExtensionGeneration; +extern _X_EXPORT unsigned long XvScreenGeneration; +extern _X_EXPORT unsigned long XvResourceGeneration; + +extern _X_EXPORT int XvReqCode; +extern _X_EXPORT int XvEventBase; +extern _X_EXPORT int XvErrorBase; + +extern _X_EXPORT RESTYPE XvRTPort; +extern _X_EXPORT RESTYPE XvRTEncoding; +extern _X_EXPORT RESTYPE XvRTGrab; +extern _X_EXPORT RESTYPE XvRTVideoNotify; +extern _X_EXPORT RESTYPE XvRTVideoNotifyList; +extern _X_EXPORT RESTYPE XvRTPortNotify; +#endif + +typedef struct { + int numerator; + int denominator; +} XvRationalRec, *XvRationalPtr; + +typedef struct { + char depth; + unsigned long visual; +} XvFormatRec, *XvFormatPtr; + +typedef struct { + unsigned long id; + ClientPtr client; +} XvGrabRec, *XvGrabPtr; + +typedef struct _XvVideoNotifyRec { + struct _XvVideoNotifyRec *next; + ClientPtr client; + unsigned long id; + unsigned long mask; +} XvVideoNotifyRec, *XvVideoNotifyPtr; + +typedef struct _XvPortNotifyRec { + struct _XvPortNotifyRec *next; + ClientPtr client; + unsigned long id; +} XvPortNotifyRec, *XvPortNotifyPtr; + +typedef struct { + int id; + ScreenPtr pScreen; + char *name; + unsigned short width, height; + XvRationalRec rate; +} XvEncodingRec, *XvEncodingPtr; + +typedef struct _XvAttributeRec { + int flags; + int min_value; + int max_value; + char *name; +} XvAttributeRec, *XvAttributePtr; + +typedef struct { + int id; + int type; + int byte_order; + char guid[16]; + int bits_per_pixel; + int format; + int num_planes; + + /* for RGB formats only */ + int depth; + unsigned int red_mask; + unsigned int green_mask; + unsigned int blue_mask; + + /* for YUV formats only */ + unsigned int y_sample_bits; + unsigned int u_sample_bits; + unsigned int v_sample_bits; + unsigned int horz_y_period; + unsigned int horz_u_period; + unsigned int horz_v_period; + unsigned int vert_y_period; + unsigned int vert_u_period; + unsigned int vert_v_period; + char component_order[32]; + int scanline_order; +} XvImageRec, *XvImagePtr; + +typedef struct { + unsigned long base_id; + unsigned char type; + char *name; + int nEncodings; + XvEncodingPtr pEncodings; + int nFormats; + XvFormatPtr pFormats; + int nAttributes; + XvAttributePtr pAttributes; + int nImages; + XvImagePtr pImages; + int nPorts; + struct _XvPortRec *pPorts; + ScreenPtr pScreen; + int (* ddAllocatePort)(unsigned long, struct _XvPortRec*, + struct _XvPortRec**); + int (* ddFreePort)(struct _XvPortRec*); + int (* ddPutVideo)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); + int (* ddPutStill)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); + int (* ddGetVideo)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); + int (* ddGetStill)(ClientPtr, DrawablePtr,struct _XvPortRec*, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); + int (* ddStopVideo)(ClientPtr, struct _XvPortRec*, DrawablePtr); + int (* ddSetPortAttribute)(ClientPtr, struct _XvPortRec*, Atom, INT32); + int (* ddGetPortAttribute)(ClientPtr, struct _XvPortRec*, Atom, INT32*); + int (* ddQueryBestSize)(ClientPtr, struct _XvPortRec*, CARD8, + CARD16, CARD16,CARD16, CARD16, + unsigned int*, unsigned int*); + int (* ddPutImage)(ClientPtr, DrawablePtr, struct _XvPortRec*, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16, + XvImagePtr, unsigned char*, Bool, + CARD16, CARD16); + int (* ddQueryImageAttributes)(ClientPtr, struct _XvPortRec*, XvImagePtr, + CARD16*, CARD16*, int*, int*); + DevUnion devPriv; +} XvAdaptorRec, *XvAdaptorPtr; + +typedef struct _XvPortRec { + unsigned long id; + XvAdaptorPtr pAdaptor; + XvPortNotifyPtr pNotify; + DrawablePtr pDraw; + ClientPtr client; + XvGrabRec grab; + TimeStamp time; + DevUnion devPriv; +} XvPortRec, *XvPortPtr; + +#define VALIDATE_XV_PORT(portID, pPort, mode)\ + {\ + int rc = dixLookupResourceByType((pointer *)&(pPort), portID,\ + XvRTPort, client, mode);\ + if (rc != Success)\ + return rc;\ + } + +typedef struct { + int version, revision; + int nAdaptors; + XvAdaptorPtr pAdaptors; + DestroyWindowProcPtr DestroyWindow; + DestroyPixmapProcPtr DestroyPixmap; + CloseScreenProcPtr CloseScreen; + Bool (* ddCloseScreen)(int, ScreenPtr); + int (* ddQueryAdaptors)(ScreenPtr, XvAdaptorPtr*, int*); + DevUnion devPriv; +} XvScreenRec, *XvScreenPtr; + +#define SCREEN_PROLOGUE(pScreen, field) ((pScreen)->field = ((XvScreenPtr) \ + dixLookupPrivate(&(pScreen)->devPrivates, XvScreenKey))->field) + +#define SCREEN_EPILOGUE(pScreen, field, wrapper)\ + ((pScreen)->field = wrapper) + +/* Errors */ + +#define _XvBadPort (XvBadPort+XvErrorBase) +#define _XvBadEncoding (XvBadEncoding+XvErrorBase) + +#ifndef XorgLoader +extern _X_EXPORT int ProcXvDispatch(ClientPtr); +extern _X_EXPORT int SProcXvDispatch(ClientPtr); + +extern _X_EXPORT void XvExtensionInit(void); +extern _X_EXPORT int XvScreenInit(ScreenPtr); +extern _X_EXPORT DevPrivateKey XvGetScreenKey(void); +extern _X_EXPORT unsigned long XvGetRTPort(void); +extern _X_EXPORT int XvdiSendPortNotify(XvPortPtr, Atom, INT32); +extern _X_EXPORT int XvdiVideoStopped(XvPortPtr, int); + +extern _X_EXPORT int XvdiPutVideo(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); +extern _X_EXPORT int XvdiPutStill(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); +extern _X_EXPORT int XvdiGetVideo(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); +extern _X_EXPORT int XvdiGetStill(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16); +extern _X_EXPORT int XvdiPutImage(ClientPtr, DrawablePtr, XvPortPtr, GCPtr, + INT16, INT16, CARD16, CARD16, + INT16, INT16, CARD16, CARD16, + XvImagePtr, unsigned char*, Bool, + CARD16, CARD16); +extern _X_EXPORT int XvdiSelectVideoNotify(ClientPtr, DrawablePtr, BOOL); +extern _X_EXPORT int XvdiSelectPortNotify(ClientPtr, XvPortPtr, BOOL); +extern _X_EXPORT int XvdiSetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32); +extern _X_EXPORT int XvdiGetPortAttribute(ClientPtr, XvPortPtr, Atom, INT32*); +extern _X_EXPORT int XvdiStopVideo(ClientPtr, XvPortPtr, DrawablePtr); +extern _X_EXPORT int XvdiPreemptVideo(ClientPtr, XvPortPtr, DrawablePtr); +extern _X_EXPORT int XvdiMatchPort(XvPortPtr, DrawablePtr); +extern _X_EXPORT int XvdiGrabPort(ClientPtr, XvPortPtr, Time, int *); +extern _X_EXPORT int XvdiUngrabPort( ClientPtr, XvPortPtr, Time); +#endif /* XorgLoader */ + +#endif /* XVDIX_H */ + diff --git a/xorg-server/Xext/xvmain.c b/xorg-server/Xext/xvmain.c index f3b6d84b9..cd6f0979c 100644 --- a/xorg-server/Xext/xvmain.c +++ b/xorg-server/Xext/xvmain.c @@ -1,1185 +1,1183 @@ -/*********************************************************** -Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, -and the Massachusetts Institute of Technology, Cambridge, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the names of Digital or MIT not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -/* -** File: -** -** xvmain.c --- Xv server extension main device independent module. -** -** Author: -** -** David Carver (Digital Workstation Engineering/Project Athena) -** -** Revisions: -** -** 04.09.91 Carver -** - change: stop video always generates an event even when video -** wasn't active -** -** 29.08.91 Carver -** - change: unrealizing windows no longer preempts video -** -** 11.06.91 Carver -** - changed SetPortControl to SetPortAttribute -** - changed GetPortControl to GetPortAttribute -** - changed QueryBestSize -** -** 28.05.91 Carver -** - fixed Put and Get requests to not preempt operations to same drawable -** -** 15.05.91 Carver -** - version 2.0 upgrade -** -** 19.03.91 Carver -** - fixed Put and Get requests to honor grabbed ports. -** - fixed Video requests to update di structure with new drawable, and -** client after calling ddx. -** -** 24.01.91 Carver -** - version 1.4 upgrade -** -** Notes: -** -** Port structures reference client structures in a two different -** ways: when grabs, or video is active. Each reference is encoded -** as fake client resources and thus when the client is goes away so -** does the reference (it is zeroed). No other action is taken, so -** video doesn't necessarily stop. It probably will as a result of -** other resources going away, but if a client starts video using -** none of its own resources, then the video will continue to play -** after the client disappears. -** -** -*/ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include - -#include -#include -#include "misc.h" -#include "os.h" -#include "scrnintstr.h" -#include "windowstr.h" -#include "pixmapstr.h" -#include "gc.h" -#include "extnsionst.h" -#include "dixstruct.h" -#include "resource.h" -#include "opaque.h" -#include "input.h" - -#define GLOBAL - -#include -#include -#include "xvdix.h" - -#ifdef PANORAMIX -#include "panoramiX.h" -#include "panoramiXsrv.h" -#endif -#include "xvdisp.h" - -static DevPrivateKeyRec XvScreenKeyRec; -#define XvScreenKey (&XvScreenKeyRec) -unsigned long XvExtensionGeneration = 0; -unsigned long XvScreenGeneration = 0; -unsigned long XvResourceGeneration = 0; - -int XvReqCode; -int XvEventBase; -int XvErrorBase; - -unsigned long XvRTPort; -unsigned long XvRTEncoding; -unsigned long XvRTGrab; -unsigned long XvRTVideoNotify; -unsigned long XvRTVideoNotifyList; -unsigned long XvRTPortNotify; - - - -/* EXTERNAL */ - -static void WriteSwappedVideoNotifyEvent(xvEvent *, xvEvent *); -static void WriteSwappedPortNotifyEvent(xvEvent *, xvEvent *); -static Bool CreateResourceTypes(void); - -static Bool XvCloseScreen(int, ScreenPtr); -static Bool XvDestroyPixmap(PixmapPtr); -static Bool XvDestroyWindow(WindowPtr); -static void XvResetProc(ExtensionEntry*); -static int XvdiDestroyGrab(pointer, XID); -static int XvdiDestroyEncoding(pointer, XID); -static int XvdiDestroyVideoNotify(pointer, XID); -static int XvdiDestroyPortNotify(pointer, XID); -static int XvdiDestroyVideoNotifyList(pointer, XID); -static int XvdiDestroyPort(pointer, XID); -static int XvdiSendVideoNotify(XvPortPtr, DrawablePtr, int); - - - - -/* -** XvExtensionInit -** -** -*/ - -void -XvExtensionInit(void) -{ - ExtensionEntry *extEntry; - - if (!dixRegisterPrivateKey(&XvScreenKeyRec, PRIVATE_SCREEN, 0)) - return; - - /* LOOK TO SEE IF ANY SCREENS WERE INITIALIZED; IF NOT THEN - INIT GLOBAL VARIABLES SO THE EXTENSION CAN FUNCTION */ - if (XvScreenGeneration != serverGeneration) - { - if (!CreateResourceTypes()) - { - ErrorF("XvExtensionInit: Unable to allocate resource types\n"); - return; - } -#ifdef PANORAMIX - XineramaRegisterConnectionBlockCallback(XineramifyXv); -#endif - XvScreenGeneration = serverGeneration; - } - - if (XvExtensionGeneration != serverGeneration) - { - XvExtensionGeneration = serverGeneration; - - extEntry = AddExtension(XvName, XvNumEvents, XvNumErrors, - ProcXvDispatch, SProcXvDispatch, - XvResetProc, StandardMinorOpcode); - if (!extEntry) - { - FatalError("XvExtensionInit: AddExtensions failed\n"); - } - - XvReqCode = extEntry->base; - XvEventBase = extEntry->eventBase; - XvErrorBase = extEntry->errorBase; - - EventSwapVector[XvEventBase+XvVideoNotify] = - (EventSwapPtr)WriteSwappedVideoNotifyEvent; - EventSwapVector[XvEventBase+XvPortNotify] = - (EventSwapPtr)WriteSwappedPortNotifyEvent; - - SetResourceTypeErrorValue(XvRTPort, _XvBadPort); - (void)MakeAtom(XvName, strlen(XvName), xTrue); - - } -} - -static Bool -CreateResourceTypes(void) - -{ - - if (XvResourceGeneration == serverGeneration) return TRUE; - - XvResourceGeneration = serverGeneration; - - if (!(XvRTPort = CreateNewResourceType(XvdiDestroyPort, "XvRTPort"))) - { - ErrorF("CreateResourceTypes: failed to allocate port resource.\n"); - return FALSE; - } - - if (!(XvRTGrab = CreateNewResourceType(XvdiDestroyGrab, "XvRTGrab"))) - { - ErrorF("CreateResourceTypes: failed to allocate grab resource.\n"); - return FALSE; - } - - if (!(XvRTEncoding = CreateNewResourceType(XvdiDestroyEncoding, - "XvRTEncoding"))) - { - ErrorF("CreateResourceTypes: failed to allocate encoding resource.\n"); - return FALSE; - } - - if (!(XvRTVideoNotify = CreateNewResourceType(XvdiDestroyVideoNotify, - "XvRTVideoNotify"))) - { - ErrorF("CreateResourceTypes: failed to allocate video notify resource.\n"); - return FALSE; - } - - if (!(XvRTVideoNotifyList = CreateNewResourceType(XvdiDestroyVideoNotifyList, - "XvRTVideoNotifyList"))) - { - ErrorF("CreateResourceTypes: failed to allocate video notify list resource.\n"); - return FALSE; - } - - if (!(XvRTPortNotify = CreateNewResourceType(XvdiDestroyPortNotify, - "XvRTPortNotify"))) - { - ErrorF("CreateResourceTypes: failed to allocate port notify resource.\n"); - return FALSE; - } - - return TRUE; - -} - -int -XvScreenInit(ScreenPtr pScreen) -{ - XvScreenPtr pxvs; - - if (XvScreenGeneration != serverGeneration) - { - if (!CreateResourceTypes()) - { - ErrorF("XvScreenInit: Unable to allocate resource types\n"); - return BadAlloc; - } -#ifdef PANORAMIX - XineramaRegisterConnectionBlockCallback(XineramifyXv); -#endif - XvScreenGeneration = serverGeneration; - } - - if (!dixRegisterPrivateKey(&XvScreenKeyRec, PRIVATE_SCREEN, 0)) - return BadAlloc; - - if (dixLookupPrivate(&pScreen->devPrivates, XvScreenKey)) - { - ErrorF("XvScreenInit: screen devPrivates ptr non-NULL before init\n"); - } - - /* ALLOCATE SCREEN PRIVATE RECORD */ - - pxvs = malloc(sizeof (XvScreenRec)); - if (!pxvs) - { - ErrorF("XvScreenInit: Unable to allocate screen private structure\n"); - return BadAlloc; - } - - dixSetPrivate(&pScreen->devPrivates, XvScreenKey, pxvs); - - pxvs->DestroyPixmap = pScreen->DestroyPixmap; - pxvs->DestroyWindow = pScreen->DestroyWindow; - pxvs->CloseScreen = pScreen->CloseScreen; - - pScreen->DestroyPixmap = XvDestroyPixmap; - pScreen->DestroyWindow = XvDestroyWindow; - pScreen->CloseScreen = XvCloseScreen; - - return Success; -} - -static Bool -XvCloseScreen( - int ii, - ScreenPtr pScreen -){ - - XvScreenPtr pxvs; - - pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); - - pScreen->DestroyPixmap = pxvs->DestroyPixmap; - pScreen->DestroyWindow = pxvs->DestroyWindow; - pScreen->CloseScreen = pxvs->CloseScreen; - - (* pxvs->ddCloseScreen)(ii, pScreen); - - free(pxvs); - - dixSetPrivate(&pScreen->devPrivates, XvScreenKey, NULL); - - return (*pScreen->CloseScreen)(ii, pScreen); -} - -static void -XvResetProc(ExtensionEntry* extEntry) -{ - XvResetProcVector(); -} - -DevPrivateKey -XvGetScreenKey(void) -{ - return XvScreenKey; -} - -unsigned long -XvGetRTPort(void) -{ - return XvRTPort; -} - -static Bool -XvDestroyPixmap(PixmapPtr pPix) -{ - Bool status; - ScreenPtr pScreen; - XvScreenPtr pxvs; - XvAdaptorPtr pa; - int na; - XvPortPtr pp; - int np; - - pScreen = pPix->drawable.pScreen; - - SCREEN_PROLOGUE(pScreen, DestroyPixmap); - - pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); - - /* CHECK TO SEE IF THIS PORT IS IN USE */ - - pa = pxvs->pAdaptors; - na = pxvs->nAdaptors; - while (na--) - { - np = pa->nPorts; - pp = pa->pPorts; - - while (np--) - { - if (pp->pDraw == (DrawablePtr)pPix) - { - XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted); - - (void)(* pp->pAdaptor->ddStopVideo)(NULL, pp, pp->pDraw); - - pp->pDraw = NULL; - pp->client = NULL; - pp->time = currentTime; - } - pp++; - } - pa++; - } - - status = (* pScreen->DestroyPixmap)(pPix); - - SCREEN_EPILOGUE(pScreen, DestroyPixmap, XvDestroyPixmap); - - return status; - -} - -static Bool -XvDestroyWindow(WindowPtr pWin) -{ - Bool status; - ScreenPtr pScreen; - XvScreenPtr pxvs; - XvAdaptorPtr pa; - int na; - XvPortPtr pp; - int np; - - pScreen = pWin->drawable.pScreen; - - SCREEN_PROLOGUE(pScreen, DestroyWindow); - - pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); - - /* CHECK TO SEE IF THIS PORT IS IN USE */ - - pa = pxvs->pAdaptors; - na = pxvs->nAdaptors; - while (na--) - { - np = pa->nPorts; - pp = pa->pPorts; - - while (np--) - { - if (pp->pDraw == (DrawablePtr)pWin) - { - XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted); - - (void)(* pp->pAdaptor->ddStopVideo)(NULL, pp, pp->pDraw); - - pp->pDraw = NULL; - pp->client = NULL; - pp->time = currentTime; - } - pp++; - } - pa++; - } - - - status = (* pScreen->DestroyWindow)(pWin); - - SCREEN_EPILOGUE(pScreen, DestroyWindow, XvDestroyWindow); - - return status; - -} - -/* The XvdiVideoStopped procedure is a hook for the device dependent layer. - It provides a way for the dd layer to inform the di layer that video has - stopped in a port for reasons that the di layer had no control over; note - that it doesn't call back into the dd layer */ - -int -XvdiVideoStopped(XvPortPtr pPort, int reason) -{ - - /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ - - if (!pPort->pDraw) return Success; - - XvdiSendVideoNotify(pPort, pPort->pDraw, reason); - - pPort->pDraw = NULL; - pPort->client = NULL; - pPort->time = currentTime; - - return Success; - -} - -static int -XvdiDestroyPort(pointer pPort, XID id) -{ - return (* ((XvPortPtr)pPort)->pAdaptor->ddFreePort)(pPort); -} - -static int -XvdiDestroyGrab(pointer pGrab, XID id) -{ - ((XvGrabPtr)pGrab)->client = NULL; - return Success; -} - -static int -XvdiDestroyVideoNotify(pointer pn, XID id) -{ - /* JUST CLEAR OUT THE client POINTER FIELD */ - - ((XvVideoNotifyPtr)pn)->client = NULL; - return Success; -} - -static int -XvdiDestroyPortNotify(pointer pn, XID id) -{ - /* JUST CLEAR OUT THE client POINTER FIELD */ - - ((XvPortNotifyPtr)pn)->client = NULL; - return Success; -} - -static int -XvdiDestroyVideoNotifyList(pointer pn, XID id) -{ - XvVideoNotifyPtr npn,cpn; - - /* ACTUALLY DESTROY THE NOTITY LIST */ - - cpn = (XvVideoNotifyPtr)pn; - - while (cpn) - { - npn = cpn->next; - if (cpn->client) FreeResource(cpn->id, XvRTVideoNotify); - free(cpn); - cpn = npn; - } - return Success; -} - -static int -XvdiDestroyEncoding(pointer value, XID id) -{ - return Success; -} - -static int -XvdiSendVideoNotify(XvPortPtr pPort, DrawablePtr pDraw, int reason) -{ - xvEvent event; - XvVideoNotifyPtr pn; - - dixLookupResourceByType((pointer *)&pn, pDraw->id, XvRTVideoNotifyList, - serverClient, DixReadAccess); - - while (pn) - { - event.u.u.type = XvEventBase + XvVideoNotify; - event.u.videoNotify.time = currentTime.milliseconds; - event.u.videoNotify.drawable = pDraw->id; - event.u.videoNotify.port = pPort->id; - event.u.videoNotify.reason = reason; - WriteEventsToClient(pn->client, 1, (xEventPtr)&event); - pn = pn->next; - } - - return Success; - -} - - -int -XvdiSendPortNotify( - XvPortPtr pPort, - Atom attribute, - INT32 value -){ - xvEvent event; - XvPortNotifyPtr pn; - - pn = pPort->pNotify; - - while (pn) - { - event.u.u.type = XvEventBase + XvPortNotify; - event.u.portNotify.time = currentTime.milliseconds; - event.u.portNotify.port = pPort->id; - event.u.portNotify.attribute = attribute; - event.u.portNotify.value = value; - WriteEventsToClient(pn->client, 1, (xEventPtr)&event); - pn = pn->next; - } - - return Success; - -} - - -#define CHECK_SIZE(dw, dh, sw, sh) { \ - if(!dw || !dh || !sw || !sh) return Success; \ - /* The region code will break these if they are too large */ \ - if((dw > 32767) || (dh > 32767) || (sw > 32767) || (sh > 32767)) \ - return BadValue; \ -} - - -int -XvdiPutVideo( - ClientPtr client, - DrawablePtr pDraw, - XvPortPtr pPort, - GCPtr pGC, - INT16 vid_x, INT16 vid_y, - CARD16 vid_w, CARD16 vid_h, - INT16 drw_x, INT16 drw_y, - CARD16 drw_w, CARD16 drw_h -){ - DrawablePtr pOldDraw; - - CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); - - /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ - - UpdateCurrentTime(); - - /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN - INFORM CLIENT OF ITS FAILURE */ - - if (pPort->grab.client && (pPort->grab.client != client)) - { - XvdiSendVideoNotify(pPort, pDraw, XvBusy); - return Success; - } - - /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED - EVENTS TO ANY CLIENTS WHO WANT THEM */ - - pOldDraw = pPort->pDraw; - if ((pOldDraw) && (pOldDraw != pDraw)) - { - XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); - } - - (void) (* pPort->pAdaptor->ddPutVideo)(client, pDraw, pPort, pGC, - vid_x, vid_y, vid_w, vid_h, - drw_x, drw_y, drw_w, drw_h); - - if ((pPort->pDraw) && (pOldDraw != pDraw)) - { - pPort->client = client; - XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted); - } - - pPort->time = currentTime; - - return Success; - -} - -int -XvdiPutStill( - ClientPtr client, - DrawablePtr pDraw, - XvPortPtr pPort, - GCPtr pGC, - INT16 vid_x, INT16 vid_y, - CARD16 vid_w, CARD16 vid_h, - INT16 drw_x, INT16 drw_y, - CARD16 drw_w, CARD16 drw_h -){ - int status; - - CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); - - /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ - - UpdateCurrentTime(); - - /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN - INFORM CLIENT OF ITS FAILURE */ - - if (pPort->grab.client && (pPort->grab.client != client)) - { - XvdiSendVideoNotify(pPort, pDraw, XvBusy); - return Success; - } - - pPort->time = currentTime; - - status = (* pPort->pAdaptor->ddPutStill)(client, pDraw, pPort, pGC, - vid_x, vid_y, vid_w, vid_h, - drw_x, drw_y, drw_w, drw_h); - - return status; - -} - -int -XvdiPutImage( - ClientPtr client, - DrawablePtr pDraw, - XvPortPtr pPort, - GCPtr pGC, - INT16 src_x, INT16 src_y, - CARD16 src_w, CARD16 src_h, - INT16 drw_x, INT16 drw_y, - CARD16 drw_w, CARD16 drw_h, - XvImagePtr image, - unsigned char* data, - Bool sync, - CARD16 width, CARD16 height -){ - CHECK_SIZE(drw_w, drw_h, src_w, src_h); - - /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ - - UpdateCurrentTime(); - - /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN - INFORM CLIENT OF ITS FAILURE */ - - if (pPort->grab.client && (pPort->grab.client != client)) - { - XvdiSendVideoNotify(pPort, pDraw, XvBusy); - return Success; - } - - pPort->time = currentTime; - - return (* pPort->pAdaptor->ddPutImage)(client, pDraw, pPort, pGC, - src_x, src_y, src_w, src_h, - drw_x, drw_y, drw_w, drw_h, - image, data, sync, width, height); -} - - -int -XvdiGetVideo( - ClientPtr client, - DrawablePtr pDraw, - XvPortPtr pPort, - GCPtr pGC, - INT16 vid_x, INT16 vid_y, - CARD16 vid_w, CARD16 vid_h, - INT16 drw_x, INT16 drw_y, - CARD16 drw_w, CARD16 drw_h -){ - DrawablePtr pOldDraw; - - CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); - - /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ - - UpdateCurrentTime(); - - /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN - INFORM CLIENT OF ITS FAILURE */ - - if (pPort->grab.client && (pPort->grab.client != client)) - { - XvdiSendVideoNotify(pPort, pDraw, XvBusy); - return Success; - } - - /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED - EVENTS TO ANY CLIENTS WHO WANT THEM */ - - pOldDraw = pPort->pDraw; - if ((pOldDraw) && (pOldDraw != pDraw)) - { - XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); - } - - (void) (* pPort->pAdaptor->ddGetVideo)(client, pDraw, pPort, pGC, - vid_x, vid_y, vid_w, vid_h, - drw_x, drw_y, drw_w, drw_h); - - if ((pPort->pDraw) && (pOldDraw != pDraw)) - { - pPort->client = client; - XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted); - } - - pPort->time = currentTime; - - return Success; - -} - -int -XvdiGetStill( - ClientPtr client, - DrawablePtr pDraw, - XvPortPtr pPort, - GCPtr pGC, - INT16 vid_x, INT16 vid_y, - CARD16 vid_w, CARD16 vid_h, - INT16 drw_x, INT16 drw_y, - CARD16 drw_w, CARD16 drw_h -){ - int status; - - CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); - - /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ - - UpdateCurrentTime(); - - /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN - INFORM CLIENT OF ITS FAILURE */ - - if (pPort->grab.client && (pPort->grab.client != client)) - { - XvdiSendVideoNotify(pPort, pDraw, XvBusy); - return Success; - } - - status = (* pPort->pAdaptor->ddGetStill)(client, pDraw, pPort, pGC, - vid_x, vid_y, vid_w, vid_h, - drw_x, drw_y, drw_w, drw_h); - - pPort->time = currentTime; - - return status; - -} - -int -XvdiGrabPort( - ClientPtr client, - XvPortPtr pPort, - Time ctime, - int *p_result -){ - unsigned long id; - TimeStamp time; - - UpdateCurrentTime(); - time = ClientTimeToServerTime(ctime); - - if (pPort->grab.client && (client != pPort->grab.client)) - { - *p_result = XvAlreadyGrabbed; - return Success; - } - - if ((CompareTimeStamps(time, currentTime) == LATER) || - (CompareTimeStamps(time, pPort->time) == EARLIER)) - { - *p_result = XvInvalidTime; - return Success; - } - - if (client == pPort->grab.client) - { - *p_result = Success; - return Success; - } - - id = FakeClientID(client->index); - - if (!AddResource(id, XvRTGrab, &pPort->grab)) - { - return BadAlloc; - } - - /* IF THERE IS ACTIVE VIDEO THEN STOP IT */ - - if ((pPort->pDraw) && (client != pPort->client)) - { - XvdiStopVideo(NULL, pPort, pPort->pDraw); - } - - pPort->grab.client = client; - pPort->grab.id = id; - - pPort->time = currentTime; - - *p_result = Success; - - return Success; - -} - -int -XvdiUngrabPort( - ClientPtr client, - XvPortPtr pPort, - Time ctime -){ - TimeStamp time; - - UpdateCurrentTime(); - time = ClientTimeToServerTime(ctime); - - if ((!pPort->grab.client) || (client != pPort->grab.client)) - { - return Success; - } - - if ((CompareTimeStamps(time, currentTime) == LATER) || - (CompareTimeStamps(time, pPort->time) == EARLIER)) - { - return Success; - } - - /* FREE THE GRAB RESOURCE; AND SET THE GRAB CLIENT TO NULL */ - - FreeResource(pPort->grab.id, XvRTGrab); - pPort->grab.client = NULL; - - pPort->time = currentTime; - - return Success; - -} - - -int -XvdiSelectVideoNotify( - ClientPtr client, - DrawablePtr pDraw, - BOOL onoff -){ - XvVideoNotifyPtr pn,tpn,fpn; - int rc; - - /* FIND VideoNotify LIST */ - - rc = dixLookupResourceByType((pointer *)&pn, pDraw->id, XvRTVideoNotifyList, - client, DixWriteAccess); - if (rc != Success && rc != BadValue) - return rc; - - /* IF ONE DONES'T EXIST AND NO MASK, THEN JUST RETURN */ - - if (!onoff && !pn) return Success; - - /* IF ONE DOESN'T EXIST CREATE IT AND ADD A RESOURCE SO THAT THE LIST - WILL BE DELETED WHEN THE DRAWABLE IS DESTROYED */ - - if (!pn) - { - if (!(tpn = malloc(sizeof(XvVideoNotifyRec)))) - return BadAlloc; - tpn->next = NULL; - if (!AddResource(pDraw->id, XvRTVideoNotifyList, tpn)) - { - free(tpn); - return BadAlloc; - } - } - else - { - /* LOOK TO SEE IF ENTRY ALREADY EXISTS */ - - fpn = NULL; - tpn = pn; - while (tpn) - { - if (tpn->client == client) - { - if (!onoff) tpn->client = NULL; - return Success; - } - if (!tpn->client) fpn = tpn; /* TAKE NOTE OF FREE ENTRY */ - tpn = tpn->next; - } - - /* IF TUNNING OFF, THEN JUST RETURN */ - - if (!onoff) return Success; - - /* IF ONE ISN'T FOUND THEN ALLOCATE ONE AND LINK IT INTO THE LIST */ - - if (fpn) - { - tpn = fpn; - } - else - { - if (!(tpn = malloc(sizeof(XvVideoNotifyRec)))) - return BadAlloc; - tpn->next = pn->next; - pn->next = tpn; - } - } - - /* INIT CLIENT PTR IN CASE WE CAN'T ADD RESOURCE */ - /* ADD RESOURCE SO THAT IF CLIENT EXITS THE CLIENT PTR WILL BE CLEARED */ - - tpn->client = NULL; - tpn->id = FakeClientID(client->index); - AddResource(tpn->id, XvRTVideoNotify, tpn); - - tpn->client = client; - return Success; - -} - -int -XvdiSelectPortNotify( - ClientPtr client, - XvPortPtr pPort, - BOOL onoff -){ - XvPortNotifyPtr pn,tpn; - - /* SEE IF CLIENT IS ALREADY IN LIST */ - - tpn = NULL; - pn = pPort->pNotify; - while (pn) - { - if (!pn->client) tpn = pn; /* TAKE NOTE OF FREE ENTRY */ - if (pn->client == client) break; - pn = pn->next; - } - - /* IS THE CLIENT ALREADY ON THE LIST? */ - - if (pn) - { - /* REMOVE IT? */ - - if (!onoff) - { - pn->client = NULL; - FreeResource(pn->id, XvRTPortNotify); - } - - return Success; - } - - /* DIDN'T FIND IT; SO REUSE LIST ELEMENT IF ONE IS FREE OTHERWISE - CREATE A NEW ONE AND ADD IT TO THE BEGINNING OF THE LIST */ - - if (!tpn) - { - if (!(tpn = malloc(sizeof(XvPortNotifyRec)))) - return BadAlloc; - tpn->next = pPort->pNotify; - pPort->pNotify = tpn; - } - - tpn->client = client; - tpn->id = FakeClientID(client->index); - AddResource(tpn->id, XvRTPortNotify, tpn); - - return Success; - -} - -int -XvdiStopVideo( - ClientPtr client, - XvPortPtr pPort, - DrawablePtr pDraw -){ - int status; - - /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ - - if (!pPort->pDraw || (pPort->pDraw != pDraw)) - { - XvdiSendVideoNotify(pPort, pDraw, XvStopped); - return Success; - } - - /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN - INFORM CLIENT OF ITS FAILURE */ - - if ((client) && (pPort->grab.client) && (pPort->grab.client != client)) - { - XvdiSendVideoNotify(pPort, pDraw, XvBusy); - return Success; - } - - XvdiSendVideoNotify(pPort, pDraw, XvStopped); - - status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pDraw); - - pPort->pDraw = NULL; - pPort->client = (ClientPtr)client; - pPort->time = currentTime; - - return status; - -} - -int -XvdiPreemptVideo( - ClientPtr client, - XvPortPtr pPort, - DrawablePtr pDraw -){ - int status; - - /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ - - if (!pPort->pDraw || (pPort->pDraw != pDraw)) return Success; - - XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); - - status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pPort->pDraw); - - pPort->pDraw = NULL; - pPort->client = (ClientPtr)client; - pPort->time = currentTime; - - return status; - -} - -int -XvdiMatchPort( - XvPortPtr pPort, - DrawablePtr pDraw -){ - - XvAdaptorPtr pa; - XvFormatPtr pf; - int nf; - - pa = pPort->pAdaptor; - - if (pa->pScreen != pDraw->pScreen) return BadMatch; - - nf = pa->nFormats; - pf = pa->pFormats; - - while (nf--) - { - if ((pf->depth == pDraw->depth) -#if 0 - && ((pDraw->type == DRAWABLE_PIXMAP) || - (wVisual(((WindowPtr)pDraw)) == pf->visual)) -#endif - ) - return Success; - pf++; - } - - return BadMatch; - -} - -int -XvdiSetPortAttribute( - ClientPtr client, - XvPortPtr pPort, - Atom attribute, - INT32 value -){ - int status; - - status = (* pPort->pAdaptor->ddSetPortAttribute)(client, pPort, attribute, value); - if (status == Success) - XvdiSendPortNotify(pPort, attribute, value); - - return status; -} - -int -XvdiGetPortAttribute( - ClientPtr client, - XvPortPtr pPort, - Atom attribute, - INT32 *p_value -){ - - return - (* pPort->pAdaptor->ddGetPortAttribute)(client, pPort, attribute, p_value); - -} - -static void -WriteSwappedVideoNotifyEvent(xvEvent *from, xvEvent *to) - -{ - - to->u.u.type = from->u.u.type; - to->u.u.detail = from->u.u.detail; - cpswaps(from->u.videoNotify.sequenceNumber, - to->u.videoNotify.sequenceNumber); - cpswapl(from->u.videoNotify.time, to->u.videoNotify.time); - cpswapl(from->u.videoNotify.drawable, to->u.videoNotify.drawable); - cpswapl(from->u.videoNotify.port, to->u.videoNotify.port); - -} - -static void -WriteSwappedPortNotifyEvent(xvEvent *from, xvEvent *to) - -{ - - to->u.u.type = from->u.u.type; - to->u.u.detail = from->u.u.detail; - cpswaps(from->u.portNotify.sequenceNumber, to->u.portNotify.sequenceNumber); - cpswapl(from->u.portNotify.time, to->u.portNotify.time); - cpswapl(from->u.portNotify.port, to->u.portNotify.port); - cpswapl(from->u.portNotify.value, to->u.portNotify.value); - -} +/*********************************************************** +Copyright 1991 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +/* +** File: +** +** xvmain.c --- Xv server extension main device independent module. +** +** Author: +** +** David Carver (Digital Workstation Engineering/Project Athena) +** +** Revisions: +** +** 04.09.91 Carver +** - change: stop video always generates an event even when video +** wasn't active +** +** 29.08.91 Carver +** - change: unrealizing windows no longer preempts video +** +** 11.06.91 Carver +** - changed SetPortControl to SetPortAttribute +** - changed GetPortControl to GetPortAttribute +** - changed QueryBestSize +** +** 28.05.91 Carver +** - fixed Put and Get requests to not preempt operations to same drawable +** +** 15.05.91 Carver +** - version 2.0 upgrade +** +** 19.03.91 Carver +** - fixed Put and Get requests to honor grabbed ports. +** - fixed Video requests to update di structure with new drawable, and +** client after calling ddx. +** +** 24.01.91 Carver +** - version 1.4 upgrade +** +** Notes: +** +** Port structures reference client structures in a two different +** ways: when grabs, or video is active. Each reference is encoded +** as fake client resources and thus when the client is goes away so +** does the reference (it is zeroed). No other action is taken, so +** video doesn't necessarily stop. It probably will as a result of +** other resources going away, but if a client starts video using +** none of its own resources, then the video will continue to play +** after the client disappears. +** +** +*/ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include +#include +#include "misc.h" +#include "os.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "gc.h" +#include "extnsionst.h" +#include "dixstruct.h" +#include "resource.h" +#include "opaque.h" +#include "input.h" + +#define GLOBAL + +#include +#include +#include "xvdix.h" + +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" +#endif +#include "xvdisp.h" + +static DevPrivateKeyRec XvScreenKeyRec; +#define XvScreenKey (&XvScreenKeyRec) +unsigned long XvExtensionGeneration = 0; +unsigned long XvScreenGeneration = 0; +unsigned long XvResourceGeneration = 0; + +int XvReqCode; +int XvEventBase; +int XvErrorBase; + +RESTYPE XvRTPort; +RESTYPE XvRTEncoding; +RESTYPE XvRTGrab; +RESTYPE XvRTVideoNotify; +RESTYPE XvRTVideoNotifyList; +RESTYPE XvRTPortNotify; + +/* EXTERNAL */ + +static void WriteSwappedVideoNotifyEvent(xvEvent *, xvEvent *); +static void WriteSwappedPortNotifyEvent(xvEvent *, xvEvent *); +static Bool CreateResourceTypes(void); + +static Bool XvCloseScreen(int, ScreenPtr); +static Bool XvDestroyPixmap(PixmapPtr); +static Bool XvDestroyWindow(WindowPtr); +static void XvResetProc(ExtensionEntry*); +static int XvdiDestroyGrab(pointer, XID); +static int XvdiDestroyEncoding(pointer, XID); +static int XvdiDestroyVideoNotify(pointer, XID); +static int XvdiDestroyPortNotify(pointer, XID); +static int XvdiDestroyVideoNotifyList(pointer, XID); +static int XvdiDestroyPort(pointer, XID); +static int XvdiSendVideoNotify(XvPortPtr, DrawablePtr, int); + + + + +/* +** XvExtensionInit +** +** +*/ + +void +XvExtensionInit(void) +{ + ExtensionEntry *extEntry; + + if (!dixRegisterPrivateKey(&XvScreenKeyRec, PRIVATE_SCREEN, 0)) + return; + + /* LOOK TO SEE IF ANY SCREENS WERE INITIALIZED; IF NOT THEN + INIT GLOBAL VARIABLES SO THE EXTENSION CAN FUNCTION */ + if (XvScreenGeneration != serverGeneration) + { + if (!CreateResourceTypes()) + { + ErrorF("XvExtensionInit: Unable to allocate resource types\n"); + return; + } +#ifdef PANORAMIX + XineramaRegisterConnectionBlockCallback(XineramifyXv); +#endif + XvScreenGeneration = serverGeneration; + } + + if (XvExtensionGeneration != serverGeneration) + { + XvExtensionGeneration = serverGeneration; + + extEntry = AddExtension(XvName, XvNumEvents, XvNumErrors, + ProcXvDispatch, SProcXvDispatch, + XvResetProc, StandardMinorOpcode); + if (!extEntry) + { + FatalError("XvExtensionInit: AddExtensions failed\n"); + } + + XvReqCode = extEntry->base; + XvEventBase = extEntry->eventBase; + XvErrorBase = extEntry->errorBase; + + EventSwapVector[XvEventBase+XvVideoNotify] = + (EventSwapPtr)WriteSwappedVideoNotifyEvent; + EventSwapVector[XvEventBase+XvPortNotify] = + (EventSwapPtr)WriteSwappedPortNotifyEvent; + + SetResourceTypeErrorValue(XvRTPort, _XvBadPort); + (void)MakeAtom(XvName, strlen(XvName), xTrue); + + } +} + +static Bool +CreateResourceTypes(void) + +{ + + if (XvResourceGeneration == serverGeneration) return TRUE; + + XvResourceGeneration = serverGeneration; + + if (!(XvRTPort = CreateNewResourceType(XvdiDestroyPort, "XvRTPort"))) + { + ErrorF("CreateResourceTypes: failed to allocate port resource.\n"); + return FALSE; + } + + if (!(XvRTGrab = CreateNewResourceType(XvdiDestroyGrab, "XvRTGrab"))) + { + ErrorF("CreateResourceTypes: failed to allocate grab resource.\n"); + return FALSE; + } + + if (!(XvRTEncoding = CreateNewResourceType(XvdiDestroyEncoding, + "XvRTEncoding"))) + { + ErrorF("CreateResourceTypes: failed to allocate encoding resource.\n"); + return FALSE; + } + + if (!(XvRTVideoNotify = CreateNewResourceType(XvdiDestroyVideoNotify, + "XvRTVideoNotify"))) + { + ErrorF("CreateResourceTypes: failed to allocate video notify resource.\n"); + return FALSE; + } + + if (!(XvRTVideoNotifyList = CreateNewResourceType(XvdiDestroyVideoNotifyList, + "XvRTVideoNotifyList"))) + { + ErrorF("CreateResourceTypes: failed to allocate video notify list resource.\n"); + return FALSE; + } + + if (!(XvRTPortNotify = CreateNewResourceType(XvdiDestroyPortNotify, + "XvRTPortNotify"))) + { + ErrorF("CreateResourceTypes: failed to allocate port notify resource.\n"); + return FALSE; + } + + return TRUE; + +} + +int +XvScreenInit(ScreenPtr pScreen) +{ + XvScreenPtr pxvs; + + if (XvScreenGeneration != serverGeneration) + { + if (!CreateResourceTypes()) + { + ErrorF("XvScreenInit: Unable to allocate resource types\n"); + return BadAlloc; + } +#ifdef PANORAMIX + XineramaRegisterConnectionBlockCallback(XineramifyXv); +#endif + XvScreenGeneration = serverGeneration; + } + + if (!dixRegisterPrivateKey(&XvScreenKeyRec, PRIVATE_SCREEN, 0)) + return BadAlloc; + + if (dixLookupPrivate(&pScreen->devPrivates, XvScreenKey)) + { + ErrorF("XvScreenInit: screen devPrivates ptr non-NULL before init\n"); + } + + /* ALLOCATE SCREEN PRIVATE RECORD */ + + pxvs = malloc(sizeof (XvScreenRec)); + if (!pxvs) + { + ErrorF("XvScreenInit: Unable to allocate screen private structure\n"); + return BadAlloc; + } + + dixSetPrivate(&pScreen->devPrivates, XvScreenKey, pxvs); + + pxvs->DestroyPixmap = pScreen->DestroyPixmap; + pxvs->DestroyWindow = pScreen->DestroyWindow; + pxvs->CloseScreen = pScreen->CloseScreen; + + pScreen->DestroyPixmap = XvDestroyPixmap; + pScreen->DestroyWindow = XvDestroyWindow; + pScreen->CloseScreen = XvCloseScreen; + + return Success; +} + +static Bool +XvCloseScreen( + int ii, + ScreenPtr pScreen +){ + + XvScreenPtr pxvs; + + pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); + + pScreen->DestroyPixmap = pxvs->DestroyPixmap; + pScreen->DestroyWindow = pxvs->DestroyWindow; + pScreen->CloseScreen = pxvs->CloseScreen; + + (* pxvs->ddCloseScreen)(ii, pScreen); + + free(pxvs); + + dixSetPrivate(&pScreen->devPrivates, XvScreenKey, NULL); + + return (*pScreen->CloseScreen)(ii, pScreen); +} + +static void +XvResetProc(ExtensionEntry* extEntry) +{ + XvResetProcVector(); +} + +DevPrivateKey +XvGetScreenKey(void) +{ + return XvScreenKey; +} + +unsigned long +XvGetRTPort(void) +{ + return XvRTPort; +} + +static Bool +XvDestroyPixmap(PixmapPtr pPix) +{ + Bool status; + ScreenPtr pScreen; + XvScreenPtr pxvs; + XvAdaptorPtr pa; + int na; + XvPortPtr pp; + int np; + + pScreen = pPix->drawable.pScreen; + + SCREEN_PROLOGUE(pScreen, DestroyPixmap); + + pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); + + /* CHECK TO SEE IF THIS PORT IS IN USE */ + + pa = pxvs->pAdaptors; + na = pxvs->nAdaptors; + while (na--) + { + np = pa->nPorts; + pp = pa->pPorts; + + while (np--) + { + if (pp->pDraw == (DrawablePtr)pPix) + { + XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted); + + (void)(* pp->pAdaptor->ddStopVideo)(NULL, pp, pp->pDraw); + + pp->pDraw = NULL; + pp->client = NULL; + pp->time = currentTime; + } + pp++; + } + pa++; + } + + status = (* pScreen->DestroyPixmap)(pPix); + + SCREEN_EPILOGUE(pScreen, DestroyPixmap, XvDestroyPixmap); + + return status; + +} + +static Bool +XvDestroyWindow(WindowPtr pWin) +{ + Bool status; + ScreenPtr pScreen; + XvScreenPtr pxvs; + XvAdaptorPtr pa; + int na; + XvPortPtr pp; + int np; + + pScreen = pWin->drawable.pScreen; + + SCREEN_PROLOGUE(pScreen, DestroyWindow); + + pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XvScreenKey); + + /* CHECK TO SEE IF THIS PORT IS IN USE */ + + pa = pxvs->pAdaptors; + na = pxvs->nAdaptors; + while (na--) + { + np = pa->nPorts; + pp = pa->pPorts; + + while (np--) + { + if (pp->pDraw == (DrawablePtr)pWin) + { + XvdiSendVideoNotify(pp, pp->pDraw, XvPreempted); + + (void)(* pp->pAdaptor->ddStopVideo)(NULL, pp, pp->pDraw); + + pp->pDraw = NULL; + pp->client = NULL; + pp->time = currentTime; + } + pp++; + } + pa++; + } + + + status = (* pScreen->DestroyWindow)(pWin); + + SCREEN_EPILOGUE(pScreen, DestroyWindow, XvDestroyWindow); + + return status; + +} + +/* The XvdiVideoStopped procedure is a hook for the device dependent layer. + It provides a way for the dd layer to inform the di layer that video has + stopped in a port for reasons that the di layer had no control over; note + that it doesn't call back into the dd layer */ + +int +XvdiVideoStopped(XvPortPtr pPort, int reason) +{ + + /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ + + if (!pPort->pDraw) return Success; + + XvdiSendVideoNotify(pPort, pPort->pDraw, reason); + + pPort->pDraw = NULL; + pPort->client = NULL; + pPort->time = currentTime; + + return Success; + +} + +static int +XvdiDestroyPort(pointer pPort, XID id) +{ + return (* ((XvPortPtr)pPort)->pAdaptor->ddFreePort)(pPort); +} + +static int +XvdiDestroyGrab(pointer pGrab, XID id) +{ + ((XvGrabPtr)pGrab)->client = NULL; + return Success; +} + +static int +XvdiDestroyVideoNotify(pointer pn, XID id) +{ + /* JUST CLEAR OUT THE client POINTER FIELD */ + + ((XvVideoNotifyPtr)pn)->client = NULL; + return Success; +} + +static int +XvdiDestroyPortNotify(pointer pn, XID id) +{ + /* JUST CLEAR OUT THE client POINTER FIELD */ + + ((XvPortNotifyPtr)pn)->client = NULL; + return Success; +} + +static int +XvdiDestroyVideoNotifyList(pointer pn, XID id) +{ + XvVideoNotifyPtr npn,cpn; + + /* ACTUALLY DESTROY THE NOTITY LIST */ + + cpn = (XvVideoNotifyPtr)pn; + + while (cpn) + { + npn = cpn->next; + if (cpn->client) FreeResource(cpn->id, XvRTVideoNotify); + free(cpn); + cpn = npn; + } + return Success; +} + +static int +XvdiDestroyEncoding(pointer value, XID id) +{ + return Success; +} + +static int +XvdiSendVideoNotify(XvPortPtr pPort, DrawablePtr pDraw, int reason) +{ + xvEvent event; + XvVideoNotifyPtr pn; + + dixLookupResourceByType((pointer *)&pn, pDraw->id, XvRTVideoNotifyList, + serverClient, DixReadAccess); + + while (pn) + { + event.u.u.type = XvEventBase + XvVideoNotify; + event.u.videoNotify.time = currentTime.milliseconds; + event.u.videoNotify.drawable = pDraw->id; + event.u.videoNotify.port = pPort->id; + event.u.videoNotify.reason = reason; + WriteEventsToClient(pn->client, 1, (xEventPtr)&event); + pn = pn->next; + } + + return Success; + +} + + +int +XvdiSendPortNotify( + XvPortPtr pPort, + Atom attribute, + INT32 value +){ + xvEvent event; + XvPortNotifyPtr pn; + + pn = pPort->pNotify; + + while (pn) + { + event.u.u.type = XvEventBase + XvPortNotify; + event.u.portNotify.time = currentTime.milliseconds; + event.u.portNotify.port = pPort->id; + event.u.portNotify.attribute = attribute; + event.u.portNotify.value = value; + WriteEventsToClient(pn->client, 1, (xEventPtr)&event); + pn = pn->next; + } + + return Success; + +} + + +#define CHECK_SIZE(dw, dh, sw, sh) { \ + if(!dw || !dh || !sw || !sh) return Success; \ + /* The region code will break these if they are too large */ \ + if((dw > 32767) || (dh > 32767) || (sw > 32767) || (sh > 32767)) \ + return BadValue; \ +} + + +int +XvdiPutVideo( + ClientPtr client, + DrawablePtr pDraw, + XvPortPtr pPort, + GCPtr pGC, + INT16 vid_x, INT16 vid_y, + CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, + CARD16 drw_w, CARD16 drw_h +){ + DrawablePtr pOldDraw; + + CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); + + /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ + + UpdateCurrentTime(); + + /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN + INFORM CLIENT OF ITS FAILURE */ + + if (pPort->grab.client && (pPort->grab.client != client)) + { + XvdiSendVideoNotify(pPort, pDraw, XvBusy); + return Success; + } + + /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED + EVENTS TO ANY CLIENTS WHO WANT THEM */ + + pOldDraw = pPort->pDraw; + if ((pOldDraw) && (pOldDraw != pDraw)) + { + XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); + } + + (void) (* pPort->pAdaptor->ddPutVideo)(client, pDraw, pPort, pGC, + vid_x, vid_y, vid_w, vid_h, + drw_x, drw_y, drw_w, drw_h); + + if ((pPort->pDraw) && (pOldDraw != pDraw)) + { + pPort->client = client; + XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted); + } + + pPort->time = currentTime; + + return Success; + +} + +int +XvdiPutStill( + ClientPtr client, + DrawablePtr pDraw, + XvPortPtr pPort, + GCPtr pGC, + INT16 vid_x, INT16 vid_y, + CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, + CARD16 drw_w, CARD16 drw_h +){ + int status; + + CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); + + /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ + + UpdateCurrentTime(); + + /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN + INFORM CLIENT OF ITS FAILURE */ + + if (pPort->grab.client && (pPort->grab.client != client)) + { + XvdiSendVideoNotify(pPort, pDraw, XvBusy); + return Success; + } + + pPort->time = currentTime; + + status = (* pPort->pAdaptor->ddPutStill)(client, pDraw, pPort, pGC, + vid_x, vid_y, vid_w, vid_h, + drw_x, drw_y, drw_w, drw_h); + + return status; + +} + +int +XvdiPutImage( + ClientPtr client, + DrawablePtr pDraw, + XvPortPtr pPort, + GCPtr pGC, + INT16 src_x, INT16 src_y, + CARD16 src_w, CARD16 src_h, + INT16 drw_x, INT16 drw_y, + CARD16 drw_w, CARD16 drw_h, + XvImagePtr image, + unsigned char* data, + Bool sync, + CARD16 width, CARD16 height +){ + CHECK_SIZE(drw_w, drw_h, src_w, src_h); + + /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ + + UpdateCurrentTime(); + + /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN + INFORM CLIENT OF ITS FAILURE */ + + if (pPort->grab.client && (pPort->grab.client != client)) + { + XvdiSendVideoNotify(pPort, pDraw, XvBusy); + return Success; + } + + pPort->time = currentTime; + + return (* pPort->pAdaptor->ddPutImage)(client, pDraw, pPort, pGC, + src_x, src_y, src_w, src_h, + drw_x, drw_y, drw_w, drw_h, + image, data, sync, width, height); +} + + +int +XvdiGetVideo( + ClientPtr client, + DrawablePtr pDraw, + XvPortPtr pPort, + GCPtr pGC, + INT16 vid_x, INT16 vid_y, + CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, + CARD16 drw_w, CARD16 drw_h +){ + DrawablePtr pOldDraw; + + CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); + + /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ + + UpdateCurrentTime(); + + /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN + INFORM CLIENT OF ITS FAILURE */ + + if (pPort->grab.client && (pPort->grab.client != client)) + { + XvdiSendVideoNotify(pPort, pDraw, XvBusy); + return Success; + } + + /* CHECK TO SEE IF PORT IS IN USE; IF SO THEN WE MUST DELIVER INTERRUPTED + EVENTS TO ANY CLIENTS WHO WANT THEM */ + + pOldDraw = pPort->pDraw; + if ((pOldDraw) && (pOldDraw != pDraw)) + { + XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); + } + + (void) (* pPort->pAdaptor->ddGetVideo)(client, pDraw, pPort, pGC, + vid_x, vid_y, vid_w, vid_h, + drw_x, drw_y, drw_w, drw_h); + + if ((pPort->pDraw) && (pOldDraw != pDraw)) + { + pPort->client = client; + XvdiSendVideoNotify(pPort, pPort->pDraw, XvStarted); + } + + pPort->time = currentTime; + + return Success; + +} + +int +XvdiGetStill( + ClientPtr client, + DrawablePtr pDraw, + XvPortPtr pPort, + GCPtr pGC, + INT16 vid_x, INT16 vid_y, + CARD16 vid_w, CARD16 vid_h, + INT16 drw_x, INT16 drw_y, + CARD16 drw_w, CARD16 drw_h +){ + int status; + + CHECK_SIZE(drw_w, drw_h, vid_w, vid_h); + + /* UPDATE TIME VARIABLES FOR USE IN EVENTS */ + + UpdateCurrentTime(); + + /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN + INFORM CLIENT OF ITS FAILURE */ + + if (pPort->grab.client && (pPort->grab.client != client)) + { + XvdiSendVideoNotify(pPort, pDraw, XvBusy); + return Success; + } + + status = (* pPort->pAdaptor->ddGetStill)(client, pDraw, pPort, pGC, + vid_x, vid_y, vid_w, vid_h, + drw_x, drw_y, drw_w, drw_h); + + pPort->time = currentTime; + + return status; + +} + +int +XvdiGrabPort( + ClientPtr client, + XvPortPtr pPort, + Time ctime, + int *p_result +){ + unsigned long id; + TimeStamp time; + + UpdateCurrentTime(); + time = ClientTimeToServerTime(ctime); + + if (pPort->grab.client && (client != pPort->grab.client)) + { + *p_result = XvAlreadyGrabbed; + return Success; + } + + if ((CompareTimeStamps(time, currentTime) == LATER) || + (CompareTimeStamps(time, pPort->time) == EARLIER)) + { + *p_result = XvInvalidTime; + return Success; + } + + if (client == pPort->grab.client) + { + *p_result = Success; + return Success; + } + + id = FakeClientID(client->index); + + if (!AddResource(id, XvRTGrab, &pPort->grab)) + { + return BadAlloc; + } + + /* IF THERE IS ACTIVE VIDEO THEN STOP IT */ + + if ((pPort->pDraw) && (client != pPort->client)) + { + XvdiStopVideo(NULL, pPort, pPort->pDraw); + } + + pPort->grab.client = client; + pPort->grab.id = id; + + pPort->time = currentTime; + + *p_result = Success; + + return Success; + +} + +int +XvdiUngrabPort( + ClientPtr client, + XvPortPtr pPort, + Time ctime +){ + TimeStamp time; + + UpdateCurrentTime(); + time = ClientTimeToServerTime(ctime); + + if ((!pPort->grab.client) || (client != pPort->grab.client)) + { + return Success; + } + + if ((CompareTimeStamps(time, currentTime) == LATER) || + (CompareTimeStamps(time, pPort->time) == EARLIER)) + { + return Success; + } + + /* FREE THE GRAB RESOURCE; AND SET THE GRAB CLIENT TO NULL */ + + FreeResource(pPort->grab.id, XvRTGrab); + pPort->grab.client = NULL; + + pPort->time = currentTime; + + return Success; + +} + + +int +XvdiSelectVideoNotify( + ClientPtr client, + DrawablePtr pDraw, + BOOL onoff +){ + XvVideoNotifyPtr pn,tpn,fpn; + int rc; + + /* FIND VideoNotify LIST */ + + rc = dixLookupResourceByType((pointer *)&pn, pDraw->id, XvRTVideoNotifyList, + client, DixWriteAccess); + if (rc != Success && rc != BadValue) + return rc; + + /* IF ONE DONES'T EXIST AND NO MASK, THEN JUST RETURN */ + + if (!onoff && !pn) return Success; + + /* IF ONE DOESN'T EXIST CREATE IT AND ADD A RESOURCE SO THAT THE LIST + WILL BE DELETED WHEN THE DRAWABLE IS DESTROYED */ + + if (!pn) + { + if (!(tpn = malloc(sizeof(XvVideoNotifyRec)))) + return BadAlloc; + tpn->next = NULL; + if (!AddResource(pDraw->id, XvRTVideoNotifyList, tpn)) + { + free(tpn); + return BadAlloc; + } + } + else + { + /* LOOK TO SEE IF ENTRY ALREADY EXISTS */ + + fpn = NULL; + tpn = pn; + while (tpn) + { + if (tpn->client == client) + { + if (!onoff) tpn->client = NULL; + return Success; + } + if (!tpn->client) fpn = tpn; /* TAKE NOTE OF FREE ENTRY */ + tpn = tpn->next; + } + + /* IF TUNNING OFF, THEN JUST RETURN */ + + if (!onoff) return Success; + + /* IF ONE ISN'T FOUND THEN ALLOCATE ONE AND LINK IT INTO THE LIST */ + + if (fpn) + { + tpn = fpn; + } + else + { + if (!(tpn = malloc(sizeof(XvVideoNotifyRec)))) + return BadAlloc; + tpn->next = pn->next; + pn->next = tpn; + } + } + + /* INIT CLIENT PTR IN CASE WE CAN'T ADD RESOURCE */ + /* ADD RESOURCE SO THAT IF CLIENT EXITS THE CLIENT PTR WILL BE CLEARED */ + + tpn->client = NULL; + tpn->id = FakeClientID(client->index); + AddResource(tpn->id, XvRTVideoNotify, tpn); + + tpn->client = client; + return Success; + +} + +int +XvdiSelectPortNotify( + ClientPtr client, + XvPortPtr pPort, + BOOL onoff +){ + XvPortNotifyPtr pn,tpn; + + /* SEE IF CLIENT IS ALREADY IN LIST */ + + tpn = NULL; + pn = pPort->pNotify; + while (pn) + { + if (!pn->client) tpn = pn; /* TAKE NOTE OF FREE ENTRY */ + if (pn->client == client) break; + pn = pn->next; + } + + /* IS THE CLIENT ALREADY ON THE LIST? */ + + if (pn) + { + /* REMOVE IT? */ + + if (!onoff) + { + pn->client = NULL; + FreeResource(pn->id, XvRTPortNotify); + } + + return Success; + } + + /* DIDN'T FIND IT; SO REUSE LIST ELEMENT IF ONE IS FREE OTHERWISE + CREATE A NEW ONE AND ADD IT TO THE BEGINNING OF THE LIST */ + + if (!tpn) + { + if (!(tpn = malloc(sizeof(XvPortNotifyRec)))) + return BadAlloc; + tpn->next = pPort->pNotify; + pPort->pNotify = tpn; + } + + tpn->client = client; + tpn->id = FakeClientID(client->index); + AddResource(tpn->id, XvRTPortNotify, tpn); + + return Success; + +} + +int +XvdiStopVideo( + ClientPtr client, + XvPortPtr pPort, + DrawablePtr pDraw +){ + int status; + + /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ + + if (!pPort->pDraw || (pPort->pDraw != pDraw)) + { + XvdiSendVideoNotify(pPort, pDraw, XvStopped); + return Success; + } + + /* CHECK FOR GRAB; IF THIS CLIENT DOESN'T HAVE THE PORT GRABBED THEN + INFORM CLIENT OF ITS FAILURE */ + + if ((client) && (pPort->grab.client) && (pPort->grab.client != client)) + { + XvdiSendVideoNotify(pPort, pDraw, XvBusy); + return Success; + } + + XvdiSendVideoNotify(pPort, pDraw, XvStopped); + + status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pDraw); + + pPort->pDraw = NULL; + pPort->client = (ClientPtr)client; + pPort->time = currentTime; + + return status; + +} + +int +XvdiPreemptVideo( + ClientPtr client, + XvPortPtr pPort, + DrawablePtr pDraw +){ + int status; + + /* IF PORT ISN'T ACTIVE THEN WE'RE DONE */ + + if (!pPort->pDraw || (pPort->pDraw != pDraw)) return Success; + + XvdiSendVideoNotify(pPort, pPort->pDraw, XvPreempted); + + status = (* pPort->pAdaptor->ddStopVideo)(client, pPort, pPort->pDraw); + + pPort->pDraw = NULL; + pPort->client = (ClientPtr)client; + pPort->time = currentTime; + + return status; + +} + +int +XvdiMatchPort( + XvPortPtr pPort, + DrawablePtr pDraw +){ + + XvAdaptorPtr pa; + XvFormatPtr pf; + int nf; + + pa = pPort->pAdaptor; + + if (pa->pScreen != pDraw->pScreen) return BadMatch; + + nf = pa->nFormats; + pf = pa->pFormats; + + while (nf--) + { + if ((pf->depth == pDraw->depth) +#if 0 + && ((pDraw->type == DRAWABLE_PIXMAP) || + (wVisual(((WindowPtr)pDraw)) == pf->visual)) +#endif + ) + return Success; + pf++; + } + + return BadMatch; + +} + +int +XvdiSetPortAttribute( + ClientPtr client, + XvPortPtr pPort, + Atom attribute, + INT32 value +){ + int status; + + status = (* pPort->pAdaptor->ddSetPortAttribute)(client, pPort, attribute, value); + if (status == Success) + XvdiSendPortNotify(pPort, attribute, value); + + return status; +} + +int +XvdiGetPortAttribute( + ClientPtr client, + XvPortPtr pPort, + Atom attribute, + INT32 *p_value +){ + + return + (* pPort->pAdaptor->ddGetPortAttribute)(client, pPort, attribute, p_value); + +} + +static void +WriteSwappedVideoNotifyEvent(xvEvent *from, xvEvent *to) + +{ + + to->u.u.type = from->u.u.type; + to->u.u.detail = from->u.u.detail; + cpswaps(from->u.videoNotify.sequenceNumber, + to->u.videoNotify.sequenceNumber); + cpswapl(from->u.videoNotify.time, to->u.videoNotify.time); + cpswapl(from->u.videoNotify.drawable, to->u.videoNotify.drawable); + cpswapl(from->u.videoNotify.port, to->u.videoNotify.port); + +} + +static void +WriteSwappedPortNotifyEvent(xvEvent *from, xvEvent *to) + +{ + + to->u.u.type = from->u.u.type; + to->u.u.detail = from->u.u.detail; + cpswaps(from->u.portNotify.sequenceNumber, to->u.portNotify.sequenceNumber); + cpswapl(from->u.portNotify.time, to->u.portNotify.time); + cpswapl(from->u.portNotify.port, to->u.portNotify.port); + cpswapl(from->u.portNotify.value, to->u.portNotify.value); + +} diff --git a/xorg-server/Xext/xvmc.c b/xorg-server/Xext/xvmc.c index 9b9dd0bc2..4d29941ee 100644 --- a/xorg-server/Xext/xvmc.c +++ b/xorg-server/Xext/xvmc.c @@ -1,789 +1,789 @@ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include - -#include -#include -#include "misc.h" -#include "os.h" -#include "dixstruct.h" -#include "resource.h" -#include "scrnintstr.h" -#include "extnsionst.h" -#include "servermd.h" -#include -#include "xvdix.h" -#include -#include -#include -#include "xvmcext.h" -#include "protocol-versions.h" - -#ifdef HAS_XVMCSHM -#include -#include -#include -#endif /* HAS_XVMCSHM */ - - - -#define DR_CLIENT_DRIVER_NAME_SIZE 48 -#define DR_BUSID_SIZE 48 - -static DevPrivateKeyRec XvMCScreenKeyRec; -#define XvMCScreenKey (&XvMCScreenKeyRec) -static Bool XvMCInUse; - -unsigned long XvMCGeneration = 0; - -int XvMCReqCode; -int XvMCEventBase; - -unsigned long XvMCRTContext; -unsigned long XvMCRTSurface; -unsigned long XvMCRTSubpicture; - -typedef struct { - int num_adaptors; - XvMCAdaptorPtr adaptors; - CloseScreenProcPtr CloseScreen; - char clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE]; - char busID[DR_BUSID_SIZE]; - int major; - int minor; - int patchLevel; -} XvMCScreenRec, *XvMCScreenPtr; - -#define XVMC_GET_PRIVATE(pScreen) \ - (XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates, XvMCScreenKey)) - - -static int -XvMCDestroyContextRes(pointer data, XID id) -{ - XvMCContextPtr pContext = (XvMCContextPtr)data; - - pContext->refcnt--; - - if(!pContext->refcnt) { - XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); - (*pScreenPriv->adaptors[pContext->adapt_num].DestroyContext)(pContext); - free(pContext); - } - - return Success; -} - -static int -XvMCDestroySurfaceRes(pointer data, XID id) -{ - XvMCSurfacePtr pSurface = (XvMCSurfacePtr)data; - XvMCContextPtr pContext = pSurface->context; - XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); - - (*pScreenPriv->adaptors[pContext->adapt_num].DestroySurface)(pSurface); - free(pSurface); - - XvMCDestroyContextRes((pointer)pContext, pContext->context_id); - - return Success; -} - - -static int -XvMCDestroySubpictureRes(pointer data, XID id) -{ - XvMCSubpicturePtr pSubpict = (XvMCSubpicturePtr)data; - XvMCContextPtr pContext = pSubpict->context; - XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); - - (*pScreenPriv->adaptors[pContext->adapt_num].DestroySubpicture)(pSubpict); - free(pSubpict); - - XvMCDestroyContextRes((pointer)pContext, pContext->context_id); - - return Success; -} - -static int -ProcXvMCQueryVersion(ClientPtr client) -{ - xvmcQueryVersionReply rep; - /* REQUEST(xvmcQueryVersionReq); */ - REQUEST_SIZE_MATCH(xvmcQueryVersionReq); - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.major = SERVER_XVMC_MAJOR_VERSION; - rep.minor = SERVER_XVMC_MINOR_VERSION; - WriteToClient(client, sizeof(xvmcQueryVersionReply), (char*)&rep); - return Success; -} - - -static int -ProcXvMCListSurfaceTypes(ClientPtr client) -{ - XvPortPtr pPort; - int i; - XvMCScreenPtr pScreenPriv; - xvmcListSurfaceTypesReply rep; - xvmcSurfaceInfo info; - XvMCAdaptorPtr adaptor = NULL; - XvMCSurfaceInfoPtr surface; - REQUEST(xvmcListSurfaceTypesReq); - REQUEST_SIZE_MATCH(xvmcListSurfaceTypesReq); - - VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); - - if(XvMCInUse) { /* any adaptors at all */ - ScreenPtr pScreen = pPort->pAdaptor->pScreen; - if((pScreenPriv = XVMC_GET_PRIVATE(pScreen))) { /* any this screen */ - for(i = 0; i < pScreenPriv->num_adaptors; i++) { - if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { - adaptor = &(pScreenPriv->adaptors[i]); - break; - } - } - } - } - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.num = (adaptor) ? adaptor->num_surfaces : 0; - rep.length = bytes_to_int32(rep.num * sizeof(xvmcSurfaceInfo)); - - WriteToClient(client, sizeof(xvmcListSurfaceTypesReply), (char*)&rep); - - for(i = 0; i < rep.num; i++) { - surface = adaptor->surfaces[i]; - info.surface_type_id = surface->surface_type_id; - info.chroma_format = surface->chroma_format; - info.max_width = surface->max_width; - info.max_height = surface->max_height; - info.subpicture_max_width = surface->subpicture_max_width; - info.subpicture_max_height = surface->subpicture_max_height; - info.mc_type = surface->mc_type; - info.flags = surface->flags; - WriteToClient(client, sizeof(xvmcSurfaceInfo), (char*)&info); - } - - return Success; -} - -static int -ProcXvMCCreateContext(ClientPtr client) -{ - XvPortPtr pPort; - CARD32 *data = NULL; - int dwords = 0; - int i, result, adapt_num = -1; - ScreenPtr pScreen; - XvMCContextPtr pContext; - XvMCScreenPtr pScreenPriv; - XvMCAdaptorPtr adaptor = NULL; - XvMCSurfaceInfoPtr surface = NULL; - xvmcCreateContextReply rep; - REQUEST(xvmcCreateContextReq); - REQUEST_SIZE_MATCH(xvmcCreateContextReq); - - VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); - - pScreen = pPort->pAdaptor->pScreen; - - if(!XvMCInUse) /* no XvMC adaptors */ - return BadMatch; - - if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) /* none this screen */ - return BadMatch; - - for(i = 0; i < pScreenPriv->num_adaptors; i++) { - if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { - adaptor = &(pScreenPriv->adaptors[i]); - adapt_num = i; - break; - } - } - - if(adapt_num < 0) /* none this port */ - return BadMatch; - - for(i = 0; i < adaptor->num_surfaces; i++) { - if(adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) { - surface = adaptor->surfaces[i]; - break; - } - } - - /* adaptor doesn't support this suface_type_id */ - if(!surface) return BadMatch; - - - if((stuff->width > surface->max_width) || - (stuff->height > surface->max_height)) - return BadValue; - - if(!(pContext = malloc(sizeof(XvMCContextRec)))) { - return BadAlloc; - } - - - pContext->pScreen = pScreen; - pContext->adapt_num = adapt_num; - pContext->context_id = stuff->context_id; - pContext->surface_type_id = stuff->surface_type_id; - pContext->width = stuff->width; - pContext->height = stuff->height; - pContext->flags = stuff->flags; - pContext->refcnt = 1; - - result = (*adaptor->CreateContext)(pPort, pContext, &dwords, &data); - - if(result != Success) { - free(pContext); - return result; - } - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.width_actual = pContext->width; - rep.height_actual = pContext->height; - rep.flags_return = pContext->flags; - rep.length = dwords; - - WriteToClient(client, sizeof(xvmcCreateContextReply), (char*)&rep); - if(dwords) - WriteToClient(client, dwords << 2, (char*)data); - AddResource(pContext->context_id, XvMCRTContext, pContext); - - free(data); - - return Success; -} - -static int -ProcXvMCDestroyContext(ClientPtr client) -{ - pointer val; - int rc; - REQUEST(xvmcDestroyContextReq); - REQUEST_SIZE_MATCH(xvmcDestroyContextReq); - - rc = dixLookupResourceByType(&val, stuff->context_id, XvMCRTContext, - client, DixDestroyAccess); - if (rc != Success) - return rc; - - FreeResource(stuff->context_id, RT_NONE); - - return Success; -} - -static int -ProcXvMCCreateSurface(ClientPtr client) -{ - CARD32 *data = NULL; - int dwords = 0; - int result; - XvMCContextPtr pContext; - XvMCSurfacePtr pSurface; - XvMCScreenPtr pScreenPriv; - xvmcCreateSurfaceReply rep; - REQUEST(xvmcCreateSurfaceReq); - REQUEST_SIZE_MATCH(xvmcCreateSurfaceReq); - - result = dixLookupResourceByType((pointer *)&pContext, stuff->context_id, - XvMCRTContext, client, DixUseAccess); - if (result != Success) - return result; - - pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); - - if(!(pSurface = malloc(sizeof(XvMCSurfaceRec)))) - return BadAlloc; - - pSurface->surface_id = stuff->surface_id; - pSurface->surface_type_id = pContext->surface_type_id; - pSurface->context = pContext; - - result = (*pScreenPriv->adaptors[pContext->adapt_num].CreateSurface)( - pSurface, &dwords, &data); - - if(result != Success) { - free(pSurface); - return result; - } - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = dwords; - - WriteToClient(client, sizeof(xvmcCreateSurfaceReply), (char*)&rep); - if(dwords) - WriteToClient(client, dwords << 2, (char*)data); - AddResource(pSurface->surface_id, XvMCRTSurface, pSurface); - - free(data); - - pContext->refcnt++; - - return Success; -} - -static int -ProcXvMCDestroySurface(ClientPtr client) -{ - pointer val; - int rc; - REQUEST(xvmcDestroySurfaceReq); - REQUEST_SIZE_MATCH(xvmcDestroySurfaceReq); - - rc = dixLookupResourceByType(&val, stuff->surface_id, XvMCRTSurface, - client, DixDestroyAccess); - if (rc != Success) - return rc; - - FreeResource(stuff->surface_id, RT_NONE); - - return Success; -} - -static int -ProcXvMCCreateSubpicture(ClientPtr client) -{ - Bool image_supported = FALSE; - CARD32 *data = NULL; - int i, result, dwords = 0; - XvMCContextPtr pContext; - XvMCSubpicturePtr pSubpicture; - XvMCScreenPtr pScreenPriv; - xvmcCreateSubpictureReply rep; - XvMCAdaptorPtr adaptor; - XvMCSurfaceInfoPtr surface = NULL; - REQUEST(xvmcCreateSubpictureReq); - REQUEST_SIZE_MATCH(xvmcCreateSubpictureReq); - - result = dixLookupResourceByType((pointer *)&pContext, stuff->context_id, - XvMCRTContext, client, DixUseAccess); - if (result != Success) - return result; - - pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); - - adaptor = &(pScreenPriv->adaptors[pContext->adapt_num]); - - /* find which surface this context supports */ - for(i = 0; i < adaptor->num_surfaces; i++) { - if(adaptor->surfaces[i]->surface_type_id == pContext->surface_type_id){ - surface = adaptor->surfaces[i]; - break; - } - } - - if(!surface) return BadMatch; - - /* make sure this surface supports that xvimage format */ - if(!surface->compatible_subpictures) return BadMatch; - - for(i = 0; i < surface->compatible_subpictures->num_xvimages; i++) { - if(surface->compatible_subpictures->xvimage_ids[i] == stuff->xvimage_id) { - image_supported = TRUE; - break; - } - } - - if(!image_supported) return BadMatch; - - /* make sure the size is OK */ - if((stuff->width > surface->subpicture_max_width) || - (stuff->height > surface->subpicture_max_height)) - return BadValue; - - if(!(pSubpicture = malloc(sizeof(XvMCSubpictureRec)))) - return BadAlloc; - - pSubpicture->subpicture_id = stuff->subpicture_id; - pSubpicture->xvimage_id = stuff->xvimage_id; - pSubpicture->width = stuff->width; - pSubpicture->height = stuff->height; - pSubpicture->num_palette_entries = 0; /* overwritten by DDX */ - pSubpicture->entry_bytes = 0; /* overwritten by DDX */ - pSubpicture->component_order[0] = 0; /* overwritten by DDX */ - pSubpicture->component_order[1] = 0; - pSubpicture->component_order[2] = 0; - pSubpicture->component_order[3] = 0; - pSubpicture->context = pContext; - - result = (*pScreenPriv->adaptors[pContext->adapt_num].CreateSubpicture)( - pSubpicture, &dwords, &data); - - if(result != Success) { - free(pSubpicture); - return result; - } - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.width_actual = pSubpicture->width; - rep.height_actual = pSubpicture->height; - rep.num_palette_entries = pSubpicture->num_palette_entries; - rep.entry_bytes = pSubpicture->entry_bytes; - rep.component_order[0] = pSubpicture->component_order[0]; - rep.component_order[1] = pSubpicture->component_order[1]; - rep.component_order[2] = pSubpicture->component_order[2]; - rep.component_order[3] = pSubpicture->component_order[3]; - rep.length = dwords; - - WriteToClient(client, sizeof(xvmcCreateSubpictureReply), (char*)&rep); - if(dwords) - WriteToClient(client, dwords << 2, (char*)data); - AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture); - - free(data); - - pContext->refcnt++; - - return Success; -} - -static int -ProcXvMCDestroySubpicture(ClientPtr client) -{ - pointer val; - int rc; - REQUEST(xvmcDestroySubpictureReq); - REQUEST_SIZE_MATCH(xvmcDestroySubpictureReq); - - rc = dixLookupResourceByType(&val, stuff->subpicture_id, XvMCRTSubpicture, - client, DixDestroyAccess); - if (rc != Success) - return rc; - - FreeResource(stuff->subpicture_id, RT_NONE); - - return Success; -} - - -static int -ProcXvMCListSubpictureTypes(ClientPtr client) -{ - XvPortPtr pPort; - xvmcListSubpictureTypesReply rep; - XvMCScreenPtr pScreenPriv; - ScreenPtr pScreen; - XvMCAdaptorPtr adaptor = NULL; - XvMCSurfaceInfoPtr surface = NULL; - xvImageFormatInfo info; - XvImagePtr pImage; - int i, j; - REQUEST(xvmcListSubpictureTypesReq); - REQUEST_SIZE_MATCH(xvmcListSubpictureTypesReq); - - VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); - - pScreen = pPort->pAdaptor->pScreen; - - if(XvMCScreenKey == NULL) /* No XvMC adaptors */ - return BadMatch; - - if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) - return BadMatch; /* None this screen */ - - for(i = 0; i < pScreenPriv->num_adaptors; i++) { - if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { - adaptor = &(pScreenPriv->adaptors[i]); - break; - } - } - - if(!adaptor) return BadMatch; - - for(i = 0; i < adaptor->num_surfaces; i++) { - if(adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) { - surface = adaptor->surfaces[i]; - break; - } - } - - if(!surface) return BadMatch; - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.num = 0; - if(surface->compatible_subpictures) - rep.num = surface->compatible_subpictures->num_xvimages; - - rep.length = bytes_to_int32(rep.num * sizeof(xvImageFormatInfo)); - - WriteToClient(client, sizeof(xvmcListSubpictureTypesReply), (char*)&rep); - - for(i = 0; i < rep.num; i++) { - pImage = NULL; - for(j = 0; j < adaptor->num_subpictures; j++) { - if(surface->compatible_subpictures->xvimage_ids[i] == - adaptor->subpictures[j]->id) - { - pImage = adaptor->subpictures[j]; - break; - } - } - if(!pImage) return BadImplementation; - - info.id = pImage->id; - info.type = pImage->type; - info.byte_order = pImage->byte_order; - memcpy(&info.guid, pImage->guid, 16); - info.bpp = pImage->bits_per_pixel; - info.num_planes = pImage->num_planes; - info.depth = pImage->depth; - info.red_mask = pImage->red_mask; - info.green_mask = pImage->green_mask; - info.blue_mask = pImage->blue_mask; - info.format = pImage->format; - info.y_sample_bits = pImage->y_sample_bits; - info.u_sample_bits = pImage->u_sample_bits; - info.v_sample_bits = pImage->v_sample_bits; - info.horz_y_period = pImage->horz_y_period; - info.horz_u_period = pImage->horz_u_period; - info.horz_v_period = pImage->horz_v_period; - info.vert_y_period = pImage->vert_y_period; - info.vert_u_period = pImage->vert_u_period; - info.vert_v_period = pImage->vert_v_period; - memcpy(&info.comp_order, pImage->component_order, 32); - info.scanline_order = pImage->scanline_order; - WriteToClient(client, sizeof(xvImageFormatInfo), (char*)&info); - } - - return Success; -} - -static int -ProcXvMCGetDRInfo(ClientPtr client) -{ - xvmcGetDRInfoReply rep; - XvPortPtr pPort; - ScreenPtr pScreen; - XvMCScreenPtr pScreenPriv; - -#ifdef HAS_XVMCSHM - volatile CARD32 *patternP; -#endif - - REQUEST(xvmcGetDRInfoReq); - REQUEST_SIZE_MATCH(xvmcGetDRInfoReq); - - VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); - - pScreen = pPort->pAdaptor->pScreen; - pScreenPriv = XVMC_GET_PRIVATE(pScreen); - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.major = pScreenPriv->major; - rep.minor = pScreenPriv->minor; - rep.patchLevel = pScreenPriv->patchLevel; - rep.nameLen = bytes_to_int32(strlen(pScreenPriv->clientDriverName) + 1); - rep.busIDLen = bytes_to_int32(strlen(pScreenPriv->busID) + 1); - - rep.length = rep.nameLen + rep.busIDLen; - rep.nameLen <<=2; - rep.busIDLen <<=2; - - /* - * Read back to the client what she has put in the shared memory - * segment she prepared for us. - */ - - rep.isLocal = 1; -#ifdef HAS_XVMCSHM - patternP = (CARD32 *)shmat( stuff->shmKey, NULL, SHM_RDONLY ); - if ( -1 != (long) patternP) { - volatile CARD32 *patternC = patternP; - int i; - CARD32 magic = stuff->magic; - - rep.isLocal = 1; - i = 1024 / sizeof(CARD32); - - while ( i-- ) { - if (*patternC++ != magic) { - rep.isLocal = 0; - break; - } - magic = ~magic; - } - shmdt( (char *)patternP ); - } -#endif /* HAS_XVMCSHM */ - - WriteToClient(client, sizeof(xvmcGetDRInfoReply), - (char*)&rep); - if (rep.length) { - WriteToClient(client, rep.nameLen, - pScreenPriv->clientDriverName); - WriteToClient(client, rep.busIDLen, - pScreenPriv->busID); - } - return Success; -} - - -int (*ProcXvMCVector[xvmcNumRequest])(ClientPtr) = { - ProcXvMCQueryVersion, - ProcXvMCListSurfaceTypes, - ProcXvMCCreateContext, - ProcXvMCDestroyContext, - ProcXvMCCreateSurface, - ProcXvMCDestroySurface, - ProcXvMCCreateSubpicture, - ProcXvMCDestroySubpicture, - ProcXvMCListSubpictureTypes, - ProcXvMCGetDRInfo -}; - -static int -ProcXvMCDispatch (ClientPtr client) -{ - REQUEST(xReq); - - if(stuff->data < xvmcNumRequest) - return (*ProcXvMCVector[stuff->data])(client); - else - return BadRequest; -} - -static int -SProcXvMCDispatch (ClientPtr client) -{ - /* We only support local */ - return BadImplementation; -} - -void -XvMCExtensionInit(void) -{ - ExtensionEntry *extEntry; - - if(XvMCScreenKey == NULL) /* nobody supports it */ - return; - - if(!(XvMCRTContext = CreateNewResourceType(XvMCDestroyContextRes, - "XvMCRTContext"))) - return; - - if(!(XvMCRTSurface = CreateNewResourceType(XvMCDestroySurfaceRes, - "XvMCRTSurface"))) - return; - - if(!(XvMCRTSubpicture = CreateNewResourceType(XvMCDestroySubpictureRes, - "XvMCRTSubpicture"))) - return; - - extEntry = AddExtension(XvMCName, XvMCNumEvents, XvMCNumErrors, - ProcXvMCDispatch, SProcXvMCDispatch, - NULL, StandardMinorOpcode); - - if(!extEntry) return; - - XvMCReqCode = extEntry->base; - XvMCEventBase = extEntry->eventBase; - SetResourceTypeErrorValue(XvMCRTContext, extEntry->errorBase + XvMCBadContext); - SetResourceTypeErrorValue(XvMCRTSurface, extEntry->errorBase + XvMCBadSurface); - SetResourceTypeErrorValue(XvMCRTSubpicture, extEntry->errorBase + XvMCBadSubpicture); -} - -static Bool -XvMCCloseScreen (int i, ScreenPtr pScreen) -{ - XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen); - - pScreen->CloseScreen = pScreenPriv->CloseScreen; - - free(pScreenPriv); - - return (*pScreen->CloseScreen)(i, pScreen); -} - - -int -XvMCScreenInit(ScreenPtr pScreen, int num, XvMCAdaptorPtr pAdapt) -{ - XvMCScreenPtr pScreenPriv; - - if (!dixRegisterPrivateKey(&XvMCScreenKeyRec, PRIVATE_SCREEN, 0)) - return BadAlloc; - - if(!(pScreenPriv = malloc(sizeof(XvMCScreenRec)))) - return BadAlloc; - - dixSetPrivate(&pScreen->devPrivates, XvMCScreenKey, pScreenPriv); - - pScreenPriv->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = XvMCCloseScreen; - - pScreenPriv->num_adaptors = num; - pScreenPriv->adaptors = pAdapt; - pScreenPriv->clientDriverName[0] = 0; - pScreenPriv->busID[0] = 0; - pScreenPriv->major = 0; - pScreenPriv->minor = 0; - pScreenPriv->patchLevel = 0; - - XvMCInUse = TRUE; - - return Success; -} - -XvImagePtr XvMCFindXvImage(XvPortPtr pPort, CARD32 id) -{ - XvImagePtr pImage = NULL; - ScreenPtr pScreen = pPort->pAdaptor->pScreen; - XvMCScreenPtr pScreenPriv; - XvMCAdaptorPtr adaptor = NULL; - int i; - - if(XvMCScreenKey == NULL) return NULL; - - if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) - return NULL; - - for(i = 0; i < pScreenPriv->num_adaptors; i++) { - if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { - adaptor = &(pScreenPriv->adaptors[i]); - break; - } - } - - if(!adaptor) return NULL; - - for(i = 0; i < adaptor->num_subpictures; i++) { - if(adaptor->subpictures[i]->id == id) { - pImage = adaptor->subpictures[i]; - break; - } - } - - return pImage; -} - -int -xf86XvMCRegisterDRInfo(ScreenPtr pScreen, char *name, - char *busID, int major, int minor, - int patchLevel) -{ - XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen); - strncpy(pScreenPriv->clientDriverName, name, - DR_CLIENT_DRIVER_NAME_SIZE); - strncpy(pScreenPriv->busID, busID, DR_BUSID_SIZE); - pScreenPriv->major = major; - pScreenPriv->minor = minor; - pScreenPriv->patchLevel = patchLevel; - pScreenPriv->clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE-1] = 0; - pScreenPriv->busID[DR_BUSID_SIZE-1] = 0; - return Success; -} - + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include +#include +#include "misc.h" +#include "os.h" +#include "dixstruct.h" +#include "resource.h" +#include "scrnintstr.h" +#include "extnsionst.h" +#include "servermd.h" +#include +#include "xvdix.h" +#include +#include +#include +#include "xvmcext.h" +#include "protocol-versions.h" + +#ifdef HAS_XVMCSHM +#include +#include +#include +#endif /* HAS_XVMCSHM */ + + + +#define DR_CLIENT_DRIVER_NAME_SIZE 48 +#define DR_BUSID_SIZE 48 + +static DevPrivateKeyRec XvMCScreenKeyRec; +#define XvMCScreenKey (&XvMCScreenKeyRec) +static Bool XvMCInUse; + +unsigned long XvMCGeneration = 0; + +int XvMCReqCode; +int XvMCEventBase; + +static RESTYPE XvMCRTContext; +static RESTYPE XvMCRTSurface; +static RESTYPE XvMCRTSubpicture; + +typedef struct { + int num_adaptors; + XvMCAdaptorPtr adaptors; + CloseScreenProcPtr CloseScreen; + char clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE]; + char busID[DR_BUSID_SIZE]; + int major; + int minor; + int patchLevel; +} XvMCScreenRec, *XvMCScreenPtr; + +#define XVMC_GET_PRIVATE(pScreen) \ + (XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates, XvMCScreenKey)) + + +static int +XvMCDestroyContextRes(pointer data, XID id) +{ + XvMCContextPtr pContext = (XvMCContextPtr)data; + + pContext->refcnt--; + + if(!pContext->refcnt) { + XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); + (*pScreenPriv->adaptors[pContext->adapt_num].DestroyContext)(pContext); + free(pContext); + } + + return Success; +} + +static int +XvMCDestroySurfaceRes(pointer data, XID id) +{ + XvMCSurfacePtr pSurface = (XvMCSurfacePtr)data; + XvMCContextPtr pContext = pSurface->context; + XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); + + (*pScreenPriv->adaptors[pContext->adapt_num].DestroySurface)(pSurface); + free(pSurface); + + XvMCDestroyContextRes((pointer)pContext, pContext->context_id); + + return Success; +} + + +static int +XvMCDestroySubpictureRes(pointer data, XID id) +{ + XvMCSubpicturePtr pSubpict = (XvMCSubpicturePtr)data; + XvMCContextPtr pContext = pSubpict->context; + XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); + + (*pScreenPriv->adaptors[pContext->adapt_num].DestroySubpicture)(pSubpict); + free(pSubpict); + + XvMCDestroyContextRes((pointer)pContext, pContext->context_id); + + return Success; +} + +static int +ProcXvMCQueryVersion(ClientPtr client) +{ + xvmcQueryVersionReply rep; + /* REQUEST(xvmcQueryVersionReq); */ + REQUEST_SIZE_MATCH(xvmcQueryVersionReq); + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.major = SERVER_XVMC_MAJOR_VERSION; + rep.minor = SERVER_XVMC_MINOR_VERSION; + WriteToClient(client, sizeof(xvmcQueryVersionReply), (char*)&rep); + return Success; +} + + +static int +ProcXvMCListSurfaceTypes(ClientPtr client) +{ + XvPortPtr pPort; + int i; + XvMCScreenPtr pScreenPriv; + xvmcListSurfaceTypesReply rep; + xvmcSurfaceInfo info; + XvMCAdaptorPtr adaptor = NULL; + XvMCSurfaceInfoPtr surface; + REQUEST(xvmcListSurfaceTypesReq); + REQUEST_SIZE_MATCH(xvmcListSurfaceTypesReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + if(XvMCInUse) { /* any adaptors at all */ + ScreenPtr pScreen = pPort->pAdaptor->pScreen; + if((pScreenPriv = XVMC_GET_PRIVATE(pScreen))) { /* any this screen */ + for(i = 0; i < pScreenPriv->num_adaptors; i++) { + if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { + adaptor = &(pScreenPriv->adaptors[i]); + break; + } + } + } + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num = (adaptor) ? adaptor->num_surfaces : 0; + rep.length = bytes_to_int32(rep.num * sizeof(xvmcSurfaceInfo)); + + WriteToClient(client, sizeof(xvmcListSurfaceTypesReply), (char*)&rep); + + for(i = 0; i < rep.num; i++) { + surface = adaptor->surfaces[i]; + info.surface_type_id = surface->surface_type_id; + info.chroma_format = surface->chroma_format; + info.max_width = surface->max_width; + info.max_height = surface->max_height; + info.subpicture_max_width = surface->subpicture_max_width; + info.subpicture_max_height = surface->subpicture_max_height; + info.mc_type = surface->mc_type; + info.flags = surface->flags; + WriteToClient(client, sizeof(xvmcSurfaceInfo), (char*)&info); + } + + return Success; +} + +static int +ProcXvMCCreateContext(ClientPtr client) +{ + XvPortPtr pPort; + CARD32 *data = NULL; + int dwords = 0; + int i, result, adapt_num = -1; + ScreenPtr pScreen; + XvMCContextPtr pContext; + XvMCScreenPtr pScreenPriv; + XvMCAdaptorPtr adaptor = NULL; + XvMCSurfaceInfoPtr surface = NULL; + xvmcCreateContextReply rep; + REQUEST(xvmcCreateContextReq); + REQUEST_SIZE_MATCH(xvmcCreateContextReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + pScreen = pPort->pAdaptor->pScreen; + + if(!XvMCInUse) /* no XvMC adaptors */ + return BadMatch; + + if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) /* none this screen */ + return BadMatch; + + for(i = 0; i < pScreenPriv->num_adaptors; i++) { + if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { + adaptor = &(pScreenPriv->adaptors[i]); + adapt_num = i; + break; + } + } + + if(adapt_num < 0) /* none this port */ + return BadMatch; + + for(i = 0; i < adaptor->num_surfaces; i++) { + if(adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) { + surface = adaptor->surfaces[i]; + break; + } + } + + /* adaptor doesn't support this suface_type_id */ + if(!surface) return BadMatch; + + + if((stuff->width > surface->max_width) || + (stuff->height > surface->max_height)) + return BadValue; + + if(!(pContext = malloc(sizeof(XvMCContextRec)))) { + return BadAlloc; + } + + + pContext->pScreen = pScreen; + pContext->adapt_num = adapt_num; + pContext->context_id = stuff->context_id; + pContext->surface_type_id = stuff->surface_type_id; + pContext->width = stuff->width; + pContext->height = stuff->height; + pContext->flags = stuff->flags; + pContext->refcnt = 1; + + result = (*adaptor->CreateContext)(pPort, pContext, &dwords, &data); + + if(result != Success) { + free(pContext); + return result; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.width_actual = pContext->width; + rep.height_actual = pContext->height; + rep.flags_return = pContext->flags; + rep.length = dwords; + + WriteToClient(client, sizeof(xvmcCreateContextReply), (char*)&rep); + if(dwords) + WriteToClient(client, dwords << 2, (char*)data); + AddResource(pContext->context_id, XvMCRTContext, pContext); + + free(data); + + return Success; +} + +static int +ProcXvMCDestroyContext(ClientPtr client) +{ + pointer val; + int rc; + REQUEST(xvmcDestroyContextReq); + REQUEST_SIZE_MATCH(xvmcDestroyContextReq); + + rc = dixLookupResourceByType(&val, stuff->context_id, XvMCRTContext, + client, DixDestroyAccess); + if (rc != Success) + return rc; + + FreeResource(stuff->context_id, RT_NONE); + + return Success; +} + +static int +ProcXvMCCreateSurface(ClientPtr client) +{ + CARD32 *data = NULL; + int dwords = 0; + int result; + XvMCContextPtr pContext; + XvMCSurfacePtr pSurface; + XvMCScreenPtr pScreenPriv; + xvmcCreateSurfaceReply rep; + REQUEST(xvmcCreateSurfaceReq); + REQUEST_SIZE_MATCH(xvmcCreateSurfaceReq); + + result = dixLookupResourceByType((pointer *)&pContext, stuff->context_id, + XvMCRTContext, client, DixUseAccess); + if (result != Success) + return result; + + pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); + + if(!(pSurface = malloc(sizeof(XvMCSurfaceRec)))) + return BadAlloc; + + pSurface->surface_id = stuff->surface_id; + pSurface->surface_type_id = pContext->surface_type_id; + pSurface->context = pContext; + + result = (*pScreenPriv->adaptors[pContext->adapt_num].CreateSurface)( + pSurface, &dwords, &data); + + if(result != Success) { + free(pSurface); + return result; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = dwords; + + WriteToClient(client, sizeof(xvmcCreateSurfaceReply), (char*)&rep); + if(dwords) + WriteToClient(client, dwords << 2, (char*)data); + AddResource(pSurface->surface_id, XvMCRTSurface, pSurface); + + free(data); + + pContext->refcnt++; + + return Success; +} + +static int +ProcXvMCDestroySurface(ClientPtr client) +{ + pointer val; + int rc; + REQUEST(xvmcDestroySurfaceReq); + REQUEST_SIZE_MATCH(xvmcDestroySurfaceReq); + + rc = dixLookupResourceByType(&val, stuff->surface_id, XvMCRTSurface, + client, DixDestroyAccess); + if (rc != Success) + return rc; + + FreeResource(stuff->surface_id, RT_NONE); + + return Success; +} + +static int +ProcXvMCCreateSubpicture(ClientPtr client) +{ + Bool image_supported = FALSE; + CARD32 *data = NULL; + int i, result, dwords = 0; + XvMCContextPtr pContext; + XvMCSubpicturePtr pSubpicture; + XvMCScreenPtr pScreenPriv; + xvmcCreateSubpictureReply rep; + XvMCAdaptorPtr adaptor; + XvMCSurfaceInfoPtr surface = NULL; + REQUEST(xvmcCreateSubpictureReq); + REQUEST_SIZE_MATCH(xvmcCreateSubpictureReq); + + result = dixLookupResourceByType((pointer *)&pContext, stuff->context_id, + XvMCRTContext, client, DixUseAccess); + if (result != Success) + return result; + + pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen); + + adaptor = &(pScreenPriv->adaptors[pContext->adapt_num]); + + /* find which surface this context supports */ + for(i = 0; i < adaptor->num_surfaces; i++) { + if(adaptor->surfaces[i]->surface_type_id == pContext->surface_type_id){ + surface = adaptor->surfaces[i]; + break; + } + } + + if(!surface) return BadMatch; + + /* make sure this surface supports that xvimage format */ + if(!surface->compatible_subpictures) return BadMatch; + + for(i = 0; i < surface->compatible_subpictures->num_xvimages; i++) { + if(surface->compatible_subpictures->xvimage_ids[i] == stuff->xvimage_id) { + image_supported = TRUE; + break; + } + } + + if(!image_supported) return BadMatch; + + /* make sure the size is OK */ + if((stuff->width > surface->subpicture_max_width) || + (stuff->height > surface->subpicture_max_height)) + return BadValue; + + if(!(pSubpicture = malloc(sizeof(XvMCSubpictureRec)))) + return BadAlloc; + + pSubpicture->subpicture_id = stuff->subpicture_id; + pSubpicture->xvimage_id = stuff->xvimage_id; + pSubpicture->width = stuff->width; + pSubpicture->height = stuff->height; + pSubpicture->num_palette_entries = 0; /* overwritten by DDX */ + pSubpicture->entry_bytes = 0; /* overwritten by DDX */ + pSubpicture->component_order[0] = 0; /* overwritten by DDX */ + pSubpicture->component_order[1] = 0; + pSubpicture->component_order[2] = 0; + pSubpicture->component_order[3] = 0; + pSubpicture->context = pContext; + + result = (*pScreenPriv->adaptors[pContext->adapt_num].CreateSubpicture)( + pSubpicture, &dwords, &data); + + if(result != Success) { + free(pSubpicture); + return result; + } + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.width_actual = pSubpicture->width; + rep.height_actual = pSubpicture->height; + rep.num_palette_entries = pSubpicture->num_palette_entries; + rep.entry_bytes = pSubpicture->entry_bytes; + rep.component_order[0] = pSubpicture->component_order[0]; + rep.component_order[1] = pSubpicture->component_order[1]; + rep.component_order[2] = pSubpicture->component_order[2]; + rep.component_order[3] = pSubpicture->component_order[3]; + rep.length = dwords; + + WriteToClient(client, sizeof(xvmcCreateSubpictureReply), (char*)&rep); + if(dwords) + WriteToClient(client, dwords << 2, (char*)data); + AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture); + + free(data); + + pContext->refcnt++; + + return Success; +} + +static int +ProcXvMCDestroySubpicture(ClientPtr client) +{ + pointer val; + int rc; + REQUEST(xvmcDestroySubpictureReq); + REQUEST_SIZE_MATCH(xvmcDestroySubpictureReq); + + rc = dixLookupResourceByType(&val, stuff->subpicture_id, XvMCRTSubpicture, + client, DixDestroyAccess); + if (rc != Success) + return rc; + + FreeResource(stuff->subpicture_id, RT_NONE); + + return Success; +} + + +static int +ProcXvMCListSubpictureTypes(ClientPtr client) +{ + XvPortPtr pPort; + xvmcListSubpictureTypesReply rep; + XvMCScreenPtr pScreenPriv; + ScreenPtr pScreen; + XvMCAdaptorPtr adaptor = NULL; + XvMCSurfaceInfoPtr surface = NULL; + xvImageFormatInfo info; + XvImagePtr pImage; + int i, j; + REQUEST(xvmcListSubpictureTypesReq); + REQUEST_SIZE_MATCH(xvmcListSubpictureTypesReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + pScreen = pPort->pAdaptor->pScreen; + + if(XvMCScreenKey == NULL) /* No XvMC adaptors */ + return BadMatch; + + if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) + return BadMatch; /* None this screen */ + + for(i = 0; i < pScreenPriv->num_adaptors; i++) { + if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { + adaptor = &(pScreenPriv->adaptors[i]); + break; + } + } + + if(!adaptor) return BadMatch; + + for(i = 0; i < adaptor->num_surfaces; i++) { + if(adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) { + surface = adaptor->surfaces[i]; + break; + } + } + + if(!surface) return BadMatch; + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.num = 0; + if(surface->compatible_subpictures) + rep.num = surface->compatible_subpictures->num_xvimages; + + rep.length = bytes_to_int32(rep.num * sizeof(xvImageFormatInfo)); + + WriteToClient(client, sizeof(xvmcListSubpictureTypesReply), (char*)&rep); + + for(i = 0; i < rep.num; i++) { + pImage = NULL; + for(j = 0; j < adaptor->num_subpictures; j++) { + if(surface->compatible_subpictures->xvimage_ids[i] == + adaptor->subpictures[j]->id) + { + pImage = adaptor->subpictures[j]; + break; + } + } + if(!pImage) return BadImplementation; + + info.id = pImage->id; + info.type = pImage->type; + info.byte_order = pImage->byte_order; + memcpy(&info.guid, pImage->guid, 16); + info.bpp = pImage->bits_per_pixel; + info.num_planes = pImage->num_planes; + info.depth = pImage->depth; + info.red_mask = pImage->red_mask; + info.green_mask = pImage->green_mask; + info.blue_mask = pImage->blue_mask; + info.format = pImage->format; + info.y_sample_bits = pImage->y_sample_bits; + info.u_sample_bits = pImage->u_sample_bits; + info.v_sample_bits = pImage->v_sample_bits; + info.horz_y_period = pImage->horz_y_period; + info.horz_u_period = pImage->horz_u_period; + info.horz_v_period = pImage->horz_v_period; + info.vert_y_period = pImage->vert_y_period; + info.vert_u_period = pImage->vert_u_period; + info.vert_v_period = pImage->vert_v_period; + memcpy(&info.comp_order, pImage->component_order, 32); + info.scanline_order = pImage->scanline_order; + WriteToClient(client, sizeof(xvImageFormatInfo), (char*)&info); + } + + return Success; +} + +static int +ProcXvMCGetDRInfo(ClientPtr client) +{ + xvmcGetDRInfoReply rep; + XvPortPtr pPort; + ScreenPtr pScreen; + XvMCScreenPtr pScreenPriv; + +#ifdef HAS_XVMCSHM + volatile CARD32 *patternP; +#endif + + REQUEST(xvmcGetDRInfoReq); + REQUEST_SIZE_MATCH(xvmcGetDRInfoReq); + + VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); + + pScreen = pPort->pAdaptor->pScreen; + pScreenPriv = XVMC_GET_PRIVATE(pScreen); + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.major = pScreenPriv->major; + rep.minor = pScreenPriv->minor; + rep.patchLevel = pScreenPriv->patchLevel; + rep.nameLen = bytes_to_int32(strlen(pScreenPriv->clientDriverName) + 1); + rep.busIDLen = bytes_to_int32(strlen(pScreenPriv->busID) + 1); + + rep.length = rep.nameLen + rep.busIDLen; + rep.nameLen <<=2; + rep.busIDLen <<=2; + + /* + * Read back to the client what she has put in the shared memory + * segment she prepared for us. + */ + + rep.isLocal = 1; +#ifdef HAS_XVMCSHM + patternP = (CARD32 *)shmat( stuff->shmKey, NULL, SHM_RDONLY ); + if ( -1 != (long) patternP) { + volatile CARD32 *patternC = patternP; + int i; + CARD32 magic = stuff->magic; + + rep.isLocal = 1; + i = 1024 / sizeof(CARD32); + + while ( i-- ) { + if (*patternC++ != magic) { + rep.isLocal = 0; + break; + } + magic = ~magic; + } + shmdt( (char *)patternP ); + } +#endif /* HAS_XVMCSHM */ + + WriteToClient(client, sizeof(xvmcGetDRInfoReply), + (char*)&rep); + if (rep.length) { + WriteToClient(client, rep.nameLen, + pScreenPriv->clientDriverName); + WriteToClient(client, rep.busIDLen, + pScreenPriv->busID); + } + return Success; +} + + +int (*ProcXvMCVector[xvmcNumRequest])(ClientPtr) = { + ProcXvMCQueryVersion, + ProcXvMCListSurfaceTypes, + ProcXvMCCreateContext, + ProcXvMCDestroyContext, + ProcXvMCCreateSurface, + ProcXvMCDestroySurface, + ProcXvMCCreateSubpicture, + ProcXvMCDestroySubpicture, + ProcXvMCListSubpictureTypes, + ProcXvMCGetDRInfo +}; + +static int +ProcXvMCDispatch (ClientPtr client) +{ + REQUEST(xReq); + + if(stuff->data < xvmcNumRequest) + return (*ProcXvMCVector[stuff->data])(client); + else + return BadRequest; +} + +static int +SProcXvMCDispatch (ClientPtr client) +{ + /* We only support local */ + return BadImplementation; +} + +void +XvMCExtensionInit(void) +{ + ExtensionEntry *extEntry; + + if(XvMCScreenKey == NULL) /* nobody supports it */ + return; + + if(!(XvMCRTContext = CreateNewResourceType(XvMCDestroyContextRes, + "XvMCRTContext"))) + return; + + if(!(XvMCRTSurface = CreateNewResourceType(XvMCDestroySurfaceRes, + "XvMCRTSurface"))) + return; + + if(!(XvMCRTSubpicture = CreateNewResourceType(XvMCDestroySubpictureRes, + "XvMCRTSubpicture"))) + return; + + extEntry = AddExtension(XvMCName, XvMCNumEvents, XvMCNumErrors, + ProcXvMCDispatch, SProcXvMCDispatch, + NULL, StandardMinorOpcode); + + if(!extEntry) return; + + XvMCReqCode = extEntry->base; + XvMCEventBase = extEntry->eventBase; + SetResourceTypeErrorValue(XvMCRTContext, extEntry->errorBase + XvMCBadContext); + SetResourceTypeErrorValue(XvMCRTSurface, extEntry->errorBase + XvMCBadSurface); + SetResourceTypeErrorValue(XvMCRTSubpicture, extEntry->errorBase + XvMCBadSubpicture); +} + +static Bool +XvMCCloseScreen (int i, ScreenPtr pScreen) +{ + XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen); + + pScreen->CloseScreen = pScreenPriv->CloseScreen; + + free(pScreenPriv); + + return (*pScreen->CloseScreen)(i, pScreen); +} + + +int +XvMCScreenInit(ScreenPtr pScreen, int num, XvMCAdaptorPtr pAdapt) +{ + XvMCScreenPtr pScreenPriv; + + if (!dixRegisterPrivateKey(&XvMCScreenKeyRec, PRIVATE_SCREEN, 0)) + return BadAlloc; + + if(!(pScreenPriv = malloc(sizeof(XvMCScreenRec)))) + return BadAlloc; + + dixSetPrivate(&pScreen->devPrivates, XvMCScreenKey, pScreenPriv); + + pScreenPriv->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = XvMCCloseScreen; + + pScreenPriv->num_adaptors = num; + pScreenPriv->adaptors = pAdapt; + pScreenPriv->clientDriverName[0] = 0; + pScreenPriv->busID[0] = 0; + pScreenPriv->major = 0; + pScreenPriv->minor = 0; + pScreenPriv->patchLevel = 0; + + XvMCInUse = TRUE; + + return Success; +} + +XvImagePtr XvMCFindXvImage(XvPortPtr pPort, CARD32 id) +{ + XvImagePtr pImage = NULL; + ScreenPtr pScreen = pPort->pAdaptor->pScreen; + XvMCScreenPtr pScreenPriv; + XvMCAdaptorPtr adaptor = NULL; + int i; + + if(XvMCScreenKey == NULL) return NULL; + + if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) + return NULL; + + for(i = 0; i < pScreenPriv->num_adaptors; i++) { + if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { + adaptor = &(pScreenPriv->adaptors[i]); + break; + } + } + + if(!adaptor) return NULL; + + for(i = 0; i < adaptor->num_subpictures; i++) { + if(adaptor->subpictures[i]->id == id) { + pImage = adaptor->subpictures[i]; + break; + } + } + + return pImage; +} + +int +xf86XvMCRegisterDRInfo(ScreenPtr pScreen, char *name, + char *busID, int major, int minor, + int patchLevel) +{ + XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen); + strncpy(pScreenPriv->clientDriverName, name, + DR_CLIENT_DRIVER_NAME_SIZE); + strncpy(pScreenPriv->busID, busID, DR_BUSID_SIZE); + pScreenPriv->major = major; + pScreenPriv->minor = minor; + pScreenPriv->patchLevel = patchLevel; + pScreenPriv->clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE-1] = 0; + pScreenPriv->busID[DR_BUSID_SIZE-1] = 0; + return Success; +} + diff --git a/xorg-server/Xi/exglobals.h b/xorg-server/Xi/exglobals.h index 4f09e6ca3..8c5a42e6e 100644 --- a/xorg-server/Xi/exglobals.h +++ b/xorg-server/Xi/exglobals.h @@ -1,84 +1,84 @@ -/************************************************************ - -Copyright 1996 by Thomas E. Dickey - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of the above listed -copyright holder(s) not be used in advertising or publicity pertaining -to distribution of the software without specific, written prior -permission. - -THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD -TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE -LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -********************************************************/ - -/***************************************************************** - * - * Globals referenced elsewhere in the server. - * - */ -#ifdef HAVE_DIX_CONFIG_H -#include -#endif -#include "privates.h" - -#ifndef EXGLOBALS_H -#define EXGLOBALS_H 1 - -extern int IReqCode; -extern int IEventBase; -extern int BadDevice; -extern int BadMode; -extern int DeviceBusy; -extern int BadClass; - -/* Note: only the ones needed in files other than extinit.c are declared */ -extern const Mask DevicePointerMotionMask; -extern const Mask DevicePointerMotionHintMask; -extern const Mask DeviceFocusChangeMask; -extern const Mask DeviceStateNotifyMask; -extern const Mask DeviceMappingNotifyMask; -extern const Mask DeviceOwnerGrabButtonMask; -extern const Mask DeviceButtonGrabMask; -extern const Mask DeviceButtonMotionMask; -extern const Mask DevicePresenceNotifyMask; -extern const Mask DevicePropertyNotifyMask; -extern const Mask XIAllMasks; - -extern Mask PropagateMask[]; - -extern int DeviceValuator; -extern int DeviceKeyPress; -extern int DeviceKeyRelease; -extern int DeviceButtonPress; -extern int DeviceButtonRelease; -extern int DeviceMotionNotify; -extern int DeviceFocusIn; -extern int DeviceFocusOut; -extern int ProximityIn; -extern int ProximityOut; -extern int DeviceStateNotify; -extern int DeviceKeyStateNotify; -extern int DeviceButtonStateNotify; -extern int DeviceMappingNotify; -extern int ChangeDeviceNotify; -extern int DevicePresenceNotify; -extern int DevicePropertyNotify; - -extern int RT_INPUTCLIENT; - -extern DevPrivateKeyRec XIClientPrivateKeyRec; -#define XIClientPrivateKey (&XIClientPrivateKeyRec) - -#endif /* EXGLOBALS_H */ +/************************************************************ + +Copyright 1996 by Thomas E. Dickey + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of the above listed +copyright holder(s) not be used in advertising or publicity pertaining +to distribution of the software without specific, written prior +permission. + +THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM ALL WARRANTIES WITH REGARD +TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) BE +LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +********************************************************/ + +/***************************************************************** + * + * Globals referenced elsewhere in the server. + * + */ +#ifdef HAVE_DIX_CONFIG_H +#include +#endif +#include "privates.h" + +#ifndef EXGLOBALS_H +#define EXGLOBALS_H 1 + +extern int IReqCode; +extern int IEventBase; +extern int BadDevice; +extern int BadMode; +extern int DeviceBusy; +extern int BadClass; + +/* Note: only the ones needed in files other than extinit.c are declared */ +extern const Mask DevicePointerMotionMask; +extern const Mask DevicePointerMotionHintMask; +extern const Mask DeviceFocusChangeMask; +extern const Mask DeviceStateNotifyMask; +extern const Mask DeviceMappingNotifyMask; +extern const Mask DeviceOwnerGrabButtonMask; +extern const Mask DeviceButtonGrabMask; +extern const Mask DeviceButtonMotionMask; +extern const Mask DevicePresenceNotifyMask; +extern const Mask DevicePropertyNotifyMask; +extern const Mask XIAllMasks; + +extern Mask PropagateMask[]; + +extern int DeviceValuator; +extern int DeviceKeyPress; +extern int DeviceKeyRelease; +extern int DeviceButtonPress; +extern int DeviceButtonRelease; +extern int DeviceMotionNotify; +extern int DeviceFocusIn; +extern int DeviceFocusOut; +extern int ProximityIn; +extern int ProximityOut; +extern int DeviceStateNotify; +extern int DeviceKeyStateNotify; +extern int DeviceButtonStateNotify; +extern int DeviceMappingNotify; +extern int ChangeDeviceNotify; +extern int DevicePresenceNotify; +extern int DevicePropertyNotify; + +extern RESTYPE RT_INPUTCLIENT; + +extern DevPrivateKeyRec XIClientPrivateKeyRec; +#define XIClientPrivateKey (&XIClientPrivateKeyRec) + +#endif /* EXGLOBALS_H */ diff --git a/xorg-server/Xi/extinit.c b/xorg-server/Xi/extinit.c index 82df7eb02..46d34599c 100644 --- a/xorg-server/Xi/extinit.c +++ b/xorg-server/Xi/extinit.c @@ -358,7 +358,7 @@ int ChangeDeviceNotify; int DevicePresenceNotify; int DevicePropertyNotify; -int RT_INPUTCLIENT; +RESTYPE RT_INPUTCLIENT; /***************************************************************** * diff --git a/xorg-server/dix/Makefile.am b/xorg-server/dix/Makefile.am index 5ff75c0ba..543554669 100644 --- a/xorg-server/dix/Makefile.am +++ b/xorg-server/dix/Makefile.am @@ -1,75 +1,74 @@ -noinst_LTLIBRARIES = libdix.la libmain.la - -AM_CPPFLAGS = -I$(top_srcdir)/include -AM_CFLAGS = $(DIX_CFLAGS) - -libmain_la_SOURCES = \ - main.c - -libdix_la_SOURCES = \ - atom.c \ - colormap.c \ - cursor.c \ - deprecated.c \ - devices.c \ - dispatch.c \ - dispatch.h \ - dixfonts.c \ - dixutils.c \ - enterleave.c \ - enterleave.h \ - events.c \ - eventconvert.c \ - extension.c \ - ffs.c \ - gc.c \ - getevents.c \ - globals.c \ - glyphcurs.c \ - grabs.c \ - initatoms.c \ - inpututils.c \ - pixmap.c \ - privates.c \ - property.c \ - ptrveloc.c \ - region.c \ - registry.c \ - resource.c \ - selection.c \ - swaprep.c \ - swapreq.c \ - tables.c \ - window.c - -EXTRA_DIST = buildatoms BuiltInAtoms Xserver.d Xserver-dtrace.h.in - -# Install list of protocol names -miscconfigdir = $(SERVER_MISC_CONFIG_PATH) -dist_miscconfig_DATA = protocol.txt - -if XSERVER_DTRACE -# Generate dtrace header file for C sources to include -BUILT_SOURCES = Xserver-dtrace.h - -Xserver-dtrace.h: $(srcdir)/Xserver.d - $(AM_V_GEN)$(DTRACE) -C -h -o $@ -s $(srcdir)/Xserver.d \ - || cp Xserver-dtrace.h.in $@ - -endif - -if SPECIAL_DTRACE_OBJECTS -# Generate dtrace object code for probes in libdix -dtrace-dix.o: $(top_srcdir)/dix/Xserver.d $(am_libdix_la_OBJECTS) - $(AM_V_GEN)$(DTRACE) -G -C -o $@ -s $(top_srcdir)/dix/Xserver.d $(am_libdix_la_OBJECTS:%.lo=.libs/%.o) - -noinst_PROGRAMS = dix.O - -dix.O: dtrace-dix.o $(am_libdix_la_OBJECTS) - $(AM_V_GEN)ld -r -o $@ $(am_libdix_la_OBJECTS:%.lo=.libs/%.o) -endif - -dix.c: - touch $@ - -CLEANFILES = dix.c Xserver-dtrace.h +noinst_LTLIBRARIES = libdix.la libmain.la + +AM_CPPFLAGS = -I$(top_srcdir)/include +AM_CFLAGS = $(DIX_CFLAGS) + +libmain_la_SOURCES = \ + main.c + +libdix_la_SOURCES = \ + atom.c \ + colormap.c \ + cursor.c \ + devices.c \ + dispatch.c \ + dispatch.h \ + dixfonts.c \ + dixutils.c \ + enterleave.c \ + enterleave.h \ + events.c \ + eventconvert.c \ + extension.c \ + ffs.c \ + gc.c \ + getevents.c \ + globals.c \ + glyphcurs.c \ + grabs.c \ + initatoms.c \ + inpututils.c \ + pixmap.c \ + privates.c \ + property.c \ + ptrveloc.c \ + region.c \ + registry.c \ + resource.c \ + selection.c \ + swaprep.c \ + swapreq.c \ + tables.c \ + window.c + +EXTRA_DIST = buildatoms BuiltInAtoms Xserver.d Xserver-dtrace.h.in + +# Install list of protocol names +miscconfigdir = $(SERVER_MISC_CONFIG_PATH) +dist_miscconfig_DATA = protocol.txt + +if XSERVER_DTRACE +# Generate dtrace header file for C sources to include +BUILT_SOURCES = Xserver-dtrace.h + +Xserver-dtrace.h: $(srcdir)/Xserver.d + $(AM_V_GEN)$(DTRACE) -C -h -o $@ -s $(srcdir)/Xserver.d \ + || cp Xserver-dtrace.h.in $@ + +endif + +if SPECIAL_DTRACE_OBJECTS +# Generate dtrace object code for probes in libdix +dtrace-dix.o: $(top_srcdir)/dix/Xserver.d $(am_libdix_la_OBJECTS) + $(AM_V_GEN)$(DTRACE) -G -C -o $@ -s $(top_srcdir)/dix/Xserver.d $(am_libdix_la_OBJECTS:%.lo=.libs/%.o) + +noinst_PROGRAMS = dix.O + +dix.O: dtrace-dix.o $(am_libdix_la_OBJECTS) + $(AM_V_GEN)ld -r -o $@ $(am_libdix_la_OBJECTS:%.lo=.libs/%.o) +endif + +dix.c: + touch $@ + +CLEANFILES = dix.c Xserver-dtrace.h diff --git a/xorg-server/dix/deprecated.c b/xorg-server/dix/deprecated.c deleted file mode 100644 index b1f4d6c5c..000000000 --- a/xorg-server/dix/deprecated.c +++ /dev/null @@ -1,165 +0,0 @@ -/*********************************************************** - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "dix.h" -#include "misc.h" -#include "dixstruct.h" - -/* - * These are deprecated compatibility functions and will be marked as such - * and removed soon! - * - * Please use the noted replacements instead. - */ - -/* replaced by dixLookupWindow */ -WindowPtr -SecurityLookupWindow(XID id, ClientPtr client, Mask access_mode) -{ - WindowPtr pWin; - static int warn = 1; - dixLookupWindow(&pWin, id, client, access_mode); - if (warn > 0 && warn--) - ErrorF("Warning: LookupWindow()/SecurityLookupWindow() " - "are deprecated. Please convert your driver/module " - "to use dixLookupWindow().\n"); - return pWin; -} - -/* replaced by dixLookupWindow */ -WindowPtr -LookupWindow(XID id, ClientPtr client) -{ - return SecurityLookupWindow(id, client, DixUnknownAccess); -} - -/* replaced by dixLookupDrawable */ -pointer -SecurityLookupDrawable(XID id, ClientPtr client, Mask access_mode) -{ - DrawablePtr pDraw; - static int warn = 1; - dixLookupDrawable(&pDraw, id, client, M_DRAWABLE, access_mode); - if (warn > 0 && warn--) - ErrorF("Warning: LookupDrawable()/SecurityLookupDrawable() " - "are deprecated. Please convert your driver/module " - "to use dixLookupDrawable().\n"); - return pDraw; -} - -/* replaced by dixLookupDrawable */ -pointer -LookupDrawable(XID id, ClientPtr client) -{ - return SecurityLookupDrawable(id, client, DixUnknownAccess); -} - -/* replaced by dixLookupClient */ -ClientPtr -LookupClient(XID id, ClientPtr client) -{ - ClientPtr pClient; - static int warn = 1; - dixLookupClient(&pClient, id, client, DixUnknownAccess); - if (warn > 0 && warn--) - ErrorF("Warning: LookupClient() is deprecated. Please convert your " - "driver/module to use dixLookupClient().\n"); - return pClient; -} - -/* replaced by dixLookupResourceByType */ -pointer -SecurityLookupIDByType(ClientPtr client, XID id, RESTYPE rtype, - Mask access_mode) -{ - pointer retval; - static int warn = 1; - dixLookupResourceByType(&retval, id, rtype, client, access_mode); - if (warn > 0 && warn--) - ErrorF("Warning: LookupIDByType()/SecurityLookupIDByType() " - "are deprecated. Please convert your driver/module " - "to use dixLookupResourceByType().\n"); - return retval; -} - -pointer -SecurityLookupIDByClass(ClientPtr client, XID id, RESTYPE classes, - Mask access_mode) -{ - pointer retval; - static int warn = 1; - dixLookupResourceByClass(&retval, id, classes, client, access_mode); - if (warn > 0 && warn--) - ErrorF("Warning: LookupIDByClass()/SecurityLookupIDByClass() " - "are deprecated. Please convert your driver/module " - "to use dixLookupResourceByClass().\n"); - return retval; -} - -/* replaced by dixLookupResourceByType */ -pointer -LookupIDByType(XID id, RESTYPE rtype) -{ - pointer val; - dixLookupResourceByType(&val, id, rtype, NullClient, DixUnknownAccess); - return val; -} - -/* replaced by dixLookupResourceByClass */ -pointer -LookupIDByClass(XID id, RESTYPE classes) -{ - pointer val; - dixLookupResourceByClass(&val, id, classes, NullClient, DixUnknownAccess); - return val; -} - -/* end deprecated functions */ diff --git a/xorg-server/exa/exa.h b/xorg-server/exa/exa.h index 8c93d156f..6de63008e 100644 --- a/xorg-server/exa/exa.h +++ b/xorg-server/exa/exa.h @@ -712,7 +712,7 @@ typedef struct _ExaDriver { * driver MUST fill out new_fb_pitch with valid pitch of pixmap */ void *(*CreatePixmap2)(ScreenPtr pScreen, int width, int height, - int depth, int usage_hint, int bitsPerPixel, + int depth, int class, int bitsPerPixel, int *new_fb_pitch); /** @} */ } ExaDriverRec, *ExaDriverPtr; diff --git a/xorg-server/exa/exa_classic.c b/xorg-server/exa/exa_classic.c index 1a1467848..640b26a12 100644 --- a/xorg-server/exa/exa_classic.c +++ b/xorg-server/exa/exa_classic.c @@ -1,266 +1,266 @@ -/* - * Copyright © 2009 Maarten Maathuis - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include - -#include "exa_priv.h" -#include "exa.h" - -/* This file holds the classic exa specific implementation. */ - -static _X_INLINE void* -ExaGetPixmapAddress(PixmapPtr p) -{ - ExaPixmapPriv(p); - - if (pExaPixmap->use_gpu_copy && pExaPixmap->fb_ptr) - return pExaPixmap->fb_ptr; - else - return pExaPixmap->sys_ptr; -} - -/** - * exaCreatePixmap() creates a new pixmap. - * - * If width and height are 0, this won't be a full-fledged pixmap and it will - * get ModifyPixmapHeader() called on it later. So, we mark it as pinned, because - * ModifyPixmapHeader() would break migration. These types of pixmaps are used - * for scratch pixmaps, or to represent the visible screen. - */ -PixmapPtr -exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth, - unsigned usage_hint) -{ - PixmapPtr pPixmap; - ExaPixmapPrivPtr pExaPixmap; - BoxRec box; - int bpp; - ExaScreenPriv(pScreen); - - if (w > 32767 || h > 32767) - return NullPixmap; - - swap(pExaScr, pScreen, CreatePixmap); - pPixmap = pScreen->CreatePixmap (pScreen, w, h, depth, usage_hint); - swap(pExaScr, pScreen, CreatePixmap); - - if (!pPixmap) - return NULL; - - pExaPixmap = ExaGetPixmapPriv(pPixmap); - pExaPixmap->driverPriv = NULL; - - bpp = pPixmap->drawable.bitsPerPixel; - - pExaPixmap->driverPriv = NULL; - /* Scratch pixmaps may have w/h equal to zero, and may not be - * migrated. - */ - if (!w || !h) - pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; - else - pExaPixmap->score = EXA_PIXMAP_SCORE_INIT; - - pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr; - pExaPixmap->sys_pitch = pPixmap->devKind; - - pPixmap->devPrivate.ptr = NULL; - pExaPixmap->use_gpu_copy = FALSE; - - pExaPixmap->fb_ptr = NULL; - exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp); - pExaPixmap->fb_size = pExaPixmap->fb_pitch * h; - - if (pExaPixmap->fb_pitch > 131071) { - swap(pExaScr, pScreen, DestroyPixmap); - pScreen->DestroyPixmap (pPixmap); - swap(pExaScr, pScreen, DestroyPixmap); - return NULL; - } - - /* Set up damage tracking */ - pExaPixmap->pDamage = DamageCreate (NULL, NULL, - DamageReportNone, TRUE, - pScreen, pPixmap); - - if (pExaPixmap->pDamage == NULL) { - swap(pExaScr, pScreen, DestroyPixmap); - pScreen->DestroyPixmap (pPixmap); - swap(pExaScr, pScreen, DestroyPixmap); - return NULL; - } - - DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage); - /* This ensures that pending damage reflects the current operation. */ - /* This is used by exa to optimize migration. */ - DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE); - - pExaPixmap->area = NULL; - - /* We set the initial pixmap as completely valid for a simple reason. - * Imagine a 1000x1000 pixmap, it has 1 million pixels, 250000 of which - * could form single pixel rects as part of a region. Setting the complete region - * as valid is a natural defragmentation of the region. - */ - box.x1 = 0; - box.y1 = 0; - box.x2 = w; - box.y2 = h; - RegionInit(&pExaPixmap->validSys, &box, 0); - RegionInit(&pExaPixmap->validFB, &box, 0); - - exaSetAccelBlock(pExaScr, pExaPixmap, - w, h, bpp); - - /* During a fallback we must prepare access. */ - if (pExaScr->fallback_counter) - exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST); - - return pPixmap; -} - -Bool -exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int depth, - int bitsPerPixel, int devKind, pointer pPixData) -{ - ScreenPtr pScreen; - ExaScreenPrivPtr pExaScr; - ExaPixmapPrivPtr pExaPixmap; - Bool ret; - - if (!pPixmap) - return FALSE; - - pScreen = pPixmap->drawable.pScreen; - pExaScr = ExaGetScreenPriv(pScreen); - pExaPixmap = ExaGetPixmapPriv(pPixmap); - - if (pExaPixmap) { - if (pPixData) - pExaPixmap->sys_ptr = pPixData; - - if (devKind > 0) - pExaPixmap->sys_pitch = devKind; - - /* Classic EXA: - * - Framebuffer. - * - Scratch pixmap with gpu memory. - */ - if (pExaScr->info->memoryBase && pPixData) { - if ((CARD8 *)pPixData >= pExaScr->info->memoryBase && - ((CARD8 *)pPixData - pExaScr->info->memoryBase) < - pExaScr->info->memorySize) { - pExaPixmap->fb_ptr = pPixData; - pExaPixmap->fb_pitch = devKind; - pExaPixmap->use_gpu_copy = TRUE; - } - } - - if (width > 0 && height > 0 && bitsPerPixel > 0) { - exaSetFbPitch(pExaScr, pExaPixmap, - width, height, bitsPerPixel); - - exaSetAccelBlock(pExaScr, pExaPixmap, - width, height, bitsPerPixel); - } - - /* Pixmaps subject to ModifyPixmapHeader will be pinned to system or - * gpu memory, so there's no need to track damage. - */ - if (pExaPixmap->pDamage) { - DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage); - DamageDestroy(pExaPixmap->pDamage); - pExaPixmap->pDamage = NULL; - } - } - - swap(pExaScr, pScreen, ModifyPixmapHeader); - ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth, - bitsPerPixel, devKind, pPixData); - swap(pExaScr, pScreen, ModifyPixmapHeader); - - /* Always NULL this, we don't want lingering pointers. */ - pPixmap->devPrivate.ptr = NULL; - - return ret; -} - -Bool -exaDestroyPixmap_classic (PixmapPtr pPixmap) -{ - ScreenPtr pScreen = pPixmap->drawable.pScreen; - ExaScreenPriv(pScreen); - Bool ret; - - if (pPixmap->refcnt == 1) - { - ExaPixmapPriv (pPixmap); - - exaDestroyPixmap(pPixmap); - - if (pExaPixmap->area) - { - DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n", - (void*)pPixmap->drawable.id, - ExaGetPixmapPriv(pPixmap)->area->offset, - pPixmap->drawable.width, - pPixmap->drawable.height)); - /* Free the offscreen area */ - exaOffscreenFree (pPixmap->drawable.pScreen, pExaPixmap->area); - pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; - pPixmap->devKind = pExaPixmap->sys_pitch; - } - RegionUninit(&pExaPixmap->validSys); - RegionUninit(&pExaPixmap->validFB); - } - - swap(pExaScr, pScreen, DestroyPixmap); - ret = pScreen->DestroyPixmap (pPixmap); - swap(pExaScr, pScreen, DestroyPixmap); - - return ret; -} - -Bool -exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap) -{ - ScreenPtr pScreen = pPixmap->drawable.pScreen; - ExaScreenPriv(pScreen); - ExaPixmapPriv(pPixmap); - Bool ret; - - if (pExaScr->info->PixmapIsOffscreen) { - void* old_ptr = pPixmap->devPrivate.ptr; - pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap); - ret = pExaScr->info->PixmapIsOffscreen(pPixmap); - pPixmap->devPrivate.ptr = old_ptr; - } else - ret = (pExaPixmap->use_gpu_copy && pExaPixmap->fb_ptr); - - return ret; -} +/* + * Copyright © 2009 Maarten Maathuis + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include "exa_priv.h" +#include "exa.h" + +/* This file holds the classic exa specific implementation. */ + +static _X_INLINE void* +ExaGetPixmapAddress(PixmapPtr p) +{ + ExaPixmapPriv(p); + + if (pExaPixmap->use_gpu_copy && pExaPixmap->fb_ptr) + return pExaPixmap->fb_ptr; + else + return pExaPixmap->sys_ptr; +} + +/** + * exaCreatePixmap() creates a new pixmap. + * + * If width and height are 0, this won't be a full-fledged pixmap and it will + * get ModifyPixmapHeader() called on it later. So, we mark it as pinned, because + * ModifyPixmapHeader() would break migration. These types of pixmaps are used + * for scratch pixmaps, or to represent the visible screen. + */ +PixmapPtr +exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth, + unsigned class) +{ + PixmapPtr pPixmap; + ExaPixmapPrivPtr pExaPixmap; + BoxRec box; + int bpp; + ExaScreenPriv(pScreen); + + if (w > 32767 || h > 32767) + return NullPixmap; + + swap(pExaScr, pScreen, CreatePixmap); + pPixmap = pScreen->CreatePixmap (pScreen, w, h, depth, class); + swap(pExaScr, pScreen, CreatePixmap); + + if (!pPixmap) + return NULL; + + pExaPixmap = ExaGetPixmapPriv(pPixmap); + pExaPixmap->driverPriv = NULL; + + bpp = pPixmap->drawable.bitsPerPixel; + + pExaPixmap->driverPriv = NULL; + /* Scratch pixmaps may have w/h equal to zero, and may not be + * migrated. + */ + if (!w || !h) + pExaPixmap->score = EXA_PIXMAP_SCORE_PINNED; + else + pExaPixmap->score = EXA_PIXMAP_SCORE_INIT; + + pExaPixmap->sys_ptr = pPixmap->devPrivate.ptr; + pExaPixmap->sys_pitch = pPixmap->devKind; + + pPixmap->devPrivate.ptr = NULL; + pExaPixmap->use_gpu_copy = FALSE; + + pExaPixmap->fb_ptr = NULL; + exaSetFbPitch(pExaScr, pExaPixmap, w, h, bpp); + pExaPixmap->fb_size = pExaPixmap->fb_pitch * h; + + if (pExaPixmap->fb_pitch > 131071) { + swap(pExaScr, pScreen, DestroyPixmap); + pScreen->DestroyPixmap (pPixmap); + swap(pExaScr, pScreen, DestroyPixmap); + return NULL; + } + + /* Set up damage tracking */ + pExaPixmap->pDamage = DamageCreate (NULL, NULL, + DamageReportNone, TRUE, + pScreen, pPixmap); + + if (pExaPixmap->pDamage == NULL) { + swap(pExaScr, pScreen, DestroyPixmap); + pScreen->DestroyPixmap (pPixmap); + swap(pExaScr, pScreen, DestroyPixmap); + return NULL; + } + + DamageRegister (&pPixmap->drawable, pExaPixmap->pDamage); + /* This ensures that pending damage reflects the current operation. */ + /* This is used by exa to optimize migration. */ + DamageSetReportAfterOp (pExaPixmap->pDamage, TRUE); + + pExaPixmap->area = NULL; + + /* We set the initial pixmap as completely valid for a simple reason. + * Imagine a 1000x1000 pixmap, it has 1 million pixels, 250000 of which + * could form single pixel rects as part of a region. Setting the complete region + * as valid is a natural defragmentation of the region. + */ + box.x1 = 0; + box.y1 = 0; + box.x2 = w; + box.y2 = h; + RegionInit(&pExaPixmap->validSys, &box, 0); + RegionInit(&pExaPixmap->validFB, &box, 0); + + exaSetAccelBlock(pExaScr, pExaPixmap, + w, h, bpp); + + /* During a fallback we must prepare access. */ + if (pExaScr->fallback_counter) + exaPrepareAccess(&pPixmap->drawable, EXA_PREPARE_AUX_DEST); + + return pPixmap; +} + +Bool +exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int depth, + int bitsPerPixel, int devKind, pointer pPixData) +{ + ScreenPtr pScreen; + ExaScreenPrivPtr pExaScr; + ExaPixmapPrivPtr pExaPixmap; + Bool ret; + + if (!pPixmap) + return FALSE; + + pScreen = pPixmap->drawable.pScreen; + pExaScr = ExaGetScreenPriv(pScreen); + pExaPixmap = ExaGetPixmapPriv(pPixmap); + + if (pExaPixmap) { + if (pPixData) + pExaPixmap->sys_ptr = pPixData; + + if (devKind > 0) + pExaPixmap->sys_pitch = devKind; + + /* Classic EXA: + * - Framebuffer. + * - Scratch pixmap with gpu memory. + */ + if (pExaScr->info->memoryBase && pPixData) { + if ((CARD8 *)pPixData >= pExaScr->info->memoryBase && + ((CARD8 *)pPixData - pExaScr->info->memoryBase) < + pExaScr->info->memorySize) { + pExaPixmap->fb_ptr = pPixData; + pExaPixmap->fb_pitch = devKind; + pExaPixmap->use_gpu_copy = TRUE; + } + } + + if (width > 0 && height > 0 && bitsPerPixel > 0) { + exaSetFbPitch(pExaScr, pExaPixmap, + width, height, bitsPerPixel); + + exaSetAccelBlock(pExaScr, pExaPixmap, + width, height, bitsPerPixel); + } + + /* Pixmaps subject to ModifyPixmapHeader will be pinned to system or + * gpu memory, so there's no need to track damage. + */ + if (pExaPixmap->pDamage) { + DamageUnregister(&pPixmap->drawable, pExaPixmap->pDamage); + DamageDestroy(pExaPixmap->pDamage); + pExaPixmap->pDamage = NULL; + } + } + + swap(pExaScr, pScreen, ModifyPixmapHeader); + ret = pScreen->ModifyPixmapHeader(pPixmap, width, height, depth, + bitsPerPixel, devKind, pPixData); + swap(pExaScr, pScreen, ModifyPixmapHeader); + + /* Always NULL this, we don't want lingering pointers. */ + pPixmap->devPrivate.ptr = NULL; + + return ret; +} + +Bool +exaDestroyPixmap_classic (PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ExaScreenPriv(pScreen); + Bool ret; + + if (pPixmap->refcnt == 1) + { + ExaPixmapPriv (pPixmap); + + exaDestroyPixmap(pPixmap); + + if (pExaPixmap->area) + { + DBG_PIXMAP(("-- 0x%p (0x%x) (%dx%d)\n", + (void*)pPixmap->drawable.id, + ExaGetPixmapPriv(pPixmap)->area->offset, + pPixmap->drawable.width, + pPixmap->drawable.height)); + /* Free the offscreen area */ + exaOffscreenFree (pPixmap->drawable.pScreen, pExaPixmap->area); + pPixmap->devPrivate.ptr = pExaPixmap->sys_ptr; + pPixmap->devKind = pExaPixmap->sys_pitch; + } + RegionUninit(&pExaPixmap->validSys); + RegionUninit(&pExaPixmap->validFB); + } + + swap(pExaScr, pScreen, DestroyPixmap); + ret = pScreen->DestroyPixmap (pPixmap); + swap(pExaScr, pScreen, DestroyPixmap); + + return ret; +} + +Bool +exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + ExaScreenPriv(pScreen); + ExaPixmapPriv(pPixmap); + Bool ret; + + if (pExaScr->info->PixmapIsOffscreen) { + void* old_ptr = pPixmap->devPrivate.ptr; + pPixmap->devPrivate.ptr = ExaGetPixmapAddress(pPixmap); + ret = pExaScr->info->PixmapIsOffscreen(pPixmap); + pPixmap->devPrivate.ptr = old_ptr; + } else + ret = (pExaPixmap->use_gpu_copy && pExaPixmap->fb_ptr); + + return ret; +} diff --git a/xorg-server/exa/exa_driver.c b/xorg-server/exa/exa_driver.c index b9903d1bc..4d2a1a5df 100644 --- a/xorg-server/exa/exa_driver.c +++ b/xorg-server/exa/exa_driver.c @@ -48,7 +48,7 @@ ExaGetPixmapAddress(PixmapPtr p) */ PixmapPtr exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth, - unsigned usage_hint) + unsigned class) { PixmapPtr pPixmap; ExaPixmapPrivPtr pExaPixmap; @@ -60,7 +60,7 @@ exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth, return NullPixmap; swap(pExaScr, pScreen, CreatePixmap); - pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, usage_hint); + pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, class); swap(pExaScr, pScreen, CreatePixmap); if (!pPixmap) @@ -78,7 +78,7 @@ exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth, if (pExaScr->info->CreatePixmap2) { int new_pitch = 0; - pExaPixmap->driverPriv = pExaScr->info->CreatePixmap2(pScreen, w, h, depth, usage_hint, bpp, &new_pitch); + pExaPixmap->driverPriv = pExaScr->info->CreatePixmap2(pScreen, w, h, depth, class, bpp, &new_pitch); paddedWidth = pExaPixmap->fb_pitch = new_pitch; } else { diff --git a/xorg-server/exa/exa_migration_mixed.c b/xorg-server/exa/exa_migration_mixed.c index fb4715135..a563357be 100644 --- a/xorg-server/exa/exa_migration_mixed.c +++ b/xorg-server/exa/exa_migration_mixed.c @@ -39,7 +39,7 @@ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap) ExaPixmapPriv(pPixmap); int w = pPixmap->drawable.width, h = pPixmap->drawable.height; int depth = pPixmap->drawable.depth, bpp = pPixmap->drawable.bitsPerPixel; - int usage_hint = pPixmap->usage_hint; + int class = pPixmap->drawable.class; int paddedWidth = pExaPixmap->sys_pitch; /* Already done. */ @@ -55,7 +55,7 @@ exaCreateDriverPixmap_mixed(PixmapPtr pPixmap) if (pExaScr->info->CreatePixmap2) { int new_pitch = 0; - pExaPixmap->driverPriv = pExaScr->info->CreatePixmap2(pScreen, w, h, depth, usage_hint, bpp, &new_pitch); + pExaPixmap->driverPriv = pExaScr->info->CreatePixmap2(pScreen, w, h, depth, class, bpp, &new_pitch); paddedWidth = pExaPixmap->fb_pitch = new_pitch; } else { if (paddedWidth < pExaPixmap->fb_pitch) diff --git a/xorg-server/exa/exa_mixed.c b/xorg-server/exa/exa_mixed.c index fd1afb246..24fce7645 100644 --- a/xorg-server/exa/exa_mixed.c +++ b/xorg-server/exa/exa_mixed.c @@ -47,7 +47,7 @@ ExaGetPixmapAddress(PixmapPtr p) */ PixmapPtr exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth, - unsigned usage_hint) + unsigned class) { PixmapPtr pPixmap; ExaPixmapPrivPtr pExaPixmap; @@ -59,7 +59,7 @@ exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth, return NullPixmap; swap(pExaScr, pScreen, CreatePixmap); - pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, usage_hint); + pPixmap = pScreen->CreatePixmap(pScreen, 0, 0, depth, class); swap(pExaScr, pScreen, CreatePixmap); if (!pPixmap) diff --git a/xorg-server/exa/exa_priv.h b/xorg-server/exa/exa_priv.h index 1b8cf294a..1f6dede94 100644 --- a/xorg-server/exa/exa_priv.h +++ b/xorg-server/exa/exa_priv.h @@ -1,725 +1,725 @@ -/* - * - * Copyright (C) 2000 Keith Packard, member of The XFree86 Project, Inc. - * 2005 Zack Rusin, Trolltech - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS - * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND - * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY - * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN - * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING - * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS - * SOFTWARE. - */ - -#ifndef EXAPRIV_H -#define EXAPRIV_H - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include "exa.h" - -#include -#include -#ifdef MITSHM -#include "shmint.h" -#endif -#include "scrnintstr.h" -#include "pixmapstr.h" -#include "windowstr.h" -#include "servermd.h" -#include "mibstore.h" -#include "colormapst.h" -#include "gcstruct.h" -#include "input.h" -#include "mipointer.h" -#include "mi.h" -#include "dix.h" -#include "fb.h" -#include "fboverlay.h" -#include "fbpict.h" -#include "glyphstr.h" -#include "damage.h" - -#define DEBUG_TRACE_FALL 0 -#define DEBUG_MIGRATE 0 -#define DEBUG_PIXMAP 0 -#define DEBUG_OFFSCREEN 0 -#define DEBUG_GLYPH_CACHE 0 - -#if DEBUG_TRACE_FALL -#define EXA_FALLBACK(x) \ -do { \ - ErrorF("EXA fallback at %s: ", __FUNCTION__); \ - ErrorF x; \ -} while (0) - -char -exaDrawableLocation(DrawablePtr pDrawable); -#else -#define EXA_FALLBACK(x) -#endif - -#if DEBUG_PIXMAP -#define DBG_PIXMAP(a) ErrorF a -#else -#define DBG_PIXMAP(a) -#endif - -#ifndef EXA_MAX_FB -#define EXA_MAX_FB FB_OVERLAY_MAX -#endif - -#ifdef DEBUG -#define EXA_FatalErrorDebug(x) FatalError x -#define EXA_FatalErrorDebugWithRet(x, ret) FatalError x -#else -#define EXA_FatalErrorDebug(x) ErrorF x -#define EXA_FatalErrorDebugWithRet(x, ret) \ -do { \ - ErrorF x; \ - return ret; \ -} while (0) -#endif - -/** - * This is the list of migration heuristics supported by EXA. See - * exaDoMigration() for what their implementations do. - */ -enum ExaMigrationHeuristic { - ExaMigrationGreedy, - ExaMigrationAlways, - ExaMigrationSmart -}; - -typedef struct { - unsigned char sha1[20]; -} ExaCachedGlyphRec, *ExaCachedGlyphPtr; - -typedef struct { - /* The identity of the cache, statically configured at initialization */ - unsigned int format; - int glyphWidth; - int glyphHeight; - - int size; /* Size of cache; eventually this should be dynamically determined */ - - /* Hash table mapping from glyph sha1 to position in the glyph; we use - * open addressing with a hash table size determined based on size and large - * enough so that we always have a good amount of free space, so we can - * use linear probing. (Linear probing is preferrable to double hashing - * here because it allows us to easily remove entries.) - */ - int *hashEntries; - int hashSize; - - ExaCachedGlyphPtr glyphs; - int glyphCount; /* Current number of glyphs */ - - PicturePtr picture; /* Where the glyphs of the cache are stored */ - int yOffset; /* y location within the picture where the cache starts */ - int columns; /* Number of columns the glyphs are layed out in */ - int evictionPosition; /* Next random position to evict a glyph */ -} ExaGlyphCacheRec, *ExaGlyphCachePtr; - -#define EXA_NUM_GLYPH_CACHES 4 - -#define EXA_FALLBACK_COPYWINDOW (1 << 0) -#define EXA_ACCEL_COPYWINDOW (1 << 1) - -typedef struct _ExaMigrationRec { - Bool as_dst; - Bool as_src; - PixmapPtr pPix; - RegionPtr pReg; -} ExaMigrationRec, *ExaMigrationPtr; - -typedef void (*EnableDisableFBAccessProcPtr)(int, Bool); -typedef struct { - ExaDriverPtr info; - ScreenBlockHandlerProcPtr SavedBlockHandler; - ScreenWakeupHandlerProcPtr SavedWakeupHandler; - CreateGCProcPtr SavedCreateGC; - CloseScreenProcPtr SavedCloseScreen; - GetImageProcPtr SavedGetImage; - GetSpansProcPtr SavedGetSpans; - CreatePixmapProcPtr SavedCreatePixmap; - DestroyPixmapProcPtr SavedDestroyPixmap; - CopyWindowProcPtr SavedCopyWindow; - ChangeWindowAttributesProcPtr SavedChangeWindowAttributes; - BitmapToRegionProcPtr SavedBitmapToRegion; - CreateScreenResourcesProcPtr SavedCreateScreenResources; - ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader; - SourceValidateProcPtr SavedSourceValidate; - CompositeProcPtr SavedComposite; - TrianglesProcPtr SavedTriangles; - GlyphsProcPtr SavedGlyphs; - TrapezoidsProcPtr SavedTrapezoids; - AddTrapsProcPtr SavedAddTraps; - void (*do_migration) (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); - Bool (*pixmap_has_gpu_copy) (PixmapPtr pPixmap); - void (*do_move_in_pixmap) (PixmapPtr pPixmap); - void (*do_move_out_pixmap) (PixmapPtr pPixmap); - void (*prepare_access_reg)(PixmapPtr pPixmap, int index, RegionPtr pReg); - - Bool swappedOut; - enum ExaMigrationHeuristic migration; - Bool checkDirtyCorrectness; - unsigned disableFbCount; - Bool optimize_migration; - unsigned offScreenCounter; - unsigned numOffscreenAvailable; - CARD32 lastDefragment; - CARD32 nextDefragment; - PixmapPtr deferred_mixed_pixmap; - - /* Reference counting for accessed pixmaps */ - struct { - PixmapPtr pixmap; - int count; - Bool retval; - } access[EXA_NUM_PREPARE_INDICES]; - - /* Holds information on fallbacks that cannot be relayed otherwise. */ - unsigned int fallback_flags; - unsigned int fallback_counter; - - ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES]; - - /** - * Regions affected by fallback composite source / mask operations. - */ - - RegionRec srcReg; - RegionRec maskReg; - PixmapPtr srcPix; - -} ExaScreenPrivRec, *ExaScreenPrivPtr; - -/* - * This is the only completely portable way to - * compute this info. - */ -#ifndef BitsPerPixel -#define BitsPerPixel(d) (\ - PixmapWidthPaddingInfo[d].notPower2 ? \ - (PixmapWidthPaddingInfo[d].bytesPerPixel * 8) : \ - ((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \ - (PixmapWidthPaddingInfo[d].padRoundUp+1))) -#endif - -extern DevPrivateKeyRec exaScreenPrivateKeyRec; -#define exaScreenPrivateKey (&exaScreenPrivateKeyRec) -extern DevPrivateKeyRec exaPixmapPrivateKeyRec; -#define exaPixmapPrivateKey (&exaPixmapPrivateKeyRec) -extern DevPrivateKeyRec exaGCPrivateKeyRec; -#define exaGCPrivateKey (&exaGCPrivateKeyRec) - -#define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)dixLookupPrivate(&(s)->devPrivates, exaScreenPrivateKey)) -#define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s) - -#define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixLookupPrivate(&(gc)->devPrivates, exaGCPrivateKey)) -#define ExaGCPriv(gc) ExaGCPrivPtr pExaGC = ExaGetGCPriv(gc) - -/* - * Some macros to deal with function wrapping. - */ -#define wrap(priv, real, mem, func) {\ - priv->Saved##mem = real->mem; \ - real->mem = func; \ -} - -#define unwrap(priv, real, mem) {\ - real->mem = priv->Saved##mem; \ -} - -#define swap(priv, real, mem) {\ - void *tmp = priv->Saved##mem; \ - priv->Saved##mem = real->mem; \ - real->mem = tmp; \ -} - -#define EXA_PRE_FALLBACK(_screen_) \ - ExaScreenPriv(_screen_); \ - pExaScr->fallback_counter++; - -#define EXA_POST_FALLBACK(_screen_) \ - pExaScr->fallback_counter--; - -#define EXA_PRE_FALLBACK_GC(_gc_) \ - ExaScreenPriv(_gc_->pScreen); \ - ExaGCPriv(_gc_); \ - pExaScr->fallback_counter++; \ - swap(pExaGC, _gc_, ops); - -#define EXA_POST_FALLBACK_GC(_gc_) \ - pExaScr->fallback_counter--; \ - swap(pExaGC, _gc_, ops); - -/** Align an offset to an arbitrary alignment */ -#define EXA_ALIGN(offset, align) (((offset) + (align) - 1) - \ - (((offset) + (align) - 1) % (align))) -/** Align an offset to a power-of-two alignment */ -#define EXA_ALIGN2(offset, align) (((offset) + (align) - 1) & ~((align) - 1)) - -#define EXA_PIXMAP_SCORE_MOVE_IN 10 -#define EXA_PIXMAP_SCORE_MAX 20 -#define EXA_PIXMAP_SCORE_MOVE_OUT -10 -#define EXA_PIXMAP_SCORE_MIN -20 -#define EXA_PIXMAP_SCORE_PINNED 1000 -#define EXA_PIXMAP_SCORE_INIT 1001 - -#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixLookupPrivate(&(p)->devPrivates, exaPixmapPrivateKey)) -#define ExaSetPixmapPriv(p,a) dixSetPrivate(&(p)->devPrivates, exaPixmapPrivateKey, a) -#define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p) - -#define EXA_RANGE_PITCH (1 << 0) -#define EXA_RANGE_WIDTH (1 << 1) -#define EXA_RANGE_HEIGHT (1 << 2) - -typedef struct { - ExaOffscreenArea *area; - int score; /**< score for the move-in vs move-out heuristic */ - Bool use_gpu_copy; - - CARD8 *sys_ptr; /**< pointer to pixmap data in system memory */ - int sys_pitch; /**< pitch of pixmap in system memory */ - - CARD8 *fb_ptr; /**< pointer to pixmap data in framebuffer memory */ - int fb_pitch; /**< pitch of pixmap in framebuffer memory */ - unsigned int fb_size; /**< size of pixmap in framebuffer memory */ - - /** - * Holds information about whether this pixmap can be used for - * acceleration (== 0) or not (> 0). - * - * Contains a OR'ed combination of the following values: - * EXA_RANGE_PITCH - set if the pixmap's pitch is out of range - * EXA_RANGE_WIDTH - set if the pixmap's width is out of range - * EXA_RANGE_HEIGHT - set if the pixmap's height is out of range - */ - unsigned int accel_blocked; - - /** - * The damage record contains the areas of the pixmap's current location - * (framebuffer or system) that have been damaged compared to the other - * location. - */ - DamagePtr pDamage; - /** - * The valid regions mark the valid bits (at least, as they're derived from - * damage, which may be overreported) of a pixmap's system and FB copies. - */ - RegionRec validSys, validFB; - /** - * Driver private storage per EXA pixmap - */ - void *driverPriv; -} ExaPixmapPrivRec, *ExaPixmapPrivPtr; - -typedef struct { - /* GC values from the layer below. */ - GCOps *Savedops; - GCFuncs *Savedfuncs; -} ExaGCPrivRec, *ExaGCPrivPtr; - -typedef struct { - PicturePtr pDst; - INT16 xSrc; - INT16 ySrc; - INT16 xMask; - INT16 yMask; - INT16 xDst; - INT16 yDst; - INT16 width; - INT16 height; -} ExaCompositeRectRec, *ExaCompositeRectPtr; - -/** - * exaDDXDriverInit must be implemented by the DDX using EXA, and is the place - * to set EXA options or hook in screen functions to handle using EXA as the AA. - */ -void exaDDXDriverInit (ScreenPtr pScreen); - -/* exa_unaccel.c */ -void -exaPrepareAccessGC(GCPtr pGC); - -void -exaFinishAccessGC(GCPtr pGC); - -void -ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans, - DDXPointPtr ppt, int *pwidth, int fSorted); - -void -ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc, - DDXPointPtr ppt, int *pwidth, int nspans, int fSorted); - -void -ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, - int x, int y, int w, int h, int leftPad, int format, - char *bits); - -void -ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, - Bool upsidedown, Pixel bitplane, void *closure); - -RegionPtr -ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, int dstx, int dsty); - -RegionPtr -ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, int dstx, int dsty, - unsigned long bitPlane); - -void -ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr pptInit); - -void -ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC, - int mode, int npt, DDXPointPtr ppt); - -void -ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC, - int nsegInit, xSegment *pSegInit); - -void -ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC, - int narcs, xArc *pArcs); - -void -ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC, - int nrect, xRectangle *prect); - -void -ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, pointer pglyphBase); - -void -ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, pointer pglyphBase); - -void -ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap, - DrawablePtr pDrawable, - int w, int h, int x, int y); - -void -ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); - -void -ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d); - -void -ExaCheckGetSpans (DrawablePtr pDrawable, - int wMax, - DDXPointPtr ppt, - int *pwidth, - int nspans, - char *pdstStart); - -void -ExaCheckAddTraps (PicturePtr pPicture, - INT16 x_off, - INT16 y_off, - int ntrap, - xTrap *traps); - -/* exa_accel.c */ - -static _X_INLINE Bool -exaGCReadsDestination(DrawablePtr pDrawable, unsigned long planemask, - unsigned int fillStyle, unsigned char alu, - unsigned int clientClipType) -{ - return ((alu != GXcopy && alu != GXclear && alu != GXset && - alu != GXcopyInverted) || fillStyle == FillStippled || - clientClipType != CT_NONE || !EXA_PM_IS_SOLID(pDrawable, planemask)); -} - -void -exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); - -Bool -exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, - DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu, - unsigned int clientClipType); - -void -exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d); - -RegionPtr -exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, - int srcx, int srcy, int width, int height, int dstx, int dsty); - -Bool -exaHWCopyNtoN (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pbox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown); - -void -exaCopyNtoN (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pbox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure); - -extern const GCOps exaOps; - -void -ExaCheckComposite (CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height); - -void -ExaCheckGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs); - -/* exa_offscreen.c */ -void -ExaOffscreenSwapOut (ScreenPtr pScreen); - -void -ExaOffscreenSwapIn (ScreenPtr pScreen); - -ExaOffscreenArea* -ExaOffscreenDefragment (ScreenPtr pScreen); - -Bool -exaOffscreenInit(ScreenPtr pScreen); - -void -ExaOffscreenFini (ScreenPtr pScreen); - -/* exa.c */ -Bool -ExaDoPrepareAccess(PixmapPtr pPixmap, int index); - -void -exaPrepareAccess(DrawablePtr pDrawable, int index); - -void -exaFinishAccess(DrawablePtr pDrawable, int index); - -void -exaDestroyPixmap(PixmapPtr pPixmap); - -void -exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2); - -void -exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap, - int *xp, int *yp); - -Bool -exaPixmapHasGpuCopy(PixmapPtr p); - -PixmapPtr -exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp); - -PixmapPtr -exaGetDrawablePixmap(DrawablePtr pDrawable); - -void -exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, - int w, int h, int bpp); - -void -exaSetAccelBlock(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, - int w, int h, int bpp); - -void -exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); - -Bool -exaPixmapIsPinned (PixmapPtr pPix); - -extern const GCFuncs exaGCFuncs; - -/* exa_classic.c */ -PixmapPtr -exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth, - unsigned usage_hint); - -Bool -exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int depth, - int bitsPerPixel, int devKind, pointer pPixData); - -Bool -exaDestroyPixmap_classic (PixmapPtr pPixmap); - -Bool -exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap); - -/* exa_driver.c */ -PixmapPtr -exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth, - unsigned usage_hint); - -Bool -exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height, int depth, - int bitsPerPixel, int devKind, pointer pPixData); - -Bool -exaDestroyPixmap_driver (PixmapPtr pPixmap); - -Bool -exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap); - -/* exa_mixed.c */ -PixmapPtr -exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth, - unsigned usage_hint); - -Bool -exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth, - int bitsPerPixel, int devKind, pointer pPixData); - -Bool -exaDestroyPixmap_mixed(PixmapPtr pPixmap); - -Bool -exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap); - -/* exa_migration_mixed.c */ -void -exaCreateDriverPixmap_mixed(PixmapPtr pPixmap); - -void -exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); - -void -exaMoveInPixmap_mixed(PixmapPtr pPixmap); - -void -exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure); - -void -exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg); - -/* exa_render.c */ -Bool -exaOpReadsDestination (CARD8 op); - -void -exaComposite(CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height); - -void -exaCompositeRects(CARD8 op, - PicturePtr Src, - PicturePtr pMask, - PicturePtr pDst, - int nrect, - ExaCompositeRectPtr rects); - -void -exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, - int ntrap, xTrapezoid *traps); - -void -exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, - int ntri, xTriangle *tris); - -/* exa_glyph.c */ -void -exaGlyphsInit(ScreenPtr pScreen); - -void -exaGlyphsFini (ScreenPtr pScreen); - -void -exaGlyphs (CARD8 op, - PicturePtr pSrc, - PicturePtr pDst, - PictFormatPtr maskFormat, - INT16 xSrc, - INT16 ySrc, - int nlist, - GlyphListPtr list, - GlyphPtr *glyphs); - -/* exa_migration_classic.c */ -void -exaCopyDirtyToSys (ExaMigrationPtr migrate); - -void -exaCopyDirtyToFb (ExaMigrationPtr migrate); - -void -exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); - -void -exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area); - -void -exaMoveOutPixmap_classic (PixmapPtr pPixmap); - -void -exaMoveInPixmap_classic (PixmapPtr pPixmap); - -void -exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg); - -#endif /* EXAPRIV_H */ +/* + * + * Copyright (C) 2000 Keith Packard, member of The XFree86 Project, Inc. + * 2005 Zack Rusin, Trolltech + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS + * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY + * SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + * AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#ifndef EXAPRIV_H +#define EXAPRIV_H + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include "exa.h" + +#include +#include +#ifdef MITSHM +#include "shmint.h" +#endif +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "servermd.h" +#include "mibstore.h" +#include "colormapst.h" +#include "gcstruct.h" +#include "input.h" +#include "mipointer.h" +#include "mi.h" +#include "dix.h" +#include "fb.h" +#include "fboverlay.h" +#include "fbpict.h" +#include "glyphstr.h" +#include "damage.h" + +#define DEBUG_TRACE_FALL 0 +#define DEBUG_MIGRATE 0 +#define DEBUG_PIXMAP 0 +#define DEBUG_OFFSCREEN 0 +#define DEBUG_GLYPH_CACHE 0 + +#if DEBUG_TRACE_FALL +#define EXA_FALLBACK(x) \ +do { \ + ErrorF("EXA fallback at %s: ", __FUNCTION__); \ + ErrorF x; \ +} while (0) + +char +exaDrawableLocation(DrawablePtr pDrawable); +#else +#define EXA_FALLBACK(x) +#endif + +#if DEBUG_PIXMAP +#define DBG_PIXMAP(a) ErrorF a +#else +#define DBG_PIXMAP(a) +#endif + +#ifndef EXA_MAX_FB +#define EXA_MAX_FB FB_OVERLAY_MAX +#endif + +#ifdef DEBUG +#define EXA_FatalErrorDebug(x) FatalError x +#define EXA_FatalErrorDebugWithRet(x, ret) FatalError x +#else +#define EXA_FatalErrorDebug(x) ErrorF x +#define EXA_FatalErrorDebugWithRet(x, ret) \ +do { \ + ErrorF x; \ + return ret; \ +} while (0) +#endif + +/** + * This is the list of migration heuristics supported by EXA. See + * exaDoMigration() for what their implementations do. + */ +enum ExaMigrationHeuristic { + ExaMigrationGreedy, + ExaMigrationAlways, + ExaMigrationSmart +}; + +typedef struct { + unsigned char sha1[20]; +} ExaCachedGlyphRec, *ExaCachedGlyphPtr; + +typedef struct { + /* The identity of the cache, statically configured at initialization */ + unsigned int format; + int glyphWidth; + int glyphHeight; + + int size; /* Size of cache; eventually this should be dynamically determined */ + + /* Hash table mapping from glyph sha1 to position in the glyph; we use + * open addressing with a hash table size determined based on size and large + * enough so that we always have a good amount of free space, so we can + * use linear probing. (Linear probing is preferrable to double hashing + * here because it allows us to easily remove entries.) + */ + int *hashEntries; + int hashSize; + + ExaCachedGlyphPtr glyphs; + int glyphCount; /* Current number of glyphs */ + + PicturePtr picture; /* Where the glyphs of the cache are stored */ + int yOffset; /* y location within the picture where the cache starts */ + int columns; /* Number of columns the glyphs are layed out in */ + int evictionPosition; /* Next random position to evict a glyph */ +} ExaGlyphCacheRec, *ExaGlyphCachePtr; + +#define EXA_NUM_GLYPH_CACHES 4 + +#define EXA_FALLBACK_COPYWINDOW (1 << 0) +#define EXA_ACCEL_COPYWINDOW (1 << 1) + +typedef struct _ExaMigrationRec { + Bool as_dst; + Bool as_src; + PixmapPtr pPix; + RegionPtr pReg; +} ExaMigrationRec, *ExaMigrationPtr; + +typedef void (*EnableDisableFBAccessProcPtr)(int, Bool); +typedef struct { + ExaDriverPtr info; + ScreenBlockHandlerProcPtr SavedBlockHandler; + ScreenWakeupHandlerProcPtr SavedWakeupHandler; + CreateGCProcPtr SavedCreateGC; + CloseScreenProcPtr SavedCloseScreen; + GetImageProcPtr SavedGetImage; + GetSpansProcPtr SavedGetSpans; + CreatePixmapProcPtr SavedCreatePixmap; + DestroyPixmapProcPtr SavedDestroyPixmap; + CopyWindowProcPtr SavedCopyWindow; + ChangeWindowAttributesProcPtr SavedChangeWindowAttributes; + BitmapToRegionProcPtr SavedBitmapToRegion; + CreateScreenResourcesProcPtr SavedCreateScreenResources; + ModifyPixmapHeaderProcPtr SavedModifyPixmapHeader; + SourceValidateProcPtr SavedSourceValidate; + CompositeProcPtr SavedComposite; + TrianglesProcPtr SavedTriangles; + GlyphsProcPtr SavedGlyphs; + TrapezoidsProcPtr SavedTrapezoids; + AddTrapsProcPtr SavedAddTraps; + void (*do_migration) (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); + Bool (*pixmap_has_gpu_copy) (PixmapPtr pPixmap); + void (*do_move_in_pixmap) (PixmapPtr pPixmap); + void (*do_move_out_pixmap) (PixmapPtr pPixmap); + void (*prepare_access_reg)(PixmapPtr pPixmap, int index, RegionPtr pReg); + + Bool swappedOut; + enum ExaMigrationHeuristic migration; + Bool checkDirtyCorrectness; + unsigned disableFbCount; + Bool optimize_migration; + unsigned offScreenCounter; + unsigned numOffscreenAvailable; + CARD32 lastDefragment; + CARD32 nextDefragment; + PixmapPtr deferred_mixed_pixmap; + + /* Reference counting for accessed pixmaps */ + struct { + PixmapPtr pixmap; + int count; + Bool retval; + } access[EXA_NUM_PREPARE_INDICES]; + + /* Holds information on fallbacks that cannot be relayed otherwise. */ + unsigned int fallback_flags; + unsigned int fallback_counter; + + ExaGlyphCacheRec glyphCaches[EXA_NUM_GLYPH_CACHES]; + + /** + * Regions affected by fallback composite source / mask operations. + */ + + RegionRec srcReg; + RegionRec maskReg; + PixmapPtr srcPix; + +} ExaScreenPrivRec, *ExaScreenPrivPtr; + +/* + * This is the only completely portable way to + * compute this info. + */ +#ifndef BitsPerPixel +#define BitsPerPixel(d) (\ + PixmapWidthPaddingInfo[d].notPower2 ? \ + (PixmapWidthPaddingInfo[d].bytesPerPixel * 8) : \ + ((1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \ + (PixmapWidthPaddingInfo[d].padRoundUp+1))) +#endif + +extern DevPrivateKeyRec exaScreenPrivateKeyRec; +#define exaScreenPrivateKey (&exaScreenPrivateKeyRec) +extern DevPrivateKeyRec exaPixmapPrivateKeyRec; +#define exaPixmapPrivateKey (&exaPixmapPrivateKeyRec) +extern DevPrivateKeyRec exaGCPrivateKeyRec; +#define exaGCPrivateKey (&exaGCPrivateKeyRec) + +#define ExaGetScreenPriv(s) ((ExaScreenPrivPtr)dixLookupPrivate(&(s)->devPrivates, exaScreenPrivateKey)) +#define ExaScreenPriv(s) ExaScreenPrivPtr pExaScr = ExaGetScreenPriv(s) + +#define ExaGetGCPriv(gc) ((ExaGCPrivPtr)dixLookupPrivate(&(gc)->devPrivates, exaGCPrivateKey)) +#define ExaGCPriv(gc) ExaGCPrivPtr pExaGC = ExaGetGCPriv(gc) + +/* + * Some macros to deal with function wrapping. + */ +#define wrap(priv, real, mem, func) {\ + priv->Saved##mem = real->mem; \ + real->mem = func; \ +} + +#define unwrap(priv, real, mem) {\ + real->mem = priv->Saved##mem; \ +} + +#define swap(priv, real, mem) {\ + void *tmp = priv->Saved##mem; \ + priv->Saved##mem = real->mem; \ + real->mem = tmp; \ +} + +#define EXA_PRE_FALLBACK(_screen_) \ + ExaScreenPriv(_screen_); \ + pExaScr->fallback_counter++; + +#define EXA_POST_FALLBACK(_screen_) \ + pExaScr->fallback_counter--; + +#define EXA_PRE_FALLBACK_GC(_gc_) \ + ExaScreenPriv(_gc_->pScreen); \ + ExaGCPriv(_gc_); \ + pExaScr->fallback_counter++; \ + swap(pExaGC, _gc_, ops); + +#define EXA_POST_FALLBACK_GC(_gc_) \ + pExaScr->fallback_counter--; \ + swap(pExaGC, _gc_, ops); + +/** Align an offset to an arbitrary alignment */ +#define EXA_ALIGN(offset, align) (((offset) + (align) - 1) - \ + (((offset) + (align) - 1) % (align))) +/** Align an offset to a power-of-two alignment */ +#define EXA_ALIGN2(offset, align) (((offset) + (align) - 1) & ~((align) - 1)) + +#define EXA_PIXMAP_SCORE_MOVE_IN 10 +#define EXA_PIXMAP_SCORE_MAX 20 +#define EXA_PIXMAP_SCORE_MOVE_OUT -10 +#define EXA_PIXMAP_SCORE_MIN -20 +#define EXA_PIXMAP_SCORE_PINNED 1000 +#define EXA_PIXMAP_SCORE_INIT 1001 + +#define ExaGetPixmapPriv(p) ((ExaPixmapPrivPtr)dixLookupPrivate(&(p)->devPrivates, exaPixmapPrivateKey)) +#define ExaSetPixmapPriv(p,a) dixSetPrivate(&(p)->devPrivates, exaPixmapPrivateKey, a) +#define ExaPixmapPriv(p) ExaPixmapPrivPtr pExaPixmap = ExaGetPixmapPriv(p) + +#define EXA_RANGE_PITCH (1 << 0) +#define EXA_RANGE_WIDTH (1 << 1) +#define EXA_RANGE_HEIGHT (1 << 2) + +typedef struct { + ExaOffscreenArea *area; + int score; /**< score for the move-in vs move-out heuristic */ + Bool use_gpu_copy; + + CARD8 *sys_ptr; /**< pointer to pixmap data in system memory */ + int sys_pitch; /**< pitch of pixmap in system memory */ + + CARD8 *fb_ptr; /**< pointer to pixmap data in framebuffer memory */ + int fb_pitch; /**< pitch of pixmap in framebuffer memory */ + unsigned int fb_size; /**< size of pixmap in framebuffer memory */ + + /** + * Holds information about whether this pixmap can be used for + * acceleration (== 0) or not (> 0). + * + * Contains a OR'ed combination of the following values: + * EXA_RANGE_PITCH - set if the pixmap's pitch is out of range + * EXA_RANGE_WIDTH - set if the pixmap's width is out of range + * EXA_RANGE_HEIGHT - set if the pixmap's height is out of range + */ + unsigned int accel_blocked; + + /** + * The damage record contains the areas of the pixmap's current location + * (framebuffer or system) that have been damaged compared to the other + * location. + */ + DamagePtr pDamage; + /** + * The valid regions mark the valid bits (at least, as they're derived from + * damage, which may be overreported) of a pixmap's system and FB copies. + */ + RegionRec validSys, validFB; + /** + * Driver private storage per EXA pixmap + */ + void *driverPriv; +} ExaPixmapPrivRec, *ExaPixmapPrivPtr; + +typedef struct { + /* GC values from the layer below. */ + GCOps *Savedops; + GCFuncs *Savedfuncs; +} ExaGCPrivRec, *ExaGCPrivPtr; + +typedef struct { + PicturePtr pDst; + INT16 xSrc; + INT16 ySrc; + INT16 xMask; + INT16 yMask; + INT16 xDst; + INT16 yDst; + INT16 width; + INT16 height; +} ExaCompositeRectRec, *ExaCompositeRectPtr; + +/** + * exaDDXDriverInit must be implemented by the DDX using EXA, and is the place + * to set EXA options or hook in screen functions to handle using EXA as the AA. + */ +void exaDDXDriverInit (ScreenPtr pScreen); + +/* exa_unaccel.c */ +void +exaPrepareAccessGC(GCPtr pGC); + +void +exaFinishAccessGC(GCPtr pGC); + +void +ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans, + DDXPointPtr ppt, int *pwidth, int fSorted); + +void +ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc, + DDXPointPtr ppt, int *pwidth, int nspans, int fSorted); + +void +ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, + int x, int y, int w, int h, int leftPad, int format, + char *bits); + +void +ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, + Bool upsidedown, Pixel bitplane, void *closure); + +RegionPtr +ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + int srcx, int srcy, int w, int h, int dstx, int dsty); + +RegionPtr +ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + int srcx, int srcy, int w, int h, int dstx, int dsty, + unsigned long bitPlane); + +void +ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, + DDXPointPtr pptInit); + +void +ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC, + int mode, int npt, DDXPointPtr ppt); + +void +ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC, + int nsegInit, xSegment *pSegInit); + +void +ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC, + int narcs, xArc *pArcs); + +void +ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC, + int nrect, xRectangle *prect); + +void +ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr *ppci, pointer pglyphBase); + +void +ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, + int x, int y, unsigned int nglyph, + CharInfoPtr *ppci, pointer pglyphBase); + +void +ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap, + DrawablePtr pDrawable, + int w, int h, int x, int y); + +void +ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); + +void +ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, + unsigned int format, unsigned long planeMask, char *d); + +void +ExaCheckGetSpans (DrawablePtr pDrawable, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pdstStart); + +void +ExaCheckAddTraps (PicturePtr pPicture, + INT16 x_off, + INT16 y_off, + int ntrap, + xTrap *traps); + +/* exa_accel.c */ + +static _X_INLINE Bool +exaGCReadsDestination(DrawablePtr pDrawable, unsigned long planemask, + unsigned int fillStyle, unsigned char alu, + unsigned int clientClipType) +{ + return ((alu != GXcopy && alu != GXclear && alu != GXset && + alu != GXcopyInverted) || fillStyle == FillStippled || + clientClipType != CT_NONE || !EXA_PM_IS_SOLID(pDrawable, planemask)); +} + +void +exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc); + +Bool +exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, + DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu, + unsigned int clientClipType); + +void +exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, + unsigned int format, unsigned long planeMask, char *d); + +RegionPtr +exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, + int srcx, int srcy, int width, int height, int dstx, int dsty); + +Bool +exaHWCopyNtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown); + +void +exaCopyNtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +extern const GCOps exaOps; + +void +ExaCheckComposite (CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +ExaCheckGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr list, + GlyphPtr *glyphs); + +/* exa_offscreen.c */ +void +ExaOffscreenSwapOut (ScreenPtr pScreen); + +void +ExaOffscreenSwapIn (ScreenPtr pScreen); + +ExaOffscreenArea* +ExaOffscreenDefragment (ScreenPtr pScreen); + +Bool +exaOffscreenInit(ScreenPtr pScreen); + +void +ExaOffscreenFini (ScreenPtr pScreen); + +/* exa.c */ +Bool +ExaDoPrepareAccess(PixmapPtr pPixmap, int index); + +void +exaPrepareAccess(DrawablePtr pDrawable, int index); + +void +exaFinishAccess(DrawablePtr pDrawable, int index); + +void +exaDestroyPixmap(PixmapPtr pPixmap); + +void +exaPixmapDirty(PixmapPtr pPix, int x1, int y1, int x2, int y2); + +void +exaGetDrawableDeltas (DrawablePtr pDrawable, PixmapPtr pPixmap, + int *xp, int *yp); + +Bool +exaPixmapHasGpuCopy(PixmapPtr p); + +PixmapPtr +exaGetOffscreenPixmap (DrawablePtr pDrawable, int *xp, int *yp); + +PixmapPtr +exaGetDrawablePixmap(DrawablePtr pDrawable); + +void +exaSetFbPitch(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, + int w, int h, int bpp); + +void +exaSetAccelBlock(ExaScreenPrivPtr pExaScr, ExaPixmapPrivPtr pExaPixmap, + int w, int h, int bpp); + +void +exaDoMigration (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); + +Bool +exaPixmapIsPinned (PixmapPtr pPix); + +extern const GCFuncs exaGCFuncs; + +/* exa_classic.c */ +PixmapPtr +exaCreatePixmap_classic(ScreenPtr pScreen, int w, int h, int depth, + unsigned class); + +Bool +exaModifyPixmapHeader_classic(PixmapPtr pPixmap, int width, int height, int depth, + int bitsPerPixel, int devKind, pointer pPixData); + +Bool +exaDestroyPixmap_classic (PixmapPtr pPixmap); + +Bool +exaPixmapHasGpuCopy_classic(PixmapPtr pPixmap); + +/* exa_driver.c */ +PixmapPtr +exaCreatePixmap_driver(ScreenPtr pScreen, int w, int h, int depth, + unsigned class); + +Bool +exaModifyPixmapHeader_driver(PixmapPtr pPixmap, int width, int height, int depth, + int bitsPerPixel, int devKind, pointer pPixData); + +Bool +exaDestroyPixmap_driver (PixmapPtr pPixmap); + +Bool +exaPixmapHasGpuCopy_driver(PixmapPtr pPixmap); + +/* exa_mixed.c */ +PixmapPtr +exaCreatePixmap_mixed(ScreenPtr pScreen, int w, int h, int depth, + unsigned class); + +Bool +exaModifyPixmapHeader_mixed(PixmapPtr pPixmap, int width, int height, int depth, + int bitsPerPixel, int devKind, pointer pPixData); + +Bool +exaDestroyPixmap_mixed(PixmapPtr pPixmap); + +Bool +exaPixmapHasGpuCopy_mixed(PixmapPtr pPixmap); + +/* exa_migration_mixed.c */ +void +exaCreateDriverPixmap_mixed(PixmapPtr pPixmap); + +void +exaDoMigration_mixed(ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); + +void +exaMoveInPixmap_mixed(PixmapPtr pPixmap); + +void +exaDamageReport_mixed(DamagePtr pDamage, RegionPtr pRegion, void *closure); + +void +exaPrepareAccessReg_mixed(PixmapPtr pPixmap, int index, RegionPtr pReg); + +/* exa_render.c */ +Bool +exaOpReadsDestination (CARD8 op); + +void +exaComposite(CARD8 op, + PicturePtr pSrc, + PicturePtr pMask, + PicturePtr pDst, + INT16 xSrc, + INT16 ySrc, + INT16 xMask, + INT16 yMask, + INT16 xDst, + INT16 yDst, + CARD16 width, + CARD16 height); + +void +exaCompositeRects(CARD8 op, + PicturePtr Src, + PicturePtr pMask, + PicturePtr pDst, + int nrect, + ExaCompositeRectPtr rects); + +void +exaTrapezoids (CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, + int ntrap, xTrapezoid *traps); + +void +exaTriangles (CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, + int ntri, xTriangle *tris); + +/* exa_glyph.c */ +void +exaGlyphsInit(ScreenPtr pScreen); + +void +exaGlyphsFini (ScreenPtr pScreen); + +void +exaGlyphs (CARD8 op, + PicturePtr pSrc, + PicturePtr pDst, + PictFormatPtr maskFormat, + INT16 xSrc, + INT16 ySrc, + int nlist, + GlyphListPtr list, + GlyphPtr *glyphs); + +/* exa_migration_classic.c */ +void +exaCopyDirtyToSys (ExaMigrationPtr migrate); + +void +exaCopyDirtyToFb (ExaMigrationPtr migrate); + +void +exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel); + +void +exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area); + +void +exaMoveOutPixmap_classic (PixmapPtr pPixmap); + +void +exaMoveInPixmap_classic (PixmapPtr pPixmap); + +void +exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg); + +#endif /* EXAPRIV_H */ diff --git a/xorg-server/fb/fb.h b/xorg-server/fb/fb.h index cefd410dd..d90521907 100644 --- a/xorg-server/fb/fb.h +++ b/xorg-server/fb/fb.h @@ -1,2090 +1,2090 @@ -/* - * - * Copyright © 1998 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - - -#ifndef _FB_H_ -#define _FB_H_ - -#include -#include - -#include "scrnintstr.h" -#include "pixmap.h" -#include "pixmapstr.h" -#include "region.h" -#include "gcstruct.h" -#include "colormap.h" -#include "miscstruct.h" -#include "servermd.h" -#include "windowstr.h" -#include "privates.h" -#include "mi.h" -#include "migc.h" -#include "mibstore.h" -#include "picturestr.h" - -#ifdef FB_ACCESS_WRAPPER - -#include "wfbrename.h" -#define FBPREFIX(x) wfb##x -#define WRITE(ptr, val) ((*wfbWriteMemory)((ptr), (val), sizeof(*(ptr)))) -#define READ(ptr) ((*wfbReadMemory)((ptr), sizeof(*(ptr)))) - -#define MEMCPY_WRAPPED(dst, src, size) do { \ - size_t _i; \ - CARD8 *_dst = (CARD8*)(dst), *_src = (CARD8*)(src); \ - for(_i = 0; _i < size; _i++) { \ - WRITE(_dst +_i, READ(_src + _i)); \ - } \ -} while(0) - -#define MEMSET_WRAPPED(dst, val, size) do { \ - size_t _i; \ - CARD8 *_dst = (CARD8*)(dst); \ - for(_i = 0; _i < size; _i++) { \ - WRITE(_dst +_i, (val)); \ - } \ -} while(0) - -#else - -#define FBPREFIX(x) fb##x -#define WRITE(ptr, val) (*(ptr) = (val)) -#define READ(ptr) (*(ptr)) -#define MEMCPY_WRAPPED(dst, src, size) memcpy((dst), (src), (size)) -#define MEMSET_WRAPPED(dst, val, size) memset((dst), (val), (size)) - -#endif - -/* - * This single define controls the basic size of data manipulated - * by this software; it must be log2(sizeof (FbBits) * 8) - */ - -#ifndef FB_SHIFT -#define FB_SHIFT LOG2_BITMAP_PAD -#endif - -#if FB_SHIFT < LOG2_BITMAP_PAD - error FB_SHIFT must be >= LOG2_BITMAP_PAD -#endif - -#define FB_UNIT (1 << FB_SHIFT) -#define FB_HALFUNIT (1 << (FB_SHIFT-1)) -#define FB_MASK (FB_UNIT - 1) -#define FB_ALLONES ((FbBits) -1) - -#if GLYPHPADBYTES != 4 -#error "GLYPHPADBYTES must be 4" -#endif -/* whether to bother to include 24bpp support */ -#ifndef FBNO24BIT -#define FB_24BIT -#endif - -/* - * Unless otherwise instructed, fb includes code to advertise 24bpp - * windows with 32bpp image format for application compatibility - */ - -#ifdef FB_24BIT -#ifndef FBNO24_32 -#define FB_24_32BIT -#endif -#endif - -#define FB_STIP_SHIFT LOG2_BITMAP_PAD -#define FB_STIP_UNIT (1 << FB_STIP_SHIFT) -#define FB_STIP_MASK (FB_STIP_UNIT - 1) -#define FB_STIP_ALLONES ((FbStip) -1) - -#define FB_STIP_ODDSTRIDE(s) (((s) & (FB_MASK >> FB_STIP_SHIFT)) != 0) -#define FB_STIP_ODDPTR(p) ((((long) (p)) & (FB_MASK >> 3)) != 0) - -#define FbStipStrideToBitsStride(s) (((s) >> (FB_SHIFT - FB_STIP_SHIFT))) -#define FbBitsStrideToStipStride(s) (((s) << (FB_SHIFT - FB_STIP_SHIFT))) - -#define FbFullMask(n) ((n) == FB_UNIT ? FB_ALLONES : ((((FbBits) 1) << n) - 1)) - -#if FB_SHIFT == 6 -# ifdef WIN32 -typedef unsigned __int64 FbBits; -# else -# if defined(__alpha__) || defined(__alpha) || \ - defined(ia64) || defined(__ia64__) || \ - defined(__sparc64__) || defined(_LP64) || \ - defined(__s390x__) || \ - defined(amd64) || defined (__amd64__) || \ - defined (__powerpc64__) -typedef unsigned long FbBits; -# else -typedef unsigned long long FbBits; -# endif -# endif -#endif - -#if FB_SHIFT == 5 -typedef CARD32 FbBits; -#endif - -#if FB_SHIFT == 4 -typedef CARD16 FbBits; -#endif - -#if LOG2_BITMAP_PAD == FB_SHIFT -typedef FbBits FbStip; -#else -# if LOG2_BITMAP_PAD == 5 -typedef CARD32 FbStip; -# endif -#endif - -typedef int FbStride; - - -#ifdef FB_DEBUG -extern _X_EXPORT void fbValidateDrawable(DrawablePtr d); -extern _X_EXPORT void fbInitializeDrawable(DrawablePtr d); -extern _X_EXPORT void fbSetBits (FbStip *bits, int stride, FbStip data); -#define FB_HEAD_BITS (FbStip) (0xbaadf00d) -#define FB_TAIL_BITS (FbStip) (0xbaddf0ad) -#else -#define fbValidateDrawable(d) -#define fdInitializeDrawable(d) -#endif - -#include "fbrop.h" - -#if BITMAP_BIT_ORDER == LSBFirst -#define FbScrLeft(x,n) ((x) >> (n)) -#define FbScrRight(x,n) ((x) << (n)) -/* #define FbLeftBits(x,n) ((x) & ((((FbBits) 1) << (n)) - 1)) */ -#define FbLeftStipBits(x,n) ((x) & ((((FbStip) 1) << (n)) - 1)) -#define FbStipMoveLsb(x,s,n) (FbStipRight (x,(s)-(n))) -#define FbPatternOffsetBits 0 -#else -#define FbScrLeft(x,n) ((x) << (n)) -#define FbScrRight(x,n) ((x) >> (n)) -/* #define FbLeftBits(x,n) ((x) >> (FB_UNIT - (n))) */ -#define FbLeftStipBits(x,n) ((x) >> (FB_STIP_UNIT - (n))) -#define FbStipMoveLsb(x,s,n) (x) -#define FbPatternOffsetBits (sizeof (FbBits) - 1) -#endif - -#include "micoord.h" - -#define FbStipLeft(x,n) FbScrLeft(x,n) -#define FbStipRight(x,n) FbScrRight(x,n) - -#define FbRotLeft(x,n) FbScrLeft(x,n) | (n ? FbScrRight(x,FB_UNIT-n) : 0) -#define FbRotRight(x,n) FbScrRight(x,n) | (n ? FbScrLeft(x,FB_UNIT-n) : 0) - -#define FbRotStipLeft(x,n) FbStipLeft(x,n) | (n ? FbStipRight(x,FB_STIP_UNIT-n) : 0) -#define FbRotStipRight(x,n) FbStipRight(x,n) | (n ? FbStipLeft(x,FB_STIP_UNIT-n) : 0) - -#define FbLeftMask(x) ( ((x) & FB_MASK) ? \ - FbScrRight(FB_ALLONES,(x) & FB_MASK) : 0) -#define FbRightMask(x) ( ((FB_UNIT - (x)) & FB_MASK) ? \ - FbScrLeft(FB_ALLONES,(FB_UNIT - (x)) & FB_MASK) : 0) - -#define FbLeftStipMask(x) ( ((x) & FB_STIP_MASK) ? \ - FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) : 0) -#define FbRightStipMask(x) ( ((FB_STIP_UNIT - (x)) & FB_STIP_MASK) ? \ - FbScrLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - (x)) & FB_STIP_MASK) : 0) - -#define FbBitsMask(x,w) (FbScrRight(FB_ALLONES,(x) & FB_MASK) & \ - FbScrLeft(FB_ALLONES,(FB_UNIT - ((x) + (w))) & FB_MASK)) - -#define FbStipMask(x,w) (FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) & \ - FbStipLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - ((x)+(w))) & FB_STIP_MASK)) - - -#define FbMaskBits(x,w,l,n,r) { \ - n = (w); \ - r = FbRightMask((x)+n); \ - l = FbLeftMask(x); \ - if (l) { \ - n -= FB_UNIT - ((x) & FB_MASK); \ - if (n < 0) { \ - n = 0; \ - l &= r; \ - r = 0; \ - } \ - } \ - n >>= FB_SHIFT; \ -} - -#ifdef FBNOPIXADDR -#define FbMaskBitsBytes(x,w,copy,l,lb,n,r,rb) FbMaskBits(x,w,l,n,r) -#define FbDoLeftMaskByteRRop(dst,lb,l,and,xor) { \ - *dst = FbDoMaskRRop(*dst,and,xor,l); \ -} -#define FbDoRightMaskByteRRop(dst,rb,r,and,xor) { \ - *dst = FbDoMaskRRop(*dst,and,xor,r); \ -} -#else - -#define FbByteMaskInvalid 0x10 - -#define FbPatternOffset(o,t) ((o) ^ (FbPatternOffsetBits & ~(sizeof (t) - 1))) - -#define FbPtrOffset(p,o,t) ((t *) ((CARD8 *) (p) + (o))) -#define FbSelectPatternPart(xor,o,t) ((xor) >> (FbPatternOffset (o,t) << 3)) -#define FbStorePart(dst,off,t,xor) (WRITE(FbPtrOffset(dst,off,t), \ - FbSelectPart(xor,off,t))) -#ifndef FbSelectPart -#define FbSelectPart(x,o,t) FbSelectPatternPart(x,o,t) -#endif - -#define FbMaskBitsBytes(x,w,copy,l,lb,n,r,rb) { \ - n = (w); \ - lb = 0; \ - rb = 0; \ - r = FbRightMask((x)+n); \ - if (r) { \ - /* compute right byte length */ \ - if ((copy) && (((x) + n) & 7) == 0) { \ - rb = (((x) + n) & FB_MASK) >> 3; \ - } else { \ - rb = FbByteMaskInvalid; \ - } \ - } \ - l = FbLeftMask(x); \ - if (l) { \ - /* compute left byte length */ \ - if ((copy) && ((x) & 7) == 0) { \ - lb = ((x) & FB_MASK) >> 3; \ - } else { \ - lb = FbByteMaskInvalid; \ - } \ - /* subtract out the portion painted by leftMask */ \ - n -= FB_UNIT - ((x) & FB_MASK); \ - if (n < 0) { \ - if (lb != FbByteMaskInvalid) { \ - if (rb == FbByteMaskInvalid) { \ - lb = FbByteMaskInvalid; \ - } else if (rb) { \ - lb |= (rb - lb) << (FB_SHIFT - 3); \ - rb = 0; \ - } \ - } \ - n = 0; \ - l &= r; \ - r = 0; \ - }\ - } \ - n >>= FB_SHIFT; \ -} - -#if FB_SHIFT == 6 -#define FbDoLeftMaskByteRRop6Cases(dst,xor) \ - case (sizeof (FbBits) - 7) | (1 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 7) | (2 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 7) | (3 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - break; \ - case (sizeof (FbBits) - 7) | (4 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 7) | (5 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - break; \ - case (sizeof (FbBits) - 7) | (6 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 7): \ - FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ - break; \ - case (sizeof (FbBits) - 6) | (1 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 6) | (2 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - break; \ - case (sizeof (FbBits) - 6) | (3 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 6) | (4 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - break; \ - case (sizeof (FbBits) - 6) | (5 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 6): \ - FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ - break; \ - case (sizeof (FbBits) - 5) | (1 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 5) | (2 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 5) | (3 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - break; \ - case (sizeof (FbBits) - 5) | (4 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 5): \ - FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ - break; \ - case (sizeof (FbBits) - 4) | (1 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 4) | (2 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - break; \ - case (sizeof (FbBits) - 4) | (3 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ - FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 4): \ - FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ - break; - -#define FbDoRightMaskByteRRop6Cases(dst,xor) \ - case 4: \ - FbStorePart(dst,0,CARD32,xor); \ - break; \ - case 5: \ - FbStorePart(dst,0,CARD32,xor); \ - FbStorePart(dst,4,CARD8,xor); \ - break; \ - case 6: \ - FbStorePart(dst,0,CARD32,xor); \ - FbStorePart(dst,4,CARD16,xor); \ - break; \ - case 7: \ - FbStorePart(dst,0,CARD32,xor); \ - FbStorePart(dst,4,CARD16,xor); \ - FbStorePart(dst,6,CARD8,xor); \ - break; -#else -#define FbDoLeftMaskByteRRop6Cases(dst,xor) -#define FbDoRightMaskByteRRop6Cases(dst,xor) -#endif - -#define FbDoLeftMaskByteRRop(dst,lb,l,and,xor) { \ - switch (lb) { \ - FbDoLeftMaskByteRRop6Cases(dst,xor) \ - case (sizeof (FbBits) - 3) | (1 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 3) | (2 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ - FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ - break; \ - case (sizeof (FbBits) - 2) | (1 << (FB_SHIFT - 3)): \ - FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ - break; \ - case sizeof (FbBits) - 3: \ - FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ - case sizeof (FbBits) - 2: \ - FbStorePart(dst,sizeof (FbBits) - 2,CARD16,xor); \ - break; \ - case sizeof (FbBits) - 1: \ - FbStorePart(dst,sizeof (FbBits) - 1,CARD8,xor); \ - break; \ - default: \ - WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, l)); \ - break; \ - } \ -} - - -#define FbDoRightMaskByteRRop(dst,rb,r,and,xor) { \ - switch (rb) { \ - case 1: \ - FbStorePart(dst,0,CARD8,xor); \ - break; \ - case 2: \ - FbStorePart(dst,0,CARD16,xor); \ - break; \ - case 3: \ - FbStorePart(dst,0,CARD16,xor); \ - FbStorePart(dst,2,CARD8,xor); \ - break; \ - FbDoRightMaskByteRRop6Cases(dst,xor) \ - default: \ - WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, r)); \ - } \ -} -#endif - -#define FbMaskStip(x,w,l,n,r) { \ - n = (w); \ - r = FbRightStipMask((x)+n); \ - l = FbLeftStipMask(x); \ - if (l) { \ - n -= FB_STIP_UNIT - ((x) & FB_STIP_MASK); \ - if (n < 0) { \ - n = 0; \ - l &= r; \ - r = 0; \ - } \ - } \ - n >>= FB_STIP_SHIFT; \ -} - -/* - * These macros are used to transparently stipple - * in copy mode; the expected usage is with 'n' constant - * so all of the conditional parts collapse into a minimal - * sequence of partial word writes - * - * 'n' is the bytemask of which bytes to store, 'a' is the address - * of the FbBits base unit, 'o' is the offset within that unit - * - * The term "lane" comes from the hardware term "byte-lane" which - */ - -#define FbLaneCase1(n,a,o) \ - if ((n) == 0x01) { \ - WRITE((CARD8 *) ((a)+FbPatternOffset(o,CARD8)), fgxor); \ - } - -#define FbLaneCase2(n,a,o) \ - if ((n) == 0x03) { \ - WRITE((CARD16 *) ((a)+FbPatternOffset(o,CARD16)), fgxor); \ - } else { \ - FbLaneCase1((n)&1,a,o) \ - FbLaneCase1((n)>>1,a,(o)+1) \ - } - -#define FbLaneCase4(n,a,o) \ - if ((n) == 0x0f) { \ - WRITE((CARD32 *) ((a)+FbPatternOffset(o,CARD32)), fgxor); \ - } else { \ - FbLaneCase2((n)&3,a,o) \ - FbLaneCase2((n)>>2,a,(o)+2) \ - } - -#define FbLaneCase8(n,a,o) \ - if ((n) == 0x0ff) { \ - *(FbBits *) ((a)+(o)) = fgxor; \ - } else { \ - FbLaneCase4((n)&15,a,o) \ - FbLaneCase4((n)>>4,a,(o)+4) \ - } - -#if FB_SHIFT == 6 -#define FbLaneCase(n,a) FbLaneCase8(n,(CARD8 *) (a),0) -#endif - -#if FB_SHIFT == 5 -#define FbLaneCase(n,a) FbLaneCase4(n,(CARD8 *) (a),0) -#endif - -/* Rotate a filled pixel value to the specified alignement */ -#define FbRot24(p,b) (FbScrRight(p,b) | FbScrLeft(p,24-(b))) -#define FbRot24Stip(p,b) (FbStipRight(p,b) | FbStipLeft(p,24-(b))) - -/* step a filled pixel value to the next/previous FB_UNIT alignment */ -#define FbNext24Pix(p) (FbRot24(p,(24-FB_UNIT%24))) -#define FbPrev24Pix(p) (FbRot24(p,FB_UNIT%24)) -#define FbNext24Stip(p) (FbRot24(p,(24-FB_STIP_UNIT%24))) -#define FbPrev24Stip(p) (FbRot24(p,FB_STIP_UNIT%24)) - -/* step a rotation value to the next/previous rotation value */ -#if FB_UNIT == 64 -#define FbNext24Rot(r) ((r) == 16 ? 0 : (r) + 8) -#define FbPrev24Rot(r) ((r) == 0 ? 16 : (r) - 8) - -#if IMAGE_BYTE_ORDER == MSBFirst -#define FbFirst24Rot(x) (((x) + 8) % 24) -#else -#define FbFirst24Rot(x) ((x) % 24) -#endif - -#endif - -#if FB_UNIT == 32 -#define FbNext24Rot(r) ((r) == 0 ? 16 : (r) - 8) -#define FbPrev24Rot(r) ((r) == 16 ? 0 : (r) + 8) - -#if IMAGE_BYTE_ORDER == MSBFirst -#define FbFirst24Rot(x) (((x) + 16) % 24) -#else -#define FbFirst24Rot(x) ((x) % 24) -#endif -#endif - -#define FbNext24RotStip(r) ((r) == 0 ? 16 : (r) - 8) -#define FbPrev24RotStip(r) ((r) == 16 ? 0 : (r) + 8) - -/* Whether 24-bit specific code is needed for this filled pixel value */ -#define FbCheck24Pix(p) ((p) == FbNext24Pix(p)) - -/* Macros for dealing with dashing */ - -#define FbDashDeclare \ - unsigned char *__dash, *__firstDash, *__lastDash - -#define FbDashInit(pGC,pPriv,dashOffset,dashlen,even) { \ - (even) = TRUE; \ - __firstDash = (pGC)->dash; \ - __lastDash = __firstDash + (pGC)->numInDashList; \ - (dashOffset) %= (pPriv)->dashLength; \ - \ - __dash = __firstDash; \ - while ((dashOffset) >= ((dashlen) = *__dash)) \ - { \ - (dashOffset) -= (dashlen); \ - (even) = 1-(even); \ - if (++__dash == __lastDash) \ - __dash = __firstDash; \ - } \ - (dashlen) -= (dashOffset); \ -} - -#define FbDashNext(dashlen) { \ - if (++__dash == __lastDash) \ - __dash = __firstDash; \ - (dashlen) = *__dash; \ -} - -/* as numInDashList is always even, this case can skip a test */ - -#define FbDashNextEven(dashlen) { \ - (dashlen) = *++__dash; \ -} - -#define FbDashNextOdd(dashlen) FbDashNext(dashlen) - -#define FbDashStep(dashlen,even) { \ - if (!--(dashlen)) { \ - FbDashNext(dashlen); \ - (even) = 1-(even); \ - } \ -} - -extern _X_EXPORT DevPrivateKey -fbGetGCPrivateKey (void); - -extern _X_EXPORT DevPrivateKey -fbGetWinPrivateKey (void); - -extern _X_EXPORT const GCOps fbGCOps; -extern _X_EXPORT const GCFuncs fbGCFuncs; - -#ifdef FB_24_32BIT -#define FB_SCREEN_PRIVATE -#endif - -/* Framebuffer access wrapper */ -typedef FbBits (*ReadMemoryProcPtr)(const void *src, int size); -typedef void (*WriteMemoryProcPtr)(void *dst, FbBits value, int size); -typedef void (*SetupWrapProcPtr)(ReadMemoryProcPtr *pRead, - WriteMemoryProcPtr *pWrite, - DrawablePtr pDraw); -typedef void (*FinishWrapProcPtr)(DrawablePtr pDraw); - -#ifdef FB_ACCESS_WRAPPER - -#define fbPrepareAccess(pDraw) \ - fbGetScreenPrivate((pDraw)->pScreen)->setupWrap( \ - &wfbReadMemory, \ - &wfbWriteMemory, \ - (pDraw)) -#define fbFinishAccess(pDraw) \ - fbGetScreenPrivate((pDraw)->pScreen)->finishWrap(pDraw) - -#else - -#define fbPrepareAccess(pPix) -#define fbFinishAccess(pDraw) - -#endif - - -#ifdef FB_SCREEN_PRIVATE -extern _X_EXPORT DevPrivateKey -fbGetScreenPrivateKey(void); - -/* private field of a screen */ -typedef struct { - unsigned char win32bpp; /* window bpp for 32-bpp images */ - unsigned char pix32bpp; /* pixmap bpp for 32-bpp images */ -#ifdef FB_ACCESS_WRAPPER - SetupWrapProcPtr setupWrap; /* driver hook to set pixmap access wrapping */ - FinishWrapProcPtr finishWrap; /* driver hook to clean up pixmap access wrapping */ -#endif -} FbScreenPrivRec, *FbScreenPrivPtr; - -#define fbGetScreenPrivate(pScreen) ((FbScreenPrivPtr) \ - dixLookupPrivate(&(pScreen)->devPrivates, fbGetScreenPrivateKey())) -#endif - -/* private field of GC */ -typedef struct { - FbBits and, xor; /* reduced rop values */ - FbBits bgand, bgxor; /* for stipples */ - FbBits fg, bg, pm; /* expanded and filled */ - unsigned int dashLength; /* total of all dash elements */ - unsigned char evenStipple; /* stipple is even */ - unsigned char bpp; /* current drawable bpp */ -} FbGCPrivRec, *FbGCPrivPtr; - -#define fbGetGCPrivate(pGC) ((FbGCPrivPtr)\ - dixLookupPrivate(&(pGC)->devPrivates, fbGetGCPrivateKey())) - -#define fbGetCompositeClip(pGC) ((pGC)->pCompositeClip) -#define fbGetExpose(pGC) ((pGC)->fExpose) -#define fbGetFreeCompClip(pGC) ((pGC)->freeCompClip) -#define fbGetRotatedPixmap(pGC) ((pGC)->pRotatedPixmap) - -#define fbGetScreenPixmap(s) ((PixmapPtr) (s)->devPrivate) -#define fbGetWindowPixmap(pWin) ((PixmapPtr)\ - dixLookupPrivate(&((WindowPtr)(pWin))->devPrivates, fbGetWinPrivateKey())) - -#ifdef ROOTLESS -#define __fbPixDrawableX(pPix) ((pPix)->drawable.x) -#define __fbPixDrawableY(pPix) ((pPix)->drawable.y) -#else -#define __fbPixDrawableX(pPix) 0 -#define __fbPixDrawableY(pPix) 0 -#endif - -#ifdef COMPOSITE -#define __fbPixOffXWin(pPix) (__fbPixDrawableX(pPix) - (pPix)->screen_x) -#define __fbPixOffYWin(pPix) (__fbPixDrawableY(pPix) - (pPix)->screen_y) -#else -#define __fbPixOffXWin(pPix) (__fbPixDrawableX(pPix)) -#define __fbPixOffYWin(pPix) (__fbPixDrawableY(pPix)) -#endif -#define __fbPixOffXPix(pPix) (__fbPixDrawableX(pPix)) -#define __fbPixOffYPix(pPix) (__fbPixDrawableY(pPix)) - -#define fbGetDrawablePixmap(pDrawable, pixmap, xoff, yoff) { \ - if ((pDrawable)->type != DRAWABLE_PIXMAP) { \ - (pixmap) = fbGetWindowPixmap(pDrawable); \ - (xoff) = __fbPixOffXWin(pixmap); \ - (yoff) = __fbPixOffYWin(pixmap); \ - } else { \ - (pixmap) = (PixmapPtr) (pDrawable); \ - (xoff) = __fbPixOffXPix(pixmap); \ - (yoff) = __fbPixOffYPix(pixmap); \ - } \ - fbPrepareAccess(pDrawable); \ -} - -#define fbGetPixmapBitsData(pixmap, pointer, stride, bpp) { \ - (pointer) = (FbBits *) (pixmap)->devPrivate.ptr; \ - (stride) = ((int) (pixmap)->devKind) / sizeof (FbBits); (void)(stride); \ - (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \ -} - -#define fbGetPixmapStipData(pixmap, pointer, stride, bpp) { \ - (pointer) = (FbStip *) (pixmap)->devPrivate.ptr; \ - (stride) = ((int) (pixmap)->devKind) / sizeof (FbStip); (void)(stride); \ - (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \ -} - -#define fbGetDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \ - PixmapPtr _pPix; \ - fbGetDrawablePixmap(pDrawable, _pPix, xoff, yoff); \ - fbGetPixmapBitsData(_pPix, pointer, stride, bpp); \ -} - -#define fbGetStipDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \ - PixmapPtr _pPix; \ - fbGetDrawablePixmap(pDrawable, _pPix, xoff, yoff); \ - fbGetPixmapStipData(_pPix, pointer, stride, bpp); \ -} - -/* - * XFree86 empties the root BorderClip when the VT is inactive, - * here's a macro which uses that to disable GetImage and GetSpans - */ - -#define fbWindowEnabled(pWin) \ - RegionNotEmpty(&(pWin)->drawable.pScreen->root->borderClip) - -#define fbDrawableEnabled(pDrawable) \ - ((pDrawable)->type == DRAWABLE_PIXMAP ? \ - TRUE : fbWindowEnabled((WindowPtr) pDrawable)) - -#define FbPowerOfTwo(w) (((w) & ((w) - 1)) == 0) -/* - * Accelerated tiles are power of 2 width <= FB_UNIT - */ -#define FbEvenTile(w) ((w) <= FB_UNIT && FbPowerOfTwo(w)) -/* - * Accelerated stipples are power of 2 width and <= FB_UNIT/dstBpp - * with dstBpp a power of 2 as well - */ -#define FbEvenStip(w,bpp) ((w) * (bpp) <= FB_UNIT && FbPowerOfTwo(w) && FbPowerOfTwo(bpp)) - -/* - * fb24_32.c - */ -extern _X_EXPORT void -fb24_32GetSpans(DrawablePtr pDrawable, - int wMax, - DDXPointPtr ppt, - int *pwidth, - int nspans, - char *pchardstStart); - -extern _X_EXPORT void -fb24_32SetSpans (DrawablePtr pDrawable, - GCPtr pGC, - char *src, - DDXPointPtr ppt, - int *pwidth, - int nspans, - int fSorted); - -extern _X_EXPORT void -fb24_32PutZImage (DrawablePtr pDrawable, - RegionPtr pClip, - int alu, - FbBits pm, - int x, - int y, - int width, - int height, - CARD8 *src, - FbStride srcStride); - -extern _X_EXPORT void -fb24_32GetImage (DrawablePtr pDrawable, - int x, - int y, - int w, - int h, - unsigned int format, - unsigned long planeMask, - char *d); - -extern _X_EXPORT void -fb24_32CopyMtoN (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pbox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure); - -extern _X_EXPORT PixmapPtr -fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel); - -extern _X_EXPORT Bool -fb24_32CreateScreenResources(ScreenPtr pScreen); - -extern _X_EXPORT Bool -fb24_32ModifyPixmapHeader (PixmapPtr pPixmap, - int width, - int height, - int depth, - int bitsPerPixel, - int devKind, - pointer pPixData); - -/* - * fballpriv.c - */ -extern _X_EXPORT Bool -fbAllocatePrivates(ScreenPtr pScreen, DevPrivateKey *pGCIndex); - -/* - * fbarc.c - */ - -extern _X_EXPORT void -fbPolyArc (DrawablePtr pDrawable, - GCPtr pGC, - int narcs, - xArc *parcs); - -/* - * fbbits.c - */ - -extern _X_EXPORT void -fbBresSolid8(DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x, - int y, - int e, - int e1, - int e3, - int len); - -extern _X_EXPORT void -fbBresDash8 (DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x, - int y, - int e, - int e1, - int e3, - int len); - -extern _X_EXPORT void -fbDots8 (FbBits *dst, - FbStride dstStride, - int dstBpp, - BoxPtr pBox, - xPoint *pts, - int npt, - int xorg, - int yorg, - int xoff, - int yoff, - FbBits and, - FbBits xor); - -extern _X_EXPORT void -fbArc8 (FbBits *dst, - FbStride dstStride, - int dstBpp, - xArc *arc, - int dx, - int dy, - FbBits and, - FbBits xor); - -extern _X_EXPORT void -fbGlyph8 (FbBits *dstLine, - FbStride dstStride, - int dstBpp, - FbStip *stipple, - FbBits fg, - int height, - int shift); - -extern _X_EXPORT void -fbPolyline8 (DrawablePtr pDrawable, - GCPtr pGC, - int mode, - int npt, - DDXPointPtr ptsOrig); - -extern _X_EXPORT void -fbPolySegment8 (DrawablePtr pDrawable, - GCPtr pGC, - int nseg, - xSegment *pseg); - -extern _X_EXPORT void -fbBresSolid16(DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x, - int y, - int e, - int e1, - int e3, - int len); - -extern _X_EXPORT void -fbBresDash16(DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x, - int y, - int e, - int e1, - int e3, - int len); - -extern _X_EXPORT void -fbDots16(FbBits *dst, - FbStride dstStride, - int dstBpp, - BoxPtr pBox, - xPoint *pts, - int npt, - int xorg, - int yorg, - int xoff, - int yoff, - FbBits and, - FbBits xor); - -extern _X_EXPORT void -fbArc16(FbBits *dst, - FbStride dstStride, - int dstBpp, - xArc *arc, - int dx, - int dy, - FbBits and, - FbBits xor); - -extern _X_EXPORT void -fbGlyph16(FbBits *dstLine, - FbStride dstStride, - int dstBpp, - FbStip *stipple, - FbBits fg, - int height, - int shift); - -extern _X_EXPORT void -fbPolyline16 (DrawablePtr pDrawable, - GCPtr pGC, - int mode, - int npt, - DDXPointPtr ptsOrig); - -extern _X_EXPORT void -fbPolySegment16 (DrawablePtr pDrawable, - GCPtr pGC, - int nseg, - xSegment *pseg); - - -extern _X_EXPORT void -fbBresSolid24(DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x, - int y, - int e, - int e1, - int e3, - int len); - -extern _X_EXPORT void -fbBresDash24(DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x, - int y, - int e, - int e1, - int e3, - int len); - -extern _X_EXPORT void -fbDots24(FbBits *dst, - FbStride dstStride, - int dstBpp, - BoxPtr pBox, - xPoint *pts, - int npt, - int xorg, - int yorg, - int xoff, - int yoff, - FbBits and, - FbBits xor); - -extern _X_EXPORT void -fbArc24(FbBits *dst, - FbStride dstStride, - int dstBpp, - xArc *arc, - int dx, - int dy, - FbBits and, - FbBits xor); - -extern _X_EXPORT void -fbGlyph24(FbBits *dstLine, - FbStride dstStride, - int dstBpp, - FbStip *stipple, - FbBits fg, - int height, - int shift); - -extern _X_EXPORT void -fbPolyline24 (DrawablePtr pDrawable, - GCPtr pGC, - int mode, - int npt, - DDXPointPtr ptsOrig); - -extern _X_EXPORT void -fbPolySegment24 (DrawablePtr pDrawable, - GCPtr pGC, - int nseg, - xSegment *pseg); - - -extern _X_EXPORT void -fbBresSolid32(DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x, - int y, - int e, - int e1, - int e3, - int len); - -extern _X_EXPORT void -fbBresDash32(DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x, - int y, - int e, - int e1, - int e3, - int len); - -extern _X_EXPORT void -fbDots32(FbBits *dst, - FbStride dstStride, - int dstBpp, - BoxPtr pBox, - xPoint *pts, - int npt, - int xorg, - int yorg, - int xoff, - int yoff, - FbBits and, - FbBits xor); - -extern _X_EXPORT void -fbArc32(FbBits *dst, - FbStride dstStride, - int dstBpp, - xArc *arc, - int dx, - int dy, - FbBits and, - FbBits xor); - -extern _X_EXPORT void -fbGlyph32(FbBits *dstLine, - FbStride dstStride, - int dstBpp, - FbStip *stipple, - FbBits fg, - int height, - int shift); -extern _X_EXPORT void -fbPolyline32 (DrawablePtr pDrawable, - GCPtr pGC, - int mode, - int npt, - DDXPointPtr ptsOrig); - -extern _X_EXPORT void -fbPolySegment32 (DrawablePtr pDrawable, - GCPtr pGC, - int nseg, - xSegment *pseg); - -/* - * fbblt.c - */ -extern _X_EXPORT void -fbBlt (FbBits *src, - FbStride srcStride, - int srcX, - - FbBits *dst, - FbStride dstStride, - int dstX, - - int width, - int height, - - int alu, - FbBits pm, - int bpp, - - Bool reverse, - Bool upsidedown); - -extern _X_EXPORT void -fbBlt24 (FbBits *srcLine, - FbStride srcStride, - int srcX, - - FbBits *dstLine, - FbStride dstStride, - int dstX, - - int width, - int height, - - int alu, - FbBits pm, - - Bool reverse, - Bool upsidedown); - -extern _X_EXPORT void -fbBltStip (FbStip *src, - FbStride srcStride, /* in FbStip units, not FbBits units */ - int srcX, - - FbStip *dst, - FbStride dstStride, /* in FbStip units, not FbBits units */ - int dstX, - - int width, - int height, - - int alu, - FbBits pm, - int bpp); - -/* - * fbbltone.c - */ -extern _X_EXPORT void -fbBltOne (FbStip *src, - FbStride srcStride, - int srcX, - FbBits *dst, - FbStride dstStride, - int dstX, - int dstBpp, - - int width, - int height, - - FbBits fgand, - FbBits fbxor, - FbBits bgand, - FbBits bgxor); - -#ifdef FB_24BIT -extern _X_EXPORT void -fbBltOne24 (FbStip *src, - FbStride srcStride, /* FbStip units per scanline */ - int srcX, /* bit position of source */ - FbBits *dst, - FbStride dstStride, /* FbBits units per scanline */ - int dstX, /* bit position of dest */ - int dstBpp, /* bits per destination unit */ - - int width, /* width in bits of destination */ - int height, /* height in scanlines */ - - FbBits fgand, /* rrop values */ - FbBits fgxor, - FbBits bgand, - FbBits bgxor); -#endif - -extern _X_EXPORT void -fbBltPlane (FbBits *src, - FbStride srcStride, - int srcX, - int srcBpp, - - FbStip *dst, - FbStride dstStride, - int dstX, - - int width, - int height, - - FbStip fgand, - FbStip fgxor, - FbStip bgand, - FbStip bgxor, - Pixel planeMask); - -/* - * fbcmap_mi.c - */ -extern _X_EXPORT int -fbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps); - -extern _X_EXPORT void -fbInstallColormap(ColormapPtr pmap); - -extern _X_EXPORT void -fbUninstallColormap(ColormapPtr pmap); - -extern _X_EXPORT void -fbResolveColor(unsigned short *pred, - unsigned short *pgreen, - unsigned short *pblue, - VisualPtr pVisual); - -extern _X_EXPORT Bool -fbInitializeColormap(ColormapPtr pmap); - -extern _X_EXPORT int -fbExpandDirectColors (ColormapPtr pmap, - int ndef, - xColorItem *indefs, - xColorItem *outdefs); - -extern _X_EXPORT Bool -fbCreateDefColormap(ScreenPtr pScreen); - -extern _X_EXPORT void -fbClearVisualTypes(void); - -extern _X_EXPORT Bool -fbHasVisualTypes (int depth); - -extern _X_EXPORT Bool -fbSetVisualTypes (int depth, int visuals, int bitsPerRGB); - -extern _X_EXPORT Bool -fbSetVisualTypesAndMasks (int depth, int visuals, int bitsPerRGB, - Pixel redMask, Pixel greenMask, Pixel blueMask); - -extern _X_EXPORT Bool -fbInitVisuals (VisualPtr *visualp, - DepthPtr *depthp, - int *nvisualp, - int *ndepthp, - int *rootDepthp, - VisualID *defaultVisp, - unsigned long sizes, - int bitsPerRGB); - -/* - * fbcopy.c - */ - -/* Compatibility definition, to be removed at next ABI change. */ -typedef void (*fbCopyProc) (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pDstBox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure); - -extern _X_EXPORT void -fbCopyNtoN (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pbox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure); - -/* Compatibility wrapper, to be removed at next ABI change. */ -extern _X_EXPORT void -fbCopyRegion (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - RegionPtr pDstRegion, - int dx, - int dy, - fbCopyProc copyProc, - Pixel bitPlane, - void *closure); - -/* Compatibility wrapper, to be removed at next ABI change. */ -extern _X_EXPORT RegionPtr -fbDoCopy (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - int xIn, - int yIn, - int widthSrc, - int heightSrc, - int xOut, - int yOut, - fbCopyProc copyProc, - Pixel bitplane, - void *closure); - -extern _X_EXPORT void -fbCopy1toN (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pbox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure); - -extern _X_EXPORT void -fbCopyNto1 (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pbox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure); - -extern _X_EXPORT RegionPtr -fbCopyArea (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - int xIn, - int yIn, - int widthSrc, - int heightSrc, - int xOut, - int yOut); - -extern _X_EXPORT RegionPtr -fbCopyPlane (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - int xIn, - int yIn, - int widthSrc, - int heightSrc, - int xOut, - int yOut, - unsigned long bitplane); - -/* - * fbfill.c - */ -extern _X_EXPORT void -fbFill (DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - int width, - int height); - -extern _X_EXPORT void -fbSolidBoxClipped (DrawablePtr pDrawable, - RegionPtr pClip, - int xa, - int ya, - int xb, - int yb, - FbBits and, - FbBits xor); - -/* - * fbfillrect.c - */ -extern _X_EXPORT void -fbPolyFillRect(DrawablePtr pDrawable, - GCPtr pGC, - int nrectInit, - xRectangle *prectInit); - -#define fbPolyFillArc miPolyFillArc - -#define fbFillPolygon miFillPolygon - -/* - * fbfillsp.c - */ -extern _X_EXPORT void -fbFillSpans (DrawablePtr pDrawable, - GCPtr pGC, - int nInit, - DDXPointPtr pptInit, - int *pwidthInit, - int fSorted); - - -/* - * fbgc.c - */ - -extern _X_EXPORT Bool -fbCreateGC(GCPtr pGC); - -extern _X_EXPORT void -fbPadPixmap (PixmapPtr pPixmap); - -extern _X_EXPORT void -fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable); - -/* - * fbgetsp.c - */ -extern _X_EXPORT void -fbGetSpans(DrawablePtr pDrawable, - int wMax, - DDXPointPtr ppt, - int *pwidth, - int nspans, - char *pchardstStart); - -/* - * fbglyph.c - */ - -extern _X_EXPORT Bool -fbGlyphIn (RegionPtr pRegion, - int x, - int y, - int width, - int height); - -extern _X_EXPORT void -fbPolyGlyphBlt (DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - unsigned int nglyph, - CharInfoPtr *ppci, - pointer pglyphBase); - -extern _X_EXPORT void -fbImageGlyphBlt (DrawablePtr pDrawable, - GCPtr pGC, - int x, - int y, - unsigned int nglyph, - CharInfoPtr *ppci, - pointer pglyphBase); - -/* - * fbimage.c - */ - -extern _X_EXPORT void -fbPutImage (DrawablePtr pDrawable, - GCPtr pGC, - int depth, - int x, - int y, - int w, - int h, - int leftPad, - int format, - char *pImage); - -extern _X_EXPORT void -fbPutZImage (DrawablePtr pDrawable, - RegionPtr pClip, - int alu, - FbBits pm, - int x, - int y, - int width, - int height, - FbStip *src, - FbStride srcStride); - -extern _X_EXPORT void -fbPutXYImage (DrawablePtr pDrawable, - RegionPtr pClip, - FbBits fg, - FbBits bg, - FbBits pm, - int alu, - Bool opaque, - - int x, - int y, - int width, - int height, - - FbStip *src, - FbStride srcStride, - int srcX); - -extern _X_EXPORT void -fbGetImage (DrawablePtr pDrawable, - int x, - int y, - int w, - int h, - unsigned int format, - unsigned long planeMask, - char *d); -/* - * fbline.c - */ - -extern _X_EXPORT void -fbZeroLine (DrawablePtr pDrawable, - GCPtr pGC, - int mode, - int npt, - DDXPointPtr ppt); - -extern _X_EXPORT void -fbZeroSegment (DrawablePtr pDrawable, - GCPtr pGC, - int nseg, - xSegment *pSegs); - -extern _X_EXPORT void -fbPolyLine (DrawablePtr pDrawable, - GCPtr pGC, - int mode, - int npt, - DDXPointPtr ppt); - -extern _X_EXPORT void -fbFixCoordModePrevious (int npt, - DDXPointPtr ppt); - -extern _X_EXPORT void -fbPolySegment (DrawablePtr pDrawable, - GCPtr pGC, - int nseg, - xSegment *pseg); - -#define fbPolyRectangle miPolyRectangle - -/* - * fbpict.c - */ - -extern _X_EXPORT Bool -fbPictureInit (ScreenPtr pScreen, - PictFormatPtr formats, - int nformats); - -/* - * fbpixmap.c - */ - -extern _X_EXPORT PixmapPtr -fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp, - unsigned usage_hint); - -extern _X_EXPORT PixmapPtr -fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth, - unsigned usage_hint); - -extern _X_EXPORT Bool -fbDestroyPixmap (PixmapPtr pPixmap); - -extern _X_EXPORT RegionPtr -fbPixmapToRegion(PixmapPtr pPix); - -/* - * fbpoint.c - */ - -extern _X_EXPORT void -fbDots (FbBits *dstOrig, - FbStride dstStride, - int dstBpp, - BoxPtr pBox, - xPoint *pts, - int npt, - int xorg, - int yorg, - int xoff, - int yoff, - FbBits andOrig, - FbBits xorOrig); - -extern _X_EXPORT void -fbPolyPoint (DrawablePtr pDrawable, - GCPtr pGC, - int mode, - int npt, - xPoint *pptInit); - -/* - * fbpush.c - */ -extern _X_EXPORT void -fbPushPattern (DrawablePtr pDrawable, - GCPtr pGC, - - FbStip *src, - FbStride srcStride, - int srcX, - - int x, - int y, - - int width, - int height); - -extern _X_EXPORT void -fbPushFill (DrawablePtr pDrawable, - GCPtr pGC, - - FbStip *src, - FbStride srcStride, - int srcX, - - int x, - int y, - int width, - int height); - -extern _X_EXPORT void -fbPushImage (DrawablePtr pDrawable, - GCPtr pGC, - - FbStip *src, - FbStride srcStride, - int srcX, - - int x, - int y, - int width, - int height); - -extern _X_EXPORT void -fbPushPixels (GCPtr pGC, - PixmapPtr pBitmap, - DrawablePtr pDrawable, - int dx, - int dy, - int xOrg, - int yOrg); - - -/* - * fbscreen.c - */ - -extern _X_EXPORT Bool -fbCloseScreen (int indx, ScreenPtr pScreen); - -extern _X_EXPORT Bool -fbRealizeFont(ScreenPtr pScreen, FontPtr pFont); - -extern _X_EXPORT Bool -fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont); - -extern _X_EXPORT void -fbQueryBestSize (int class, - unsigned short *width, unsigned short *height, - ScreenPtr pScreen); - -extern _X_EXPORT PixmapPtr -_fbGetWindowPixmap (WindowPtr pWindow); - -extern _X_EXPORT void -_fbSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap); - -extern _X_EXPORT Bool -fbSetupScreen(ScreenPtr pScreen, - pointer pbits, /* pointer to screen bitmap */ - int xsize, /* in pixels */ - int ysize, - int dpix, /* dots per inch */ - int dpiy, - int width, /* pixel width of frame buffer */ - int bpp); /* bits per pixel of frame buffer */ - -extern _X_EXPORT Bool -wfbFinishScreenInit(ScreenPtr pScreen, - pointer pbits, - int xsize, - int ysize, - int dpix, - int dpiy, - int width, - int bpp, - SetupWrapProcPtr setupWrap, - FinishWrapProcPtr finishWrap); - -extern _X_EXPORT Bool -wfbScreenInit(ScreenPtr pScreen, - pointer pbits, - int xsize, - int ysize, - int dpix, - int dpiy, - int width, - int bpp, - SetupWrapProcPtr setupWrap, - FinishWrapProcPtr finishWrap); - -extern _X_EXPORT Bool -fbFinishScreenInit(ScreenPtr pScreen, - pointer pbits, - int xsize, - int ysize, - int dpix, - int dpiy, - int width, - int bpp); - -extern _X_EXPORT Bool -fbScreenInit(ScreenPtr pScreen, - pointer pbits, - int xsize, - int ysize, - int dpix, - int dpiy, - int width, - int bpp); - -/* - * fbseg.c - */ -typedef void FbBres (DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x, - int y, - int e, - int e1, - int e3, - int len); - -extern _X_EXPORT FbBres fbBresSolid, fbBresDash, fbBresFill, fbBresFillDash; -/* - * fbsetsp.c - */ - -extern _X_EXPORT void -fbSetSpans (DrawablePtr pDrawable, - GCPtr pGC, - char *src, - DDXPointPtr ppt, - int *pwidth, - int nspans, - int fSorted); - -extern _X_EXPORT FbBres * -fbSelectBres (DrawablePtr pDrawable, - GCPtr pGC); - -extern _X_EXPORT void -fbBres (DrawablePtr pDrawable, - GCPtr pGC, - int dashOffset, - int signdx, - int signdy, - int axis, - int x, - int y, - int e, - int e1, - int e3, - int len); - -extern _X_EXPORT void -fbSegment (DrawablePtr pDrawable, - GCPtr pGC, - int xa, - int ya, - int xb, - int yb, - Bool drawLast, - int *dashOffset); - - -/* - * fbsolid.c - */ - -extern _X_EXPORT void -fbSolid (FbBits *dst, - FbStride dstStride, - int dstX, - int bpp, - - int width, - int height, - - FbBits and, - FbBits xor); - -#ifdef FB_24BIT -extern _X_EXPORT void -fbSolid24 (FbBits *dst, - FbStride dstStride, - int dstX, - - int width, - int height, - - FbBits and, - FbBits xor); -#endif - -/* - * fbstipple.c - */ - -extern _X_EXPORT void -fbTransparentSpan (FbBits *dst, - FbBits stip, - FbBits fgxor, - int n); - -extern _X_EXPORT void -fbEvenStipple (FbBits *dst, - FbStride dstStride, - int dstX, - int dstBpp, - - int width, - int height, - - FbStip *stip, - FbStride stipStride, - int stipHeight, - - FbBits fgand, - FbBits fgxor, - FbBits bgand, - FbBits bgxor, - - int xRot, - int yRot); - -extern _X_EXPORT void -fbOddStipple (FbBits *dst, - FbStride dstStride, - int dstX, - int dstBpp, - - int width, - int height, - - FbStip *stip, - FbStride stipStride, - int stipWidth, - int stipHeight, - - FbBits fgand, - FbBits fgxor, - FbBits bgand, - FbBits bgxor, - - int xRot, - int yRot); - -extern _X_EXPORT void -fbStipple (FbBits *dst, - FbStride dstStride, - int dstX, - int dstBpp, - - int width, - int height, - - FbStip *stip, - FbStride stipStride, - int stipWidth, - int stipHeight, - Bool even, - - FbBits fgand, - FbBits fgxor, - FbBits bgand, - FbBits bgxor, - - int xRot, - int yRot); - -/* - * fbtile.c - */ - -extern _X_EXPORT void -fbEvenTile (FbBits *dst, - FbStride dstStride, - int dstX, - - int width, - int height, - - FbBits *tile, - FbStride tileStride, - int tileHeight, - - int alu, - FbBits pm, - int xRot, - int yRot); - -extern _X_EXPORT void -fbOddTile (FbBits *dst, - FbStride dstStride, - int dstX, - - int width, - int height, - - FbBits *tile, - FbStride tileStride, - int tileWidth, - int tileHeight, - - int alu, - FbBits pm, - int bpp, - - int xRot, - int yRot); - -extern _X_EXPORT void -fbTile (FbBits *dst, - FbStride dstStride, - int dstX, - - int width, - int height, - - FbBits *tile, - FbStride tileStride, - int tileWidth, - int tileHeight, - - int alu, - FbBits pm, - int bpp, - - int xRot, - int yRot); - -/* - * fbutil.c - */ -extern _X_EXPORT FbBits -fbReplicatePixel (Pixel p, int bpp); - -extern _X_EXPORT void -fbReduceRasterOp (int rop, FbBits fg, FbBits pm, FbBits *andp, FbBits *xorp); - -#ifdef FB_ACCESS_WRAPPER -extern _X_EXPORT ReadMemoryProcPtr wfbReadMemory; -extern _X_EXPORT WriteMemoryProcPtr wfbWriteMemory; -#endif - -/* - * fbwindow.c - */ - -extern _X_EXPORT Bool -fbCreateWindow(WindowPtr pWin); - -extern _X_EXPORT Bool -fbDestroyWindow(WindowPtr pWin); - -extern _X_EXPORT Bool -fbMapWindow(WindowPtr pWindow); - -extern _X_EXPORT Bool -fbPositionWindow(WindowPtr pWin, int x, int y); - -extern _X_EXPORT Bool -fbUnmapWindow(WindowPtr pWindow); - -extern _X_EXPORT void -fbCopyWindowProc (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pbox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure); - -extern _X_EXPORT void -fbCopyWindow(WindowPtr pWin, - DDXPointRec ptOldOrg, - RegionPtr prgnSrc); - -extern _X_EXPORT Bool -fbChangeWindowAttributes(WindowPtr pWin, unsigned long mask); - -extern _X_EXPORT void -fbFillRegionSolid (DrawablePtr pDrawable, - RegionPtr pRegion, - FbBits and, - FbBits xor); - -extern _X_EXPORT pixman_image_t * -image_from_pict (PicturePtr pict, - Bool has_clip, - int *xoff, - int *yoff); - -extern _X_EXPORT void free_pixman_pict (PicturePtr, pixman_image_t *); - -#endif /* _FB_H_ */ - +/* + * + * Copyright © 1998 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + + +#ifndef _FB_H_ +#define _FB_H_ + +#include +#include + +#include "scrnintstr.h" +#include "pixmap.h" +#include "pixmapstr.h" +#include "region.h" +#include "gcstruct.h" +#include "colormap.h" +#include "miscstruct.h" +#include "servermd.h" +#include "windowstr.h" +#include "privates.h" +#include "mi.h" +#include "migc.h" +#include "mibstore.h" +#include "picturestr.h" + +#ifdef FB_ACCESS_WRAPPER + +#include "wfbrename.h" +#define FBPREFIX(x) wfb##x +#define WRITE(ptr, val) ((*wfbWriteMemory)((ptr), (val), sizeof(*(ptr)))) +#define READ(ptr) ((*wfbReadMemory)((ptr), sizeof(*(ptr)))) + +#define MEMCPY_WRAPPED(dst, src, size) do { \ + size_t _i; \ + CARD8 *_dst = (CARD8*)(dst), *_src = (CARD8*)(src); \ + for(_i = 0; _i < size; _i++) { \ + WRITE(_dst +_i, READ(_src + _i)); \ + } \ +} while(0) + +#define MEMSET_WRAPPED(dst, val, size) do { \ + size_t _i; \ + CARD8 *_dst = (CARD8*)(dst); \ + for(_i = 0; _i < size; _i++) { \ + WRITE(_dst +_i, (val)); \ + } \ +} while(0) + +#else + +#define FBPREFIX(x) fb##x +#define WRITE(ptr, val) (*(ptr) = (val)) +#define READ(ptr) (*(ptr)) +#define MEMCPY_WRAPPED(dst, src, size) memcpy((dst), (src), (size)) +#define MEMSET_WRAPPED(dst, val, size) memset((dst), (val), (size)) + +#endif + +/* + * This single define controls the basic size of data manipulated + * by this software; it must be log2(sizeof (FbBits) * 8) + */ + +#ifndef FB_SHIFT +#define FB_SHIFT LOG2_BITMAP_PAD +#endif + +#if FB_SHIFT < LOG2_BITMAP_PAD + error FB_SHIFT must be >= LOG2_BITMAP_PAD +#endif + +#define FB_UNIT (1 << FB_SHIFT) +#define FB_HALFUNIT (1 << (FB_SHIFT-1)) +#define FB_MASK (FB_UNIT - 1) +#define FB_ALLONES ((FbBits) -1) + +#if GLYPHPADBYTES != 4 +#error "GLYPHPADBYTES must be 4" +#endif +/* whether to bother to include 24bpp support */ +#ifndef FBNO24BIT +#define FB_24BIT +#endif + +/* + * Unless otherwise instructed, fb includes code to advertise 24bpp + * windows with 32bpp image format for application compatibility + */ + +#ifdef FB_24BIT +#ifndef FBNO24_32 +#define FB_24_32BIT +#endif +#endif + +#define FB_STIP_SHIFT LOG2_BITMAP_PAD +#define FB_STIP_UNIT (1 << FB_STIP_SHIFT) +#define FB_STIP_MASK (FB_STIP_UNIT - 1) +#define FB_STIP_ALLONES ((FbStip) -1) + +#define FB_STIP_ODDSTRIDE(s) (((s) & (FB_MASK >> FB_STIP_SHIFT)) != 0) +#define FB_STIP_ODDPTR(p) ((((long) (p)) & (FB_MASK >> 3)) != 0) + +#define FbStipStrideToBitsStride(s) (((s) >> (FB_SHIFT - FB_STIP_SHIFT))) +#define FbBitsStrideToStipStride(s) (((s) << (FB_SHIFT - FB_STIP_SHIFT))) + +#define FbFullMask(n) ((n) == FB_UNIT ? FB_ALLONES : ((((FbBits) 1) << n) - 1)) + +#if FB_SHIFT == 6 +# ifdef WIN32 +typedef unsigned __int64 FbBits; +# else +# if defined(__alpha__) || defined(__alpha) || \ + defined(ia64) || defined(__ia64__) || \ + defined(__sparc64__) || defined(_LP64) || \ + defined(__s390x__) || \ + defined(amd64) || defined (__amd64__) || \ + defined (__powerpc64__) +typedef unsigned long FbBits; +# else +typedef unsigned long long FbBits; +# endif +# endif +#endif + +#if FB_SHIFT == 5 +typedef CARD32 FbBits; +#endif + +#if FB_SHIFT == 4 +typedef CARD16 FbBits; +#endif + +#if LOG2_BITMAP_PAD == FB_SHIFT +typedef FbBits FbStip; +#else +# if LOG2_BITMAP_PAD == 5 +typedef CARD32 FbStip; +# endif +#endif + +typedef int FbStride; + + +#ifdef FB_DEBUG +extern _X_EXPORT void fbValidateDrawable(DrawablePtr d); +extern _X_EXPORT void fbInitializeDrawable(DrawablePtr d); +extern _X_EXPORT void fbSetBits (FbStip *bits, int stride, FbStip data); +#define FB_HEAD_BITS (FbStip) (0xbaadf00d) +#define FB_TAIL_BITS (FbStip) (0xbaddf0ad) +#else +#define fbValidateDrawable(d) +#define fdInitializeDrawable(d) +#endif + +#include "fbrop.h" + +#if BITMAP_BIT_ORDER == LSBFirst +#define FbScrLeft(x,n) ((x) >> (n)) +#define FbScrRight(x,n) ((x) << (n)) +/* #define FbLeftBits(x,n) ((x) & ((((FbBits) 1) << (n)) - 1)) */ +#define FbLeftStipBits(x,n) ((x) & ((((FbStip) 1) << (n)) - 1)) +#define FbStipMoveLsb(x,s,n) (FbStipRight (x,(s)-(n))) +#define FbPatternOffsetBits 0 +#else +#define FbScrLeft(x,n) ((x) << (n)) +#define FbScrRight(x,n) ((x) >> (n)) +/* #define FbLeftBits(x,n) ((x) >> (FB_UNIT - (n))) */ +#define FbLeftStipBits(x,n) ((x) >> (FB_STIP_UNIT - (n))) +#define FbStipMoveLsb(x,s,n) (x) +#define FbPatternOffsetBits (sizeof (FbBits) - 1) +#endif + +#include "micoord.h" + +#define FbStipLeft(x,n) FbScrLeft(x,n) +#define FbStipRight(x,n) FbScrRight(x,n) + +#define FbRotLeft(x,n) FbScrLeft(x,n) | (n ? FbScrRight(x,FB_UNIT-n) : 0) +#define FbRotRight(x,n) FbScrRight(x,n) | (n ? FbScrLeft(x,FB_UNIT-n) : 0) + +#define FbRotStipLeft(x,n) FbStipLeft(x,n) | (n ? FbStipRight(x,FB_STIP_UNIT-n) : 0) +#define FbRotStipRight(x,n) FbStipRight(x,n) | (n ? FbStipLeft(x,FB_STIP_UNIT-n) : 0) + +#define FbLeftMask(x) ( ((x) & FB_MASK) ? \ + FbScrRight(FB_ALLONES,(x) & FB_MASK) : 0) +#define FbRightMask(x) ( ((FB_UNIT - (x)) & FB_MASK) ? \ + FbScrLeft(FB_ALLONES,(FB_UNIT - (x)) & FB_MASK) : 0) + +#define FbLeftStipMask(x) ( ((x) & FB_STIP_MASK) ? \ + FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) : 0) +#define FbRightStipMask(x) ( ((FB_STIP_UNIT - (x)) & FB_STIP_MASK) ? \ + FbScrLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - (x)) & FB_STIP_MASK) : 0) + +#define FbBitsMask(x,w) (FbScrRight(FB_ALLONES,(x) & FB_MASK) & \ + FbScrLeft(FB_ALLONES,(FB_UNIT - ((x) + (w))) & FB_MASK)) + +#define FbStipMask(x,w) (FbStipRight(FB_STIP_ALLONES,(x) & FB_STIP_MASK) & \ + FbStipLeft(FB_STIP_ALLONES,(FB_STIP_UNIT - ((x)+(w))) & FB_STIP_MASK)) + + +#define FbMaskBits(x,w,l,n,r) { \ + n = (w); \ + r = FbRightMask((x)+n); \ + l = FbLeftMask(x); \ + if (l) { \ + n -= FB_UNIT - ((x) & FB_MASK); \ + if (n < 0) { \ + n = 0; \ + l &= r; \ + r = 0; \ + } \ + } \ + n >>= FB_SHIFT; \ +} + +#ifdef FBNOPIXADDR +#define FbMaskBitsBytes(x,w,copy,l,lb,n,r,rb) FbMaskBits(x,w,l,n,r) +#define FbDoLeftMaskByteRRop(dst,lb,l,and,xor) { \ + *dst = FbDoMaskRRop(*dst,and,xor,l); \ +} +#define FbDoRightMaskByteRRop(dst,rb,r,and,xor) { \ + *dst = FbDoMaskRRop(*dst,and,xor,r); \ +} +#else + +#define FbByteMaskInvalid 0x10 + +#define FbPatternOffset(o,t) ((o) ^ (FbPatternOffsetBits & ~(sizeof (t) - 1))) + +#define FbPtrOffset(p,o,t) ((t *) ((CARD8 *) (p) + (o))) +#define FbSelectPatternPart(xor,o,t) ((xor) >> (FbPatternOffset (o,t) << 3)) +#define FbStorePart(dst,off,t,xor) (WRITE(FbPtrOffset(dst,off,t), \ + FbSelectPart(xor,off,t))) +#ifndef FbSelectPart +#define FbSelectPart(x,o,t) FbSelectPatternPart(x,o,t) +#endif + +#define FbMaskBitsBytes(x,w,copy,l,lb,n,r,rb) { \ + n = (w); \ + lb = 0; \ + rb = 0; \ + r = FbRightMask((x)+n); \ + if (r) { \ + /* compute right byte length */ \ + if ((copy) && (((x) + n) & 7) == 0) { \ + rb = (((x) + n) & FB_MASK) >> 3; \ + } else { \ + rb = FbByteMaskInvalid; \ + } \ + } \ + l = FbLeftMask(x); \ + if (l) { \ + /* compute left byte length */ \ + if ((copy) && ((x) & 7) == 0) { \ + lb = ((x) & FB_MASK) >> 3; \ + } else { \ + lb = FbByteMaskInvalid; \ + } \ + /* subtract out the portion painted by leftMask */ \ + n -= FB_UNIT - ((x) & FB_MASK); \ + if (n < 0) { \ + if (lb != FbByteMaskInvalid) { \ + if (rb == FbByteMaskInvalid) { \ + lb = FbByteMaskInvalid; \ + } else if (rb) { \ + lb |= (rb - lb) << (FB_SHIFT - 3); \ + rb = 0; \ + } \ + } \ + n = 0; \ + l &= r; \ + r = 0; \ + }\ + } \ + n >>= FB_SHIFT; \ +} + +#if FB_SHIFT == 6 +#define FbDoLeftMaskByteRRop6Cases(dst,xor) \ + case (sizeof (FbBits) - 7) | (1 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 7) | (2 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 7) | (3 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + break; \ + case (sizeof (FbBits) - 7) | (4 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 7) | (5 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + break; \ + case (sizeof (FbBits) - 7) | (6 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 7): \ + FbStorePart(dst,sizeof (FbBits) - 7,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ + break; \ + case (sizeof (FbBits) - 6) | (1 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 6) | (2 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + break; \ + case (sizeof (FbBits) - 6) | (3 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 6) | (4 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + break; \ + case (sizeof (FbBits) - 6) | (5 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 6): \ + FbStorePart(dst,sizeof (FbBits) - 6,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ + break; \ + case (sizeof (FbBits) - 5) | (1 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 5) | (2 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 5) | (3 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + break; \ + case (sizeof (FbBits) - 5) | (4 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 5): \ + FbStorePart(dst,sizeof (FbBits) - 5,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ + break; \ + case (sizeof (FbBits) - 4) | (1 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 4) | (2 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + break; \ + case (sizeof (FbBits) - 4) | (3 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD16,xor); \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 4): \ + FbStorePart(dst,sizeof (FbBits) - 4,CARD32,xor); \ + break; + +#define FbDoRightMaskByteRRop6Cases(dst,xor) \ + case 4: \ + FbStorePart(dst,0,CARD32,xor); \ + break; \ + case 5: \ + FbStorePart(dst,0,CARD32,xor); \ + FbStorePart(dst,4,CARD8,xor); \ + break; \ + case 6: \ + FbStorePart(dst,0,CARD32,xor); \ + FbStorePart(dst,4,CARD16,xor); \ + break; \ + case 7: \ + FbStorePart(dst,0,CARD32,xor); \ + FbStorePart(dst,4,CARD16,xor); \ + FbStorePart(dst,6,CARD8,xor); \ + break; +#else +#define FbDoLeftMaskByteRRop6Cases(dst,xor) +#define FbDoRightMaskByteRRop6Cases(dst,xor) +#endif + +#define FbDoLeftMaskByteRRop(dst,lb,l,and,xor) { \ + switch (lb) { \ + FbDoLeftMaskByteRRop6Cases(dst,xor) \ + case (sizeof (FbBits) - 3) | (1 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 3) | (2 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ + break; \ + case (sizeof (FbBits) - 2) | (1 << (FB_SHIFT - 3)): \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD8,xor); \ + break; \ + case sizeof (FbBits) - 3: \ + FbStorePart(dst,sizeof (FbBits) - 3,CARD8,xor); \ + case sizeof (FbBits) - 2: \ + FbStorePart(dst,sizeof (FbBits) - 2,CARD16,xor); \ + break; \ + case sizeof (FbBits) - 1: \ + FbStorePart(dst,sizeof (FbBits) - 1,CARD8,xor); \ + break; \ + default: \ + WRITE(dst, FbDoMaskRRop(READ(dst), and, xor, l)); \ + break; \ + } \ +} + + +#define FbDoRightMaskByteRRop(dst,rb,r,and,xor) { \ + switch (rb) { \ + case 1: \ + FbStorePart(dst,0,CARD8,xor); \ + break; \ + case 2: \ + FbStorePart(dst,0,CARD16,xor); \ + break; \ + case 3: \ + FbStorePart(dst,0,CARD16,xor); \ + FbStorePart(dst,2,CARD8,xor); \ + break; \ + FbDoRightMaskByteRRop6Cases(dst,xor) \ + default: \ + WRITE(dst, FbDoMaskRRop (READ(dst), and, xor, r)); \ + } \ +} +#endif + +#define FbMaskStip(x,w,l,n,r) { \ + n = (w); \ + r = FbRightStipMask((x)+n); \ + l = FbLeftStipMask(x); \ + if (l) { \ + n -= FB_STIP_UNIT - ((x) & FB_STIP_MASK); \ + if (n < 0) { \ + n = 0; \ + l &= r; \ + r = 0; \ + } \ + } \ + n >>= FB_STIP_SHIFT; \ +} + +/* + * These macros are used to transparently stipple + * in copy mode; the expected usage is with 'n' constant + * so all of the conditional parts collapse into a minimal + * sequence of partial word writes + * + * 'n' is the bytemask of which bytes to store, 'a' is the address + * of the FbBits base unit, 'o' is the offset within that unit + * + * The term "lane" comes from the hardware term "byte-lane" which + */ + +#define FbLaneCase1(n,a,o) \ + if ((n) == 0x01) { \ + WRITE((CARD8 *) ((a)+FbPatternOffset(o,CARD8)), fgxor); \ + } + +#define FbLaneCase2(n,a,o) \ + if ((n) == 0x03) { \ + WRITE((CARD16 *) ((a)+FbPatternOffset(o,CARD16)), fgxor); \ + } else { \ + FbLaneCase1((n)&1,a,o) \ + FbLaneCase1((n)>>1,a,(o)+1) \ + } + +#define FbLaneCase4(n,a,o) \ + if ((n) == 0x0f) { \ + WRITE((CARD32 *) ((a)+FbPatternOffset(o,CARD32)), fgxor); \ + } else { \ + FbLaneCase2((n)&3,a,o) \ + FbLaneCase2((n)>>2,a,(o)+2) \ + } + +#define FbLaneCase8(n,a,o) \ + if ((n) == 0x0ff) { \ + *(FbBits *) ((a)+(o)) = fgxor; \ + } else { \ + FbLaneCase4((n)&15,a,o) \ + FbLaneCase4((n)>>4,a,(o)+4) \ + } + +#if FB_SHIFT == 6 +#define FbLaneCase(n,a) FbLaneCase8(n,(CARD8 *) (a),0) +#endif + +#if FB_SHIFT == 5 +#define FbLaneCase(n,a) FbLaneCase4(n,(CARD8 *) (a),0) +#endif + +/* Rotate a filled pixel value to the specified alignement */ +#define FbRot24(p,b) (FbScrRight(p,b) | FbScrLeft(p,24-(b))) +#define FbRot24Stip(p,b) (FbStipRight(p,b) | FbStipLeft(p,24-(b))) + +/* step a filled pixel value to the next/previous FB_UNIT alignment */ +#define FbNext24Pix(p) (FbRot24(p,(24-FB_UNIT%24))) +#define FbPrev24Pix(p) (FbRot24(p,FB_UNIT%24)) +#define FbNext24Stip(p) (FbRot24(p,(24-FB_STIP_UNIT%24))) +#define FbPrev24Stip(p) (FbRot24(p,FB_STIP_UNIT%24)) + +/* step a rotation value to the next/previous rotation value */ +#if FB_UNIT == 64 +#define FbNext24Rot(r) ((r) == 16 ? 0 : (r) + 8) +#define FbPrev24Rot(r) ((r) == 0 ? 16 : (r) - 8) + +#if IMAGE_BYTE_ORDER == MSBFirst +#define FbFirst24Rot(x) (((x) + 8) % 24) +#else +#define FbFirst24Rot(x) ((x) % 24) +#endif + +#endif + +#if FB_UNIT == 32 +#define FbNext24Rot(r) ((r) == 0 ? 16 : (r) - 8) +#define FbPrev24Rot(r) ((r) == 16 ? 0 : (r) + 8) + +#if IMAGE_BYTE_ORDER == MSBFirst +#define FbFirst24Rot(x) (((x) + 16) % 24) +#else +#define FbFirst24Rot(x) ((x) % 24) +#endif +#endif + +#define FbNext24RotStip(r) ((r) == 0 ? 16 : (r) - 8) +#define FbPrev24RotStip(r) ((r) == 16 ? 0 : (r) + 8) + +/* Whether 24-bit specific code is needed for this filled pixel value */ +#define FbCheck24Pix(p) ((p) == FbNext24Pix(p)) + +/* Macros for dealing with dashing */ + +#define FbDashDeclare \ + unsigned char *__dash, *__firstDash, *__lastDash + +#define FbDashInit(pGC,pPriv,dashOffset,dashlen,even) { \ + (even) = TRUE; \ + __firstDash = (pGC)->dash; \ + __lastDash = __firstDash + (pGC)->numInDashList; \ + (dashOffset) %= (pPriv)->dashLength; \ + \ + __dash = __firstDash; \ + while ((dashOffset) >= ((dashlen) = *__dash)) \ + { \ + (dashOffset) -= (dashlen); \ + (even) = 1-(even); \ + if (++__dash == __lastDash) \ + __dash = __firstDash; \ + } \ + (dashlen) -= (dashOffset); \ +} + +#define FbDashNext(dashlen) { \ + if (++__dash == __lastDash) \ + __dash = __firstDash; \ + (dashlen) = *__dash; \ +} + +/* as numInDashList is always even, this case can skip a test */ + +#define FbDashNextEven(dashlen) { \ + (dashlen) = *++__dash; \ +} + +#define FbDashNextOdd(dashlen) FbDashNext(dashlen) + +#define FbDashStep(dashlen,even) { \ + if (!--(dashlen)) { \ + FbDashNext(dashlen); \ + (even) = 1-(even); \ + } \ +} + +extern _X_EXPORT DevPrivateKey +fbGetGCPrivateKey (void); + +extern _X_EXPORT DevPrivateKey +fbGetWinPrivateKey (void); + +extern _X_EXPORT const GCOps fbGCOps; +extern _X_EXPORT const GCFuncs fbGCFuncs; + +#ifdef FB_24_32BIT +#define FB_SCREEN_PRIVATE +#endif + +/* Framebuffer access wrapper */ +typedef FbBits (*ReadMemoryProcPtr)(const void *src, int size); +typedef void (*WriteMemoryProcPtr)(void *dst, FbBits value, int size); +typedef void (*SetupWrapProcPtr)(ReadMemoryProcPtr *pRead, + WriteMemoryProcPtr *pWrite, + DrawablePtr pDraw); +typedef void (*FinishWrapProcPtr)(DrawablePtr pDraw); + +#ifdef FB_ACCESS_WRAPPER + +#define fbPrepareAccess(pDraw) \ + fbGetScreenPrivate((pDraw)->pScreen)->setupWrap( \ + &wfbReadMemory, \ + &wfbWriteMemory, \ + (pDraw)) +#define fbFinishAccess(pDraw) \ + fbGetScreenPrivate((pDraw)->pScreen)->finishWrap(pDraw) + +#else + +#define fbPrepareAccess(pPix) +#define fbFinishAccess(pDraw) + +#endif + + +#ifdef FB_SCREEN_PRIVATE +extern _X_EXPORT DevPrivateKey +fbGetScreenPrivateKey(void); + +/* private field of a screen */ +typedef struct { + unsigned char win32bpp; /* window bpp for 32-bpp images */ + unsigned char pix32bpp; /* pixmap bpp for 32-bpp images */ +#ifdef FB_ACCESS_WRAPPER + SetupWrapProcPtr setupWrap; /* driver hook to set pixmap access wrapping */ + FinishWrapProcPtr finishWrap; /* driver hook to clean up pixmap access wrapping */ +#endif +} FbScreenPrivRec, *FbScreenPrivPtr; + +#define fbGetScreenPrivate(pScreen) ((FbScreenPrivPtr) \ + dixLookupPrivate(&(pScreen)->devPrivates, fbGetScreenPrivateKey())) +#endif + +/* private field of GC */ +typedef struct { + FbBits and, xor; /* reduced rop values */ + FbBits bgand, bgxor; /* for stipples */ + FbBits fg, bg, pm; /* expanded and filled */ + unsigned int dashLength; /* total of all dash elements */ + unsigned char evenStipple; /* stipple is even */ + unsigned char bpp; /* current drawable bpp */ +} FbGCPrivRec, *FbGCPrivPtr; + +#define fbGetGCPrivate(pGC) ((FbGCPrivPtr)\ + dixLookupPrivate(&(pGC)->devPrivates, fbGetGCPrivateKey())) + +#define fbGetCompositeClip(pGC) ((pGC)->pCompositeClip) +#define fbGetExpose(pGC) ((pGC)->fExpose) +#define fbGetFreeCompClip(pGC) ((pGC)->freeCompClip) +#define fbGetRotatedPixmap(pGC) ((pGC)->pRotatedPixmap) + +#define fbGetScreenPixmap(s) ((PixmapPtr) (s)->devPrivate) +#define fbGetWindowPixmap(pWin) ((PixmapPtr)\ + dixLookupPrivate(&((WindowPtr)(pWin))->devPrivates, fbGetWinPrivateKey())) + +#ifdef ROOTLESS +#define __fbPixDrawableX(pPix) ((pPix)->drawable.x) +#define __fbPixDrawableY(pPix) ((pPix)->drawable.y) +#else +#define __fbPixDrawableX(pPix) 0 +#define __fbPixDrawableY(pPix) 0 +#endif + +#ifdef COMPOSITE +#define __fbPixOffXWin(pPix) (__fbPixDrawableX(pPix) - (pPix)->screen_x) +#define __fbPixOffYWin(pPix) (__fbPixDrawableY(pPix) - (pPix)->screen_y) +#else +#define __fbPixOffXWin(pPix) (__fbPixDrawableX(pPix)) +#define __fbPixOffYWin(pPix) (__fbPixDrawableY(pPix)) +#endif +#define __fbPixOffXPix(pPix) (__fbPixDrawableX(pPix)) +#define __fbPixOffYPix(pPix) (__fbPixDrawableY(pPix)) + +#define fbGetDrawablePixmap(pDrawable, pixmap, xoff, yoff) { \ + if ((pDrawable)->type != DRAWABLE_PIXMAP) { \ + (pixmap) = fbGetWindowPixmap(pDrawable); \ + (xoff) = __fbPixOffXWin(pixmap); \ + (yoff) = __fbPixOffYWin(pixmap); \ + } else { \ + (pixmap) = (PixmapPtr) (pDrawable); \ + (xoff) = __fbPixOffXPix(pixmap); \ + (yoff) = __fbPixOffYPix(pixmap); \ + } \ + fbPrepareAccess(pDrawable); \ +} + +#define fbGetPixmapBitsData(pixmap, pointer, stride, bpp) { \ + (pointer) = (FbBits *) (pixmap)->devPrivate.ptr; \ + (stride) = ((int) (pixmap)->devKind) / sizeof (FbBits); (void)(stride); \ + (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \ +} + +#define fbGetPixmapStipData(pixmap, pointer, stride, bpp) { \ + (pointer) = (FbStip *) (pixmap)->devPrivate.ptr; \ + (stride) = ((int) (pixmap)->devKind) / sizeof (FbStip); (void)(stride); \ + (bpp) = (pixmap)->drawable.bitsPerPixel; (void)(bpp); \ +} + +#define fbGetDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \ + PixmapPtr _pPix; \ + fbGetDrawablePixmap(pDrawable, _pPix, xoff, yoff); \ + fbGetPixmapBitsData(_pPix, pointer, stride, bpp); \ +} + +#define fbGetStipDrawable(pDrawable, pointer, stride, bpp, xoff, yoff) { \ + PixmapPtr _pPix; \ + fbGetDrawablePixmap(pDrawable, _pPix, xoff, yoff); \ + fbGetPixmapStipData(_pPix, pointer, stride, bpp); \ +} + +/* + * XFree86 empties the root BorderClip when the VT is inactive, + * here's a macro which uses that to disable GetImage and GetSpans + */ + +#define fbWindowEnabled(pWin) \ + RegionNotEmpty(&(pWin)->drawable.pScreen->root->borderClip) + +#define fbDrawableEnabled(pDrawable) \ + ((pDrawable)->type == DRAWABLE_PIXMAP ? \ + TRUE : fbWindowEnabled((WindowPtr) pDrawable)) + +#define FbPowerOfTwo(w) (((w) & ((w) - 1)) == 0) +/* + * Accelerated tiles are power of 2 width <= FB_UNIT + */ +#define FbEvenTile(w) ((w) <= FB_UNIT && FbPowerOfTwo(w)) +/* + * Accelerated stipples are power of 2 width and <= FB_UNIT/dstBpp + * with dstBpp a power of 2 as well + */ +#define FbEvenStip(w,bpp) ((w) * (bpp) <= FB_UNIT && FbPowerOfTwo(w) && FbPowerOfTwo(bpp)) + +/* + * fb24_32.c + */ +extern _X_EXPORT void +fb24_32GetSpans(DrawablePtr pDrawable, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pchardstStart); + +extern _X_EXPORT void +fb24_32SetSpans (DrawablePtr pDrawable, + GCPtr pGC, + char *src, + DDXPointPtr ppt, + int *pwidth, + int nspans, + int fSorted); + +extern _X_EXPORT void +fb24_32PutZImage (DrawablePtr pDrawable, + RegionPtr pClip, + int alu, + FbBits pm, + int x, + int y, + int width, + int height, + CARD8 *src, + FbStride srcStride); + +extern _X_EXPORT void +fb24_32GetImage (DrawablePtr pDrawable, + int x, + int y, + int w, + int h, + unsigned int format, + unsigned long planeMask, + char *d); + +extern _X_EXPORT void +fb24_32CopyMtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +extern _X_EXPORT PixmapPtr +fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel); + +extern _X_EXPORT Bool +fb24_32CreateScreenResources(ScreenPtr pScreen); + +extern _X_EXPORT Bool +fb24_32ModifyPixmapHeader (PixmapPtr pPixmap, + int width, + int height, + int depth, + int bitsPerPixel, + int devKind, + pointer pPixData); + +/* + * fballpriv.c + */ +extern _X_EXPORT Bool +fbAllocatePrivates(ScreenPtr pScreen, DevPrivateKey *pGCIndex); + +/* + * fbarc.c + */ + +extern _X_EXPORT void +fbPolyArc (DrawablePtr pDrawable, + GCPtr pGC, + int narcs, + xArc *parcs); + +/* + * fbbits.c + */ + +extern _X_EXPORT void +fbBresSolid8(DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +extern _X_EXPORT void +fbBresDash8 (DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +extern _X_EXPORT void +fbDots8 (FbBits *dst, + FbStride dstStride, + int dstBpp, + BoxPtr pBox, + xPoint *pts, + int npt, + int xorg, + int yorg, + int xoff, + int yoff, + FbBits and, + FbBits xor); + +extern _X_EXPORT void +fbArc8 (FbBits *dst, + FbStride dstStride, + int dstBpp, + xArc *arc, + int dx, + int dy, + FbBits and, + FbBits xor); + +extern _X_EXPORT void +fbGlyph8 (FbBits *dstLine, + FbStride dstStride, + int dstBpp, + FbStip *stipple, + FbBits fg, + int height, + int shift); + +extern _X_EXPORT void +fbPolyline8 (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ptsOrig); + +extern _X_EXPORT void +fbPolySegment8 (DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pseg); + +extern _X_EXPORT void +fbBresSolid16(DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +extern _X_EXPORT void +fbBresDash16(DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +extern _X_EXPORT void +fbDots16(FbBits *dst, + FbStride dstStride, + int dstBpp, + BoxPtr pBox, + xPoint *pts, + int npt, + int xorg, + int yorg, + int xoff, + int yoff, + FbBits and, + FbBits xor); + +extern _X_EXPORT void +fbArc16(FbBits *dst, + FbStride dstStride, + int dstBpp, + xArc *arc, + int dx, + int dy, + FbBits and, + FbBits xor); + +extern _X_EXPORT void +fbGlyph16(FbBits *dstLine, + FbStride dstStride, + int dstBpp, + FbStip *stipple, + FbBits fg, + int height, + int shift); + +extern _X_EXPORT void +fbPolyline16 (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ptsOrig); + +extern _X_EXPORT void +fbPolySegment16 (DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pseg); + + +extern _X_EXPORT void +fbBresSolid24(DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +extern _X_EXPORT void +fbBresDash24(DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +extern _X_EXPORT void +fbDots24(FbBits *dst, + FbStride dstStride, + int dstBpp, + BoxPtr pBox, + xPoint *pts, + int npt, + int xorg, + int yorg, + int xoff, + int yoff, + FbBits and, + FbBits xor); + +extern _X_EXPORT void +fbArc24(FbBits *dst, + FbStride dstStride, + int dstBpp, + xArc *arc, + int dx, + int dy, + FbBits and, + FbBits xor); + +extern _X_EXPORT void +fbGlyph24(FbBits *dstLine, + FbStride dstStride, + int dstBpp, + FbStip *stipple, + FbBits fg, + int height, + int shift); + +extern _X_EXPORT void +fbPolyline24 (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ptsOrig); + +extern _X_EXPORT void +fbPolySegment24 (DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pseg); + + +extern _X_EXPORT void +fbBresSolid32(DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +extern _X_EXPORT void +fbBresDash32(DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +extern _X_EXPORT void +fbDots32(FbBits *dst, + FbStride dstStride, + int dstBpp, + BoxPtr pBox, + xPoint *pts, + int npt, + int xorg, + int yorg, + int xoff, + int yoff, + FbBits and, + FbBits xor); + +extern _X_EXPORT void +fbArc32(FbBits *dst, + FbStride dstStride, + int dstBpp, + xArc *arc, + int dx, + int dy, + FbBits and, + FbBits xor); + +extern _X_EXPORT void +fbGlyph32(FbBits *dstLine, + FbStride dstStride, + int dstBpp, + FbStip *stipple, + FbBits fg, + int height, + int shift); +extern _X_EXPORT void +fbPolyline32 (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ptsOrig); + +extern _X_EXPORT void +fbPolySegment32 (DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pseg); + +/* + * fbblt.c + */ +extern _X_EXPORT void +fbBlt (FbBits *src, + FbStride srcStride, + int srcX, + + FbBits *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + int alu, + FbBits pm, + int bpp, + + Bool reverse, + Bool upsidedown); + +extern _X_EXPORT void +fbBlt24 (FbBits *srcLine, + FbStride srcStride, + int srcX, + + FbBits *dstLine, + FbStride dstStride, + int dstX, + + int width, + int height, + + int alu, + FbBits pm, + + Bool reverse, + Bool upsidedown); + +extern _X_EXPORT void +fbBltStip (FbStip *src, + FbStride srcStride, /* in FbStip units, not FbBits units */ + int srcX, + + FbStip *dst, + FbStride dstStride, /* in FbStip units, not FbBits units */ + int dstX, + + int width, + int height, + + int alu, + FbBits pm, + int bpp); + +/* + * fbbltone.c + */ +extern _X_EXPORT void +fbBltOne (FbStip *src, + FbStride srcStride, + int srcX, + FbBits *dst, + FbStride dstStride, + int dstX, + int dstBpp, + + int width, + int height, + + FbBits fgand, + FbBits fbxor, + FbBits bgand, + FbBits bgxor); + +#ifdef FB_24BIT +extern _X_EXPORT void +fbBltOne24 (FbStip *src, + FbStride srcStride, /* FbStip units per scanline */ + int srcX, /* bit position of source */ + FbBits *dst, + FbStride dstStride, /* FbBits units per scanline */ + int dstX, /* bit position of dest */ + int dstBpp, /* bits per destination unit */ + + int width, /* width in bits of destination */ + int height, /* height in scanlines */ + + FbBits fgand, /* rrop values */ + FbBits fgxor, + FbBits bgand, + FbBits bgxor); +#endif + +extern _X_EXPORT void +fbBltPlane (FbBits *src, + FbStride srcStride, + int srcX, + int srcBpp, + + FbStip *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + FbStip fgand, + FbStip fgxor, + FbStip bgand, + FbStip bgxor, + Pixel planeMask); + +/* + * fbcmap_mi.c + */ +extern _X_EXPORT int +fbListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps); + +extern _X_EXPORT void +fbInstallColormap(ColormapPtr pmap); + +extern _X_EXPORT void +fbUninstallColormap(ColormapPtr pmap); + +extern _X_EXPORT void +fbResolveColor(unsigned short *pred, + unsigned short *pgreen, + unsigned short *pblue, + VisualPtr pVisual); + +extern _X_EXPORT Bool +fbInitializeColormap(ColormapPtr pmap); + +extern _X_EXPORT int +fbExpandDirectColors (ColormapPtr pmap, + int ndef, + xColorItem *indefs, + xColorItem *outdefs); + +extern _X_EXPORT Bool +fbCreateDefColormap(ScreenPtr pScreen); + +extern _X_EXPORT void +fbClearVisualTypes(void); + +extern _X_EXPORT Bool +fbHasVisualTypes (int depth); + +extern _X_EXPORT Bool +fbSetVisualTypes (int depth, int visuals, int bitsPerRGB); + +extern _X_EXPORT Bool +fbSetVisualTypesAndMasks (int depth, int visuals, int bitsPerRGB, + Pixel redMask, Pixel greenMask, Pixel blueMask); + +extern _X_EXPORT Bool +fbInitVisuals (VisualPtr *visualp, + DepthPtr *depthp, + int *nvisualp, + int *ndepthp, + int *rootDepthp, + VisualID *defaultVisp, + unsigned long sizes, + int bitsPerRGB); + +/* + * fbcopy.c + */ + +/* Compatibility definition, to be removed at next ABI change. */ +typedef void (*fbCopyProc) (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pDstBox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +extern _X_EXPORT void +fbCopyNtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +/* Compatibility wrapper, to be removed at next ABI change. */ +extern _X_EXPORT void +fbCopyRegion (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + RegionPtr pDstRegion, + int dx, + int dy, + fbCopyProc copyProc, + Pixel bitPlane, + void *closure); + +/* Compatibility wrapper, to be removed at next ABI change. */ +extern _X_EXPORT RegionPtr +fbDoCopy (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, + int yOut, + fbCopyProc copyProc, + Pixel bitplane, + void *closure); + +extern _X_EXPORT void +fbCopy1toN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +extern _X_EXPORT void +fbCopyNto1 (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +extern _X_EXPORT RegionPtr +fbCopyArea (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, + int yOut); + +extern _X_EXPORT RegionPtr +fbCopyPlane (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + int xIn, + int yIn, + int widthSrc, + int heightSrc, + int xOut, + int yOut, + unsigned long bitplane); + +/* + * fbfill.c + */ +extern _X_EXPORT void +fbFill (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + int width, + int height); + +extern _X_EXPORT void +fbSolidBoxClipped (DrawablePtr pDrawable, + RegionPtr pClip, + int xa, + int ya, + int xb, + int yb, + FbBits and, + FbBits xor); + +/* + * fbfillrect.c + */ +extern _X_EXPORT void +fbPolyFillRect(DrawablePtr pDrawable, + GCPtr pGC, + int nrectInit, + xRectangle *prectInit); + +#define fbPolyFillArc miPolyFillArc + +#define fbFillPolygon miFillPolygon + +/* + * fbfillsp.c + */ +extern _X_EXPORT void +fbFillSpans (DrawablePtr pDrawable, + GCPtr pGC, + int nInit, + DDXPointPtr pptInit, + int *pwidthInit, + int fSorted); + + +/* + * fbgc.c + */ + +extern _X_EXPORT Bool +fbCreateGC(GCPtr pGC); + +extern _X_EXPORT void +fbPadPixmap (PixmapPtr pPixmap); + +extern _X_EXPORT void +fbValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable); + +/* + * fbgetsp.c + */ +extern _X_EXPORT void +fbGetSpans(DrawablePtr pDrawable, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pchardstStart); + +/* + * fbglyph.c + */ + +extern _X_EXPORT Bool +fbGlyphIn (RegionPtr pRegion, + int x, + int y, + int width, + int height); + +extern _X_EXPORT void +fbPolyGlyphBlt (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, + CharInfoPtr *ppci, + pointer pglyphBase); + +extern _X_EXPORT void +fbImageGlyphBlt (DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nglyph, + CharInfoPtr *ppci, + pointer pglyphBase); + +/* + * fbimage.c + */ + +extern _X_EXPORT void +fbPutImage (DrawablePtr pDrawable, + GCPtr pGC, + int depth, + int x, + int y, + int w, + int h, + int leftPad, + int format, + char *pImage); + +extern _X_EXPORT void +fbPutZImage (DrawablePtr pDrawable, + RegionPtr pClip, + int alu, + FbBits pm, + int x, + int y, + int width, + int height, + FbStip *src, + FbStride srcStride); + +extern _X_EXPORT void +fbPutXYImage (DrawablePtr pDrawable, + RegionPtr pClip, + FbBits fg, + FbBits bg, + FbBits pm, + int alu, + Bool opaque, + + int x, + int y, + int width, + int height, + + FbStip *src, + FbStride srcStride, + int srcX); + +extern _X_EXPORT void +fbGetImage (DrawablePtr pDrawable, + int x, + int y, + int w, + int h, + unsigned int format, + unsigned long planeMask, + char *d); +/* + * fbline.c + */ + +extern _X_EXPORT void +fbZeroLine (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ppt); + +extern _X_EXPORT void +fbZeroSegment (DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pSegs); + +extern _X_EXPORT void +fbPolyLine (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr ppt); + +extern _X_EXPORT void +fbFixCoordModePrevious (int npt, + DDXPointPtr ppt); + +extern _X_EXPORT void +fbPolySegment (DrawablePtr pDrawable, + GCPtr pGC, + int nseg, + xSegment *pseg); + +#define fbPolyRectangle miPolyRectangle + +/* + * fbpict.c + */ + +extern _X_EXPORT Bool +fbPictureInit (ScreenPtr pScreen, + PictFormatPtr formats, + int nformats); + +/* + * fbpixmap.c + */ + +extern _X_EXPORT PixmapPtr +fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp, + unsigned class); + +extern _X_EXPORT PixmapPtr +fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth, + unsigned class); + +extern _X_EXPORT Bool +fbDestroyPixmap (PixmapPtr pPixmap); + +extern _X_EXPORT RegionPtr +fbPixmapToRegion(PixmapPtr pPix); + +/* + * fbpoint.c + */ + +extern _X_EXPORT void +fbDots (FbBits *dstOrig, + FbStride dstStride, + int dstBpp, + BoxPtr pBox, + xPoint *pts, + int npt, + int xorg, + int yorg, + int xoff, + int yoff, + FbBits andOrig, + FbBits xorOrig); + +extern _X_EXPORT void +fbPolyPoint (DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int npt, + xPoint *pptInit); + +/* + * fbpush.c + */ +extern _X_EXPORT void +fbPushPattern (DrawablePtr pDrawable, + GCPtr pGC, + + FbStip *src, + FbStride srcStride, + int srcX, + + int x, + int y, + + int width, + int height); + +extern _X_EXPORT void +fbPushFill (DrawablePtr pDrawable, + GCPtr pGC, + + FbStip *src, + FbStride srcStride, + int srcX, + + int x, + int y, + int width, + int height); + +extern _X_EXPORT void +fbPushImage (DrawablePtr pDrawable, + GCPtr pGC, + + FbStip *src, + FbStride srcStride, + int srcX, + + int x, + int y, + int width, + int height); + +extern _X_EXPORT void +fbPushPixels (GCPtr pGC, + PixmapPtr pBitmap, + DrawablePtr pDrawable, + int dx, + int dy, + int xOrg, + int yOrg); + + +/* + * fbscreen.c + */ + +extern _X_EXPORT Bool +fbCloseScreen (int indx, ScreenPtr pScreen); + +extern _X_EXPORT Bool +fbRealizeFont(ScreenPtr pScreen, FontPtr pFont); + +extern _X_EXPORT Bool +fbUnrealizeFont(ScreenPtr pScreen, FontPtr pFont); + +extern _X_EXPORT void +fbQueryBestSize (int class, + unsigned short *width, unsigned short *height, + ScreenPtr pScreen); + +extern _X_EXPORT PixmapPtr +_fbGetWindowPixmap (WindowPtr pWindow); + +extern _X_EXPORT void +_fbSetWindowPixmap (WindowPtr pWindow, PixmapPtr pPixmap); + +extern _X_EXPORT Bool +fbSetupScreen(ScreenPtr pScreen, + pointer pbits, /* pointer to screen bitmap */ + int xsize, /* in pixels */ + int ysize, + int dpix, /* dots per inch */ + int dpiy, + int width, /* pixel width of frame buffer */ + int bpp); /* bits per pixel of frame buffer */ + +extern _X_EXPORT Bool +wfbFinishScreenInit(ScreenPtr pScreen, + pointer pbits, + int xsize, + int ysize, + int dpix, + int dpiy, + int width, + int bpp, + SetupWrapProcPtr setupWrap, + FinishWrapProcPtr finishWrap); + +extern _X_EXPORT Bool +wfbScreenInit(ScreenPtr pScreen, + pointer pbits, + int xsize, + int ysize, + int dpix, + int dpiy, + int width, + int bpp, + SetupWrapProcPtr setupWrap, + FinishWrapProcPtr finishWrap); + +extern _X_EXPORT Bool +fbFinishScreenInit(ScreenPtr pScreen, + pointer pbits, + int xsize, + int ysize, + int dpix, + int dpiy, + int width, + int bpp); + +extern _X_EXPORT Bool +fbScreenInit(ScreenPtr pScreen, + pointer pbits, + int xsize, + int ysize, + int dpix, + int dpiy, + int width, + int bpp); + +/* + * fbseg.c + */ +typedef void FbBres (DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +extern _X_EXPORT FbBres fbBresSolid, fbBresDash, fbBresFill, fbBresFillDash; +/* + * fbsetsp.c + */ + +extern _X_EXPORT void +fbSetSpans (DrawablePtr pDrawable, + GCPtr pGC, + char *src, + DDXPointPtr ppt, + int *pwidth, + int nspans, + int fSorted); + +extern _X_EXPORT FbBres * +fbSelectBres (DrawablePtr pDrawable, + GCPtr pGC); + +extern _X_EXPORT void +fbBres (DrawablePtr pDrawable, + GCPtr pGC, + int dashOffset, + int signdx, + int signdy, + int axis, + int x, + int y, + int e, + int e1, + int e3, + int len); + +extern _X_EXPORT void +fbSegment (DrawablePtr pDrawable, + GCPtr pGC, + int xa, + int ya, + int xb, + int yb, + Bool drawLast, + int *dashOffset); + + +/* + * fbsolid.c + */ + +extern _X_EXPORT void +fbSolid (FbBits *dst, + FbStride dstStride, + int dstX, + int bpp, + + int width, + int height, + + FbBits and, + FbBits xor); + +#ifdef FB_24BIT +extern _X_EXPORT void +fbSolid24 (FbBits *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + FbBits and, + FbBits xor); +#endif + +/* + * fbstipple.c + */ + +extern _X_EXPORT void +fbTransparentSpan (FbBits *dst, + FbBits stip, + FbBits fgxor, + int n); + +extern _X_EXPORT void +fbEvenStipple (FbBits *dst, + FbStride dstStride, + int dstX, + int dstBpp, + + int width, + int height, + + FbStip *stip, + FbStride stipStride, + int stipHeight, + + FbBits fgand, + FbBits fgxor, + FbBits bgand, + FbBits bgxor, + + int xRot, + int yRot); + +extern _X_EXPORT void +fbOddStipple (FbBits *dst, + FbStride dstStride, + int dstX, + int dstBpp, + + int width, + int height, + + FbStip *stip, + FbStride stipStride, + int stipWidth, + int stipHeight, + + FbBits fgand, + FbBits fgxor, + FbBits bgand, + FbBits bgxor, + + int xRot, + int yRot); + +extern _X_EXPORT void +fbStipple (FbBits *dst, + FbStride dstStride, + int dstX, + int dstBpp, + + int width, + int height, + + FbStip *stip, + FbStride stipStride, + int stipWidth, + int stipHeight, + Bool even, + + FbBits fgand, + FbBits fgxor, + FbBits bgand, + FbBits bgxor, + + int xRot, + int yRot); + +/* + * fbtile.c + */ + +extern _X_EXPORT void +fbEvenTile (FbBits *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + FbBits *tile, + FbStride tileStride, + int tileHeight, + + int alu, + FbBits pm, + int xRot, + int yRot); + +extern _X_EXPORT void +fbOddTile (FbBits *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + FbBits *tile, + FbStride tileStride, + int tileWidth, + int tileHeight, + + int alu, + FbBits pm, + int bpp, + + int xRot, + int yRot); + +extern _X_EXPORT void +fbTile (FbBits *dst, + FbStride dstStride, + int dstX, + + int width, + int height, + + FbBits *tile, + FbStride tileStride, + int tileWidth, + int tileHeight, + + int alu, + FbBits pm, + int bpp, + + int xRot, + int yRot); + +/* + * fbutil.c + */ +extern _X_EXPORT FbBits +fbReplicatePixel (Pixel p, int bpp); + +extern _X_EXPORT void +fbReduceRasterOp (int rop, FbBits fg, FbBits pm, FbBits *andp, FbBits *xorp); + +#ifdef FB_ACCESS_WRAPPER +extern _X_EXPORT ReadMemoryProcPtr wfbReadMemory; +extern _X_EXPORT WriteMemoryProcPtr wfbWriteMemory; +#endif + +/* + * fbwindow.c + */ + +extern _X_EXPORT Bool +fbCreateWindow(WindowPtr pWin); + +extern _X_EXPORT Bool +fbDestroyWindow(WindowPtr pWin); + +extern _X_EXPORT Bool +fbMapWindow(WindowPtr pWindow); + +extern _X_EXPORT Bool +fbPositionWindow(WindowPtr pWin, int x, int y); + +extern _X_EXPORT Bool +fbUnmapWindow(WindowPtr pWindow); + +extern _X_EXPORT void +fbCopyWindowProc (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure); + +extern _X_EXPORT void +fbCopyWindow(WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc); + +extern _X_EXPORT Bool +fbChangeWindowAttributes(WindowPtr pWin, unsigned long mask); + +extern _X_EXPORT void +fbFillRegionSolid (DrawablePtr pDrawable, + RegionPtr pRegion, + FbBits and, + FbBits xor); + +extern _X_EXPORT pixman_image_t * +image_from_pict (PicturePtr pict, + Bool has_clip, + int *xoff, + int *yoff); + +extern _X_EXPORT void free_pixman_pict (PicturePtr, pixman_image_t *); + +#endif /* _FB_H_ */ + diff --git a/xorg-server/fb/fb24_32.c b/xorg-server/fb/fb24_32.c index 748a0ec04..e24f394bc 100644 --- a/xorg-server/fb/fb24_32.c +++ b/xorg-server/fb/fb24_32.c @@ -1,635 +1,635 @@ -/* - * Copyright © 2000 SuSE, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Author: Keith Packard, SuSE, Inc. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include - -#include "fb.h" - -/* X apps don't like 24bpp images, this code exposes 32bpp images */ - -/* - * These two functions do a full CopyArea while reformatting - * the data between 24 and 32bpp. They try to go a bit faster - * by reading/writing aligned CARD32s where it's easy - */ - -#define Get8(a) ((CARD32) READ(a)) - -#if BITMAP_BIT_ORDER == MSBFirst -#define Get24(a) ((Get8(a) << 16) | (Get8((a)+1) << 8) | Get8((a)+2)) -#define Put24(a,p) ((WRITE((a+0), (CARD8) ((p) >> 16))), \ - (WRITE((a+1), (CARD8) ((p) >> 8))), \ - (WRITE((a+2), (CARD8) (p)))) -#else -#define Get24(a) (Get8(a) | (Get8((a)+1) << 8) | (Get8((a)+2)<<16)) -#define Put24(a,p) ((WRITE((a+0), (CARD8) (p))), \ - (WRITE((a+1), (CARD8) ((p) >> 8))), \ - (WRITE((a+2), (CARD8) ((p) >> 16)))) -#endif - -typedef void (*fb24_32BltFunc) (CARD8 *srcLine, - FbStride srcStride, - int srcX, - - CARD8 *dstLine, - FbStride dstStride, - int dstX, - - int width, - int height, - - int alu, - FbBits pm); - -static void -fb24_32BltDown (CARD8 *srcLine, - FbStride srcStride, - int srcX, - - CARD8 *dstLine, - FbStride dstStride, - int dstX, - - int width, - int height, - - int alu, - FbBits pm) -{ - CARD32 *src; - CARD8 *dst; - int w; - Bool destInvarient; - CARD32 pixel, dpixel; - FbDeclareMergeRop (); - - srcLine += srcX * 4; - dstLine += dstX * 3; - - FbInitializeMergeRop(alu, (pm | ~(FbBits) 0xffffff)); - destInvarient = FbDestInvarientMergeRop(); - - while (height--) - { - src = (CARD32 *) srcLine; - dst = dstLine; - srcLine += srcStride; - dstLine += dstStride; - w = width; - if (destInvarient) - { - while (((long) dst & 3) && w) - { - w--; - pixel = READ(src++); - pixel = FbDoDestInvarientMergeRop(pixel); - Put24 (dst, pixel); - dst += 3; - } - /* Do four aligned pixels at a time */ - while (w >= 4) - { - CARD32 s0, s1; - s0 = READ(src++); - s0 = FbDoDestInvarientMergeRop(s0); - s1 = READ(src++); - s1 = FbDoDestInvarientMergeRop(s1); -#if BITMAP_BIT_ORDER == LSBFirst - WRITE((CARD32 *)dst, (s0 & 0xffffff) | (s1 << 24)); -#else - WRITE((CARD32 *)dst, (s0 << 8) | ((s1 & 0xffffff) >> 16)); -#endif - s0 = READ(src++); - s0 = FbDoDestInvarientMergeRop(s0); -#if BITMAP_BIT_ORDER == LSBFirst - WRITE((CARD32 *)(dst+4), ((s1 & 0xffffff) >> 8) | (s0 << 16)); -#else - WRITE((CARD32 *)(dst+4), (s1 << 16) | ((s0 & 0xffffff) >> 8)); -#endif - s1 = READ(src++); - s1 = FbDoDestInvarientMergeRop(s1); -#if BITMAP_BIT_ORDER == LSBFirst - WRITE((CARD32 *)(dst+8), ((s0 & 0xffffff) >> 16) | (s1 << 8)); -#else - WRITE((CARD32 *)(dst+8), (s0 << 24) | (s1 & 0xffffff)); -#endif - dst += 12; - w -= 4; - } - while (w--) - { - pixel = READ(src++); - pixel = FbDoDestInvarientMergeRop(pixel); - Put24 (dst, pixel); - dst += 3; - } - } - else - { - while (w--) - { - pixel = READ(src++); - dpixel = Get24 (dst); - pixel = FbDoMergeRop(pixel, dpixel); - Put24 (dst, pixel); - dst += 3; - } - } - } -} - -static void -fb24_32BltUp (CARD8 *srcLine, - FbStride srcStride, - int srcX, - - CARD8 *dstLine, - FbStride dstStride, - int dstX, - - int width, - int height, - - int alu, - FbBits pm) -{ - CARD8 *src; - CARD32 *dst; - int w; - Bool destInvarient; - CARD32 pixel; - FbDeclareMergeRop (); - - FbInitializeMergeRop(alu, (pm | (~(FbBits) 0xffffff))); - destInvarient = FbDestInvarientMergeRop(); - - srcLine += srcX * 3; - dstLine += dstX * 4; - - while (height--) - { - w = width; - src = srcLine; - dst = (CARD32 *) dstLine; - srcLine += srcStride; - dstLine += dstStride; - if (destInvarient) - { - while (((long) src & 3) && w) - { - w--; - pixel = Get24(src); - src += 3; - WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); - } - /* Do four aligned pixels at a time */ - while (w >= 4) - { - CARD32 s0, s1; - - s0 = READ((CARD32 *)src); -#if BITMAP_BIT_ORDER == LSBFirst - pixel = s0 & 0xffffff; -#else - pixel = s0 >> 8; -#endif - WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); - s1 = READ((CARD32 *)(src+4)); -#if BITMAP_BIT_ORDER == LSBFirst - pixel = (s0 >> 24) | ((s1 << 8) & 0xffffff); -#else - pixel = ((s0 << 16) & 0xffffff) | (s1 >> 16); -#endif - WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); - s0 = READ((CARD32 *)(src+8)); -#if BITMAP_BIT_ORDER == LSBFirst - pixel = (s1 >> 16) | ((s0 << 16) & 0xffffff); -#else - pixel = ((s1 << 8) & 0xffffff) | (s0 >> 24); -#endif - WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); -#if BITMAP_BIT_ORDER == LSBFirst - pixel = s0 >> 8; -#else - pixel = s0 & 0xffffff; -#endif - WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); - src += 12; - w -= 4; - } - while (w) - { - w--; - pixel = Get24(src); - src += 3; - WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); - } - } - else - { - while (w--) - { - pixel = Get24(src); - src += 3; - WRITE(dst, FbDoMergeRop(pixel, READ(dst))); - dst++; - } - } - } -} - -/* - * Spans functions; probably unused. - */ -void -fb24_32GetSpans(DrawablePtr pDrawable, - int wMax, - DDXPointPtr ppt, - int *pwidth, - int nspans, - char *pchardstStart) -{ - FbBits *srcBits; - CARD8 *src; - FbStride srcStride; - int srcBpp; - int srcXoff, srcYoff; - CARD8 *dst; - - fbGetDrawable (pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); - src = (CARD8 *) srcBits; - srcStride *= sizeof (FbBits); - - while (nspans--) - { - dst = (CARD8 *) pchardstStart; - fb24_32BltUp (src + (ppt->y + srcYoff) * srcStride, srcStride, - ppt->x + srcXoff, - - dst, - 1, - 0, - - *pwidth, - 1, - - GXcopy, - FB_ALLONES); - - pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth); - ppt++; - pwidth++; - } - - fbFinishAccess (pDrawable); -} - -void -fb24_32SetSpans (DrawablePtr pDrawable, - GCPtr pGC, - char *src, - DDXPointPtr ppt, - int *pwidth, - int nspans, - int fSorted) -{ - FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); - RegionPtr pClip = fbGetCompositeClip(pGC); - FbBits *dstBits; - CARD8 *dst, *d, *s; - FbStride dstStride; - int dstBpp; - int dstXoff, dstYoff; - BoxPtr pbox; - int n; - int x1, x2; - - fbGetDrawable (pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); - dst = (CARD8 *) dstBits; - dstStride *= sizeof (FbBits); - while (nspans--) - { - d = dst + (ppt->y + dstYoff) * dstStride; - s = (CARD8 *) src; - n = RegionNumRects(pClip); - pbox = RegionRects (pClip); - while (n--) - { - if (pbox->y1 > ppt->y) - break; - if (pbox->y2 > ppt->y) - { - x1 = ppt->x; - x2 = x1 + *pwidth; - if (pbox->x1 > x1) - x1 = pbox->x1; - if (pbox->x2 < x2) - x2 = pbox->x2; - if (x1 < x2) - fb24_32BltDown (s, - 0, - (x1 - ppt->x), - d, - dstStride, - x1 + dstXoff, - - (x2 - x1), - 1, - pGC->alu, - pPriv->pm); - } - } - src += PixmapBytePad (*pwidth, pDrawable->depth); - ppt++; - pwidth++; - } - - fbFinishAccess (pDrawable); -} - -/* - * Clip and put 32bpp Z-format images to a 24bpp drawable - */ -void -fb24_32PutZImage (DrawablePtr pDrawable, - RegionPtr pClip, - int alu, - FbBits pm, - int x, - int y, - int width, - int height, - CARD8 *src, - FbStride srcStride) -{ - FbBits *dstBits; - CARD8 *dst; - FbStride dstStride; - int dstBpp; - int dstXoff, dstYoff; - int nbox; - BoxPtr pbox; - int x1, y1, x2, y2; - - fbGetDrawable (pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); - dstStride *= sizeof(FbBits); - dst = (CARD8 *) dstBits; - - for (nbox = RegionNumRects (pClip), - pbox = RegionRects(pClip); - nbox--; - pbox++) - { - x1 = x; - y1 = y; - x2 = x + width; - y2 = y + height; - if (x1 < pbox->x1) - x1 = pbox->x1; - if (y1 < pbox->y1) - y1 = pbox->y1; - if (x2 > pbox->x2) - x2 = pbox->x2; - if (y2 > pbox->y2) - y2 = pbox->y2; - if (x1 >= x2 || y1 >= y2) - continue; - fb24_32BltDown (src + (y1 - y) * srcStride, - srcStride, - (x1 - x), - - dst + (y1 + dstYoff) * dstStride, - dstStride, - x1 + dstXoff, - - (x2 - x1), - (y2 - y1), - - alu, - pm); - } - - fbFinishAccess (pDrawable); -} - -void -fb24_32GetImage (DrawablePtr pDrawable, - int x, - int y, - int w, - int h, - unsigned int format, - unsigned long planeMask, - char *d) -{ - FbBits *srcBits; - CARD8 *src; - FbStride srcStride; - int srcBpp; - int srcXoff, srcYoff; - FbStride dstStride; - FbBits pm; - - fbGetDrawable (pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); - src = (CARD8 *) srcBits; - srcStride *= sizeof (FbBits); - - x += pDrawable->x; - y += pDrawable->y; - - pm = fbReplicatePixel (planeMask, 32); - dstStride = PixmapBytePad(w, pDrawable->depth); - if (pm != FB_ALLONES) - memset (d, 0, dstStride * h); - fb24_32BltUp (src + (y + srcYoff) * srcStride, srcStride, x + srcXoff, - (CARD8 *) d, dstStride, 0, - w, h, GXcopy, pm); - - fbFinishAccess (pDrawable); -} - -void -fb24_32CopyMtoN (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pbox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure) -{ - FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); - FbBits *srcBits; - CARD8 *src; - FbStride srcStride; - int srcBpp; - FbBits *dstBits; - CARD8 *dst; - FbStride dstStride; - int dstBpp; - fb24_32BltFunc blt; - int srcXoff, srcYoff; - int dstXoff, dstYoff; - - fbGetDrawable (pSrcDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); - src = (CARD8 *) srcBits; - srcStride *= sizeof (FbBits); - fbGetDrawable (pDstDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); - dst = (CARD8 *) dstBits; - dstStride *= sizeof (FbBits); - if (srcBpp == 24) - blt = fb24_32BltUp; - else - blt = fb24_32BltDown; - - while (nbox--) - { - (*blt) (src + (pbox->y1 + dy + srcYoff) * srcStride, - srcStride, - (pbox->x1 + dx + srcXoff), - - dst + (pbox->y1 + dstYoff) * dstStride, - dstStride, - (pbox->x1 + dstXoff), - - (pbox->x2 - pbox->x1), - (pbox->y2 - pbox->y1), - - pGC->alu, - pPriv->pm); - pbox++; - } - - fbFinishAccess (pSrcDrawable); - fbFinishAccess (pDstDrawable); -} - -PixmapPtr -fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel) -{ - ScreenPtr pScreen = pOldTile->drawable.pScreen; - PixmapPtr pNewTile; - FbBits *old, *new; - FbStride oldStride, newStride; - int oldBpp, newBpp; - fb24_32BltFunc blt; - int oldXoff, oldYoff; - int newXoff, newYoff; - - pNewTile = pScreen->CreatePixmap(pScreen, pOldTile->drawable.width, - pOldTile->drawable.height, - pOldTile->drawable.depth, - pOldTile->usage_hint); - if (!pNewTile) - return 0; - fbGetDrawable (&pOldTile->drawable, - old, oldStride, oldBpp, oldXoff, oldYoff); - fbGetDrawable (&pNewTile->drawable, - new, newStride, newBpp, newXoff, newYoff); - if (oldBpp == 24) - blt = fb24_32BltUp; - else - blt = fb24_32BltDown; - - (*blt) ((CARD8 *) old, - oldStride * sizeof (FbBits), - 0, - - (CARD8 *) new, - newStride * sizeof (FbBits), - 0, - - pOldTile->drawable.width, - pOldTile->drawable.height, - - GXcopy, - FB_ALLONES); - - fbFinishAccess (&pOldTile->drawable); - fbFinishAccess (&pNewTile->drawable); - - return pNewTile; -} - -typedef struct { - pointer pbits; - int width; -} miScreenInitParmsRec, *miScreenInitParmsPtr; - -Bool -fb24_32CreateScreenResources(ScreenPtr pScreen) -{ - miScreenInitParmsPtr pScrInitParms; - int pitch; - Bool retval; - - /* get the pitch before mi destroys it */ - pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate; - pitch = BitmapBytePad(pScrInitParms->width * 24); - - if((retval = miCreateScreenResources(pScreen))) { - /* fix the screen pixmap */ - PixmapPtr pPix = (PixmapPtr)pScreen->devPrivate; - pPix->drawable.bitsPerPixel = 24; - pPix->devKind = pitch; - } - - return retval; -} - -Bool -fb24_32ModifyPixmapHeader (PixmapPtr pPixmap, - int width, - int height, - int depth, - int bitsPerPixel, - int devKind, - pointer pPixData) -{ - int bpp, w; - - if (!pPixmap) - return FALSE; - bpp = bitsPerPixel; - if (bpp <= 0) - bpp = pPixmap->drawable.bitsPerPixel; - if (bpp == 24) - { - if (devKind < 0) - { - w = width; - if (w <= 0) - w = pPixmap->drawable.width; - devKind = BitmapBytePad(w * 24); - } - } - return miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, - devKind, pPixData); -} +/* + * Copyright © 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include "fb.h" + +/* X apps don't like 24bpp images, this code exposes 32bpp images */ + +/* + * These two functions do a full CopyArea while reformatting + * the data between 24 and 32bpp. They try to go a bit faster + * by reading/writing aligned CARD32s where it's easy + */ + +#define Get8(a) ((CARD32) READ(a)) + +#if BITMAP_BIT_ORDER == MSBFirst +#define Get24(a) ((Get8(a) << 16) | (Get8((a)+1) << 8) | Get8((a)+2)) +#define Put24(a,p) ((WRITE((a+0), (CARD8) ((p) >> 16))), \ + (WRITE((a+1), (CARD8) ((p) >> 8))), \ + (WRITE((a+2), (CARD8) (p)))) +#else +#define Get24(a) (Get8(a) | (Get8((a)+1) << 8) | (Get8((a)+2)<<16)) +#define Put24(a,p) ((WRITE((a+0), (CARD8) (p))), \ + (WRITE((a+1), (CARD8) ((p) >> 8))), \ + (WRITE((a+2), (CARD8) ((p) >> 16)))) +#endif + +typedef void (*fb24_32BltFunc) (CARD8 *srcLine, + FbStride srcStride, + int srcX, + + CARD8 *dstLine, + FbStride dstStride, + int dstX, + + int width, + int height, + + int alu, + FbBits pm); + +static void +fb24_32BltDown (CARD8 *srcLine, + FbStride srcStride, + int srcX, + + CARD8 *dstLine, + FbStride dstStride, + int dstX, + + int width, + int height, + + int alu, + FbBits pm) +{ + CARD32 *src; + CARD8 *dst; + int w; + Bool destInvarient; + CARD32 pixel, dpixel; + FbDeclareMergeRop (); + + srcLine += srcX * 4; + dstLine += dstX * 3; + + FbInitializeMergeRop(alu, (pm | ~(FbBits) 0xffffff)); + destInvarient = FbDestInvarientMergeRop(); + + while (height--) + { + src = (CARD32 *) srcLine; + dst = dstLine; + srcLine += srcStride; + dstLine += dstStride; + w = width; + if (destInvarient) + { + while (((long) dst & 3) && w) + { + w--; + pixel = READ(src++); + pixel = FbDoDestInvarientMergeRop(pixel); + Put24 (dst, pixel); + dst += 3; + } + /* Do four aligned pixels at a time */ + while (w >= 4) + { + CARD32 s0, s1; + s0 = READ(src++); + s0 = FbDoDestInvarientMergeRop(s0); + s1 = READ(src++); + s1 = FbDoDestInvarientMergeRop(s1); +#if BITMAP_BIT_ORDER == LSBFirst + WRITE((CARD32 *)dst, (s0 & 0xffffff) | (s1 << 24)); +#else + WRITE((CARD32 *)dst, (s0 << 8) | ((s1 & 0xffffff) >> 16)); +#endif + s0 = READ(src++); + s0 = FbDoDestInvarientMergeRop(s0); +#if BITMAP_BIT_ORDER == LSBFirst + WRITE((CARD32 *)(dst+4), ((s1 & 0xffffff) >> 8) | (s0 << 16)); +#else + WRITE((CARD32 *)(dst+4), (s1 << 16) | ((s0 & 0xffffff) >> 8)); +#endif + s1 = READ(src++); + s1 = FbDoDestInvarientMergeRop(s1); +#if BITMAP_BIT_ORDER == LSBFirst + WRITE((CARD32 *)(dst+8), ((s0 & 0xffffff) >> 16) | (s1 << 8)); +#else + WRITE((CARD32 *)(dst+8), (s0 << 24) | (s1 & 0xffffff)); +#endif + dst += 12; + w -= 4; + } + while (w--) + { + pixel = READ(src++); + pixel = FbDoDestInvarientMergeRop(pixel); + Put24 (dst, pixel); + dst += 3; + } + } + else + { + while (w--) + { + pixel = READ(src++); + dpixel = Get24 (dst); + pixel = FbDoMergeRop(pixel, dpixel); + Put24 (dst, pixel); + dst += 3; + } + } + } +} + +static void +fb24_32BltUp (CARD8 *srcLine, + FbStride srcStride, + int srcX, + + CARD8 *dstLine, + FbStride dstStride, + int dstX, + + int width, + int height, + + int alu, + FbBits pm) +{ + CARD8 *src; + CARD32 *dst; + int w; + Bool destInvarient; + CARD32 pixel; + FbDeclareMergeRop (); + + FbInitializeMergeRop(alu, (pm | (~(FbBits) 0xffffff))); + destInvarient = FbDestInvarientMergeRop(); + + srcLine += srcX * 3; + dstLine += dstX * 4; + + while (height--) + { + w = width; + src = srcLine; + dst = (CARD32 *) dstLine; + srcLine += srcStride; + dstLine += dstStride; + if (destInvarient) + { + while (((long) src & 3) && w) + { + w--; + pixel = Get24(src); + src += 3; + WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); + } + /* Do four aligned pixels at a time */ + while (w >= 4) + { + CARD32 s0, s1; + + s0 = READ((CARD32 *)src); +#if BITMAP_BIT_ORDER == LSBFirst + pixel = s0 & 0xffffff; +#else + pixel = s0 >> 8; +#endif + WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); + s1 = READ((CARD32 *)(src+4)); +#if BITMAP_BIT_ORDER == LSBFirst + pixel = (s0 >> 24) | ((s1 << 8) & 0xffffff); +#else + pixel = ((s0 << 16) & 0xffffff) | (s1 >> 16); +#endif + WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); + s0 = READ((CARD32 *)(src+8)); +#if BITMAP_BIT_ORDER == LSBFirst + pixel = (s1 >> 16) | ((s0 << 16) & 0xffffff); +#else + pixel = ((s1 << 8) & 0xffffff) | (s0 >> 24); +#endif + WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); +#if BITMAP_BIT_ORDER == LSBFirst + pixel = s0 >> 8; +#else + pixel = s0 & 0xffffff; +#endif + WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); + src += 12; + w -= 4; + } + while (w) + { + w--; + pixel = Get24(src); + src += 3; + WRITE(dst++, FbDoDestInvarientMergeRop(pixel)); + } + } + else + { + while (w--) + { + pixel = Get24(src); + src += 3; + WRITE(dst, FbDoMergeRop(pixel, READ(dst))); + dst++; + } + } + } +} + +/* + * Spans functions; probably unused. + */ +void +fb24_32GetSpans(DrawablePtr pDrawable, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pchardstStart) +{ + FbBits *srcBits; + CARD8 *src; + FbStride srcStride; + int srcBpp; + int srcXoff, srcYoff; + CARD8 *dst; + + fbGetDrawable (pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); + src = (CARD8 *) srcBits; + srcStride *= sizeof (FbBits); + + while (nspans--) + { + dst = (CARD8 *) pchardstStart; + fb24_32BltUp (src + (ppt->y + srcYoff) * srcStride, srcStride, + ppt->x + srcXoff, + + dst, + 1, + 0, + + *pwidth, + 1, + + GXcopy, + FB_ALLONES); + + pchardstStart += PixmapBytePad(*pwidth, pDrawable->depth); + ppt++; + pwidth++; + } + + fbFinishAccess (pDrawable); +} + +void +fb24_32SetSpans (DrawablePtr pDrawable, + GCPtr pGC, + char *src, + DDXPointPtr ppt, + int *pwidth, + int nspans, + int fSorted) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate (pGC); + RegionPtr pClip = fbGetCompositeClip(pGC); + FbBits *dstBits; + CARD8 *dst, *d, *s; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + BoxPtr pbox; + int n; + int x1, x2; + + fbGetDrawable (pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); + dst = (CARD8 *) dstBits; + dstStride *= sizeof (FbBits); + while (nspans--) + { + d = dst + (ppt->y + dstYoff) * dstStride; + s = (CARD8 *) src; + n = RegionNumRects(pClip); + pbox = RegionRects (pClip); + while (n--) + { + if (pbox->y1 > ppt->y) + break; + if (pbox->y2 > ppt->y) + { + x1 = ppt->x; + x2 = x1 + *pwidth; + if (pbox->x1 > x1) + x1 = pbox->x1; + if (pbox->x2 < x2) + x2 = pbox->x2; + if (x1 < x2) + fb24_32BltDown (s, + 0, + (x1 - ppt->x), + d, + dstStride, + x1 + dstXoff, + + (x2 - x1), + 1, + pGC->alu, + pPriv->pm); + } + } + src += PixmapBytePad (*pwidth, pDrawable->depth); + ppt++; + pwidth++; + } + + fbFinishAccess (pDrawable); +} + +/* + * Clip and put 32bpp Z-format images to a 24bpp drawable + */ +void +fb24_32PutZImage (DrawablePtr pDrawable, + RegionPtr pClip, + int alu, + FbBits pm, + int x, + int y, + int width, + int height, + CARD8 *src, + FbStride srcStride) +{ + FbBits *dstBits; + CARD8 *dst; + FbStride dstStride; + int dstBpp; + int dstXoff, dstYoff; + int nbox; + BoxPtr pbox; + int x1, y1, x2, y2; + + fbGetDrawable (pDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); + dstStride *= sizeof(FbBits); + dst = (CARD8 *) dstBits; + + for (nbox = RegionNumRects (pClip), + pbox = RegionRects(pClip); + nbox--; + pbox++) + { + x1 = x; + y1 = y; + x2 = x + width; + y2 = y + height; + if (x1 < pbox->x1) + x1 = pbox->x1; + if (y1 < pbox->y1) + y1 = pbox->y1; + if (x2 > pbox->x2) + x2 = pbox->x2; + if (y2 > pbox->y2) + y2 = pbox->y2; + if (x1 >= x2 || y1 >= y2) + continue; + fb24_32BltDown (src + (y1 - y) * srcStride, + srcStride, + (x1 - x), + + dst + (y1 + dstYoff) * dstStride, + dstStride, + x1 + dstXoff, + + (x2 - x1), + (y2 - y1), + + alu, + pm); + } + + fbFinishAccess (pDrawable); +} + +void +fb24_32GetImage (DrawablePtr pDrawable, + int x, + int y, + int w, + int h, + unsigned int format, + unsigned long planeMask, + char *d) +{ + FbBits *srcBits; + CARD8 *src; + FbStride srcStride; + int srcBpp; + int srcXoff, srcYoff; + FbStride dstStride; + FbBits pm; + + fbGetDrawable (pDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); + src = (CARD8 *) srcBits; + srcStride *= sizeof (FbBits); + + x += pDrawable->x; + y += pDrawable->y; + + pm = fbReplicatePixel (planeMask, 32); + dstStride = PixmapBytePad(w, pDrawable->depth); + if (pm != FB_ALLONES) + memset (d, 0, dstStride * h); + fb24_32BltUp (src + (y + srcYoff) * srcStride, srcStride, x + srcXoff, + (CARD8 *) d, dstStride, 0, + w, h, GXcopy, pm); + + fbFinishAccess (pDrawable); +} + +void +fb24_32CopyMtoN (DrawablePtr pSrcDrawable, + DrawablePtr pDstDrawable, + GCPtr pGC, + BoxPtr pbox, + int nbox, + int dx, + int dy, + Bool reverse, + Bool upsidedown, + Pixel bitplane, + void *closure) +{ + FbGCPrivPtr pPriv = fbGetGCPrivate(pGC); + FbBits *srcBits; + CARD8 *src; + FbStride srcStride; + int srcBpp; + FbBits *dstBits; + CARD8 *dst; + FbStride dstStride; + int dstBpp; + fb24_32BltFunc blt; + int srcXoff, srcYoff; + int dstXoff, dstYoff; + + fbGetDrawable (pSrcDrawable, srcBits, srcStride, srcBpp, srcXoff, srcYoff); + src = (CARD8 *) srcBits; + srcStride *= sizeof (FbBits); + fbGetDrawable (pDstDrawable, dstBits, dstStride, dstBpp, dstXoff, dstYoff); + dst = (CARD8 *) dstBits; + dstStride *= sizeof (FbBits); + if (srcBpp == 24) + blt = fb24_32BltUp; + else + blt = fb24_32BltDown; + + while (nbox--) + { + (*blt) (src + (pbox->y1 + dy + srcYoff) * srcStride, + srcStride, + (pbox->x1 + dx + srcXoff), + + dst + (pbox->y1 + dstYoff) * dstStride, + dstStride, + (pbox->x1 + dstXoff), + + (pbox->x2 - pbox->x1), + (pbox->y2 - pbox->y1), + + pGC->alu, + pPriv->pm); + pbox++; + } + + fbFinishAccess (pSrcDrawable); + fbFinishAccess (pDstDrawable); +} + +PixmapPtr +fb24_32ReformatTile(PixmapPtr pOldTile, int bitsPerPixel) +{ + ScreenPtr pScreen = pOldTile->drawable.pScreen; + PixmapPtr pNewTile; + FbBits *old, *new; + FbStride oldStride, newStride; + int oldBpp, newBpp; + fb24_32BltFunc blt; + int oldXoff, oldYoff; + int newXoff, newYoff; + + pNewTile = pScreen->CreatePixmap(pScreen, pOldTile->drawable.width, + pOldTile->drawable.height, + pOldTile->drawable.depth, + pOldTile->drawable.class); + if (!pNewTile) + return 0; + fbGetDrawable (&pOldTile->drawable, + old, oldStride, oldBpp, oldXoff, oldYoff); + fbGetDrawable (&pNewTile->drawable, + new, newStride, newBpp, newXoff, newYoff); + if (oldBpp == 24) + blt = fb24_32BltUp; + else + blt = fb24_32BltDown; + + (*blt) ((CARD8 *) old, + oldStride * sizeof (FbBits), + 0, + + (CARD8 *) new, + newStride * sizeof (FbBits), + 0, + + pOldTile->drawable.width, + pOldTile->drawable.height, + + GXcopy, + FB_ALLONES); + + fbFinishAccess (&pOldTile->drawable); + fbFinishAccess (&pNewTile->drawable); + + return pNewTile; +} + +typedef struct { + pointer pbits; + int width; +} miScreenInitParmsRec, *miScreenInitParmsPtr; + +Bool +fb24_32CreateScreenResources(ScreenPtr pScreen) +{ + miScreenInitParmsPtr pScrInitParms; + int pitch; + Bool retval; + + /* get the pitch before mi destroys it */ + pScrInitParms = (miScreenInitParmsPtr)pScreen->devPrivate; + pitch = BitmapBytePad(pScrInitParms->width * 24); + + if((retval = miCreateScreenResources(pScreen))) { + /* fix the screen pixmap */ + PixmapPtr pPix = (PixmapPtr)pScreen->devPrivate; + pPix->drawable.bitsPerPixel = 24; + pPix->devKind = pitch; + } + + return retval; +} + +Bool +fb24_32ModifyPixmapHeader (PixmapPtr pPixmap, + int width, + int height, + int depth, + int bitsPerPixel, + int devKind, + pointer pPixData) +{ + int bpp, w; + + if (!pPixmap) + return FALSE; + bpp = bitsPerPixel; + if (bpp <= 0) + bpp = pPixmap->drawable.bitsPerPixel; + if (bpp == 24) + { + if (devKind < 0) + { + w = width; + if (w <= 0) + w = pPixmap->drawable.width; + devKind = BitmapBytePad(w * 24); + } + } + return miModifyPixmapHeader(pPixmap, width, height, depth, bitsPerPixel, + devKind, pPixData); +} diff --git a/xorg-server/fb/fbpixmap.c b/xorg-server/fb/fbpixmap.c index 155f1e134..232de82a9 100644 --- a/xorg-server/fb/fbpixmap.c +++ b/xorg-server/fb/fbpixmap.c @@ -1,392 +1,390 @@ -/* - * Copyright © 1998 Keith Packard - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of Keith Packard not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Keith Packard makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR - * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, - * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER - * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include - -#include "fb.h" - -PixmapPtr -fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp, - unsigned usage_hint) -{ - PixmapPtr pPixmap; - size_t datasize; - size_t paddedWidth; - int adjust; - int base; - - paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits); - if (paddedWidth / 4 > 32767 || height > 32767) - return NullPixmap; - datasize = height * paddedWidth; - base = pScreen->totalPixmapSize; - adjust = 0; - if (base & 7) - adjust = 8 - (base & 7); - datasize += adjust; -#ifdef FB_DEBUG - datasize += 2 * paddedWidth; -#endif - pPixmap = AllocatePixmap(pScreen, datasize); - if (!pPixmap) - return NullPixmap; - pPixmap->drawable.type = DRAWABLE_PIXMAP; - pPixmap->drawable.class = 0; - pPixmap->drawable.pScreen = pScreen; - pPixmap->drawable.depth = depth; - pPixmap->drawable.bitsPerPixel = bpp; - pPixmap->drawable.id = 0; - pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; - pPixmap->drawable.x = 0; - pPixmap->drawable.y = 0; - pPixmap->drawable.width = width; - pPixmap->drawable.height = height; - pPixmap->devKind = paddedWidth; - pPixmap->refcnt = 1; - pPixmap->devPrivate.ptr = (pointer) ((char *)pPixmap + base + adjust); - -#ifdef FB_DEBUG - pPixmap->devPrivate.ptr = (void *) ((char *) pPixmap->devPrivate.ptr + paddedWidth); - fbInitializeDrawable (&pPixmap->drawable); -#endif - -#ifdef COMPOSITE - pPixmap->screen_x = 0; - pPixmap->screen_y = 0; -#endif - - pPixmap->usage_hint = usage_hint; - - return pPixmap; -} - -PixmapPtr -fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth, - unsigned usage_hint) -{ - int bpp; - bpp = BitsPerPixel (depth); -#ifdef FB_SCREEN_PRIVATE - if (bpp == 32 && depth <= 24) - bpp = fbGetScreenPrivate(pScreen)->pix32bpp; -#endif - return fbCreatePixmapBpp (pScreen, width, height, depth, bpp, usage_hint); -} - -Bool -fbDestroyPixmap (PixmapPtr pPixmap) -{ - if(--pPixmap->refcnt) - return TRUE; - FreePixmap(pPixmap); - return TRUE; -} - -#define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2) \ -if (((rx1) < (rx2)) && ((ry1) < (ry2)) && \ - (!((reg)->data->numRects && \ - ((r-1)->y1 == (ry1)) && \ - ((r-1)->y2 == (ry2)) && \ - ((r-1)->x1 <= (rx1)) && \ - ((r-1)->x2 >= (rx2))))) \ -{ \ - if ((reg)->data->numRects == (reg)->data->size) \ - { \ - RegionRectAlloc(reg, 1); \ - fr = RegionBoxptr(reg); \ - r = fr + (reg)->data->numRects; \ - } \ - r->x1 = (rx1); \ - r->y1 = (ry1); \ - r->x2 = (rx2); \ - r->y2 = (ry2); \ - (reg)->data->numRects++; \ - if(r->x1 < (reg)->extents.x1) \ - (reg)->extents.x1 = r->x1; \ - if(r->x2 > (reg)->extents.x2) \ - (reg)->extents.x2 = r->x2; \ - r++; \ -} - -/* Convert bitmap clip mask into clipping region. - * First, goes through each line and makes boxes by noting the transitions - * from 0 to 1 and 1 to 0. - * Then it coalesces the current line with the previous if they have boxes - * at the same X coordinates. - */ -RegionPtr -fbPixmapToRegion(PixmapPtr pPix) -{ - register RegionPtr pReg; - FbBits *pw, w; - register int ib; - int width, h, base, rx1 = 0, crects; - FbBits *pwLineEnd; - int irectPrevStart, irectLineStart; - register BoxPtr prectO, prectN; - BoxPtr FirstRect, rects, prectLineStart; - Bool fInBox, fSame; - register FbBits mask0 = FB_ALLONES & ~FbScrRight(FB_ALLONES, 1); - FbBits *pwLine; - int nWidth; - - pReg = RegionCreate(NULL, 1); - if(!pReg) - return NullRegion; - FirstRect = RegionBoxptr(pReg); - rects = FirstRect; - - fbPrepareAccess(&pPix->drawable); - - pwLine = (FbBits *) pPix->devPrivate.ptr; - nWidth = pPix->devKind >> (FB_SHIFT-3); - - width = pPix->drawable.width; - pReg->extents.x1 = width - 1; - pReg->extents.x2 = 0; - irectPrevStart = -1; - for(h = 0; h < pPix->drawable.height; h++) - { - pw = pwLine; - pwLine += nWidth; - irectLineStart = rects - FirstRect; - /* If the Screen left most bit of the word is set, we're starting in - * a box */ - if(READ(pw) & mask0) - { - fInBox = TRUE; - rx1 = 0; - } - else - fInBox = FALSE; - /* Process all words which are fully in the pixmap */ - pwLineEnd = pw + (width >> FB_SHIFT); - for (base = 0; pw < pwLineEnd; base += FB_UNIT) - { - w = READ(pw++); - if (fInBox) - { - if (!~w) - continue; - } - else - { - if (!w) - continue; - } - for(ib = 0; ib < FB_UNIT; ib++) - { - /* If the Screen left most bit of the word is set, we're - * starting a box */ - if(w & mask0) - { - if(!fInBox) - { - rx1 = base + ib; - /* start new box */ - fInBox = TRUE; - } - } - else - { - if(fInBox) - { - /* end box */ - ADDRECT(pReg, rects, FirstRect, - rx1, h, base + ib, h + 1); - fInBox = FALSE; - } - } - /* Shift the word VISUALLY left one. */ - w = FbScrLeft(w, 1); - } - } - if(width & FB_MASK) - { - /* Process final partial word on line */ - w = READ(pw++); - for(ib = 0; ib < (width & FB_MASK); ib++) - { - /* If the Screen left most bit of the word is set, we're - * starting a box */ - if(w & mask0) - { - if(!fInBox) - { - rx1 = base + ib; - /* start new box */ - fInBox = TRUE; - } - } - else - { - if(fInBox) - { - /* end box */ - ADDRECT(pReg, rects, FirstRect, - rx1, h, base + ib, h + 1); - fInBox = FALSE; - } - } - /* Shift the word VISUALLY left one. */ - w = FbScrLeft(w, 1); - } - } - /* If scanline ended with last bit set, end the box */ - if(fInBox) - { - ADDRECT(pReg, rects, FirstRect, - rx1, h, base + (width & FB_MASK), h + 1); - } - /* if all rectangles on this line have the same x-coords as - * those on the previous line, then add 1 to all the previous y2s and - * throw away all the rectangles from this line - */ - fSame = FALSE; - if(irectPrevStart != -1) - { - crects = irectLineStart - irectPrevStart; - if(crects == ((rects - FirstRect) - irectLineStart)) - { - prectO = FirstRect + irectPrevStart; - prectN = prectLineStart = FirstRect + irectLineStart; - fSame = TRUE; - while(prectO < prectLineStart) - { - if((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2)) - { - fSame = FALSE; - break; - } - prectO++; - prectN++; - } - if (fSame) - { - prectO = FirstRect + irectPrevStart; - while(prectO < prectLineStart) - { - prectO->y2 += 1; - prectO++; - } - rects -= crects; - pReg->data->numRects -= crects; - } - } - } - if(!fSame) - irectPrevStart = irectLineStart; - } - if (!pReg->data->numRects) - pReg->extents.x1 = pReg->extents.x2 = 0; - else - { - pReg->extents.y1 = RegionBoxptr(pReg)->y1; - pReg->extents.y2 = RegionEnd(pReg)->y2; - if (pReg->data->numRects == 1) - { - free(pReg->data); - pReg->data = (RegDataPtr)NULL; - } - } - - fbFinishAccess(&pPix->drawable); -#ifdef DEBUG - if (!RegionIsValid(pReg)) - FatalError("Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__); -#endif - return pReg; -} - -#ifdef FB_DEBUG - -#ifndef WIN32 -#include -#else -#include -#endif - -static Bool -fbValidateBits (FbStip *bits, int stride, FbStip data) -{ - while (stride--) - { - if (*bits != data) - { -#ifdef WIN32 - NCD_DEBUG ((DEBUG_FAILURE, "fdValidateBits failed at 0x%x (is 0x%x want 0x%x)", - bits, *bits, data)); -#else - fprintf (stderr, "fbValidateBits failed\n"); -#endif - return FALSE; - } - bits++; - } -} - -void -fbValidateDrawable (DrawablePtr pDrawable) -{ - FbStip *bits, *first, *last; - int stride, bpp; - int xoff, yoff; - int height; - Bool failed; - - if (pDrawable->type != DRAWABLE_PIXMAP) - pDrawable = (DrawablePtr) fbGetWindowPixmap(pDrawable); - fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff); - first = bits - stride; - last = bits + stride * pDrawable->height; - if (!fbValidateBits (first, stride, FB_HEAD_BITS) || - !fbValidateBits (last, stride, FB_TAIL_BITS)) - fbInitializeDrawable(pDrawable); - fbFinishAccess (pDrawable); -} - -void -fbSetBits (FbStip *bits, int stride, FbStip data) -{ - while (stride--) - *bits++ = data; -} - -void -fbInitializeDrawable (DrawablePtr pDrawable) -{ - FbStip *bits, *first, *last; - int stride, bpp; - int xoff, yoff; - - fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff); - first = bits - stride; - last = bits + stride * pDrawable->height; - fbSetBits (first, stride, FB_HEAD_BITS); - fbSetBits (last, stride, FB_TAIL_BITS); - fbFinishAccess (pDrawable); -} -#endif /* FB_DEBUG */ +/* + * Copyright © 1998 Keith Packard + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of Keith Packard not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. Keith Packard makes no + * representations about the suitability of this software for any purpose. It + * is provided "as is" without express or implied warranty. + * + * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include + +#include "fb.h" + +PixmapPtr +fbCreatePixmapBpp (ScreenPtr pScreen, int width, int height, int depth, int bpp, + unsigned class) +{ + PixmapPtr pPixmap; + size_t datasize; + size_t paddedWidth; + int adjust; + int base; + + paddedWidth = ((width * bpp + FB_MASK) >> FB_SHIFT) * sizeof (FbBits); + if (paddedWidth / 4 > 32767 || height > 32767) + return NullPixmap; + datasize = height * paddedWidth; + base = pScreen->totalPixmapSize; + adjust = 0; + if (base & 7) + adjust = 8 - (base & 7); + datasize += adjust; +#ifdef FB_DEBUG + datasize += 2 * paddedWidth; +#endif + pPixmap = AllocatePixmap(pScreen, datasize); + if (!pPixmap) + return NullPixmap; + pPixmap->drawable.type = DRAWABLE_PIXMAP; + pPixmap->drawable.class = class; + pPixmap->drawable.pScreen = pScreen; + pPixmap->drawable.depth = depth; + pPixmap->drawable.bitsPerPixel = bpp; + pPixmap->drawable.id = 0; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pPixmap->drawable.x = 0; + pPixmap->drawable.y = 0; + pPixmap->drawable.width = width; + pPixmap->drawable.height = height; + pPixmap->devKind = paddedWidth; + pPixmap->refcnt = 1; + pPixmap->devPrivate.ptr = (pointer) ((char *)pPixmap + base + adjust); + +#ifdef FB_DEBUG + pPixmap->devPrivate.ptr = (void *) ((char *) pPixmap->devPrivate.ptr + paddedWidth); + fbInitializeDrawable (&pPixmap->drawable); +#endif + +#ifdef COMPOSITE + pPixmap->screen_x = 0; + pPixmap->screen_y = 0; +#endif + + return pPixmap; +} + +PixmapPtr +fbCreatePixmap (ScreenPtr pScreen, int width, int height, int depth, + unsigned class) +{ + int bpp; + bpp = BitsPerPixel (depth); +#ifdef FB_SCREEN_PRIVATE + if (bpp == 32 && depth <= 24) + bpp = fbGetScreenPrivate(pScreen)->pix32bpp; +#endif + return fbCreatePixmapBpp (pScreen, width, height, depth, bpp, class); +} + +Bool +fbDestroyPixmap (PixmapPtr pPixmap) +{ + if(--pPixmap->refcnt) + return TRUE; + FreePixmap(pPixmap); + return TRUE; +} + +#define ADDRECT(reg,r,fr,rx1,ry1,rx2,ry2) \ +if (((rx1) < (rx2)) && ((ry1) < (ry2)) && \ + (!((reg)->data->numRects && \ + ((r-1)->y1 == (ry1)) && \ + ((r-1)->y2 == (ry2)) && \ + ((r-1)->x1 <= (rx1)) && \ + ((r-1)->x2 >= (rx2))))) \ +{ \ + if ((reg)->data->numRects == (reg)->data->size) \ + { \ + RegionRectAlloc(reg, 1); \ + fr = RegionBoxptr(reg); \ + r = fr + (reg)->data->numRects; \ + } \ + r->x1 = (rx1); \ + r->y1 = (ry1); \ + r->x2 = (rx2); \ + r->y2 = (ry2); \ + (reg)->data->numRects++; \ + if(r->x1 < (reg)->extents.x1) \ + (reg)->extents.x1 = r->x1; \ + if(r->x2 > (reg)->extents.x2) \ + (reg)->extents.x2 = r->x2; \ + r++; \ +} + +/* Convert bitmap clip mask into clipping region. + * First, goes through each line and makes boxes by noting the transitions + * from 0 to 1 and 1 to 0. + * Then it coalesces the current line with the previous if they have boxes + * at the same X coordinates. + */ +RegionPtr +fbPixmapToRegion(PixmapPtr pPix) +{ + register RegionPtr pReg; + FbBits *pw, w; + register int ib; + int width, h, base, rx1 = 0, crects; + FbBits *pwLineEnd; + int irectPrevStart, irectLineStart; + register BoxPtr prectO, prectN; + BoxPtr FirstRect, rects, prectLineStart; + Bool fInBox, fSame; + register FbBits mask0 = FB_ALLONES & ~FbScrRight(FB_ALLONES, 1); + FbBits *pwLine; + int nWidth; + + pReg = RegionCreate(NULL, 1); + if(!pReg) + return NullRegion; + FirstRect = RegionBoxptr(pReg); + rects = FirstRect; + + fbPrepareAccess(&pPix->drawable); + + pwLine = (FbBits *) pPix->devPrivate.ptr; + nWidth = pPix->devKind >> (FB_SHIFT-3); + + width = pPix->drawable.width; + pReg->extents.x1 = width - 1; + pReg->extents.x2 = 0; + irectPrevStart = -1; + for(h = 0; h < pPix->drawable.height; h++) + { + pw = pwLine; + pwLine += nWidth; + irectLineStart = rects - FirstRect; + /* If the Screen left most bit of the word is set, we're starting in + * a box */ + if(READ(pw) & mask0) + { + fInBox = TRUE; + rx1 = 0; + } + else + fInBox = FALSE; + /* Process all words which are fully in the pixmap */ + pwLineEnd = pw + (width >> FB_SHIFT); + for (base = 0; pw < pwLineEnd; base += FB_UNIT) + { + w = READ(pw++); + if (fInBox) + { + if (!~w) + continue; + } + else + { + if (!w) + continue; + } + for(ib = 0; ib < FB_UNIT; ib++) + { + /* If the Screen left most bit of the word is set, we're + * starting a box */ + if(w & mask0) + { + if(!fInBox) + { + rx1 = base + ib; + /* start new box */ + fInBox = TRUE; + } + } + else + { + if(fInBox) + { + /* end box */ + ADDRECT(pReg, rects, FirstRect, + rx1, h, base + ib, h + 1); + fInBox = FALSE; + } + } + /* Shift the word VISUALLY left one. */ + w = FbScrLeft(w, 1); + } + } + if(width & FB_MASK) + { + /* Process final partial word on line */ + w = READ(pw++); + for(ib = 0; ib < (width & FB_MASK); ib++) + { + /* If the Screen left most bit of the word is set, we're + * starting a box */ + if(w & mask0) + { + if(!fInBox) + { + rx1 = base + ib; + /* start new box */ + fInBox = TRUE; + } + } + else + { + if(fInBox) + { + /* end box */ + ADDRECT(pReg, rects, FirstRect, + rx1, h, base + ib, h + 1); + fInBox = FALSE; + } + } + /* Shift the word VISUALLY left one. */ + w = FbScrLeft(w, 1); + } + } + /* If scanline ended with last bit set, end the box */ + if(fInBox) + { + ADDRECT(pReg, rects, FirstRect, + rx1, h, base + (width & FB_MASK), h + 1); + } + /* if all rectangles on this line have the same x-coords as + * those on the previous line, then add 1 to all the previous y2s and + * throw away all the rectangles from this line + */ + fSame = FALSE; + if(irectPrevStart != -1) + { + crects = irectLineStart - irectPrevStart; + if(crects == ((rects - FirstRect) - irectLineStart)) + { + prectO = FirstRect + irectPrevStart; + prectN = prectLineStart = FirstRect + irectLineStart; + fSame = TRUE; + while(prectO < prectLineStart) + { + if((prectO->x1 != prectN->x1) || (prectO->x2 != prectN->x2)) + { + fSame = FALSE; + break; + } + prectO++; + prectN++; + } + if (fSame) + { + prectO = FirstRect + irectPrevStart; + while(prectO < prectLineStart) + { + prectO->y2 += 1; + prectO++; + } + rects -= crects; + pReg->data->numRects -= crects; + } + } + } + if(!fSame) + irectPrevStart = irectLineStart; + } + if (!pReg->data->numRects) + pReg->extents.x1 = pReg->extents.x2 = 0; + else + { + pReg->extents.y1 = RegionBoxptr(pReg)->y1; + pReg->extents.y2 = RegionEnd(pReg)->y2; + if (pReg->data->numRects == 1) + { + free(pReg->data); + pReg->data = (RegDataPtr)NULL; + } + } + + fbFinishAccess(&pPix->drawable); +#ifdef DEBUG + if (!RegionIsValid(pReg)) + FatalError("Assertion failed file %s, line %d: expr\n", __FILE__, __LINE__); +#endif + return pReg; +} + +#ifdef FB_DEBUG + +#ifndef WIN32 +#include +#else +#include +#endif + +static Bool +fbValidateBits (FbStip *bits, int stride, FbStip data) +{ + while (stride--) + { + if (*bits != data) + { +#ifdef WIN32 + NCD_DEBUG ((DEBUG_FAILURE, "fdValidateBits failed at 0x%x (is 0x%x want 0x%x)", + bits, *bits, data)); +#else + fprintf (stderr, "fbValidateBits failed\n"); +#endif + return FALSE; + } + bits++; + } +} + +void +fbValidateDrawable (DrawablePtr pDrawable) +{ + FbStip *bits, *first, *last; + int stride, bpp; + int xoff, yoff; + int height; + Bool failed; + + if (pDrawable->type != DRAWABLE_PIXMAP) + pDrawable = (DrawablePtr) fbGetWindowPixmap(pDrawable); + fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff); + first = bits - stride; + last = bits + stride * pDrawable->height; + if (!fbValidateBits (first, stride, FB_HEAD_BITS) || + !fbValidateBits (last, stride, FB_TAIL_BITS)) + fbInitializeDrawable(pDrawable); + fbFinishAccess (pDrawable); +} + +void +fbSetBits (FbStip *bits, int stride, FbStip data) +{ + while (stride--) + *bits++ = data; +} + +void +fbInitializeDrawable (DrawablePtr pDrawable) +{ + FbStip *bits, *first, *last; + int stride, bpp; + int xoff, yoff; + + fbGetStipDrawable(pDrawable, bits, stride, bpp, xoff, yoff); + first = bits - stride; + last = bits + stride * pDrawable->height; + fbSetBits (first, stride, FB_HEAD_BITS); + fbSetBits (last, stride, FB_TAIL_BITS); + fbFinishAccess (pDrawable); +} +#endif /* FB_DEBUG */ diff --git a/xorg-server/glx/glapi.c b/xorg-server/glx/glapi.c index d6a568e88..209ae50c0 100644 --- a/xorg-server/glx/glapi.c +++ b/xorg-server/glx/glapi.c @@ -175,12 +175,6 @@ static GLint NoOpUnused(void) * static dispatch functions access these variables via \c _glapi_get_dispatch * and \c _glapi_get_context. * - * There is a race condition in setting \c _glapi_Dispatch to \c NULL. It is - * possible for the original thread to be setting it at the same instant a new - * thread, perhaps running on a different processor, is clearing it. Because - * of that, \c ThreadSafe, which can only ever be changed to \c GL_TRUE, is - * used to determine whether or not the application is multithreaded. - * * In the TLS case, the variables \c _glapi_Dispatch and \c _glapi_Context are * hardcoded to \c NULL. Instead the TLS variables \c _glapi_tls_Dispatch and * \c _glapi_tls_Context are used. Having \c _glapi_Dispatch and @@ -204,7 +198,6 @@ PUBLIC const void *_glapi_Context = NULL; #if defined(THREADS) -static GLboolean ThreadSafe = GL_FALSE; /**< In thread-safe mode? */ _glthread_TSD _gl_DispatchTSD; /**< Per-thread dispatch pointer */ static _glthread_TSD ContextTSD; /**< Per-thread context pointer */ @@ -243,37 +236,14 @@ str_dup(const char *str) } - -/** - * We should call this periodically from a function such as glXMakeCurrent - * in order to test if multiple threads are being used. +/* + * xserver's gl is not multithreaded, we promise. */ PUBLIC void _glapi_check_multithread(void) { -#if defined(THREADS) && !defined(GLX_USE_TLS) - if (!ThreadSafe) { - static unsigned long knownID; - static GLboolean firstCall = GL_TRUE; - if (firstCall) { - knownID = _glthread_GetID(); - firstCall = GL_FALSE; - } - else if (knownID != _glthread_GetID()) { - ThreadSafe = GL_TRUE; - _glapi_set_dispatch(NULL); - _glapi_set_context(NULL); - } - } - else if (!_glapi_get_dispatch()) { - /* make sure that this thread's dispatch pointer isn't null */ - _glapi_set_dispatch(NULL); - } -#endif } - - /** * Set the current context pointer for this thread. * The context pointer is an opaque type which should be cast to @@ -287,7 +257,7 @@ _glapi_set_context(void *context) _glapi_tls_Context = context; #elif defined(THREADS) _glthread_SetTSD(&ContextTSD, context); - _glapi_Context = (ThreadSafe) ? NULL : context; + _glapi_Context = context; #else _glapi_Context = context; #endif @@ -305,13 +275,6 @@ _glapi_get_context(void) { #if defined(GLX_USE_TLS) return _glapi_tls_Context; -#elif defined(THREADS) - if (ThreadSafe) { - return _glthread_GetTSD(&ContextTSD); - } - else { - return _glapi_Context; - } #else return _glapi_Context; #endif @@ -336,17 +299,12 @@ _glapi_set_dispatch(struct _glapi_table *dispatch) /* use the no-op functions */ dispatch = (struct _glapi_table *) __glapi_noop_table; } -#ifdef DEBUG - else { - _glapi_check_table(dispatch); - } -#endif #if defined(GLX_USE_TLS) _glapi_tls_Dispatch = dispatch; #elif defined(THREADS) _glthread_SetTSD(&_gl_DispatchTSD, (void *) dispatch); - _glapi_Dispatch = (ThreadSafe) ? NULL : dispatch; + _glapi_Dispatch = dispatch; #else /*THREADS*/ _glapi_Dispatch = dispatch; #endif /*THREADS*/ @@ -363,10 +321,6 @@ _glapi_get_dispatch(void) struct _glapi_table * api; #if defined(GLX_USE_TLS) api = _glapi_tls_Dispatch; -#elif defined(THREADS) - api = (ThreadSafe) - ? (struct _glapi_table *) _glthread_GetTSD(&_gl_DispatchTSD) - : _glapi_Dispatch; #else api = _glapi_Dispatch; #endif @@ -472,26 +426,6 @@ get_static_proc_address(const char *funcName) #endif /* !defined(XFree86Server) && !defined(XGLServer) */ - - -/** - * Return the name of the function at the given offset in the dispatch - * table. For debugging only. - */ -static const char * -get_static_proc_name( GLuint offset ) -{ - GLuint i; - for (i = 0; static_functions[i].Name_offset >= 0; i++) { - if (static_functions[i].Offset == offset) { - return gl_string_table + static_functions[i].Name_offset; - } - } - return NULL; -} - - - /********************************************************************** * Extension function management. */ @@ -867,26 +801,6 @@ _glapi_add_dispatch( const char * const * function_names, return offset; } - -/** - * Return offset of entrypoint for named function within dispatch table. - */ -PUBLIC GLint -_glapi_get_proc_offset(const char *funcName) -{ - /* search extension functions first */ - GLuint i; - for (i = 0; i < NumExtEntryPoints; i++) { - if (strcmp(ExtEntryTable[i].name, funcName) == 0) { - return ExtEntryTable[i].dispatch_offset; - } - } - /* search static functions */ - return get_static_proc_offset(funcName); -} - - - /** * Return pointer to the named function. If the function name isn't found * in the name of static functions, try generating a new API entrypoint on @@ -926,35 +840,6 @@ _glapi_get_proc_address(const char *funcName) return (entry == NULL) ? NULL : entry->dispatch_stub; } - - -/** - * Return the name of the function at the given dispatch offset. - * This is only intended for debugging. - */ -const char * -_glapi_get_proc_name(GLuint offset) -{ - GLuint i; - const char * n; - - /* search built-in functions */ - n = get_static_proc_name(offset); - if ( n != NULL ) { - return n; - } - - /* search added extension functions */ - for (i = 0; i < NumExtEntryPoints; i++) { - if (ExtEntryTable[i].dispatch_offset == offset) { - return ExtEntryTable[i].name; - } - } - return NULL; -} - - - /** * Return size of dispatch table struct as number of functions (or * slots). @@ -965,88 +850,6 @@ _glapi_get_dispatch_table_size(void) return DISPATCH_TABLE_SIZE; } - - -/** - * Make sure there are no NULL pointers in the given dispatch table. - * Intended for debugging purposes. - */ -void -_glapi_check_table(const struct _glapi_table *table) -{ -#ifdef DEBUG - const GLuint entries = _glapi_get_dispatch_table_size(); - const void **tab = (const void **) table; - GLuint i; - for (i = 1; i < entries; i++) { - assert(tab[i]); - } - - /* Do some spot checks to be sure that the dispatch table - * slots are assigned correctly. - */ - { - GLuint BeginOffset = _glapi_get_proc_offset("glBegin"); - char *BeginFunc = (char*) &table->Begin; - GLuint offset = (BeginFunc - (char *) table) / sizeof(void *); - assert(BeginOffset == _gloffset_Begin); - assert(BeginOffset == offset); - } - { - GLuint viewportOffset = _glapi_get_proc_offset("glViewport"); - char *viewportFunc = (char*) &table->Viewport; - GLuint offset = (viewportFunc - (char *) table) / sizeof(void *); - assert(viewportOffset == _gloffset_Viewport); - assert(viewportOffset == offset); - } - { - GLuint VertexPointerOffset = _glapi_get_proc_offset("glVertexPointer"); - char *VertexPointerFunc = (char*) &table->VertexPointer; - GLuint offset = (VertexPointerFunc - (char *) table) / sizeof(void *); - assert(VertexPointerOffset == _gloffset_VertexPointer); - assert(VertexPointerOffset == offset); - } - { - GLuint ResetMinMaxOffset = _glapi_get_proc_offset("glResetMinmax"); - char *ResetMinMaxFunc = (char*) &table->ResetMinmax; - GLuint offset = (ResetMinMaxFunc - (char *) table) / sizeof(void *); - assert(ResetMinMaxOffset == _gloffset_ResetMinmax); - assert(ResetMinMaxOffset == offset); - } - { - GLuint blendColorOffset = _glapi_get_proc_offset("glBlendColor"); - char *blendColorFunc = (char*) &table->BlendColor; - GLuint offset = (blendColorFunc - (char *) table) / sizeof(void *); - assert(blendColorOffset == _gloffset_BlendColor); - assert(blendColorOffset == offset); - } - { - GLuint secondaryColor3fOffset = _glapi_get_proc_offset("glSecondaryColor3fEXT"); - char *secondaryColor3fFunc = (char*) &table->SecondaryColor3fEXT; - GLuint offset = (secondaryColor3fFunc - (char *) table) / sizeof(void *); - assert(secondaryColor3fOffset == _gloffset_SecondaryColor3fEXT); - assert(secondaryColor3fOffset == offset); - } - { - GLuint pointParameterivOffset = _glapi_get_proc_offset("glPointParameterivNV"); - char *pointParameterivFunc = (char*) &table->PointParameterivNV; - GLuint offset = (pointParameterivFunc - (char *) table) / sizeof(void *); - assert(pointParameterivOffset == _gloffset_PointParameterivNV); - assert(pointParameterivOffset == offset); - } - { - GLuint setFenceOffset = _glapi_get_proc_offset("glSetFenceNV"); - char *setFenceFunc = (char*) &table->SetFenceNV; - GLuint offset = (setFenceFunc - (char *) table) / sizeof(void *); - assert(setFenceOffset == _gloffset_SetFenceNV); - assert(setFenceOffset == offset); - } -#else - (void) table; -#endif -} - - #if defined(PTHREADS) || defined(GLX_USE_TLS) /** * Perform platform-specific GL API entry-point fixups. diff --git a/xorg-server/glx/glapi.h b/xorg-server/glx/glapi.h index 8f2cf6621..80b53aa92 100644 --- a/xorg-server/glx/glapi.h +++ b/xorg-server/glx/glapi.h @@ -115,57 +115,35 @@ _glapi_set_warning_func(_glapi_warning_func func); extern void _glapi_check_multithread(void); - extern void _glapi_set_context(void *context); - extern void * _glapi_get_context(void); - extern void _glapi_set_dispatch(struct _glapi_table *dispatch); - extern struct _glapi_table * _glapi_get_dispatch(void); - extern int _glapi_begin_dispatch_override(struct _glapi_table *override); - extern void _glapi_end_dispatch_override(int layer); - struct _glapi_table * _glapi_get_override_dispatch(int layer); - extern GLuint _glapi_get_dispatch_table_size(void); - -extern void -_glapi_check_table(const struct _glapi_table *table); - - extern int _glapi_add_dispatch( const char * const * function_names, const char * parameter_signature ); -extern GLint -_glapi_get_proc_offset(const char *funcName); - - extern _glapi_proc _glapi_get_proc_address(const char *funcName); - -extern const char * -_glapi_get_proc_name(GLuint offset); - - #endif diff --git a/xorg-server/glx/glthread.c b/xorg-server/glx/glthread.c index 8b9f61885..5da7e433c 100644 --- a/xorg-server/glx/glthread.c +++ b/xorg-server/glx/glthread.c @@ -114,76 +114,6 @@ _glthread_SetTSD(_glthread_TSD *tsd, void *ptr) #endif /* PTHREADS */ - - -/* - * Solaris/Unix International Threads -- Use only if POSIX threads - * aren't available on your Unix platform. Solaris 2.[34] are examples - * of platforms where this is the case. Be sure to use -mt and/or - * -D_REENTRANT when compiling. - */ -#ifdef SOLARIS_THREADS -#define USE_LOCK_FOR_KEY /* undef this to try a version without - lock for the global key... */ - -_X_EXPORT unsigned long -_glthread_GetID(void) -{ - OsAbort(); /* XXX not implemented yet */ - return (unsigned long) 0; -} - - -void -_glthread_InitTSD(_glthread_TSD *tsd) -{ - if ((errno = mutex_init(&tsd->keylock, 0, NULL)) != 0 || - (errno = thr_keycreate(&(tsd->key), free)) != 0) { - perror(INIT_TSD_ERROR); - exit(-1); - } - tsd->initMagic = INIT_MAGIC; -} - - -void * -_glthread_GetTSD(_glthread_TSD *tsd) -{ - void* ret; - if (tsd->initMagic != INIT_MAGIC) { - _glthread_InitTSD(tsd); - } -#ifdef USE_LOCK_FOR_KEY - mutex_lock(&tsd->keylock); - thr_getspecific(tsd->key, &ret); - mutex_unlock(&tsd->keylock); -#else - if ((errno = thr_getspecific(tsd->key, &ret)) != 0) { - perror(GET_TSD_ERROR); - exit(-1); - } -#endif - return ret; -} - - -void -_glthread_SetTSD(_glthread_TSD *tsd, void *ptr) -{ - if (tsd->initMagic != INIT_MAGIC) { - _glthread_InitTSD(tsd); - } - if ((errno = thr_setspecific(tsd->key, ptr)) != 0) { - perror(SET_TSD_ERROR); - exit(-1); - } -} - -#undef USE_LOCK_FOR_KEY -#endif /* SOLARIS_THREADS */ - - - /* * Win32 Threads. The only available option for Windows 95/NT. * Be sure that you compile using the Multithreaded runtime, otherwise @@ -249,100 +179,8 @@ _glthread_SetTSD(_glthread_TSD *tsd, void *ptr) #endif /* WIN32_THREADS */ - - -/* - * XFree86 has its own thread wrapper, Xthreads.h - * We wrap it again for GL. - */ -#ifdef USE_XTHREADS - -_X_EXPORT unsigned long -_glthread_GetID(void) -{ - return (unsigned long) xthread_self(); -} - - -void -_glthread_InitTSD(_glthread_TSD *tsd) -{ - if (xthread_key_create(&tsd->key, NULL) != 0) { - perror(INIT_TSD_ERROR); - exit(-1); - } - tsd->initMagic = INIT_MAGIC; -} - - -void * -_glthread_GetTSD(_glthread_TSD *tsd) -{ - void *ptr; - if (tsd->initMagic != INIT_MAGIC) { - _glthread_InitTSD(tsd); - } - xthread_get_specific(tsd->key, &ptr); - return ptr; -} - - -void -_glthread_SetTSD(_glthread_TSD *tsd, void *ptr) -{ - if (tsd->initMagic != INIT_MAGIC) { - _glthread_InitTSD(tsd); - } - xthread_set_specific(tsd->key, ptr); -} - -#endif /* XTHREAD */ - - - -/* - * BeOS threads - */ -#ifdef BEOS_THREADS - -unsigned long -_glthread_GetID(void) -{ - return (unsigned long) find_thread(NULL); -} - -void -_glthread_InitTSD(_glthread_TSD *tsd) -{ - tsd->key = tls_allocate(); - tsd->initMagic = INIT_MAGIC; -} - -void * -_glthread_GetTSD(_glthread_TSD *tsd) -{ - if (tsd->initMagic != (int) INIT_MAGIC) { - _glthread_InitTSD(tsd); - } - return tls_get(tsd->key); -} - -void -_glthread_SetTSD(_glthread_TSD *tsd, void *ptr) -{ - if (tsd->initMagic != (int) INIT_MAGIC) { - _glthread_InitTSD(tsd); - } - tls_set(tsd->key, ptr); -} - -#endif /* BEOS_THREADS */ - - - #else /* THREADS */ - /* * no-op functions */ diff --git a/xorg-server/glx/glthread.h b/xorg-server/glx/glthread.h index e2765cebb..28793fcc7 100644 --- a/xorg-server/glx/glthread.h +++ b/xorg-server/glx/glthread.h @@ -68,10 +68,7 @@ #define _glapi_Dispatch _mglapi_Dispatch #endif - - -#if (defined(PTHREADS) || defined(SOLARIS_THREADS) ||\ - defined(WIN32_THREADS) || defined(USE_XTHREADS) || defined(BEOS_THREADS)) \ +#if (defined(PTHREADS) || defined(WIN32_THREADS)) \ && !defined(THREADS) # define THREADS #endif @@ -127,27 +124,6 @@ typedef pthread_mutex_t _glthread_Mutex; * Be sure to compile with -mt on the Solaris compilers, or * use -D_REENTRANT if using gcc. */ -#ifdef SOLARIS_THREADS -#include - -typedef struct { - thread_key_t key; - mutex_t keylock; - int initMagic; -} _glthread_TSD; - -typedef thread_t _glthread_Thread; - -typedef mutex_t _glthread_Mutex; - -/* XXX need to really implement mutex-related macros */ -#define _glthread_DECLARE_STATIC_MUTEX(name) static _glthread_Mutex name = 0 -#define _glthread_INIT_MUTEX(name) (void) name -#define _glthread_DESTROY_MUTEX(name) (void) name -#define _glthread_LOCK_MUTEX(name) (void) name -#define _glthread_UNLOCK_MUTEX(name) (void) name - -#endif /* SOLARIS_THREADS */ @@ -177,49 +153,6 @@ typedef CRITICAL_SECTION _glthread_Mutex; #endif /* WIN32_THREADS */ - - - -/* - * XFree86 has its own thread wrapper, Xthreads.h - * We wrap it again for GL. - */ -#ifdef USE_XTHREADS -#include - -typedef struct { - xthread_key_t key; - int initMagic; -} _glthread_TSD; - -typedef xthread_t _glthread_Thread; - -typedef xmutex_rec _glthread_Mutex; - -#ifdef XMUTEX_INITIALIZER -#define _glthread_DECLARE_STATIC_MUTEX(name) \ - static _glthread_Mutex name = XMUTEX_INITIALIZER -#else -#define _glthread_DECLARE_STATIC_MUTEX(name) \ - static _glthread_Mutex name -#endif - -#define _glthread_INIT_MUTEX(name) \ - xmutex_init(&(name)) - -#define _glthread_DESTROY_MUTEX(name) \ - xmutex_clear(&(name)) - -#define _glthread_LOCK_MUTEX(name) \ - (void) xmutex_lock(&(name)) - -#define _glthread_UNLOCK_MUTEX(name) \ - (void) xmutex_unlock(&(name)) - -#endif /* USE_XTHREADS */ - - - /* * BeOS threads. R5.x required. */ diff --git a/xorg-server/hw/dmx/dmxpixmap.c b/xorg-server/hw/dmx/dmxpixmap.c index 119dd1134..a16736419 100644 --- a/xorg-server/hw/dmx/dmxpixmap.c +++ b/xorg-server/hw/dmx/dmxpixmap.c @@ -1,251 +1,250 @@ -/* - * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation on the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* - * Authors: - * Kevin E. Martin - * - */ - -/** \file - * Provides pixmap support. */ - -#ifdef HAVE_DMX_CONFIG_H -#include -#endif - -#include "dmx.h" -#include "dmxsync.h" -#include "dmxpixmap.h" - -#include "pixmapstr.h" -#include "servermd.h" -#include "privates.h" - -/** Initialize a private area in \a pScreen for pixmap information. */ -Bool dmxInitPixmap(ScreenPtr pScreen) -{ - if (!dixRegisterPrivateKey(&dmxPixPrivateKeyRec, PRIVATE_PIXMAP, sizeof(dmxPixPrivRec))) - return FALSE; - - return TRUE; -} - -/** Create a pixmap on the back-end server. */ -void dmxBECreatePixmap(PixmapPtr pPixmap) -{ - ScreenPtr pScreen = pPixmap->drawable.pScreen; - DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; - dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); - - /* Make sure we haven't already created this pixmap. This can - * happen when the pixmap is used elsewhere (e.g., as a background - * or border for a window) and the refcnt > 1. - */ - if (pPixPriv->pixmap) - return; - - if (pPixmap->drawable.width && pPixmap->drawable.height) { - pPixPriv->pixmap = XCreatePixmap(dmxScreen->beDisplay, - dmxScreen->scrnWin, - pPixmap->drawable.width, - pPixmap->drawable.height, - pPixmap->drawable.depth); - dmxSync(dmxScreen, FALSE); - } -} - -/** Create a pixmap for \a pScreen with the specified \a width, \a - * height, and \a depth. */ -PixmapPtr dmxCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, - unsigned usage_hint) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; - PixmapPtr pPixmap; - int bpp; - dmxPixPrivPtr pPixPriv; - -#if 0 - DMX_UNWRAP(CreatePixmap, dmxScreen, pScreen); - if (pScreen->CreatePixmap) - ret = pScreen->CreatePixmap(pPixmap); -#endif - - /* Create pixmap on back-end server */ - if (depth == 24) bpp = 32; - else bpp = depth; - - pPixmap = AllocatePixmap(pScreen, 0); - if (!pPixmap) - return NullPixmap; - - pPixmap->drawable.type = DRAWABLE_PIXMAP; - pPixmap->drawable.class = 0; - pPixmap->drawable.pScreen = pScreen; - pPixmap->drawable.depth = depth; - pPixmap->drawable.bitsPerPixel = bpp; - pPixmap->drawable.id = 0; - pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; - pPixmap->drawable.x = 0; - pPixmap->drawable.y = 0; - pPixmap->drawable.width = width; - pPixmap->drawable.height = height; - pPixmap->devKind = PixmapBytePad(width, bpp); - pPixmap->refcnt = 1; - pPixmap->usage_hint = usage_hint; - - pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); - pPixPriv->pixmap = (Pixmap)0; - pPixPriv->detachedImage = NULL; - - /* Create the pixmap on the back-end server */ - if (dmxScreen->beDisplay) { - dmxBECreatePixmap(pPixmap); - } - -#if 0 - DMX_WRAP(CreatePixmap, dmxCreatePixmap, dmxScreen, pScreen); -#endif - - return pPixmap; -} - -/** Destroy the pixmap on the back-end server. */ -Bool dmxBEFreePixmap(PixmapPtr pPixmap) -{ - ScreenPtr pScreen = pPixmap->drawable.pScreen; - DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; - dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); - - if (pPixPriv->pixmap) { - XFreePixmap(dmxScreen->beDisplay, pPixPriv->pixmap); - pPixPriv->pixmap = (Pixmap)0; - return TRUE; - } - - return FALSE; -} - -/** Destroy the pixmap pointed to by \a pPixmap. */ -Bool dmxDestroyPixmap(PixmapPtr pPixmap) -{ - ScreenPtr pScreen = pPixmap->drawable.pScreen; - DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; - Bool ret = TRUE; - -#if 0 - DMX_UNWRAP(DestroyPixmap, dmxScreen, pScreen); -#endif - - if (--pPixmap->refcnt) - return TRUE; - - /* Destroy pixmap on back-end server */ - if (dmxScreen->beDisplay) { - if (dmxBEFreePixmap(pPixmap)) { - /* Also make sure that we destroy any detached image */ - dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); - if (pPixPriv->detachedImage) - XDestroyImage(pPixPriv->detachedImage); - dmxSync(dmxScreen, FALSE); - } - } - FreePixmap(pPixmap); - -#if 0 - if (pScreen->DestroyPixmap) - ret = pScreen->DestroyPixmap(pPixmap); - DMX_WRAP(DestroyPixmap, dmxDestroyPixmap, dmxScreen, pScreen); -#endif - - return ret; -} - -/** Create and return a region based on the pixmap pointed to by \a - * pPixmap. */ -RegionPtr dmxBitmapToRegion(PixmapPtr pPixmap) -{ - DMXScreenInfo *dmxScreen = &dmxScreens[pPixmap->drawable.pScreen->myNum]; - dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); - XImage *ximage; - RegionPtr pReg, pTmpReg; - int x, y; - unsigned long previousPixel, currentPixel; - BoxRec Box; - Bool overlap; - - if (!dmxScreen->beDisplay) { - pReg = RegionCreate(NullBox, 1); - return pReg; - } - - ximage = XGetImage(dmxScreen->beDisplay, pPixPriv->pixmap, 0, 0, - pPixmap->drawable.width, pPixmap->drawable.height, - 1, XYPixmap); - - pReg = RegionCreate(NullBox, 1); - pTmpReg = RegionCreate(NullBox, 1); - if(!pReg || !pTmpReg) { - XDestroyImage(ximage); - return NullRegion; - } - - for (y = 0; y < pPixmap->drawable.height; y++) { - Box.y1 = y; - Box.y2 = y + 1; - previousPixel = 0L; - for (x = 0; x < pPixmap->drawable.width; x++) { - currentPixel = XGetPixel(ximage, x, y); - if (previousPixel != currentPixel) { - if (previousPixel == 0L) { - /* left edge */ - Box.x1 = x; - } else if (currentPixel == 0L) { - /* right edge */ - Box.x2 = x; - RegionReset(pTmpReg, &Box); - RegionAppend(pReg, pTmpReg); - } - previousPixel = currentPixel; - } - } - if (previousPixel != 0L) { - /* right edge because of the end of pixmap */ - Box.x2 = pPixmap->drawable.width; - RegionReset(pTmpReg, &Box); - RegionAppend(pReg, pTmpReg); - } - } - - RegionDestroy(pTmpReg); - XDestroyImage(ximage); - - RegionValidate(pReg, &overlap); - - dmxSync(dmxScreen, FALSE); - return pReg; -} +/* + * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation on the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Authors: + * Kevin E. Martin + * + */ + +/** \file + * Provides pixmap support. */ + +#ifdef HAVE_DMX_CONFIG_H +#include +#endif + +#include "dmx.h" +#include "dmxsync.h" +#include "dmxpixmap.h" + +#include "pixmapstr.h" +#include "servermd.h" +#include "privates.h" + +/** Initialize a private area in \a pScreen for pixmap information. */ +Bool dmxInitPixmap(ScreenPtr pScreen) +{ + if (!dixRegisterPrivateKey(&dmxPixPrivateKeyRec, PRIVATE_PIXMAP, sizeof(dmxPixPrivRec))) + return FALSE; + + return TRUE; +} + +/** Create a pixmap on the back-end server. */ +void dmxBECreatePixmap(PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); + + /* Make sure we haven't already created this pixmap. This can + * happen when the pixmap is used elsewhere (e.g., as a background + * or border for a window) and the refcnt > 1. + */ + if (pPixPriv->pixmap) + return; + + if (pPixmap->drawable.width && pPixmap->drawable.height) { + pPixPriv->pixmap = XCreatePixmap(dmxScreen->beDisplay, + dmxScreen->scrnWin, + pPixmap->drawable.width, + pPixmap->drawable.height, + pPixmap->drawable.depth); + dmxSync(dmxScreen, FALSE); + } +} + +/** Create a pixmap for \a pScreen with the specified \a width, \a + * height, and \a depth. */ +PixmapPtr dmxCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, + unsigned class) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + PixmapPtr pPixmap; + int bpp; + dmxPixPrivPtr pPixPriv; + +#if 0 + DMX_UNWRAP(CreatePixmap, dmxScreen, pScreen); + if (pScreen->CreatePixmap) + ret = pScreen->CreatePixmap(pPixmap); +#endif + + /* Create pixmap on back-end server */ + if (depth == 24) bpp = 32; + else bpp = depth; + + pPixmap = AllocatePixmap(pScreen, 0); + if (!pPixmap) + return NullPixmap; + + pPixmap->drawable.type = DRAWABLE_PIXMAP; + pPixmap->drawable.class = class; + pPixmap->drawable.pScreen = pScreen; + pPixmap->drawable.depth = depth; + pPixmap->drawable.bitsPerPixel = bpp; + pPixmap->drawable.id = 0; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pPixmap->drawable.x = 0; + pPixmap->drawable.y = 0; + pPixmap->drawable.width = width; + pPixmap->drawable.height = height; + pPixmap->devKind = PixmapBytePad(width, bpp); + pPixmap->refcnt = 1; + + pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); + pPixPriv->pixmap = (Pixmap)0; + pPixPriv->detachedImage = NULL; + + /* Create the pixmap on the back-end server */ + if (dmxScreen->beDisplay) { + dmxBECreatePixmap(pPixmap); + } + +#if 0 + DMX_WRAP(CreatePixmap, dmxCreatePixmap, dmxScreen, pScreen); +#endif + + return pPixmap; +} + +/** Destroy the pixmap on the back-end server. */ +Bool dmxBEFreePixmap(PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); + + if (pPixPriv->pixmap) { + XFreePixmap(dmxScreen->beDisplay, pPixPriv->pixmap); + pPixPriv->pixmap = (Pixmap)0; + return TRUE; + } + + return FALSE; +} + +/** Destroy the pixmap pointed to by \a pPixmap. */ +Bool dmxDestroyPixmap(PixmapPtr pPixmap) +{ + ScreenPtr pScreen = pPixmap->drawable.pScreen; + DMXScreenInfo *dmxScreen = &dmxScreens[pScreen->myNum]; + Bool ret = TRUE; + +#if 0 + DMX_UNWRAP(DestroyPixmap, dmxScreen, pScreen); +#endif + + if (--pPixmap->refcnt) + return TRUE; + + /* Destroy pixmap on back-end server */ + if (dmxScreen->beDisplay) { + if (dmxBEFreePixmap(pPixmap)) { + /* Also make sure that we destroy any detached image */ + dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); + if (pPixPriv->detachedImage) + XDestroyImage(pPixPriv->detachedImage); + dmxSync(dmxScreen, FALSE); + } + } + FreePixmap(pPixmap); + +#if 0 + if (pScreen->DestroyPixmap) + ret = pScreen->DestroyPixmap(pPixmap); + DMX_WRAP(DestroyPixmap, dmxDestroyPixmap, dmxScreen, pScreen); +#endif + + return ret; +} + +/** Create and return a region based on the pixmap pointed to by \a + * pPixmap. */ +RegionPtr dmxBitmapToRegion(PixmapPtr pPixmap) +{ + DMXScreenInfo *dmxScreen = &dmxScreens[pPixmap->drawable.pScreen->myNum]; + dmxPixPrivPtr pPixPriv = DMX_GET_PIXMAP_PRIV(pPixmap); + XImage *ximage; + RegionPtr pReg, pTmpReg; + int x, y; + unsigned long previousPixel, currentPixel; + BoxRec Box; + Bool overlap; + + if (!dmxScreen->beDisplay) { + pReg = RegionCreate(NullBox, 1); + return pReg; + } + + ximage = XGetImage(dmxScreen->beDisplay, pPixPriv->pixmap, 0, 0, + pPixmap->drawable.width, pPixmap->drawable.height, + 1, XYPixmap); + + pReg = RegionCreate(NullBox, 1); + pTmpReg = RegionCreate(NullBox, 1); + if(!pReg || !pTmpReg) { + XDestroyImage(ximage); + return NullRegion; + } + + for (y = 0; y < pPixmap->drawable.height; y++) { + Box.y1 = y; + Box.y2 = y + 1; + previousPixel = 0L; + for (x = 0; x < pPixmap->drawable.width; x++) { + currentPixel = XGetPixel(ximage, x, y); + if (previousPixel != currentPixel) { + if (previousPixel == 0L) { + /* left edge */ + Box.x1 = x; + } else if (currentPixel == 0L) { + /* right edge */ + Box.x2 = x; + RegionReset(pTmpReg, &Box); + RegionAppend(pReg, pTmpReg); + } + previousPixel = currentPixel; + } + } + if (previousPixel != 0L) { + /* right edge because of the end of pixmap */ + Box.x2 = pPixmap->drawable.width; + RegionReset(pTmpReg, &Box); + RegionAppend(pReg, pTmpReg); + } + } + + RegionDestroy(pTmpReg); + XDestroyImage(ximage); + + RegionValidate(pReg, &overlap); + + dmxSync(dmxScreen, FALSE); + return pReg; +} diff --git a/xorg-server/hw/dmx/dmxpixmap.h b/xorg-server/hw/dmx/dmxpixmap.h index a41918ce4..4b4a8b275 100644 --- a/xorg-server/hw/dmx/dmxpixmap.h +++ b/xorg-server/hw/dmx/dmxpixmap.h @@ -1,64 +1,64 @@ -/* - * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation on the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial - * portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS - * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN - * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -/* - * Authors: - * Kevin E. Martin - * - */ - -/** \file - * Interface for pixmap support. \see dmxpixmap.c */ - -#ifndef DMXPIXMAP_H -#define DMXPIXMAP_H - -#include "pixmapstr.h" - -/** Pixmap private area. */ -typedef struct _dmxPixPriv { - Pixmap pixmap; - XImage *detachedImage; -} dmxPixPrivRec, *dmxPixPrivPtr; - - -extern Bool dmxInitPixmap(ScreenPtr pScreen); - -extern PixmapPtr dmxCreatePixmap(ScreenPtr pScreen, - int width, int height, int depth, - unsigned usage_hint); -extern Bool dmxDestroyPixmap(PixmapPtr pPixmap); -extern RegionPtr dmxBitmapToRegion(PixmapPtr pPixmap); - -extern void dmxBECreatePixmap(PixmapPtr pPixmap); -extern Bool dmxBEFreePixmap(PixmapPtr pPixmap); - -/** Get pixmap private pointer. */ -#define DMX_GET_PIXMAP_PRIV(_pPix) \ - (dmxPixPrivPtr)dixLookupPrivate(&(_pPix)->devPrivates, dmxPixPrivateKey) - -#endif /* DMXPIXMAP_H */ +/* + * Copyright 2001-2004 Red Hat Inc., Durham, North Carolina. + * + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation on the rights to use, copy, modify, merge, + * publish, distribute, sublicense, and/or sell copies of the Software, + * and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +/* + * Authors: + * Kevin E. Martin + * + */ + +/** \file + * Interface for pixmap support. \see dmxpixmap.c */ + +#ifndef DMXPIXMAP_H +#define DMXPIXMAP_H + +#include "pixmapstr.h" + +/** Pixmap private area. */ +typedef struct _dmxPixPriv { + Pixmap pixmap; + XImage *detachedImage; +} dmxPixPrivRec, *dmxPixPrivPtr; + + +extern Bool dmxInitPixmap(ScreenPtr pScreen); + +extern PixmapPtr dmxCreatePixmap(ScreenPtr pScreen, + int width, int height, int depth, + unsigned class); +extern Bool dmxDestroyPixmap(PixmapPtr pPixmap); +extern RegionPtr dmxBitmapToRegion(PixmapPtr pPixmap); + +extern void dmxBECreatePixmap(PixmapPtr pPixmap); +extern Bool dmxBEFreePixmap(PixmapPtr pPixmap); + +/** Get pixmap private pointer. */ +#define DMX_GET_PIXMAP_PRIV(_pPix) \ + (dmxPixPrivPtr)dixLookupPrivate(&(_pPix)->devPrivates, dmxPixPrivateKey) + +#endif /* DMXPIXMAP_H */ diff --git a/xorg-server/hw/xfree86/common/xf86Config.c b/xorg-server/hw/xfree86/common/xf86Config.c index 9602e899f..5312ca60d 100644 --- a/xorg-server/hw/xfree86/common/xf86Config.c +++ b/xorg-server/hw/xfree86/common/xf86Config.c @@ -1787,9 +1787,11 @@ configScreen(confScreenPtr screenp, XF86ConfScreenPtr conf_screen, int scrnum, XF86ConfDisplayPtr dispptr; XF86ConfAdaptorLinkPtr conf_adaptor; Bool defaultMonitor = FALSE; + XF86ConfScreenRec local_conf_screen; if (!conf_screen) { - conf_screen = xnfcalloc(1, sizeof(XF86ConfScreenRec)); + memset(&local_conf_screen, 0, sizeof(local_conf_screen)); + conf_screen = &local_conf_screen; conf_screen->scrn_identifier = "Default Screen Section"; xf86Msg(X_DEFAULT, "No screen section available. Using defaults.\n"); } diff --git a/xorg-server/hw/xfree86/common/xf86VGAarbiter.c b/xorg-server/hw/xfree86/common/xf86VGAarbiter.c index 0aa6f2cf4..c5ebb2780 100644 --- a/xorg-server/hw/xfree86/common/xf86VGAarbiter.c +++ b/xorg-server/hw/xfree86/common/xf86VGAarbiter.c @@ -1,1127 +1,1127 @@ -/* - * This code was stolen from RAC and adapted to control the legacy vga - * interface. - * - * - * Copyright (c) 2007 Paulo R. Zanoni, Tiago Vignatti - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#include "xorg-config.h" - -#include "xf86VGAarbiter.h" - -#ifdef HAVE_PCI_DEVICE_VGAARB_INIT -#include "xf86VGAarbiterPriv.h" -#include "xf86Bus.h" -#include "xf86Priv.h" -#include "pciaccess.h" - - -static GCFuncs VGAarbiterGCFuncs = { - VGAarbiterValidateGC, VGAarbiterChangeGC, VGAarbiterCopyGC, - VGAarbiterDestroyGC, VGAarbiterChangeClip, VGAarbiterDestroyClip, - VGAarbiterCopyClip -}; - -static GCOps VGAarbiterGCOps = { - VGAarbiterFillSpans, VGAarbiterSetSpans, VGAarbiterPutImage, - VGAarbiterCopyArea, VGAarbiterCopyPlane, VGAarbiterPolyPoint, - VGAarbiterPolylines, VGAarbiterPolySegment, VGAarbiterPolyRectangle, - VGAarbiterPolyArc, VGAarbiterFillPolygon, VGAarbiterPolyFillRect, - VGAarbiterPolyFillArc, VGAarbiterPolyText8, VGAarbiterPolyText16, - VGAarbiterImageText8, VGAarbiterImageText16, VGAarbiterImageGlyphBlt, - VGAarbiterPolyGlyphBlt, VGAarbiterPushPixels, -}; - -static miPointerSpriteFuncRec VGAarbiterSpriteFuncs = { - VGAarbiterSpriteRealizeCursor, VGAarbiterSpriteUnrealizeCursor, - VGAarbiterSpriteSetCursor, VGAarbiterSpriteMoveCursor, - VGAarbiterDeviceCursorInitialize, VGAarbiterDeviceCursorCleanup -}; - -static DevPrivateKeyRec VGAarbiterScreenKeyRec; -#define VGAarbiterScreenKey (&VGAarbiterScreenKeyRec) -static DevPrivateKeyRec VGAarbiterGCKeyRec; -#define VGAarbiterGCKey (&VGAarbiterGCKeyRec) - -static int vga_no_arb = 0; -void -xf86VGAarbiterInit(void) -{ - if (pci_device_vgaarb_init() != 0) { - vga_no_arb = 1; - xf86Msg(X_WARNING, "VGA arbiter: cannot open kernel arbiter, no multi-card support\n"); - } -} - -void -xf86VGAarbiterFini(void) -{ - if (vga_no_arb) - return; - pci_device_vgaarb_fini(); -} - -void -xf86VGAarbiterLock(ScrnInfoPtr pScrn) -{ - if (vga_no_arb) - return; - pci_device_vgaarb_set_target(pScrn->vgaDev); - pci_device_vgaarb_lock(); -} - -void -xf86VGAarbiterUnlock(ScrnInfoPtr pScrn) -{ - if (vga_no_arb) - return; - pci_device_vgaarb_unlock(); -} - -Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen) -{ - int vga_count; - int rsrc_decodes; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - - if (vga_no_arb) - return TRUE; - - pci_device_vgaarb_get_info(pScrn->vgaDev, &vga_count, &rsrc_decodes); - if (vga_count > 1) { - if (rsrc_decodes) { - return FALSE; - } - } - return TRUE; -} - -void -xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn) -{ - struct pci_device *dev; - EntityPtr pEnt; - - if (vga_no_arb) - return; - - pEnt = xf86Entities[pScrn->entityList[0]]; - if (pEnt->bus.type != BUS_PCI) - return; - - dev = pEnt->bus.id.pci; - pScrn->vgaDev = dev; -} - -void -xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn, int rsrc) -{ - if (vga_no_arb) - return; - pci_device_vgaarb_set_target(pScrn->vgaDev); - pci_device_vgaarb_decodes(rsrc); -} - -Bool -xf86VGAarbiterWrapFunctions(void) -{ - ScrnInfoPtr pScrn; - VGAarbiterScreenPtr pScreenPriv; - miPointerScreenPtr PointPriv; - PictureScreenPtr ps; - ScreenPtr pScreen; - int vga_count, i; - - if (vga_no_arb) - return FALSE; - - /* - * we need to wrap the arbiter if we have more than - * one VGA card - hotplug cries. - */ - pci_device_vgaarb_get_info(NULL, &vga_count, NULL); - if (vga_count < 2 || !xf86Screens) - return FALSE; - - xf86Msg(X_INFO,"Found %d VGA devices: arbiter wrapping enabled\n", - vga_count); - - for (i = 0; i < xf86NumScreens; i++) { - pScreen = xf86Screens[i]->pScreen; - ps = GetPictureScreenIfSet(pScreen); - pScrn = xf86Screens[pScreen->myNum]; - PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); - - if (!dixRegisterPrivateKey(&VGAarbiterGCKeyRec, PRIVATE_GC, sizeof(VGAarbiterGCRec))) - return FALSE; - - if (!dixRegisterPrivateKey(&VGAarbiterScreenKeyRec, PRIVATE_SCREEN, 0)) - return FALSE; - - if (!(pScreenPriv = malloc(sizeof(VGAarbiterScreenRec)))) - return FALSE; - - dixSetPrivate(&pScreen->devPrivates, VGAarbiterScreenKey, pScreenPriv); - - WRAP_SCREEN(CloseScreen, VGAarbiterCloseScreen); - WRAP_SCREEN(SaveScreen, VGAarbiterSaveScreen); - WRAP_SCREEN(WakeupHandler, VGAarbiterWakeupHandler); - WRAP_SCREEN(BlockHandler, VGAarbiterBlockHandler); - WRAP_SCREEN(CreateGC, VGAarbiterCreateGC); - WRAP_SCREEN(GetImage, VGAarbiterGetImage); - WRAP_SCREEN(GetSpans, VGAarbiterGetSpans); - WRAP_SCREEN(SourceValidate, VGAarbiterSourceValidate); - WRAP_SCREEN(CopyWindow, VGAarbiterCopyWindow); - WRAP_SCREEN(ClearToBackground, VGAarbiterClearToBackground); - WRAP_SCREEN(CreatePixmap, VGAarbiterCreatePixmap); - WRAP_SCREEN(StoreColors, VGAarbiterStoreColors); - WRAP_SCREEN(DisplayCursor, VGAarbiterDisplayCursor); - WRAP_SCREEN(RealizeCursor, VGAarbiterRealizeCursor); - WRAP_SCREEN(UnrealizeCursor, VGAarbiterUnrealizeCursor); - WRAP_SCREEN(RecolorCursor, VGAarbiterRecolorCursor); - WRAP_SCREEN(SetCursorPosition, VGAarbiterSetCursorPosition); - WRAP_PICT(Composite,VGAarbiterComposite); - WRAP_PICT(Glyphs,VGAarbiterGlyphs); - WRAP_PICT(CompositeRects,VGAarbiterCompositeRects); - WRAP_SCREEN_INFO(AdjustFrame, VGAarbiterAdjustFrame); - WRAP_SCREEN_INFO(SwitchMode, VGAarbiterSwitchMode); - WRAP_SCREEN_INFO(EnterVT, VGAarbiterEnterVT); - WRAP_SCREEN_INFO(LeaveVT, VGAarbiterLeaveVT); - WRAP_SCREEN_INFO(FreeScreen, VGAarbiterFreeScreen); - WRAP_SPRITE; - } - - return TRUE; -} - -/* Screen funcs */ -static Bool -VGAarbiterCloseScreen (int i, ScreenPtr pScreen) -{ - Bool val; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate( - &pScreen->devPrivates, VGAarbiterScreenKey); - miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate( - &pScreen->devPrivates, miPointerScreenKey); - PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); - - UNWRAP_SCREEN(CreateGC); - UNWRAP_SCREEN(CloseScreen); - UNWRAP_SCREEN(GetImage); - UNWRAP_SCREEN(GetSpans); - UNWRAP_SCREEN(SourceValidate); - UNWRAP_SCREEN(CopyWindow); - UNWRAP_SCREEN(ClearToBackground); - UNWRAP_SCREEN(SaveScreen); - UNWRAP_SCREEN(StoreColors); - UNWRAP_SCREEN(DisplayCursor); - UNWRAP_SCREEN(RealizeCursor); - UNWRAP_SCREEN(UnrealizeCursor); - UNWRAP_SCREEN(RecolorCursor); - UNWRAP_SCREEN(SetCursorPosition); - UNWRAP_PICT(Composite); - UNWRAP_PICT(Glyphs); - UNWRAP_PICT(CompositeRects); - UNWRAP_SCREEN_INFO(AdjustFrame); - UNWRAP_SCREEN_INFO(SwitchMode); - UNWRAP_SCREEN_INFO(EnterVT); - UNWRAP_SCREEN_INFO(LeaveVT); - UNWRAP_SCREEN_INFO(FreeScreen); - UNWRAP_SPRITE; - - free((pointer) pScreenPriv); - xf86VGAarbiterLock(xf86Screens[i]); - val = (*pScreen->CloseScreen) (i, pScreen); - xf86VGAarbiterUnlock(xf86Screens[i]); - return val; -} - -static void -VGAarbiterBlockHandler(int i, - pointer blockData, pointer pTimeout, pointer pReadmask) -{ - ScreenPtr pScreen = screenInfo.screens[i]; - SCREEN_PROLOG(BlockHandler); - VGAGet(pScreen); - pScreen->BlockHandler(i, blockData, pTimeout, pReadmask); - VGAPut(); - SCREEN_EPILOG(BlockHandler, VGAarbiterBlockHandler); -} - -static void -VGAarbiterWakeupHandler(int i, pointer blockData, unsigned long result, pointer pReadmask) -{ - ScreenPtr pScreen = screenInfo.screens[i]; - SCREEN_PROLOG(WakeupHandler); - VGAGet(pScreen); - pScreen->WakeupHandler(i, blockData, result, pReadmask); - VGAPut(); - SCREEN_EPILOG(WakeupHandler, VGAarbiterWakeupHandler); -} - -static void -VGAarbiterGetImage ( - DrawablePtr pDrawable, - int sx, int sy, int w, int h, - unsigned int format, - unsigned long planemask, - char *pdstLine - ) -{ - ScreenPtr pScreen = pDrawable->pScreen; - SCREEN_PROLOG(GetImage); -// if (xf86Screens[pScreen->myNum]->vtSema) { - VGAGet(pScreen); -// } - (*pScreen->GetImage) (pDrawable, sx, sy, w, h, - format, planemask, pdstLine); - VGAPut(); - SCREEN_EPILOG (GetImage, VGAarbiterGetImage); -} - -static void -VGAarbiterGetSpans ( - DrawablePtr pDrawable, - int wMax, - DDXPointPtr ppt, - int *pwidth, - int nspans, - char *pdstStart - ) -{ - ScreenPtr pScreen = pDrawable->pScreen; - - SCREEN_PROLOG (GetSpans); - VGAGet(pScreen); - (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); - VGAPut(); - SCREEN_EPILOG (GetSpans, VGAarbiterGetSpans); -} - -static void -VGAarbiterSourceValidate ( - DrawablePtr pDrawable, - int x, int y, int width, int height, - unsigned int subWindowMode ) -{ - ScreenPtr pScreen = pDrawable->pScreen; - SCREEN_PROLOG (SourceValidate); - VGAGet(pScreen); - if (pScreen->SourceValidate) - (*pScreen->SourceValidate) (pDrawable, x, y, width, height, subWindowMode); - VGAPut(); - SCREEN_EPILOG (SourceValidate, VGAarbiterSourceValidate); -} - -static void -VGAarbiterCopyWindow( - WindowPtr pWin, - DDXPointRec ptOldOrg, - RegionPtr prgnSrc ) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - - SCREEN_PROLOG (CopyWindow); - VGAGet(pScreen); - (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc); - VGAPut(); - SCREEN_EPILOG (CopyWindow, VGAarbiterCopyWindow); -} - -static void -VGAarbiterClearToBackground ( - WindowPtr pWin, - int x, int y, - int w, int h, - Bool generateExposures ) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - - SCREEN_PROLOG ( ClearToBackground); - VGAGet(pScreen); - (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures); - VGAPut(); - SCREEN_EPILOG (ClearToBackground, VGAarbiterClearToBackground); -} - -static PixmapPtr -VGAarbiterCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint) -{ - PixmapPtr pPix; - - SCREEN_PROLOG ( CreatePixmap); - VGAGet(pScreen); - pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, usage_hint); - VGAPut(); - SCREEN_EPILOG (CreatePixmap, VGAarbiterCreatePixmap); - - return pPix; -} - -static Bool -VGAarbiterSaveScreen(ScreenPtr pScreen, Bool unblank) -{ - Bool val; - - SCREEN_PROLOG (SaveScreen); - VGAGet(pScreen); - val = (*pScreen->SaveScreen) (pScreen, unblank); - VGAPut(); - SCREEN_EPILOG (SaveScreen, VGAarbiterSaveScreen); - - return val; -} - -static void -VGAarbiterStoreColors ( - ColormapPtr pmap, - int ndef, - xColorItem *pdefs) -{ - ScreenPtr pScreen = pmap->pScreen; - - SCREEN_PROLOG (StoreColors); - VGAGet(pScreen); - (*pScreen->StoreColors) (pmap,ndef,pdefs); - VGAPut(); - SCREEN_EPILOG ( StoreColors, VGAarbiterStoreColors); -} - -static void -VGAarbiterRecolorCursor ( - DeviceIntPtr pDev, - ScreenPtr pScreen, - CursorPtr pCurs, - Bool displayed - ) -{ - SCREEN_PROLOG (RecolorCursor); - VGAGet(pScreen); - (*pScreen->RecolorCursor) (pDev, pScreen, pCurs, displayed); - VGAPut(); - SCREEN_EPILOG ( RecolorCursor, VGAarbiterRecolorCursor); -} - -static Bool -VGAarbiterRealizeCursor ( - DeviceIntPtr pDev, - ScreenPtr pScreen, - CursorPtr pCursor - ) -{ - Bool val; - - SCREEN_PROLOG (RealizeCursor); - VGAGet(pScreen); - val = (*pScreen->RealizeCursor) (pDev, pScreen,pCursor); - VGAPut(); - SCREEN_EPILOG ( RealizeCursor, VGAarbiterRealizeCursor); - return val; -} - -static Bool -VGAarbiterUnrealizeCursor ( - DeviceIntPtr pDev, - ScreenPtr pScreen, - CursorPtr pCursor - ) -{ - Bool val; - - SCREEN_PROLOG (UnrealizeCursor); - VGAGet(pScreen); - val = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor); - VGAPut(); - SCREEN_EPILOG ( UnrealizeCursor, VGAarbiterUnrealizeCursor); - return val; -} - -static Bool -VGAarbiterDisplayCursor ( - DeviceIntPtr pDev, - ScreenPtr pScreen, - CursorPtr pCursor - ) -{ - Bool val; - - SCREEN_PROLOG (DisplayCursor); - VGAGet(pScreen); - val = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor); - VGAPut(); - SCREEN_EPILOG ( DisplayCursor, VGAarbiterDisplayCursor); - return val; -} - -static Bool -VGAarbiterSetCursorPosition ( - DeviceIntPtr pDev, - ScreenPtr pScreen, - int x, int y, - Bool generateEvent) -{ - Bool val; - - SCREEN_PROLOG (SetCursorPosition); - VGAGet(pScreen); - val = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent); - VGAPut(); - SCREEN_EPILOG ( SetCursorPosition, VGAarbiterSetCursorPosition); - return val; -} - -static void -VGAarbiterAdjustFrame(int index, int x, int y, int flags) -{ - ScreenPtr pScreen = screenInfo.screens[index]; - VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate( - &pScreen->devPrivates, VGAarbiterScreenKey); - - VGAGet(pScreen); - (*pScreenPriv->AdjustFrame)(index, x, y, flags); - VGAPut(); -} - -static Bool -VGAarbiterSwitchMode(int index, DisplayModePtr mode, int flags) -{ - Bool val; - ScreenPtr pScreen = screenInfo.screens[index]; - VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate( - &pScreen->devPrivates, VGAarbiterScreenKey); - - VGAGet(pScreen); - val = (*pScreenPriv->SwitchMode)(index, mode, flags); - VGAPut(); - return val; -} - -static Bool -VGAarbiterEnterVT(int index, int flags) -{ - Bool val; - ScrnInfoPtr pScrn = xf86Screens[index]; - ScreenPtr pScreen = screenInfo.screens[index]; - VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate( - &pScreen->devPrivates, VGAarbiterScreenKey); - - VGAGet(pScreen); - pScrn->EnterVT = pScreenPriv->EnterVT; - val = (*pScrn->EnterVT)(index, flags); - pScreenPriv->EnterVT = pScrn->EnterVT; - pScrn->EnterVT = VGAarbiterEnterVT; - VGAPut(); - return val; -} - -static void -VGAarbiterLeaveVT(int index, int flags) -{ - ScrnInfoPtr pScrn = xf86Screens[index]; - ScreenPtr pScreen = screenInfo.screens[index]; - VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate( - &pScreen->devPrivates, VGAarbiterScreenKey); - - VGAGet(pScreen); - pScrn->LeaveVT = pScreenPriv->LeaveVT; - (*pScreenPriv->LeaveVT)(index, flags); - pScreenPriv->LeaveVT = pScrn->LeaveVT; - pScrn->LeaveVT = VGAarbiterLeaveVT; - VGAPut(); -} - -static void -VGAarbiterFreeScreen(int index, int flags) -{ - ScreenPtr pScreen = screenInfo.screens[index]; - VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate( - &pScreen->devPrivates, VGAarbiterScreenKey); - - VGAGet(pScreen); - (*pScreenPriv->FreeScreen)(index, flags); - VGAPut(); -} - -static Bool -VGAarbiterCreateGC(GCPtr pGC) -{ - ScreenPtr pScreen = pGC->pScreen; - VGAarbiterGCPtr pGCPriv = (VGAarbiterGCPtr)dixLookupPrivate(&pGC->devPrivates, VGAarbiterGCKey); - Bool ret; - - SCREEN_PROLOG(CreateGC); - ret = (*pScreen->CreateGC)(pGC); - GC_WRAP(pGC); - SCREEN_EPILOG(CreateGC,VGAarbiterCreateGC); - - return ret; -} - -/* GC funcs */ -static void -VGAarbiterValidateGC( - GCPtr pGC, - unsigned long changes, - DrawablePtr pDraw ) -{ - GC_UNWRAP(pGC); - (*pGC->funcs->ValidateGC)(pGC, changes, pDraw); - GC_WRAP(pGC); -} - - -static void -VGAarbiterDestroyGC(GCPtr pGC) -{ - GC_UNWRAP (pGC); - (*pGC->funcs->DestroyGC)(pGC); - GC_WRAP (pGC); -} - -static void -VGAarbiterChangeGC ( - GCPtr pGC, - unsigned long mask) -{ - GC_UNWRAP (pGC); - (*pGC->funcs->ChangeGC) (pGC, mask); - GC_WRAP (pGC); -} - -static void -VGAarbiterCopyGC ( - GCPtr pGCSrc, - unsigned long mask, - GCPtr pGCDst) -{ - GC_UNWRAP (pGCDst); - (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); - GC_WRAP (pGCDst); -} - -static void -VGAarbiterChangeClip ( - GCPtr pGC, - int type, - pointer pvalue, - int nrects ) -{ - GC_UNWRAP (pGC); - (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); - GC_WRAP (pGC); -} - -static void -VGAarbiterCopyClip(GCPtr pgcDst, GCPtr pgcSrc) -{ - GC_UNWRAP (pgcDst); - (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); - GC_WRAP (pgcDst); -} - -static void -VGAarbiterDestroyClip(GCPtr pGC) -{ - GC_UNWRAP (pGC); - (* pGC->funcs->DestroyClip)(pGC); - GC_WRAP (pGC); -} - -/* GC Ops */ -static void -VGAarbiterFillSpans( - DrawablePtr pDraw, - GC *pGC, - int nInit, - DDXPointPtr pptInit, - int *pwidthInit, - int fSorted ) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted); - VGAPut(); - GC_WRAP(pGC); -} - -static void -VGAarbiterSetSpans( - DrawablePtr pDraw, - GCPtr pGC, - char *pcharsrc, - register DDXPointPtr ppt, - int *pwidth, - int nspans, - int fSorted ) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted); - VGAPut(); - GC_WRAP(pGC); -} - -static void -VGAarbiterPutImage( - DrawablePtr pDraw, - GCPtr pGC, - int depth, - int x, int y, int w, int h, - int leftPad, - int format, - char *pImage ) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h, - leftPad, format, pImage); - VGAPut(); - GC_WRAP(pGC); -} - -static RegionPtr -VGAarbiterCopyArea( - DrawablePtr pSrc, - DrawablePtr pDst, - GC *pGC, - int srcx, int srcy, - int width, int height, - int dstx, int dsty ) -{ - RegionPtr ret; - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - ret = (*pGC->ops->CopyArea)(pSrc, pDst, - pGC, srcx, srcy, width, height, dstx, dsty); - VGAPut(); - GC_WRAP(pGC); - return ret; -} - -static RegionPtr -VGAarbiterCopyPlane( - DrawablePtr pSrc, - DrawablePtr pDst, - GCPtr pGC, - int srcx, int srcy, - int width, int height, - int dstx, int dsty, - unsigned long bitPlane ) -{ - RegionPtr ret; - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - ret = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC, srcx, srcy, - width, height, dstx, dsty, bitPlane); - VGAPut(); - GC_WRAP(pGC); - return ret; -} - -static void -VGAarbiterPolyPoint( - DrawablePtr pDraw, - GCPtr pGC, - int mode, - int npt, - xPoint *pptInit ) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit); - VGAPut(); - GC_WRAP(pGC); -} - - -static void -VGAarbiterPolylines( - DrawablePtr pDraw, - GCPtr pGC, - int mode, - int npt, - DDXPointPtr pptInit ) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit); - VGAPut(); - GC_WRAP(pGC); -} - -static void -VGAarbiterPolySegment( - DrawablePtr pDraw, - GCPtr pGC, - int nseg, - xSegment *pSeg ) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg); - VGAPut(); - GC_WRAP(pGC); -} - -static void -VGAarbiterPolyRectangle( - DrawablePtr pDraw, - GCPtr pGC, - int nRectsInit, - xRectangle *pRectsInit ) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit); - VGAPut(); - GC_WRAP(pGC); -} - -static void -VGAarbiterPolyArc( - DrawablePtr pDraw, - GCPtr pGC, - int narcs, - xArc *parcs ) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs); - VGAPut(); - GC_WRAP(pGC); -} - -static void -VGAarbiterFillPolygon( - DrawablePtr pDraw, - GCPtr pGC, - int shape, - int mode, - int count, - DDXPointPtr ptsIn ) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn); - VGAPut(); - GC_WRAP(pGC); -} - -static void -VGAarbiterPolyFillRect( - DrawablePtr pDraw, - GCPtr pGC, - int nrectFill, - xRectangle *prectInit) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit); - VGAPut(); - GC_WRAP(pGC); -} - -static void -VGAarbiterPolyFillArc( - DrawablePtr pDraw, - GCPtr pGC, - int narcs, - xArc *parcs ) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs); - VGAPut(); - GC_WRAP(pGC); -} - -static int -VGAarbiterPolyText8( - DrawablePtr pDraw, - GCPtr pGC, - int x, - int y, - int count, - char *chars ) -{ - int ret; - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars); - VGAPut(); - GC_WRAP(pGC); - return ret; -} - -static int -VGAarbiterPolyText16( - DrawablePtr pDraw, - GCPtr pGC, - int x, - int y, - int count, - unsigned short *chars ) -{ - int ret; - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars); - VGAPut(); - GC_WRAP(pGC); - return ret; -} - -static void -VGAarbiterImageText8( - DrawablePtr pDraw, - GCPtr pGC, - int x, - int y, - int count, - char *chars ) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars); - VGAPut(); - GC_WRAP(pGC); -} - -static void -VGAarbiterImageText16( - DrawablePtr pDraw, - GCPtr pGC, - int x, - int y, - int count, - unsigned short *chars ) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars); - VGAPut(); - GC_WRAP(pGC); -} - - -static void -VGAarbiterImageGlyphBlt( - DrawablePtr pDraw, - GCPtr pGC, - int xInit, int yInit, - unsigned int nglyph, - CharInfoPtr *ppci, - pointer pglyphBase ) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit, - nglyph, ppci, pglyphBase); - VGAPut(); - GC_WRAP(pGC); -} - -static void -VGAarbiterPolyGlyphBlt( - DrawablePtr pDraw, - GCPtr pGC, - int xInit, int yInit, - unsigned int nglyph, - CharInfoPtr *ppci, - pointer pglyphBase ) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit, - nglyph, ppci, pglyphBase); - VGAPut(); - GC_WRAP(pGC); -} - -static void -VGAarbiterPushPixels( - GCPtr pGC, - PixmapPtr pBitMap, - DrawablePtr pDraw, - int dx, int dy, int xOrg, int yOrg ) -{ - ScreenPtr pScreen = pGC->pScreen; - GC_UNWRAP(pGC); - VGAGet(pScreen); - (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg); - VGAPut(); - GC_WRAP(pGC); -} - - -/* miSpriteFuncs */ -static Bool -VGAarbiterSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur) -{ - Bool val; - SPRITE_PROLOG; - VGAGet(pScreen); - val = PointPriv->spriteFuncs->RealizeCursor(pDev, pScreen, pCur); - VGAPut(); - SPRITE_EPILOG; - return val; -} - -static Bool -VGAarbiterSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur) -{ - Bool val; - SPRITE_PROLOG; - VGAGet(pScreen); - val = PointPriv->spriteFuncs->UnrealizeCursor(pDev, pScreen, pCur); - VGAPut(); - SPRITE_EPILOG; - return val; -} - -static void -VGAarbiterSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur, int x, int y) -{ - SPRITE_PROLOG; - VGAGet(pScreen); - PointPriv->spriteFuncs->SetCursor(pDev, pScreen, pCur, x, y); - VGAPut(); - SPRITE_EPILOG; -} - -static void -VGAarbiterSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) -{ - SPRITE_PROLOG; - VGAGet(pScreen); - PointPriv->spriteFuncs->MoveCursor(pDev, pScreen, x, y); - VGAPut(); - SPRITE_EPILOG; -} - -static Bool -VGAarbiterDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) -{ - Bool val; - SPRITE_PROLOG; - VGAGet(pScreen); - val = PointPriv->spriteFuncs->DeviceCursorInitialize(pDev, pScreen); - VGAPut(); - SPRITE_EPILOG; - return val; -} - -static void -VGAarbiterDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) -{ - SPRITE_PROLOG; - VGAGet(pScreen); - PointPriv->spriteFuncs->DeviceCursorCleanup(pDev, pScreen); - VGAPut(); - SPRITE_EPILOG; -} - -static void -VGAarbiterComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, - PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, - INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, - CARD16 height) -{ - ScreenPtr pScreen = pDst->pDrawable->pScreen; - PictureScreenPtr ps = GetPictureScreen(pScreen); - - PICTURE_PROLOGUE(Composite); - - VGAGet(pScreen); - (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, - yDst, width, height); - VGAPut(); - PICTURE_EPILOGUE(Composite, VGAarbiterComposite); -} - -static void -VGAarbiterGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, - GlyphListPtr list, GlyphPtr *glyphs) -{ - ScreenPtr pScreen = pDst->pDrawable->pScreen; - PictureScreenPtr ps = GetPictureScreen(pScreen); - - PICTURE_PROLOGUE(Glyphs); - - VGAGet(pScreen); - (*ps->Glyphs)(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); - VGAPut(); - PICTURE_EPILOGUE (Glyphs, VGAarbiterGlyphs); -} - -static void -VGAarbiterCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor *color, int nRect, - xRectangle *rects) -{ - ScreenPtr pScreen = pDst->pDrawable->pScreen; - PictureScreenPtr ps = GetPictureScreen(pScreen); - - PICTURE_PROLOGUE(CompositeRects); - - VGAGet(pScreen); - (*ps->CompositeRects)(op, pDst, color, nRect, rects); - VGAPut(); - PICTURE_EPILOGUE (CompositeRects, VGAarbiterCompositeRects); -} -#else -/* dummy functions */ -void xf86VGAarbiterInit(void) {} -void xf86VGAarbiterFini(void) {} - -void xf86VGAarbiterLock(ScrnInfoPtr pScrn) {} -void xf86VGAarbiterUnlock(ScrnInfoPtr pScrn) {} -Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen) { return TRUE; } -void xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn) {} -void xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn, int rsrc) {} -Bool xf86VGAarbiterWrapFunctions(void) { return FALSE; } - -#endif +/* + * This code was stolen from RAC and adapted to control the legacy vga + * interface. + * + * + * Copyright (c) 2007 Paulo R. Zanoni, Tiago Vignatti + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#include "xorg-config.h" + +#include "xf86VGAarbiter.h" + +#ifdef HAVE_PCI_DEVICE_VGAARB_INIT +#include "xf86VGAarbiterPriv.h" +#include "xf86Bus.h" +#include "xf86Priv.h" +#include "pciaccess.h" + + +static GCFuncs VGAarbiterGCFuncs = { + VGAarbiterValidateGC, VGAarbiterChangeGC, VGAarbiterCopyGC, + VGAarbiterDestroyGC, VGAarbiterChangeClip, VGAarbiterDestroyClip, + VGAarbiterCopyClip +}; + +static GCOps VGAarbiterGCOps = { + VGAarbiterFillSpans, VGAarbiterSetSpans, VGAarbiterPutImage, + VGAarbiterCopyArea, VGAarbiterCopyPlane, VGAarbiterPolyPoint, + VGAarbiterPolylines, VGAarbiterPolySegment, VGAarbiterPolyRectangle, + VGAarbiterPolyArc, VGAarbiterFillPolygon, VGAarbiterPolyFillRect, + VGAarbiterPolyFillArc, VGAarbiterPolyText8, VGAarbiterPolyText16, + VGAarbiterImageText8, VGAarbiterImageText16, VGAarbiterImageGlyphBlt, + VGAarbiterPolyGlyphBlt, VGAarbiterPushPixels, +}; + +static miPointerSpriteFuncRec VGAarbiterSpriteFuncs = { + VGAarbiterSpriteRealizeCursor, VGAarbiterSpriteUnrealizeCursor, + VGAarbiterSpriteSetCursor, VGAarbiterSpriteMoveCursor, + VGAarbiterDeviceCursorInitialize, VGAarbiterDeviceCursorCleanup +}; + +static DevPrivateKeyRec VGAarbiterScreenKeyRec; +#define VGAarbiterScreenKey (&VGAarbiterScreenKeyRec) +static DevPrivateKeyRec VGAarbiterGCKeyRec; +#define VGAarbiterGCKey (&VGAarbiterGCKeyRec) + +static int vga_no_arb = 0; +void +xf86VGAarbiterInit(void) +{ + if (pci_device_vgaarb_init() != 0) { + vga_no_arb = 1; + xf86Msg(X_WARNING, "VGA arbiter: cannot open kernel arbiter, no multi-card support\n"); + } +} + +void +xf86VGAarbiterFini(void) +{ + if (vga_no_arb) + return; + pci_device_vgaarb_fini(); +} + +void +xf86VGAarbiterLock(ScrnInfoPtr pScrn) +{ + if (vga_no_arb) + return; + pci_device_vgaarb_set_target(pScrn->vgaDev); + pci_device_vgaarb_lock(); +} + +void +xf86VGAarbiterUnlock(ScrnInfoPtr pScrn) +{ + if (vga_no_arb) + return; + pci_device_vgaarb_unlock(); +} + +Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen) +{ + int vga_count; + int rsrc_decodes; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + + if (vga_no_arb) + return TRUE; + + pci_device_vgaarb_get_info(pScrn->vgaDev, &vga_count, &rsrc_decodes); + if (vga_count > 1) { + if (rsrc_decodes) { + return FALSE; + } + } + return TRUE; +} + +void +xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn) +{ + struct pci_device *dev; + EntityPtr pEnt; + + if (vga_no_arb) + return; + + pEnt = xf86Entities[pScrn->entityList[0]]; + if (pEnt->bus.type != BUS_PCI) + return; + + dev = pEnt->bus.id.pci; + pScrn->vgaDev = dev; +} + +void +xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn, int rsrc) +{ + if (vga_no_arb) + return; + pci_device_vgaarb_set_target(pScrn->vgaDev); + pci_device_vgaarb_decodes(rsrc); +} + +Bool +xf86VGAarbiterWrapFunctions(void) +{ + ScrnInfoPtr pScrn; + VGAarbiterScreenPtr pScreenPriv; + miPointerScreenPtr PointPriv; + PictureScreenPtr ps; + ScreenPtr pScreen; + int vga_count, i; + + if (vga_no_arb) + return FALSE; + + /* + * we need to wrap the arbiter if we have more than + * one VGA card - hotplug cries. + */ + pci_device_vgaarb_get_info(NULL, &vga_count, NULL); + if (vga_count < 2 || !xf86Screens) + return FALSE; + + xf86Msg(X_INFO,"Found %d VGA devices: arbiter wrapping enabled\n", + vga_count); + + for (i = 0; i < xf86NumScreens; i++) { + pScreen = xf86Screens[i]->pScreen; + ps = GetPictureScreenIfSet(pScreen); + pScrn = xf86Screens[pScreen->myNum]; + PointPriv = dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); + + if (!dixRegisterPrivateKey(&VGAarbiterGCKeyRec, PRIVATE_GC, sizeof(VGAarbiterGCRec))) + return FALSE; + + if (!dixRegisterPrivateKey(&VGAarbiterScreenKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + + if (!(pScreenPriv = malloc(sizeof(VGAarbiterScreenRec)))) + return FALSE; + + dixSetPrivate(&pScreen->devPrivates, VGAarbiterScreenKey, pScreenPriv); + + WRAP_SCREEN(CloseScreen, VGAarbiterCloseScreen); + WRAP_SCREEN(SaveScreen, VGAarbiterSaveScreen); + WRAP_SCREEN(WakeupHandler, VGAarbiterWakeupHandler); + WRAP_SCREEN(BlockHandler, VGAarbiterBlockHandler); + WRAP_SCREEN(CreateGC, VGAarbiterCreateGC); + WRAP_SCREEN(GetImage, VGAarbiterGetImage); + WRAP_SCREEN(GetSpans, VGAarbiterGetSpans); + WRAP_SCREEN(SourceValidate, VGAarbiterSourceValidate); + WRAP_SCREEN(CopyWindow, VGAarbiterCopyWindow); + WRAP_SCREEN(ClearToBackground, VGAarbiterClearToBackground); + WRAP_SCREEN(CreatePixmap, VGAarbiterCreatePixmap); + WRAP_SCREEN(StoreColors, VGAarbiterStoreColors); + WRAP_SCREEN(DisplayCursor, VGAarbiterDisplayCursor); + WRAP_SCREEN(RealizeCursor, VGAarbiterRealizeCursor); + WRAP_SCREEN(UnrealizeCursor, VGAarbiterUnrealizeCursor); + WRAP_SCREEN(RecolorCursor, VGAarbiterRecolorCursor); + WRAP_SCREEN(SetCursorPosition, VGAarbiterSetCursorPosition); + WRAP_PICT(Composite,VGAarbiterComposite); + WRAP_PICT(Glyphs,VGAarbiterGlyphs); + WRAP_PICT(CompositeRects,VGAarbiterCompositeRects); + WRAP_SCREEN_INFO(AdjustFrame, VGAarbiterAdjustFrame); + WRAP_SCREEN_INFO(SwitchMode, VGAarbiterSwitchMode); + WRAP_SCREEN_INFO(EnterVT, VGAarbiterEnterVT); + WRAP_SCREEN_INFO(LeaveVT, VGAarbiterLeaveVT); + WRAP_SCREEN_INFO(FreeScreen, VGAarbiterFreeScreen); + WRAP_SPRITE; + } + + return TRUE; +} + +/* Screen funcs */ +static Bool +VGAarbiterCloseScreen (int i, ScreenPtr pScreen) +{ + Bool val; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate( + &pScreen->devPrivates, VGAarbiterScreenKey); + miPointerScreenPtr PointPriv = (miPointerScreenPtr)dixLookupPrivate( + &pScreen->devPrivates, miPointerScreenKey); + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + + UNWRAP_SCREEN(CreateGC); + UNWRAP_SCREEN(CloseScreen); + UNWRAP_SCREEN(GetImage); + UNWRAP_SCREEN(GetSpans); + UNWRAP_SCREEN(SourceValidate); + UNWRAP_SCREEN(CopyWindow); + UNWRAP_SCREEN(ClearToBackground); + UNWRAP_SCREEN(SaveScreen); + UNWRAP_SCREEN(StoreColors); + UNWRAP_SCREEN(DisplayCursor); + UNWRAP_SCREEN(RealizeCursor); + UNWRAP_SCREEN(UnrealizeCursor); + UNWRAP_SCREEN(RecolorCursor); + UNWRAP_SCREEN(SetCursorPosition); + UNWRAP_PICT(Composite); + UNWRAP_PICT(Glyphs); + UNWRAP_PICT(CompositeRects); + UNWRAP_SCREEN_INFO(AdjustFrame); + UNWRAP_SCREEN_INFO(SwitchMode); + UNWRAP_SCREEN_INFO(EnterVT); + UNWRAP_SCREEN_INFO(LeaveVT); + UNWRAP_SCREEN_INFO(FreeScreen); + UNWRAP_SPRITE; + + free((pointer) pScreenPriv); + xf86VGAarbiterLock(xf86Screens[i]); + val = (*pScreen->CloseScreen) (i, pScreen); + xf86VGAarbiterUnlock(xf86Screens[i]); + return val; +} + +static void +VGAarbiterBlockHandler(int i, + pointer blockData, pointer pTimeout, pointer pReadmask) +{ + ScreenPtr pScreen = screenInfo.screens[i]; + SCREEN_PROLOG(BlockHandler); + VGAGet(pScreen); + pScreen->BlockHandler(i, blockData, pTimeout, pReadmask); + VGAPut(); + SCREEN_EPILOG(BlockHandler, VGAarbiterBlockHandler); +} + +static void +VGAarbiterWakeupHandler(int i, pointer blockData, unsigned long result, pointer pReadmask) +{ + ScreenPtr pScreen = screenInfo.screens[i]; + SCREEN_PROLOG(WakeupHandler); + VGAGet(pScreen); + pScreen->WakeupHandler(i, blockData, result, pReadmask); + VGAPut(); + SCREEN_EPILOG(WakeupHandler, VGAarbiterWakeupHandler); +} + +static void +VGAarbiterGetImage ( + DrawablePtr pDrawable, + int sx, int sy, int w, int h, + unsigned int format, + unsigned long planemask, + char *pdstLine + ) +{ + ScreenPtr pScreen = pDrawable->pScreen; + SCREEN_PROLOG(GetImage); +// if (xf86Screens[pScreen->myNum]->vtSema) { + VGAGet(pScreen); +// } + (*pScreen->GetImage) (pDrawable, sx, sy, w, h, + format, planemask, pdstLine); + VGAPut(); + SCREEN_EPILOG (GetImage, VGAarbiterGetImage); +} + +static void +VGAarbiterGetSpans ( + DrawablePtr pDrawable, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pdstStart + ) +{ + ScreenPtr pScreen = pDrawable->pScreen; + + SCREEN_PROLOG (GetSpans); + VGAGet(pScreen); + (*pScreen->GetSpans) (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); + VGAPut(); + SCREEN_EPILOG (GetSpans, VGAarbiterGetSpans); +} + +static void +VGAarbiterSourceValidate ( + DrawablePtr pDrawable, + int x, int y, int width, int height, + unsigned int subWindowMode ) +{ + ScreenPtr pScreen = pDrawable->pScreen; + SCREEN_PROLOG (SourceValidate); + VGAGet(pScreen); + if (pScreen->SourceValidate) + (*pScreen->SourceValidate) (pDrawable, x, y, width, height, subWindowMode); + VGAPut(); + SCREEN_EPILOG (SourceValidate, VGAarbiterSourceValidate); +} + +static void +VGAarbiterCopyWindow( + WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc ) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + + SCREEN_PROLOG (CopyWindow); + VGAGet(pScreen); + (*pScreen->CopyWindow) (pWin, ptOldOrg, prgnSrc); + VGAPut(); + SCREEN_EPILOG (CopyWindow, VGAarbiterCopyWindow); +} + +static void +VGAarbiterClearToBackground ( + WindowPtr pWin, + int x, int y, + int w, int h, + Bool generateExposures ) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + + SCREEN_PROLOG ( ClearToBackground); + VGAGet(pScreen); + (*pScreen->ClearToBackground) (pWin, x, y, w, h, generateExposures); + VGAPut(); + SCREEN_EPILOG (ClearToBackground, VGAarbiterClearToBackground); +} + +static PixmapPtr +VGAarbiterCreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned class) +{ + PixmapPtr pPix; + + SCREEN_PROLOG ( CreatePixmap); + VGAGet(pScreen); + pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, class); + VGAPut(); + SCREEN_EPILOG (CreatePixmap, VGAarbiterCreatePixmap); + + return pPix; +} + +static Bool +VGAarbiterSaveScreen(ScreenPtr pScreen, Bool unblank) +{ + Bool val; + + SCREEN_PROLOG (SaveScreen); + VGAGet(pScreen); + val = (*pScreen->SaveScreen) (pScreen, unblank); + VGAPut(); + SCREEN_EPILOG (SaveScreen, VGAarbiterSaveScreen); + + return val; +} + +static void +VGAarbiterStoreColors ( + ColormapPtr pmap, + int ndef, + xColorItem *pdefs) +{ + ScreenPtr pScreen = pmap->pScreen; + + SCREEN_PROLOG (StoreColors); + VGAGet(pScreen); + (*pScreen->StoreColors) (pmap,ndef,pdefs); + VGAPut(); + SCREEN_EPILOG ( StoreColors, VGAarbiterStoreColors); +} + +static void +VGAarbiterRecolorCursor ( + DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCurs, + Bool displayed + ) +{ + SCREEN_PROLOG (RecolorCursor); + VGAGet(pScreen); + (*pScreen->RecolorCursor) (pDev, pScreen, pCurs, displayed); + VGAPut(); + SCREEN_EPILOG ( RecolorCursor, VGAarbiterRecolorCursor); +} + +static Bool +VGAarbiterRealizeCursor ( + DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor + ) +{ + Bool val; + + SCREEN_PROLOG (RealizeCursor); + VGAGet(pScreen); + val = (*pScreen->RealizeCursor) (pDev, pScreen,pCursor); + VGAPut(); + SCREEN_EPILOG ( RealizeCursor, VGAarbiterRealizeCursor); + return val; +} + +static Bool +VGAarbiterUnrealizeCursor ( + DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor + ) +{ + Bool val; + + SCREEN_PROLOG (UnrealizeCursor); + VGAGet(pScreen); + val = (*pScreen->UnrealizeCursor) (pDev, pScreen, pCursor); + VGAPut(); + SCREEN_EPILOG ( UnrealizeCursor, VGAarbiterUnrealizeCursor); + return val; +} + +static Bool +VGAarbiterDisplayCursor ( + DeviceIntPtr pDev, + ScreenPtr pScreen, + CursorPtr pCursor + ) +{ + Bool val; + + SCREEN_PROLOG (DisplayCursor); + VGAGet(pScreen); + val = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor); + VGAPut(); + SCREEN_EPILOG ( DisplayCursor, VGAarbiterDisplayCursor); + return val; +} + +static Bool +VGAarbiterSetCursorPosition ( + DeviceIntPtr pDev, + ScreenPtr pScreen, + int x, int y, + Bool generateEvent) +{ + Bool val; + + SCREEN_PROLOG (SetCursorPosition); + VGAGet(pScreen); + val = (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent); + VGAPut(); + SCREEN_EPILOG ( SetCursorPosition, VGAarbiterSetCursorPosition); + return val; +} + +static void +VGAarbiterAdjustFrame(int index, int x, int y, int flags) +{ + ScreenPtr pScreen = screenInfo.screens[index]; + VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate( + &pScreen->devPrivates, VGAarbiterScreenKey); + + VGAGet(pScreen); + (*pScreenPriv->AdjustFrame)(index, x, y, flags); + VGAPut(); +} + +static Bool +VGAarbiterSwitchMode(int index, DisplayModePtr mode, int flags) +{ + Bool val; + ScreenPtr pScreen = screenInfo.screens[index]; + VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate( + &pScreen->devPrivates, VGAarbiterScreenKey); + + VGAGet(pScreen); + val = (*pScreenPriv->SwitchMode)(index, mode, flags); + VGAPut(); + return val; +} + +static Bool +VGAarbiterEnterVT(int index, int flags) +{ + Bool val; + ScrnInfoPtr pScrn = xf86Screens[index]; + ScreenPtr pScreen = screenInfo.screens[index]; + VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate( + &pScreen->devPrivates, VGAarbiterScreenKey); + + VGAGet(pScreen); + pScrn->EnterVT = pScreenPriv->EnterVT; + val = (*pScrn->EnterVT)(index, flags); + pScreenPriv->EnterVT = pScrn->EnterVT; + pScrn->EnterVT = VGAarbiterEnterVT; + VGAPut(); + return val; +} + +static void +VGAarbiterLeaveVT(int index, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[index]; + ScreenPtr pScreen = screenInfo.screens[index]; + VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate( + &pScreen->devPrivates, VGAarbiterScreenKey); + + VGAGet(pScreen); + pScrn->LeaveVT = pScreenPriv->LeaveVT; + (*pScreenPriv->LeaveVT)(index, flags); + pScreenPriv->LeaveVT = pScrn->LeaveVT; + pScrn->LeaveVT = VGAarbiterLeaveVT; + VGAPut(); +} + +static void +VGAarbiterFreeScreen(int index, int flags) +{ + ScreenPtr pScreen = screenInfo.screens[index]; + VGAarbiterScreenPtr pScreenPriv = (VGAarbiterScreenPtr)dixLookupPrivate( + &pScreen->devPrivates, VGAarbiterScreenKey); + + VGAGet(pScreen); + (*pScreenPriv->FreeScreen)(index, flags); + VGAPut(); +} + +static Bool +VGAarbiterCreateGC(GCPtr pGC) +{ + ScreenPtr pScreen = pGC->pScreen; + VGAarbiterGCPtr pGCPriv = (VGAarbiterGCPtr)dixLookupPrivate(&pGC->devPrivates, VGAarbiterGCKey); + Bool ret; + + SCREEN_PROLOG(CreateGC); + ret = (*pScreen->CreateGC)(pGC); + GC_WRAP(pGC); + SCREEN_EPILOG(CreateGC,VGAarbiterCreateGC); + + return ret; +} + +/* GC funcs */ +static void +VGAarbiterValidateGC( + GCPtr pGC, + unsigned long changes, + DrawablePtr pDraw ) +{ + GC_UNWRAP(pGC); + (*pGC->funcs->ValidateGC)(pGC, changes, pDraw); + GC_WRAP(pGC); +} + + +static void +VGAarbiterDestroyGC(GCPtr pGC) +{ + GC_UNWRAP (pGC); + (*pGC->funcs->DestroyGC)(pGC); + GC_WRAP (pGC); +} + +static void +VGAarbiterChangeGC ( + GCPtr pGC, + unsigned long mask) +{ + GC_UNWRAP (pGC); + (*pGC->funcs->ChangeGC) (pGC, mask); + GC_WRAP (pGC); +} + +static void +VGAarbiterCopyGC ( + GCPtr pGCSrc, + unsigned long mask, + GCPtr pGCDst) +{ + GC_UNWRAP (pGCDst); + (*pGCDst->funcs->CopyGC) (pGCSrc, mask, pGCDst); + GC_WRAP (pGCDst); +} + +static void +VGAarbiterChangeClip ( + GCPtr pGC, + int type, + pointer pvalue, + int nrects ) +{ + GC_UNWRAP (pGC); + (*pGC->funcs->ChangeClip) (pGC, type, pvalue, nrects); + GC_WRAP (pGC); +} + +static void +VGAarbiterCopyClip(GCPtr pgcDst, GCPtr pgcSrc) +{ + GC_UNWRAP (pgcDst); + (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); + GC_WRAP (pgcDst); +} + +static void +VGAarbiterDestroyClip(GCPtr pGC) +{ + GC_UNWRAP (pGC); + (* pGC->funcs->DestroyClip)(pGC); + GC_WRAP (pGC); +} + +/* GC Ops */ +static void +VGAarbiterFillSpans( + DrawablePtr pDraw, + GC *pGC, + int nInit, + DDXPointPtr pptInit, + int *pwidthInit, + int fSorted ) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->FillSpans)(pDraw, pGC, nInit, pptInit, pwidthInit, fSorted); + VGAPut(); + GC_WRAP(pGC); +} + +static void +VGAarbiterSetSpans( + DrawablePtr pDraw, + GCPtr pGC, + char *pcharsrc, + register DDXPointPtr ppt, + int *pwidth, + int nspans, + int fSorted ) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->SetSpans)(pDraw, pGC, pcharsrc, ppt, pwidth, nspans, fSorted); + VGAPut(); + GC_WRAP(pGC); +} + +static void +VGAarbiterPutImage( + DrawablePtr pDraw, + GCPtr pGC, + int depth, + int x, int y, int w, int h, + int leftPad, + int format, + char *pImage ) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->PutImage)(pDraw, pGC, depth, x, y, w, h, + leftPad, format, pImage); + VGAPut(); + GC_WRAP(pGC); +} + +static RegionPtr +VGAarbiterCopyArea( + DrawablePtr pSrc, + DrawablePtr pDst, + GC *pGC, + int srcx, int srcy, + int width, int height, + int dstx, int dsty ) +{ + RegionPtr ret; + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + ret = (*pGC->ops->CopyArea)(pSrc, pDst, + pGC, srcx, srcy, width, height, dstx, dsty); + VGAPut(); + GC_WRAP(pGC); + return ret; +} + +static RegionPtr +VGAarbiterCopyPlane( + DrawablePtr pSrc, + DrawablePtr pDst, + GCPtr pGC, + int srcx, int srcy, + int width, int height, + int dstx, int dsty, + unsigned long bitPlane ) +{ + RegionPtr ret; + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + ret = (*pGC->ops->CopyPlane)(pSrc, pDst, pGC, srcx, srcy, + width, height, dstx, dsty, bitPlane); + VGAPut(); + GC_WRAP(pGC); + return ret; +} + +static void +VGAarbiterPolyPoint( + DrawablePtr pDraw, + GCPtr pGC, + int mode, + int npt, + xPoint *pptInit ) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->PolyPoint)(pDraw, pGC, mode, npt, pptInit); + VGAPut(); + GC_WRAP(pGC); +} + + +static void +VGAarbiterPolylines( + DrawablePtr pDraw, + GCPtr pGC, + int mode, + int npt, + DDXPointPtr pptInit ) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->Polylines)(pDraw, pGC, mode, npt, pptInit); + VGAPut(); + GC_WRAP(pGC); +} + +static void +VGAarbiterPolySegment( + DrawablePtr pDraw, + GCPtr pGC, + int nseg, + xSegment *pSeg ) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->PolySegment)(pDraw, pGC, nseg, pSeg); + VGAPut(); + GC_WRAP(pGC); +} + +static void +VGAarbiterPolyRectangle( + DrawablePtr pDraw, + GCPtr pGC, + int nRectsInit, + xRectangle *pRectsInit ) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->PolyRectangle)(pDraw, pGC, nRectsInit, pRectsInit); + VGAPut(); + GC_WRAP(pGC); +} + +static void +VGAarbiterPolyArc( + DrawablePtr pDraw, + GCPtr pGC, + int narcs, + xArc *parcs ) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->PolyArc)(pDraw, pGC, narcs, parcs); + VGAPut(); + GC_WRAP(pGC); +} + +static void +VGAarbiterFillPolygon( + DrawablePtr pDraw, + GCPtr pGC, + int shape, + int mode, + int count, + DDXPointPtr ptsIn ) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->FillPolygon)(pDraw, pGC, shape, mode, count, ptsIn); + VGAPut(); + GC_WRAP(pGC); +} + +static void +VGAarbiterPolyFillRect( + DrawablePtr pDraw, + GCPtr pGC, + int nrectFill, + xRectangle *prectInit) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->PolyFillRect)(pDraw, pGC, nrectFill, prectInit); + VGAPut(); + GC_WRAP(pGC); +} + +static void +VGAarbiterPolyFillArc( + DrawablePtr pDraw, + GCPtr pGC, + int narcs, + xArc *parcs ) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->PolyFillArc)(pDraw, pGC, narcs, parcs); + VGAPut(); + GC_WRAP(pGC); +} + +static int +VGAarbiterPolyText8( + DrawablePtr pDraw, + GCPtr pGC, + int x, + int y, + int count, + char *chars ) +{ + int ret; + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + ret = (*pGC->ops->PolyText8)(pDraw, pGC, x, y, count, chars); + VGAPut(); + GC_WRAP(pGC); + return ret; +} + +static int +VGAarbiterPolyText16( + DrawablePtr pDraw, + GCPtr pGC, + int x, + int y, + int count, + unsigned short *chars ) +{ + int ret; + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + ret = (*pGC->ops->PolyText16)(pDraw, pGC, x, y, count, chars); + VGAPut(); + GC_WRAP(pGC); + return ret; +} + +static void +VGAarbiterImageText8( + DrawablePtr pDraw, + GCPtr pGC, + int x, + int y, + int count, + char *chars ) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->ImageText8)(pDraw, pGC, x, y, count, chars); + VGAPut(); + GC_WRAP(pGC); +} + +static void +VGAarbiterImageText16( + DrawablePtr pDraw, + GCPtr pGC, + int x, + int y, + int count, + unsigned short *chars ) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->ImageText16)(pDraw, pGC, x, y, count, chars); + VGAPut(); + GC_WRAP(pGC); +} + + +static void +VGAarbiterImageGlyphBlt( + DrawablePtr pDraw, + GCPtr pGC, + int xInit, int yInit, + unsigned int nglyph, + CharInfoPtr *ppci, + pointer pglyphBase ) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->ImageGlyphBlt)(pDraw, pGC, xInit, yInit, + nglyph, ppci, pglyphBase); + VGAPut(); + GC_WRAP(pGC); +} + +static void +VGAarbiterPolyGlyphBlt( + DrawablePtr pDraw, + GCPtr pGC, + int xInit, int yInit, + unsigned int nglyph, + CharInfoPtr *ppci, + pointer pglyphBase ) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->PolyGlyphBlt)(pDraw, pGC, xInit, yInit, + nglyph, ppci, pglyphBase); + VGAPut(); + GC_WRAP(pGC); +} + +static void +VGAarbiterPushPixels( + GCPtr pGC, + PixmapPtr pBitMap, + DrawablePtr pDraw, + int dx, int dy, int xOrg, int yOrg ) +{ + ScreenPtr pScreen = pGC->pScreen; + GC_UNWRAP(pGC); + VGAGet(pScreen); + (*pGC->ops->PushPixels)(pGC, pBitMap, pDraw, dx, dy, xOrg, yOrg); + VGAPut(); + GC_WRAP(pGC); +} + + +/* miSpriteFuncs */ +static Bool +VGAarbiterSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur) +{ + Bool val; + SPRITE_PROLOG; + VGAGet(pScreen); + val = PointPriv->spriteFuncs->RealizeCursor(pDev, pScreen, pCur); + VGAPut(); + SPRITE_EPILOG; + return val; +} + +static Bool +VGAarbiterSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur) +{ + Bool val; + SPRITE_PROLOG; + VGAGet(pScreen); + val = PointPriv->spriteFuncs->UnrealizeCursor(pDev, pScreen, pCur); + VGAPut(); + SPRITE_EPILOG; + return val; +} + +static void +VGAarbiterSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCur, int x, int y) +{ + SPRITE_PROLOG; + VGAGet(pScreen); + PointPriv->spriteFuncs->SetCursor(pDev, pScreen, pCur, x, y); + VGAPut(); + SPRITE_EPILOG; +} + +static void +VGAarbiterSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) +{ + SPRITE_PROLOG; + VGAGet(pScreen); + PointPriv->spriteFuncs->MoveCursor(pDev, pScreen, x, y); + VGAPut(); + SPRITE_EPILOG; +} + +static Bool +VGAarbiterDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) +{ + Bool val; + SPRITE_PROLOG; + VGAGet(pScreen); + val = PointPriv->spriteFuncs->DeviceCursorInitialize(pDev, pScreen); + VGAPut(); + SPRITE_EPILOG; + return val; +} + +static void +VGAarbiterDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen) +{ + SPRITE_PROLOG; + VGAGet(pScreen); + PointPriv->spriteFuncs->DeviceCursorCleanup(pDev, pScreen); + VGAPut(); + SPRITE_EPILOG; +} + +static void +VGAarbiterComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, + PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, + INT16 yMask, INT16 xDst, INT16 yDst, CARD16 width, + CARD16 height) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + + PICTURE_PROLOGUE(Composite); + + VGAGet(pScreen); + (*ps->Composite) (op, pSrc, pMask, pDst, xSrc, ySrc, xMask, yMask, xDst, + yDst, width, height); + VGAPut(); + PICTURE_EPILOGUE(Composite, VGAarbiterComposite); +} + +static void +VGAarbiterGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, + GlyphListPtr list, GlyphPtr *glyphs) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + + PICTURE_PROLOGUE(Glyphs); + + VGAGet(pScreen); + (*ps->Glyphs)(op, pSrc, pDst, maskFormat, xSrc, ySrc, nlist, list, glyphs); + VGAPut(); + PICTURE_EPILOGUE (Glyphs, VGAarbiterGlyphs); +} + +static void +VGAarbiterCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor *color, int nRect, + xRectangle *rects) +{ + ScreenPtr pScreen = pDst->pDrawable->pScreen; + PictureScreenPtr ps = GetPictureScreen(pScreen); + + PICTURE_PROLOGUE(CompositeRects); + + VGAGet(pScreen); + (*ps->CompositeRects)(op, pDst, color, nRect, rects); + VGAPut(); + PICTURE_EPILOGUE (CompositeRects, VGAarbiterCompositeRects); +} +#else +/* dummy functions */ +void xf86VGAarbiterInit(void) {} +void xf86VGAarbiterFini(void) {} + +void xf86VGAarbiterLock(ScrnInfoPtr pScrn) {} +void xf86VGAarbiterUnlock(ScrnInfoPtr pScrn) {} +Bool xf86VGAarbiterAllowDRI(ScreenPtr pScreen) { return TRUE; } +void xf86VGAarbiterScrnInit(ScrnInfoPtr pScrn) {} +void xf86VGAarbiterDeviceDecodes(ScrnInfoPtr pScrn, int rsrc) {} +Bool xf86VGAarbiterWrapFunctions(void) { return FALSE; } + +#endif diff --git a/xorg-server/hw/xfree86/common/xf86VGAarbiterPriv.h b/xorg-server/hw/xfree86/common/xf86VGAarbiterPriv.h index 13fde5e79..e1ac20f1f 100644 --- a/xorg-server/hw/xfree86/common/xf86VGAarbiterPriv.h +++ b/xorg-server/hw/xfree86/common/xf86VGAarbiterPriv.h @@ -1,253 +1,253 @@ -/* - * Copyright (c) 2009 Tiago Vignatti - * - * Permission is hereby granted, free of charge, to any person - * obtaining a copy of this software and associated documentation - * files (the "Software"), to deal in the Software without - * restriction, including without limitation the rights to use, - * copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following - * conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifdef HAVE_XORG_CONFIG_H -#include -#endif - -#include "misc.h" -#include "xf86.h" -#include "xf86_OSproc.h" -#include -#include "colormapst.h" -#include "scrnintstr.h" -#include "screenint.h" -#include "gcstruct.h" -#include "pixmapstr.h" -#include "pixmap.h" -#include "windowstr.h" -#include "window.h" -#include "xf86str.h" -#include "mipointer.h" -#include "mipointrst.h" -# include "picturestr.h" - - -#define WRAP_SCREEN(x,y) {pScreenPriv->x = pScreen->x; pScreen->x = y;} - -#define UNWRAP_SCREEN(x) pScreen->x = pScreenPriv->x - -#define SCREEN_PROLOG(x) pScreen->x = ((VGAarbiterScreenPtr) \ - dixLookupPrivate(&(pScreen)->devPrivates, VGAarbiterScreenKey))->x - -#define SCREEN_EPILOG(x,y) pScreen->x = y; - -#define WRAP_PICT(x,y) if (ps) {pScreenPriv->x = ps->x;\ - ps->x = y;} - -#define UNWRAP_PICT(x) if (ps) {ps->x = pScreenPriv->x;} - -#define PICTURE_PROLOGUE(field) ps->field = \ - ((VGAarbiterScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, \ - VGAarbiterScreenKey))->field - -#define PICTURE_EPILOGUE(field, wrap) ps->field = wrap - -#define WRAP_SCREEN_INFO(x,y) do {pScreenPriv->x = pScrn->x; pScrn->x = y;} while(0) - -#define UNWRAP_SCREEN_INFO(x) pScrn->x = pScreenPriv->x - -#define SPRITE_PROLOG miPointerScreenPtr PointPriv = \ - (miPointerScreenPtr)dixLookupPrivate(&pScreen->devPrivates, \ - miPointerScreenKey); VGAarbiterScreenPtr pScreenPriv = \ - ((VGAarbiterScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, \ - VGAarbiterScreenKey)); PointPriv->spriteFuncs = pScreenPriv->miSprite; - -#define SPRITE_EPILOG pScreenPriv->miSprite = PointPriv->spriteFuncs;\ - PointPriv->spriteFuncs = &VGAarbiterSpriteFuncs; - -#define WRAP_SPRITE do { pScreenPriv->miSprite = PointPriv->spriteFuncs;\ - PointPriv->spriteFuncs = &VGAarbiterSpriteFuncs; \ - } while (0) - -#define UNWRAP_SPRITE PointPriv->spriteFuncs = pScreenPriv->miSprite - -#define GC_WRAP(x) pGCPriv->wrapOps = (x)->ops;\ - pGCPriv->wrapFuncs = (x)->funcs; (x)->ops = &VGAarbiterGCOps;\ - (x)->funcs = &VGAarbiterGCFuncs; - -#define GC_UNWRAP(x) VGAarbiterGCPtr pGCPriv = \ - (VGAarbiterGCPtr)dixLookupPrivate(&(x)->devPrivates, VGAarbiterGCKey);\ - (x)->ops = pGCPriv->wrapOps; (x)->funcs = pGCPriv->wrapFuncs; - -static inline void -VGAGet(ScreenPtr pScreen) { - pci_device_vgaarb_set_target(xf86Screens[pScreen->myNum]->vgaDev); - pci_device_vgaarb_lock(); -} - -static inline void -VGAPut(void) { - pci_device_vgaarb_unlock(); -} - -typedef struct _VGAarbiterScreen { - CreateGCProcPtr CreateGC; - CloseScreenProcPtr CloseScreen; - ScreenBlockHandlerProcPtr BlockHandler; - ScreenWakeupHandlerProcPtr WakeupHandler; - GetImageProcPtr GetImage; - GetSpansProcPtr GetSpans; - SourceValidateProcPtr SourceValidate; - CopyWindowProcPtr CopyWindow; - ClearToBackgroundProcPtr ClearToBackground; - CreatePixmapProcPtr CreatePixmap; - SaveScreenProcPtr SaveScreen; - /* Colormap */ - StoreColorsProcPtr StoreColors; - /* Cursor */ - DisplayCursorProcPtr DisplayCursor; - RealizeCursorProcPtr RealizeCursor; - UnrealizeCursorProcPtr UnrealizeCursor; - RecolorCursorProcPtr RecolorCursor; - SetCursorPositionProcPtr SetCursorPosition; - void (*AdjustFrame)(int,int,int,int); - Bool (*SwitchMode)(int, DisplayModePtr,int); - Bool (*EnterVT)(int, int); - void (*LeaveVT)(int, int); - void (*FreeScreen)(int, int); - miPointerSpriteFuncPtr miSprite; - CompositeProcPtr Composite; - GlyphsProcPtr Glyphs; - CompositeRectsProcPtr CompositeRects; -} VGAarbiterScreenRec, *VGAarbiterScreenPtr; - -typedef struct _VGAarbiterGC { - GCOps *wrapOps; - GCFuncs *wrapFuncs; -} VGAarbiterGCRec, *VGAarbiterGCPtr; - -/* Screen funcs */ -static void VGAarbiterBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask); -static void VGAarbiterWakeupHandler(int i, pointer blockData, unsigned long result, pointer pReadmask); -static Bool VGAarbiterCloseScreen (int i, ScreenPtr pScreen); -static void VGAarbiterGetImage (DrawablePtr pDrawable, int sx, int sy, int w, - int h, unsigned int format, unsigned long planemask, char *pdstLine); -static void VGAarbiterGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr - ppt, int *pwidth, int nspans, char *pdstStart); -static void VGAarbiterSourceValidate (DrawablePtr pDrawable, int x, int y, - int width, int height, unsigned int subWindowMode); -static void VGAarbiterCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, - RegionPtr prgnSrc); -static void VGAarbiterClearToBackground (WindowPtr pWin, int x, int y, int w, - int h, Bool generateExposures); -static PixmapPtr VGAarbiterCreatePixmap(ScreenPtr pScreen, int w, int h, - int depth, unsigned int usage_hint); -static Bool VGAarbiterCreateGC(GCPtr pGC); -static Bool VGAarbiterSaveScreen(ScreenPtr pScreen, Bool unblank); -static void VGAarbiterStoreColors (ColormapPtr pmap, int ndef, xColorItem - *pdefs); -static void VGAarbiterRecolorCursor (DeviceIntPtr pDev, ScreenPtr pScreen, - CursorPtr pCurs, Bool displayed); -static Bool VGAarbiterRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, - CursorPtr pCursor); -static Bool VGAarbiterUnrealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, - CursorPtr pCursor); -static Bool VGAarbiterDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, - CursorPtr pCursor); -static Bool VGAarbiterSetCursorPosition (DeviceIntPtr pDev, ScreenPtr - pScreen, int x, int y, Bool generateEvent); -static void VGAarbiterAdjustFrame(int index, int x, int y, int flags); -static Bool VGAarbiterSwitchMode(int index, DisplayModePtr mode, int flags); -static Bool VGAarbiterEnterVT(int index, int flags); -static void VGAarbiterLeaveVT(int index, int flags); -static void VGAarbiterFreeScreen(int index, int flags); - -/* GC funcs */ -static void VGAarbiterValidateGC(GCPtr pGC, unsigned long changes, - DrawablePtr pDraw); -static void VGAarbiterChangeGC(GCPtr pGC, unsigned long mask); -static void VGAarbiterCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst); -static void VGAarbiterDestroyGC(GCPtr pGC); -static void VGAarbiterChangeClip(GCPtr pGC, int type, pointer pvalue, - int nrects); -static void VGAarbiterDestroyClip(GCPtr pGC); -static void VGAarbiterCopyClip(GCPtr pgcDst, GCPtr pgcSrc); - -/* GC ops */ -static void VGAarbiterFillSpans( DrawablePtr pDraw, GC *pGC, int nInit, - DDXPointPtr pptInit, int *pwidthInit, int fSorted); -static void VGAarbiterSetSpans(DrawablePtr pDraw, GCPtr pGC, char *pcharsrc, - register DDXPointPtr ppt, int *pwidth, int nspans, int fSorted); -static void VGAarbiterPutImage(DrawablePtr pDraw, GCPtr pGC, int depth, - int x, int y, int w, int h, int leftPad, int format, char *pImage); -static RegionPtr VGAarbiterCopyArea(DrawablePtr pSrc, DrawablePtr pDst, - GC *pGC, int srcx, int srcy, int width, int height, int dstx, int dsty); -static RegionPtr VGAarbiterCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, - GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty, - unsigned long bitPlane); -static void VGAarbiterPolyPoint(DrawablePtr pDraw, GCPtr pGC, int mode, - int npt, xPoint *pptInit); -static void VGAarbiterPolylines(DrawablePtr pDraw, GCPtr pGC, int mode, - int npt, DDXPointPtr pptInit); -static void VGAarbiterPolySegment(DrawablePtr pDraw, GCPtr pGC, int nseg, - xSegment *pSeg); -static void VGAarbiterPolyRectangle(DrawablePtr pDraw, GCPtr pGC, - int nRectsInit, xRectangle *pRectsInit); -static void VGAarbiterPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, - xArc *parcs); -static void VGAarbiterFillPolygon(DrawablePtr pDraw, GCPtr pGC, int shape, - int mode, int count, DDXPointPtr ptsIn); -static void VGAarbiterPolyFillRect( DrawablePtr pDraw, GCPtr pGC, - int nrectFill, xRectangle *prectInit); -static void VGAarbiterPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs, - xArc *parcs); -static int VGAarbiterPolyText8(DrawablePtr pDraw, GCPtr pGC, int x, int y, - int count, char *chars); -static int VGAarbiterPolyText16(DrawablePtr pDraw, GCPtr pGC, int x, int y, - int count, unsigned short *chars); -static void VGAarbiterImageText8(DrawablePtr pDraw, GCPtr pGC, int x, int y, - int count, char *chars); -static void VGAarbiterImageText16(DrawablePtr pDraw, GCPtr pGC, int x, int y, - int count, unsigned short *chars); -static void VGAarbiterImageGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int xInit, - int yInit, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase); -static void VGAarbiterPolyGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int xInit, - int yInit, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase); -static void VGAarbiterPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr - pDraw, int dx, int dy, int xOrg, int yOrg); - -/* miSpriteFuncs */ -static Bool VGAarbiterSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr - pScreen, CursorPtr pCur); -static Bool VGAarbiterSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr - pScreen, CursorPtr pCur); -static void VGAarbiterSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, - CursorPtr pCur, int x, int y); -static void VGAarbiterSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, - int x, int y); -static Bool VGAarbiterDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen); -static void VGAarbiterDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen); - - -static void VGAarbiterComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, - PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, - INT16 xDst, INT16 yDst, CARD16 width, CARD16 height); -static void VGAarbiterGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, - PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr - list, GlyphPtr *glyphs); -static void VGAarbiterCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor - *color, int nRect, xRectangle *rects); +/* + * Copyright (c) 2009 Tiago Vignatti + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#include "misc.h" +#include "xf86.h" +#include "xf86_OSproc.h" +#include +#include "colormapst.h" +#include "scrnintstr.h" +#include "screenint.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "pixmap.h" +#include "windowstr.h" +#include "window.h" +#include "xf86str.h" +#include "mipointer.h" +#include "mipointrst.h" +# include "picturestr.h" + + +#define WRAP_SCREEN(x,y) {pScreenPriv->x = pScreen->x; pScreen->x = y;} + +#define UNWRAP_SCREEN(x) pScreen->x = pScreenPriv->x + +#define SCREEN_PROLOG(x) pScreen->x = ((VGAarbiterScreenPtr) \ + dixLookupPrivate(&(pScreen)->devPrivates, VGAarbiterScreenKey))->x + +#define SCREEN_EPILOG(x,y) pScreen->x = y; + +#define WRAP_PICT(x,y) if (ps) {pScreenPriv->x = ps->x;\ + ps->x = y;} + +#define UNWRAP_PICT(x) if (ps) {ps->x = pScreenPriv->x;} + +#define PICTURE_PROLOGUE(field) ps->field = \ + ((VGAarbiterScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, \ + VGAarbiterScreenKey))->field + +#define PICTURE_EPILOGUE(field, wrap) ps->field = wrap + +#define WRAP_SCREEN_INFO(x,y) do {pScreenPriv->x = pScrn->x; pScrn->x = y;} while(0) + +#define UNWRAP_SCREEN_INFO(x) pScrn->x = pScreenPriv->x + +#define SPRITE_PROLOG miPointerScreenPtr PointPriv = \ + (miPointerScreenPtr)dixLookupPrivate(&pScreen->devPrivates, \ + miPointerScreenKey); VGAarbiterScreenPtr pScreenPriv = \ + ((VGAarbiterScreenPtr)dixLookupPrivate(&(pScreen)->devPrivates, \ + VGAarbiterScreenKey)); PointPriv->spriteFuncs = pScreenPriv->miSprite; + +#define SPRITE_EPILOG pScreenPriv->miSprite = PointPriv->spriteFuncs;\ + PointPriv->spriteFuncs = &VGAarbiterSpriteFuncs; + +#define WRAP_SPRITE do { pScreenPriv->miSprite = PointPriv->spriteFuncs;\ + PointPriv->spriteFuncs = &VGAarbiterSpriteFuncs; \ + } while (0) + +#define UNWRAP_SPRITE PointPriv->spriteFuncs = pScreenPriv->miSprite + +#define GC_WRAP(x) pGCPriv->wrapOps = (x)->ops;\ + pGCPriv->wrapFuncs = (x)->funcs; (x)->ops = &VGAarbiterGCOps;\ + (x)->funcs = &VGAarbiterGCFuncs; + +#define GC_UNWRAP(x) VGAarbiterGCPtr pGCPriv = \ + (VGAarbiterGCPtr)dixLookupPrivate(&(x)->devPrivates, VGAarbiterGCKey);\ + (x)->ops = pGCPriv->wrapOps; (x)->funcs = pGCPriv->wrapFuncs; + +static inline void +VGAGet(ScreenPtr pScreen) { + pci_device_vgaarb_set_target(xf86Screens[pScreen->myNum]->vgaDev); + pci_device_vgaarb_lock(); +} + +static inline void +VGAPut(void) { + pci_device_vgaarb_unlock(); +} + +typedef struct _VGAarbiterScreen { + CreateGCProcPtr CreateGC; + CloseScreenProcPtr CloseScreen; + ScreenBlockHandlerProcPtr BlockHandler; + ScreenWakeupHandlerProcPtr WakeupHandler; + GetImageProcPtr GetImage; + GetSpansProcPtr GetSpans; + SourceValidateProcPtr SourceValidate; + CopyWindowProcPtr CopyWindow; + ClearToBackgroundProcPtr ClearToBackground; + CreatePixmapProcPtr CreatePixmap; + SaveScreenProcPtr SaveScreen; + /* Colormap */ + StoreColorsProcPtr StoreColors; + /* Cursor */ + DisplayCursorProcPtr DisplayCursor; + RealizeCursorProcPtr RealizeCursor; + UnrealizeCursorProcPtr UnrealizeCursor; + RecolorCursorProcPtr RecolorCursor; + SetCursorPositionProcPtr SetCursorPosition; + void (*AdjustFrame)(int,int,int,int); + Bool (*SwitchMode)(int, DisplayModePtr,int); + Bool (*EnterVT)(int, int); + void (*LeaveVT)(int, int); + void (*FreeScreen)(int, int); + miPointerSpriteFuncPtr miSprite; + CompositeProcPtr Composite; + GlyphsProcPtr Glyphs; + CompositeRectsProcPtr CompositeRects; +} VGAarbiterScreenRec, *VGAarbiterScreenPtr; + +typedef struct _VGAarbiterGC { + GCOps *wrapOps; + GCFuncs *wrapFuncs; +} VGAarbiterGCRec, *VGAarbiterGCPtr; + +/* Screen funcs */ +static void VGAarbiterBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask); +static void VGAarbiterWakeupHandler(int i, pointer blockData, unsigned long result, pointer pReadmask); +static Bool VGAarbiterCloseScreen (int i, ScreenPtr pScreen); +static void VGAarbiterGetImage (DrawablePtr pDrawable, int sx, int sy, int w, + int h, unsigned int format, unsigned long planemask, char *pdstLine); +static void VGAarbiterGetSpans (DrawablePtr pDrawable, int wMax, DDXPointPtr + ppt, int *pwidth, int nspans, char *pdstStart); +static void VGAarbiterSourceValidate (DrawablePtr pDrawable, int x, int y, + int width, int height, unsigned int subWindowMode); +static void VGAarbiterCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, + RegionPtr prgnSrc); +static void VGAarbiterClearToBackground (WindowPtr pWin, int x, int y, int w, + int h, Bool generateExposures); +static PixmapPtr VGAarbiterCreatePixmap(ScreenPtr pScreen, int w, int h, + int depth, unsigned int class); +static Bool VGAarbiterCreateGC(GCPtr pGC); +static Bool VGAarbiterSaveScreen(ScreenPtr pScreen, Bool unblank); +static void VGAarbiterStoreColors (ColormapPtr pmap, int ndef, xColorItem + *pdefs); +static void VGAarbiterRecolorCursor (DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCurs, Bool displayed); +static Bool VGAarbiterRealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor); +static Bool VGAarbiterUnrealizeCursor (DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor); +static Bool VGAarbiterDisplayCursor (DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCursor); +static Bool VGAarbiterSetCursorPosition (DeviceIntPtr pDev, ScreenPtr + pScreen, int x, int y, Bool generateEvent); +static void VGAarbiterAdjustFrame(int index, int x, int y, int flags); +static Bool VGAarbiterSwitchMode(int index, DisplayModePtr mode, int flags); +static Bool VGAarbiterEnterVT(int index, int flags); +static void VGAarbiterLeaveVT(int index, int flags); +static void VGAarbiterFreeScreen(int index, int flags); + +/* GC funcs */ +static void VGAarbiterValidateGC(GCPtr pGC, unsigned long changes, + DrawablePtr pDraw); +static void VGAarbiterChangeGC(GCPtr pGC, unsigned long mask); +static void VGAarbiterCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst); +static void VGAarbiterDestroyGC(GCPtr pGC); +static void VGAarbiterChangeClip(GCPtr pGC, int type, pointer pvalue, + int nrects); +static void VGAarbiterDestroyClip(GCPtr pGC); +static void VGAarbiterCopyClip(GCPtr pgcDst, GCPtr pgcSrc); + +/* GC ops */ +static void VGAarbiterFillSpans( DrawablePtr pDraw, GC *pGC, int nInit, + DDXPointPtr pptInit, int *pwidthInit, int fSorted); +static void VGAarbiterSetSpans(DrawablePtr pDraw, GCPtr pGC, char *pcharsrc, + register DDXPointPtr ppt, int *pwidth, int nspans, int fSorted); +static void VGAarbiterPutImage(DrawablePtr pDraw, GCPtr pGC, int depth, + int x, int y, int w, int h, int leftPad, int format, char *pImage); +static RegionPtr VGAarbiterCopyArea(DrawablePtr pSrc, DrawablePtr pDst, + GC *pGC, int srcx, int srcy, int width, int height, int dstx, int dsty); +static RegionPtr VGAarbiterCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, + GCPtr pGC, int srcx, int srcy, int width, int height, int dstx, int dsty, + unsigned long bitPlane); +static void VGAarbiterPolyPoint(DrawablePtr pDraw, GCPtr pGC, int mode, + int npt, xPoint *pptInit); +static void VGAarbiterPolylines(DrawablePtr pDraw, GCPtr pGC, int mode, + int npt, DDXPointPtr pptInit); +static void VGAarbiterPolySegment(DrawablePtr pDraw, GCPtr pGC, int nseg, + xSegment *pSeg); +static void VGAarbiterPolyRectangle(DrawablePtr pDraw, GCPtr pGC, + int nRectsInit, xRectangle *pRectsInit); +static void VGAarbiterPolyArc(DrawablePtr pDraw, GCPtr pGC, int narcs, + xArc *parcs); +static void VGAarbiterFillPolygon(DrawablePtr pDraw, GCPtr pGC, int shape, + int mode, int count, DDXPointPtr ptsIn); +static void VGAarbiterPolyFillRect( DrawablePtr pDraw, GCPtr pGC, + int nrectFill, xRectangle *prectInit); +static void VGAarbiterPolyFillArc(DrawablePtr pDraw, GCPtr pGC, int narcs, + xArc *parcs); +static int VGAarbiterPolyText8(DrawablePtr pDraw, GCPtr pGC, int x, int y, + int count, char *chars); +static int VGAarbiterPolyText16(DrawablePtr pDraw, GCPtr pGC, int x, int y, + int count, unsigned short *chars); +static void VGAarbiterImageText8(DrawablePtr pDraw, GCPtr pGC, int x, int y, + int count, char *chars); +static void VGAarbiterImageText16(DrawablePtr pDraw, GCPtr pGC, int x, int y, + int count, unsigned short *chars); +static void VGAarbiterImageGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int xInit, + int yInit, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase); +static void VGAarbiterPolyGlyphBlt(DrawablePtr pDraw, GCPtr pGC, int xInit, + int yInit, unsigned int nglyph, CharInfoPtr *ppci, pointer pglyphBase); +static void VGAarbiterPushPixels(GCPtr pGC, PixmapPtr pBitMap, DrawablePtr + pDraw, int dx, int dy, int xOrg, int yOrg); + +/* miSpriteFuncs */ +static Bool VGAarbiterSpriteRealizeCursor(DeviceIntPtr pDev, ScreenPtr + pScreen, CursorPtr pCur); +static Bool VGAarbiterSpriteUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr + pScreen, CursorPtr pCur); +static void VGAarbiterSpriteSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + CursorPtr pCur, int x, int y); +static void VGAarbiterSpriteMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, + int x, int y); +static Bool VGAarbiterDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen); +static void VGAarbiterDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScreen); + + +static void VGAarbiterComposite(CARD8 op, PicturePtr pSrc, PicturePtr pMask, + PicturePtr pDst, INT16 xSrc, INT16 ySrc, INT16 xMask, INT16 yMask, + INT16 xDst, INT16 yDst, CARD16 width, CARD16 height); +static void VGAarbiterGlyphs(CARD8 op, PicturePtr pSrc, PicturePtr pDst, + PictFormatPtr maskFormat, INT16 xSrc, INT16 ySrc, int nlist, GlyphListPtr + list, GlyphPtr *glyphs); +static void VGAarbiterCompositeRects(CARD8 op, PicturePtr pDst, xRenderColor + *color, int nRect, xRectangle *rects); diff --git a/xorg-server/hw/xfree86/vbe/vbe.c b/xorg-server/hw/xfree86/vbe/vbe.c index 5120b3199..04132d956 100644 --- a/xorg-server/hw/xfree86/vbe/vbe.c +++ b/xorg-server/hw/xfree86/vbe/vbe.c @@ -1,1089 +1,1089 @@ - -/* - * XFree86 vbe module - * Copyright 2000 Egbert Eich - * - * The mode query/save/set/restore functions from the vesa driver - * have been moved here. - * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com) - * Authors: Paulo César Pereira de Andrade - */ - -#ifdef HAVE_XORG_CONFIG_H -#include -#endif - -#include - -#include "xf86.h" -#include "vbe.h" -#include - -#define VERSION(x) VBE_VERSION_MAJOR(x),VBE_VERSION_MINOR(x) - -#if X_BYTE_ORDER == X_LITTLE_ENDIAN -#define B_O16(x) (x) -#define B_O32(x) (x) -#else -#define B_O16(x) ((((x) & 0xff) << 8) | (((x) & 0xff) >> 8)) -#define B_O32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) \ - | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24)) -#endif -#define L_ADD(x) (B_O32(x) & 0xffff) + ((B_O32(x) >> 12) & 0xffff00) - -#define FARP(p) (((unsigned)(p & 0xffff0000) >> 12) | (p & 0xffff)) -#define R16(v) ((v) & 0xffff) - -static unsigned char * vbeReadEDID(vbeInfoPtr pVbe); -static Bool vbeProbeDDC(vbeInfoPtr pVbe); - -static const char vbeVersionString[] = "VBE2"; - -vbeInfoPtr -VBEInit(xf86Int10InfoPtr pInt, int entityIndex) -{ - return VBEExtendedInit(pInt, entityIndex, 0); -} - -vbeInfoPtr -VBEExtendedInit(xf86Int10InfoPtr pInt, int entityIndex, int Flags) -{ - int RealOff; - pointer page = NULL; - ScrnInfoPtr pScrn = xf86FindScreenForEntity(entityIndex); - vbeControllerInfoPtr vbe = NULL; - Bool init_int10 = FALSE; - vbeInfoPtr vip = NULL; - int screen; - - if (!pScrn) return NULL; - screen = pScrn->scrnIndex; - - if (!pInt) { - if (!xf86LoadSubModule(pScrn, "int10")) - goto error; - - xf86DrvMsg(screen,X_INFO,"initializing int10\n"); - pInt = xf86ExtendedInitInt10(entityIndex,Flags); - if (!pInt) - goto error; - init_int10 = TRUE; - } - - page = xf86Int10AllocPages(pInt,1,&RealOff); - if (!page) goto error; - vbe = (vbeControllerInfoPtr) page; - memcpy(vbe->VbeSignature,vbeVersionString,4); - - pInt->ax = 0x4F00; - pInt->es = SEG_ADDR(RealOff); - pInt->di = SEG_OFF(RealOff); - pInt->num = 0x10; - - xf86ExecX86int10(pInt); - - if ((pInt->ax & 0xff) != 0x4f) { - xf86DrvMsgVerb(screen,X_INFO,3,"VESA BIOS not detected\n"); - goto error; - } - - switch (pInt->ax & 0xff00) { - case 0: - xf86DrvMsg(screen,X_INFO,"VESA BIOS detected\n"); - break; - case 0x100: - xf86DrvMsg(screen,X_INFO,"VESA BIOS function failed\n"); - goto error; - case 0x200: - xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported\n"); - goto error; - case 0x300: - xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported in current mode\n"); - goto error; - default: - xf86DrvMsg(screen,X_INFO,"Invalid\n"); - goto error; - } - - xf86DrvMsgVerb(screen, X_INFO, 4, - "VbeVersion is %d, OemStringPtr is 0x%08lx,\n" - "\tOemVendorNamePtr is 0x%08lx, OemProductNamePtr is 0x%08lx,\n" - "\tOemProductRevPtr is 0x%08lx\n", - vbe->VbeVersion, (unsigned long)vbe->OemStringPtr, - (unsigned long)vbe->OemVendorNamePtr, - (unsigned long)vbe->OemProductNamePtr, - (unsigned long)vbe->OemProductRevPtr); - - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Version %i.%i\n", - VERSION(vbe->VbeVersion)); - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Total Mem: %i kB\n", - vbe->TotalMem * 64); - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM: %s\n", - (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemStringPtr))); - - if (B_O16(vbe->VbeVersion) >= 0x200) { - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Software Rev: %i.%i\n", - VERSION(vbe->OemSoftwareRev)); - if (vbe->OemVendorNamePtr) - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Vendor: %s\n", - (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemVendorNamePtr))); - if (vbe->OemProductNamePtr) - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product: %s\n", - (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductNamePtr))); - if (vbe->OemProductRevPtr) - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product Rev: %s\n", - (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductRevPtr))); - } - vip = (vbeInfoPtr)xnfalloc(sizeof(vbeInfoRec)); - vip->version = B_O16(vbe->VbeVersion); - vip->pInt10 = pInt; - vip->ddc = DDC_UNCHECKED; - vip->memory = page; - vip->real_mode_base = RealOff; - vip->num_pages = 1; - vip->init_int10 = init_int10; - - return vip; - - error: - if (page) - xf86Int10FreePages(pInt, page, 1); - if (init_int10) - xf86FreeInt10(pInt); - return NULL; -} - -void -vbeFree(vbeInfoPtr pVbe) -{ - if (!pVbe) - return; - - xf86Int10FreePages(pVbe->pInt10,pVbe->memory,pVbe->num_pages); - /* If we have initalized int10 we ought to free it, too */ - if (pVbe->init_int10) - xf86FreeInt10(pVbe->pInt10); - free(pVbe); - return; -} - -static Bool -vbeProbeDDC(vbeInfoPtr pVbe) -{ - char *ddc_level; - int screen = pVbe->pInt10->scrnIndex; - - if (pVbe->ddc == DDC_NONE) - return FALSE; - if (pVbe->ddc != DDC_UNCHECKED) - return TRUE; - - pVbe->pInt10->ax = 0x4F15; - pVbe->pInt10->bx = 0; - pVbe->pInt10->cx = 0; - pVbe->pInt10->es = 0; - pVbe->pInt10->di = 0; - pVbe->pInt10->num = 0x10; - - xf86ExecX86int10(pVbe->pInt10); - - if ((pVbe->pInt10->ax & 0xff) != 0x4f) { - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC not supported\n"); - pVbe->ddc = DDC_NONE; - return FALSE; - } - - switch ((pVbe->pInt10->ax >> 8) & 0xff) { - case 0: - xf86DrvMsg(screen,X_INFO,"VESA VBE DDC supported\n"); - switch (pVbe->pInt10->bx & 0x3) { - case 0: - ddc_level = " none"; - pVbe->ddc = DDC_NONE; - break; - case 1: - ddc_level = " 1"; - pVbe->ddc = DDC_1; - break; - case 2: - ddc_level = " 2"; - pVbe->ddc = DDC_2; - break; - case 3: - ddc_level = " 1 + 2"; - pVbe->ddc = DDC_1_2; - break; - default: - ddc_level = ""; - pVbe->ddc = DDC_NONE; - break; - } - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Level%s\n",ddc_level); - if (pVbe->pInt10->bx & 0x4) { - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Screen blanked" - "for data transfer\n"); - pVbe->ddc_blank = TRUE; - } else - pVbe->ddc_blank = FALSE; - - xf86DrvMsgVerb(screen,X_INFO,3, - "VESA VBE DDC transfer in appr. %x sec.\n", - (pVbe->pInt10->bx >> 8) & 0xff); - } - - return TRUE; -} - -typedef enum { - VBEOPT_NOVBE, - VBEOPT_NODDC -} VBEOpts; - -static const OptionInfoRec VBEOptions[] = { - { VBEOPT_NOVBE, "NoVBE", OPTV_BOOLEAN, {0}, FALSE }, - { VBEOPT_NODDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE }, - { -1, NULL, OPTV_NONE, {0}, FALSE }, -}; - -static unsigned char * -vbeReadEDID(vbeInfoPtr pVbe) -{ - int RealOff = pVbe->real_mode_base; - pointer page = pVbe->memory; - unsigned char *tmp = NULL; - Bool novbe = FALSE; - Bool noddc = FALSE; - int screen = pVbe->pInt10->scrnIndex; - OptionInfoPtr options; - - if (!page) return NULL; - - options = xnfalloc(sizeof(VBEOptions)); - (void)memcpy(options, VBEOptions, sizeof(VBEOptions)); - xf86ProcessOptions(screen, xf86Screens[screen]->options, options); - xf86GetOptValBool(options, VBEOPT_NOVBE, &novbe); - xf86GetOptValBool(options, VBEOPT_NODDC, &noddc); - free(options); - if (novbe || noddc) return NULL; - - if (!vbeProbeDDC(pVbe)) goto error; - - memset(page,0,sizeof(vbeInfoPtr)); - strcpy(page,vbeVersionString); - - pVbe->pInt10->ax = 0x4F15; - pVbe->pInt10->bx = 0x01; - pVbe->pInt10->cx = 0; - pVbe->pInt10->dx = 0; - pVbe->pInt10->es = SEG_ADDR(RealOff); - pVbe->pInt10->di = SEG_OFF(RealOff); - pVbe->pInt10->num = 0x10; - - xf86ExecX86int10(pVbe->pInt10); - - if ((pVbe->pInt10->ax & 0xff) != 0x4f) { - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC invalid\n"); - goto error; - } - switch (pVbe->pInt10->ax & 0xff00) { - case 0x0: - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read successfully\n"); - tmp = (unsigned char *)xnfalloc(128); - memcpy(tmp,page,128); - break; - case 0x100: - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read failed\n"); - break; - default: - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC unkown failure %i\n", - pVbe->pInt10->ax & 0xff00); - break; - } - - error: - return tmp; -} - -xf86MonPtr -vbeDoEDID(vbeInfoPtr pVbe, pointer pDDCModule) -{ - xf86MonPtr pMonitor; - pointer pModule; - unsigned char *DDC_data = NULL; - - if (!pVbe) return NULL; - if (pVbe->version < 0x200) - return NULL; - - if (!(pModule = pDDCModule)) { - pModule = - xf86LoadSubModule(xf86Screens[pVbe->pInt10->scrnIndex], "ddc"); - if (!pModule) - return NULL; - } - - DDC_data = vbeReadEDID(pVbe); - - if (!DDC_data) - return NULL; - - pMonitor = xf86InterpretEDID(pVbe->pInt10->scrnIndex, DDC_data); - - if (!pDDCModule) - xf86UnloadSubModule(pModule); - return pMonitor; -} - -#define GET_UNALIGNED2(x) \ - ((*(CARD16*)(x)) | (*(((CARD16*)(x) + 1))) << 16) - -VbeInfoBlock * -VBEGetVBEInfo(vbeInfoPtr pVbe) -{ - VbeInfoBlock *block = NULL; - int i, pStr, pModes; - char *str; - CARD16 major, *modes; - - memset(pVbe->memory, 0, sizeof(VbeInfoBlock)); - - /* - Input: - AH := 4Fh Super VGA support - AL := 00h Return Super VGA information - ES:DI := Pointer to buffer - - Output: - AX := status - (All other registers are preserved) - */ - - ((char*)pVbe->memory)[0] = 'V'; - ((char*)pVbe->memory)[1] = 'B'; - ((char*)pVbe->memory)[2] = 'E'; - ((char*)pVbe->memory)[3] = '2'; - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f00; - pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base); - pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base); - xf86ExecX86int10(pVbe->pInt10); - - if (R16(pVbe->pInt10->ax) != 0x4f) - return NULL; - - block = calloc(sizeof(VbeInfoBlock), 1); - block->VESASignature[0] = ((char*)pVbe->memory)[0]; - block->VESASignature[1] = ((char*)pVbe->memory)[1]; - block->VESASignature[2] = ((char*)pVbe->memory)[2]; - block->VESASignature[3] = ((char*)pVbe->memory)[3]; - - block->VESAVersion = *(CARD16*)(((char*)pVbe->memory) + 4); - major = (unsigned)block->VESAVersion >> 8; - - pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 6)); - str = xf86int10Addr(pVbe->pInt10, FARP(pStr)); - block->OEMStringPtr = strdup(str); - - block->Capabilities[0] = ((char*)pVbe->memory)[10]; - block->Capabilities[1] = ((char*)pVbe->memory)[11]; - block->Capabilities[2] = ((char*)pVbe->memory)[12]; - block->Capabilities[3] = ((char*)pVbe->memory)[13]; - - pModes = GET_UNALIGNED2((((char*)pVbe->memory) + 14)); - modes = xf86int10Addr(pVbe->pInt10, FARP(pModes)); - i = 0; - while (modes[i] != 0xffff) - i++; - block->VideoModePtr = malloc(sizeof(CARD16) * i + 1); - memcpy(block->VideoModePtr, modes, sizeof(CARD16) * i); - block->VideoModePtr[i] = 0xffff; - - block->TotalMemory = *(CARD16*)(((char*)pVbe->memory) + 18); - - if (major < 2) - memcpy(&block->OemSoftwareRev, ((char*)pVbe->memory) + 20, 236); - else { - block->OemSoftwareRev = *(CARD16*)(((char*)pVbe->memory) + 20); - pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 22)); - str = xf86int10Addr(pVbe->pInt10, FARP(pStr)); - block->OemVendorNamePtr = strdup(str); - pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 26)); - str = xf86int10Addr(pVbe->pInt10, FARP(pStr)); - block->OemProductNamePtr = strdup(str); - pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 30)); - str = xf86int10Addr(pVbe->pInt10, FARP(pStr)); - block->OemProductRevPtr = strdup(str); - memcpy(&block->Reserved, ((char*)pVbe->memory) + 34, 222); - memcpy(&block->OemData, ((char*)pVbe->memory) + 256, 256); - } - - return block; -} - -void -VBEFreeVBEInfo(VbeInfoBlock *block) -{ - free(block->OEMStringPtr); - free(block->VideoModePtr); - if (((unsigned)block->VESAVersion >> 8) >= 2) { - free(block->OemVendorNamePtr); - free(block->OemProductNamePtr); - free(block->OemProductRevPtr); - } - free(block); -} - -Bool -VBESetVBEMode(vbeInfoPtr pVbe, int mode, VbeCRTCInfoBlock *block) -{ - /* - Input: - AH := 4Fh Super VGA support - AL := 02h Set Super VGA video mode - BX := Video mode - D0-D8 := Mode number - D9-D10 := Reserved (must be 0) - D11 := 0 Use current default refresh rate - := 1 Use user specified CRTC values for refresh rate - D12-13 Reserved for VBE/AF (must be 0) - D14 := 0 Use windowed frame buffer model - := 1 Use linear/flat frame buffer model - D15 := 0 Clear video memory - := 1 Don't clear video memory - ES:DI := Pointer to VbeCRTCInfoBlock structure - - Output: AX = Status - (All other registers are preserved) - */ - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f02; - pVbe->pInt10->bx = mode; - if (block) { - pVbe->pInt10->bx |= 1 << 11; - memcpy(pVbe->memory, block, sizeof(VbeCRTCInfoBlock)); - pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base); - pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base); - } else - pVbe->pInt10->bx &= ~(1 << 11); - - xf86ExecX86int10(pVbe->pInt10); - - return (R16(pVbe->pInt10->ax) == 0x4f); -} - -Bool -VBEGetVBEMode(vbeInfoPtr pVbe, int *mode) -{ - /* - Input: - AH := 4Fh Super VGA support - AL := 03h Return current video mode - - Output: - AX := Status - BX := Current video mode - (All other registers are preserved) - */ - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f03; - - xf86ExecX86int10(pVbe->pInt10); - - if (R16(pVbe->pInt10->ax) == 0x4f) { - *mode = R16(pVbe->pInt10->bx); - - return TRUE; - } - - return FALSE; -} - -VbeModeInfoBlock * -VBEGetModeInfo(vbeInfoPtr pVbe, int mode) -{ - VbeModeInfoBlock *block = NULL; - - memset(pVbe->memory, 0, sizeof(VbeModeInfoBlock)); - - /* - Input: - AH := 4Fh Super VGA support - AL := 01h Return Super VGA mode information - CX := Super VGA video mode - (mode number must be one of those returned by Function 0) - ES:DI := Pointer to buffer - - Output: - AX := status - (All other registers are preserved) - */ - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f01; - pVbe->pInt10->cx = mode; - pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base); - pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base); - xf86ExecX86int10(pVbe->pInt10); - if (R16(pVbe->pInt10->ax) != 0x4f) - return NULL; - - block = malloc(sizeof(VbeModeInfoBlock)); - if (block) - memcpy(block, pVbe->memory, sizeof(*block)); - - return block; -} - -void -VBEFreeModeInfo(VbeModeInfoBlock *block) -{ - free(block); -} - -Bool -VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction function, - pointer *memory, int *size, int *real_mode_pages) -{ - /* - Input: - AH := 4Fh Super VGA support - AL := 04h Save/restore Super VGA video state - DL := 00h Return save/restore state buffer size - CX := Requested states - D0 = Save/restore video hardware state - D1 = Save/restore video BIOS data state - D2 = Save/restore video DAC state - D3 = Save/restore Super VGA state - - Output: - AX = Status - BX = Number of 64-byte blocks to hold the state buffer - (All other registers are preserved) - - - Input: - AH := 4Fh Super VGA support - AL := 04h Save/restore Super VGA video state - DL := 01h Save Super VGA video state - CX := Requested states (see above) - ES:BX := Pointer to buffer - - Output: - AX := Status - (All other registers are preserved) - - - Input: - AH := 4Fh Super VGA support - AL := 04h Save/restore Super VGA video state - DL := 02h Restore Super VGA video state - CX := Requested states (see above) - ES:BX := Pointer to buffer - - Output: - AX := Status - (All other registers are preserved) - */ - - if ((pVbe->version & 0xff00) > 0x100) { - int screen = pVbe->pInt10->scrnIndex; - if (function == MODE_QUERY || - (function == MODE_SAVE && !*memory)) { - /* Query amount of memory to save state */ - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f04; - pVbe->pInt10->dx = 0; - pVbe->pInt10->cx = 0x000f; - xf86ExecX86int10(pVbe->pInt10); - if (R16(pVbe->pInt10->ax) != 0x4f) - return FALSE; - - if (function == MODE_SAVE) { - int npages = (R16(pVbe->pInt10->bx) * 64) / 4096 + 1; - if ((*memory = xf86Int10AllocPages(pVbe->pInt10, npages, - real_mode_pages)) == NULL) { - xf86DrvMsg(screen, X_ERROR, - "Cannot allocate memory to save SVGA state.\n"); - return FALSE; - } - } - *size = pVbe->pInt10->bx * 64; - } - - /* Save/Restore Super VGA state */ - if (function != MODE_QUERY) { - - if (!*memory) return FALSE; - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f04; - switch (function) { - case MODE_SAVE: - pVbe->pInt10->dx = 1; - break; - case MODE_RESTORE: - pVbe->pInt10->dx = 2; - break; - case MODE_QUERY: - return FALSE; - } - pVbe->pInt10->cx = 0x000f; - - pVbe->pInt10->es = SEG_ADDR(*real_mode_pages); - pVbe->pInt10->bx = SEG_OFF(*real_mode_pages); - xf86ExecX86int10(pVbe->pInt10); - return (R16(pVbe->pInt10->ax) == 0x4f); - - } - } - return TRUE; -} - -Bool -VBEBankSwitch(vbeInfoPtr pVbe, unsigned int iBank, int window) -{ - /* - Input: - AH := 4Fh Super VGA support - AL := 05h - - Output: - */ - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f05; - pVbe->pInt10->bx = window; - pVbe->pInt10->dx = iBank; - xf86ExecX86int10(pVbe->pInt10); - - if (R16(pVbe->pInt10->ax) != 0x4f) - return FALSE; - - return TRUE; -} - -Bool -VBESetGetLogicalScanlineLength(vbeInfoPtr pVbe, vbeScanwidthCommand command, - int width, int *pixels, int *bytes, int *max) -{ - if (command < SCANWID_SET || command > SCANWID_GET_MAX) - return FALSE; - - /* - Input: - AX := 4F06h VBE Set/Get Logical Scan Line Length - BL := 00h Set Scan Line Length in Pixels - := 01h Get Scan Line Length - := 02h Set Scan Line Length in Bytes - := 03h Get Maximum Scan Line Length - CX := If BL=00h Desired Width in Pixels - If BL=02h Desired Width in Bytes - (Ignored for Get Functions) - - Output: - AX := VBE Return Status - BX := Bytes Per Scan Line - CX := Actual Pixels Per Scan Line - (truncated to nearest complete pixel) - DX := Maximum Number of Scan Lines - */ - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f06; - pVbe->pInt10->bx = command; - if (command == SCANWID_SET || command == SCANWID_SET_BYTES) - pVbe->pInt10->cx = width; - xf86ExecX86int10(pVbe->pInt10); - - if (R16(pVbe->pInt10->ax) != 0x4f) - return FALSE; - - if (command == SCANWID_GET || command == SCANWID_GET_MAX) { - if (pixels) - *pixels = R16(pVbe->pInt10->cx); - if (bytes) - *bytes = R16(pVbe->pInt10->bx); - if (max) - *max = R16(pVbe->pInt10->dx); - } - - return TRUE; -} - -Bool -VBESetDisplayStart(vbeInfoPtr pVbe, int x, int y, Bool wait_retrace) -{ - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f07; - pVbe->pInt10->bx = wait_retrace ? 0x80 : 0x00; - pVbe->pInt10->cx = x; - pVbe->pInt10->dx = y; - xf86ExecX86int10(pVbe->pInt10); - - if (R16(pVbe->pInt10->ax) != 0x4f) - return FALSE; - - return TRUE; -} - -Bool -VBEGetDisplayStart(vbeInfoPtr pVbe, int *x, int *y) -{ - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f07; - pVbe->pInt10->bx = 0x01; - xf86ExecX86int10(pVbe->pInt10); - - if (R16(pVbe->pInt10->ax) != 0x4f) - return FALSE; - - *x = pVbe->pInt10->cx; - *y = pVbe->pInt10->dx; - - return TRUE; -} - -int -VBESetGetDACPaletteFormat(vbeInfoPtr pVbe, int bits) -{ - /* - Input: - AX := 4F08h VBE Set/Get Palette Format - BL := 00h Set DAC Palette Format - := 01h Get DAC Palette Format - BH := Desired bits of color per primary - (Set DAC Palette Format only) - - Output: - AX := VBE Return Status - BH := Current number of bits of color per primary - */ - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f08; - if (!bits) - pVbe->pInt10->bx = 0x01; - else - pVbe->pInt10->bx = (bits & 0x00ff) << 8; - xf86ExecX86int10(pVbe->pInt10); - - if (R16(pVbe->pInt10->ax) != 0x4f) - return 0; - - return (bits != 0 ? bits : (pVbe->pInt10->bx >> 8) & 0x00ff); -} - -CARD32 * -VBESetGetPaletteData(vbeInfoPtr pVbe, Bool set, int first, int num, - CARD32 *data, Bool secondary, Bool wait_retrace) -{ - /* - Input: - (16-bit) - AX := 4F09h VBE Load/Unload Palette Data - BL := 00h Set Palette Data - := 01h Get Palette Data - := 02h Set Secondary Palette Data - := 03h Get Secondary Palette Data - := 80h Set Palette Data during Vertical Retrace - CX := Number of palette registers to update (to a maximum of 256) - DX := First of the palette registers to update (start) - ES:DI := Table of palette values (see below for format) - - Output: - AX := VBE Return Status - - - Input: - (32-bit) - BL := 00h Set Palette Data - := 80h Set Palette Data during Vertical Retrace - CX := Number of palette registers to update (to a maximum of 256) - DX := First of the palette registers to update (start) - ES:EDI := Table of palette values (see below for format) - DS := Selector for memory mapped registers - */ - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f09; - if (!secondary) - pVbe->pInt10->bx = set && wait_retrace ? 0x80 : set ? 0 : 1; - else - pVbe->pInt10->bx = set ? 2 : 3; - pVbe->pInt10->cx = num; - pVbe->pInt10->dx = first; - pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base); - pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base); - if (set) - memcpy(pVbe->memory, data, num * sizeof(CARD32)); - xf86ExecX86int10(pVbe->pInt10); - - if (R16(pVbe->pInt10->ax) != 0x4f) - return NULL; - - if (set) - return data; - - data = malloc(num * sizeof(CARD32)); - memcpy(data, pVbe->memory, num * sizeof(CARD32)); - - return data; -} - -VBEpmi * -VBEGetVBEpmi(vbeInfoPtr pVbe) -{ - VBEpmi *pmi; - - /* - Input: - AH := 4Fh Super VGA support - AL := 0Ah Protected Mode Interface - BL := 00h Return Protected Mode Table - - Output: - AX := Status - ES := Real Mode Segment of Table - DI := Offset of Table - CX := Lenght of Table including protected mode code in bytes (for copying purposes) - (All other registers are preserved) - */ - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f0a; - pVbe->pInt10->bx = 0; - pVbe->pInt10->di = 0; - xf86ExecX86int10(pVbe->pInt10); - - if (R16(pVbe->pInt10->ax) != 0x4f) - return NULL; - - pmi = malloc(sizeof(VBEpmi)); - pmi->seg_tbl = R16(pVbe->pInt10->es); - pmi->tbl_off = R16(pVbe->pInt10->di); - pmi->tbl_len = R16(pVbe->pInt10->cx); - - return pmi; -} - -#if 0 -vbeModeInfoPtr -VBEBuildVbeModeList(vbeInfoPtr pVbe, VbeInfoBlock *vbe) -{ - vbeModeInfoPtr ModeList = NULL; - - int i = 0; - while (vbe->VideoModePtr[i] != 0xffff) { - vbeModeInfoPtr m; - VbeModeInfoBlock *mode; - int id = vbe->VideoModePtr[i++]; - int bpp; - - if ((mode = VBEGetModeInfo(pVbe, id)) == NULL) - continue; - - bpp = mode->BitsPerPixel; - - m = xnfcalloc(sizeof(vbeModeInfoRec),1); - m->width = mode->XResolution; - m->height = mode->YResolution; - m->bpp = bpp; - m->n = id; - m->next = ModeList; - - xf86DrvMsgVerb(pVbe->pInt10->scrnIndex, X_PROBED, 3, - "BIOS reported VESA mode 0x%x: x:%i y:%i bpp:%i\n", - m->n, m->width, m->height, m->bpp); - - ModeList = m; - - VBEFreeModeInfo(mode); - } - return ModeList; -} - -unsigned short -VBECalcVbeModeIndex(vbeModeInfoPtr m, DisplayModePtr mode, int bpp) -{ - while (m) { - if (bpp == m->bpp - && mode->HDisplay == m->width - && mode->VDisplay == m->height) - return m->n; - m = m->next; - } - return 0; -} -#endif - -void -VBEVesaSaveRestore(vbeInfoPtr pVbe, vbeSaveRestorePtr vbe_sr, - vbeSaveRestoreFunction function) -{ - Bool SaveSucc = FALSE; - - if (VBE_VERSION_MAJOR(pVbe->version) > 1 - && (function == MODE_SAVE || vbe_sr->pstate)) { - if (function == MODE_RESTORE) - memcpy(vbe_sr->state, vbe_sr->pstate, vbe_sr->stateSize); - ErrorF("VBESaveRestore\n"); - if ((VBESaveRestore(pVbe,function, - (pointer)&vbe_sr->state, - &vbe_sr->stateSize,&vbe_sr->statePage))) { - if (function == MODE_SAVE) { - SaveSucc = TRUE; - vbe_sr->stateMode = -1; /* invalidate */ - /* don't rely on the memory not being touched */ - if (vbe_sr->pstate == NULL) - vbe_sr->pstate = malloc(vbe_sr->stateSize); - memcpy(vbe_sr->pstate, vbe_sr->state, vbe_sr->stateSize); - } - ErrorF("VBESaveRestore done with success\n"); - return; - } - ErrorF("VBESaveRestore done\n"); - } - - if (function == MODE_SAVE && !SaveSucc) - (void)VBEGetVBEMode(pVbe, &vbe_sr->stateMode); - - if (function == MODE_RESTORE && vbe_sr->stateMode != -1) - VBESetVBEMode(pVbe, vbe_sr->stateMode, NULL); - -} - -int -VBEGetPixelClock(vbeInfoPtr pVbe, int mode, int clock) -{ - /* - Input: - AX := 4F0Bh VBE Get Pixel Clock - BL := 00h Get Pixel Clock - ECX := pixel clock in units of Hz - DX := mode number - - Output: - AX := VBE Return Status - ECX := Closest pixel clock - */ - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f0b; - pVbe->pInt10->bx = 0x00; - pVbe->pInt10->cx = clock; - pVbe->pInt10->dx = mode; - xf86ExecX86int10(pVbe->pInt10); - - if (R16(pVbe->pInt10->ax) != 0x4f) - return 0; - - return pVbe->pInt10->cx; -} - -Bool -VBEDPMSSet(vbeInfoPtr pVbe, int mode) -{ - /* - Input: - AX := 4F10h DPMS - BL := 01h Set Display Power State - BH := requested power state - - Output: - AX := VBE Return Status - */ - - pVbe->pInt10->num = 0x10; - pVbe->pInt10->ax = 0x4f10; - pVbe->pInt10->bx = 0x01; - switch (mode) { - case DPMSModeOn: - break; - case DPMSModeStandby: - pVbe->pInt10->bx |= 0x100; - break; - case DPMSModeSuspend: - pVbe->pInt10->bx |= 0x200; - break; - case DPMSModeOff: - pVbe->pInt10->bx |= 0x400; - break; - } - xf86ExecX86int10(pVbe->pInt10); - return (R16(pVbe->pInt10->ax) == 0x4f); -} - -void -VBEInterpretPanelID(int scrnIndex, struct vbePanelID *data) -{ - ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; - DisplayModePtr mode; - const float PANEL_HZ = 60.0; - - if (!data) - return; - - xf86DrvMsg(scrnIndex, X_INFO, "PanelID returned panel resolution %dx%d\n", - data->hsize, data->vsize); - - if (pScrn->monitor->nHsync || pScrn->monitor->nVrefresh) - return; - - if (data->hsize < 320 || data->vsize < 240) { - xf86DrvMsg(scrnIndex, X_INFO, "...which I refuse to believe\n"); - return; - } - - mode = xf86CVTMode(data->hsize, data->vsize, PANEL_HZ, 1, 0); - - pScrn->monitor->nHsync = 1; - pScrn->monitor->hsync[0].lo = 31.5; - pScrn->monitor->hsync[0].hi = (float)mode->Clock / (float)mode->HTotal; - pScrn->monitor->nVrefresh = 1; - pScrn->monitor->vrefresh[0].lo = 56.0; - pScrn->monitor->vrefresh[0].hi = - (float)mode->Clock*1000.0 / (float)mode->HTotal / (float)mode->VTotal; - - free(mode); -} - -struct vbePanelID * -VBEReadPanelID(vbeInfoPtr pVbe) -{ - int RealOff = pVbe->real_mode_base; - pointer page = pVbe->memory; - void *tmp = NULL; - int screen = pVbe->pInt10->scrnIndex; - - pVbe->pInt10->ax = 0x4F11; - pVbe->pInt10->bx = 0x01; - pVbe->pInt10->cx = 0; - pVbe->pInt10->dx = 0; - pVbe->pInt10->es = SEG_ADDR(RealOff); - pVbe->pInt10->di = SEG_OFF(RealOff); - pVbe->pInt10->num = 0x10; - - xf86ExecX86int10(pVbe->pInt10); - - if ((pVbe->pInt10->ax & 0xff) != 0x4f) { - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID invalid\n"); - goto error; - } - - switch (pVbe->pInt10->ax & 0xff00) { - case 0x0: - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read successfully\n"); - tmp = xnfalloc(32); - memcpy(tmp, page, 32); - break; - case 0x100: - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read failed\n"); - break; - default: - xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID unknown failure %i\n", - pVbe->pInt10->ax & 0xff00); - break; - } - -error: - return tmp; -} + +/* + * XFree86 vbe module + * Copyright 2000 Egbert Eich + * + * The mode query/save/set/restore functions from the vesa driver + * have been moved here. + * Copyright (c) 2000 by Conectiva S.A. (http://www.conectiva.com) + * Authors: Paulo César Pereira de Andrade + */ + +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#include + +#include "xf86.h" +#include "vbe.h" +#include + +#define VERSION(x) VBE_VERSION_MAJOR(x),VBE_VERSION_MINOR(x) + +#if X_BYTE_ORDER == X_LITTLE_ENDIAN +#define B_O16(x) (x) +#define B_O32(x) (x) +#else +#define B_O16(x) ((((x) & 0xff) << 8) | (((x) & 0xff) >> 8)) +#define B_O32(x) ((((x) & 0xff) << 24) | (((x) & 0xff00) << 8) \ + | (((x) & 0xff0000) >> 8) | (((x) & 0xff000000) >> 24)) +#endif +#define L_ADD(x) (B_O32(x) & 0xffff) + ((B_O32(x) >> 12) & 0xffff00) + +#define FARP(p) (((unsigned)(p & 0xffff0000) >> 12) | (p & 0xffff)) +#define R16(v) ((v) & 0xffff) + +static unsigned char * vbeReadEDID(vbeInfoPtr pVbe); +static Bool vbeProbeDDC(vbeInfoPtr pVbe); + +static const char vbeVersionString[] = "VBE2"; + +vbeInfoPtr +VBEInit(xf86Int10InfoPtr pInt, int entityIndex) +{ + return VBEExtendedInit(pInt, entityIndex, 0); +} + +vbeInfoPtr +VBEExtendedInit(xf86Int10InfoPtr pInt, int entityIndex, int Flags) +{ + int RealOff; + pointer page = NULL; + ScrnInfoPtr pScrn = xf86FindScreenForEntity(entityIndex); + vbeControllerInfoPtr vbe = NULL; + Bool init_int10 = FALSE; + vbeInfoPtr vip = NULL; + int screen; + + if (!pScrn) return NULL; + screen = pScrn->scrnIndex; + + if (!pInt) { + if (!xf86LoadSubModule(pScrn, "int10")) + goto error; + + xf86DrvMsg(screen,X_INFO,"initializing int10\n"); + pInt = xf86ExtendedInitInt10(entityIndex,Flags); + if (!pInt) + goto error; + init_int10 = TRUE; + } + + page = xf86Int10AllocPages(pInt,1,&RealOff); + if (!page) goto error; + vbe = (vbeControllerInfoPtr) page; + memcpy(vbe->VbeSignature,vbeVersionString,4); + + pInt->ax = 0x4F00; + pInt->es = SEG_ADDR(RealOff); + pInt->di = SEG_OFF(RealOff); + pInt->num = 0x10; + + xf86ExecX86int10(pInt); + + if ((pInt->ax & 0xff) != 0x4f) { + xf86DrvMsgVerb(screen,X_INFO,3,"VESA BIOS not detected\n"); + goto error; + } + + switch (pInt->ax & 0xff00) { + case 0: + xf86DrvMsg(screen,X_INFO,"VESA BIOS detected\n"); + break; + case 0x100: + xf86DrvMsg(screen,X_INFO,"VESA BIOS function failed\n"); + goto error; + case 0x200: + xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported\n"); + goto error; + case 0x300: + xf86DrvMsg(screen,X_INFO,"VESA BIOS not supported in current mode\n"); + goto error; + default: + xf86DrvMsg(screen,X_INFO,"Invalid\n"); + goto error; + } + + xf86DrvMsgVerb(screen, X_INFO, 4, + "VbeVersion is %d, OemStringPtr is 0x%08lx,\n" + "\tOemVendorNamePtr is 0x%08lx, OemProductNamePtr is 0x%08lx,\n" + "\tOemProductRevPtr is 0x%08lx\n", + vbe->VbeVersion, (unsigned long)vbe->OemStringPtr, + (unsigned long)vbe->OemVendorNamePtr, + (unsigned long)vbe->OemProductNamePtr, + (unsigned long)vbe->OemProductRevPtr); + + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Version %i.%i\n", + VERSION(vbe->VbeVersion)); + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE Total Mem: %i kB\n", + vbe->TotalMem * 64); + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM: %s\n", + (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemStringPtr))); + + if (B_O16(vbe->VbeVersion) >= 0x200) { + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Software Rev: %i.%i\n", + VERSION(vbe->OemSoftwareRev)); + if (vbe->OemVendorNamePtr) + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Vendor: %s\n", + (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemVendorNamePtr))); + if (vbe->OemProductNamePtr) + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product: %s\n", + (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductNamePtr))); + if (vbe->OemProductRevPtr) + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE OEM Product Rev: %s\n", + (CARD8*)xf86int10Addr(pInt,L_ADD(vbe->OemProductRevPtr))); + } + vip = (vbeInfoPtr)xnfalloc(sizeof(vbeInfoRec)); + vip->version = B_O16(vbe->VbeVersion); + vip->pInt10 = pInt; + vip->ddc = DDC_UNCHECKED; + vip->memory = page; + vip->real_mode_base = RealOff; + vip->num_pages = 1; + vip->init_int10 = init_int10; + + return vip; + + error: + if (page) + xf86Int10FreePages(pInt, page, 1); + if (init_int10) + xf86FreeInt10(pInt); + return NULL; +} + +void +vbeFree(vbeInfoPtr pVbe) +{ + if (!pVbe) + return; + + xf86Int10FreePages(pVbe->pInt10,pVbe->memory,pVbe->num_pages); + /* If we have initalized int10 we ought to free it, too */ + if (pVbe->init_int10) + xf86FreeInt10(pVbe->pInt10); + free(pVbe); + return; +} + +static Bool +vbeProbeDDC(vbeInfoPtr pVbe) +{ + char *ddc_level; + int screen = pVbe->pInt10->scrnIndex; + + if (pVbe->ddc == DDC_NONE) + return FALSE; + if (pVbe->ddc != DDC_UNCHECKED) + return TRUE; + + pVbe->pInt10->ax = 0x4F15; + pVbe->pInt10->bx = 0; + pVbe->pInt10->cx = 0; + pVbe->pInt10->es = 0; + pVbe->pInt10->di = 0; + pVbe->pInt10->num = 0x10; + + xf86ExecX86int10(pVbe->pInt10); + + if ((pVbe->pInt10->ax & 0xff) != 0x4f) { + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC not supported\n"); + pVbe->ddc = DDC_NONE; + return FALSE; + } + + switch ((pVbe->pInt10->ax >> 8) & 0xff) { + case 0: + xf86DrvMsg(screen,X_INFO,"VESA VBE DDC supported\n"); + switch (pVbe->pInt10->bx & 0x3) { + case 0: + ddc_level = " none"; + pVbe->ddc = DDC_NONE; + break; + case 1: + ddc_level = " 1"; + pVbe->ddc = DDC_1; + break; + case 2: + ddc_level = " 2"; + pVbe->ddc = DDC_2; + break; + case 3: + ddc_level = " 1 + 2"; + pVbe->ddc = DDC_1_2; + break; + default: + ddc_level = ""; + pVbe->ddc = DDC_NONE; + break; + } + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Level%s\n",ddc_level); + if (pVbe->pInt10->bx & 0x4) { + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC Screen blanked" + "for data transfer\n"); + pVbe->ddc_blank = TRUE; + } else + pVbe->ddc_blank = FALSE; + + xf86DrvMsgVerb(screen,X_INFO,3, + "VESA VBE DDC transfer in appr. %x sec.\n", + (pVbe->pInt10->bx >> 8) & 0xff); + } + + return TRUE; +} + +typedef enum { + VBEOPT_NOVBE, + VBEOPT_NODDC +} VBEOpts; + +static const OptionInfoRec VBEOptions[] = { + { VBEOPT_NOVBE, "NoVBE", OPTV_BOOLEAN, {0}, FALSE }, + { VBEOPT_NODDC, "NoDDC", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE }, +}; + +static unsigned char * +vbeReadEDID(vbeInfoPtr pVbe) +{ + int RealOff = pVbe->real_mode_base; + pointer page = pVbe->memory; + unsigned char *tmp = NULL; + Bool novbe = FALSE; + Bool noddc = FALSE; + int screen = pVbe->pInt10->scrnIndex; + OptionInfoPtr options; + + if (!page) return NULL; + + options = xnfalloc(sizeof(VBEOptions)); + (void)memcpy(options, VBEOptions, sizeof(VBEOptions)); + xf86ProcessOptions(screen, xf86Screens[screen]->options, options); + xf86GetOptValBool(options, VBEOPT_NOVBE, &novbe); + xf86GetOptValBool(options, VBEOPT_NODDC, &noddc); + free(options); + if (novbe || noddc) return NULL; + + if (!vbeProbeDDC(pVbe)) goto error; + + memset(page,0,sizeof(vbeInfoPtr)); + strcpy(page,vbeVersionString); + + pVbe->pInt10->ax = 0x4F15; + pVbe->pInt10->bx = 0x01; + pVbe->pInt10->cx = 0; + pVbe->pInt10->dx = 0; + pVbe->pInt10->es = SEG_ADDR(RealOff); + pVbe->pInt10->di = SEG_OFF(RealOff); + pVbe->pInt10->num = 0x10; + + xf86ExecX86int10(pVbe->pInt10); + + if ((pVbe->pInt10->ax & 0xff) != 0x4f) { + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC invalid\n"); + goto error; + } + switch (pVbe->pInt10->ax & 0xff00) { + case 0x0: + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read successfully\n"); + tmp = (unsigned char *)xnfalloc(128); + memcpy(tmp,page,128); + break; + case 0x100: + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC read failed\n"); + break; + default: + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE DDC unkown failure %i\n", + pVbe->pInt10->ax & 0xff00); + break; + } + + error: + return tmp; +} + +xf86MonPtr +vbeDoEDID(vbeInfoPtr pVbe, pointer pDDCModule) +{ + xf86MonPtr pMonitor; + pointer pModule; + unsigned char *DDC_data = NULL; + + if (!pVbe) return NULL; + if (pVbe->version < 0x200) + return NULL; + + if (!(pModule = pDDCModule)) { + pModule = + xf86LoadSubModule(xf86Screens[pVbe->pInt10->scrnIndex], "ddc"); + if (!pModule) + return NULL; + } + + DDC_data = vbeReadEDID(pVbe); + + if (!DDC_data) + return NULL; + + pMonitor = xf86InterpretEDID(pVbe->pInt10->scrnIndex, DDC_data); + + if (!pDDCModule) + xf86UnloadSubModule(pModule); + return pMonitor; +} + +#define GET_UNALIGNED2(x) \ + ((*(CARD16*)(x)) | (*(((CARD16*)(x) + 1))) << 16) + +VbeInfoBlock * +VBEGetVBEInfo(vbeInfoPtr pVbe) +{ + VbeInfoBlock *block = NULL; + int i, pStr, pModes; + char *str; + CARD16 major, *modes; + + memset(pVbe->memory, 0, sizeof(VbeInfoBlock)); + + /* + Input: + AH := 4Fh Super VGA support + AL := 00h Return Super VGA information + ES:DI := Pointer to buffer + + Output: + AX := status + (All other registers are preserved) + */ + + ((char*)pVbe->memory)[0] = 'V'; + ((char*)pVbe->memory)[1] = 'B'; + ((char*)pVbe->memory)[2] = 'E'; + ((char*)pVbe->memory)[3] = '2'; + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x4f00; + pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base); + pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base); + xf86ExecX86int10(pVbe->pInt10); + + if (R16(pVbe->pInt10->ax) != 0x4f) + return NULL; + + block = calloc(sizeof(VbeInfoBlock), 1); + block->VESASignature[0] = ((char*)pVbe->memory)[0]; + block->VESASignature[1] = ((char*)pVbe->memory)[1]; + block->VESASignature[2] = ((char*)pVbe->memory)[2]; + block->VESASignature[3] = ((char*)pVbe->memory)[3]; + + block->VESAVersion = *(CARD16*)(((char*)pVbe->memory) + 4); + major = (unsigned)block->VESAVersion >> 8; + + pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 6)); + str = xf86int10Addr(pVbe->pInt10, FARP(pStr)); + block->OEMStringPtr = strdup(str); + + block->Capabilities[0] = ((char*)pVbe->memory)[10]; + block->Capabilities[1] = ((char*)pVbe->memory)[11]; + block->Capabilities[2] = ((char*)pVbe->memory)[12]; + block->Capabilities[3] = ((char*)pVbe->memory)[13]; + + pModes = GET_UNALIGNED2((((char*)pVbe->memory) + 14)); + modes = xf86int10Addr(pVbe->pInt10, FARP(pModes)); + i = 0; + while (modes[i] != 0xffff) + i++; + block->VideoModePtr = malloc(sizeof(CARD16) * (i + 1)); + memcpy(block->VideoModePtr, modes, sizeof(CARD16) * i); + block->VideoModePtr[i] = 0xffff; + + block->TotalMemory = *(CARD16*)(((char*)pVbe->memory) + 18); + + if (major < 2) + memcpy(&block->OemSoftwareRev, ((char*)pVbe->memory) + 20, 236); + else { + block->OemSoftwareRev = *(CARD16*)(((char*)pVbe->memory) + 20); + pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 22)); + str = xf86int10Addr(pVbe->pInt10, FARP(pStr)); + block->OemVendorNamePtr = strdup(str); + pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 26)); + str = xf86int10Addr(pVbe->pInt10, FARP(pStr)); + block->OemProductNamePtr = strdup(str); + pStr = GET_UNALIGNED2((((char*)pVbe->memory) + 30)); + str = xf86int10Addr(pVbe->pInt10, FARP(pStr)); + block->OemProductRevPtr = strdup(str); + memcpy(&block->Reserved, ((char*)pVbe->memory) + 34, 222); + memcpy(&block->OemData, ((char*)pVbe->memory) + 256, 256); + } + + return block; +} + +void +VBEFreeVBEInfo(VbeInfoBlock *block) +{ + free(block->OEMStringPtr); + free(block->VideoModePtr); + if (((unsigned)block->VESAVersion >> 8) >= 2) { + free(block->OemVendorNamePtr); + free(block->OemProductNamePtr); + free(block->OemProductRevPtr); + } + free(block); +} + +Bool +VBESetVBEMode(vbeInfoPtr pVbe, int mode, VbeCRTCInfoBlock *block) +{ + /* + Input: + AH := 4Fh Super VGA support + AL := 02h Set Super VGA video mode + BX := Video mode + D0-D8 := Mode number + D9-D10 := Reserved (must be 0) + D11 := 0 Use current default refresh rate + := 1 Use user specified CRTC values for refresh rate + D12-13 Reserved for VBE/AF (must be 0) + D14 := 0 Use windowed frame buffer model + := 1 Use linear/flat frame buffer model + D15 := 0 Clear video memory + := 1 Don't clear video memory + ES:DI := Pointer to VbeCRTCInfoBlock structure + + Output: AX = Status + (All other registers are preserved) + */ + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x4f02; + pVbe->pInt10->bx = mode; + if (block) { + pVbe->pInt10->bx |= 1 << 11; + memcpy(pVbe->memory, block, sizeof(VbeCRTCInfoBlock)); + pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base); + pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base); + } else + pVbe->pInt10->bx &= ~(1 << 11); + + xf86ExecX86int10(pVbe->pInt10); + + return (R16(pVbe->pInt10->ax) == 0x4f); +} + +Bool +VBEGetVBEMode(vbeInfoPtr pVbe, int *mode) +{ + /* + Input: + AH := 4Fh Super VGA support + AL := 03h Return current video mode + + Output: + AX := Status + BX := Current video mode + (All other registers are preserved) + */ + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x4f03; + + xf86ExecX86int10(pVbe->pInt10); + + if (R16(pVbe->pInt10->ax) == 0x4f) { + *mode = R16(pVbe->pInt10->bx); + + return TRUE; + } + + return FALSE; +} + +VbeModeInfoBlock * +VBEGetModeInfo(vbeInfoPtr pVbe, int mode) +{ + VbeModeInfoBlock *block = NULL; + + memset(pVbe->memory, 0, sizeof(VbeModeInfoBlock)); + + /* + Input: + AH := 4Fh Super VGA support + AL := 01h Return Super VGA mode information + CX := Super VGA video mode + (mode number must be one of those returned by Function 0) + ES:DI := Pointer to buffer + + Output: + AX := status + (All other registers are preserved) + */ + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x4f01; + pVbe->pInt10->cx = mode; + pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base); + pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base); + xf86ExecX86int10(pVbe->pInt10); + if (R16(pVbe->pInt10->ax) != 0x4f) + return NULL; + + block = malloc(sizeof(VbeModeInfoBlock)); + if (block) + memcpy(block, pVbe->memory, sizeof(*block)); + + return block; +} + +void +VBEFreeModeInfo(VbeModeInfoBlock *block) +{ + free(block); +} + +Bool +VBESaveRestore(vbeInfoPtr pVbe, vbeSaveRestoreFunction function, + pointer *memory, int *size, int *real_mode_pages) +{ + /* + Input: + AH := 4Fh Super VGA support + AL := 04h Save/restore Super VGA video state + DL := 00h Return save/restore state buffer size + CX := Requested states + D0 = Save/restore video hardware state + D1 = Save/restore video BIOS data state + D2 = Save/restore video DAC state + D3 = Save/restore Super VGA state + + Output: + AX = Status + BX = Number of 64-byte blocks to hold the state buffer + (All other registers are preserved) + + + Input: + AH := 4Fh Super VGA support + AL := 04h Save/restore Super VGA video state + DL := 01h Save Super VGA video state + CX := Requested states (see above) + ES:BX := Pointer to buffer + + Output: + AX := Status + (All other registers are preserved) + + + Input: + AH := 4Fh Super VGA support + AL := 04h Save/restore Super VGA video state + DL := 02h Restore Super VGA video state + CX := Requested states (see above) + ES:BX := Pointer to buffer + + Output: + AX := Status + (All other registers are preserved) + */ + + if ((pVbe->version & 0xff00) > 0x100) { + int screen = pVbe->pInt10->scrnIndex; + if (function == MODE_QUERY || + (function == MODE_SAVE && !*memory)) { + /* Query amount of memory to save state */ + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x4f04; + pVbe->pInt10->dx = 0; + pVbe->pInt10->cx = 0x000f; + xf86ExecX86int10(pVbe->pInt10); + if (R16(pVbe->pInt10->ax) != 0x4f) + return FALSE; + + if (function == MODE_SAVE) { + int npages = (R16(pVbe->pInt10->bx) * 64) / 4096 + 1; + if ((*memory = xf86Int10AllocPages(pVbe->pInt10, npages, + real_mode_pages)) == NULL) { + xf86DrvMsg(screen, X_ERROR, + "Cannot allocate memory to save SVGA state.\n"); + return FALSE; + } + } + *size = pVbe->pInt10->bx * 64; + } + + /* Save/Restore Super VGA state */ + if (function != MODE_QUERY) { + + if (!*memory) return FALSE; + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x4f04; + switch (function) { + case MODE_SAVE: + pVbe->pInt10->dx = 1; + break; + case MODE_RESTORE: + pVbe->pInt10->dx = 2; + break; + case MODE_QUERY: + return FALSE; + } + pVbe->pInt10->cx = 0x000f; + + pVbe->pInt10->es = SEG_ADDR(*real_mode_pages); + pVbe->pInt10->bx = SEG_OFF(*real_mode_pages); + xf86ExecX86int10(pVbe->pInt10); + return (R16(pVbe->pInt10->ax) == 0x4f); + + } + } + return TRUE; +} + +Bool +VBEBankSwitch(vbeInfoPtr pVbe, unsigned int iBank, int window) +{ + /* + Input: + AH := 4Fh Super VGA support + AL := 05h + + Output: + */ + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x4f05; + pVbe->pInt10->bx = window; + pVbe->pInt10->dx = iBank; + xf86ExecX86int10(pVbe->pInt10); + + if (R16(pVbe->pInt10->ax) != 0x4f) + return FALSE; + + return TRUE; +} + +Bool +VBESetGetLogicalScanlineLength(vbeInfoPtr pVbe, vbeScanwidthCommand command, + int width, int *pixels, int *bytes, int *max) +{ + if (command < SCANWID_SET || command > SCANWID_GET_MAX) + return FALSE; + + /* + Input: + AX := 4F06h VBE Set/Get Logical Scan Line Length + BL := 00h Set Scan Line Length in Pixels + := 01h Get Scan Line Length + := 02h Set Scan Line Length in Bytes + := 03h Get Maximum Scan Line Length + CX := If BL=00h Desired Width in Pixels + If BL=02h Desired Width in Bytes + (Ignored for Get Functions) + + Output: + AX := VBE Return Status + BX := Bytes Per Scan Line + CX := Actual Pixels Per Scan Line + (truncated to nearest complete pixel) + DX := Maximum Number of Scan Lines + */ + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x4f06; + pVbe->pInt10->bx = command; + if (command == SCANWID_SET || command == SCANWID_SET_BYTES) + pVbe->pInt10->cx = width; + xf86ExecX86int10(pVbe->pInt10); + + if (R16(pVbe->pInt10->ax) != 0x4f) + return FALSE; + + if (command == SCANWID_GET || command == SCANWID_GET_MAX) { + if (pixels) + *pixels = R16(pVbe->pInt10->cx); + if (bytes) + *bytes = R16(pVbe->pInt10->bx); + if (max) + *max = R16(pVbe->pInt10->dx); + } + + return TRUE; +} + +Bool +VBESetDisplayStart(vbeInfoPtr pVbe, int x, int y, Bool wait_retrace) +{ + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x4f07; + pVbe->pInt10->bx = wait_retrace ? 0x80 : 0x00; + pVbe->pInt10->cx = x; + pVbe->pInt10->dx = y; + xf86ExecX86int10(pVbe->pInt10); + + if (R16(pVbe->pInt10->ax) != 0x4f) + return FALSE; + + return TRUE; +} + +Bool +VBEGetDisplayStart(vbeInfoPtr pVbe, int *x, int *y) +{ + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x4f07; + pVbe->pInt10->bx = 0x01; + xf86ExecX86int10(pVbe->pInt10); + + if (R16(pVbe->pInt10->ax) != 0x4f) + return FALSE; + + *x = pVbe->pInt10->cx; + *y = pVbe->pInt10->dx; + + return TRUE; +} + +int +VBESetGetDACPaletteFormat(vbeInfoPtr pVbe, int bits) +{ + /* + Input: + AX := 4F08h VBE Set/Get Palette Format + BL := 00h Set DAC Palette Format + := 01h Get DAC Palette Format + BH := Desired bits of color per primary + (Set DAC Palette Format only) + + Output: + AX := VBE Return Status + BH := Current number of bits of color per primary + */ + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x4f08; + if (!bits) + pVbe->pInt10->bx = 0x01; + else + pVbe->pInt10->bx = (bits & 0x00ff) << 8; + xf86ExecX86int10(pVbe->pInt10); + + if (R16(pVbe->pInt10->ax) != 0x4f) + return 0; + + return (bits != 0 ? bits : (pVbe->pInt10->bx >> 8) & 0x00ff); +} + +CARD32 * +VBESetGetPaletteData(vbeInfoPtr pVbe, Bool set, int first, int num, + CARD32 *data, Bool secondary, Bool wait_retrace) +{ + /* + Input: + (16-bit) + AX := 4F09h VBE Load/Unload Palette Data + BL := 00h Set Palette Data + := 01h Get Palette Data + := 02h Set Secondary Palette Data + := 03h Get Secondary Palette Data + := 80h Set Palette Data during Vertical Retrace + CX := Number of palette registers to update (to a maximum of 256) + DX := First of the palette registers to update (start) + ES:DI := Table of palette values (see below for format) + + Output: + AX := VBE Return Status + + + Input: + (32-bit) + BL := 00h Set Palette Data + := 80h Set Palette Data during Vertical Retrace + CX := Number of palette registers to update (to a maximum of 256) + DX := First of the palette registers to update (start) + ES:EDI := Table of palette values (see below for format) + DS := Selector for memory mapped registers + */ + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x4f09; + if (!secondary) + pVbe->pInt10->bx = set && wait_retrace ? 0x80 : set ? 0 : 1; + else + pVbe->pInt10->bx = set ? 2 : 3; + pVbe->pInt10->cx = num; + pVbe->pInt10->dx = first; + pVbe->pInt10->es = SEG_ADDR(pVbe->real_mode_base); + pVbe->pInt10->di = SEG_OFF(pVbe->real_mode_base); + if (set) + memcpy(pVbe->memory, data, num * sizeof(CARD32)); + xf86ExecX86int10(pVbe->pInt10); + + if (R16(pVbe->pInt10->ax) != 0x4f) + return NULL; + + if (set) + return data; + + data = malloc(num * sizeof(CARD32)); + memcpy(data, pVbe->memory, num * sizeof(CARD32)); + + return data; +} + +VBEpmi * +VBEGetVBEpmi(vbeInfoPtr pVbe) +{ + VBEpmi *pmi; + + /* + Input: + AH := 4Fh Super VGA support + AL := 0Ah Protected Mode Interface + BL := 00h Return Protected Mode Table + + Output: + AX := Status + ES := Real Mode Segment of Table + DI := Offset of Table + CX := Lenght of Table including protected mode code in bytes (for copying purposes) + (All other registers are preserved) + */ + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x4f0a; + pVbe->pInt10->bx = 0; + pVbe->pInt10->di = 0; + xf86ExecX86int10(pVbe->pInt10); + + if (R16(pVbe->pInt10->ax) != 0x4f) + return NULL; + + pmi = malloc(sizeof(VBEpmi)); + pmi->seg_tbl = R16(pVbe->pInt10->es); + pmi->tbl_off = R16(pVbe->pInt10->di); + pmi->tbl_len = R16(pVbe->pInt10->cx); + + return pmi; +} + +#if 0 +vbeModeInfoPtr +VBEBuildVbeModeList(vbeInfoPtr pVbe, VbeInfoBlock *vbe) +{ + vbeModeInfoPtr ModeList = NULL; + + int i = 0; + while (vbe->VideoModePtr[i] != 0xffff) { + vbeModeInfoPtr m; + VbeModeInfoBlock *mode; + int id = vbe->VideoModePtr[i++]; + int bpp; + + if ((mode = VBEGetModeInfo(pVbe, id)) == NULL) + continue; + + bpp = mode->BitsPerPixel; + + m = xnfcalloc(sizeof(vbeModeInfoRec),1); + m->width = mode->XResolution; + m->height = mode->YResolution; + m->bpp = bpp; + m->n = id; + m->next = ModeList; + + xf86DrvMsgVerb(pVbe->pInt10->scrnIndex, X_PROBED, 3, + "BIOS reported VESA mode 0x%x: x:%i y:%i bpp:%i\n", + m->n, m->width, m->height, m->bpp); + + ModeList = m; + + VBEFreeModeInfo(mode); + } + return ModeList; +} + +unsigned short +VBECalcVbeModeIndex(vbeModeInfoPtr m, DisplayModePtr mode, int bpp) +{ + while (m) { + if (bpp == m->bpp + && mode->HDisplay == m->width + && mode->VDisplay == m->height) + return m->n; + m = m->next; + } + return 0; +} +#endif + +void +VBEVesaSaveRestore(vbeInfoPtr pVbe, vbeSaveRestorePtr vbe_sr, + vbeSaveRestoreFunction function) +{ + Bool SaveSucc = FALSE; + + if (VBE_VERSION_MAJOR(pVbe->version) > 1 + && (function == MODE_SAVE || vbe_sr->pstate)) { + if (function == MODE_RESTORE) + memcpy(vbe_sr->state, vbe_sr->pstate, vbe_sr->stateSize); + ErrorF("VBESaveRestore\n"); + if ((VBESaveRestore(pVbe,function, + (pointer)&vbe_sr->state, + &vbe_sr->stateSize,&vbe_sr->statePage))) { + if (function == MODE_SAVE) { + SaveSucc = TRUE; + vbe_sr->stateMode = -1; /* invalidate */ + /* don't rely on the memory not being touched */ + if (vbe_sr->pstate == NULL) + vbe_sr->pstate = malloc(vbe_sr->stateSize); + memcpy(vbe_sr->pstate, vbe_sr->state, vbe_sr->stateSize); + } + ErrorF("VBESaveRestore done with success\n"); + return; + } + ErrorF("VBESaveRestore done\n"); + } + + if (function == MODE_SAVE && !SaveSucc) + (void)VBEGetVBEMode(pVbe, &vbe_sr->stateMode); + + if (function == MODE_RESTORE && vbe_sr->stateMode != -1) + VBESetVBEMode(pVbe, vbe_sr->stateMode, NULL); + +} + +int +VBEGetPixelClock(vbeInfoPtr pVbe, int mode, int clock) +{ + /* + Input: + AX := 4F0Bh VBE Get Pixel Clock + BL := 00h Get Pixel Clock + ECX := pixel clock in units of Hz + DX := mode number + + Output: + AX := VBE Return Status + ECX := Closest pixel clock + */ + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x4f0b; + pVbe->pInt10->bx = 0x00; + pVbe->pInt10->cx = clock; + pVbe->pInt10->dx = mode; + xf86ExecX86int10(pVbe->pInt10); + + if (R16(pVbe->pInt10->ax) != 0x4f) + return 0; + + return pVbe->pInt10->cx; +} + +Bool +VBEDPMSSet(vbeInfoPtr pVbe, int mode) +{ + /* + Input: + AX := 4F10h DPMS + BL := 01h Set Display Power State + BH := requested power state + + Output: + AX := VBE Return Status + */ + + pVbe->pInt10->num = 0x10; + pVbe->pInt10->ax = 0x4f10; + pVbe->pInt10->bx = 0x01; + switch (mode) { + case DPMSModeOn: + break; + case DPMSModeStandby: + pVbe->pInt10->bx |= 0x100; + break; + case DPMSModeSuspend: + pVbe->pInt10->bx |= 0x200; + break; + case DPMSModeOff: + pVbe->pInt10->bx |= 0x400; + break; + } + xf86ExecX86int10(pVbe->pInt10); + return (R16(pVbe->pInt10->ax) == 0x4f); +} + +void +VBEInterpretPanelID(int scrnIndex, struct vbePanelID *data) +{ + ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; + DisplayModePtr mode; + const float PANEL_HZ = 60.0; + + if (!data) + return; + + xf86DrvMsg(scrnIndex, X_INFO, "PanelID returned panel resolution %dx%d\n", + data->hsize, data->vsize); + + if (pScrn->monitor->nHsync || pScrn->monitor->nVrefresh) + return; + + if (data->hsize < 320 || data->vsize < 240) { + xf86DrvMsg(scrnIndex, X_INFO, "...which I refuse to believe\n"); + return; + } + + mode = xf86CVTMode(data->hsize, data->vsize, PANEL_HZ, 1, 0); + + pScrn->monitor->nHsync = 1; + pScrn->monitor->hsync[0].lo = 31.5; + pScrn->monitor->hsync[0].hi = (float)mode->Clock / (float)mode->HTotal; + pScrn->monitor->nVrefresh = 1; + pScrn->monitor->vrefresh[0].lo = 56.0; + pScrn->monitor->vrefresh[0].hi = + (float)mode->Clock*1000.0 / (float)mode->HTotal / (float)mode->VTotal; + + free(mode); +} + +struct vbePanelID * +VBEReadPanelID(vbeInfoPtr pVbe) +{ + int RealOff = pVbe->real_mode_base; + pointer page = pVbe->memory; + void *tmp = NULL; + int screen = pVbe->pInt10->scrnIndex; + + pVbe->pInt10->ax = 0x4F11; + pVbe->pInt10->bx = 0x01; + pVbe->pInt10->cx = 0; + pVbe->pInt10->dx = 0; + pVbe->pInt10->es = SEG_ADDR(RealOff); + pVbe->pInt10->di = SEG_OFF(RealOff); + pVbe->pInt10->num = 0x10; + + xf86ExecX86int10(pVbe->pInt10); + + if ((pVbe->pInt10->ax & 0xff) != 0x4f) { + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID invalid\n"); + goto error; + } + + switch (pVbe->pInt10->ax & 0xff00) { + case 0x0: + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read successfully\n"); + tmp = xnfalloc(32); + memcpy(tmp, page, 32); + break; + case 0x100: + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID read failed\n"); + break; + default: + xf86DrvMsgVerb(screen,X_INFO,3,"VESA VBE PanelID unknown failure %i\n", + pVbe->pInt10->ax & 0xff00); + break; + } + +error: + return tmp; +} diff --git a/xorg-server/hw/xfree86/xaa/xaaInit.c b/xorg-server/hw/xfree86/xaa/xaaInit.c index ff1dd3d8b..dcbd5aba0 100644 --- a/xorg-server/hw/xfree86/xaa/xaaInit.c +++ b/xorg-server/hw/xfree86/xaa/xaaInit.c @@ -1,635 +1,635 @@ - -#ifdef HAVE_XORG_CONFIG_H -#include -#endif - -#include "misc.h" -#include "xf86.h" -#include "xf86_OSproc.h" - -#include -#include "scrnintstr.h" -#include "pixmapstr.h" -#include "windowstr.h" -#include "xf86str.h" -#include "mi.h" -#include "miline.h" -#include "xaa.h" -#include "xaalocal.h" -#include "xaawrap.h" -#include "xf86fbman.h" -#include "servermd.h" -#ifdef COMPOSITE -#include "cw.h" -#endif - -#define MAX_PREALLOC_MEM 65536 /* MUST be >= 1024 */ - -#define MIN_OFFPIX_SIZE (320*200) - -static Bool XAACloseScreen(int i, ScreenPtr pScreen); -static void XAAGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, - unsigned int format, unsigned long planemask, - char *pdstLine); -static void XAAGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, - int *pwidth, int nspans, char *pdstStart); -static PixmapPtr XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth, - unsigned usage_hint); -static Bool XAADestroyPixmap(PixmapPtr pPixmap); -static Bool XAAEnterVT (int index, int flags); -static void XAALeaveVT (int index, int flags); -static int XAASetDGAMode(int index, int num, DGADevicePtr devRet); -static void XAAEnableDisableFBAccess (int index, Bool enable); -static Bool XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask); - -static DevPrivateKeyRec XAAScreenKeyRec; -#define XAAScreenKey (&XAAScreenKeyRec) -static DevPrivateKeyRec XAAGCKeyRec; -#define XAAGCKey (&XAAGCKeyRec) -static DevPrivateKeyRec XAAPixmapKeyRec; -#define XAAPixmapKey (&XAAPixmapKeyRec) - -DevPrivateKey XAAGetScreenKey(void) { - return XAAScreenKey; -} - -DevPrivateKey XAAGetGCKey(void) { - return XAAGCKey; -} - -DevPrivateKey XAAGetPixmapKey(void) { - return XAAPixmapKey; -} - -/* temp kludge */ -static Bool SwitchedOut = FALSE; - -XAAInfoRecPtr -XAACreateInfoRec(void) -{ - XAAInfoRecPtr infoRec; - - infoRec = calloc(1, sizeof(XAAInfoRec)); - if(infoRec) - infoRec->CachePixelGranularity = -1; - - return infoRec; -} - -void -XAADestroyInfoRec(XAAInfoRecPtr infoRec) -{ - if(!infoRec) return; - - if(infoRec->ClosePixmapCache) - (*infoRec->ClosePixmapCache)(infoRec->pScrn->pScreen); - - free(infoRec->PreAllocMem); - - free(infoRec->PixmapCachePrivate); - - free(infoRec); -} - - -Bool -XAAInit(ScreenPtr pScreen, XAAInfoRecPtr infoRec) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - XAAScreenPtr pScreenPriv; - int i; - PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); - - /* Return successfully if no acceleration wanted */ - if (!infoRec) - return TRUE; - - if (!dixRegisterPrivateKey(&XAAGCKeyRec, PRIVATE_GC, sizeof(XAAGCRec))) - return FALSE; - - if (!dixRegisterPrivateKey(&XAAPixmapKeyRec, PRIVATE_PIXMAP, sizeof(XAAPixmapRec))) - return FALSE; - - if (!dixRegisterPrivateKey(&XAAScreenKeyRec, PRIVATE_SCREEN, 0)) - return FALSE; - - if (!(pScreenPriv = malloc(sizeof(XAAScreenRec)))) - return FALSE; - - dixSetPrivate(&pScreen->devPrivates, XAAScreenKey, pScreenPriv); - - if(!xf86FBManagerRunning(pScreen)) - infoRec->Flags &= ~(PIXMAP_CACHE | OFFSCREEN_PIXMAPS); - if(!(infoRec->Flags & LINEAR_FRAMEBUFFER)) - infoRec->Flags &= ~OFFSCREEN_PIXMAPS; - - if(!infoRec->FullPlanemask) { /* for backwards compatibility */ - infoRec->FullPlanemask = (1 << pScrn->depth) - 1; - infoRec->FullPlanemasks[pScrn->depth - 1] = infoRec->FullPlanemask; - } - - for(i = 0; i < 32; i++) { - if(!infoRec->FullPlanemasks[i]) /* keep any set by caller */ - infoRec->FullPlanemasks[i] = (1 << (i+1)) - 1; - } - - if(!XAAInitAccel(pScreen, infoRec)) return FALSE; - pScreenPriv->AccelInfoRec = infoRec; - infoRec->ScratchGC.pScreen = pScreen; - - - if(!infoRec->GetImage) - infoRec->GetImage = XAAGetImage; - if(!infoRec->GetSpans) - infoRec->GetSpans = XAAGetSpans; - if(!infoRec->CopyWindow) - infoRec->CopyWindow = XAACopyWindow; - - pScreenPriv->CreateGC = pScreen->CreateGC; - pScreen->CreateGC = XAACreateGC; - pScreenPriv->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = XAACloseScreen; - pScreenPriv->GetImage = pScreen->GetImage; - pScreen->GetImage = infoRec->GetImage; - pScreenPriv->GetSpans = pScreen->GetSpans; - pScreen->GetSpans = infoRec->GetSpans; - pScreenPriv->CopyWindow = pScreen->CopyWindow; - pScreen->CopyWindow = infoRec->CopyWindow; - pScreenPriv->CreatePixmap = pScreen->CreatePixmap; - pScreen->CreatePixmap = XAACreatePixmap; - pScreenPriv->DestroyPixmap = pScreen->DestroyPixmap; - pScreen->DestroyPixmap = XAADestroyPixmap; - pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes; - pScreen->ChangeWindowAttributes = XAAChangeWindowAttributes; - - pScreenPriv->EnterVT = pScrn->EnterVT; - pScrn->EnterVT = XAAEnterVT; - pScreenPriv->LeaveVT = pScrn->LeaveVT; - pScrn->LeaveVT = XAALeaveVT; - pScreenPriv->SetDGAMode = pScrn->SetDGAMode; - pScrn->SetDGAMode = XAASetDGAMode; - pScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess; - pScrn->EnableDisableFBAccess = XAAEnableDisableFBAccess; - - pScreenPriv->WindowExposures = pScreen->WindowExposures; - if (ps) - { - pScreenPriv->Composite = ps->Composite; - ps->Composite = XAAComposite; - pScreenPriv->Glyphs = ps->Glyphs; - ps->Glyphs = XAAGlyphs; - } - if(pScrn->overlayFlags & OVERLAY_8_32_PLANAR) - XAASetupOverlay8_32Planar(pScreen); - - infoRec->PreAllocMem = malloc(MAX_PREALLOC_MEM); - if(infoRec->PreAllocMem) - infoRec->PreAllocSize = MAX_PREALLOC_MEM; - - if(infoRec->Flags & PIXMAP_CACHE) - xf86RegisterFreeBoxCallback(pScreen, infoRec->InitPixmapCache, - (pointer)infoRec); - - if(infoRec->Flags & MICROSOFT_ZERO_LINE_BIAS) - miSetZeroLineBias(pScreen, OCTANT1 | OCTANT2 | OCTANT3 | OCTANT4); - -#ifdef COMPOSITE - /* Initialize the composite wrapper. This needs to happen after the - * wrapping above (so it comes before us), but before all other extensions, - * so it doesn't confuse them. (particularly damage). - */ - miInitializeCompositeWrapper(pScreen); -#endif - - return TRUE; -} - - - -static Bool -XAACloseScreen (int i, ScreenPtr pScreen) -{ - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - XAAScreenPtr pScreenPriv = - (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); - - pScrn->EnterVT = pScreenPriv->EnterVT; - pScrn->LeaveVT = pScreenPriv->LeaveVT; - pScrn->EnableDisableFBAccess = pScreenPriv->EnableDisableFBAccess; - - pScreen->CreateGC = pScreenPriv->CreateGC; - pScreen->CloseScreen = pScreenPriv->CloseScreen; - pScreen->GetImage = pScreenPriv->GetImage; - pScreen->GetSpans = pScreenPriv->GetSpans; - pScreen->CopyWindow = pScreenPriv->CopyWindow; - pScreen->WindowExposures = pScreenPriv->WindowExposures; - pScreen->CreatePixmap = pScreenPriv->CreatePixmap; - pScreen->DestroyPixmap = pScreenPriv->DestroyPixmap; - pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes; - - /* We leave it up to the client to free the XAAInfoRec */ - - free((pointer) pScreenPriv); - - return (*pScreen->CloseScreen) (i, pScreen); -} - -static void -XAAGetImage ( - DrawablePtr pDraw, - int sx, int sy, int w, int h, - unsigned int format, - unsigned long planemask, - char *pdstLine -) -{ - ScreenPtr pScreen = pDraw->pScreen; - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); - ScrnInfoPtr pScrn = infoRec->pScrn; - - if(pScrn->vtSema && - ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) - { - if(infoRec->ReadPixmap && (format == ZPixmap) && - ((planemask & infoRec->FullPlanemasks[pDraw->depth - 1]) == - infoRec->FullPlanemasks[pDraw->depth - 1]) && - (pDraw->bitsPerPixel == BitsPerPixel(pDraw->depth))) - { - (*infoRec->ReadPixmap)(pScrn, - sx + pDraw->x, sy + pDraw->y, w, h, - (unsigned char *)pdstLine, - PixmapBytePad(w, pDraw->depth), - pDraw->bitsPerPixel, pDraw->depth); - return; - } - SYNC_CHECK(pDraw); - } - - XAA_SCREEN_PROLOGUE (pScreen, GetImage); - (*pScreen->GetImage) (pDraw, sx, sy, w, h, format, planemask, pdstLine); - XAA_SCREEN_EPILOGUE (pScreen, GetImage, XAAGetImage); -} - -static void -XAAGetSpans ( - DrawablePtr pDraw, - int wMax, - DDXPointPtr ppt, - int *pwidth, - int nspans, - char *pdstStart -) -{ - ScreenPtr pScreen = pDraw->pScreen; - XAA_SCREEN_PROLOGUE (pScreen, GetSpans); - if(xf86Screens[pScreen->myNum]->vtSema && - ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) { - SYNC_CHECK(pDraw); - } - (*pScreen->GetSpans) (pDraw, wMax, ppt, pwidth, nspans, pdstStart); - XAA_SCREEN_EPILOGUE (pScreen, GetSpans, XAAGetSpans); -} - - -static int -XAAPixmapBPP (ScreenPtr pScreen, int depth) -{ - PixmapPtr pPix; - int bpp; - DestroyPixmapProcPtr destroyPixmap; - - XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap); - pPix = (*pScreen->CreatePixmap) (pScreen, 1, 1, depth, - CREATE_PIXMAP_USAGE_SCRATCH); - XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap); - if (!pPix) - return 0; - bpp = pPix->drawable.bitsPerPixel; - destroyPixmap = pScreen->DestroyPixmap; - XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap); - (*pScreen->DestroyPixmap) (pPix); - XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, destroyPixmap); - return bpp; -} - -static void -XAAInitializeOffscreenDepths (ScreenPtr pScreen) -{ - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - int d, dep; - - infoRec->offscreenDepthsInitialized = TRUE; - infoRec->offscreenDepths = 0; - if (infoRec->Flags & OFFSCREEN_PIXMAPS) { - for (d = 0; d < pScreen->numDepths; d++) { - dep = pScreen->allowedDepths[d].depth; - if (XAAPixmapBPP (pScreen, dep) == pScrn->bitsPerPixel) - infoRec->offscreenDepths |= (1 << (dep - 1)); - } - } -} - -static PixmapPtr -XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned usage_hint) -{ - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - XAAPixmapPtr pPriv; - PixmapPtr pPix = NULL; - int size = w * h; - - if (w > 32767 || h > 32767) - return NullPixmap; - - if (!infoRec->offscreenDepthsInitialized) - XAAInitializeOffscreenDepths (pScreen); - - if(pScrn->vtSema && - (usage_hint != CREATE_PIXMAP_USAGE_GLYPH_PICTURE) && - (infoRec->offscreenDepths & (1 << (depth - 1))) && - (size >= MIN_OFFPIX_SIZE) && !SwitchedOut && - (!infoRec->maxOffPixWidth || (w <= infoRec->maxOffPixWidth)) && - (!infoRec->maxOffPixHeight || (h <= infoRec->maxOffPixHeight)) ) - { - PixmapLinkPtr pLink; - PixmapPtr pScreenPix; - FBAreaPtr area; - int gran = 0; - - switch(pScrn->bitsPerPixel) { - case 24: - case 8: gran = 4; break; - case 16: gran = 2; break; - case 32: gran = 1; break; - default: break; - } - - if(BITMAP_SCANLINE_PAD == 64) - gran *= 2; - - if(!(area = xf86AllocateOffscreenArea(pScreen, w, h, gran, 0, - XAARemoveAreaCallback, NULL))) { - goto BAILOUT; - } - - if(!(pLink = malloc(sizeof(PixmapLink)))) { - xf86FreeOffscreenArea(area); - goto BAILOUT; - } - - XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap); - pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth, usage_hint); - XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap); - - if (!pPix) { - free(pLink); - xf86FreeOffscreenArea(area); - goto BAILOUT; - } - - pScreenPix = (*pScreen->GetScreenPixmap)(pScreen); - - pPriv = XAA_GET_PIXMAP_PRIVATE(pPix); - pPix->drawable.x = area->box.x1; - pPix->drawable.y = area->box.y1; - pPix->drawable.width = w; - pPix->drawable.height = h; - pPix->drawable.bitsPerPixel = pScrn->bitsPerPixel; - pPix->devKind = pScreenPix->devKind; - pPix->devPrivate.ptr = pScreenPix->devPrivate.ptr; - area->devPrivate.ptr = pPix; - - pPriv->flags = OFFSCREEN; - pPriv->offscreenArea = area; - pPriv->freeData = FALSE; - - pLink->next = infoRec->OffscreenPixmaps; - pLink->pPix = pPix; - infoRec->OffscreenPixmaps = pLink; - return pPix; - } -BAILOUT: - XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap); - pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, usage_hint); - XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap); - - if(pPix) { - pPriv = XAA_GET_PIXMAP_PRIVATE(pPix); - pPriv->flags = 0; - pPriv->offscreenArea = NULL; - pPriv->freeData = FALSE; - if(!w || !h) /* either scratch or shared memory */ - pPriv->flags |= SHARED_PIXMAP; - } - - return pPix; -} - -static Bool -XAADestroyPixmap(PixmapPtr pPix) -{ - ScreenPtr pScreen = pPix->drawable.pScreen; - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); - XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix); - Bool ret; - - if(pPix->refcnt == 1) { - if(pPriv->flags & OFFSCREEN) { - if(pPriv->flags & DGA_PIXMAP) - free(pPriv->offscreenArea); - else { - FBAreaPtr area = pPriv->offscreenArea; - PixmapLinkPtr pLink = infoRec->OffscreenPixmaps; - PixmapLinkPtr prev = NULL; - - while(pLink->pPix != pPix) { - prev = pLink; - pLink = pLink->next; - } - - if(prev) prev->next = pLink->next; - else infoRec->OffscreenPixmaps = pLink->next; - - if(!area) area = pLink->area; - - xf86FreeOffscreenArea(area); - pPriv->offscreenArea = NULL; - free(pLink); - } - } - - if(pPriv->freeData) { /* pixmaps that were once in video ram */ - free(pPix->devPrivate.ptr); - pPix->devPrivate.ptr = NULL; - } - } - - XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap); - ret = (*pScreen->DestroyPixmap) (pPix); - XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, XAADestroyPixmap); - - return ret; -} - -static Bool -XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - Bool ret; - - XAA_SCREEN_PROLOGUE (pScreen, ChangeWindowAttributes); - ret = (*pScreen->ChangeWindowAttributes) (pWin, mask); - XAA_SCREEN_EPILOGUE (pScreen, ChangeWindowAttributes, XAAChangeWindowAttributes); - - /* we have to assume that shared memory pixmaps are dirty - because we can't wrap operations on them */ - - if((mask & CWBackPixmap) && (pWin->backgroundState == BackgroundPixmap) && - PIXMAP_IS_SHARED(pWin->background.pixmap)) - { - XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->background.pixmap); - pPixPriv->flags |= DIRTY; - } - if((mask & CWBorderPixmap) && !(pWin->borderIsPixel) && - PIXMAP_IS_SHARED(pWin->border.pixmap)) - { - XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->border.pixmap); - pPixPriv->flags |= DIRTY; - } - - return ret; -} - - - -/* These two aren't really needed for anything */ - -static Bool -XAAEnterVT(int index, int flags) -{ - ScrnInfoPtr pScrn = xf86Screens[index]; - Bool ret; - ScreenPtr pScreen = screenInfo.screens[index]; - XAAScreenPtr pScreenPriv = - (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); - - pScrn->EnterVT = pScreenPriv->EnterVT; - ret = ((*pScreenPriv->EnterVT)(index, flags)); - pScreenPriv->EnterVT = pScrn->EnterVT; - pScrn->EnterVT = XAAEnterVT; - return ret; -} - -static void -XAALeaveVT(int index, int flags) -{ - ScrnInfoPtr pScrn = xf86Screens[index]; - ScreenPtr pScreen = screenInfo.screens[index]; - XAAScreenPtr pScreenPriv = - (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); - XAAInfoRecPtr infoRec = pScreenPriv->AccelInfoRec; - - if(infoRec->NeedToSync) { - (*infoRec->Sync)(infoRec->pScrn); - infoRec->NeedToSync = FALSE; - } - - pScrn->LeaveVT = pScreenPriv->LeaveVT; - (*pScreenPriv->LeaveVT)(index, flags); - pScreenPriv->LeaveVT = pScrn->LeaveVT; - pScrn->LeaveVT = XAALeaveVT; -} - -typedef struct { - Bool UsingPixmapCache; - Bool CanDoColor8x8; - Bool CanDoMono8x8; -} SavedCacheState, *SavedCacheStatePtr; - -static int -XAASetDGAMode(int index, int num, DGADevicePtr devRet) -{ - ScreenPtr pScreen = screenInfo.screens[index]; - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); - XAAScreenPtr pScreenPriv = - (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); - int ret; - - if (!num && infoRec->dgaSaves) { /* restore old pixmap cache state */ - SavedCacheStatePtr state = (SavedCacheStatePtr)infoRec->dgaSaves; - - infoRec->UsingPixmapCache = state->UsingPixmapCache; - infoRec->CanDoColor8x8 = state->CanDoColor8x8; - infoRec->CanDoMono8x8 = state->CanDoMono8x8; - free(infoRec->dgaSaves); - infoRec->dgaSaves = NULL; - } - - ret = (*pScreenPriv->SetDGAMode)(index, num, devRet); - if(ret != Success) return ret; - - if(num && devRet->pPix) { /* accelerate this pixmap */ - XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(devRet->pPix); - FBAreaPtr area; - - if((area = malloc(sizeof(FBArea)))) { - area->pScreen = pScreen; - area->box.x1 = 0; - area->box.x2 = 0; - area->box.y1 = devRet->mode->pixmapWidth; - area->box.y2 = devRet->mode->pixmapHeight; - area->granularity = 0; - area->MoveAreaCallback = 0; - area->RemoveAreaCallback = 0; - area->devPrivate.ptr = 0; - - pixPriv->flags |= OFFSCREEN | DGA_PIXMAP; - pixPriv->offscreenArea = area; - - if(!infoRec->dgaSaves) { /* save pixmap cache state */ - SavedCacheStatePtr state = malloc(sizeof(SavedCacheState)); - - state->UsingPixmapCache = infoRec->UsingPixmapCache; - state->CanDoColor8x8 = infoRec->CanDoColor8x8; - state->CanDoMono8x8 = infoRec->CanDoMono8x8; - infoRec->dgaSaves = (char*)state; - - infoRec->UsingPixmapCache = FALSE; - if(infoRec->PixmapCacheFlags & CACHE_MONO_8x8) - infoRec->CanDoMono8x8 = FALSE; - if(infoRec->PixmapCacheFlags & CACHE_COLOR_8x8) - infoRec->CanDoColor8x8 = FALSE; - } - } - } - - return ret; -} - - - -static void -XAAEnableDisableFBAccess (int index, Bool enable) -{ - ScreenPtr pScreen = screenInfo.screens[index]; - XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); - XAAScreenPtr pScreenPriv = - (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); - - if(!enable) { - if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps)) - XAAMoveOutOffscreenPixmaps(pScreen); - if(infoRec->Flags & PIXMAP_CACHE) - XAAInvalidatePixmapCache(pScreen); - SwitchedOut = TRUE; - } - - (*pScreenPriv->EnableDisableFBAccess)(index, enable); - - if(enable) { - if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps)) - XAAMoveInOffscreenPixmaps(pScreen); - SwitchedOut = FALSE; - } -} + +#ifdef HAVE_XORG_CONFIG_H +#include +#endif + +#include "misc.h" +#include "xf86.h" +#include "xf86_OSproc.h" + +#include +#include "scrnintstr.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "xf86str.h" +#include "mi.h" +#include "miline.h" +#include "xaa.h" +#include "xaalocal.h" +#include "xaawrap.h" +#include "xf86fbman.h" +#include "servermd.h" +#ifdef COMPOSITE +#include "cw.h" +#endif + +#define MAX_PREALLOC_MEM 65536 /* MUST be >= 1024 */ + +#define MIN_OFFPIX_SIZE (320*200) + +static Bool XAACloseScreen(int i, ScreenPtr pScreen); +static void XAAGetImage(DrawablePtr pDrawable, int sx, int sy, int w, int h, + unsigned int format, unsigned long planemask, + char *pdstLine); +static void XAAGetSpans(DrawablePtr pDrawable, int wMax, DDXPointPtr ppt, + int *pwidth, int nspans, char *pdstStart); +static PixmapPtr XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth, + unsigned class); +static Bool XAADestroyPixmap(PixmapPtr pPixmap); +static Bool XAAEnterVT (int index, int flags); +static void XAALeaveVT (int index, int flags); +static int XAASetDGAMode(int index, int num, DGADevicePtr devRet); +static void XAAEnableDisableFBAccess (int index, Bool enable); +static Bool XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask); + +static DevPrivateKeyRec XAAScreenKeyRec; +#define XAAScreenKey (&XAAScreenKeyRec) +static DevPrivateKeyRec XAAGCKeyRec; +#define XAAGCKey (&XAAGCKeyRec) +static DevPrivateKeyRec XAAPixmapKeyRec; +#define XAAPixmapKey (&XAAPixmapKeyRec) + +DevPrivateKey XAAGetScreenKey(void) { + return XAAScreenKey; +} + +DevPrivateKey XAAGetGCKey(void) { + return XAAGCKey; +} + +DevPrivateKey XAAGetPixmapKey(void) { + return XAAPixmapKey; +} + +/* temp kludge */ +static Bool SwitchedOut = FALSE; + +XAAInfoRecPtr +XAACreateInfoRec(void) +{ + XAAInfoRecPtr infoRec; + + infoRec = calloc(1, sizeof(XAAInfoRec)); + if(infoRec) + infoRec->CachePixelGranularity = -1; + + return infoRec; +} + +void +XAADestroyInfoRec(XAAInfoRecPtr infoRec) +{ + if(!infoRec) return; + + if(infoRec->ClosePixmapCache) + (*infoRec->ClosePixmapCache)(infoRec->pScrn->pScreen); + + free(infoRec->PreAllocMem); + + free(infoRec->PixmapCachePrivate); + + free(infoRec); +} + + +Bool +XAAInit(ScreenPtr pScreen, XAAInfoRecPtr infoRec) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XAAScreenPtr pScreenPriv; + int i; + PictureScreenPtr ps = GetPictureScreenIfSet(pScreen); + + /* Return successfully if no acceleration wanted */ + if (!infoRec) + return TRUE; + + if (!dixRegisterPrivateKey(&XAAGCKeyRec, PRIVATE_GC, sizeof(XAAGCRec))) + return FALSE; + + if (!dixRegisterPrivateKey(&XAAPixmapKeyRec, PRIVATE_PIXMAP, sizeof(XAAPixmapRec))) + return FALSE; + + if (!dixRegisterPrivateKey(&XAAScreenKeyRec, PRIVATE_SCREEN, 0)) + return FALSE; + + if (!(pScreenPriv = malloc(sizeof(XAAScreenRec)))) + return FALSE; + + dixSetPrivate(&pScreen->devPrivates, XAAScreenKey, pScreenPriv); + + if(!xf86FBManagerRunning(pScreen)) + infoRec->Flags &= ~(PIXMAP_CACHE | OFFSCREEN_PIXMAPS); + if(!(infoRec->Flags & LINEAR_FRAMEBUFFER)) + infoRec->Flags &= ~OFFSCREEN_PIXMAPS; + + if(!infoRec->FullPlanemask) { /* for backwards compatibility */ + infoRec->FullPlanemask = (1 << pScrn->depth) - 1; + infoRec->FullPlanemasks[pScrn->depth - 1] = infoRec->FullPlanemask; + } + + for(i = 0; i < 32; i++) { + if(!infoRec->FullPlanemasks[i]) /* keep any set by caller */ + infoRec->FullPlanemasks[i] = (1 << (i+1)) - 1; + } + + if(!XAAInitAccel(pScreen, infoRec)) return FALSE; + pScreenPriv->AccelInfoRec = infoRec; + infoRec->ScratchGC.pScreen = pScreen; + + + if(!infoRec->GetImage) + infoRec->GetImage = XAAGetImage; + if(!infoRec->GetSpans) + infoRec->GetSpans = XAAGetSpans; + if(!infoRec->CopyWindow) + infoRec->CopyWindow = XAACopyWindow; + + pScreenPriv->CreateGC = pScreen->CreateGC; + pScreen->CreateGC = XAACreateGC; + pScreenPriv->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = XAACloseScreen; + pScreenPriv->GetImage = pScreen->GetImage; + pScreen->GetImage = infoRec->GetImage; + pScreenPriv->GetSpans = pScreen->GetSpans; + pScreen->GetSpans = infoRec->GetSpans; + pScreenPriv->CopyWindow = pScreen->CopyWindow; + pScreen->CopyWindow = infoRec->CopyWindow; + pScreenPriv->CreatePixmap = pScreen->CreatePixmap; + pScreen->CreatePixmap = XAACreatePixmap; + pScreenPriv->DestroyPixmap = pScreen->DestroyPixmap; + pScreen->DestroyPixmap = XAADestroyPixmap; + pScreenPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes; + pScreen->ChangeWindowAttributes = XAAChangeWindowAttributes; + + pScreenPriv->EnterVT = pScrn->EnterVT; + pScrn->EnterVT = XAAEnterVT; + pScreenPriv->LeaveVT = pScrn->LeaveVT; + pScrn->LeaveVT = XAALeaveVT; + pScreenPriv->SetDGAMode = pScrn->SetDGAMode; + pScrn->SetDGAMode = XAASetDGAMode; + pScreenPriv->EnableDisableFBAccess = pScrn->EnableDisableFBAccess; + pScrn->EnableDisableFBAccess = XAAEnableDisableFBAccess; + + pScreenPriv->WindowExposures = pScreen->WindowExposures; + if (ps) + { + pScreenPriv->Composite = ps->Composite; + ps->Composite = XAAComposite; + pScreenPriv->Glyphs = ps->Glyphs; + ps->Glyphs = XAAGlyphs; + } + if(pScrn->overlayFlags & OVERLAY_8_32_PLANAR) + XAASetupOverlay8_32Planar(pScreen); + + infoRec->PreAllocMem = malloc(MAX_PREALLOC_MEM); + if(infoRec->PreAllocMem) + infoRec->PreAllocSize = MAX_PREALLOC_MEM; + + if(infoRec->Flags & PIXMAP_CACHE) + xf86RegisterFreeBoxCallback(pScreen, infoRec->InitPixmapCache, + (pointer)infoRec); + + if(infoRec->Flags & MICROSOFT_ZERO_LINE_BIAS) + miSetZeroLineBias(pScreen, OCTANT1 | OCTANT2 | OCTANT3 | OCTANT4); + +#ifdef COMPOSITE + /* Initialize the composite wrapper. This needs to happen after the + * wrapping above (so it comes before us), but before all other extensions, + * so it doesn't confuse them. (particularly damage). + */ + miInitializeCompositeWrapper(pScreen); +#endif + + return TRUE; +} + + + +static Bool +XAACloseScreen (int i, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XAAScreenPtr pScreenPriv = + (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); + + pScrn->EnterVT = pScreenPriv->EnterVT; + pScrn->LeaveVT = pScreenPriv->LeaveVT; + pScrn->EnableDisableFBAccess = pScreenPriv->EnableDisableFBAccess; + + pScreen->CreateGC = pScreenPriv->CreateGC; + pScreen->CloseScreen = pScreenPriv->CloseScreen; + pScreen->GetImage = pScreenPriv->GetImage; + pScreen->GetSpans = pScreenPriv->GetSpans; + pScreen->CopyWindow = pScreenPriv->CopyWindow; + pScreen->WindowExposures = pScreenPriv->WindowExposures; + pScreen->CreatePixmap = pScreenPriv->CreatePixmap; + pScreen->DestroyPixmap = pScreenPriv->DestroyPixmap; + pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes; + + /* We leave it up to the client to free the XAAInfoRec */ + + free((pointer) pScreenPriv); + + return (*pScreen->CloseScreen) (i, pScreen); +} + +static void +XAAGetImage ( + DrawablePtr pDraw, + int sx, int sy, int w, int h, + unsigned int format, + unsigned long planemask, + char *pdstLine +) +{ + ScreenPtr pScreen = pDraw->pScreen; + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); + ScrnInfoPtr pScrn = infoRec->pScrn; + + if(pScrn->vtSema && + ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) + { + if(infoRec->ReadPixmap && (format == ZPixmap) && + ((planemask & infoRec->FullPlanemasks[pDraw->depth - 1]) == + infoRec->FullPlanemasks[pDraw->depth - 1]) && + (pDraw->bitsPerPixel == BitsPerPixel(pDraw->depth))) + { + (*infoRec->ReadPixmap)(pScrn, + sx + pDraw->x, sy + pDraw->y, w, h, + (unsigned char *)pdstLine, + PixmapBytePad(w, pDraw->depth), + pDraw->bitsPerPixel, pDraw->depth); + return; + } + SYNC_CHECK(pDraw); + } + + XAA_SCREEN_PROLOGUE (pScreen, GetImage); + (*pScreen->GetImage) (pDraw, sx, sy, w, h, format, planemask, pdstLine); + XAA_SCREEN_EPILOGUE (pScreen, GetImage, XAAGetImage); +} + +static void +XAAGetSpans ( + DrawablePtr pDraw, + int wMax, + DDXPointPtr ppt, + int *pwidth, + int nspans, + char *pdstStart +) +{ + ScreenPtr pScreen = pDraw->pScreen; + XAA_SCREEN_PROLOGUE (pScreen, GetSpans); + if(xf86Screens[pScreen->myNum]->vtSema && + ((pDraw->type == DRAWABLE_WINDOW) || IS_OFFSCREEN_PIXMAP(pDraw))) { + SYNC_CHECK(pDraw); + } + (*pScreen->GetSpans) (pDraw, wMax, ppt, pwidth, nspans, pdstStart); + XAA_SCREEN_EPILOGUE (pScreen, GetSpans, XAAGetSpans); +} + + +static int +XAAPixmapBPP (ScreenPtr pScreen, int depth) +{ + PixmapPtr pPix; + int bpp; + DestroyPixmapProcPtr destroyPixmap; + + XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap); + pPix = (*pScreen->CreatePixmap) (pScreen, 1, 1, depth, + CREATE_PIXMAP_USAGE_SCRATCH); + XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap); + if (!pPix) + return 0; + bpp = pPix->drawable.bitsPerPixel; + destroyPixmap = pScreen->DestroyPixmap; + XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap); + (*pScreen->DestroyPixmap) (pPix); + XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, destroyPixmap); + return bpp; +} + +static void +XAAInitializeOffscreenDepths (ScreenPtr pScreen) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + int d, dep; + + infoRec->offscreenDepthsInitialized = TRUE; + infoRec->offscreenDepths = 0; + if (infoRec->Flags & OFFSCREEN_PIXMAPS) { + for (d = 0; d < pScreen->numDepths; d++) { + dep = pScreen->allowedDepths[d].depth; + if (XAAPixmapBPP (pScreen, dep) == pScrn->bitsPerPixel) + infoRec->offscreenDepths |= (1 << (dep - 1)); + } + } +} + +static PixmapPtr +XAACreatePixmap(ScreenPtr pScreen, int w, int h, int depth, unsigned class) +{ + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + XAAPixmapPtr pPriv; + PixmapPtr pPix = NULL; + int size = w * h; + + if (w > 32767 || h > 32767) + return NullPixmap; + + if (!infoRec->offscreenDepthsInitialized) + XAAInitializeOffscreenDepths (pScreen); + + if(pScrn->vtSema && + (class != CREATE_PIXMAP_USAGE_GLYPH_PICTURE) && + (infoRec->offscreenDepths & (1 << (depth - 1))) && + (size >= MIN_OFFPIX_SIZE) && !SwitchedOut && + (!infoRec->maxOffPixWidth || (w <= infoRec->maxOffPixWidth)) && + (!infoRec->maxOffPixHeight || (h <= infoRec->maxOffPixHeight)) ) + { + PixmapLinkPtr pLink; + PixmapPtr pScreenPix; + FBAreaPtr area; + int gran = 0; + + switch(pScrn->bitsPerPixel) { + case 24: + case 8: gran = 4; break; + case 16: gran = 2; break; + case 32: gran = 1; break; + default: break; + } + + if(BITMAP_SCANLINE_PAD == 64) + gran *= 2; + + if(!(area = xf86AllocateOffscreenArea(pScreen, w, h, gran, 0, + XAARemoveAreaCallback, NULL))) { + goto BAILOUT; + } + + if(!(pLink = malloc(sizeof(PixmapLink)))) { + xf86FreeOffscreenArea(area); + goto BAILOUT; + } + + XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap); + pPix = (*pScreen->CreatePixmap) (pScreen, 0, 0, depth, class); + XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap); + + if (!pPix) { + free(pLink); + xf86FreeOffscreenArea(area); + goto BAILOUT; + } + + pScreenPix = (*pScreen->GetScreenPixmap)(pScreen); + + pPriv = XAA_GET_PIXMAP_PRIVATE(pPix); + pPix->drawable.x = area->box.x1; + pPix->drawable.y = area->box.y1; + pPix->drawable.width = w; + pPix->drawable.height = h; + pPix->drawable.bitsPerPixel = pScrn->bitsPerPixel; + pPix->devKind = pScreenPix->devKind; + pPix->devPrivate.ptr = pScreenPix->devPrivate.ptr; + area->devPrivate.ptr = pPix; + + pPriv->flags = OFFSCREEN; + pPriv->offscreenArea = area; + pPriv->freeData = FALSE; + + pLink->next = infoRec->OffscreenPixmaps; + pLink->pPix = pPix; + infoRec->OffscreenPixmaps = pLink; + return pPix; + } +BAILOUT: + XAA_SCREEN_PROLOGUE (pScreen, CreatePixmap); + pPix = (*pScreen->CreatePixmap) (pScreen, w, h, depth, class); + XAA_SCREEN_EPILOGUE (pScreen, CreatePixmap, XAACreatePixmap); + + if(pPix) { + pPriv = XAA_GET_PIXMAP_PRIVATE(pPix); + pPriv->flags = 0; + pPriv->offscreenArea = NULL; + pPriv->freeData = FALSE; + if(!w || !h) /* either scratch or shared memory */ + pPriv->flags |= SHARED_PIXMAP; + } + + return pPix; +} + +static Bool +XAADestroyPixmap(PixmapPtr pPix) +{ + ScreenPtr pScreen = pPix->drawable.pScreen; + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); + XAAPixmapPtr pPriv = XAA_GET_PIXMAP_PRIVATE(pPix); + Bool ret; + + if(pPix->refcnt == 1) { + if(pPriv->flags & OFFSCREEN) { + if(pPriv->flags & DGA_PIXMAP) + free(pPriv->offscreenArea); + else { + FBAreaPtr area = pPriv->offscreenArea; + PixmapLinkPtr pLink = infoRec->OffscreenPixmaps; + PixmapLinkPtr prev = NULL; + + while(pLink->pPix != pPix) { + prev = pLink; + pLink = pLink->next; + } + + if(prev) prev->next = pLink->next; + else infoRec->OffscreenPixmaps = pLink->next; + + if(!area) area = pLink->area; + + xf86FreeOffscreenArea(area); + pPriv->offscreenArea = NULL; + free(pLink); + } + } + + if(pPriv->freeData) { /* pixmaps that were once in video ram */ + free(pPix->devPrivate.ptr); + pPix->devPrivate.ptr = NULL; + } + } + + XAA_SCREEN_PROLOGUE (pScreen, DestroyPixmap); + ret = (*pScreen->DestroyPixmap) (pPix); + XAA_SCREEN_EPILOGUE (pScreen, DestroyPixmap, XAADestroyPixmap); + + return ret; +} + +static Bool +XAAChangeWindowAttributes (WindowPtr pWin, unsigned long mask) +{ + ScreenPtr pScreen = pWin->drawable.pScreen; + Bool ret; + + XAA_SCREEN_PROLOGUE (pScreen, ChangeWindowAttributes); + ret = (*pScreen->ChangeWindowAttributes) (pWin, mask); + XAA_SCREEN_EPILOGUE (pScreen, ChangeWindowAttributes, XAAChangeWindowAttributes); + + /* we have to assume that shared memory pixmaps are dirty + because we can't wrap operations on them */ + + if((mask & CWBackPixmap) && (pWin->backgroundState == BackgroundPixmap) && + PIXMAP_IS_SHARED(pWin->background.pixmap)) + { + XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->background.pixmap); + pPixPriv->flags |= DIRTY; + } + if((mask & CWBorderPixmap) && !(pWin->borderIsPixel) && + PIXMAP_IS_SHARED(pWin->border.pixmap)) + { + XAAPixmapPtr pPixPriv = XAA_GET_PIXMAP_PRIVATE(pWin->border.pixmap); + pPixPriv->flags |= DIRTY; + } + + return ret; +} + + + +/* These two aren't really needed for anything */ + +static Bool +XAAEnterVT(int index, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[index]; + Bool ret; + ScreenPtr pScreen = screenInfo.screens[index]; + XAAScreenPtr pScreenPriv = + (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); + + pScrn->EnterVT = pScreenPriv->EnterVT; + ret = ((*pScreenPriv->EnterVT)(index, flags)); + pScreenPriv->EnterVT = pScrn->EnterVT; + pScrn->EnterVT = XAAEnterVT; + return ret; +} + +static void +XAALeaveVT(int index, int flags) +{ + ScrnInfoPtr pScrn = xf86Screens[index]; + ScreenPtr pScreen = screenInfo.screens[index]; + XAAScreenPtr pScreenPriv = + (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); + XAAInfoRecPtr infoRec = pScreenPriv->AccelInfoRec; + + if(infoRec->NeedToSync) { + (*infoRec->Sync)(infoRec->pScrn); + infoRec->NeedToSync = FALSE; + } + + pScrn->LeaveVT = pScreenPriv->LeaveVT; + (*pScreenPriv->LeaveVT)(index, flags); + pScreenPriv->LeaveVT = pScrn->LeaveVT; + pScrn->LeaveVT = XAALeaveVT; +} + +typedef struct { + Bool UsingPixmapCache; + Bool CanDoColor8x8; + Bool CanDoMono8x8; +} SavedCacheState, *SavedCacheStatePtr; + +static int +XAASetDGAMode(int index, int num, DGADevicePtr devRet) +{ + ScreenPtr pScreen = screenInfo.screens[index]; + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); + XAAScreenPtr pScreenPriv = + (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); + int ret; + + if (!num && infoRec->dgaSaves) { /* restore old pixmap cache state */ + SavedCacheStatePtr state = (SavedCacheStatePtr)infoRec->dgaSaves; + + infoRec->UsingPixmapCache = state->UsingPixmapCache; + infoRec->CanDoColor8x8 = state->CanDoColor8x8; + infoRec->CanDoMono8x8 = state->CanDoMono8x8; + free(infoRec->dgaSaves); + infoRec->dgaSaves = NULL; + } + + ret = (*pScreenPriv->SetDGAMode)(index, num, devRet); + if(ret != Success) return ret; + + if(num && devRet->pPix) { /* accelerate this pixmap */ + XAAPixmapPtr pixPriv = XAA_GET_PIXMAP_PRIVATE(devRet->pPix); + FBAreaPtr area; + + if((area = malloc(sizeof(FBArea)))) { + area->pScreen = pScreen; + area->box.x1 = 0; + area->box.x2 = 0; + area->box.y1 = devRet->mode->pixmapWidth; + area->box.y2 = devRet->mode->pixmapHeight; + area->granularity = 0; + area->MoveAreaCallback = 0; + area->RemoveAreaCallback = 0; + area->devPrivate.ptr = 0; + + pixPriv->flags |= OFFSCREEN | DGA_PIXMAP; + pixPriv->offscreenArea = area; + + if(!infoRec->dgaSaves) { /* save pixmap cache state */ + SavedCacheStatePtr state = malloc(sizeof(SavedCacheState)); + + state->UsingPixmapCache = infoRec->UsingPixmapCache; + state->CanDoColor8x8 = infoRec->CanDoColor8x8; + state->CanDoMono8x8 = infoRec->CanDoMono8x8; + infoRec->dgaSaves = (char*)state; + + infoRec->UsingPixmapCache = FALSE; + if(infoRec->PixmapCacheFlags & CACHE_MONO_8x8) + infoRec->CanDoMono8x8 = FALSE; + if(infoRec->PixmapCacheFlags & CACHE_COLOR_8x8) + infoRec->CanDoColor8x8 = FALSE; + } + } + } + + return ret; +} + + + +static void +XAAEnableDisableFBAccess (int index, Bool enable) +{ + ScreenPtr pScreen = screenInfo.screens[index]; + XAAInfoRecPtr infoRec = GET_XAAINFORECPTR_FROM_SCREEN(pScreen); + XAAScreenPtr pScreenPriv = + (XAAScreenPtr)dixLookupPrivate(&pScreen->devPrivates, XAAScreenKey); + + if(!enable) { + if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps)) + XAAMoveOutOffscreenPixmaps(pScreen); + if(infoRec->Flags & PIXMAP_CACHE) + XAAInvalidatePixmapCache(pScreen); + SwitchedOut = TRUE; + } + + (*pScreenPriv->EnableDisableFBAccess)(index, enable); + + if(enable) { + if((infoRec->Flags & OFFSCREEN_PIXMAPS) && (infoRec->OffscreenPixmaps)) + XAAMoveInOffscreenPixmaps(pScreen); + SwitchedOut = FALSE; + } +} diff --git a/xorg-server/hw/xnest/Pixmap.c b/xorg-server/hw/xnest/Pixmap.c index da81a1d06..c901db19f 100644 --- a/xorg-server/hw/xnest/Pixmap.c +++ b/xorg-server/hw/xnest/Pixmap.c @@ -1,137 +1,136 @@ -/* - -Copyright 1993 by Davor Matic - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation. Davor Matic makes no representations about -the suitability of this software for any purpose. It is provided "as -is" without express or implied warranty. - -*/ - -#ifdef HAVE_XNEST_CONFIG_H -#include -#endif - -#include -#include -#include "regionstr.h" -#include "pixmapstr.h" -#include "scrnintstr.h" -#include "regionstr.h" -#include "gc.h" -#include "servermd.h" -#include "privates.h" -#include "mi.h" - -#include "Xnest.h" - -#include "Display.h" -#include "Screen.h" -#include "XNPixmap.h" - -DevPrivateKeyRec xnestPixmapPrivateKeyRec; - -PixmapPtr -xnestCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, - unsigned usage_hint) -{ - PixmapPtr pPixmap; - - pPixmap = AllocatePixmap(pScreen, 0); - if (!pPixmap) - return NullPixmap; - pPixmap->drawable.type = DRAWABLE_PIXMAP; - pPixmap->drawable.class = 0; - pPixmap->drawable.depth = depth; - pPixmap->drawable.bitsPerPixel = depth; - pPixmap->drawable.id = 0; - pPixmap->drawable.x = 0; - pPixmap->drawable.y = 0; - pPixmap->drawable.width = width; - pPixmap->drawable.height = height; - pPixmap->drawable.pScreen = pScreen; - pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; - pPixmap->refcnt = 1; - pPixmap->devKind = PixmapBytePad(width, depth); - pPixmap->usage_hint = usage_hint; - if (width && height) - xnestPixmapPriv(pPixmap)->pixmap = - XCreatePixmap(xnestDisplay, - xnestDefaultWindows[pScreen->myNum], - width, height, depth); - else - xnestPixmapPriv(pPixmap)->pixmap = 0; - - return pPixmap; -} - -Bool -xnestDestroyPixmap(PixmapPtr pPixmap) -{ - if(--pPixmap->refcnt) - return TRUE; - XFreePixmap(xnestDisplay, xnestPixmap(pPixmap)); - FreePixmap(pPixmap); - return TRUE; -} - -RegionPtr -xnestPixmapToRegion(PixmapPtr pPixmap) -{ - XImage *ximage; - register RegionPtr pReg, pTmpReg; - register int x, y; - unsigned long previousPixel, currentPixel; - BoxRec Box = { 0, 0, 0, 0 }; - Bool overlap; - - ximage = XGetImage(xnestDisplay, xnestPixmap(pPixmap), 0, 0, - pPixmap->drawable.width, pPixmap->drawable.height, - 1, XYPixmap); - - pReg = RegionCreate(NULL, 1); - pTmpReg = RegionCreate(NULL, 1); - if(!pReg || !pTmpReg) { - XDestroyImage(ximage); - return NullRegion; - } - - for (y = 0; y < pPixmap->drawable.height; y++) { - Box.y1 = y; - Box.y2 = y + 1; - previousPixel = 0L; - for (x = 0; x < pPixmap->drawable.width; x++) { - currentPixel = XGetPixel(ximage, x, y); - if (previousPixel != currentPixel) { - if (previousPixel == 0L) { - /* left edge */ - Box.x1 = x; - } - else if (currentPixel == 0L) { - /* right edge */ - Box.x2 = x; - RegionReset(pTmpReg, &Box); - RegionAppend(pReg, pTmpReg); - } - previousPixel = currentPixel; - } - } - if (previousPixel != 0L) { - /* right edge because of the end of pixmap */ - Box.x2 = pPixmap->drawable.width; - RegionReset(pTmpReg, &Box); - RegionAppend(pReg, pTmpReg); - } - } - - RegionDestroy(pTmpReg); - XDestroyImage(ximage); - - RegionValidate(pReg, &overlap); - - return pReg; -} +/* + +Copyright 1993 by Davor Matic + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation. Davor Matic makes no representations about +the suitability of this software for any purpose. It is provided "as +is" without express or implied warranty. + +*/ + +#ifdef HAVE_XNEST_CONFIG_H +#include +#endif + +#include +#include +#include "regionstr.h" +#include "pixmapstr.h" +#include "scrnintstr.h" +#include "regionstr.h" +#include "gc.h" +#include "servermd.h" +#include "privates.h" +#include "mi.h" + +#include "Xnest.h" + +#include "Display.h" +#include "Screen.h" +#include "XNPixmap.h" + +DevPrivateKeyRec xnestPixmapPrivateKeyRec; + +PixmapPtr +xnestCreatePixmap(ScreenPtr pScreen, int width, int height, int depth, + unsigned class) +{ + PixmapPtr pPixmap; + + pPixmap = AllocatePixmap(pScreen, 0); + if (!pPixmap) + return NullPixmap; + pPixmap->drawable.type = DRAWABLE_PIXMAP; + pPixmap->drawable.class = class; + pPixmap->drawable.depth = depth; + pPixmap->drawable.bitsPerPixel = depth; + pPixmap->drawable.id = 0; + pPixmap->drawable.x = 0; + pPixmap->drawable.y = 0; + pPixmap->drawable.width = width; + pPixmap->drawable.height = height; + pPixmap->drawable.pScreen = pScreen; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pPixmap->refcnt = 1; + pPixmap->devKind = PixmapBytePad(width, depth); + if (width && height) + xnestPixmapPriv(pPixmap)->pixmap = + XCreatePixmap(xnestDisplay, + xnestDefaultWindows[pScreen->myNum], + width, height, depth); + else + xnestPixmapPriv(pPixmap)->pixmap = 0; + + return pPixmap; +} + +Bool +xnestDestroyPixmap(PixmapPtr pPixmap) +{ + if(--pPixmap->refcnt) + return TRUE; + XFreePixmap(xnestDisplay, xnestPixmap(pPixmap)); + FreePixmap(pPixmap); + return TRUE; +} + +RegionPtr +xnestPixmapToRegion(PixmapPtr pPixmap) +{ + XImage *ximage; + register RegionPtr pReg, pTmpReg; + register int x, y; + unsigned long previousPixel, currentPixel; + BoxRec Box = { 0, 0, 0, 0 }; + Bool overlap; + + ximage = XGetImage(xnestDisplay, xnestPixmap(pPixmap), 0, 0, + pPixmap->drawable.width, pPixmap->drawable.height, + 1, XYPixmap); + + pReg = RegionCreate(NULL, 1); + pTmpReg = RegionCreate(NULL, 1); + if(!pReg || !pTmpReg) { + XDestroyImage(ximage); + return NullRegion; + } + + for (y = 0; y < pPixmap->drawable.height; y++) { + Box.y1 = y; + Box.y2 = y + 1; + previousPixel = 0L; + for (x = 0; x < pPixmap->drawable.width; x++) { + currentPixel = XGetPixel(ximage, x, y); + if (previousPixel != currentPixel) { + if (previousPixel == 0L) { + /* left edge */ + Box.x1 = x; + } + else if (currentPixel == 0L) { + /* right edge */ + Box.x2 = x; + RegionReset(pTmpReg, &Box); + RegionAppend(pReg, pTmpReg); + } + previousPixel = currentPixel; + } + } + if (previousPixel != 0L) { + /* right edge because of the end of pixmap */ + Box.x2 = pPixmap->drawable.width; + RegionReset(pTmpReg, &Box); + RegionAppend(pReg, pTmpReg); + } + } + + RegionDestroy(pTmpReg); + XDestroyImage(ximage); + + RegionValidate(pReg, &overlap); + + return pReg; +} diff --git a/xorg-server/hw/xnest/XNPixmap.h b/xorg-server/hw/xnest/XNPixmap.h index 0d7c6b61e..638a43a1a 100644 --- a/xorg-server/hw/xnest/XNPixmap.h +++ b/xorg-server/hw/xnest/XNPixmap.h @@ -1,37 +1,37 @@ -/* - -Copyright 1993 by Davor Matic - -Permission to use, copy, modify, distribute, and sell this software -and its documentation for any purpose is hereby granted without fee, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation. Davor Matic makes no representations about -the suitability of this software for any purpose. It is provided "as -is" without express or implied warranty. - -*/ - -#ifndef XNESTPIXMAP_H -#define XNESTPIXMAP_H - -extern DevPrivateKeyRec xnestPixmapPrivateKeyRec; -#define xnestPixmapPrivateKey (&xnestPixmapPrivateKeyRec) - -typedef struct { - Pixmap pixmap; -} xnestPrivPixmap; - -#define xnestPixmapPriv(pPixmap) ((xnestPrivPixmap *) \ - dixLookupPrivate(&(pPixmap)->devPrivates, xnestPixmapPrivateKey)) - -#define xnestPixmap(pPixmap) (xnestPixmapPriv(pPixmap)->pixmap) - -#define xnestSharePixmap(pPixmap) ((pPixmap)->refcnt++) - -PixmapPtr xnestCreatePixmap(ScreenPtr pScreen, int width, int height, - int depth, unsigned usage_hint); -Bool xnestDestroyPixmap(PixmapPtr pPixmap); -RegionPtr xnestPixmapToRegion(PixmapPtr pPixmap); - -#endif /* XNESTPIXMAP_H */ +/* + +Copyright 1993 by Davor Matic + +Permission to use, copy, modify, distribute, and sell this software +and its documentation for any purpose is hereby granted without fee, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation. Davor Matic makes no representations about +the suitability of this software for any purpose. It is provided "as +is" without express or implied warranty. + +*/ + +#ifndef XNESTPIXMAP_H +#define XNESTPIXMAP_H + +extern DevPrivateKeyRec xnestPixmapPrivateKeyRec; +#define xnestPixmapPrivateKey (&xnestPixmapPrivateKeyRec) + +typedef struct { + Pixmap pixmap; +} xnestPrivPixmap; + +#define xnestPixmapPriv(pPixmap) ((xnestPrivPixmap *) \ + dixLookupPrivate(&(pPixmap)->devPrivates, xnestPixmapPrivateKey)) + +#define xnestPixmap(pPixmap) (xnestPixmapPriv(pPixmap)->pixmap) + +#define xnestSharePixmap(pPixmap) ((pPixmap)->refcnt++) + +PixmapPtr xnestCreatePixmap(ScreenPtr pScreen, int width, int height, + int depth, unsigned class); +Bool xnestDestroyPixmap(PixmapPtr pPixmap); +RegionPtr xnestPixmapToRegion(PixmapPtr pPixmap); + +#endif /* XNESTPIXMAP_H */ diff --git a/xorg-server/hw/xwin/win.h b/xorg-server/hw/xwin/win.h index 3f40fdbe0..606645f9f 100644 --- a/xorg-server/hw/xwin/win.h +++ b/xorg-server/hw/xwin/win.h @@ -1069,7 +1069,7 @@ winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen); PixmapPtr winCreatePixmapNativeGDI (ScreenPtr pScreen, int width, int height, int depth, - unsigned usage_hint); + unsigned class); Bool winDestroyPixmapNativeGDI (PixmapPtr pPixmap); diff --git a/xorg-server/hw/xwin/winpixmap.c b/xorg-server/hw/xwin/winpixmap.c index 82b6bbb5c..62717f31b 100644 --- a/xorg-server/hw/xwin/winpixmap.c +++ b/xorg-server/hw/xwin/winpixmap.c @@ -1,232 +1,231 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. - * - *Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - *"Software"), to deal in the Software without restriction, including - *without limitation the rights to use, copy, modify, merge, publish, - *distribute, sublicense, and/or sell copies of the Software, and to - *permit persons to whom the Software is furnished to do so, subject to - *the following conditions: - * - *The above copyright notice and this permission notice shall be - *included in all copies or substantial portions of the Software. - * - *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR - *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - *Except as contained in this notice, the name of the XFree86 Project - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from the XFree86 Project. - * - * Authors: drewry, september 1986 - * Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include -#endif -#include "win.h" - - -/* - * Local prototypes - */ - -#if 0 -static void -winXRotatePixmapNativeGDI (PixmapPtr pPix, int rw); - -static void -winYRotatePixmapNativeGDI (PixmapPtr pPix, int rh); - -static void -winCopyRotatePixmapNativeGDI (PixmapPtr psrcPix, PixmapPtr *ppdstPix, - int xrot, int yrot); -#endif - - -/* See Porting Layer Definition - p. 34 */ -/* See mfb/mfbpixmap.c - mfbCreatePixmap() */ -PixmapPtr -winCreatePixmapNativeGDI (ScreenPtr pScreen, - int iWidth, int iHeight, - int iDepth, unsigned usage_hint) -{ - winPrivPixmapPtr pPixmapPriv = NULL; - PixmapPtr pPixmap = NULL; - - /* Allocate pixmap memory */ - pPixmap = AllocatePixmap (pScreen, 0); - if (!pPixmap) - { - ErrorF ("winCreatePixmapNativeGDI () - Couldn't allocate a pixmap\n"); - return NullPixmap; - } - -#if CYGDEBUG - winDebug ("winCreatePixmap () - w %d h %d d %d uh %d bw %d\n", - iWidth, iHeight, iDepth, usage_hint, - PixmapBytePad (iWidth, iDepth)); -#endif - - /* Setup pixmap values */ - pPixmap->drawable.type = DRAWABLE_PIXMAP; - pPixmap->drawable.class = 0; - pPixmap->drawable.pScreen = pScreen; - pPixmap->drawable.depth = iDepth; - pPixmap->drawable.bitsPerPixel = BitsPerPixel (iDepth); - pPixmap->drawable.id = 0; - pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; - pPixmap->drawable.x = 0; - pPixmap->drawable.y = 0; - pPixmap->drawable.width = iWidth; - pPixmap->drawable.height = iHeight; - pPixmap->devKind = 0; - pPixmap->refcnt = 1; - pPixmap->devPrivate.ptr = NULL; - pPixmap->usage_hint = usage_hint; - - /* Pixmap privates are allocated by AllocatePixmap */ - pPixmapPriv = winGetPixmapPriv (pPixmap); - - /* Initialize pixmap privates */ - pPixmapPriv->hBitmap = NULL; - pPixmapPriv->hdcSelected = NULL; - pPixmapPriv->pbBits = NULL; - pPixmapPriv->dwScanlineBytes = PixmapBytePad (iWidth, iDepth); - - /* Check for zero width or height pixmaps */ - if (iWidth == 0 || iHeight == 0) - { - /* Don't allocate a real pixmap, just set fields and return */ - return pPixmap; - } - - /* Create a DIB for the pixmap */ - pPixmapPriv->hBitmap = winCreateDIBNativeGDI (iWidth, iHeight, iDepth, - &pPixmapPriv->pbBits, - (BITMAPINFO **) &pPixmapPriv->pbmih); - -#if CYGDEBUG - winDebug ("winCreatePixmap () - Created a pixmap %08x, %dx%dx%d, for " \ - "screen: %08x\n", - pPixmapPriv->hBitmap, iWidth, iHeight, iDepth, pScreen); -#endif - - return pPixmap; -} - - -/* - * See Porting Layer Definition - p. 35 - * - * See mfb/mfbpixmap.c - mfbDestroyPixmap() - */ - -Bool -winDestroyPixmapNativeGDI (PixmapPtr pPixmap) -{ - winPrivPixmapPtr pPixmapPriv = NULL; - -#if CYGDEBUG - winDebug ("winDestroyPixmapNativeGDI ()\n"); -#endif - - /* Bail early if there is not a pixmap to destroy */ - if (pPixmap == NULL) - { - ErrorF ("winDestroyPixmapNativeGDI () - No pixmap to destroy\n"); - return TRUE; - } - - /* Get a handle to the pixmap privates */ - pPixmapPriv = winGetPixmapPriv (pPixmap); - -#if CYGDEBUG - winDebug ("winDestroyPixmapNativeGDI - pPixmapPriv->hBitmap: %08x\n", - pPixmapPriv->hBitmap); -#endif - - /* Decrement reference count, return if nonzero */ - --pPixmap->refcnt; - if (pPixmap->refcnt != 0) - return TRUE; - - /* Free GDI bitmap */ - if (pPixmapPriv->hBitmap) DeleteObject (pPixmapPriv->hBitmap); - - /* Free the bitmap info header memory */ - free(pPixmapPriv->pbmih); - pPixmapPriv->pbmih = NULL; - - /* Free the pixmap memory */ - free (pPixmap); - pPixmap = NULL; - - return TRUE; -} - - -/* - * Not used yet - */ - -Bool -winModifyPixmapHeaderNativeGDI (PixmapPtr pPixmap, - int iWidth, int iHeight, - int iDepth, - int iBitsPerPixel, - int devKind, - pointer pPixData) -{ - FatalError ("winModifyPixmapHeaderNativeGDI ()\n"); - return TRUE; -} - - -#if 0 -/* - * Not used yet. - * See cfb/cfbpixmap.c - */ - -static void -winXRotatePixmapNativeGDI (PixmapPtr pPix, int rw) -{ - ErrorF ("winXRotatePixmap()\n"); - /* fill in this function, look at CFB */ -} - - -/* - * Not used yet. - * See cfb/cfbpixmap.c - */ -static void -winYRotatePixmapNativeGDI (PixmapPtr pPix, int rh) -{ - ErrorF ("winYRotatePixmap()\n"); - /* fill in this function, look at CFB */ -} - - -/* - * Not used yet. - * See cfb/cfbpixmap.c - */ - -static void -winCopyRotatePixmapNativeGDI (PixmapPtr psrcPix, PixmapPtr *ppdstPix, - int xrot, int yrot) -{ - ErrorF ("winCopyRotatePixmap()\n"); - /* fill in this function, look at CFB */ -} -#endif +/* + *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. + * + *Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + *"Software"), to deal in the Software without restriction, including + *without limitation the rights to use, copy, modify, merge, publish, + *distribute, sublicense, and/or sell copies of the Software, and to + *permit persons to whom the Software is furnished to do so, subject to + *the following conditions: + * + *The above copyright notice and this permission notice shall be + *included in all copies or substantial portions of the Software. + * + *THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + *EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + *MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + *NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR + *ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + *CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + *WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + *Except as contained in this notice, the name of the XFree86 Project + *shall not be used in advertising or otherwise to promote the sale, use + *or other dealings in this Software without prior written authorization + *from the XFree86 Project. + * + * Authors: drewry, september 1986 + * Harold L Hunt II + */ + +#ifdef HAVE_XWIN_CONFIG_H +#include +#endif +#include "win.h" + + +/* + * Local prototypes + */ + +#if 0 +static void +winXRotatePixmapNativeGDI (PixmapPtr pPix, int rw); + +static void +winYRotatePixmapNativeGDI (PixmapPtr pPix, int rh); + +static void +winCopyRotatePixmapNativeGDI (PixmapPtr psrcPix, PixmapPtr *ppdstPix, + int xrot, int yrot); +#endif + + +/* See Porting Layer Definition - p. 34 */ +/* See mfb/mfbpixmap.c - mfbCreatePixmap() */ +PixmapPtr +winCreatePixmapNativeGDI (ScreenPtr pScreen, + int iWidth, int iHeight, + int iDepth, unsigned class) +{ + winPrivPixmapPtr pPixmapPriv = NULL; + PixmapPtr pPixmap = NULL; + + /* Allocate pixmap memory */ + pPixmap = AllocatePixmap (pScreen, 0); + if (!pPixmap) + { + ErrorF ("winCreatePixmapNativeGDI () - Couldn't allocate a pixmap\n"); + return NullPixmap; + } + +#if CYGDEBUG + winDebug ("winCreatePixmap () - w %d h %d d %d uh %d bw %d\n", + iWidth, iHeight, iDepth, class, + PixmapBytePad (iWidth, iDepth)); +#endif + + /* Setup pixmap values */ + pPixmap->drawable.type = DRAWABLE_PIXMAP; + pPixmap->drawable.class = class; + pPixmap->drawable.pScreen = pScreen; + pPixmap->drawable.depth = iDepth; + pPixmap->drawable.bitsPerPixel = BitsPerPixel (iDepth); + pPixmap->drawable.id = 0; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pPixmap->drawable.x = 0; + pPixmap->drawable.y = 0; + pPixmap->drawable.width = iWidth; + pPixmap->drawable.height = iHeight; + pPixmap->devKind = 0; + pPixmap->refcnt = 1; + pPixmap->devPrivate.ptr = NULL; + + /* Pixmap privates are allocated by AllocatePixmap */ + pPixmapPriv = winGetPixmapPriv (pPixmap); + + /* Initialize pixmap privates */ + pPixmapPriv->hBitmap = NULL; + pPixmapPriv->hdcSelected = NULL; + pPixmapPriv->pbBits = NULL; + pPixmapPriv->dwScanlineBytes = PixmapBytePad (iWidth, iDepth); + + /* Check for zero width or height pixmaps */ + if (iWidth == 0 || iHeight == 0) + { + /* Don't allocate a real pixmap, just set fields and return */ + return pPixmap; + } + + /* Create a DIB for the pixmap */ + pPixmapPriv->hBitmap = winCreateDIBNativeGDI (iWidth, iHeight, iDepth, + &pPixmapPriv->pbBits, + (BITMAPINFO **) &pPixmapPriv->pbmih); + +#if CYGDEBUG + winDebug ("winCreatePixmap () - Created a pixmap %08x, %dx%dx%d, for " \ + "screen: %08x\n", + pPixmapPriv->hBitmap, iWidth, iHeight, iDepth, pScreen); +#endif + + return pPixmap; +} + + +/* + * See Porting Layer Definition - p. 35 + * + * See mfb/mfbpixmap.c - mfbDestroyPixmap() + */ + +Bool +winDestroyPixmapNativeGDI (PixmapPtr pPixmap) +{ + winPrivPixmapPtr pPixmapPriv = NULL; + +#if CYGDEBUG + winDebug ("winDestroyPixmapNativeGDI ()\n"); +#endif + + /* Bail early if there is not a pixmap to destroy */ + if (pPixmap == NULL) + { + ErrorF ("winDestroyPixmapNativeGDI () - No pixmap to destroy\n"); + return TRUE; + } + + /* Get a handle to the pixmap privates */ + pPixmapPriv = winGetPixmapPriv (pPixmap); + +#if CYGDEBUG + winDebug ("winDestroyPixmapNativeGDI - pPixmapPriv->hBitmap: %08x\n", + pPixmapPriv->hBitmap); +#endif + + /* Decrement reference count, return if nonzero */ + --pPixmap->refcnt; + if (pPixmap->refcnt != 0) + return TRUE; + + /* Free GDI bitmap */ + if (pPixmapPriv->hBitmap) DeleteObject (pPixmapPriv->hBitmap); + + /* Free the bitmap info header memory */ + free(pPixmapPriv->pbmih); + pPixmapPriv->pbmih = NULL; + + /* Free the pixmap memory */ + free (pPixmap); + pPixmap = NULL; + + return TRUE; +} + + +/* + * Not used yet + */ + +Bool +winModifyPixmapHeaderNativeGDI (PixmapPtr pPixmap, + int iWidth, int iHeight, + int iDepth, + int iBitsPerPixel, + int devKind, + pointer pPixData) +{ + FatalError ("winModifyPixmapHeaderNativeGDI ()\n"); + return TRUE; +} + + +#if 0 +/* + * Not used yet. + * See cfb/cfbpixmap.c + */ + +static void +winXRotatePixmapNativeGDI (PixmapPtr pPix, int rw) +{ + ErrorF ("winXRotatePixmap()\n"); + /* fill in this function, look at CFB */ +} + + +/* + * Not used yet. + * See cfb/cfbpixmap.c + */ +static void +winYRotatePixmapNativeGDI (PixmapPtr pPix, int rh) +{ + ErrorF ("winYRotatePixmap()\n"); + /* fill in this function, look at CFB */ +} + + +/* + * Not used yet. + * See cfb/cfbpixmap.c + */ + +static void +winCopyRotatePixmapNativeGDI (PixmapPtr psrcPix, PixmapPtr *ppdstPix, + int xrot, int yrot) +{ + ErrorF ("winCopyRotatePixmap()\n"); + /* fill in this function, look at CFB */ +} +#endif diff --git a/xorg-server/include/dix.h b/xorg-server/include/dix.h index 3f99098a2..c201e3ac1 100644 --- a/xorg-server/include/dix.h +++ b/xorg-server/include/dix.h @@ -576,35 +576,4 @@ extern _X_HIDDEN void CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master); extern _X_HIDDEN int CorePointerProc(DeviceIntPtr dev, int what); extern _X_HIDDEN int CoreKeyboardProc(DeviceIntPtr dev, int what); - -/* - * These are deprecated compatibility functions and will be removed soon! - * Please use the noted replacements instead. - */ -/* replaced by dixLookupWindow */ -extern _X_EXPORT WindowPtr SecurityLookupWindow( - XID id, - ClientPtr client, - Mask access_mode); -/* replaced by dixLookupWindow */ -extern _X_EXPORT WindowPtr LookupWindow( - XID id, - ClientPtr client); - -/* replaced by dixLookupDrawable */ -extern _X_EXPORT pointer SecurityLookupDrawable( - XID id, - ClientPtr client, - Mask access_mode); - -/* replaced by dixLookupDrawable */ -extern _X_EXPORT pointer LookupDrawable( - XID id, - ClientPtr client); - -/* replaced by dixLookupClient */ -extern _X_EXPORT ClientPtr LookupClient( - XID id, - ClientPtr client); - #endif /* DIX_H */ diff --git a/xorg-server/include/misc.h b/xorg-server/include/misc.h index 6cc29c024..0717db64d 100644 --- a/xorg-server/include/misc.h +++ b/xorg-server/include/misc.h @@ -1,292 +1,290 @@ -/*********************************************************** - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -Copyright 1992, 1993 Data General Corporation; -Copyright 1992, 1993 OMRON Corporation - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that the -above copyright notice appear in all copies and that both that copyright -notice and this permission notice appear in supporting documentation, and that -neither the name OMRON or DATA GENERAL be used in advertising or publicity -pertaining to distribution of the software without specific, written prior -permission of the party whose name is to be used. Neither OMRON or -DATA GENERAL make any representation about the suitability of this software -for any purpose. It is provided "as is" without express or implied warranty. - -OMRON AND DATA GENERAL EACH DISCLAIM ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, -IN NO EVENT SHALL OMRON OR DATA GENERAL BE LIABLE FOR ANY SPECIAL, INDIRECT -OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, -DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER -TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE -OF THIS SOFTWARE. - -******************************************************************/ -#ifndef MISC_H -#define MISC_H 1 -/* - * X internal definitions - * - */ - -#include -#include -#include -#include -#include - -#include - -#ifndef MAXSCREENS -#define MAXSCREENS 16 -#endif -#define MAXCLIENTS 256 -#define MAXEXTENSIONS 128 -#define MAXFORMATS 8 -#define MAXDEVICES 40 /* input devices */ - -#define EXTENSION_EVENT_BASE 64 -#define EXTENSION_BASE 128 - -typedef unsigned long PIXEL; -typedef unsigned long ATOM; - - -#ifndef TRUE -#define TRUE 1 -#define FALSE 0 -#endif - -#ifndef _XTYPEDEF_CALLBACKLISTPTR -typedef struct _CallbackList *CallbackListPtr; /* also in dix.h */ -#define _XTYPEDEF_CALLBACKLISTPTR -#endif - -typedef struct _xReq *xReqPtr; - -#include "os.h" /* for ALLOCATE_LOCAL and DEALLOCATE_LOCAL */ -#include /* for bcopy, bzero, and bcmp */ - -#define NullBox ((BoxPtr)0) -#define MILLI_PER_MIN (1000 * 60) -#define MILLI_PER_SECOND (1000) - - /* this next is used with None and ParentRelative to tell - PaintWin() what to use to paint the background. Also used - in the macro IS_VALID_PIXMAP */ - -#define USE_BACKGROUND_PIXEL 3 -#define USE_BORDER_PIXEL 3 - - -/* byte swap a 32-bit literal */ -#define lswapl(x) ((((x) & 0xff) << 24) |\ - (((x) & 0xff00) << 8) |\ - (((x) & 0xff0000) >> 8) |\ - (((x) >> 24) & 0xff)) - -/* byte swap a short literal */ -#define lswaps(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff)) - -#undef min -#undef max - -#define min(a, b) (((a) < (b)) ? (a) : (b)) -#define max(a, b) (((a) > (b)) ? (a) : (b)) -/* abs() is a function, not a macro; include the file declaring - * it in case we haven't done that yet. - */ -#include -#ifndef Fabs -#define Fabs(a) ((a) > 0.0 ? (a) : -(a)) /* floating absolute value */ -#endif -#define sign(x) ((x) < 0 ? -1 : ((x) > 0 ? 1 : 0)) -/* this assumes b > 0 */ -#define modulus(a, b, d) if (((d) = (a) % (b)) < 0) (d) += (b) -/* - * return the least significant bit in x which is set - * - * This works on 1's complement and 2's complement machines. - * If you care about the extra instruction on 2's complement - * machines, change to ((x) & (-(x))) - */ -#define lowbit(x) ((x) & (~(x) + 1)) - -/* XXX Not for modules */ -#include -#if !defined(MAXSHORT) || !defined(MINSHORT) || \ - !defined(MAXINT) || !defined(MININT) -/* - * Some implementations #define these through , so preclude - * #include'ing it later. - */ - -#include -#undef MAXSHORT -#define MAXSHORT SHRT_MAX -#undef MINSHORT -#define MINSHORT SHRT_MIN -#undef MAXINT -#define MAXINT INT_MAX -#undef MININT -#define MININT INT_MIN - -#include -#include -#include /* for fopen, etc... */ - -#endif - -/** - * Calculate the number of bytes needed to hold bits. - * @param bits The minimum number of bits needed. - * @return The number of bytes needed to hold bits. - */ -static inline int -bits_to_bytes(const int bits) { - return ((bits + 7) >> 3); -} -/** - * Calculate the number of 4-byte units needed to hold the given number of - * bytes. - * @param bytes The minimum number of bytes needed. - * @return The number of 4-byte units needed to hold bytes. - */ -static inline int -bytes_to_int32(const int bytes) { - return (((bytes) + 3) >> 2); -} - -/** - * Calculate the number of bytes (in multiples of 4) needed to hold bytes. - * @param bytes The minimum number of bytes needed. - * @return The closest multiple of 4 that is equal or higher than bytes. - */ -static inline int -pad_to_int32(const int bytes) { - return (((bytes) + 3) & ~3); -} - -extern char** -xstrtokenize(const char *str, const char* separators); - -/* some macros to help swap requests, replies, and events */ - -#define LengthRestB(stuff) \ - ((client->req_len << 2) - sizeof(*stuff)) - -#define LengthRestS(stuff) \ - ((client->req_len << 1) - (sizeof(*stuff) >> 1)) - -#define LengthRestL(stuff) \ - (client->req_len - (sizeof(*stuff) >> 2)) - -#define SwapRestS(stuff) \ - SwapShorts((short *)(stuff + 1), LengthRestS(stuff)) - -#define SwapRestL(stuff) \ - SwapLongs((CARD32 *)(stuff + 1), LengthRestL(stuff)) - -/* byte swap a 32-bit value */ -#define swapl(x, n) { \ - n = ((char *) (x))[0];\ - ((char *) (x))[0] = ((char *) (x))[3];\ - ((char *) (x))[3] = n;\ - n = ((char *) (x))[1];\ - ((char *) (x))[1] = ((char *) (x))[2];\ - ((char *) (x))[2] = n; } - -/* byte swap a short */ -#define swaps(x, n) { \ - n = ((char *) (x))[0];\ - ((char *) (x))[0] = ((char *) (x))[1];\ - ((char *) (x))[1] = n; } - -/* copy 32-bit value from src to dst byteswapping on the way */ -#define cpswapl(src, dst) { \ - ((char *)&(dst))[0] = ((char *) &(src))[3];\ - ((char *)&(dst))[1] = ((char *) &(src))[2];\ - ((char *)&(dst))[2] = ((char *) &(src))[1];\ - ((char *)&(dst))[3] = ((char *) &(src))[0]; } - -/* copy short from src to dst byteswapping on the way */ -#define cpswaps(src, dst) { \ - ((char *) &(dst))[0] = ((char *) &(src))[1];\ - ((char *) &(dst))[1] = ((char *) &(src))[0]; } - -extern _X_EXPORT void SwapLongs( - CARD32 *list, - unsigned long count); - -extern _X_EXPORT void SwapShorts( - short *list, - unsigned long count); - -extern _X_EXPORT void MakePredeclaredAtoms(void); - -extern _X_EXPORT int Ones( - unsigned long /*mask*/); - -typedef struct _xPoint *DDXPointPtr; -typedef struct pixman_box16 *BoxPtr; -typedef struct _xEvent *xEventPtr; -typedef struct _xRectangle *xRectanglePtr; -typedef struct _GrabRec *GrabPtr; - -/* typedefs from other places - duplicated here to minimize the amount - * of unnecessary junk that one would normally have to include to get - * these symbols defined - */ - -#ifndef _XTYPEDEF_CHARINFOPTR -typedef struct _CharInfo *CharInfoPtr; /* also in fonts/include/font.h */ -#define _XTYPEDEF_CHARINFOPTR -#endif - -extern _X_EXPORT unsigned long globalSerialNumber; -extern _X_EXPORT unsigned long serverGeneration; - -#endif /* MISC_H */ +/*********************************************************** + +Copyright 1987, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +Copyright 1992, 1993 Data General Corporation; +Copyright 1992, 1993 OMRON Corporation + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that the +above copyright notice appear in all copies and that both that copyright +notice and this permission notice appear in supporting documentation, and that +neither the name OMRON or DATA GENERAL be used in advertising or publicity +pertaining to distribution of the software without specific, written prior +permission of the party whose name is to be used. Neither OMRON or +DATA GENERAL make any representation about the suitability of this software +for any purpose. It is provided "as is" without express or implied warranty. + +OMRON AND DATA GENERAL EACH DISCLAIM ALL WARRANTIES WITH REGARD TO THIS +SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, +IN NO EVENT SHALL OMRON OR DATA GENERAL BE LIABLE FOR ANY SPECIAL, INDIRECT +OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, +DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER +TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE +OF THIS SOFTWARE. + +******************************************************************/ +#ifndef MISC_H +#define MISC_H 1 +/* + * X internal definitions + * + */ + +#include +#include +#include +#include +#include + +#include + +#ifndef MAXSCREENS +#define MAXSCREENS 16 +#endif +#define MAXCLIENTS 256 +#define MAXEXTENSIONS 128 +#define MAXFORMATS 8 +#define MAXDEVICES 40 /* input devices */ + +#define EXTENSION_EVENT_BASE 64 +#define EXTENSION_BASE 128 + +typedef unsigned long ATOM; + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif + +#ifndef _XTYPEDEF_CALLBACKLISTPTR +typedef struct _CallbackList *CallbackListPtr; /* also in dix.h */ +#define _XTYPEDEF_CALLBACKLISTPTR +#endif + +typedef struct _xReq *xReqPtr; + +#include "os.h" /* for ALLOCATE_LOCAL and DEALLOCATE_LOCAL */ +#include /* for bcopy, bzero, and bcmp */ + +#define NullBox ((BoxPtr)0) +#define MILLI_PER_MIN (1000 * 60) +#define MILLI_PER_SECOND (1000) + + /* this next is used with None and ParentRelative to tell + PaintWin() what to use to paint the background. Also used + in the macro IS_VALID_PIXMAP */ + +#define USE_BACKGROUND_PIXEL 3 +#define USE_BORDER_PIXEL 3 + + +/* byte swap a 32-bit literal */ +#define lswapl(x) ((((x) & 0xff) << 24) |\ + (((x) & 0xff00) << 8) |\ + (((x) & 0xff0000) >> 8) |\ + (((x) >> 24) & 0xff)) + +/* byte swap a short literal */ +#define lswaps(x) ((((x) & 0xff) << 8) | (((x) >> 8) & 0xff)) + +#undef min +#undef max + +#define min(a, b) (((a) < (b)) ? (a) : (b)) +#define max(a, b) (((a) > (b)) ? (a) : (b)) +/* abs() is a function, not a macro; include the file declaring + * it in case we haven't done that yet. + */ +#include +#ifndef Fabs +#define Fabs(a) ((a) > 0.0 ? (a) : -(a)) /* floating absolute value */ +#endif +#define sign(x) ((x) < 0 ? -1 : ((x) > 0 ? 1 : 0)) +/* this assumes b > 0 */ +#define modulus(a, b, d) if (((d) = (a) % (b)) < 0) (d) += (b) +/* + * return the least significant bit in x which is set + * + * This works on 1's complement and 2's complement machines. + * If you care about the extra instruction on 2's complement + * machines, change to ((x) & (-(x))) + */ +#define lowbit(x) ((x) & (~(x) + 1)) + +/* XXX Not for modules */ +#include +#if !defined(MAXSHORT) || !defined(MINSHORT) || \ + !defined(MAXINT) || !defined(MININT) +/* + * Some implementations #define these through , so preclude + * #include'ing it later. + */ + +#include +#undef MAXSHORT +#define MAXSHORT SHRT_MAX +#undef MINSHORT +#define MINSHORT SHRT_MIN +#undef MAXINT +#define MAXINT INT_MAX +#undef MININT +#define MININT INT_MIN + +#include +#include +#include /* for fopen, etc... */ + +#endif + +/** + * Calculate the number of bytes needed to hold bits. + * @param bits The minimum number of bits needed. + * @return The number of bytes needed to hold bits. + */ +static inline int +bits_to_bytes(const int bits) { + return ((bits + 7) >> 3); +} +/** + * Calculate the number of 4-byte units needed to hold the given number of + * bytes. + * @param bytes The minimum number of bytes needed. + * @return The number of 4-byte units needed to hold bytes. + */ +static inline int +bytes_to_int32(const int bytes) { + return (((bytes) + 3) >> 2); +} + +/** + * Calculate the number of bytes (in multiples of 4) needed to hold bytes. + * @param bytes The minimum number of bytes needed. + * @return The closest multiple of 4 that is equal or higher than bytes. + */ +static inline int +pad_to_int32(const int bytes) { + return (((bytes) + 3) & ~3); +} + +extern char** +xstrtokenize(const char *str, const char* separators); + +/* some macros to help swap requests, replies, and events */ + +#define LengthRestB(stuff) \ + ((client->req_len << 2) - sizeof(*stuff)) + +#define LengthRestS(stuff) \ + ((client->req_len << 1) - (sizeof(*stuff) >> 1)) + +#define LengthRestL(stuff) \ + (client->req_len - (sizeof(*stuff) >> 2)) + +#define SwapRestS(stuff) \ + SwapShorts((short *)(stuff + 1), LengthRestS(stuff)) + +#define SwapRestL(stuff) \ + SwapLongs((CARD32 *)(stuff + 1), LengthRestL(stuff)) + +/* byte swap a 32-bit value */ +#define swapl(x, n) { \ + n = ((char *) (x))[0];\ + ((char *) (x))[0] = ((char *) (x))[3];\ + ((char *) (x))[3] = n;\ + n = ((char *) (x))[1];\ + ((char *) (x))[1] = ((char *) (x))[2];\ + ((char *) (x))[2] = n; } + +/* byte swap a short */ +#define swaps(x, n) { \ + n = ((char *) (x))[0];\ + ((char *) (x))[0] = ((char *) (x))[1];\ + ((char *) (x))[1] = n; } + +/* copy 32-bit value from src to dst byteswapping on the way */ +#define cpswapl(src, dst) { \ + ((char *)&(dst))[0] = ((char *) &(src))[3];\ + ((char *)&(dst))[1] = ((char *) &(src))[2];\ + ((char *)&(dst))[2] = ((char *) &(src))[1];\ + ((char *)&(dst))[3] = ((char *) &(src))[0]; } + +/* copy short from src to dst byteswapping on the way */ +#define cpswaps(src, dst) { \ + ((char *) &(dst))[0] = ((char *) &(src))[1];\ + ((char *) &(dst))[1] = ((char *) &(src))[0]; } + +extern _X_EXPORT void SwapLongs( + CARD32 *list, + unsigned long count); + +extern _X_EXPORT void SwapShorts( + short *list, + unsigned long count); + +extern _X_EXPORT void MakePredeclaredAtoms(void); + +extern _X_EXPORT int Ones( + unsigned long /*mask*/); + +typedef struct _xPoint *DDXPointPtr; +typedef struct pixman_box16 *BoxPtr; +typedef struct _xEvent *xEventPtr; +typedef struct _xRectangle *xRectanglePtr; +typedef struct _GrabRec *GrabPtr; + +/* typedefs from other places - duplicated here to minimize the amount + * of unnecessary junk that one would normally have to include to get + * these symbols defined + */ + +#ifndef _XTYPEDEF_CHARINFOPTR +typedef struct _CharInfo *CharInfoPtr; /* also in fonts/include/font.h */ +#define _XTYPEDEF_CHARINFOPTR +#endif + +extern _X_EXPORT unsigned long globalSerialNumber; +extern _X_EXPORT unsigned long serverGeneration; + +#endif /* MISC_H */ diff --git a/xorg-server/include/pixmapstr.h b/xorg-server/include/pixmapstr.h index 702faf0ac..542c381bc 100644 --- a/xorg-server/include/pixmapstr.h +++ b/xorg-server/include/pixmapstr.h @@ -80,7 +80,6 @@ typedef struct _Pixmap { short screen_x; short screen_y; #endif - unsigned usage_hint; /* see CREATE_PIXMAP_USAGE_* */ } PixmapRec; #endif /* PIXMAPSTRUCT_H */ diff --git a/xorg-server/include/resource.h b/xorg-server/include/resource.h index a09679ad6..763aa99d9 100644 --- a/xorg-server/include/resource.h +++ b/xorg-server/include/resource.h @@ -1,284 +1,255 @@ -/*********************************************************** - -Copyright 1987, 1989, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. - - All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, -provided that the above copyright notice appear in all copies and that -both that copyright notice and this permission notice appear in -supporting documentation, and that the name of Digital not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR -ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, -WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, -ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS -SOFTWARE. - -******************************************************************/ - -#ifndef RESOURCE_H -#define RESOURCE_H 1 -#include "misc.h" -#include "dixaccess.h" - -/***************************************************************** - * STUFF FOR RESOURCES - *****************************************************************/ - -/* classes for Resource routines */ - -typedef unsigned long RESTYPE; - -#define RC_VANILLA ((RESTYPE)0) -#define RC_CACHED ((RESTYPE)1<<31) -#define RC_DRAWABLE ((RESTYPE)1<<30) -/* Use class RC_NEVERRETAIN for resources that should not be retained - * regardless of the close down mode when the client dies. (A client's - * event selections on objects that it doesn't own are good candidates.) - * Extensions can use this too! - */ -#define RC_NEVERRETAIN ((RESTYPE)1<<29) -#define RC_LASTPREDEF RC_NEVERRETAIN -#define RC_ANY (~(RESTYPE)0) - -/* types for Resource routines */ - -#define RT_WINDOW ((RESTYPE)1|RC_DRAWABLE) -#define RT_PIXMAP ((RESTYPE)2|RC_DRAWABLE) -#define RT_GC ((RESTYPE)3) -#undef RT_FONT -#undef RT_CURSOR -#define RT_FONT ((RESTYPE)4) -#define RT_CURSOR ((RESTYPE)5) -#define RT_COLORMAP ((RESTYPE)6) -#define RT_CMAPENTRY ((RESTYPE)7) -#define RT_OTHERCLIENT ((RESTYPE)8|RC_NEVERRETAIN) -#define RT_PASSIVEGRAB ((RESTYPE)9|RC_NEVERRETAIN) -#define RT_LASTPREDEF ((RESTYPE)9) -#define RT_NONE ((RESTYPE)0) - -/* bits and fields within a resource id */ -#define RESOURCE_AND_CLIENT_COUNT 29 /* 29 bits for XIDs */ -#if MAXCLIENTS == 64 -#define RESOURCE_CLIENT_BITS 6 -#endif -#if MAXCLIENTS == 128 -#define RESOURCE_CLIENT_BITS 7 -#endif -#if MAXCLIENTS == 256 -#define RESOURCE_CLIENT_BITS 8 -#endif -#if MAXCLIENTS == 512 -#define RESOURCE_CLIENT_BITS 9 -#endif -/* client field offset */ -#define CLIENTOFFSET (RESOURCE_AND_CLIENT_COUNT - RESOURCE_CLIENT_BITS) -/* resource field */ -#define RESOURCE_ID_MASK ((1 << CLIENTOFFSET) - 1) -/* client field */ -#define RESOURCE_CLIENT_MASK (((1 << RESOURCE_CLIENT_BITS) - 1) << CLIENTOFFSET) -/* extract the client mask from an XID */ -#define CLIENT_BITS(id) ((id) & RESOURCE_CLIENT_MASK) -/* extract the client id from an XID */ -#define CLIENT_ID(id) ((int)(CLIENT_BITS(id) >> CLIENTOFFSET)) -#define SERVER_BIT (Mask)0x40000000 /* use illegal bit */ - -#ifdef INVALID -#undef INVALID /* needed on HP/UX */ -#endif - -/* Invalid resource id */ -#define INVALID (0) - -#define BAD_RESOURCE 0xe0000000 - -#define rClient(obj) (clients[CLIENT_ID((obj)->resource)]) - -/* Resource state callback */ -extern _X_EXPORT CallbackListPtr ResourceStateCallback; - -typedef enum {ResourceStateAdding, - ResourceStateFreeing} ResourceState; - -typedef struct { - ResourceState state; - XID id; - RESTYPE type; - pointer value; -} ResourceStateInfoRec; - -typedef int (*DeleteType)( - pointer /*value*/, - XID /*id*/); - -typedef void (*FindResType)( - pointer /*value*/, - XID /*id*/, - pointer /*cdata*/); - -typedef void (*FindAllRes)( - pointer /*value*/, - XID /*id*/, - RESTYPE /*type*/, - pointer /*cdata*/); - -typedef Bool (*FindComplexResType)( - pointer /*value*/, - XID /*id*/, - pointer /*cdata*/); - -extern _X_EXPORT RESTYPE CreateNewResourceType( - DeleteType /*deleteFunc*/, char * /*name*/); - -extern _X_EXPORT void SetResourceTypeErrorValue( - RESTYPE /*type*/, int /*errorValue*/); - -extern _X_EXPORT RESTYPE CreateNewResourceClass(void); - -extern _X_EXPORT Bool InitClientResources( - ClientPtr /*client*/); - -extern _X_EXPORT XID FakeClientID( - int /*client*/); - -/* Quartz support on Mac OS X uses the CarbonCore - framework whose AddResource function conflicts here. */ -#ifdef __APPLE__ -#define AddResource Darwin_X_AddResource -#endif -extern _X_EXPORT Bool AddResource( - XID /*id*/, - RESTYPE /*type*/, - pointer /*value*/); - -extern _X_EXPORT void FreeResource( - XID /*id*/, - RESTYPE /*skipDeleteFuncType*/); - -extern _X_EXPORT void FreeResourceByType( - XID /*id*/, - RESTYPE /*type*/, - Bool /*skipFree*/); - -extern _X_EXPORT Bool ChangeResourceValue( - XID /*id*/, - RESTYPE /*rtype*/, - pointer /*value*/); - -extern _X_EXPORT void FindClientResourcesByType( - ClientPtr /*client*/, - RESTYPE /*type*/, - FindResType /*func*/, - pointer /*cdata*/); - -extern _X_EXPORT void FindAllClientResources( - ClientPtr /*client*/, - FindAllRes /*func*/, - pointer /*cdata*/); - -extern _X_EXPORT void FreeClientNeverRetainResources( - ClientPtr /*client*/); - -extern _X_EXPORT void FreeClientResources( - ClientPtr /*client*/); - -extern _X_EXPORT void FreeAllResources(void); - -extern _X_EXPORT Bool LegalNewID( - XID /*id*/, - ClientPtr /*client*/); - -extern _X_EXPORT pointer LookupClientResourceComplex( - ClientPtr client, - RESTYPE type, - FindComplexResType func, - pointer cdata); - -extern _X_EXPORT int dixLookupResourceByType( - pointer *result, - XID id, - RESTYPE rtype, - ClientPtr client, - Mask access_mode); - -extern _X_EXPORT int dixLookupResourceByClass( - pointer *result, - XID id, - RESTYPE rclass, - ClientPtr client, - Mask access_mode); - -extern _X_EXPORT void GetXIDRange( - int /*client*/, - Bool /*server*/, - XID * /*minp*/, - XID * /*maxp*/); - -extern _X_EXPORT unsigned int GetXIDList( - ClientPtr /*client*/, - unsigned int /*count*/, - XID * /*pids*/); - -extern _X_EXPORT RESTYPE lastResourceType; -extern _X_EXPORT RESTYPE TypeMask; - -/* - * These are deprecated compatibility functions and will be removed soon! - * Please use the noted replacements instead. - */ - -/* replaced by dixLookupResourceByType */ -extern _X_EXPORT pointer SecurityLookupIDByType( - ClientPtr client, - XID id, - RESTYPE rtype, - Mask access_mode) _X_DEPRECATED; - -/* replaced by dixLookupResourceByClass */ -extern _X_EXPORT pointer SecurityLookupIDByClass( - ClientPtr client, - XID id, - RESTYPE classes, - Mask access_mode) _X_DEPRECATED; - -/* replaced by dixLookupResourceByType */ -extern _X_EXPORT pointer LookupIDByType( - XID id, - RESTYPE rtype) _X_DEPRECATED; - -/* replaced by dixLookupResourceByClass */ -extern _X_EXPORT pointer LookupIDByClass( - XID id, - RESTYPE classes) _X_DEPRECATED; - -#endif /* RESOURCE_H */ - +/*********************************************************** + +Copyright 1987, 1989, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + + +Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the name of Digital not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. + +******************************************************************/ + +#ifndef RESOURCE_H +#define RESOURCE_H 1 +#include "misc.h" +#include "dixaccess.h" + +/***************************************************************** + * STUFF FOR RESOURCES + *****************************************************************/ + +/* classes for Resource routines */ + +typedef unsigned long RESTYPE; + +#define RC_VANILLA ((RESTYPE)0) +#define RC_CACHED ((RESTYPE)1<<31) +#define RC_DRAWABLE ((RESTYPE)1<<30) +/* Use class RC_NEVERRETAIN for resources that should not be retained + * regardless of the close down mode when the client dies. (A client's + * event selections on objects that it doesn't own are good candidates.) + * Extensions can use this too! + */ +#define RC_NEVERRETAIN ((RESTYPE)1<<29) +#define RC_LASTPREDEF RC_NEVERRETAIN +#define RC_ANY (~(RESTYPE)0) + +/* types for Resource routines */ + +#define RT_WINDOW ((RESTYPE)1|RC_DRAWABLE) +#define RT_PIXMAP ((RESTYPE)2|RC_DRAWABLE) +#define RT_GC ((RESTYPE)3) +#undef RT_FONT +#undef RT_CURSOR +#define RT_FONT ((RESTYPE)4) +#define RT_CURSOR ((RESTYPE)5) +#define RT_COLORMAP ((RESTYPE)6) +#define RT_CMAPENTRY ((RESTYPE)7) +#define RT_OTHERCLIENT ((RESTYPE)8|RC_NEVERRETAIN) +#define RT_PASSIVEGRAB ((RESTYPE)9|RC_NEVERRETAIN) +#define RT_LASTPREDEF ((RESTYPE)9) +#define RT_NONE ((RESTYPE)0) + +/* bits and fields within a resource id */ +#define RESOURCE_AND_CLIENT_COUNT 29 /* 29 bits for XIDs */ +#if MAXCLIENTS == 64 +#define RESOURCE_CLIENT_BITS 6 +#endif +#if MAXCLIENTS == 128 +#define RESOURCE_CLIENT_BITS 7 +#endif +#if MAXCLIENTS == 256 +#define RESOURCE_CLIENT_BITS 8 +#endif +#if MAXCLIENTS == 512 +#define RESOURCE_CLIENT_BITS 9 +#endif +/* client field offset */ +#define CLIENTOFFSET (RESOURCE_AND_CLIENT_COUNT - RESOURCE_CLIENT_BITS) +/* resource field */ +#define RESOURCE_ID_MASK ((1 << CLIENTOFFSET) - 1) +/* client field */ +#define RESOURCE_CLIENT_MASK (((1 << RESOURCE_CLIENT_BITS) - 1) << CLIENTOFFSET) +/* extract the client mask from an XID */ +#define CLIENT_BITS(id) ((id) & RESOURCE_CLIENT_MASK) +/* extract the client id from an XID */ +#define CLIENT_ID(id) ((int)(CLIENT_BITS(id) >> CLIENTOFFSET)) +#define SERVER_BIT (Mask)0x40000000 /* use illegal bit */ + +#ifdef INVALID +#undef INVALID /* needed on HP/UX */ +#endif + +/* Invalid resource id */ +#define INVALID (0) + +#define BAD_RESOURCE 0xe0000000 + +#define rClient(obj) (clients[CLIENT_ID((obj)->resource)]) + +/* Resource state callback */ +extern _X_EXPORT CallbackListPtr ResourceStateCallback; + +typedef enum {ResourceStateAdding, + ResourceStateFreeing} ResourceState; + +typedef struct { + ResourceState state; + XID id; + RESTYPE type; + pointer value; +} ResourceStateInfoRec; + +typedef int (*DeleteType)( + pointer /*value*/, + XID /*id*/); + +typedef void (*FindResType)( + pointer /*value*/, + XID /*id*/, + pointer /*cdata*/); + +typedef void (*FindAllRes)( + pointer /*value*/, + XID /*id*/, + RESTYPE /*type*/, + pointer /*cdata*/); + +typedef Bool (*FindComplexResType)( + pointer /*value*/, + XID /*id*/, + pointer /*cdata*/); + +extern _X_EXPORT RESTYPE CreateNewResourceType( + DeleteType /*deleteFunc*/, char * /*name*/); + +extern _X_EXPORT void SetResourceTypeErrorValue( + RESTYPE /*type*/, int /*errorValue*/); + +extern _X_EXPORT RESTYPE CreateNewResourceClass(void); + +extern _X_EXPORT Bool InitClientResources( + ClientPtr /*client*/); + +extern _X_EXPORT XID FakeClientID( + int /*client*/); + +/* Quartz support on Mac OS X uses the CarbonCore + framework whose AddResource function conflicts here. */ +#ifdef __APPLE__ +#define AddResource Darwin_X_AddResource +#endif +extern _X_EXPORT Bool AddResource( + XID /*id*/, + RESTYPE /*type*/, + pointer /*value*/); + +extern _X_EXPORT void FreeResource( + XID /*id*/, + RESTYPE /*skipDeleteFuncType*/); + +extern _X_EXPORT void FreeResourceByType( + XID /*id*/, + RESTYPE /*type*/, + Bool /*skipFree*/); + +extern _X_EXPORT Bool ChangeResourceValue( + XID /*id*/, + RESTYPE /*rtype*/, + pointer /*value*/); + +extern _X_EXPORT void FindClientResourcesByType( + ClientPtr /*client*/, + RESTYPE /*type*/, + FindResType /*func*/, + pointer /*cdata*/); + +extern _X_EXPORT void FindAllClientResources( + ClientPtr /*client*/, + FindAllRes /*func*/, + pointer /*cdata*/); + +extern _X_EXPORT void FreeClientNeverRetainResources( + ClientPtr /*client*/); + +extern _X_EXPORT void FreeClientResources( + ClientPtr /*client*/); + +extern _X_EXPORT void FreeAllResources(void); + +extern _X_EXPORT Bool LegalNewID( + XID /*id*/, + ClientPtr /*client*/); + +extern _X_EXPORT pointer LookupClientResourceComplex( + ClientPtr client, + RESTYPE type, + FindComplexResType func, + pointer cdata); + +extern _X_EXPORT int dixLookupResourceByType( + pointer *result, + XID id, + RESTYPE rtype, + ClientPtr client, + Mask access_mode); + +extern _X_EXPORT int dixLookupResourceByClass( + pointer *result, + XID id, + RESTYPE rclass, + ClientPtr client, + Mask access_mode); + +extern _X_EXPORT void GetXIDRange( + int /*client*/, + Bool /*server*/, + XID * /*minp*/, + XID * /*maxp*/); + +extern _X_EXPORT unsigned int GetXIDList( + ClientPtr /*client*/, + unsigned int /*count*/, + XID * /*pids*/); + +extern _X_EXPORT RESTYPE lastResourceType; +extern _X_EXPORT RESTYPE TypeMask; + +#endif /* RESOURCE_H */ + diff --git a/xorg-server/include/scrnintstr.h b/xorg-server/include/scrnintstr.h index a9357e8a5..302a561bd 100644 --- a/xorg-server/include/scrnintstr.h +++ b/xorg-server/include/scrnintstr.h @@ -208,7 +208,7 @@ typedef PixmapPtr (* CreatePixmapProcPtr)( int /*width*/, int /*height*/, int /*depth*/, - unsigned /*usage_hint*/); + unsigned /*class*/); typedef Bool (* DestroyPixmapProcPtr)( PixmapPtr /*pPixmap*/); diff --git a/xorg-server/render/render.c b/xorg-server/render/render.c index 9f1b4701f..fbb296809 100644 --- a/xorg-server/render/render.c +++ b/xorg-server/render/render.c @@ -1,3394 +1,3394 @@ -/* - * - * Copyright © 2000 SuSE, Inc. - * - * Permission to use, copy, modify, distribute, and sell this software and its - * documentation for any purpose is hereby granted without fee, provided that - * the above copyright notice appear in all copies and that both that - * copyright notice and this permission notice appear in supporting - * documentation, and that the name of SuSE not be used in advertising or - * publicity pertaining to distribution of the software without specific, - * written prior permission. SuSE makes no representations about the - * suitability of this software for any purpose. It is provided "as is" - * without express or implied warranty. - * - * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE - * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION - * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN - * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - * Author: Keith Packard, SuSE, Inc. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include -#endif - -#include -#include -#include "misc.h" -#include "os.h" -#include "dixstruct.h" -#include "resource.h" -#include "scrnintstr.h" -#include "windowstr.h" -#include "pixmapstr.h" -#include "colormapst.h" -#include "extnsionst.h" -#include "servermd.h" -#include -#include -#include "picturestr.h" -#include "glyphstr.h" -#include -#include "cursorstr.h" -#include "xace.h" -#include "protocol-versions.h" - -#ifdef PANORAMIX -#include "panoramiX.h" -#include "panoramiXsrv.h" -#endif - -#if HAVE_STDINT_H -#include -#elif !defined(UINT32_MAX) -#define UINT32_MAX 0xffffffffU -#endif - -static int ProcRenderQueryVersion (ClientPtr pClient); -static int ProcRenderQueryPictFormats (ClientPtr pClient); -static int ProcRenderQueryPictIndexValues (ClientPtr pClient); -static int ProcRenderQueryDithers (ClientPtr pClient); -static int ProcRenderCreatePicture (ClientPtr pClient); -static int ProcRenderChangePicture (ClientPtr pClient); -static int ProcRenderSetPictureClipRectangles (ClientPtr pClient); -static int ProcRenderFreePicture (ClientPtr pClient); -static int ProcRenderComposite (ClientPtr pClient); -static int ProcRenderScale (ClientPtr pClient); -static int ProcRenderTrapezoids (ClientPtr pClient); -static int ProcRenderTriangles (ClientPtr pClient); -static int ProcRenderTriStrip (ClientPtr pClient); -static int ProcRenderTriFan (ClientPtr pClient); -static int ProcRenderColorTrapezoids (ClientPtr pClient); -static int ProcRenderColorTriangles (ClientPtr pClient); -static int ProcRenderTransform (ClientPtr pClient); -static int ProcRenderCreateGlyphSet (ClientPtr pClient); -static int ProcRenderReferenceGlyphSet (ClientPtr pClient); -static int ProcRenderFreeGlyphSet (ClientPtr pClient); -static int ProcRenderAddGlyphs (ClientPtr pClient); -static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient); -static int ProcRenderFreeGlyphs (ClientPtr pClient); -static int ProcRenderCompositeGlyphs (ClientPtr pClient); -static int ProcRenderFillRectangles (ClientPtr pClient); -static int ProcRenderCreateCursor (ClientPtr pClient); -static int ProcRenderSetPictureTransform (ClientPtr pClient); -static int ProcRenderQueryFilters (ClientPtr pClient); -static int ProcRenderSetPictureFilter (ClientPtr pClient); -static int ProcRenderCreateAnimCursor (ClientPtr pClient); -static int ProcRenderAddTraps (ClientPtr pClient); -static int ProcRenderCreateSolidFill (ClientPtr pClient); -static int ProcRenderCreateLinearGradient (ClientPtr pClient); -static int ProcRenderCreateRadialGradient (ClientPtr pClient); -static int ProcRenderCreateConicalGradient (ClientPtr pClient); - -static int ProcRenderDispatch (ClientPtr pClient); - -static int SProcRenderQueryVersion (ClientPtr pClient); -static int SProcRenderQueryPictFormats (ClientPtr pClient); -static int SProcRenderQueryPictIndexValues (ClientPtr pClient); -static int SProcRenderQueryDithers (ClientPtr pClient); -static int SProcRenderCreatePicture (ClientPtr pClient); -static int SProcRenderChangePicture (ClientPtr pClient); -static int SProcRenderSetPictureClipRectangles (ClientPtr pClient); -static int SProcRenderFreePicture (ClientPtr pClient); -static int SProcRenderComposite (ClientPtr pClient); -static int SProcRenderScale (ClientPtr pClient); -static int SProcRenderTrapezoids (ClientPtr pClient); -static int SProcRenderTriangles (ClientPtr pClient); -static int SProcRenderTriStrip (ClientPtr pClient); -static int SProcRenderTriFan (ClientPtr pClient); -static int SProcRenderColorTrapezoids (ClientPtr pClient); -static int SProcRenderColorTriangles (ClientPtr pClient); -static int SProcRenderTransform (ClientPtr pClient); -static int SProcRenderCreateGlyphSet (ClientPtr pClient); -static int SProcRenderReferenceGlyphSet (ClientPtr pClient); -static int SProcRenderFreeGlyphSet (ClientPtr pClient); -static int SProcRenderAddGlyphs (ClientPtr pClient); -static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient); -static int SProcRenderFreeGlyphs (ClientPtr pClient); -static int SProcRenderCompositeGlyphs (ClientPtr pClient); -static int SProcRenderFillRectangles (ClientPtr pClient); -static int SProcRenderCreateCursor (ClientPtr pClient); -static int SProcRenderSetPictureTransform (ClientPtr pClient); -static int SProcRenderQueryFilters (ClientPtr pClient); -static int SProcRenderSetPictureFilter (ClientPtr pClient); -static int SProcRenderCreateAnimCursor (ClientPtr pClient); -static int SProcRenderAddTraps (ClientPtr pClient); -static int SProcRenderCreateSolidFill (ClientPtr pClient); -static int SProcRenderCreateLinearGradient (ClientPtr pClient); -static int SProcRenderCreateRadialGradient (ClientPtr pClient); -static int SProcRenderCreateConicalGradient (ClientPtr pClient); - -static int SProcRenderDispatch (ClientPtr pClient); - -int (*ProcRenderVector[RenderNumberRequests])(ClientPtr) = { - ProcRenderQueryVersion, - ProcRenderQueryPictFormats, - ProcRenderQueryPictIndexValues, - ProcRenderQueryDithers, - ProcRenderCreatePicture, - ProcRenderChangePicture, - ProcRenderSetPictureClipRectangles, - ProcRenderFreePicture, - ProcRenderComposite, - ProcRenderScale, - ProcRenderTrapezoids, - ProcRenderTriangles, - ProcRenderTriStrip, - ProcRenderTriFan, - ProcRenderColorTrapezoids, - ProcRenderColorTriangles, - ProcRenderTransform, - ProcRenderCreateGlyphSet, - ProcRenderReferenceGlyphSet, - ProcRenderFreeGlyphSet, - ProcRenderAddGlyphs, - ProcRenderAddGlyphsFromPicture, - ProcRenderFreeGlyphs, - ProcRenderCompositeGlyphs, - ProcRenderCompositeGlyphs, - ProcRenderCompositeGlyphs, - ProcRenderFillRectangles, - ProcRenderCreateCursor, - ProcRenderSetPictureTransform, - ProcRenderQueryFilters, - ProcRenderSetPictureFilter, - ProcRenderCreateAnimCursor, - ProcRenderAddTraps, - ProcRenderCreateSolidFill, - ProcRenderCreateLinearGradient, - ProcRenderCreateRadialGradient, - ProcRenderCreateConicalGradient -}; - -int (*SProcRenderVector[RenderNumberRequests])(ClientPtr) = { - SProcRenderQueryVersion, - SProcRenderQueryPictFormats, - SProcRenderQueryPictIndexValues, - SProcRenderQueryDithers, - SProcRenderCreatePicture, - SProcRenderChangePicture, - SProcRenderSetPictureClipRectangles, - SProcRenderFreePicture, - SProcRenderComposite, - SProcRenderScale, - SProcRenderTrapezoids, - SProcRenderTriangles, - SProcRenderTriStrip, - SProcRenderTriFan, - SProcRenderColorTrapezoids, - SProcRenderColorTriangles, - SProcRenderTransform, - SProcRenderCreateGlyphSet, - SProcRenderReferenceGlyphSet, - SProcRenderFreeGlyphSet, - SProcRenderAddGlyphs, - SProcRenderAddGlyphsFromPicture, - SProcRenderFreeGlyphs, - SProcRenderCompositeGlyphs, - SProcRenderCompositeGlyphs, - SProcRenderCompositeGlyphs, - SProcRenderFillRectangles, - SProcRenderCreateCursor, - SProcRenderSetPictureTransform, - SProcRenderQueryFilters, - SProcRenderSetPictureFilter, - SProcRenderCreateAnimCursor, - SProcRenderAddTraps, - SProcRenderCreateSolidFill, - SProcRenderCreateLinearGradient, - SProcRenderCreateRadialGradient, - SProcRenderCreateConicalGradient -}; - -int RenderErrBase; -static DevPrivateKeyRec RenderClientPrivateKeyRec; -#define RenderClientPrivateKey (&RenderClientPrivateKeyRec ) - -typedef struct _RenderClient { - int major_version; - int minor_version; -} RenderClientRec, *RenderClientPtr; - -#define GetRenderClient(pClient) ((RenderClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RenderClientPrivateKey)) - -static void -RenderClientCallback (CallbackListPtr *list, - pointer closure, - pointer data) -{ - NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; - ClientPtr pClient = clientinfo->client; - RenderClientPtr pRenderClient = GetRenderClient (pClient); - - pRenderClient->major_version = 0; - pRenderClient->minor_version = 0; -} - -#ifdef PANORAMIX -unsigned long XRT_PICTURE; -#endif - -void -RenderExtensionInit (void) -{ - ExtensionEntry *extEntry; - - if (!PictureType) - return; - if (!PictureFinishInit ()) - return; - if (!dixRegisterPrivateKey(&RenderClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(RenderClientRec))) - return; - if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0)) - return; - - extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors, - ProcRenderDispatch, SProcRenderDispatch, - NULL, StandardMinorOpcode); - if (!extEntry) - return; - RenderErrBase = extEntry->errorBase; -#ifdef PANORAMIX - if (XRT_PICTURE) - SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture); -#endif - SetResourceTypeErrorValue(PictureType, RenderErrBase + BadPicture); - SetResourceTypeErrorValue(PictFormatType, RenderErrBase + BadPictFormat); - SetResourceTypeErrorValue(GlyphSetType, RenderErrBase + BadGlyphSet); -} - -static int -ProcRenderQueryVersion (ClientPtr client) -{ - RenderClientPtr pRenderClient = GetRenderClient (client); - xRenderQueryVersionReply rep; - register int n; - REQUEST(xRenderQueryVersionReq); - - pRenderClient->major_version = stuff->majorVersion; - pRenderClient->minor_version = stuff->minorVersion; - - REQUEST_SIZE_MATCH(xRenderQueryVersionReq); - memset(&rep, 0, sizeof(xRenderQueryVersionReply)); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - if ((stuff->majorVersion * 1000 + stuff->minorVersion) < - (SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION)) - { - rep.majorVersion = stuff->majorVersion; - rep.minorVersion = stuff->minorVersion; - } else - { - rep.majorVersion = SERVER_RENDER_MAJOR_VERSION; - rep.minorVersion = SERVER_RENDER_MINOR_VERSION; - } - - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swapl(&rep.majorVersion, n); - swapl(&rep.minorVersion, n); - } - WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep); - return Success; -} - -static VisualPtr -findVisual (ScreenPtr pScreen, VisualID vid) -{ - VisualPtr pVisual; - int v; - - for (v = 0; v < pScreen->numVisuals; v++) - { - pVisual = pScreen->visuals + v; - if (pVisual->vid == vid) - return pVisual; - } - return 0; -} - -static int -ProcRenderQueryPictFormats (ClientPtr client) -{ - RenderClientPtr pRenderClient = GetRenderClient (client); - xRenderQueryPictFormatsReply *reply; - xPictScreen *pictScreen; - xPictDepth *pictDepth; - xPictVisual *pictVisual; - xPictFormInfo *pictForm; - CARD32 *pictSubpixel; - ScreenPtr pScreen; - VisualPtr pVisual; - DepthPtr pDepth; - int v, d; - PictureScreenPtr ps; - PictFormatPtr pFormat; - int nformat; - int ndepth; - int nvisual; - int rlength; - int s; - int n; - int numScreens; - int numSubpixel; -/* REQUEST(xRenderQueryPictFormatsReq); */ - - REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq); - -#ifdef PANORAMIX - if (noPanoramiXExtension) - numScreens = screenInfo.numScreens; - else - numScreens = ((xConnSetup *)ConnectionInfo)->numRoots; -#else - numScreens = screenInfo.numScreens; -#endif - ndepth = nformat = nvisual = 0; - for (s = 0; s < numScreens; s++) - { - pScreen = screenInfo.screens[s]; - for (d = 0; d < pScreen->numDepths; d++) - { - pDepth = pScreen->allowedDepths + d; - ++ndepth; - - for (v = 0; v < pDepth->numVids; v++) - { - pVisual = findVisual (pScreen, pDepth->vids[v]); - if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual)) - ++nvisual; - } - } - ps = GetPictureScreenIfSet(pScreen); - if (ps) - nformat += ps->nformats; - } - if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6) - numSubpixel = 0; - else - numSubpixel = numScreens; - - rlength = (sizeof (xRenderQueryPictFormatsReply) + - nformat * sizeof (xPictFormInfo) + - numScreens * sizeof (xPictScreen) + - ndepth * sizeof (xPictDepth) + - nvisual * sizeof (xPictVisual) + - numSubpixel * sizeof (CARD32)); - reply = (xRenderQueryPictFormatsReply *) calloc(1, rlength); - if (!reply) - return BadAlloc; - reply->type = X_Reply; - reply->sequenceNumber = client->sequence; - reply->length = bytes_to_int32(rlength - sizeof(xGenericReply)); - reply->numFormats = nformat; - reply->numScreens = numScreens; - reply->numDepths = ndepth; - reply->numVisuals = nvisual; - reply->numSubpixel = numSubpixel; - - pictForm = (xPictFormInfo *) (reply + 1); - - for (s = 0; s < numScreens; s++) - { - pScreen = screenInfo.screens[s]; - ps = GetPictureScreenIfSet(pScreen); - if (ps) - { - for (nformat = 0, pFormat = ps->formats; - nformat < ps->nformats; - nformat++, pFormat++) - { - pictForm->id = pFormat->id; - pictForm->type = pFormat->type; - pictForm->depth = pFormat->depth; - pictForm->direct.red = pFormat->direct.red; - pictForm->direct.redMask = pFormat->direct.redMask; - pictForm->direct.green = pFormat->direct.green; - pictForm->direct.greenMask = pFormat->direct.greenMask; - pictForm->direct.blue = pFormat->direct.blue; - pictForm->direct.blueMask = pFormat->direct.blueMask; - pictForm->direct.alpha = pFormat->direct.alpha; - pictForm->direct.alphaMask = pFormat->direct.alphaMask; - if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap) - pictForm->colormap = pFormat->index.pColormap->mid; - else - pictForm->colormap = None; - if (client->swapped) - { - swapl (&pictForm->id, n); - swaps (&pictForm->direct.red, n); - swaps (&pictForm->direct.redMask, n); - swaps (&pictForm->direct.green, n); - swaps (&pictForm->direct.greenMask, n); - swaps (&pictForm->direct.blue, n); - swaps (&pictForm->direct.blueMask, n); - swaps (&pictForm->direct.alpha, n); - swaps (&pictForm->direct.alphaMask, n); - swapl (&pictForm->colormap, n); - } - pictForm++; - } - } - } - - pictScreen = (xPictScreen *) pictForm; - for (s = 0; s < numScreens; s++) - { - pScreen = screenInfo.screens[s]; - pictDepth = (xPictDepth *) (pictScreen + 1); - ndepth = 0; - for (d = 0; d < pScreen->numDepths; d++) - { - pictVisual = (xPictVisual *) (pictDepth + 1); - pDepth = pScreen->allowedDepths + d; - - nvisual = 0; - for (v = 0; v < pDepth->numVids; v++) - { - pVisual = findVisual (pScreen, pDepth->vids[v]); - if (pVisual && (pFormat = PictureMatchVisual (pScreen, - pDepth->depth, - pVisual))) - { - pictVisual->visual = pVisual->vid; - pictVisual->format = pFormat->id; - if (client->swapped) - { - swapl (&pictVisual->visual, n); - swapl (&pictVisual->format, n); - } - pictVisual++; - nvisual++; - } - } - pictDepth->depth = pDepth->depth; - pictDepth->nPictVisuals = nvisual; - if (client->swapped) - { - swaps (&pictDepth->nPictVisuals, n); - } - ndepth++; - pictDepth = (xPictDepth *) pictVisual; - } - pictScreen->nDepth = ndepth; - ps = GetPictureScreenIfSet(pScreen); - if (ps) - pictScreen->fallback = ps->fallback->id; - else - pictScreen->fallback = 0; - if (client->swapped) - { - swapl (&pictScreen->nDepth, n); - swapl (&pictScreen->fallback, n); - } - pictScreen = (xPictScreen *) pictDepth; - } - pictSubpixel = (CARD32 *) pictScreen; - - for (s = 0; s < numSubpixel; s++) - { - pScreen = screenInfo.screens[s]; - ps = GetPictureScreenIfSet(pScreen); - if (ps) - *pictSubpixel = ps->subpixel; - else - *pictSubpixel = SubPixelUnknown; - if (client->swapped) - { - swapl (pictSubpixel, n); - } - ++pictSubpixel; - } - - if (client->swapped) - { - swaps (&reply->sequenceNumber, n); - swapl (&reply->length, n); - swapl (&reply->numFormats, n); - swapl (&reply->numScreens, n); - swapl (&reply->numDepths, n); - swapl (&reply->numVisuals, n); - swapl (&reply->numSubpixel, n); - } - WriteToClient(client, rlength, (char *) reply); - free(reply); - return Success; -} - -static int -ProcRenderQueryPictIndexValues (ClientPtr client) -{ - PictFormatPtr pFormat; - int rc, num; - int rlength; - int i, n; - REQUEST(xRenderQueryPictIndexValuesReq); - xRenderQueryPictIndexValuesReply *reply; - xIndexValue *values; - - REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq); - - rc = dixLookupResourceByType((pointer *)&pFormat, stuff->format, - PictFormatType, client, DixReadAccess); - if (rc != Success) - return rc; - - if (pFormat->type != PictTypeIndexed) - { - client->errorValue = stuff->format; - return BadMatch; - } - num = pFormat->index.nvalues; - rlength = (sizeof (xRenderQueryPictIndexValuesReply) + - num * sizeof(xIndexValue)); - reply = (xRenderQueryPictIndexValuesReply *) malloc(rlength); - if (!reply) - return BadAlloc; - - reply->type = X_Reply; - reply->sequenceNumber = client->sequence; - reply->length = bytes_to_int32(rlength - sizeof(xGenericReply)); - reply->numIndexValues = num; - - values = (xIndexValue *) (reply + 1); - - memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue)); - - if (client->swapped) - { - for (i = 0; i < num; i++) - { - swapl (&values[i].pixel, n); - swaps (&values[i].red, n); - swaps (&values[i].green, n); - swaps (&values[i].blue, n); - swaps (&values[i].alpha, n); - } - swaps (&reply->sequenceNumber, n); - swapl (&reply->length, n); - swapl (&reply->numIndexValues, n); - } - - WriteToClient(client, rlength, (char *) reply); - free(reply); - return Success; -} - -static int -ProcRenderQueryDithers (ClientPtr client) -{ - return BadImplementation; -} - -static int -ProcRenderCreatePicture (ClientPtr client) -{ - PicturePtr pPicture; - DrawablePtr pDrawable; - PictFormatPtr pFormat; - int len, error, rc; - REQUEST(xRenderCreatePictureReq); - - REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); - - LEGAL_NEW_RESOURCE(stuff->pid, client); - rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, - DixReadAccess|DixAddAccess); - if (rc != Success) - return rc; - - rc = dixLookupResourceByType((pointer *)&pFormat, stuff->format, - PictFormatType, client, DixReadAccess); - if (rc != Success) - return rc; - - if (pFormat->depth != pDrawable->depth) - return BadMatch; - len = client->req_len - bytes_to_int32(sizeof(xRenderCreatePictureReq)); - if (Ones(stuff->mask) != len) - return BadLength; - - pPicture = CreatePicture (stuff->pid, - pDrawable, - pFormat, - stuff->mask, - (XID *) (stuff + 1), - client, - &error); - if (!pPicture) - return error; - if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) - return BadAlloc; - return Success; -} - -static int -ProcRenderChangePicture (ClientPtr client) -{ - PicturePtr pPicture; - REQUEST(xRenderChangePictureReq); - int len; - - REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq); - VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess); - - len = client->req_len - bytes_to_int32(sizeof(xRenderChangePictureReq)); - if (Ones(stuff->mask) != len) - return BadLength; - - return ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1), - (DevUnion *) 0, client); -} - -static int -ProcRenderSetPictureClipRectangles (ClientPtr client) -{ - REQUEST(xRenderSetPictureClipRectanglesReq); - PicturePtr pPicture; - int nr; - - REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); - VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess); - if (!pPicture->pDrawable) - return BadDrawable; - - nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq); - if (nr & 4) - return BadLength; - nr >>= 3; - return SetPictureClipRects (pPicture, - stuff->xOrigin, stuff->yOrigin, - nr, (xRectangle *) &stuff[1]); -} - -static int -ProcRenderFreePicture (ClientPtr client) -{ - PicturePtr pPicture; - REQUEST(xRenderFreePictureReq); - - REQUEST_SIZE_MATCH(xRenderFreePictureReq); - - VERIFY_PICTURE (pPicture, stuff->picture, client, DixDestroyAccess); - FreeResource (stuff->picture, RT_NONE); - return Success; -} - -static Bool -PictOpValid (CARD8 op) -{ - if (/*PictOpMinimum <= op && */ op <= PictOpMaximum) - return TRUE; - if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum) - return TRUE; - if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum) - return TRUE; - if (PictOpBlendMinimum <= op && op <= PictOpBlendMaximum) - return TRUE; - return FALSE; -} - -static int -ProcRenderComposite (ClientPtr client) -{ - PicturePtr pSrc, pMask, pDst; - REQUEST(xRenderCompositeReq); - - REQUEST_SIZE_MATCH(xRenderCompositeReq); - if (!PictOpValid (stuff->op)) - { - client->errorValue = stuff->op; - return BadValue; - } - VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); - if (!pDst->pDrawable) - return BadDrawable; - VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); - VERIFY_ALPHA (pMask, stuff->mask, client, DixReadAccess); - if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) || - (pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen)) - return BadMatch; - CompositePicture (stuff->op, - pSrc, - pMask, - pDst, - stuff->xSrc, - stuff->ySrc, - stuff->xMask, - stuff->yMask, - stuff->xDst, - stuff->yDst, - stuff->width, - stuff->height); - return Success; -} - -static int -ProcRenderScale (ClientPtr client) -{ - return BadImplementation; -} - -static int -ProcRenderTrapezoids (ClientPtr client) -{ - int rc, ntraps; - PicturePtr pSrc, pDst; - PictFormatPtr pFormat; - REQUEST(xRenderTrapezoidsReq); - - REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq); - if (!PictOpValid (stuff->op)) - { - client->errorValue = stuff->op; - return BadValue; - } - VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); - VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); - if (!pDst->pDrawable) - return BadDrawable; - if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) - return BadMatch; - if (stuff->maskFormat) - { - rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat, - PictFormatType, client, DixReadAccess); - if (rc != Success) - return rc; - } - else - pFormat = 0; - ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq); - if (ntraps % sizeof (xTrapezoid)) - return BadLength; - ntraps /= sizeof (xTrapezoid); - if (ntraps) - CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat, - stuff->xSrc, stuff->ySrc, - ntraps, (xTrapezoid *) &stuff[1]); - return Success; -} - -static int -ProcRenderTriangles (ClientPtr client) -{ - int rc, ntris; - PicturePtr pSrc, pDst; - PictFormatPtr pFormat; - REQUEST(xRenderTrianglesReq); - - REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); - if (!PictOpValid (stuff->op)) - { - client->errorValue = stuff->op; - return BadValue; - } - VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); - VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); - if (!pDst->pDrawable) - return BadDrawable; - if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) - return BadMatch; - if (stuff->maskFormat) - { - rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat, - PictFormatType, client, DixReadAccess); - if (rc != Success) - return rc; - } - else - pFormat = 0; - ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq); - if (ntris % sizeof (xTriangle)) - return BadLength; - ntris /= sizeof (xTriangle); - if (ntris) - CompositeTriangles (stuff->op, pSrc, pDst, pFormat, - stuff->xSrc, stuff->ySrc, - ntris, (xTriangle *) &stuff[1]); - return Success; -} - -static int -ProcRenderTriStrip (ClientPtr client) -{ - int rc, npoints; - PicturePtr pSrc, pDst; - PictFormatPtr pFormat; - REQUEST(xRenderTrianglesReq); - - REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); - if (!PictOpValid (stuff->op)) - { - client->errorValue = stuff->op; - return BadValue; - } - VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); - VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); - if (!pDst->pDrawable) - return BadDrawable; - if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) - return BadMatch; - if (stuff->maskFormat) - { - rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat, - PictFormatType, client, DixReadAccess); - if (rc != Success) - return rc; - } - else - pFormat = 0; - npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq)); - if (npoints & 4) - return BadLength; - npoints >>= 3; - if (npoints >= 3) - CompositeTriStrip (stuff->op, pSrc, pDst, pFormat, - stuff->xSrc, stuff->ySrc, - npoints, (xPointFixed *) &stuff[1]); - return Success; -} - -static int -ProcRenderTriFan (ClientPtr client) -{ - int rc, npoints; - PicturePtr pSrc, pDst; - PictFormatPtr pFormat; - REQUEST(xRenderTrianglesReq); - - REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); - if (!PictOpValid (stuff->op)) - { - client->errorValue = stuff->op; - return BadValue; - } - VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); - VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); - if (!pDst->pDrawable) - return BadDrawable; - if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) - return BadMatch; - if (stuff->maskFormat) - { - rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat, - PictFormatType, client, DixReadAccess); - if (rc != Success) - return rc; - } - else - pFormat = 0; - npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq)); - if (npoints & 4) - return BadLength; - npoints >>= 3; - if (npoints >= 3) - CompositeTriFan (stuff->op, pSrc, pDst, pFormat, - stuff->xSrc, stuff->ySrc, - npoints, (xPointFixed *) &stuff[1]); - return Success; -} - -static int -ProcRenderColorTrapezoids (ClientPtr client) -{ - return BadImplementation; -} - -static int -ProcRenderColorTriangles (ClientPtr client) -{ - return BadImplementation; -} - -static int -ProcRenderTransform (ClientPtr client) -{ - return BadImplementation; -} - -static int -ProcRenderCreateGlyphSet (ClientPtr client) -{ - GlyphSetPtr glyphSet; - PictFormatPtr format; - int rc, f; - REQUEST(xRenderCreateGlyphSetReq); - - REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq); - - LEGAL_NEW_RESOURCE(stuff->gsid, client); - rc = dixLookupResourceByType((pointer *)&format, stuff->format, - PictFormatType, client, DixReadAccess); - if (rc != Success) - return rc; - - switch (format->depth) { - case 1: - f = GlyphFormat1; - break; - case 4: - f = GlyphFormat4; - break; - case 8: - f = GlyphFormat8; - break; - case 16: - f = GlyphFormat16; - break; - case 32: - f = GlyphFormat32; - break; - default: - return BadMatch; - } - if (format->type != PictTypeDirect) - return BadMatch; - glyphSet = AllocateGlyphSet (f, format); - if (!glyphSet) - return BadAlloc; - /* security creation/labeling check */ - rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->gsid, GlyphSetType, - glyphSet, RT_NONE, NULL, DixCreateAccess); - if (rc != Success) - return rc; - if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet)) - return BadAlloc; - return Success; -} - -static int -ProcRenderReferenceGlyphSet (ClientPtr client) -{ - GlyphSetPtr glyphSet; - int rc; - REQUEST(xRenderReferenceGlyphSetReq); - - REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq); - - LEGAL_NEW_RESOURCE(stuff->gsid, client); - - rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->existing, GlyphSetType, - client, DixGetAttrAccess); - if (rc != Success) - { - client->errorValue = stuff->existing; - return rc; - } - glyphSet->refcnt++; - if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet)) - return BadAlloc; - return Success; -} - -#define NLOCALDELTA 64 -#define NLOCALGLYPH 256 - -static int -ProcRenderFreeGlyphSet (ClientPtr client) -{ - GlyphSetPtr glyphSet; - int rc; - REQUEST(xRenderFreeGlyphSetReq); - - REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq); - rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType, - client, DixDestroyAccess); - if (rc != Success) - { - client->errorValue = stuff->glyphset; - return rc; - } - FreeResource (stuff->glyphset, RT_NONE); - return Success; -} - -typedef struct _GlyphNew { - Glyph id; - GlyphPtr glyph; - Bool found; - unsigned char sha1[20]; -} GlyphNewRec, *GlyphNewPtr; - -#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) - -static int -ProcRenderAddGlyphs (ClientPtr client) -{ - GlyphSetPtr glyphSet; - REQUEST(xRenderAddGlyphsReq); - GlyphNewRec glyphsLocal[NLOCALGLYPH]; - GlyphNewPtr glyphsBase, glyphs, glyph_new; - int remain, nglyphs; - CARD32 *gids; - xGlyphInfo *gi; - CARD8 *bits; - unsigned int size; - int err; - int i, screen; - PicturePtr pSrc = NULL, pDst = NULL; - PixmapPtr pSrcPix = NULL, pDstPix = NULL; - CARD32 component_alpha; - - REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); - err = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType, - client, DixAddAccess); - if (err != Success) - { - client->errorValue = stuff->glyphset; - return err; - } - - err = BadAlloc; - nglyphs = stuff->nglyphs; - if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec)) - return BadAlloc; - - component_alpha = NeedsComponent (glyphSet->format->format); - - if (nglyphs <= NLOCALGLYPH) { - memset (glyphsLocal, 0, sizeof (glyphsLocal)); - glyphsBase = glyphsLocal; - } - else - { - glyphsBase = (GlyphNewPtr)calloc(nglyphs, sizeof (GlyphNewRec)); - if (!glyphsBase) - return BadAlloc; - } - - remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq); - - glyphs = glyphsBase; - - gids = (CARD32 *) (stuff + 1); - gi = (xGlyphInfo *) (gids + nglyphs); - bits = (CARD8 *) (gi + nglyphs); - remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs; - - /* protect against bad nglyphs */ - if (gi < ((xGlyphInfo *)stuff) || - gi > ((xGlyphInfo *)((CARD32 *)stuff + client->req_len)) || - bits < ((CARD8 *)stuff) || - bits > ((CARD8 *)((CARD32 *)stuff + client->req_len))) { - err = BadLength; - goto bail; - } - - for (i = 0; i < nglyphs; i++) - { - size_t padded_width; - glyph_new = &glyphs[i]; - - padded_width = PixmapBytePad (gi[i].width, - glyphSet->format->depth); - - if (gi[i].height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi[i].height) - break; - - size = gi[i].height * padded_width; - if (remain < size) - break; - - err = HashGlyph (&gi[i], bits, size, glyph_new->sha1); - if (err) - goto bail; - - glyph_new->glyph = FindGlyphByHash (glyph_new->sha1, - glyphSet->fdepth); - - if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) - { - glyph_new->found = TRUE; - } - else - { - GlyphPtr glyph; - - glyph_new->found = FALSE; - glyph_new->glyph = glyph = AllocateGlyph (&gi[i], glyphSet->fdepth); - if (! glyph) - { - err = BadAlloc; - goto bail; - } - - for (screen = 0; screen < screenInfo.numScreens; screen++) - { - int width = gi[i].width; - int height = gi[i].height; - int depth = glyphSet->format->depth; - ScreenPtr pScreen; - int error; - - /* Skip work if it's invisibly small anyway */ - if (!width || !height) - break; - - pScreen = screenInfo.screens[screen]; - pSrcPix = GetScratchPixmapHeader (pScreen, - width, height, - depth, depth, - -1, bits); - if (! pSrcPix) - { - err = BadAlloc; - goto bail; - } - - pSrc = CreatePicture (0, &pSrcPix->drawable, - glyphSet->format, 0, NULL, - serverClient, &error); - if (! pSrc) - { - err = BadAlloc; - goto bail; - } - - pDstPix = (pScreen->CreatePixmap) (pScreen, - width, height, depth, - CREATE_PIXMAP_USAGE_GLYPH_PICTURE); - - if (!pDstPix) - { - err = BadAlloc; - goto bail; - } - - GlyphPicture (glyph)[screen] = pDst = - CreatePicture (0, &pDstPix->drawable, - glyphSet->format, - CPComponentAlpha, &component_alpha, - serverClient, &error); - - /* The picture takes a reference to the pixmap, so we - drop ours. */ - (pScreen->DestroyPixmap) (pDstPix); - pDstPix = NULL; - - if (! pDst) - { - err = BadAlloc; - goto bail; - } - - CompositePicture (PictOpSrc, - pSrc, - None, - pDst, - 0, 0, - 0, 0, - 0, 0, - width, height); - - FreePicture ((pointer) pSrc, 0); - pSrc = NULL; - FreeScratchPixmapHeader (pSrcPix); - pSrcPix = NULL; - } - - memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20); - } - - glyph_new->id = gids[i]; - - if (size & 3) - size += 4 - (size & 3); - bits += size; - remain -= size; - } - if (remain || i < nglyphs) - { - err = BadLength; - goto bail; - } - if (!ResizeGlyphSet (glyphSet, nglyphs)) - { - err = BadAlloc; - goto bail; - } - for (i = 0; i < nglyphs; i++) - AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id); - - if (glyphsBase != glyphsLocal) - free(glyphsBase); - return Success; -bail: - if (pSrc) - FreePicture ((pointer) pSrc, 0); - if (pSrcPix) - FreeScratchPixmapHeader (pSrcPix); - for (i = 0; i < nglyphs; i++) - if (glyphs[i].glyph && ! glyphs[i].found) - free(glyphs[i].glyph); - if (glyphsBase != glyphsLocal) - free(glyphsBase); - return err; -} - -static int -ProcRenderAddGlyphsFromPicture (ClientPtr client) -{ - return BadImplementation; -} - -static int -ProcRenderFreeGlyphs (ClientPtr client) -{ - REQUEST(xRenderFreeGlyphsReq); - GlyphSetPtr glyphSet; - int rc, nglyph; - CARD32 *gids; - CARD32 glyph; - - REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq); - rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType, - client, DixRemoveAccess); - if (rc != Success) - { - client->errorValue = stuff->glyphset; - return rc; - } - nglyph = bytes_to_int32((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)); - gids = (CARD32 *) (stuff + 1); - while (nglyph-- > 0) - { - glyph = *gids++; - if (!DeleteGlyph (glyphSet, glyph)) - { - client->errorValue = glyph; - return RenderErrBase + BadGlyph; - } - } - return Success; -} - -static int -ProcRenderCompositeGlyphs (ClientPtr client) -{ - GlyphSetPtr glyphSet; - GlyphSet gs; - PicturePtr pSrc, pDst; - PictFormatPtr pFormat; - GlyphListRec listsLocal[NLOCALDELTA]; - GlyphListPtr lists, listsBase; - GlyphPtr glyphsLocal[NLOCALGLYPH]; - Glyph glyph; - GlyphPtr *glyphs, *glyphsBase; - xGlyphElt *elt; - CARD8 *buffer, *end; - int nglyph; - int nlist; - int space; - int size; - int rc, n; - - REQUEST(xRenderCompositeGlyphsReq); - - REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); - - switch (stuff->renderReqType) { - default: size = 1; break; - case X_RenderCompositeGlyphs16: size = 2; break; - case X_RenderCompositeGlyphs32: size = 4; break; - } - - if (!PictOpValid (stuff->op)) - { - client->errorValue = stuff->op; - return BadValue; - } - VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); - VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); - if (!pDst->pDrawable) - return BadDrawable; - if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) - return BadMatch; - if (stuff->maskFormat) - { - rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat, - PictFormatType, client, DixReadAccess); - if (rc != Success) - return rc; - } - else - pFormat = 0; - - rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, - GlyphSetType, client, DixUseAccess); - if (rc != Success) - return rc; - - buffer = (CARD8 *) (stuff + 1); - end = (CARD8 *) stuff + (client->req_len << 2); - nglyph = 0; - nlist = 0; - while (buffer + sizeof (xGlyphElt) < end) - { - elt = (xGlyphElt *) buffer; - buffer += sizeof (xGlyphElt); - - if (elt->len == 0xff) - { - buffer += 4; - } - else - { - nlist++; - nglyph += elt->len; - space = size * elt->len; - if (space & 3) - space += 4 - (space & 3); - buffer += space; - } - } - if (nglyph <= NLOCALGLYPH) - glyphsBase = glyphsLocal; - else - { - glyphsBase = (GlyphPtr *) malloc(nglyph * sizeof (GlyphPtr)); - if (!glyphsBase) - return BadAlloc; - } - if (nlist <= NLOCALDELTA) - listsBase = listsLocal; - else - { - listsBase = (GlyphListPtr) malloc(nlist * sizeof (GlyphListRec)); - if (!listsBase) - return BadAlloc; - } - buffer = (CARD8 *) (stuff + 1); - glyphs = glyphsBase; - lists = listsBase; - while (buffer + sizeof (xGlyphElt) < end) - { - elt = (xGlyphElt *) buffer; - buffer += sizeof (xGlyphElt); - - if (elt->len == 0xff) - { - if (buffer + sizeof (GlyphSet) < end) - { - memcpy(&gs, buffer, sizeof(GlyphSet)); - rc = dixLookupResourceByType((pointer *)&glyphSet, gs, - GlyphSetType, client, - DixUseAccess); - if (rc != Success) - { - if (glyphsBase != glyphsLocal) - free(glyphsBase); - if (listsBase != listsLocal) - free(listsBase); - return rc; - } - } - buffer += 4; - } - else - { - lists->xOff = elt->deltax; - lists->yOff = elt->deltay; - lists->format = glyphSet->format; - lists->len = 0; - n = elt->len; - while (n--) - { - if (buffer + size <= end) - { - switch (size) { - case 1: - glyph = *((CARD8 *)buffer); break; - case 2: - glyph = *((CARD16 *)buffer); break; - case 4: - default: - glyph = *((CARD32 *)buffer); break; - } - if ((*glyphs = FindGlyph (glyphSet, glyph))) - { - lists->len++; - glyphs++; - } - } - buffer += size; - } - space = size * elt->len; - if (space & 3) - buffer += 4 - (space & 3); - lists++; - } - } - if (buffer > end) - return BadLength; - - CompositeGlyphs (stuff->op, - pSrc, - pDst, - pFormat, - stuff->xSrc, - stuff->ySrc, - nlist, - listsBase, - glyphsBase); - - if (glyphsBase != glyphsLocal) - free(glyphsBase); - if (listsBase != listsLocal) - free(listsBase); - - return Success; -} - -static int -ProcRenderFillRectangles (ClientPtr client) -{ - PicturePtr pDst; - int things; - REQUEST(xRenderFillRectanglesReq); - - REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq); - if (!PictOpValid (stuff->op)) - { - client->errorValue = stuff->op; - return BadValue; - } - VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); - if (!pDst->pDrawable) - return BadDrawable; - - things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq); - if (things & 4) - return BadLength; - things >>= 3; - - CompositeRects (stuff->op, - pDst, - &stuff->color, - things, - (xRectangle *) &stuff[1]); - - return Success; -} - -static void -RenderSetBit (unsigned char *line, int x, int bit) -{ - unsigned char mask; - - if (screenInfo.bitmapBitOrder == LSBFirst) - mask = (1 << (x & 7)); - else - mask = (0x80 >> (x & 7)); - /* XXX assumes byte order is host byte order */ - line += (x >> 3); - if (bit) - *line |= mask; - else - *line &= ~mask; -} - -#define DITHER_DIM 2 - -static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = { - { 1, 3, }, - { 4, 2, }, -}; - -#define DITHER_SIZE ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1) - -static int -ProcRenderCreateCursor (ClientPtr client) -{ - REQUEST(xRenderCreateCursorReq); - PicturePtr pSrc; - ScreenPtr pScreen; - unsigned short width, height; - CARD32 *argbbits, *argb; - unsigned char *srcbits, *srcline; - unsigned char *mskbits, *mskline; - int stride; - int x, y; - int nbytes_mono; - CursorMetricRec cm; - CursorPtr pCursor; - CARD32 twocolor[3]; - int rc, ncolor; - - REQUEST_SIZE_MATCH (xRenderCreateCursorReq); - LEGAL_NEW_RESOURCE(stuff->cid, client); - - VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); - if (!pSrc->pDrawable) - return BadDrawable; - pScreen = pSrc->pDrawable->pScreen; - width = pSrc->pDrawable->width; - height = pSrc->pDrawable->height; - if (height && width > UINT32_MAX/(height*sizeof(CARD32))) - return BadAlloc; - if ( stuff->x > width - || stuff->y > height ) - return BadMatch; - argbbits = malloc(width * height * sizeof (CARD32)); - if (!argbbits) - return BadAlloc; - - stride = BitmapBytePad(width); - nbytes_mono = stride*height; - srcbits = calloc(1, nbytes_mono); - if (!srcbits) - { - free(argbbits); - return BadAlloc; - } - mskbits = calloc(1, nbytes_mono); - if (!mskbits) - { - free(argbbits); - free(srcbits); - return BadAlloc; - } - - if (pSrc->format == PICT_a8r8g8b8) - { - (*pScreen->GetImage) (pSrc->pDrawable, - 0, 0, width, height, ZPixmap, - 0xffffffff, (pointer) argbbits); - } - else - { - PixmapPtr pPixmap; - PicturePtr pPicture; - PictFormatPtr pFormat; - int error; - - pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8); - if (!pFormat) - { - free(argbbits); - free(srcbits); - free(mskbits); - return BadImplementation; - } - pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32, - CREATE_PIXMAP_USAGE_SCRATCH); - if (!pPixmap) - { - free(argbbits); - free(srcbits); - free(mskbits); - return BadAlloc; - } - pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0, - client, &error); - if (!pPicture) - { - free(argbbits); - free(srcbits); - free(mskbits); - return error; - } - (*pScreen->DestroyPixmap) (pPixmap); - CompositePicture (PictOpSrc, - pSrc, 0, pPicture, - 0, 0, 0, 0, 0, 0, width, height); - (*pScreen->GetImage) (pPicture->pDrawable, - 0, 0, width, height, ZPixmap, - 0xffffffff, (pointer) argbbits); - FreePicture (pPicture, 0); - } - /* - * Check whether the cursor can be directly supported by - * the core cursor code - */ - ncolor = 0; - argb = argbbits; - for (y = 0; ncolor <= 2 && y < height; y++) - { - for (x = 0; ncolor <= 2 && x < width; x++) - { - CARD32 p = *argb++; - CARD32 a = (p >> 24); - - if (a == 0) /* transparent */ - continue; - if (a == 0xff) /* opaque */ - { - int n; - for (n = 0; n < ncolor; n++) - if (p == twocolor[n]) - break; - if (n == ncolor) - twocolor[ncolor++] = p; - } - else - ncolor = 3; - } - } - - /* - * Convert argb image to two plane cursor - */ - srcline = srcbits; - mskline = mskbits; - argb = argbbits; - for (y = 0; y < height; y++) - { - for (x = 0; x < width; x++) - { - CARD32 p = *argb++; - - if (ncolor <= 2) - { - CARD32 a = ((p >> 24)); - - RenderSetBit (mskline, x, a != 0); - RenderSetBit (srcline, x, a != 0 && p == twocolor[0]); - } - else - { - CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255; - CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255; - CARD32 d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)]; - /* Set mask from dithered alpha value */ - RenderSetBit(mskline, x, a > d); - /* Set src from dithered intensity value */ - RenderSetBit(srcline, x, a > d && i <= d); - } - } - srcline += stride; - mskline += stride; - } - /* - * Dither to white and black if the cursor has more than two colors - */ - if (ncolor > 2) - { - twocolor[0] = 0xff000000; - twocolor[1] = 0xffffffff; - } - else - { - free(argbbits); - argbbits = 0; - } - -#define GetByte(p,s) (((p) >> (s)) & 0xff) -#define GetColor(p,s) (GetByte(p,s) | (GetByte(p,s) << 8)) - - cm.width = width; - cm.height = height; - cm.xhot = stuff->x; - cm.yhot = stuff->y; - rc = AllocARGBCursor(srcbits, mskbits, argbbits, &cm, - GetColor(twocolor[0], 16), - GetColor(twocolor[0], 8), - GetColor(twocolor[0], 0), - GetColor(twocolor[1], 16), - GetColor(twocolor[1], 8), - GetColor(twocolor[1], 0), - &pCursor, client, stuff->cid); - if (rc != Success) - return rc; - if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) - return BadAlloc; - - return Success; -} - -static int -ProcRenderSetPictureTransform (ClientPtr client) -{ - REQUEST(xRenderSetPictureTransformReq); - PicturePtr pPicture; - - REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq); - VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess); - return SetPictureTransform (pPicture, (PictTransform *) &stuff->transform); -} - -static int -ProcRenderQueryFilters (ClientPtr client) -{ - REQUEST (xRenderQueryFiltersReq); - DrawablePtr pDrawable; - xRenderQueryFiltersReply *reply; - int nbytesName; - int nnames; - ScreenPtr pScreen; - PictureScreenPtr ps; - int i, j, len, total_bytes, rc; - INT16 *aliases; - char *names; - - REQUEST_SIZE_MATCH(xRenderQueryFiltersReq); - rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, - DixGetAttrAccess); - if (rc != Success) - return rc; - - pScreen = pDrawable->pScreen; - nbytesName = 0; - nnames = 0; - ps = GetPictureScreenIfSet(pScreen); - if (ps) - { - for (i = 0; i < ps->nfilters; i++) - nbytesName += 1 + strlen (ps->filters[i].name); - for (i = 0; i < ps->nfilterAliases; i++) - nbytesName += 1 + strlen (ps->filterAliases[i].alias); - nnames = ps->nfilters + ps->nfilterAliases; - } - len = ((nnames + 1) >> 1) + bytes_to_int32(nbytesName); - total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2); - reply = (xRenderQueryFiltersReply *) malloc(total_bytes); - if (!reply) - return BadAlloc; - aliases = (INT16 *) (reply + 1); - names = (char *) (aliases + ((nnames + 1) & ~1)); - - reply->type = X_Reply; - reply->sequenceNumber = client->sequence; - reply->length = len; - reply->numAliases = nnames; - reply->numFilters = nnames; - if (ps) - { - - /* fill in alias values */ - for (i = 0; i < ps->nfilters; i++) - aliases[i] = FilterAliasNone; - for (i = 0; i < ps->nfilterAliases; i++) - { - for (j = 0; j < ps->nfilters; j++) - if (ps->filterAliases[i].filter_id == ps->filters[j].id) - break; - if (j == ps->nfilters) - { - for (j = 0; j < ps->nfilterAliases; j++) - if (ps->filterAliases[i].filter_id == - ps->filterAliases[j].alias_id) - { - break; - } - if (j == ps->nfilterAliases) - j = FilterAliasNone; - else - j = j + ps->nfilters; - } - aliases[i + ps->nfilters] = j; - } - - /* fill in filter names */ - for (i = 0; i < ps->nfilters; i++) - { - j = strlen (ps->filters[i].name); - *names++ = j; - strncpy (names, ps->filters[i].name, j); - names += j; - } - - /* fill in filter alias names */ - for (i = 0; i < ps->nfilterAliases; i++) - { - j = strlen (ps->filterAliases[i].alias); - *names++ = j; - strncpy (names, ps->filterAliases[i].alias, j); - names += j; - } - } - - if (client->swapped) - { - register int n; - - for (i = 0; i < reply->numAliases; i++) - { - swaps (&aliases[i], n); - } - swaps(&reply->sequenceNumber, n); - swapl(&reply->length, n); - swapl(&reply->numAliases, n); - swapl(&reply->numFilters, n); - } - WriteToClient(client, total_bytes, (char *) reply); - free(reply); - - return Success; -} - -static int -ProcRenderSetPictureFilter (ClientPtr client) -{ - REQUEST (xRenderSetPictureFilterReq); - PicturePtr pPicture; - int result; - xFixed *params; - int nparams; - char *name; - - REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq); - VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess); - name = (char *) (stuff + 1); - params = (xFixed *) (name + pad_to_int32(stuff->nbytes)); - nparams = ((xFixed *) stuff + client->req_len) - params; - result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams); - return result; -} - -static int -ProcRenderCreateAnimCursor (ClientPtr client) -{ - REQUEST(xRenderCreateAnimCursorReq); - CursorPtr *cursors; - CARD32 *deltas; - CursorPtr pCursor; - int ncursor; - xAnimCursorElt *elt; - int i; - int ret; - - REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq); - LEGAL_NEW_RESOURCE(stuff->cid, client); - if (client->req_len & 1) - return BadLength; - ncursor = (client->req_len - (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1; - cursors = malloc(ncursor * (sizeof (CursorPtr) + sizeof (CARD32))); - if (!cursors) - return BadAlloc; - deltas = (CARD32 *) (cursors + ncursor); - elt = (xAnimCursorElt *) (stuff + 1); - for (i = 0; i < ncursor; i++) - { - ret = dixLookupResourceByType((pointer *)(cursors + i), elt->cursor, - RT_CURSOR, client, DixReadAccess); - if (ret != Success) - { - free(cursors); - return ret; - } - deltas[i] = elt->delay; - elt++; - } - ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor, client, - stuff->cid); - free(cursors); - if (ret != Success) - return ret; - - if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor)) - return Success; - return BadAlloc; -} - -static int -ProcRenderAddTraps (ClientPtr client) -{ - int ntraps; - PicturePtr pPicture; - REQUEST(xRenderAddTrapsReq); - - REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq); - VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess); - if (!pPicture->pDrawable) - return BadDrawable; - ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq); - if (ntraps % sizeof (xTrap)) - return BadLength; - ntraps /= sizeof (xTrap); - if (ntraps) - AddTraps (pPicture, - stuff->xOff, stuff->yOff, - ntraps, (xTrap *) &stuff[1]); - return Success; -} - -static int ProcRenderCreateSolidFill(ClientPtr client) -{ - PicturePtr pPicture; - int error = 0; - REQUEST(xRenderCreateSolidFillReq); - - REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq); - - LEGAL_NEW_RESOURCE(stuff->pid, client); - - pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error); - if (!pPicture) - return error; - /* security creation/labeling check */ - error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, - pPicture, RT_NONE, NULL, DixCreateAccess); - if (error != Success) - return error; - if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) - return BadAlloc; - return Success; -} - -static int ProcRenderCreateLinearGradient (ClientPtr client) -{ - PicturePtr pPicture; - int len; - int error = 0; - xFixed *stops; - xRenderColor *colors; - REQUEST(xRenderCreateLinearGradientReq); - - REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq); - - LEGAL_NEW_RESOURCE(stuff->pid, client); - - len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq); - if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) - return BadLength; - if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) - return BadLength; - - stops = (xFixed *)(stuff + 1); - colors = (xRenderColor *)(stops + stuff->nStops); - - pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2, - stuff->nStops, stops, colors, &error); - if (!pPicture) - return error; - /* security creation/labeling check */ - error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, - pPicture, RT_NONE, NULL, DixCreateAccess); - if (error != Success) - return error; - if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) - return BadAlloc; - return Success; -} - -static int ProcRenderCreateRadialGradient (ClientPtr client) -{ - PicturePtr pPicture; - int len; - int error = 0; - xFixed *stops; - xRenderColor *colors; - REQUEST(xRenderCreateRadialGradientReq); - - REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq); - - LEGAL_NEW_RESOURCE(stuff->pid, client); - - len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq); - if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) - return BadLength; - - stops = (xFixed *)(stuff + 1); - colors = (xRenderColor *)(stops + stuff->nStops); - - pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer, - stuff->inner_radius, stuff->outer_radius, - stuff->nStops, stops, colors, &error); - if (!pPicture) - return error; - /* security creation/labeling check */ - error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, - pPicture, RT_NONE, NULL, DixCreateAccess); - if (error != Success) - return error; - if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) - return BadAlloc; - return Success; -} - -static int ProcRenderCreateConicalGradient (ClientPtr client) -{ - PicturePtr pPicture; - int len; - int error = 0; - xFixed *stops; - xRenderColor *colors; - REQUEST(xRenderCreateConicalGradientReq); - - REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq); - - LEGAL_NEW_RESOURCE(stuff->pid, client); - - len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq); - if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) - return BadLength; - - stops = (xFixed *)(stuff + 1); - colors = (xRenderColor *)(stops + stuff->nStops); - - pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle, - stuff->nStops, stops, colors, &error); - if (!pPicture) - return error; - /* security creation/labeling check */ - error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, - pPicture, RT_NONE, NULL, DixCreateAccess); - if (error != Success) - return error; - if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) - return BadAlloc; - return Success; -} - - -static int -ProcRenderDispatch (ClientPtr client) -{ - REQUEST(xReq); - - if (stuff->data < RenderNumberRequests) - return (*ProcRenderVector[stuff->data]) (client); - else - return BadRequest; -} - -static int -SProcRenderQueryVersion (ClientPtr client) -{ - register int n; - REQUEST(xRenderQueryVersionReq); - - swaps(&stuff->length, n); - swapl(&stuff->majorVersion, n); - swapl(&stuff->minorVersion, n); - return (*ProcRenderVector[stuff->renderReqType])(client); -} - -static int -SProcRenderQueryPictFormats (ClientPtr client) -{ - register int n; - REQUEST(xRenderQueryPictFormatsReq); - swaps(&stuff->length, n); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderQueryPictIndexValues (ClientPtr client) -{ - register int n; - REQUEST(xRenderQueryPictIndexValuesReq); - swaps(&stuff->length, n); - swapl(&stuff->format, n); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderQueryDithers (ClientPtr client) -{ - return BadImplementation; -} - -static int -SProcRenderCreatePicture (ClientPtr client) -{ - register int n; - REQUEST(xRenderCreatePictureReq); - swaps(&stuff->length, n); - swapl(&stuff->pid, n); - swapl(&stuff->drawable, n); - swapl(&stuff->format, n); - swapl(&stuff->mask, n); - SwapRestL(stuff); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderChangePicture (ClientPtr client) -{ - register int n; - REQUEST(xRenderChangePictureReq); - swaps(&stuff->length, n); - swapl(&stuff->picture, n); - swapl(&stuff->mask, n); - SwapRestL(stuff); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderSetPictureClipRectangles (ClientPtr client) -{ - register int n; - REQUEST(xRenderSetPictureClipRectanglesReq); - swaps(&stuff->length, n); - swapl(&stuff->picture, n); - swaps(&stuff->xOrigin, n); - swaps(&stuff->yOrigin, n); - SwapRestS(stuff); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderFreePicture (ClientPtr client) -{ - register int n; - REQUEST(xRenderFreePictureReq); - swaps(&stuff->length, n); - swapl(&stuff->picture, n); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderComposite (ClientPtr client) -{ - register int n; - REQUEST(xRenderCompositeReq); - swaps(&stuff->length, n); - swapl(&stuff->src, n); - swapl(&stuff->mask, n); - swapl(&stuff->dst, n); - swaps(&stuff->xSrc, n); - swaps(&stuff->ySrc, n); - swaps(&stuff->xMask, n); - swaps(&stuff->yMask, n); - swaps(&stuff->xDst, n); - swaps(&stuff->yDst, n); - swaps(&stuff->width, n); - swaps(&stuff->height, n); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderScale (ClientPtr client) -{ - register int n; - REQUEST(xRenderScaleReq); - swaps(&stuff->length, n); - swapl(&stuff->src, n); - swapl(&stuff->dst, n); - swapl(&stuff->colorScale, n); - swapl(&stuff->alphaScale, n); - swaps(&stuff->xSrc, n); - swaps(&stuff->ySrc, n); - swaps(&stuff->xDst, n); - swaps(&stuff->yDst, n); - swaps(&stuff->width, n); - swaps(&stuff->height, n); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderTrapezoids (ClientPtr client) -{ - register int n; - REQUEST(xRenderTrapezoidsReq); - - REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq); - swaps (&stuff->length, n); - swapl (&stuff->src, n); - swapl (&stuff->dst, n); - swapl (&stuff->maskFormat, n); - swaps (&stuff->xSrc, n); - swaps (&stuff->ySrc, n); - SwapRestL(stuff); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderTriangles (ClientPtr client) -{ - register int n; - REQUEST(xRenderTrianglesReq); - - REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); - swaps (&stuff->length, n); - swapl (&stuff->src, n); - swapl (&stuff->dst, n); - swapl (&stuff->maskFormat, n); - swaps (&stuff->xSrc, n); - swaps (&stuff->ySrc, n); - SwapRestL(stuff); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderTriStrip (ClientPtr client) -{ - register int n; - REQUEST(xRenderTriStripReq); - - REQUEST_AT_LEAST_SIZE(xRenderTriStripReq); - swaps (&stuff->length, n); - swapl (&stuff->src, n); - swapl (&stuff->dst, n); - swapl (&stuff->maskFormat, n); - swaps (&stuff->xSrc, n); - swaps (&stuff->ySrc, n); - SwapRestL(stuff); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderTriFan (ClientPtr client) -{ - register int n; - REQUEST(xRenderTriFanReq); - - REQUEST_AT_LEAST_SIZE(xRenderTriFanReq); - swaps (&stuff->length, n); - swapl (&stuff->src, n); - swapl (&stuff->dst, n); - swapl (&stuff->maskFormat, n); - swaps (&stuff->xSrc, n); - swaps (&stuff->ySrc, n); - SwapRestL(stuff); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderColorTrapezoids (ClientPtr client) -{ - return BadImplementation; -} - -static int -SProcRenderColorTriangles (ClientPtr client) -{ - return BadImplementation; -} - -static int -SProcRenderTransform (ClientPtr client) -{ - return BadImplementation; -} - -static int -SProcRenderCreateGlyphSet (ClientPtr client) -{ - register int n; - REQUEST(xRenderCreateGlyphSetReq); - swaps(&stuff->length, n); - swapl(&stuff->gsid, n); - swapl(&stuff->format, n); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderReferenceGlyphSet (ClientPtr client) -{ - register int n; - REQUEST(xRenderReferenceGlyphSetReq); - swaps(&stuff->length, n); - swapl(&stuff->gsid, n); - swapl(&stuff->existing, n); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderFreeGlyphSet (ClientPtr client) -{ - register int n; - REQUEST(xRenderFreeGlyphSetReq); - swaps(&stuff->length, n); - swapl(&stuff->glyphset, n); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderAddGlyphs (ClientPtr client) -{ - register int n; - register int i; - CARD32 *gids; - void *end; - xGlyphInfo *gi; - REQUEST(xRenderAddGlyphsReq); - swaps(&stuff->length, n); - swapl(&stuff->glyphset, n); - swapl(&stuff->nglyphs, n); - if (stuff->nglyphs & 0xe0000000) - return BadLength; - end = (CARD8 *) stuff + (client->req_len << 2); - gids = (CARD32 *) (stuff + 1); - gi = (xGlyphInfo *) (gids + stuff->nglyphs); - if ((char *) end - (char *) (gids + stuff->nglyphs) < 0) - return BadLength; - if ((char *) end - (char *) (gi + stuff->nglyphs) < 0) - return BadLength; - for (i = 0; i < stuff->nglyphs; i++) - { - swapl (&gids[i], n); - swaps (&gi[i].width, n); - swaps (&gi[i].height, n); - swaps (&gi[i].x, n); - swaps (&gi[i].y, n); - swaps (&gi[i].xOff, n); - swaps (&gi[i].yOff, n); - } - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderAddGlyphsFromPicture (ClientPtr client) -{ - return BadImplementation; -} - -static int -SProcRenderFreeGlyphs (ClientPtr client) -{ - register int n; - REQUEST(xRenderFreeGlyphsReq); - swaps(&stuff->length, n); - swapl(&stuff->glyphset, n); - SwapRestL(stuff); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderCompositeGlyphs (ClientPtr client) -{ - register int n; - xGlyphElt *elt; - CARD8 *buffer; - CARD8 *end; - int space; - int i; - int size; - - REQUEST(xRenderCompositeGlyphsReq); - - switch (stuff->renderReqType) { - default: size = 1; break; - case X_RenderCompositeGlyphs16: size = 2; break; - case X_RenderCompositeGlyphs32: size = 4; break; - } - - swaps(&stuff->length, n); - swapl(&stuff->src, n); - swapl(&stuff->dst, n); - swapl(&stuff->maskFormat, n); - swapl(&stuff->glyphset, n); - swaps(&stuff->xSrc, n); - swaps(&stuff->ySrc, n); - buffer = (CARD8 *) (stuff + 1); - end = (CARD8 *) stuff + (client->req_len << 2); - while (buffer + sizeof (xGlyphElt) < end) - { - elt = (xGlyphElt *) buffer; - buffer += sizeof (xGlyphElt); - - swaps (&elt->deltax, n); - swaps (&elt->deltay, n); - - i = elt->len; - if (i == 0xff) - { - swapl (buffer, n); - buffer += 4; - } - else - { - space = size * i; - switch (size) { - case 1: - buffer += i; - break; - case 2: - while (i--) - { - swaps (buffer, n); - buffer += 2; - } - break; - case 4: - while (i--) - { - swapl (buffer, n); - buffer += 4; - } - break; - } - if (space & 3) - buffer += 4 - (space & 3); - } - } - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderFillRectangles (ClientPtr client) -{ - register int n; - REQUEST(xRenderFillRectanglesReq); - - REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq); - swaps(&stuff->length, n); - swapl(&stuff->dst, n); - swaps(&stuff->color.red, n); - swaps(&stuff->color.green, n); - swaps(&stuff->color.blue, n); - swaps(&stuff->color.alpha, n); - SwapRestS(stuff); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderCreateCursor (ClientPtr client) -{ - register int n; - REQUEST(xRenderCreateCursorReq); - REQUEST_SIZE_MATCH (xRenderCreateCursorReq); - - swaps(&stuff->length, n); - swapl(&stuff->cid, n); - swapl(&stuff->src, n); - swaps(&stuff->x, n); - swaps(&stuff->y, n); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderSetPictureTransform (ClientPtr client) -{ - register int n; - REQUEST(xRenderSetPictureTransformReq); - REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq); - - swaps(&stuff->length, n); - swapl(&stuff->picture, n); - swapl(&stuff->transform.matrix11, n); - swapl(&stuff->transform.matrix12, n); - swapl(&stuff->transform.matrix13, n); - swapl(&stuff->transform.matrix21, n); - swapl(&stuff->transform.matrix22, n); - swapl(&stuff->transform.matrix23, n); - swapl(&stuff->transform.matrix31, n); - swapl(&stuff->transform.matrix32, n); - swapl(&stuff->transform.matrix33, n); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderQueryFilters (ClientPtr client) -{ - register int n; - REQUEST (xRenderQueryFiltersReq); - REQUEST_SIZE_MATCH (xRenderQueryFiltersReq); - - swaps(&stuff->length, n); - swapl(&stuff->drawable, n); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderSetPictureFilter (ClientPtr client) -{ - register int n; - REQUEST (xRenderSetPictureFilterReq); - REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq); - - swaps(&stuff->length, n); - swapl(&stuff->picture, n); - swaps(&stuff->nbytes, n); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderCreateAnimCursor (ClientPtr client) -{ - register int n; - REQUEST (xRenderCreateAnimCursorReq); - REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq); - - swaps(&stuff->length, n); - swapl(&stuff->cid, n); - SwapRestL(stuff); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderAddTraps (ClientPtr client) -{ - register int n; - REQUEST (xRenderAddTrapsReq); - REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq); - - swaps(&stuff->length, n); - swapl(&stuff->picture, n); - swaps(&stuff->xOff, n); - swaps(&stuff->yOff, n); - SwapRestL(stuff); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderCreateSolidFill(ClientPtr client) -{ - register int n; - REQUEST (xRenderCreateSolidFillReq); - REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq); - - swaps(&stuff->length, n); - swapl(&stuff->pid, n); - swaps(&stuff->color.alpha, n); - swaps(&stuff->color.red, n); - swaps(&stuff->color.green, n); - swaps(&stuff->color.blue, n); - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static void swapStops(void *stuff, int num) -{ - int i, n; - CARD32 *stops; - CARD16 *colors; - stops = (CARD32 *)(stuff); - for (i = 0; i < num; ++i) { - swapl(stops, n); - ++stops; - } - colors = (CARD16 *)(stops); - for (i = 0; i < 4*num; ++i) { - swaps(colors, n); - ++colors; - } -} - -static int -SProcRenderCreateLinearGradient (ClientPtr client) -{ - register int n; - int len; - REQUEST (xRenderCreateLinearGradientReq); - REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq); - - swaps(&stuff->length, n); - swapl(&stuff->pid, n); - swapl(&stuff->p1.x, n); - swapl(&stuff->p1.y, n); - swapl(&stuff->p2.x, n); - swapl(&stuff->p2.y, n); - swapl(&stuff->nStops, n); - - len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq); - if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) - return BadLength; - if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) - return BadLength; - - swapStops(stuff+1, stuff->nStops); - - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderCreateRadialGradient (ClientPtr client) -{ - register int n; - int len; - REQUEST (xRenderCreateRadialGradientReq); - REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq); - - swaps(&stuff->length, n); - swapl(&stuff->pid, n); - swapl(&stuff->inner.x, n); - swapl(&stuff->inner.y, n); - swapl(&stuff->outer.x, n); - swapl(&stuff->outer.y, n); - swapl(&stuff->inner_radius, n); - swapl(&stuff->outer_radius, n); - swapl(&stuff->nStops, n); - - len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq); - if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) - return BadLength; - if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) - return BadLength; - - swapStops(stuff+1, stuff->nStops); - - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderCreateConicalGradient (ClientPtr client) -{ - register int n; - int len; - REQUEST (xRenderCreateConicalGradientReq); - REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq); - - swaps(&stuff->length, n); - swapl(&stuff->pid, n); - swapl(&stuff->center.x, n); - swapl(&stuff->center.y, n); - swapl(&stuff->angle, n); - swapl(&stuff->nStops, n); - - len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq); - if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) - return BadLength; - if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) - return BadLength; - - swapStops(stuff+1, stuff->nStops); - - return (*ProcRenderVector[stuff->renderReqType]) (client); -} - -static int -SProcRenderDispatch (ClientPtr client) -{ - REQUEST(xReq); - - if (stuff->data < RenderNumberRequests) - return (*SProcRenderVector[stuff->data]) (client); - else - return BadRequest; -} - -#ifdef PANORAMIX -#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\ - int rc = dixLookupResourceByType((pointer *)&(pPicture), pid,\ - XRT_PICTURE, client, mode);\ - if (rc != Success)\ - return rc;\ -} - -#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode) {\ - if (pid == None) \ - pPicture = 0; \ - else { \ - VERIFY_XIN_PICTURE(pPicture, pid, client, mode); \ - } \ -} \ - -int (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr); - -static int -PanoramiXRenderCreatePicture (ClientPtr client) -{ - REQUEST(xRenderCreatePictureReq); - PanoramiXRes *refDraw, *newPict; - int result, j; - - REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); - result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable, - XRC_DRAWABLE, client, DixWriteAccess); - if (result != Success) - return (result == BadValue) ? BadDrawable : result; - if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) - return BadAlloc; - newPict->type = XRT_PICTURE; - newPict->info[0].id = stuff->pid; - - if (refDraw->type == XRT_WINDOW && - stuff->drawable == screenInfo.screens[0]->root->drawable.id) - { - newPict->u.pict.root = TRUE; - } - else - newPict->u.pict.root = FALSE; - - for(j = 1; j < PanoramiXNumScreens; j++) - newPict->info[j].id = FakeClientID(client->index); - - FOR_NSCREENS_BACKWARD(j) { - stuff->pid = newPict->info[j].id; - stuff->drawable = refDraw->info[j].id; - result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client); - if(result != Success) break; - } - - if (result == Success) - AddResource(newPict->info[0].id, XRT_PICTURE, newPict); - else - free(newPict); - - return result; -} - -static int -PanoramiXRenderChangePicture (ClientPtr client) -{ - PanoramiXRes *pict; - int result = Success, j; - REQUEST(xRenderChangePictureReq); - - REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq); - - VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); - - FOR_NSCREENS_BACKWARD(j) { - stuff->picture = pict->info[j].id; - result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client); - if(result != Success) break; - } - - return result; -} - -static int -PanoramiXRenderSetPictureClipRectangles (ClientPtr client) -{ - REQUEST(xRenderSetPictureClipRectanglesReq); - int result = Success, j; - PanoramiXRes *pict; - - REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); - - VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); - - FOR_NSCREENS_BACKWARD(j) { - stuff->picture = pict->info[j].id; - result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client); - if(result != Success) break; - } - - return result; -} - -static int -PanoramiXRenderSetPictureTransform (ClientPtr client) -{ - REQUEST(xRenderSetPictureTransformReq); - int result = Success, j; - PanoramiXRes *pict; - - REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq); - - VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); - - FOR_NSCREENS_BACKWARD(j) { - stuff->picture = pict->info[j].id; - result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client); - if(result != Success) break; - } - - return result; -} - -static int -PanoramiXRenderSetPictureFilter (ClientPtr client) -{ - REQUEST(xRenderSetPictureFilterReq); - int result = Success, j; - PanoramiXRes *pict; - - REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq); - - VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); - - FOR_NSCREENS_BACKWARD(j) { - stuff->picture = pict->info[j].id; - result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client); - if(result != Success) break; - } - - return result; -} - -static int -PanoramiXRenderFreePicture (ClientPtr client) -{ - PanoramiXRes *pict; - int result = Success, j; - REQUEST(xRenderFreePictureReq); - - REQUEST_SIZE_MATCH(xRenderFreePictureReq); - - client->errorValue = stuff->picture; - - VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess); - - - FOR_NSCREENS_BACKWARD(j) { - stuff->picture = pict->info[j].id; - result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client); - if(result != Success) break; - } - - /* Since ProcRenderFreePicture is using FreeResource, it will free - our resource for us on the last pass through the loop above */ - - return result; -} - -static int -PanoramiXRenderComposite (ClientPtr client) -{ - PanoramiXRes *src, *msk, *dst; - int result = Success, j; - xRenderCompositeReq orig; - REQUEST(xRenderCompositeReq); - - REQUEST_SIZE_MATCH(xRenderCompositeReq); - - VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); - VERIFY_XIN_ALPHA (msk, stuff->mask, client, DixReadAccess); - VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); - - orig = *stuff; - - FOR_NSCREENS_FORWARD(j) { - stuff->src = src->info[j].id; - if (src->u.pict.root) - { - stuff->xSrc = orig.xSrc - screenInfo.screens[j]->x; - stuff->ySrc = orig.ySrc - screenInfo.screens[j]->y; - } - stuff->dst = dst->info[j].id; - if (dst->u.pict.root) - { - stuff->xDst = orig.xDst - screenInfo.screens[j]->x; - stuff->yDst = orig.yDst - screenInfo.screens[j]->y; - } - if (msk) - { - stuff->mask = msk->info[j].id; - if (msk->u.pict.root) - { - stuff->xMask = orig.xMask - screenInfo.screens[j]->x; - stuff->yMask = orig.yMask - screenInfo.screens[j]->y; - } - } - result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client); - if(result != Success) break; - } - - return result; -} - -static int -PanoramiXRenderCompositeGlyphs (ClientPtr client) -{ - PanoramiXRes *src, *dst; - int result = Success, j; - REQUEST(xRenderCompositeGlyphsReq); - xGlyphElt origElt, *elt; - INT16 xSrc, ySrc; - - REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); - VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); - VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); - - if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) + - sizeof (xGlyphElt))) - { - elt = (xGlyphElt *) (stuff + 1); - origElt = *elt; - xSrc = stuff->xSrc; - ySrc = stuff->ySrc; - FOR_NSCREENS_FORWARD(j) { - stuff->src = src->info[j].id; - if (src->u.pict.root) - { - stuff->xSrc = xSrc - screenInfo.screens[j]->x; - stuff->ySrc = ySrc - screenInfo.screens[j]->y; - } - stuff->dst = dst->info[j].id; - if (dst->u.pict.root) - { - elt->deltax = origElt.deltax - screenInfo.screens[j]->x; - elt->deltay = origElt.deltay - screenInfo.screens[j]->y; - } - result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client); - if(result != Success) break; - } - } - - return result; -} - -static int -PanoramiXRenderFillRectangles (ClientPtr client) -{ - PanoramiXRes *dst; - int result = Success, j; - REQUEST(xRenderFillRectanglesReq); - char *extra; - int extra_len; - - REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq); - VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); - extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq); - if (extra_len && - (extra = (char *) malloc(extra_len))) - { - memcpy (extra, stuff + 1, extra_len); - FOR_NSCREENS_FORWARD(j) { - if (j) memcpy (stuff + 1, extra, extra_len); - if (dst->u.pict.root) - { - int x_off = screenInfo.screens[j]->x; - int y_off = screenInfo.screens[j]->y; - - if(x_off || y_off) { - xRectangle *rects = (xRectangle *) (stuff + 1); - int i = extra_len / sizeof (xRectangle); - - while (i--) - { - rects->x -= x_off; - rects->y -= y_off; - rects++; - } - } - } - stuff->dst = dst->info[j].id; - result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client); - if(result != Success) break; - } - free(extra); - } - - return result; -} - -static int -PanoramiXRenderTrapezoids(ClientPtr client) -{ - PanoramiXRes *src, *dst; - int result = Success, j; - REQUEST(xRenderTrapezoidsReq); - char *extra; - int extra_len; - - REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq); - - VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); - VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); - - extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq); - - if (extra_len && - (extra = (char *) malloc(extra_len))) { - memcpy (extra, stuff + 1, extra_len); - - FOR_NSCREENS_FORWARD(j) { - if (j) memcpy (stuff + 1, extra, extra_len); - if (dst->u.pict.root) { - int x_off = screenInfo.screens[j]->x; - int y_off = screenInfo.screens[j]->y; - - if(x_off || y_off) { - xTrapezoid *trap = (xTrapezoid *) (stuff + 1); - int i = extra_len / sizeof (xTrapezoid); - - while (i--) { - trap->top -= y_off; - trap->bottom -= y_off; - trap->left.p1.x -= x_off; - trap->left.p1.y -= y_off; - trap->left.p2.x -= x_off; - trap->left.p2.y -= y_off; - trap->right.p1.x -= x_off; - trap->right.p1.y -= y_off; - trap->right.p2.x -= x_off; - trap->right.p2.y -= y_off; - trap++; - } - } - } - - stuff->src = src->info[j].id; - stuff->dst = dst->info[j].id; - result = - (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client); - - if(result != Success) break; - } - - free(extra); - } - - return result; -} - -static int -PanoramiXRenderTriangles(ClientPtr client) -{ - PanoramiXRes *src, *dst; - int result = Success, j; - REQUEST(xRenderTrianglesReq); - char *extra; - int extra_len; - - REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq); - - VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); - VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); - - extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq); - - if (extra_len && - (extra = (char *) malloc(extra_len))) { - memcpy (extra, stuff + 1, extra_len); - - FOR_NSCREENS_FORWARD(j) { - if (j) memcpy (stuff + 1, extra, extra_len); - if (dst->u.pict.root) { - int x_off = screenInfo.screens[j]->x; - int y_off = screenInfo.screens[j]->y; - - if(x_off || y_off) { - xTriangle *tri = (xTriangle *) (stuff + 1); - int i = extra_len / sizeof (xTriangle); - - while (i--) { - tri->p1.x -= x_off; - tri->p1.y -= y_off; - tri->p2.x -= x_off; - tri->p2.y -= y_off; - tri->p3.x -= x_off; - tri->p3.y -= y_off; - tri++; - } - } - } - - stuff->src = src->info[j].id; - stuff->dst = dst->info[j].id; - result = - (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client); - - if(result != Success) break; - } - - free(extra); - } - - return result; -} - -static int -PanoramiXRenderTriStrip(ClientPtr client) -{ - PanoramiXRes *src, *dst; - int result = Success, j; - REQUEST(xRenderTriStripReq); - char *extra; - int extra_len; - - REQUEST_AT_LEAST_SIZE (xRenderTriStripReq); - - VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); - VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); - - extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq); - - if (extra_len && - (extra = (char *) malloc(extra_len))) { - memcpy (extra, stuff + 1, extra_len); - - FOR_NSCREENS_FORWARD(j) { - if (j) memcpy (stuff + 1, extra, extra_len); - if (dst->u.pict.root) { - int x_off = screenInfo.screens[j]->x; - int y_off = screenInfo.screens[j]->y; - - if(x_off || y_off) { - xPointFixed *fixed = (xPointFixed *) (stuff + 1); - int i = extra_len / sizeof (xPointFixed); - - while (i--) { - fixed->x -= x_off; - fixed->y -= y_off; - fixed++; - } - } - } - - stuff->src = src->info[j].id; - stuff->dst = dst->info[j].id; - result = - (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client); - - if(result != Success) break; - } - - free(extra); - } - - return result; -} - -static int -PanoramiXRenderTriFan(ClientPtr client) -{ - PanoramiXRes *src, *dst; - int result = Success, j; - REQUEST(xRenderTriFanReq); - char *extra; - int extra_len; - - REQUEST_AT_LEAST_SIZE (xRenderTriFanReq); - - VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); - VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); - - extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq); - - if (extra_len && - (extra = (char *) malloc(extra_len))) { - memcpy (extra, stuff + 1, extra_len); - - FOR_NSCREENS_FORWARD(j) { - if (j) memcpy (stuff + 1, extra, extra_len); - if (dst->u.pict.root) { - int x_off = screenInfo.screens[j]->x; - int y_off = screenInfo.screens[j]->y; - - if(x_off || y_off) { - xPointFixed *fixed = (xPointFixed *) (stuff + 1); - int i = extra_len / sizeof (xPointFixed); - - while (i--) { - fixed->x -= x_off; - fixed->y -= y_off; - fixed++; - } - } - } - - stuff->src = src->info[j].id; - stuff->dst = dst->info[j].id; - result = - (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client); - - if(result != Success) break; - } - - free(extra); - } - - return result; -} - -static int -PanoramiXRenderAddTraps (ClientPtr client) -{ - PanoramiXRes *picture; - int result = Success, j; - REQUEST(xRenderAddTrapsReq); - char *extra; - int extra_len; - INT16 x_off, y_off; - - REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq); - VERIFY_XIN_PICTURE (picture, stuff->picture, client, DixWriteAccess); - extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq); - if (extra_len && - (extra = (char *) malloc(extra_len))) - { - memcpy (extra, stuff + 1, extra_len); - x_off = stuff->xOff; - y_off = stuff->yOff; - FOR_NSCREENS_FORWARD(j) { - if (j) memcpy (stuff + 1, extra, extra_len); - stuff->picture = picture->info[j].id; - - if (picture->u.pict.root) - { - stuff->xOff = x_off + screenInfo.screens[j]->x; - stuff->yOff = y_off + screenInfo.screens[j]->y; - } - result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client); - if(result != Success) break; - } - free(extra); - } - - return result; -} - -static int -PanoramiXRenderCreateSolidFill (ClientPtr client) -{ - REQUEST(xRenderCreateSolidFillReq); - PanoramiXRes *newPict; - int result = Success, j; - - REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq); - - if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) - return BadAlloc; - - newPict->type = XRT_PICTURE; - newPict->info[0].id = stuff->pid; - newPict->u.pict.root = FALSE; - - for(j = 1; j < PanoramiXNumScreens; j++) - newPict->info[j].id = FakeClientID(client->index); - - FOR_NSCREENS_BACKWARD(j) { - stuff->pid = newPict->info[j].id; - result = (*PanoramiXSaveRenderVector[X_RenderCreateSolidFill]) (client); - if(result != Success) break; - } - - if (result == Success) - AddResource(newPict->info[0].id, XRT_PICTURE, newPict); - else - free(newPict); - - return result; -} - -static int -PanoramiXRenderCreateLinearGradient (ClientPtr client) -{ - REQUEST(xRenderCreateLinearGradientReq); - PanoramiXRes *newPict; - int result = Success, j; - - REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq); - - if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) - return BadAlloc; - - newPict->type = XRT_PICTURE; - newPict->info[0].id = stuff->pid; - newPict->u.pict.root = FALSE; - - for(j = 1; j < PanoramiXNumScreens; j++) - newPict->info[j].id = FakeClientID(client->index); - - FOR_NSCREENS_BACKWARD(j) { - stuff->pid = newPict->info[j].id; - result = (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client); - if(result != Success) break; - } - - if (result == Success) - AddResource(newPict->info[0].id, XRT_PICTURE, newPict); - else - free(newPict); - - return result; -} - -static int -PanoramiXRenderCreateRadialGradient (ClientPtr client) -{ - REQUEST(xRenderCreateRadialGradientReq); - PanoramiXRes *newPict; - int result = Success, j; - - REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq); - - if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) - return BadAlloc; - - newPict->type = XRT_PICTURE; - newPict->info[0].id = stuff->pid; - newPict->u.pict.root = FALSE; - - for(j = 1; j < PanoramiXNumScreens; j++) - newPict->info[j].id = FakeClientID(client->index); - - FOR_NSCREENS_BACKWARD(j) { - stuff->pid = newPict->info[j].id; - result = (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client); - if(result != Success) break; - } - - if (result == Success) - AddResource(newPict->info[0].id, XRT_PICTURE, newPict); - else - free(newPict); - - return result; -} - -static int -PanoramiXRenderCreateConicalGradient (ClientPtr client) -{ - REQUEST(xRenderCreateConicalGradientReq); - PanoramiXRes *newPict; - int result = Success, j; - - REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq); - - if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) - return BadAlloc; - - newPict->type = XRT_PICTURE; - newPict->info[0].id = stuff->pid; - newPict->u.pict.root = FALSE; - - for(j = 1; j < PanoramiXNumScreens; j++) - newPict->info[j].id = FakeClientID(client->index); - - FOR_NSCREENS_BACKWARD(j) { - stuff->pid = newPict->info[j].id; - result = (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient]) (client); - if(result != Success) break; - } - - if (result == Success) - AddResource(newPict->info[0].id, XRT_PICTURE, newPict); - else - free(newPict); - - return result; -} - -void -PanoramiXRenderInit (void) -{ - int i; - - XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource, - "XineramaPicture"); - if (RenderErrBase) - SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture); - for (i = 0; i < RenderNumberRequests; i++) - PanoramiXSaveRenderVector[i] = ProcRenderVector[i]; - /* - * Stuff in Xinerama aware request processing hooks - */ - ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture; - ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture; - ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform; - ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter; - ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles; - ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture; - ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite; - ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs; - ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs; - ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs; - ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles; - - ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids; - ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles; - ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip; - ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan; - ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps; - - ProcRenderVector[X_RenderCreateSolidFill] = PanoramiXRenderCreateSolidFill; - ProcRenderVector[X_RenderCreateLinearGradient] = PanoramiXRenderCreateLinearGradient; - ProcRenderVector[X_RenderCreateRadialGradient] = PanoramiXRenderCreateRadialGradient; - ProcRenderVector[X_RenderCreateConicalGradient] = PanoramiXRenderCreateConicalGradient; -} - -void -PanoramiXRenderReset (void) -{ - int i; - for (i = 0; i < RenderNumberRequests; i++) - ProcRenderVector[i] = PanoramiXSaveRenderVector[i]; - RenderErrBase = 0; -} - -#endif /* PANORAMIX */ +/* + * + * Copyright © 2000 SuSE, Inc. + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that + * copyright notice and this permission notice appear in supporting + * documentation, and that the name of SuSE not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. SuSE makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * SuSE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL SuSE + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Keith Packard, SuSE, Inc. + */ + +#ifdef HAVE_DIX_CONFIG_H +#include +#endif + +#include +#include +#include "misc.h" +#include "os.h" +#include "dixstruct.h" +#include "resource.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "pixmapstr.h" +#include "colormapst.h" +#include "extnsionst.h" +#include "servermd.h" +#include +#include +#include "picturestr.h" +#include "glyphstr.h" +#include +#include "cursorstr.h" +#include "xace.h" +#include "protocol-versions.h" + +#ifdef PANORAMIX +#include "panoramiX.h" +#include "panoramiXsrv.h" +#endif + +#if HAVE_STDINT_H +#include +#elif !defined(UINT32_MAX) +#define UINT32_MAX 0xffffffffU +#endif + +static int ProcRenderQueryVersion (ClientPtr pClient); +static int ProcRenderQueryPictFormats (ClientPtr pClient); +static int ProcRenderQueryPictIndexValues (ClientPtr pClient); +static int ProcRenderQueryDithers (ClientPtr pClient); +static int ProcRenderCreatePicture (ClientPtr pClient); +static int ProcRenderChangePicture (ClientPtr pClient); +static int ProcRenderSetPictureClipRectangles (ClientPtr pClient); +static int ProcRenderFreePicture (ClientPtr pClient); +static int ProcRenderComposite (ClientPtr pClient); +static int ProcRenderScale (ClientPtr pClient); +static int ProcRenderTrapezoids (ClientPtr pClient); +static int ProcRenderTriangles (ClientPtr pClient); +static int ProcRenderTriStrip (ClientPtr pClient); +static int ProcRenderTriFan (ClientPtr pClient); +static int ProcRenderColorTrapezoids (ClientPtr pClient); +static int ProcRenderColorTriangles (ClientPtr pClient); +static int ProcRenderTransform (ClientPtr pClient); +static int ProcRenderCreateGlyphSet (ClientPtr pClient); +static int ProcRenderReferenceGlyphSet (ClientPtr pClient); +static int ProcRenderFreeGlyphSet (ClientPtr pClient); +static int ProcRenderAddGlyphs (ClientPtr pClient); +static int ProcRenderAddGlyphsFromPicture (ClientPtr pClient); +static int ProcRenderFreeGlyphs (ClientPtr pClient); +static int ProcRenderCompositeGlyphs (ClientPtr pClient); +static int ProcRenderFillRectangles (ClientPtr pClient); +static int ProcRenderCreateCursor (ClientPtr pClient); +static int ProcRenderSetPictureTransform (ClientPtr pClient); +static int ProcRenderQueryFilters (ClientPtr pClient); +static int ProcRenderSetPictureFilter (ClientPtr pClient); +static int ProcRenderCreateAnimCursor (ClientPtr pClient); +static int ProcRenderAddTraps (ClientPtr pClient); +static int ProcRenderCreateSolidFill (ClientPtr pClient); +static int ProcRenderCreateLinearGradient (ClientPtr pClient); +static int ProcRenderCreateRadialGradient (ClientPtr pClient); +static int ProcRenderCreateConicalGradient (ClientPtr pClient); + +static int ProcRenderDispatch (ClientPtr pClient); + +static int SProcRenderQueryVersion (ClientPtr pClient); +static int SProcRenderQueryPictFormats (ClientPtr pClient); +static int SProcRenderQueryPictIndexValues (ClientPtr pClient); +static int SProcRenderQueryDithers (ClientPtr pClient); +static int SProcRenderCreatePicture (ClientPtr pClient); +static int SProcRenderChangePicture (ClientPtr pClient); +static int SProcRenderSetPictureClipRectangles (ClientPtr pClient); +static int SProcRenderFreePicture (ClientPtr pClient); +static int SProcRenderComposite (ClientPtr pClient); +static int SProcRenderScale (ClientPtr pClient); +static int SProcRenderTrapezoids (ClientPtr pClient); +static int SProcRenderTriangles (ClientPtr pClient); +static int SProcRenderTriStrip (ClientPtr pClient); +static int SProcRenderTriFan (ClientPtr pClient); +static int SProcRenderColorTrapezoids (ClientPtr pClient); +static int SProcRenderColorTriangles (ClientPtr pClient); +static int SProcRenderTransform (ClientPtr pClient); +static int SProcRenderCreateGlyphSet (ClientPtr pClient); +static int SProcRenderReferenceGlyphSet (ClientPtr pClient); +static int SProcRenderFreeGlyphSet (ClientPtr pClient); +static int SProcRenderAddGlyphs (ClientPtr pClient); +static int SProcRenderAddGlyphsFromPicture (ClientPtr pClient); +static int SProcRenderFreeGlyphs (ClientPtr pClient); +static int SProcRenderCompositeGlyphs (ClientPtr pClient); +static int SProcRenderFillRectangles (ClientPtr pClient); +static int SProcRenderCreateCursor (ClientPtr pClient); +static int SProcRenderSetPictureTransform (ClientPtr pClient); +static int SProcRenderQueryFilters (ClientPtr pClient); +static int SProcRenderSetPictureFilter (ClientPtr pClient); +static int SProcRenderCreateAnimCursor (ClientPtr pClient); +static int SProcRenderAddTraps (ClientPtr pClient); +static int SProcRenderCreateSolidFill (ClientPtr pClient); +static int SProcRenderCreateLinearGradient (ClientPtr pClient); +static int SProcRenderCreateRadialGradient (ClientPtr pClient); +static int SProcRenderCreateConicalGradient (ClientPtr pClient); + +static int SProcRenderDispatch (ClientPtr pClient); + +int (*ProcRenderVector[RenderNumberRequests])(ClientPtr) = { + ProcRenderQueryVersion, + ProcRenderQueryPictFormats, + ProcRenderQueryPictIndexValues, + ProcRenderQueryDithers, + ProcRenderCreatePicture, + ProcRenderChangePicture, + ProcRenderSetPictureClipRectangles, + ProcRenderFreePicture, + ProcRenderComposite, + ProcRenderScale, + ProcRenderTrapezoids, + ProcRenderTriangles, + ProcRenderTriStrip, + ProcRenderTriFan, + ProcRenderColorTrapezoids, + ProcRenderColorTriangles, + ProcRenderTransform, + ProcRenderCreateGlyphSet, + ProcRenderReferenceGlyphSet, + ProcRenderFreeGlyphSet, + ProcRenderAddGlyphs, + ProcRenderAddGlyphsFromPicture, + ProcRenderFreeGlyphs, + ProcRenderCompositeGlyphs, + ProcRenderCompositeGlyphs, + ProcRenderCompositeGlyphs, + ProcRenderFillRectangles, + ProcRenderCreateCursor, + ProcRenderSetPictureTransform, + ProcRenderQueryFilters, + ProcRenderSetPictureFilter, + ProcRenderCreateAnimCursor, + ProcRenderAddTraps, + ProcRenderCreateSolidFill, + ProcRenderCreateLinearGradient, + ProcRenderCreateRadialGradient, + ProcRenderCreateConicalGradient +}; + +int (*SProcRenderVector[RenderNumberRequests])(ClientPtr) = { + SProcRenderQueryVersion, + SProcRenderQueryPictFormats, + SProcRenderQueryPictIndexValues, + SProcRenderQueryDithers, + SProcRenderCreatePicture, + SProcRenderChangePicture, + SProcRenderSetPictureClipRectangles, + SProcRenderFreePicture, + SProcRenderComposite, + SProcRenderScale, + SProcRenderTrapezoids, + SProcRenderTriangles, + SProcRenderTriStrip, + SProcRenderTriFan, + SProcRenderColorTrapezoids, + SProcRenderColorTriangles, + SProcRenderTransform, + SProcRenderCreateGlyphSet, + SProcRenderReferenceGlyphSet, + SProcRenderFreeGlyphSet, + SProcRenderAddGlyphs, + SProcRenderAddGlyphsFromPicture, + SProcRenderFreeGlyphs, + SProcRenderCompositeGlyphs, + SProcRenderCompositeGlyphs, + SProcRenderCompositeGlyphs, + SProcRenderFillRectangles, + SProcRenderCreateCursor, + SProcRenderSetPictureTransform, + SProcRenderQueryFilters, + SProcRenderSetPictureFilter, + SProcRenderCreateAnimCursor, + SProcRenderAddTraps, + SProcRenderCreateSolidFill, + SProcRenderCreateLinearGradient, + SProcRenderCreateRadialGradient, + SProcRenderCreateConicalGradient +}; + +int RenderErrBase; +static DevPrivateKeyRec RenderClientPrivateKeyRec; +#define RenderClientPrivateKey (&RenderClientPrivateKeyRec ) + +typedef struct _RenderClient { + int major_version; + int minor_version; +} RenderClientRec, *RenderClientPtr; + +#define GetRenderClient(pClient) ((RenderClientPtr)dixLookupPrivate(&(pClient)->devPrivates, RenderClientPrivateKey)) + +static void +RenderClientCallback (CallbackListPtr *list, + pointer closure, + pointer data) +{ + NewClientInfoRec *clientinfo = (NewClientInfoRec *) data; + ClientPtr pClient = clientinfo->client; + RenderClientPtr pRenderClient = GetRenderClient (pClient); + + pRenderClient->major_version = 0; + pRenderClient->minor_version = 0; +} + +#ifdef PANORAMIX +RESTYPE XRT_PICTURE; +#endif + +void +RenderExtensionInit (void) +{ + ExtensionEntry *extEntry; + + if (!PictureType) + return; + if (!PictureFinishInit ()) + return; + if (!dixRegisterPrivateKey(&RenderClientPrivateKeyRec, PRIVATE_CLIENT, sizeof(RenderClientRec))) + return; + if (!AddCallback (&ClientStateCallback, RenderClientCallback, 0)) + return; + + extEntry = AddExtension (RENDER_NAME, 0, RenderNumberErrors, + ProcRenderDispatch, SProcRenderDispatch, + NULL, StandardMinorOpcode); + if (!extEntry) + return; + RenderErrBase = extEntry->errorBase; +#ifdef PANORAMIX + if (XRT_PICTURE) + SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture); +#endif + SetResourceTypeErrorValue(PictureType, RenderErrBase + BadPicture); + SetResourceTypeErrorValue(PictFormatType, RenderErrBase + BadPictFormat); + SetResourceTypeErrorValue(GlyphSetType, RenderErrBase + BadGlyphSet); +} + +static int +ProcRenderQueryVersion (ClientPtr client) +{ + RenderClientPtr pRenderClient = GetRenderClient (client); + xRenderQueryVersionReply rep; + register int n; + REQUEST(xRenderQueryVersionReq); + + pRenderClient->major_version = stuff->majorVersion; + pRenderClient->minor_version = stuff->minorVersion; + + REQUEST_SIZE_MATCH(xRenderQueryVersionReq); + memset(&rep, 0, sizeof(xRenderQueryVersionReply)); + rep.type = X_Reply; + rep.length = 0; + rep.sequenceNumber = client->sequence; + + if ((stuff->majorVersion * 1000 + stuff->minorVersion) < + (SERVER_RENDER_MAJOR_VERSION * 1000 + SERVER_RENDER_MINOR_VERSION)) + { + rep.majorVersion = stuff->majorVersion; + rep.minorVersion = stuff->minorVersion; + } else + { + rep.majorVersion = SERVER_RENDER_MAJOR_VERSION; + rep.minorVersion = SERVER_RENDER_MINOR_VERSION; + } + + if (client->swapped) { + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, n); + swapl(&rep.majorVersion, n); + swapl(&rep.minorVersion, n); + } + WriteToClient(client, sizeof(xRenderQueryVersionReply), (char *)&rep); + return Success; +} + +static VisualPtr +findVisual (ScreenPtr pScreen, VisualID vid) +{ + VisualPtr pVisual; + int v; + + for (v = 0; v < pScreen->numVisuals; v++) + { + pVisual = pScreen->visuals + v; + if (pVisual->vid == vid) + return pVisual; + } + return 0; +} + +static int +ProcRenderQueryPictFormats (ClientPtr client) +{ + RenderClientPtr pRenderClient = GetRenderClient (client); + xRenderQueryPictFormatsReply *reply; + xPictScreen *pictScreen; + xPictDepth *pictDepth; + xPictVisual *pictVisual; + xPictFormInfo *pictForm; + CARD32 *pictSubpixel; + ScreenPtr pScreen; + VisualPtr pVisual; + DepthPtr pDepth; + int v, d; + PictureScreenPtr ps; + PictFormatPtr pFormat; + int nformat; + int ndepth; + int nvisual; + int rlength; + int s; + int n; + int numScreens; + int numSubpixel; +/* REQUEST(xRenderQueryPictFormatsReq); */ + + REQUEST_SIZE_MATCH(xRenderQueryPictFormatsReq); + +#ifdef PANORAMIX + if (noPanoramiXExtension) + numScreens = screenInfo.numScreens; + else + numScreens = ((xConnSetup *)ConnectionInfo)->numRoots; +#else + numScreens = screenInfo.numScreens; +#endif + ndepth = nformat = nvisual = 0; + for (s = 0; s < numScreens; s++) + { + pScreen = screenInfo.screens[s]; + for (d = 0; d < pScreen->numDepths; d++) + { + pDepth = pScreen->allowedDepths + d; + ++ndepth; + + for (v = 0; v < pDepth->numVids; v++) + { + pVisual = findVisual (pScreen, pDepth->vids[v]); + if (pVisual && PictureMatchVisual (pScreen, pDepth->depth, pVisual)) + ++nvisual; + } + } + ps = GetPictureScreenIfSet(pScreen); + if (ps) + nformat += ps->nformats; + } + if (pRenderClient->major_version == 0 && pRenderClient->minor_version < 6) + numSubpixel = 0; + else + numSubpixel = numScreens; + + rlength = (sizeof (xRenderQueryPictFormatsReply) + + nformat * sizeof (xPictFormInfo) + + numScreens * sizeof (xPictScreen) + + ndepth * sizeof (xPictDepth) + + nvisual * sizeof (xPictVisual) + + numSubpixel * sizeof (CARD32)); + reply = (xRenderQueryPictFormatsReply *) calloc(1, rlength); + if (!reply) + return BadAlloc; + reply->type = X_Reply; + reply->sequenceNumber = client->sequence; + reply->length = bytes_to_int32(rlength - sizeof(xGenericReply)); + reply->numFormats = nformat; + reply->numScreens = numScreens; + reply->numDepths = ndepth; + reply->numVisuals = nvisual; + reply->numSubpixel = numSubpixel; + + pictForm = (xPictFormInfo *) (reply + 1); + + for (s = 0; s < numScreens; s++) + { + pScreen = screenInfo.screens[s]; + ps = GetPictureScreenIfSet(pScreen); + if (ps) + { + for (nformat = 0, pFormat = ps->formats; + nformat < ps->nformats; + nformat++, pFormat++) + { + pictForm->id = pFormat->id; + pictForm->type = pFormat->type; + pictForm->depth = pFormat->depth; + pictForm->direct.red = pFormat->direct.red; + pictForm->direct.redMask = pFormat->direct.redMask; + pictForm->direct.green = pFormat->direct.green; + pictForm->direct.greenMask = pFormat->direct.greenMask; + pictForm->direct.blue = pFormat->direct.blue; + pictForm->direct.blueMask = pFormat->direct.blueMask; + pictForm->direct.alpha = pFormat->direct.alpha; + pictForm->direct.alphaMask = pFormat->direct.alphaMask; + if (pFormat->type == PictTypeIndexed && pFormat->index.pColormap) + pictForm->colormap = pFormat->index.pColormap->mid; + else + pictForm->colormap = None; + if (client->swapped) + { + swapl (&pictForm->id, n); + swaps (&pictForm->direct.red, n); + swaps (&pictForm->direct.redMask, n); + swaps (&pictForm->direct.green, n); + swaps (&pictForm->direct.greenMask, n); + swaps (&pictForm->direct.blue, n); + swaps (&pictForm->direct.blueMask, n); + swaps (&pictForm->direct.alpha, n); + swaps (&pictForm->direct.alphaMask, n); + swapl (&pictForm->colormap, n); + } + pictForm++; + } + } + } + + pictScreen = (xPictScreen *) pictForm; + for (s = 0; s < numScreens; s++) + { + pScreen = screenInfo.screens[s]; + pictDepth = (xPictDepth *) (pictScreen + 1); + ndepth = 0; + for (d = 0; d < pScreen->numDepths; d++) + { + pictVisual = (xPictVisual *) (pictDepth + 1); + pDepth = pScreen->allowedDepths + d; + + nvisual = 0; + for (v = 0; v < pDepth->numVids; v++) + { + pVisual = findVisual (pScreen, pDepth->vids[v]); + if (pVisual && (pFormat = PictureMatchVisual (pScreen, + pDepth->depth, + pVisual))) + { + pictVisual->visual = pVisual->vid; + pictVisual->format = pFormat->id; + if (client->swapped) + { + swapl (&pictVisual->visual, n); + swapl (&pictVisual->format, n); + } + pictVisual++; + nvisual++; + } + } + pictDepth->depth = pDepth->depth; + pictDepth->nPictVisuals = nvisual; + if (client->swapped) + { + swaps (&pictDepth->nPictVisuals, n); + } + ndepth++; + pictDepth = (xPictDepth *) pictVisual; + } + pictScreen->nDepth = ndepth; + ps = GetPictureScreenIfSet(pScreen); + if (ps) + pictScreen->fallback = ps->fallback->id; + else + pictScreen->fallback = 0; + if (client->swapped) + { + swapl (&pictScreen->nDepth, n); + swapl (&pictScreen->fallback, n); + } + pictScreen = (xPictScreen *) pictDepth; + } + pictSubpixel = (CARD32 *) pictScreen; + + for (s = 0; s < numSubpixel; s++) + { + pScreen = screenInfo.screens[s]; + ps = GetPictureScreenIfSet(pScreen); + if (ps) + *pictSubpixel = ps->subpixel; + else + *pictSubpixel = SubPixelUnknown; + if (client->swapped) + { + swapl (pictSubpixel, n); + } + ++pictSubpixel; + } + + if (client->swapped) + { + swaps (&reply->sequenceNumber, n); + swapl (&reply->length, n); + swapl (&reply->numFormats, n); + swapl (&reply->numScreens, n); + swapl (&reply->numDepths, n); + swapl (&reply->numVisuals, n); + swapl (&reply->numSubpixel, n); + } + WriteToClient(client, rlength, (char *) reply); + free(reply); + return Success; +} + +static int +ProcRenderQueryPictIndexValues (ClientPtr client) +{ + PictFormatPtr pFormat; + int rc, num; + int rlength; + int i, n; + REQUEST(xRenderQueryPictIndexValuesReq); + xRenderQueryPictIndexValuesReply *reply; + xIndexValue *values; + + REQUEST_AT_LEAST_SIZE(xRenderQueryPictIndexValuesReq); + + rc = dixLookupResourceByType((pointer *)&pFormat, stuff->format, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + + if (pFormat->type != PictTypeIndexed) + { + client->errorValue = stuff->format; + return BadMatch; + } + num = pFormat->index.nvalues; + rlength = (sizeof (xRenderQueryPictIndexValuesReply) + + num * sizeof(xIndexValue)); + reply = (xRenderQueryPictIndexValuesReply *) malloc(rlength); + if (!reply) + return BadAlloc; + + reply->type = X_Reply; + reply->sequenceNumber = client->sequence; + reply->length = bytes_to_int32(rlength - sizeof(xGenericReply)); + reply->numIndexValues = num; + + values = (xIndexValue *) (reply + 1); + + memcpy (reply + 1, pFormat->index.pValues, num * sizeof (xIndexValue)); + + if (client->swapped) + { + for (i = 0; i < num; i++) + { + swapl (&values[i].pixel, n); + swaps (&values[i].red, n); + swaps (&values[i].green, n); + swaps (&values[i].blue, n); + swaps (&values[i].alpha, n); + } + swaps (&reply->sequenceNumber, n); + swapl (&reply->length, n); + swapl (&reply->numIndexValues, n); + } + + WriteToClient(client, rlength, (char *) reply); + free(reply); + return Success; +} + +static int +ProcRenderQueryDithers (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderCreatePicture (ClientPtr client) +{ + PicturePtr pPicture; + DrawablePtr pDrawable; + PictFormatPtr pFormat; + int len, error, rc; + REQUEST(xRenderCreatePictureReq); + + REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); + + LEGAL_NEW_RESOURCE(stuff->pid, client); + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixReadAccess|DixAddAccess); + if (rc != Success) + return rc; + + rc = dixLookupResourceByType((pointer *)&pFormat, stuff->format, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + + if (pFormat->depth != pDrawable->depth) + return BadMatch; + len = client->req_len - bytes_to_int32(sizeof(xRenderCreatePictureReq)); + if (Ones(stuff->mask) != len) + return BadLength; + + pPicture = CreatePicture (stuff->pid, + pDrawable, + pFormat, + stuff->mask, + (XID *) (stuff + 1), + client, + &error); + if (!pPicture) + return error; + if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) + return BadAlloc; + return Success; +} + +static int +ProcRenderChangePicture (ClientPtr client) +{ + PicturePtr pPicture; + REQUEST(xRenderChangePictureReq); + int len; + + REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq); + VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess); + + len = client->req_len - bytes_to_int32(sizeof(xRenderChangePictureReq)); + if (Ones(stuff->mask) != len) + return BadLength; + + return ChangePicture (pPicture, stuff->mask, (XID *) (stuff + 1), + (DevUnion *) 0, client); +} + +static int +ProcRenderSetPictureClipRectangles (ClientPtr client) +{ + REQUEST(xRenderSetPictureClipRectanglesReq); + PicturePtr pPicture; + int nr; + + REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); + VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess); + if (!pPicture->pDrawable) + return BadDrawable; + + nr = (client->req_len << 2) - sizeof(xRenderSetPictureClipRectanglesReq); + if (nr & 4) + return BadLength; + nr >>= 3; + return SetPictureClipRects (pPicture, + stuff->xOrigin, stuff->yOrigin, + nr, (xRectangle *) &stuff[1]); +} + +static int +ProcRenderFreePicture (ClientPtr client) +{ + PicturePtr pPicture; + REQUEST(xRenderFreePictureReq); + + REQUEST_SIZE_MATCH(xRenderFreePictureReq); + + VERIFY_PICTURE (pPicture, stuff->picture, client, DixDestroyAccess); + FreeResource (stuff->picture, RT_NONE); + return Success; +} + +static Bool +PictOpValid (CARD8 op) +{ + if (/*PictOpMinimum <= op && */ op <= PictOpMaximum) + return TRUE; + if (PictOpDisjointMinimum <= op && op <= PictOpDisjointMaximum) + return TRUE; + if (PictOpConjointMinimum <= op && op <= PictOpConjointMaximum) + return TRUE; + if (PictOpBlendMinimum <= op && op <= PictOpBlendMaximum) + return TRUE; + return FALSE; +} + +static int +ProcRenderComposite (ClientPtr client) +{ + PicturePtr pSrc, pMask, pDst; + REQUEST(xRenderCompositeReq); + + REQUEST_SIZE_MATCH(xRenderCompositeReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); + if (!pDst->pDrawable) + return BadDrawable; + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); + VERIFY_ALPHA (pMask, stuff->mask, client, DixReadAccess); + if ((pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) || + (pMask && pMask->pDrawable && pDst->pDrawable->pScreen != pMask->pDrawable->pScreen)) + return BadMatch; + CompositePicture (stuff->op, + pSrc, + pMask, + pDst, + stuff->xSrc, + stuff->ySrc, + stuff->xMask, + stuff->yMask, + stuff->xDst, + stuff->yDst, + stuff->width, + stuff->height); + return Success; +} + +static int +ProcRenderScale (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderTrapezoids (ClientPtr client) +{ + int rc, ntraps; + PicturePtr pSrc, pDst; + PictFormatPtr pFormat; + REQUEST(xRenderTrapezoidsReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); + if (!pDst->pDrawable) + return BadDrawable; + if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) + return BadMatch; + if (stuff->maskFormat) + { + rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + } + else + pFormat = 0; + ntraps = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq); + if (ntraps % sizeof (xTrapezoid)) + return BadLength; + ntraps /= sizeof (xTrapezoid); + if (ntraps) + CompositeTrapezoids (stuff->op, pSrc, pDst, pFormat, + stuff->xSrc, stuff->ySrc, + ntraps, (xTrapezoid *) &stuff[1]); + return Success; +} + +static int +ProcRenderTriangles (ClientPtr client) +{ + int rc, ntris; + PicturePtr pSrc, pDst; + PictFormatPtr pFormat; + REQUEST(xRenderTrianglesReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); + if (!pDst->pDrawable) + return BadDrawable; + if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) + return BadMatch; + if (stuff->maskFormat) + { + rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + } + else + pFormat = 0; + ntris = (client->req_len << 2) - sizeof (xRenderTrianglesReq); + if (ntris % sizeof (xTriangle)) + return BadLength; + ntris /= sizeof (xTriangle); + if (ntris) + CompositeTriangles (stuff->op, pSrc, pDst, pFormat, + stuff->xSrc, stuff->ySrc, + ntris, (xTriangle *) &stuff[1]); + return Success; +} + +static int +ProcRenderTriStrip (ClientPtr client) +{ + int rc, npoints; + PicturePtr pSrc, pDst; + PictFormatPtr pFormat; + REQUEST(xRenderTrianglesReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); + if (!pDst->pDrawable) + return BadDrawable; + if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) + return BadMatch; + if (stuff->maskFormat) + { + rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + } + else + pFormat = 0; + npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq)); + if (npoints & 4) + return BadLength; + npoints >>= 3; + if (npoints >= 3) + CompositeTriStrip (stuff->op, pSrc, pDst, pFormat, + stuff->xSrc, stuff->ySrc, + npoints, (xPointFixed *) &stuff[1]); + return Success; +} + +static int +ProcRenderTriFan (ClientPtr client) +{ + int rc, npoints; + PicturePtr pSrc, pDst; + PictFormatPtr pFormat; + REQUEST(xRenderTrianglesReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); + if (!pDst->pDrawable) + return BadDrawable; + if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) + return BadMatch; + if (stuff->maskFormat) + { + rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + } + else + pFormat = 0; + npoints = ((client->req_len << 2) - sizeof (xRenderTriStripReq)); + if (npoints & 4) + return BadLength; + npoints >>= 3; + if (npoints >= 3) + CompositeTriFan (stuff->op, pSrc, pDst, pFormat, + stuff->xSrc, stuff->ySrc, + npoints, (xPointFixed *) &stuff[1]); + return Success; +} + +static int +ProcRenderColorTrapezoids (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderColorTriangles (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderTransform (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderCreateGlyphSet (ClientPtr client) +{ + GlyphSetPtr glyphSet; + PictFormatPtr format; + int rc, f; + REQUEST(xRenderCreateGlyphSetReq); + + REQUEST_SIZE_MATCH(xRenderCreateGlyphSetReq); + + LEGAL_NEW_RESOURCE(stuff->gsid, client); + rc = dixLookupResourceByType((pointer *)&format, stuff->format, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + + switch (format->depth) { + case 1: + f = GlyphFormat1; + break; + case 4: + f = GlyphFormat4; + break; + case 8: + f = GlyphFormat8; + break; + case 16: + f = GlyphFormat16; + break; + case 32: + f = GlyphFormat32; + break; + default: + return BadMatch; + } + if (format->type != PictTypeDirect) + return BadMatch; + glyphSet = AllocateGlyphSet (f, format); + if (!glyphSet) + return BadAlloc; + /* security creation/labeling check */ + rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->gsid, GlyphSetType, + glyphSet, RT_NONE, NULL, DixCreateAccess); + if (rc != Success) + return rc; + if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet)) + return BadAlloc; + return Success; +} + +static int +ProcRenderReferenceGlyphSet (ClientPtr client) +{ + GlyphSetPtr glyphSet; + int rc; + REQUEST(xRenderReferenceGlyphSetReq); + + REQUEST_SIZE_MATCH(xRenderReferenceGlyphSetReq); + + LEGAL_NEW_RESOURCE(stuff->gsid, client); + + rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->existing, GlyphSetType, + client, DixGetAttrAccess); + if (rc != Success) + { + client->errorValue = stuff->existing; + return rc; + } + glyphSet->refcnt++; + if (!AddResource (stuff->gsid, GlyphSetType, (pointer)glyphSet)) + return BadAlloc; + return Success; +} + +#define NLOCALDELTA 64 +#define NLOCALGLYPH 256 + +static int +ProcRenderFreeGlyphSet (ClientPtr client) +{ + GlyphSetPtr glyphSet; + int rc; + REQUEST(xRenderFreeGlyphSetReq); + + REQUEST_SIZE_MATCH(xRenderFreeGlyphSetReq); + rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType, + client, DixDestroyAccess); + if (rc != Success) + { + client->errorValue = stuff->glyphset; + return rc; + } + FreeResource (stuff->glyphset, RT_NONE); + return Success; +} + +typedef struct _GlyphNew { + Glyph id; + GlyphPtr glyph; + Bool found; + unsigned char sha1[20]; +} GlyphNewRec, *GlyphNewPtr; + +#define NeedsComponent(f) (PICT_FORMAT_A(f) != 0 && PICT_FORMAT_RGB(f) != 0) + +static int +ProcRenderAddGlyphs (ClientPtr client) +{ + GlyphSetPtr glyphSet; + REQUEST(xRenderAddGlyphsReq); + GlyphNewRec glyphsLocal[NLOCALGLYPH]; + GlyphNewPtr glyphsBase, glyphs, glyph_new; + int remain, nglyphs; + CARD32 *gids; + xGlyphInfo *gi; + CARD8 *bits; + unsigned int size; + int err; + int i, screen; + PicturePtr pSrc = NULL, pDst = NULL; + PixmapPtr pSrcPix = NULL, pDstPix = NULL; + CARD32 component_alpha; + + REQUEST_AT_LEAST_SIZE(xRenderAddGlyphsReq); + err = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType, + client, DixAddAccess); + if (err != Success) + { + client->errorValue = stuff->glyphset; + return err; + } + + err = BadAlloc; + nglyphs = stuff->nglyphs; + if (nglyphs > UINT32_MAX / sizeof(GlyphNewRec)) + return BadAlloc; + + component_alpha = NeedsComponent (glyphSet->format->format); + + if (nglyphs <= NLOCALGLYPH) { + memset (glyphsLocal, 0, sizeof (glyphsLocal)); + glyphsBase = glyphsLocal; + } + else + { + glyphsBase = (GlyphNewPtr)calloc(nglyphs, sizeof (GlyphNewRec)); + if (!glyphsBase) + return BadAlloc; + } + + remain = (client->req_len << 2) - sizeof (xRenderAddGlyphsReq); + + glyphs = glyphsBase; + + gids = (CARD32 *) (stuff + 1); + gi = (xGlyphInfo *) (gids + nglyphs); + bits = (CARD8 *) (gi + nglyphs); + remain -= (sizeof (CARD32) + sizeof (xGlyphInfo)) * nglyphs; + + /* protect against bad nglyphs */ + if (gi < ((xGlyphInfo *)stuff) || + gi > ((xGlyphInfo *)((CARD32 *)stuff + client->req_len)) || + bits < ((CARD8 *)stuff) || + bits > ((CARD8 *)((CARD32 *)stuff + client->req_len))) { + err = BadLength; + goto bail; + } + + for (i = 0; i < nglyphs; i++) + { + size_t padded_width; + glyph_new = &glyphs[i]; + + padded_width = PixmapBytePad (gi[i].width, + glyphSet->format->depth); + + if (gi[i].height && padded_width > (UINT32_MAX - sizeof(GlyphRec))/gi[i].height) + break; + + size = gi[i].height * padded_width; + if (remain < size) + break; + + err = HashGlyph (&gi[i], bits, size, glyph_new->sha1); + if (err) + goto bail; + + glyph_new->glyph = FindGlyphByHash (glyph_new->sha1, + glyphSet->fdepth); + + if (glyph_new->glyph && glyph_new->glyph != DeletedGlyph) + { + glyph_new->found = TRUE; + } + else + { + GlyphPtr glyph; + + glyph_new->found = FALSE; + glyph_new->glyph = glyph = AllocateGlyph (&gi[i], glyphSet->fdepth); + if (! glyph) + { + err = BadAlloc; + goto bail; + } + + for (screen = 0; screen < screenInfo.numScreens; screen++) + { + int width = gi[i].width; + int height = gi[i].height; + int depth = glyphSet->format->depth; + ScreenPtr pScreen; + int error; + + /* Skip work if it's invisibly small anyway */ + if (!width || !height) + break; + + pScreen = screenInfo.screens[screen]; + pSrcPix = GetScratchPixmapHeader (pScreen, + width, height, + depth, depth, + -1, bits); + if (! pSrcPix) + { + err = BadAlloc; + goto bail; + } + + pSrc = CreatePicture (0, &pSrcPix->drawable, + glyphSet->format, 0, NULL, + serverClient, &error); + if (! pSrc) + { + err = BadAlloc; + goto bail; + } + + pDstPix = (pScreen->CreatePixmap) (pScreen, + width, height, depth, + CREATE_PIXMAP_USAGE_GLYPH_PICTURE); + + if (!pDstPix) + { + err = BadAlloc; + goto bail; + } + + GlyphPicture (glyph)[screen] = pDst = + CreatePicture (0, &pDstPix->drawable, + glyphSet->format, + CPComponentAlpha, &component_alpha, + serverClient, &error); + + /* The picture takes a reference to the pixmap, so we + drop ours. */ + (pScreen->DestroyPixmap) (pDstPix); + pDstPix = NULL; + + if (! pDst) + { + err = BadAlloc; + goto bail; + } + + CompositePicture (PictOpSrc, + pSrc, + None, + pDst, + 0, 0, + 0, 0, + 0, 0, + width, height); + + FreePicture ((pointer) pSrc, 0); + pSrc = NULL; + FreeScratchPixmapHeader (pSrcPix); + pSrcPix = NULL; + } + + memcpy (glyph_new->glyph->sha1, glyph_new->sha1, 20); + } + + glyph_new->id = gids[i]; + + if (size & 3) + size += 4 - (size & 3); + bits += size; + remain -= size; + } + if (remain || i < nglyphs) + { + err = BadLength; + goto bail; + } + if (!ResizeGlyphSet (glyphSet, nglyphs)) + { + err = BadAlloc; + goto bail; + } + for (i = 0; i < nglyphs; i++) + AddGlyph (glyphSet, glyphs[i].glyph, glyphs[i].id); + + if (glyphsBase != glyphsLocal) + free(glyphsBase); + return Success; +bail: + if (pSrc) + FreePicture ((pointer) pSrc, 0); + if (pSrcPix) + FreeScratchPixmapHeader (pSrcPix); + for (i = 0; i < nglyphs; i++) + if (glyphs[i].glyph && ! glyphs[i].found) + free(glyphs[i].glyph); + if (glyphsBase != glyphsLocal) + free(glyphsBase); + return err; +} + +static int +ProcRenderAddGlyphsFromPicture (ClientPtr client) +{ + return BadImplementation; +} + +static int +ProcRenderFreeGlyphs (ClientPtr client) +{ + REQUEST(xRenderFreeGlyphsReq); + GlyphSetPtr glyphSet; + int rc, nglyph; + CARD32 *gids; + CARD32 glyph; + + REQUEST_AT_LEAST_SIZE(xRenderFreeGlyphsReq); + rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, GlyphSetType, + client, DixRemoveAccess); + if (rc != Success) + { + client->errorValue = stuff->glyphset; + return rc; + } + nglyph = bytes_to_int32((client->req_len << 2) - sizeof (xRenderFreeGlyphsReq)); + gids = (CARD32 *) (stuff + 1); + while (nglyph-- > 0) + { + glyph = *gids++; + if (!DeleteGlyph (glyphSet, glyph)) + { + client->errorValue = glyph; + return RenderErrBase + BadGlyph; + } + } + return Success; +} + +static int +ProcRenderCompositeGlyphs (ClientPtr client) +{ + GlyphSetPtr glyphSet; + GlyphSet gs; + PicturePtr pSrc, pDst; + PictFormatPtr pFormat; + GlyphListRec listsLocal[NLOCALDELTA]; + GlyphListPtr lists, listsBase; + GlyphPtr glyphsLocal[NLOCALGLYPH]; + Glyph glyph; + GlyphPtr *glyphs, *glyphsBase; + xGlyphElt *elt; + CARD8 *buffer, *end; + int nglyph; + int nlist; + int space; + int size; + int rc, n; + + REQUEST(xRenderCompositeGlyphsReq); + + REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); + + switch (stuff->renderReqType) { + default: size = 1; break; + case X_RenderCompositeGlyphs16: size = 2; break; + case X_RenderCompositeGlyphs32: size = 4; break; + } + + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); + if (!pDst->pDrawable) + return BadDrawable; + if (pSrc->pDrawable && pSrc->pDrawable->pScreen != pDst->pDrawable->pScreen) + return BadMatch; + if (stuff->maskFormat) + { + rc = dixLookupResourceByType((pointer *)&pFormat, stuff->maskFormat, + PictFormatType, client, DixReadAccess); + if (rc != Success) + return rc; + } + else + pFormat = 0; + + rc = dixLookupResourceByType((pointer *)&glyphSet, stuff->glyphset, + GlyphSetType, client, DixUseAccess); + if (rc != Success) + return rc; + + buffer = (CARD8 *) (stuff + 1); + end = (CARD8 *) stuff + (client->req_len << 2); + nglyph = 0; + nlist = 0; + while (buffer + sizeof (xGlyphElt) < end) + { + elt = (xGlyphElt *) buffer; + buffer += sizeof (xGlyphElt); + + if (elt->len == 0xff) + { + buffer += 4; + } + else + { + nlist++; + nglyph += elt->len; + space = size * elt->len; + if (space & 3) + space += 4 - (space & 3); + buffer += space; + } + } + if (nglyph <= NLOCALGLYPH) + glyphsBase = glyphsLocal; + else + { + glyphsBase = (GlyphPtr *) malloc(nglyph * sizeof (GlyphPtr)); + if (!glyphsBase) + return BadAlloc; + } + if (nlist <= NLOCALDELTA) + listsBase = listsLocal; + else + { + listsBase = (GlyphListPtr) malloc(nlist * sizeof (GlyphListRec)); + if (!listsBase) + return BadAlloc; + } + buffer = (CARD8 *) (stuff + 1); + glyphs = glyphsBase; + lists = listsBase; + while (buffer + sizeof (xGlyphElt) < end) + { + elt = (xGlyphElt *) buffer; + buffer += sizeof (xGlyphElt); + + if (elt->len == 0xff) + { + if (buffer + sizeof (GlyphSet) < end) + { + memcpy(&gs, buffer, sizeof(GlyphSet)); + rc = dixLookupResourceByType((pointer *)&glyphSet, gs, + GlyphSetType, client, + DixUseAccess); + if (rc != Success) + { + if (glyphsBase != glyphsLocal) + free(glyphsBase); + if (listsBase != listsLocal) + free(listsBase); + return rc; + } + } + buffer += 4; + } + else + { + lists->xOff = elt->deltax; + lists->yOff = elt->deltay; + lists->format = glyphSet->format; + lists->len = 0; + n = elt->len; + while (n--) + { + if (buffer + size <= end) + { + switch (size) { + case 1: + glyph = *((CARD8 *)buffer); break; + case 2: + glyph = *((CARD16 *)buffer); break; + case 4: + default: + glyph = *((CARD32 *)buffer); break; + } + if ((*glyphs = FindGlyph (glyphSet, glyph))) + { + lists->len++; + glyphs++; + } + } + buffer += size; + } + space = size * elt->len; + if (space & 3) + buffer += 4 - (space & 3); + lists++; + } + } + if (buffer > end) + return BadLength; + + CompositeGlyphs (stuff->op, + pSrc, + pDst, + pFormat, + stuff->xSrc, + stuff->ySrc, + nlist, + listsBase, + glyphsBase); + + if (glyphsBase != glyphsLocal) + free(glyphsBase); + if (listsBase != listsLocal) + free(listsBase); + + return Success; +} + +static int +ProcRenderFillRectangles (ClientPtr client) +{ + PicturePtr pDst; + int things; + REQUEST(xRenderFillRectanglesReq); + + REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq); + if (!PictOpValid (stuff->op)) + { + client->errorValue = stuff->op; + return BadValue; + } + VERIFY_PICTURE (pDst, stuff->dst, client, DixWriteAccess); + if (!pDst->pDrawable) + return BadDrawable; + + things = (client->req_len << 2) - sizeof(xRenderFillRectanglesReq); + if (things & 4) + return BadLength; + things >>= 3; + + CompositeRects (stuff->op, + pDst, + &stuff->color, + things, + (xRectangle *) &stuff[1]); + + return Success; +} + +static void +RenderSetBit (unsigned char *line, int x, int bit) +{ + unsigned char mask; + + if (screenInfo.bitmapBitOrder == LSBFirst) + mask = (1 << (x & 7)); + else + mask = (0x80 >> (x & 7)); + /* XXX assumes byte order is host byte order */ + line += (x >> 3); + if (bit) + *line |= mask; + else + *line &= ~mask; +} + +#define DITHER_DIM 2 + +static CARD32 orderedDither[DITHER_DIM][DITHER_DIM] = { + { 1, 3, }, + { 4, 2, }, +}; + +#define DITHER_SIZE ((sizeof orderedDither / sizeof orderedDither[0][0]) + 1) + +static int +ProcRenderCreateCursor (ClientPtr client) +{ + REQUEST(xRenderCreateCursorReq); + PicturePtr pSrc; + ScreenPtr pScreen; + unsigned short width, height; + CARD32 *argbbits, *argb; + unsigned char *srcbits, *srcline; + unsigned char *mskbits, *mskline; + int stride; + int x, y; + int nbytes_mono; + CursorMetricRec cm; + CursorPtr pCursor; + CARD32 twocolor[3]; + int rc, ncolor; + + REQUEST_SIZE_MATCH (xRenderCreateCursorReq); + LEGAL_NEW_RESOURCE(stuff->cid, client); + + VERIFY_PICTURE (pSrc, stuff->src, client, DixReadAccess); + if (!pSrc->pDrawable) + return BadDrawable; + pScreen = pSrc->pDrawable->pScreen; + width = pSrc->pDrawable->width; + height = pSrc->pDrawable->height; + if (height && width > UINT32_MAX/(height*sizeof(CARD32))) + return BadAlloc; + if ( stuff->x > width + || stuff->y > height ) + return BadMatch; + argbbits = malloc(width * height * sizeof (CARD32)); + if (!argbbits) + return BadAlloc; + + stride = BitmapBytePad(width); + nbytes_mono = stride*height; + srcbits = calloc(1, nbytes_mono); + if (!srcbits) + { + free(argbbits); + return BadAlloc; + } + mskbits = calloc(1, nbytes_mono); + if (!mskbits) + { + free(argbbits); + free(srcbits); + return BadAlloc; + } + + if (pSrc->format == PICT_a8r8g8b8) + { + (*pScreen->GetImage) (pSrc->pDrawable, + 0, 0, width, height, ZPixmap, + 0xffffffff, (pointer) argbbits); + } + else + { + PixmapPtr pPixmap; + PicturePtr pPicture; + PictFormatPtr pFormat; + int error; + + pFormat = PictureMatchFormat (pScreen, 32, PICT_a8r8g8b8); + if (!pFormat) + { + free(argbbits); + free(srcbits); + free(mskbits); + return BadImplementation; + } + pPixmap = (*pScreen->CreatePixmap) (pScreen, width, height, 32, + CREATE_PIXMAP_USAGE_SCRATCH); + if (!pPixmap) + { + free(argbbits); + free(srcbits); + free(mskbits); + return BadAlloc; + } + pPicture = CreatePicture (0, &pPixmap->drawable, pFormat, 0, 0, + client, &error); + if (!pPicture) + { + free(argbbits); + free(srcbits); + free(mskbits); + return error; + } + (*pScreen->DestroyPixmap) (pPixmap); + CompositePicture (PictOpSrc, + pSrc, 0, pPicture, + 0, 0, 0, 0, 0, 0, width, height); + (*pScreen->GetImage) (pPicture->pDrawable, + 0, 0, width, height, ZPixmap, + 0xffffffff, (pointer) argbbits); + FreePicture (pPicture, 0); + } + /* + * Check whether the cursor can be directly supported by + * the core cursor code + */ + ncolor = 0; + argb = argbbits; + for (y = 0; ncolor <= 2 && y < height; y++) + { + for (x = 0; ncolor <= 2 && x < width; x++) + { + CARD32 p = *argb++; + CARD32 a = (p >> 24); + + if (a == 0) /* transparent */ + continue; + if (a == 0xff) /* opaque */ + { + int n; + for (n = 0; n < ncolor; n++) + if (p == twocolor[n]) + break; + if (n == ncolor) + twocolor[ncolor++] = p; + } + else + ncolor = 3; + } + } + + /* + * Convert argb image to two plane cursor + */ + srcline = srcbits; + mskline = mskbits; + argb = argbbits; + for (y = 0; y < height; y++) + { + for (x = 0; x < width; x++) + { + CARD32 p = *argb++; + + if (ncolor <= 2) + { + CARD32 a = ((p >> 24)); + + RenderSetBit (mskline, x, a != 0); + RenderSetBit (srcline, x, a != 0 && p == twocolor[0]); + } + else + { + CARD32 a = ((p >> 24) * DITHER_SIZE + 127) / 255; + CARD32 i = ((CvtR8G8B8toY15(p) >> 7) * DITHER_SIZE + 127) / 255; + CARD32 d = orderedDither[y&(DITHER_DIM-1)][x&(DITHER_DIM-1)]; + /* Set mask from dithered alpha value */ + RenderSetBit(mskline, x, a > d); + /* Set src from dithered intensity value */ + RenderSetBit(srcline, x, a > d && i <= d); + } + } + srcline += stride; + mskline += stride; + } + /* + * Dither to white and black if the cursor has more than two colors + */ + if (ncolor > 2) + { + twocolor[0] = 0xff000000; + twocolor[1] = 0xffffffff; + } + else + { + free(argbbits); + argbbits = 0; + } + +#define GetByte(p,s) (((p) >> (s)) & 0xff) +#define GetColor(p,s) (GetByte(p,s) | (GetByte(p,s) << 8)) + + cm.width = width; + cm.height = height; + cm.xhot = stuff->x; + cm.yhot = stuff->y; + rc = AllocARGBCursor(srcbits, mskbits, argbbits, &cm, + GetColor(twocolor[0], 16), + GetColor(twocolor[0], 8), + GetColor(twocolor[0], 0), + GetColor(twocolor[1], 16), + GetColor(twocolor[1], 8), + GetColor(twocolor[1], 0), + &pCursor, client, stuff->cid); + if (rc != Success) + return rc; + if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) + return BadAlloc; + + return Success; +} + +static int +ProcRenderSetPictureTransform (ClientPtr client) +{ + REQUEST(xRenderSetPictureTransformReq); + PicturePtr pPicture; + + REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq); + VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess); + return SetPictureTransform (pPicture, (PictTransform *) &stuff->transform); +} + +static int +ProcRenderQueryFilters (ClientPtr client) +{ + REQUEST (xRenderQueryFiltersReq); + DrawablePtr pDrawable; + xRenderQueryFiltersReply *reply; + int nbytesName; + int nnames; + ScreenPtr pScreen; + PictureScreenPtr ps; + int i, j, len, total_bytes, rc; + INT16 *aliases; + char *names; + + REQUEST_SIZE_MATCH(xRenderQueryFiltersReq); + rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0, + DixGetAttrAccess); + if (rc != Success) + return rc; + + pScreen = pDrawable->pScreen; + nbytesName = 0; + nnames = 0; + ps = GetPictureScreenIfSet(pScreen); + if (ps) + { + for (i = 0; i < ps->nfilters; i++) + nbytesName += 1 + strlen (ps->filters[i].name); + for (i = 0; i < ps->nfilterAliases; i++) + nbytesName += 1 + strlen (ps->filterAliases[i].alias); + nnames = ps->nfilters + ps->nfilterAliases; + } + len = ((nnames + 1) >> 1) + bytes_to_int32(nbytesName); + total_bytes = sizeof (xRenderQueryFiltersReply) + (len << 2); + reply = (xRenderQueryFiltersReply *) malloc(total_bytes); + if (!reply) + return BadAlloc; + aliases = (INT16 *) (reply + 1); + names = (char *) (aliases + ((nnames + 1) & ~1)); + + reply->type = X_Reply; + reply->sequenceNumber = client->sequence; + reply->length = len; + reply->numAliases = nnames; + reply->numFilters = nnames; + if (ps) + { + + /* fill in alias values */ + for (i = 0; i < ps->nfilters; i++) + aliases[i] = FilterAliasNone; + for (i = 0; i < ps->nfilterAliases; i++) + { + for (j = 0; j < ps->nfilters; j++) + if (ps->filterAliases[i].filter_id == ps->filters[j].id) + break; + if (j == ps->nfilters) + { + for (j = 0; j < ps->nfilterAliases; j++) + if (ps->filterAliases[i].filter_id == + ps->filterAliases[j].alias_id) + { + break; + } + if (j == ps->nfilterAliases) + j = FilterAliasNone; + else + j = j + ps->nfilters; + } + aliases[i + ps->nfilters] = j; + } + + /* fill in filter names */ + for (i = 0; i < ps->nfilters; i++) + { + j = strlen (ps->filters[i].name); + *names++ = j; + strncpy (names, ps->filters[i].name, j); + names += j; + } + + /* fill in filter alias names */ + for (i = 0; i < ps->nfilterAliases; i++) + { + j = strlen (ps->filterAliases[i].alias); + *names++ = j; + strncpy (names, ps->filterAliases[i].alias, j); + names += j; + } + } + + if (client->swapped) + { + register int n; + + for (i = 0; i < reply->numAliases; i++) + { + swaps (&aliases[i], n); + } + swaps(&reply->sequenceNumber, n); + swapl(&reply->length, n); + swapl(&reply->numAliases, n); + swapl(&reply->numFilters, n); + } + WriteToClient(client, total_bytes, (char *) reply); + free(reply); + + return Success; +} + +static int +ProcRenderSetPictureFilter (ClientPtr client) +{ + REQUEST (xRenderSetPictureFilterReq); + PicturePtr pPicture; + int result; + xFixed *params; + int nparams; + char *name; + + REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq); + VERIFY_PICTURE (pPicture, stuff->picture, client, DixSetAttrAccess); + name = (char *) (stuff + 1); + params = (xFixed *) (name + pad_to_int32(stuff->nbytes)); + nparams = ((xFixed *) stuff + client->req_len) - params; + result = SetPictureFilter (pPicture, name, stuff->nbytes, params, nparams); + return result; +} + +static int +ProcRenderCreateAnimCursor (ClientPtr client) +{ + REQUEST(xRenderCreateAnimCursorReq); + CursorPtr *cursors; + CARD32 *deltas; + CursorPtr pCursor; + int ncursor; + xAnimCursorElt *elt; + int i; + int ret; + + REQUEST_AT_LEAST_SIZE(xRenderCreateAnimCursorReq); + LEGAL_NEW_RESOURCE(stuff->cid, client); + if (client->req_len & 1) + return BadLength; + ncursor = (client->req_len - (bytes_to_int32(sizeof(xRenderCreateAnimCursorReq)))) >> 1; + cursors = malloc(ncursor * (sizeof (CursorPtr) + sizeof (CARD32))); + if (!cursors) + return BadAlloc; + deltas = (CARD32 *) (cursors + ncursor); + elt = (xAnimCursorElt *) (stuff + 1); + for (i = 0; i < ncursor; i++) + { + ret = dixLookupResourceByType((pointer *)(cursors + i), elt->cursor, + RT_CURSOR, client, DixReadAccess); + if (ret != Success) + { + free(cursors); + return ret; + } + deltas[i] = elt->delay; + elt++; + } + ret = AnimCursorCreate (cursors, deltas, ncursor, &pCursor, client, + stuff->cid); + free(cursors); + if (ret != Success) + return ret; + + if (AddResource (stuff->cid, RT_CURSOR, (pointer)pCursor)) + return Success; + return BadAlloc; +} + +static int +ProcRenderAddTraps (ClientPtr client) +{ + int ntraps; + PicturePtr pPicture; + REQUEST(xRenderAddTrapsReq); + + REQUEST_AT_LEAST_SIZE(xRenderAddTrapsReq); + VERIFY_PICTURE (pPicture, stuff->picture, client, DixWriteAccess); + if (!pPicture->pDrawable) + return BadDrawable; + ntraps = (client->req_len << 2) - sizeof (xRenderAddTrapsReq); + if (ntraps % sizeof (xTrap)) + return BadLength; + ntraps /= sizeof (xTrap); + if (ntraps) + AddTraps (pPicture, + stuff->xOff, stuff->yOff, + ntraps, (xTrap *) &stuff[1]); + return Success; +} + +static int ProcRenderCreateSolidFill(ClientPtr client) +{ + PicturePtr pPicture; + int error = 0; + REQUEST(xRenderCreateSolidFillReq); + + REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq); + + LEGAL_NEW_RESOURCE(stuff->pid, client); + + pPicture = CreateSolidPicture(stuff->pid, &stuff->color, &error); + if (!pPicture) + return error; + /* security creation/labeling check */ + error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, + pPicture, RT_NONE, NULL, DixCreateAccess); + if (error != Success) + return error; + if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) + return BadAlloc; + return Success; +} + +static int ProcRenderCreateLinearGradient (ClientPtr client) +{ + PicturePtr pPicture; + int len; + int error = 0; + xFixed *stops; + xRenderColor *colors; + REQUEST(xRenderCreateLinearGradientReq); + + REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq); + + LEGAL_NEW_RESOURCE(stuff->pid, client); + + len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + stops = (xFixed *)(stuff + 1); + colors = (xRenderColor *)(stops + stuff->nStops); + + pPicture = CreateLinearGradientPicture (stuff->pid, &stuff->p1, &stuff->p2, + stuff->nStops, stops, colors, &error); + if (!pPicture) + return error; + /* security creation/labeling check */ + error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, + pPicture, RT_NONE, NULL, DixCreateAccess); + if (error != Success) + return error; + if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) + return BadAlloc; + return Success; +} + +static int ProcRenderCreateRadialGradient (ClientPtr client) +{ + PicturePtr pPicture; + int len; + int error = 0; + xFixed *stops; + xRenderColor *colors; + REQUEST(xRenderCreateRadialGradientReq); + + REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq); + + LEGAL_NEW_RESOURCE(stuff->pid, client); + + len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq); + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + stops = (xFixed *)(stuff + 1); + colors = (xRenderColor *)(stops + stuff->nStops); + + pPicture = CreateRadialGradientPicture (stuff->pid, &stuff->inner, &stuff->outer, + stuff->inner_radius, stuff->outer_radius, + stuff->nStops, stops, colors, &error); + if (!pPicture) + return error; + /* security creation/labeling check */ + error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, + pPicture, RT_NONE, NULL, DixCreateAccess); + if (error != Success) + return error; + if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) + return BadAlloc; + return Success; +} + +static int ProcRenderCreateConicalGradient (ClientPtr client) +{ + PicturePtr pPicture; + int len; + int error = 0; + xFixed *stops; + xRenderColor *colors; + REQUEST(xRenderCreateConicalGradientReq); + + REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq); + + LEGAL_NEW_RESOURCE(stuff->pid, client); + + len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq); + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + stops = (xFixed *)(stuff + 1); + colors = (xRenderColor *)(stops + stuff->nStops); + + pPicture = CreateConicalGradientPicture (stuff->pid, &stuff->center, stuff->angle, + stuff->nStops, stops, colors, &error); + if (!pPicture) + return error; + /* security creation/labeling check */ + error = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, PictureType, + pPicture, RT_NONE, NULL, DixCreateAccess); + if (error != Success) + return error; + if (!AddResource (stuff->pid, PictureType, (pointer)pPicture)) + return BadAlloc; + return Success; +} + + +static int +ProcRenderDispatch (ClientPtr client) +{ + REQUEST(xReq); + + if (stuff->data < RenderNumberRequests) + return (*ProcRenderVector[stuff->data]) (client); + else + return BadRequest; +} + +static int +SProcRenderQueryVersion (ClientPtr client) +{ + register int n; + REQUEST(xRenderQueryVersionReq); + + swaps(&stuff->length, n); + swapl(&stuff->majorVersion, n); + swapl(&stuff->minorVersion, n); + return (*ProcRenderVector[stuff->renderReqType])(client); +} + +static int +SProcRenderQueryPictFormats (ClientPtr client) +{ + register int n; + REQUEST(xRenderQueryPictFormatsReq); + swaps(&stuff->length, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderQueryPictIndexValues (ClientPtr client) +{ + register int n; + REQUEST(xRenderQueryPictIndexValuesReq); + swaps(&stuff->length, n); + swapl(&stuff->format, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderQueryDithers (ClientPtr client) +{ + return BadImplementation; +} + +static int +SProcRenderCreatePicture (ClientPtr client) +{ + register int n; + REQUEST(xRenderCreatePictureReq); + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swapl(&stuff->drawable, n); + swapl(&stuff->format, n); + swapl(&stuff->mask, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderChangePicture (ClientPtr client) +{ + register int n; + REQUEST(xRenderChangePictureReq); + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + swapl(&stuff->mask, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderSetPictureClipRectangles (ClientPtr client) +{ + register int n; + REQUEST(xRenderSetPictureClipRectanglesReq); + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + swaps(&stuff->xOrigin, n); + swaps(&stuff->yOrigin, n); + SwapRestS(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderFreePicture (ClientPtr client) +{ + register int n; + REQUEST(xRenderFreePictureReq); + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderComposite (ClientPtr client) +{ + register int n; + REQUEST(xRenderCompositeReq); + swaps(&stuff->length, n); + swapl(&stuff->src, n); + swapl(&stuff->mask, n); + swapl(&stuff->dst, n); + swaps(&stuff->xSrc, n); + swaps(&stuff->ySrc, n); + swaps(&stuff->xMask, n); + swaps(&stuff->yMask, n); + swaps(&stuff->xDst, n); + swaps(&stuff->yDst, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderScale (ClientPtr client) +{ + register int n; + REQUEST(xRenderScaleReq); + swaps(&stuff->length, n); + swapl(&stuff->src, n); + swapl(&stuff->dst, n); + swapl(&stuff->colorScale, n); + swapl(&stuff->alphaScale, n); + swaps(&stuff->xSrc, n); + swaps(&stuff->ySrc, n); + swaps(&stuff->xDst, n); + swaps(&stuff->yDst, n); + swaps(&stuff->width, n); + swaps(&stuff->height, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderTrapezoids (ClientPtr client) +{ + register int n; + REQUEST(xRenderTrapezoidsReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrapezoidsReq); + swaps (&stuff->length, n); + swapl (&stuff->src, n); + swapl (&stuff->dst, n); + swapl (&stuff->maskFormat, n); + swaps (&stuff->xSrc, n); + swaps (&stuff->ySrc, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderTriangles (ClientPtr client) +{ + register int n; + REQUEST(xRenderTrianglesReq); + + REQUEST_AT_LEAST_SIZE(xRenderTrianglesReq); + swaps (&stuff->length, n); + swapl (&stuff->src, n); + swapl (&stuff->dst, n); + swapl (&stuff->maskFormat, n); + swaps (&stuff->xSrc, n); + swaps (&stuff->ySrc, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderTriStrip (ClientPtr client) +{ + register int n; + REQUEST(xRenderTriStripReq); + + REQUEST_AT_LEAST_SIZE(xRenderTriStripReq); + swaps (&stuff->length, n); + swapl (&stuff->src, n); + swapl (&stuff->dst, n); + swapl (&stuff->maskFormat, n); + swaps (&stuff->xSrc, n); + swaps (&stuff->ySrc, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderTriFan (ClientPtr client) +{ + register int n; + REQUEST(xRenderTriFanReq); + + REQUEST_AT_LEAST_SIZE(xRenderTriFanReq); + swaps (&stuff->length, n); + swapl (&stuff->src, n); + swapl (&stuff->dst, n); + swapl (&stuff->maskFormat, n); + swaps (&stuff->xSrc, n); + swaps (&stuff->ySrc, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderColorTrapezoids (ClientPtr client) +{ + return BadImplementation; +} + +static int +SProcRenderColorTriangles (ClientPtr client) +{ + return BadImplementation; +} + +static int +SProcRenderTransform (ClientPtr client) +{ + return BadImplementation; +} + +static int +SProcRenderCreateGlyphSet (ClientPtr client) +{ + register int n; + REQUEST(xRenderCreateGlyphSetReq); + swaps(&stuff->length, n); + swapl(&stuff->gsid, n); + swapl(&stuff->format, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderReferenceGlyphSet (ClientPtr client) +{ + register int n; + REQUEST(xRenderReferenceGlyphSetReq); + swaps(&stuff->length, n); + swapl(&stuff->gsid, n); + swapl(&stuff->existing, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderFreeGlyphSet (ClientPtr client) +{ + register int n; + REQUEST(xRenderFreeGlyphSetReq); + swaps(&stuff->length, n); + swapl(&stuff->glyphset, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderAddGlyphs (ClientPtr client) +{ + register int n; + register int i; + CARD32 *gids; + void *end; + xGlyphInfo *gi; + REQUEST(xRenderAddGlyphsReq); + swaps(&stuff->length, n); + swapl(&stuff->glyphset, n); + swapl(&stuff->nglyphs, n); + if (stuff->nglyphs & 0xe0000000) + return BadLength; + end = (CARD8 *) stuff + (client->req_len << 2); + gids = (CARD32 *) (stuff + 1); + gi = (xGlyphInfo *) (gids + stuff->nglyphs); + if ((char *) end - (char *) (gids + stuff->nglyphs) < 0) + return BadLength; + if ((char *) end - (char *) (gi + stuff->nglyphs) < 0) + return BadLength; + for (i = 0; i < stuff->nglyphs; i++) + { + swapl (&gids[i], n); + swaps (&gi[i].width, n); + swaps (&gi[i].height, n); + swaps (&gi[i].x, n); + swaps (&gi[i].y, n); + swaps (&gi[i].xOff, n); + swaps (&gi[i].yOff, n); + } + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderAddGlyphsFromPicture (ClientPtr client) +{ + return BadImplementation; +} + +static int +SProcRenderFreeGlyphs (ClientPtr client) +{ + register int n; + REQUEST(xRenderFreeGlyphsReq); + swaps(&stuff->length, n); + swapl(&stuff->glyphset, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCompositeGlyphs (ClientPtr client) +{ + register int n; + xGlyphElt *elt; + CARD8 *buffer; + CARD8 *end; + int space; + int i; + int size; + + REQUEST(xRenderCompositeGlyphsReq); + + switch (stuff->renderReqType) { + default: size = 1; break; + case X_RenderCompositeGlyphs16: size = 2; break; + case X_RenderCompositeGlyphs32: size = 4; break; + } + + swaps(&stuff->length, n); + swapl(&stuff->src, n); + swapl(&stuff->dst, n); + swapl(&stuff->maskFormat, n); + swapl(&stuff->glyphset, n); + swaps(&stuff->xSrc, n); + swaps(&stuff->ySrc, n); + buffer = (CARD8 *) (stuff + 1); + end = (CARD8 *) stuff + (client->req_len << 2); + while (buffer + sizeof (xGlyphElt) < end) + { + elt = (xGlyphElt *) buffer; + buffer += sizeof (xGlyphElt); + + swaps (&elt->deltax, n); + swaps (&elt->deltay, n); + + i = elt->len; + if (i == 0xff) + { + swapl (buffer, n); + buffer += 4; + } + else + { + space = size * i; + switch (size) { + case 1: + buffer += i; + break; + case 2: + while (i--) + { + swaps (buffer, n); + buffer += 2; + } + break; + case 4: + while (i--) + { + swapl (buffer, n); + buffer += 4; + } + break; + } + if (space & 3) + buffer += 4 - (space & 3); + } + } + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderFillRectangles (ClientPtr client) +{ + register int n; + REQUEST(xRenderFillRectanglesReq); + + REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq); + swaps(&stuff->length, n); + swapl(&stuff->dst, n); + swaps(&stuff->color.red, n); + swaps(&stuff->color.green, n); + swaps(&stuff->color.blue, n); + swaps(&stuff->color.alpha, n); + SwapRestS(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCreateCursor (ClientPtr client) +{ + register int n; + REQUEST(xRenderCreateCursorReq); + REQUEST_SIZE_MATCH (xRenderCreateCursorReq); + + swaps(&stuff->length, n); + swapl(&stuff->cid, n); + swapl(&stuff->src, n); + swaps(&stuff->x, n); + swaps(&stuff->y, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderSetPictureTransform (ClientPtr client) +{ + register int n; + REQUEST(xRenderSetPictureTransformReq); + REQUEST_SIZE_MATCH(xRenderSetPictureTransformReq); + + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + swapl(&stuff->transform.matrix11, n); + swapl(&stuff->transform.matrix12, n); + swapl(&stuff->transform.matrix13, n); + swapl(&stuff->transform.matrix21, n); + swapl(&stuff->transform.matrix22, n); + swapl(&stuff->transform.matrix23, n); + swapl(&stuff->transform.matrix31, n); + swapl(&stuff->transform.matrix32, n); + swapl(&stuff->transform.matrix33, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderQueryFilters (ClientPtr client) +{ + register int n; + REQUEST (xRenderQueryFiltersReq); + REQUEST_SIZE_MATCH (xRenderQueryFiltersReq); + + swaps(&stuff->length, n); + swapl(&stuff->drawable, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderSetPictureFilter (ClientPtr client) +{ + register int n; + REQUEST (xRenderSetPictureFilterReq); + REQUEST_AT_LEAST_SIZE (xRenderSetPictureFilterReq); + + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + swaps(&stuff->nbytes, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCreateAnimCursor (ClientPtr client) +{ + register int n; + REQUEST (xRenderCreateAnimCursorReq); + REQUEST_AT_LEAST_SIZE (xRenderCreateAnimCursorReq); + + swaps(&stuff->length, n); + swapl(&stuff->cid, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderAddTraps (ClientPtr client) +{ + register int n; + REQUEST (xRenderAddTrapsReq); + REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq); + + swaps(&stuff->length, n); + swapl(&stuff->picture, n); + swaps(&stuff->xOff, n); + swaps(&stuff->yOff, n); + SwapRestL(stuff); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCreateSolidFill(ClientPtr client) +{ + register int n; + REQUEST (xRenderCreateSolidFillReq); + REQUEST_AT_LEAST_SIZE (xRenderCreateSolidFillReq); + + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swaps(&stuff->color.alpha, n); + swaps(&stuff->color.red, n); + swaps(&stuff->color.green, n); + swaps(&stuff->color.blue, n); + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static void swapStops(void *stuff, int num) +{ + int i, n; + CARD32 *stops; + CARD16 *colors; + stops = (CARD32 *)(stuff); + for (i = 0; i < num; ++i) { + swapl(stops, n); + ++stops; + } + colors = (CARD16 *)(stops); + for (i = 0; i < 4*num; ++i) { + swaps(colors, n); + ++colors; + } +} + +static int +SProcRenderCreateLinearGradient (ClientPtr client) +{ + register int n; + int len; + REQUEST (xRenderCreateLinearGradientReq); + REQUEST_AT_LEAST_SIZE (xRenderCreateLinearGradientReq); + + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swapl(&stuff->p1.x, n); + swapl(&stuff->p1.y, n); + swapl(&stuff->p2.x, n); + swapl(&stuff->p2.y, n); + swapl(&stuff->nStops, n); + + len = (client->req_len << 2) - sizeof(xRenderCreateLinearGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + swapStops(stuff+1, stuff->nStops); + + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCreateRadialGradient (ClientPtr client) +{ + register int n; + int len; + REQUEST (xRenderCreateRadialGradientReq); + REQUEST_AT_LEAST_SIZE (xRenderCreateRadialGradientReq); + + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swapl(&stuff->inner.x, n); + swapl(&stuff->inner.y, n); + swapl(&stuff->outer.x, n); + swapl(&stuff->outer.y, n); + swapl(&stuff->inner_radius, n); + swapl(&stuff->outer_radius, n); + swapl(&stuff->nStops, n); + + len = (client->req_len << 2) - sizeof(xRenderCreateRadialGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + swapStops(stuff+1, stuff->nStops); + + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderCreateConicalGradient (ClientPtr client) +{ + register int n; + int len; + REQUEST (xRenderCreateConicalGradientReq); + REQUEST_AT_LEAST_SIZE (xRenderCreateConicalGradientReq); + + swaps(&stuff->length, n); + swapl(&stuff->pid, n); + swapl(&stuff->center.x, n); + swapl(&stuff->center.y, n); + swapl(&stuff->angle, n); + swapl(&stuff->nStops, n); + + len = (client->req_len << 2) - sizeof(xRenderCreateConicalGradientReq); + if (stuff->nStops > UINT32_MAX/(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + if (len != stuff->nStops*(sizeof(xFixed) + sizeof(xRenderColor))) + return BadLength; + + swapStops(stuff+1, stuff->nStops); + + return (*ProcRenderVector[stuff->renderReqType]) (client); +} + +static int +SProcRenderDispatch (ClientPtr client) +{ + REQUEST(xReq); + + if (stuff->data < RenderNumberRequests) + return (*SProcRenderVector[stuff->data]) (client); + else + return BadRequest; +} + +#ifdef PANORAMIX +#define VERIFY_XIN_PICTURE(pPicture, pid, client, mode) {\ + int rc = dixLookupResourceByType((pointer *)&(pPicture), pid,\ + XRT_PICTURE, client, mode);\ + if (rc != Success)\ + return rc;\ +} + +#define VERIFY_XIN_ALPHA(pPicture, pid, client, mode) {\ + if (pid == None) \ + pPicture = 0; \ + else { \ + VERIFY_XIN_PICTURE(pPicture, pid, client, mode); \ + } \ +} \ + +int (*PanoramiXSaveRenderVector[RenderNumberRequests])(ClientPtr); + +static int +PanoramiXRenderCreatePicture (ClientPtr client) +{ + REQUEST(xRenderCreatePictureReq); + PanoramiXRes *refDraw, *newPict; + int result, j; + + REQUEST_AT_LEAST_SIZE(xRenderCreatePictureReq); + result = dixLookupResourceByClass((pointer *)&refDraw, stuff->drawable, + XRC_DRAWABLE, client, DixWriteAccess); + if (result != Success) + return (result == BadValue) ? BadDrawable : result; + if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + newPict->type = XRT_PICTURE; + newPict->info[0].id = stuff->pid; + + if (refDraw->type == XRT_WINDOW && + stuff->drawable == screenInfo.screens[0]->root->drawable.id) + { + newPict->u.pict.root = TRUE; + } + else + newPict->u.pict.root = FALSE; + + for(j = 1; j < PanoramiXNumScreens; j++) + newPict->info[j].id = FakeClientID(client->index); + + FOR_NSCREENS_BACKWARD(j) { + stuff->pid = newPict->info[j].id; + stuff->drawable = refDraw->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderCreatePicture]) (client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newPict->info[0].id, XRT_PICTURE, newPict); + else + free(newPict); + + return result; +} + +static int +PanoramiXRenderChangePicture (ClientPtr client) +{ + PanoramiXRes *pict; + int result = Success, j; + REQUEST(xRenderChangePictureReq); + + REQUEST_AT_LEAST_SIZE(xRenderChangePictureReq); + + VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); + + FOR_NSCREENS_BACKWARD(j) { + stuff->picture = pict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderChangePicture]) (client); + if(result != Success) break; + } + + return result; +} + +static int +PanoramiXRenderSetPictureClipRectangles (ClientPtr client) +{ + REQUEST(xRenderSetPictureClipRectanglesReq); + int result = Success, j; + PanoramiXRes *pict; + + REQUEST_AT_LEAST_SIZE(xRenderSetPictureClipRectanglesReq); + + VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); + + FOR_NSCREENS_BACKWARD(j) { + stuff->picture = pict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderSetPictureClipRectangles]) (client); + if(result != Success) break; + } + + return result; +} + +static int +PanoramiXRenderSetPictureTransform (ClientPtr client) +{ + REQUEST(xRenderSetPictureTransformReq); + int result = Success, j; + PanoramiXRes *pict; + + REQUEST_AT_LEAST_SIZE(xRenderSetPictureTransformReq); + + VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); + + FOR_NSCREENS_BACKWARD(j) { + stuff->picture = pict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderSetPictureTransform]) (client); + if(result != Success) break; + } + + return result; +} + +static int +PanoramiXRenderSetPictureFilter (ClientPtr client) +{ + REQUEST(xRenderSetPictureFilterReq); + int result = Success, j; + PanoramiXRes *pict; + + REQUEST_AT_LEAST_SIZE(xRenderSetPictureFilterReq); + + VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixWriteAccess); + + FOR_NSCREENS_BACKWARD(j) { + stuff->picture = pict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderSetPictureFilter]) (client); + if(result != Success) break; + } + + return result; +} + +static int +PanoramiXRenderFreePicture (ClientPtr client) +{ + PanoramiXRes *pict; + int result = Success, j; + REQUEST(xRenderFreePictureReq); + + REQUEST_SIZE_MATCH(xRenderFreePictureReq); + + client->errorValue = stuff->picture; + + VERIFY_XIN_PICTURE(pict, stuff->picture, client, DixDestroyAccess); + + + FOR_NSCREENS_BACKWARD(j) { + stuff->picture = pict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderFreePicture]) (client); + if(result != Success) break; + } + + /* Since ProcRenderFreePicture is using FreeResource, it will free + our resource for us on the last pass through the loop above */ + + return result; +} + +static int +PanoramiXRenderComposite (ClientPtr client) +{ + PanoramiXRes *src, *msk, *dst; + int result = Success, j; + xRenderCompositeReq orig; + REQUEST(xRenderCompositeReq); + + REQUEST_SIZE_MATCH(xRenderCompositeReq); + + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); + VERIFY_XIN_ALPHA (msk, stuff->mask, client, DixReadAccess); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); + + orig = *stuff; + + FOR_NSCREENS_FORWARD(j) { + stuff->src = src->info[j].id; + if (src->u.pict.root) + { + stuff->xSrc = orig.xSrc - screenInfo.screens[j]->x; + stuff->ySrc = orig.ySrc - screenInfo.screens[j]->y; + } + stuff->dst = dst->info[j].id; + if (dst->u.pict.root) + { + stuff->xDst = orig.xDst - screenInfo.screens[j]->x; + stuff->yDst = orig.yDst - screenInfo.screens[j]->y; + } + if (msk) + { + stuff->mask = msk->info[j].id; + if (msk->u.pict.root) + { + stuff->xMask = orig.xMask - screenInfo.screens[j]->x; + stuff->yMask = orig.yMask - screenInfo.screens[j]->y; + } + } + result = (*PanoramiXSaveRenderVector[X_RenderComposite]) (client); + if(result != Success) break; + } + + return result; +} + +static int +PanoramiXRenderCompositeGlyphs (ClientPtr client) +{ + PanoramiXRes *src, *dst; + int result = Success, j; + REQUEST(xRenderCompositeGlyphsReq); + xGlyphElt origElt, *elt; + INT16 xSrc, ySrc; + + REQUEST_AT_LEAST_SIZE(xRenderCompositeGlyphsReq); + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); + + if (client->req_len << 2 >= (sizeof (xRenderCompositeGlyphsReq) + + sizeof (xGlyphElt))) + { + elt = (xGlyphElt *) (stuff + 1); + origElt = *elt; + xSrc = stuff->xSrc; + ySrc = stuff->ySrc; + FOR_NSCREENS_FORWARD(j) { + stuff->src = src->info[j].id; + if (src->u.pict.root) + { + stuff->xSrc = xSrc - screenInfo.screens[j]->x; + stuff->ySrc = ySrc - screenInfo.screens[j]->y; + } + stuff->dst = dst->info[j].id; + if (dst->u.pict.root) + { + elt->deltax = origElt.deltax - screenInfo.screens[j]->x; + elt->deltay = origElt.deltay - screenInfo.screens[j]->y; + } + result = (*PanoramiXSaveRenderVector[stuff->renderReqType]) (client); + if(result != Success) break; + } + } + + return result; +} + +static int +PanoramiXRenderFillRectangles (ClientPtr client) +{ + PanoramiXRes *dst; + int result = Success, j; + REQUEST(xRenderFillRectanglesReq); + char *extra; + int extra_len; + + REQUEST_AT_LEAST_SIZE (xRenderFillRectanglesReq); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); + extra_len = (client->req_len << 2) - sizeof (xRenderFillRectanglesReq); + if (extra_len && + (extra = (char *) malloc(extra_len))) + { + memcpy (extra, stuff + 1, extra_len); + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + if (dst->u.pict.root) + { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xRectangle *rects = (xRectangle *) (stuff + 1); + int i = extra_len / sizeof (xRectangle); + + while (i--) + { + rects->x -= x_off; + rects->y -= y_off; + rects++; + } + } + } + stuff->dst = dst->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderFillRectangles]) (client); + if(result != Success) break; + } + free(extra); + } + + return result; +} + +static int +PanoramiXRenderTrapezoids(ClientPtr client) +{ + PanoramiXRes *src, *dst; + int result = Success, j; + REQUEST(xRenderTrapezoidsReq); + char *extra; + int extra_len; + + REQUEST_AT_LEAST_SIZE (xRenderTrapezoidsReq); + + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); + + extra_len = (client->req_len << 2) - sizeof (xRenderTrapezoidsReq); + + if (extra_len && + (extra = (char *) malloc(extra_len))) { + memcpy (extra, stuff + 1, extra_len); + + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + if (dst->u.pict.root) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xTrapezoid *trap = (xTrapezoid *) (stuff + 1); + int i = extra_len / sizeof (xTrapezoid); + + while (i--) { + trap->top -= y_off; + trap->bottom -= y_off; + trap->left.p1.x -= x_off; + trap->left.p1.y -= y_off; + trap->left.p2.x -= x_off; + trap->left.p2.y -= y_off; + trap->right.p1.x -= x_off; + trap->right.p1.y -= y_off; + trap->right.p2.x -= x_off; + trap->right.p2.y -= y_off; + trap++; + } + } + } + + stuff->src = src->info[j].id; + stuff->dst = dst->info[j].id; + result = + (*PanoramiXSaveRenderVector[X_RenderTrapezoids]) (client); + + if(result != Success) break; + } + + free(extra); + } + + return result; +} + +static int +PanoramiXRenderTriangles(ClientPtr client) +{ + PanoramiXRes *src, *dst; + int result = Success, j; + REQUEST(xRenderTrianglesReq); + char *extra; + int extra_len; + + REQUEST_AT_LEAST_SIZE (xRenderTrianglesReq); + + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); + + extra_len = (client->req_len << 2) - sizeof (xRenderTrianglesReq); + + if (extra_len && + (extra = (char *) malloc(extra_len))) { + memcpy (extra, stuff + 1, extra_len); + + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + if (dst->u.pict.root) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xTriangle *tri = (xTriangle *) (stuff + 1); + int i = extra_len / sizeof (xTriangle); + + while (i--) { + tri->p1.x -= x_off; + tri->p1.y -= y_off; + tri->p2.x -= x_off; + tri->p2.y -= y_off; + tri->p3.x -= x_off; + tri->p3.y -= y_off; + tri++; + } + } + } + + stuff->src = src->info[j].id; + stuff->dst = dst->info[j].id; + result = + (*PanoramiXSaveRenderVector[X_RenderTriangles]) (client); + + if(result != Success) break; + } + + free(extra); + } + + return result; +} + +static int +PanoramiXRenderTriStrip(ClientPtr client) +{ + PanoramiXRes *src, *dst; + int result = Success, j; + REQUEST(xRenderTriStripReq); + char *extra; + int extra_len; + + REQUEST_AT_LEAST_SIZE (xRenderTriStripReq); + + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); + + extra_len = (client->req_len << 2) - sizeof (xRenderTriStripReq); + + if (extra_len && + (extra = (char *) malloc(extra_len))) { + memcpy (extra, stuff + 1, extra_len); + + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + if (dst->u.pict.root) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xPointFixed *fixed = (xPointFixed *) (stuff + 1); + int i = extra_len / sizeof (xPointFixed); + + while (i--) { + fixed->x -= x_off; + fixed->y -= y_off; + fixed++; + } + } + } + + stuff->src = src->info[j].id; + stuff->dst = dst->info[j].id; + result = + (*PanoramiXSaveRenderVector[X_RenderTriStrip]) (client); + + if(result != Success) break; + } + + free(extra); + } + + return result; +} + +static int +PanoramiXRenderTriFan(ClientPtr client) +{ + PanoramiXRes *src, *dst; + int result = Success, j; + REQUEST(xRenderTriFanReq); + char *extra; + int extra_len; + + REQUEST_AT_LEAST_SIZE (xRenderTriFanReq); + + VERIFY_XIN_PICTURE (src, stuff->src, client, DixReadAccess); + VERIFY_XIN_PICTURE (dst, stuff->dst, client, DixWriteAccess); + + extra_len = (client->req_len << 2) - sizeof (xRenderTriFanReq); + + if (extra_len && + (extra = (char *) malloc(extra_len))) { + memcpy (extra, stuff + 1, extra_len); + + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + if (dst->u.pict.root) { + int x_off = screenInfo.screens[j]->x; + int y_off = screenInfo.screens[j]->y; + + if(x_off || y_off) { + xPointFixed *fixed = (xPointFixed *) (stuff + 1); + int i = extra_len / sizeof (xPointFixed); + + while (i--) { + fixed->x -= x_off; + fixed->y -= y_off; + fixed++; + } + } + } + + stuff->src = src->info[j].id; + stuff->dst = dst->info[j].id; + result = + (*PanoramiXSaveRenderVector[X_RenderTriFan]) (client); + + if(result != Success) break; + } + + free(extra); + } + + return result; +} + +static int +PanoramiXRenderAddTraps (ClientPtr client) +{ + PanoramiXRes *picture; + int result = Success, j; + REQUEST(xRenderAddTrapsReq); + char *extra; + int extra_len; + INT16 x_off, y_off; + + REQUEST_AT_LEAST_SIZE (xRenderAddTrapsReq); + VERIFY_XIN_PICTURE (picture, stuff->picture, client, DixWriteAccess); + extra_len = (client->req_len << 2) - sizeof (xRenderAddTrapsReq); + if (extra_len && + (extra = (char *) malloc(extra_len))) + { + memcpy (extra, stuff + 1, extra_len); + x_off = stuff->xOff; + y_off = stuff->yOff; + FOR_NSCREENS_FORWARD(j) { + if (j) memcpy (stuff + 1, extra, extra_len); + stuff->picture = picture->info[j].id; + + if (picture->u.pict.root) + { + stuff->xOff = x_off + screenInfo.screens[j]->x; + stuff->yOff = y_off + screenInfo.screens[j]->y; + } + result = (*PanoramiXSaveRenderVector[X_RenderAddTraps]) (client); + if(result != Success) break; + } + free(extra); + } + + return result; +} + +static int +PanoramiXRenderCreateSolidFill (ClientPtr client) +{ + REQUEST(xRenderCreateSolidFillReq); + PanoramiXRes *newPict; + int result = Success, j; + + REQUEST_AT_LEAST_SIZE(xRenderCreateSolidFillReq); + + if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newPict->type = XRT_PICTURE; + newPict->info[0].id = stuff->pid; + newPict->u.pict.root = FALSE; + + for(j = 1; j < PanoramiXNumScreens; j++) + newPict->info[j].id = FakeClientID(client->index); + + FOR_NSCREENS_BACKWARD(j) { + stuff->pid = newPict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderCreateSolidFill]) (client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newPict->info[0].id, XRT_PICTURE, newPict); + else + free(newPict); + + return result; +} + +static int +PanoramiXRenderCreateLinearGradient (ClientPtr client) +{ + REQUEST(xRenderCreateLinearGradientReq); + PanoramiXRes *newPict; + int result = Success, j; + + REQUEST_AT_LEAST_SIZE(xRenderCreateLinearGradientReq); + + if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newPict->type = XRT_PICTURE; + newPict->info[0].id = stuff->pid; + newPict->u.pict.root = FALSE; + + for(j = 1; j < PanoramiXNumScreens; j++) + newPict->info[j].id = FakeClientID(client->index); + + FOR_NSCREENS_BACKWARD(j) { + stuff->pid = newPict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderCreateLinearGradient]) (client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newPict->info[0].id, XRT_PICTURE, newPict); + else + free(newPict); + + return result; +} + +static int +PanoramiXRenderCreateRadialGradient (ClientPtr client) +{ + REQUEST(xRenderCreateRadialGradientReq); + PanoramiXRes *newPict; + int result = Success, j; + + REQUEST_AT_LEAST_SIZE(xRenderCreateRadialGradientReq); + + if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newPict->type = XRT_PICTURE; + newPict->info[0].id = stuff->pid; + newPict->u.pict.root = FALSE; + + for(j = 1; j < PanoramiXNumScreens; j++) + newPict->info[j].id = FakeClientID(client->index); + + FOR_NSCREENS_BACKWARD(j) { + stuff->pid = newPict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderCreateRadialGradient]) (client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newPict->info[0].id, XRT_PICTURE, newPict); + else + free(newPict); + + return result; +} + +static int +PanoramiXRenderCreateConicalGradient (ClientPtr client) +{ + REQUEST(xRenderCreateConicalGradientReq); + PanoramiXRes *newPict; + int result = Success, j; + + REQUEST_AT_LEAST_SIZE(xRenderCreateConicalGradientReq); + + if(!(newPict = (PanoramiXRes *) malloc(sizeof(PanoramiXRes)))) + return BadAlloc; + + newPict->type = XRT_PICTURE; + newPict->info[0].id = stuff->pid; + newPict->u.pict.root = FALSE; + + for(j = 1; j < PanoramiXNumScreens; j++) + newPict->info[j].id = FakeClientID(client->index); + + FOR_NSCREENS_BACKWARD(j) { + stuff->pid = newPict->info[j].id; + result = (*PanoramiXSaveRenderVector[X_RenderCreateConicalGradient]) (client); + if(result != Success) break; + } + + if (result == Success) + AddResource(newPict->info[0].id, XRT_PICTURE, newPict); + else + free(newPict); + + return result; +} + +void +PanoramiXRenderInit (void) +{ + int i; + + XRT_PICTURE = CreateNewResourceType (XineramaDeleteResource, + "XineramaPicture"); + if (RenderErrBase) + SetResourceTypeErrorValue(XRT_PICTURE, RenderErrBase + BadPicture); + for (i = 0; i < RenderNumberRequests; i++) + PanoramiXSaveRenderVector[i] = ProcRenderVector[i]; + /* + * Stuff in Xinerama aware request processing hooks + */ + ProcRenderVector[X_RenderCreatePicture] = PanoramiXRenderCreatePicture; + ProcRenderVector[X_RenderChangePicture] = PanoramiXRenderChangePicture; + ProcRenderVector[X_RenderSetPictureTransform] = PanoramiXRenderSetPictureTransform; + ProcRenderVector[X_RenderSetPictureFilter] = PanoramiXRenderSetPictureFilter; + ProcRenderVector[X_RenderSetPictureClipRectangles] = PanoramiXRenderSetPictureClipRectangles; + ProcRenderVector[X_RenderFreePicture] = PanoramiXRenderFreePicture; + ProcRenderVector[X_RenderComposite] = PanoramiXRenderComposite; + ProcRenderVector[X_RenderCompositeGlyphs8] = PanoramiXRenderCompositeGlyphs; + ProcRenderVector[X_RenderCompositeGlyphs16] = PanoramiXRenderCompositeGlyphs; + ProcRenderVector[X_RenderCompositeGlyphs32] = PanoramiXRenderCompositeGlyphs; + ProcRenderVector[X_RenderFillRectangles] = PanoramiXRenderFillRectangles; + + ProcRenderVector[X_RenderTrapezoids] = PanoramiXRenderTrapezoids; + ProcRenderVector[X_RenderTriangles] = PanoramiXRenderTriangles; + ProcRenderVector[X_RenderTriStrip] = PanoramiXRenderTriStrip; + ProcRenderVector[X_RenderTriFan] = PanoramiXRenderTriFan; + ProcRenderVector[X_RenderAddTraps] = PanoramiXRenderAddTraps; + + ProcRenderVector[X_RenderCreateSolidFill] = PanoramiXRenderCreateSolidFill; + ProcRenderVector[X_RenderCreateLinearGradient] = PanoramiXRenderCreateLinearGradient; + ProcRenderVector[X_RenderCreateRadialGradient] = PanoramiXRenderCreateRadialGradient; + ProcRenderVector[X_RenderCreateConicalGradient] = PanoramiXRenderCreateConicalGradient; +} + +void +PanoramiXRenderReset (void) +{ + int i; + for (i = 0; i < RenderNumberRequests; i++) + ProcRenderVector[i] = PanoramiXSaveRenderVector[i]; + RenderErrBase = 0; +} + +#endif /* PANORAMIX */ -- cgit v1.2.3