diff options
Diffstat (limited to 'xorg-server')
291 files changed, 106476 insertions, 75166 deletions
diff --git a/xorg-server/Xext/Makefile b/xorg-server/Xext/Makefile new file mode 100644 index 000000000..204ffe797 --- /dev/null +++ b/xorg-server/Xext/Makefile @@ -0,0 +1,38 @@ +CSRCS=\ +bigreq.c \ +dpms.c \ +dpmsstubs.c \ +mbuf.c \ +saver.c \ +security.c \ +shape.c \ +sleepuntil.c \ +sync.c \ +xace.c \ +xcmisc.c \ +xres.c \ +xtest.c \ +geext.c \ +panoramiX.c \ +panoramiXprocs.c \ +panoramiXSwap.c + +#shm.c \ +#appgroup.c \ +#fontcache.c \ +#mbufbf.c \ +#mbufpx.c \ +#xcalibrate.c \ +#xf86bigfont.c \ +#xprint.c \ +#xselinux.c \ +#xvdisp.c \ +#xvmain.c \ +#xvmc.c + +LIBRARY=libxext + +INCLUDES += ..\hw\xfree86\dixmods\extmod + + + diff --git a/xorg-server/Xext/dpms.c b/xorg-server/Xext/dpms.c index df63a8bf1..1130fe244 100644 --- a/xorg-server/Xext/dpms.c +++ b/xorg-server/Xext/dpms.c @@ -28,6 +28,8 @@ Equipment Corporation. #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else +#define DPMSExtension #endif #include <X11/X.h> diff --git a/xorg-server/Xext/mbuf.c b/xorg-server/Xext/mbuf.c index aacb9cfde..b4c635799 100644 --- a/xorg-server/Xext/mbuf.c +++ b/xorg-server/Xext/mbuf.c @@ -468,7 +468,7 @@ MultibufferExtensionInit() */ MultibufferDrawableResType = CreateNewResourceType(MultibufferDrawableDelete, "MultibufferDrawable"); - if (MultiBufferDrawableResType) + if (MultibufferDrawableResType) MultibufferDrawableResType |= RC_DRAWABLE; MultibufferResType = CreateNewResourceType(MultibufferDelete, "MultibufferBuffer"); diff --git a/xorg-server/Xext/saver.c b/xorg-server/Xext/saver.c index 2549e8a31..ab8fd79c9 100644 --- a/xorg-server/Xext/saver.c +++ b/xorg-server/Xext/saver.c @@ -1,1539 +1,1545 @@ -/* - * -Copyright (c) 1992 X Consortium - -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 -X CONSORTIUM 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 X Consortium 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 X Consortium. - * - * Author: Keith Packard, MIT X Consortium - */ - - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <X11/X.h> -#include <X11/Xproto.h> -#include "misc.h" -#include "os.h" -#include "windowstr.h" -#include "scrnintstr.h" -#include "pixmapstr.h" -#include "extnsionst.h" -#include "dixstruct.h" -#include "resource.h" -#include "opaque.h" -#include <X11/extensions/saverproto.h> -#include "gcstruct.h" -#include "cursorstr.h" -#include "colormapst.h" -#include "xace.h" -#ifdef PANORAMIX -#include "panoramiX.h" -#include "panoramiXsrv.h" -#endif -#ifdef DPMSExtension -#include <X11/extensions/dpmsconst.h> -#endif -#include "protocol-versions.h" - -#include <stdio.h> - -#include "modinit.h" - -static int ScreenSaverEventBase = 0; - -static DISPATCH_PROC(ProcScreenSaverQueryInfo); -static DISPATCH_PROC(ProcScreenSaverDispatch); -static DISPATCH_PROC(ProcScreenSaverQueryVersion); -static DISPATCH_PROC(ProcScreenSaverSelectInput); -static DISPATCH_PROC(ProcScreenSaverSetAttributes); -static DISPATCH_PROC(ProcScreenSaverUnsetAttributes); -static DISPATCH_PROC(ProcScreenSaverSuspend); -static DISPATCH_PROC(SProcScreenSaverDispatch); -static DISPATCH_PROC(SProcScreenSaverQueryInfo); -static DISPATCH_PROC(SProcScreenSaverQueryVersion); -static DISPATCH_PROC(SProcScreenSaverSelectInput); -static DISPATCH_PROC(SProcScreenSaverSetAttributes); -static DISPATCH_PROC(SProcScreenSaverUnsetAttributes); -static DISPATCH_PROC(SProcScreenSaverSuspend); - -static Bool ScreenSaverHandle ( - ScreenPtr /* pScreen */, - int /* xstate */, - Bool /* force */ - ); - -static Bool -CreateSaverWindow ( - ScreenPtr /* pScreen */ - ); - -static Bool -DestroySaverWindow ( - ScreenPtr /* pScreen */ - ); - -static void -UninstallSaverColormap ( - ScreenPtr /* pScreen */ - ); - -static void -CheckScreenPrivate ( - ScreenPtr /* pScreen */ - ); - -static void SScreenSaverNotifyEvent ( - xScreenSaverNotifyEvent * /* from */, - xScreenSaverNotifyEvent * /* to */ - ); - -static RESTYPE SuspendType; /* resource type for suspension records */ - -typedef struct _ScreenSaverSuspension *ScreenSaverSuspensionPtr; - -/* List of clients that are suspending the screensaver. */ -static ScreenSaverSuspensionPtr suspendingClients = NULL; - -/* - * clientResource is a resource ID that's added when the record is - * allocated, so the record is freed and the screensaver resumed when - * the client disconnects. count is the number of times the client has - * requested the screensaver be suspended. - */ -typedef struct _ScreenSaverSuspension -{ - ScreenSaverSuspensionPtr next; - ClientPtr pClient; - XID clientResource; - int count; -} ScreenSaverSuspensionRec; - -static int ScreenSaverFreeSuspend( - pointer /*value */, - XID /* id */ -); - -/* - * each screen has a list of clients requesting - * ScreenSaverNotify events. Each client has a resource - * for each screen it selects ScreenSaverNotify input for, - * this resource is used to delete the ScreenSaverNotifyRec - * entry from the per-screen queue. - */ - -static RESTYPE SaverEventType; /* resource type for event masks */ - -typedef struct _ScreenSaverEvent *ScreenSaverEventPtr; - -typedef struct _ScreenSaverEvent { - ScreenSaverEventPtr next; - ClientPtr client; - ScreenPtr screen; - XID resource; - CARD32 mask; -} ScreenSaverEventRec; - -static int ScreenSaverFreeEvents( - pointer /* value */, - XID /* id */ -); - -static Bool setEventMask ( - ScreenPtr /* pScreen */, - ClientPtr /* client */, - unsigned long /* mask */ -); - -static unsigned long getEventMask ( - ScreenPtr /* pScreen */, - ClientPtr /* client */ -); - -/* - * when a client sets the screen saver attributes, a resource is - * kept to be freed when the client exits - */ - -static RESTYPE AttrType; /* resource type for attributes */ - -typedef struct _ScreenSaverAttr { - ScreenPtr screen; - ClientPtr client; - XID resource; - short x, y; - unsigned short width, height, borderWidth; - unsigned char class; - unsigned char depth; - VisualID visual; - CursorPtr pCursor; - PixmapPtr pBackgroundPixmap; - PixmapPtr pBorderPixmap; - Colormap colormap; - unsigned long mask; /* no pixmaps or cursors */ - unsigned long *values; -} ScreenSaverAttrRec, *ScreenSaverAttrPtr; - -static int ScreenSaverFreeAttr ( - pointer /* value */, - XID /* id */ -); - -static void FreeAttrs ( - ScreenSaverAttrPtr /* pAttr */ -); - -static void FreeScreenAttr ( - ScreenSaverAttrPtr /* pAttr */ -); - -static void -SendScreenSaverNotify ( - ScreenPtr /* pScreen */, - int /* state */, - Bool /* forced */ -); - -typedef struct _ScreenSaverScreenPrivate { - ScreenSaverEventPtr events; - ScreenSaverAttrPtr attr; - Bool hasWindow; - Colormap installedMap; -} ScreenSaverScreenPrivateRec, *ScreenSaverScreenPrivatePtr; - -static ScreenSaverScreenPrivatePtr -MakeScreenPrivate ( - ScreenPtr /* pScreen */ - ); - -static int ScreenPrivateKeyIndex; -static DevPrivateKey ScreenPrivateKey = &ScreenPrivateKeyIndex; - -#define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr) \ - dixLookupPrivate(&(s)->devPrivates, ScreenPrivateKey)) -#define SetScreenPrivate(s,v) \ - dixSetPrivate(&(s)->devPrivates, ScreenPrivateKey, v); -#define SetupScreen(s) ScreenSaverScreenPrivatePtr pPriv = (s ? GetScreenPrivate(s) : NULL) - -#define New(t) (xalloc (sizeof (t))) - -/**************** - * ScreenSaverExtensionInit - * - * Called from InitExtensions in main() or from QueryExtension() if the - * extension is dynamically loaded. - * - ****************/ - -void -ScreenSaverExtensionInit(INITARGS) -{ - ExtensionEntry *extEntry; - int i; - ScreenPtr pScreen; - - AttrType = CreateNewResourceType(ScreenSaverFreeAttr, "SaverAttr"); - SaverEventType = CreateNewResourceType(ScreenSaverFreeEvents, - "SaverEvent"); - SuspendType = CreateNewResourceType(ScreenSaverFreeSuspend, - "SaverSuspend"); - - for (i = 0; i < screenInfo.numScreens; i++) - { - pScreen = screenInfo.screens[i]; - SetScreenPrivate (pScreen, NULL); - } - if (AttrType && SaverEventType && SuspendType && - (extEntry = AddExtension(ScreenSaverName, ScreenSaverNumberEvents, 0, - ProcScreenSaverDispatch, SProcScreenSaverDispatch, - NULL, StandardMinorOpcode))) - { - ScreenSaverEventBase = extEntry->eventBase; - EventSwapVector[ScreenSaverEventBase] = (EventSwapPtr) SScreenSaverNotifyEvent; - } -} - -static void -CheckScreenPrivate (ScreenPtr pScreen) -{ - SetupScreen (pScreen); - - if (!pPriv) - return; - if (!pPriv->attr && !pPriv->events && - !pPriv->hasWindow && pPriv->installedMap == None) - { - xfree (pPriv); - SetScreenPrivate (pScreen, NULL); - savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL; - } -} - -static ScreenSaverScreenPrivatePtr -MakeScreenPrivate (ScreenPtr pScreen) -{ - SetupScreen (pScreen); - - if (pPriv) - return pPriv; - pPriv = New (ScreenSaverScreenPrivateRec); - if (!pPriv) - return 0; - pPriv->events = 0; - pPriv->attr = 0; - pPriv->hasWindow = FALSE; - pPriv->installedMap = None; - SetScreenPrivate (pScreen, pPriv); - savedScreenInfo[pScreen->myNum].ExternalScreenSaver = ScreenSaverHandle; - return pPriv; -} - -static unsigned long -getEventMask (ScreenPtr pScreen, ClientPtr client) -{ - SetupScreen(pScreen); - ScreenSaverEventPtr pEv; - - if (!pPriv) - return 0; - for (pEv = pPriv->events; pEv; pEv = pEv->next) - if (pEv->client == client) - return pEv->mask; - return 0; -} - -static Bool -setEventMask (ScreenPtr pScreen, ClientPtr client, unsigned long mask) -{ - SetupScreen(pScreen); - ScreenSaverEventPtr pEv, *pPrev; - - if (getEventMask (pScreen, client) == mask) - return TRUE; - if (!pPriv) - { - pPriv = MakeScreenPrivate (pScreen); - if (!pPriv) - return FALSE; - } - for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next) - if (pEv->client == client) - break; - if (mask == 0) - { - FreeResource (pEv->resource, SaverEventType); - *pPrev = pEv->next; - xfree (pEv); - CheckScreenPrivate (pScreen); - } - else - { - if (!pEv) - { - pEv = New (ScreenSaverEventRec); - if (!pEv) - { - CheckScreenPrivate (pScreen); - return FALSE; - } - *pPrev = pEv; - pEv->next = NULL; - pEv->client = client; - pEv->screen = pScreen; - pEv->resource = FakeClientID (client->index); - if (!AddResource (pEv->resource, SaverEventType, (pointer) pEv)) - return FALSE; - } - pEv->mask = mask; - } - return TRUE; -} - -static void -FreeAttrs (ScreenSaverAttrPtr pAttr) -{ - PixmapPtr pPixmap; - CursorPtr pCursor; - - if ((pPixmap = pAttr->pBackgroundPixmap) != 0) - (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); - if ((pPixmap = pAttr->pBorderPixmap) != 0) - (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); - if ((pCursor = pAttr->pCursor) != 0) - FreeCursor (pCursor, (Cursor) 0); -} - -static void -FreeScreenAttr (ScreenSaverAttrPtr pAttr) -{ - FreeAttrs (pAttr); - xfree (pAttr->values); - xfree (pAttr); -} - -static int -ScreenSaverFreeEvents (pointer value, XID id) -{ - ScreenSaverEventPtr pOld = (ScreenSaverEventPtr)value; - ScreenPtr pScreen = pOld->screen; - SetupScreen (pScreen); - ScreenSaverEventPtr pEv, *pPrev; - - if (!pPriv) - return TRUE; - for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next) - if (pEv == pOld) - break; - if (!pEv) - return TRUE; - *pPrev = pEv->next; - xfree (pEv); - CheckScreenPrivate (pScreen); - return TRUE; -} - -static int -ScreenSaverFreeAttr (pointer value, XID id) -{ - ScreenSaverAttrPtr pOldAttr = (ScreenSaverAttrPtr)value; - ScreenPtr pScreen = pOldAttr->screen; - SetupScreen (pScreen); - - if (!pPriv) - return TRUE; - if (pPriv->attr != pOldAttr) - return TRUE; - FreeScreenAttr (pOldAttr); - pPriv->attr = NULL; - if (pPriv->hasWindow) - { - dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset); - dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverActive); - } - CheckScreenPrivate (pScreen); - return TRUE; -} - -static int -ScreenSaverFreeSuspend (pointer value, XID id) -{ - ScreenSaverSuspensionPtr data = (ScreenSaverSuspensionPtr) value; - ScreenSaverSuspensionPtr *prev, this; - - /* Unlink and free the suspension record for the client */ - for (prev = &suspendingClients; (this = *prev); prev = &this->next) - { - if (this == data) - { - *prev = this->next; - xfree (this); - break; - } - } - - /* Reenable the screensaver if this was the last client suspending it. */ - if (screenSaverSuspended && suspendingClients == NULL) - { - screenSaverSuspended = FALSE; - - /* The screensaver could be active, since suspending it (by design) - doesn't prevent it from being forceably activated */ -#ifdef DPMSExtension - if (screenIsSaved != SCREEN_SAVER_ON && DPMSPowerLevel == DPMSModeOn) -#else - if (screenIsSaved != SCREEN_SAVER_ON) -#endif - { - UpdateCurrentTimeIf(); - lastDeviceEventTime = currentTime; - SetScreenSaverTimer(); - } - } - - return Success; -} - -static void -SendScreenSaverNotify (ScreenPtr pScreen, int state, Bool forced) -{ - ScreenSaverScreenPrivatePtr pPriv; - ScreenSaverEventPtr pEv; - unsigned long mask; - xScreenSaverNotifyEvent ev; - ClientPtr client; - int kind; - - UpdateCurrentTimeIf (); - mask = ScreenSaverNotifyMask; - if (state == ScreenSaverCycle) - mask = ScreenSaverCycleMask; - pScreen = screenInfo.screens[pScreen->myNum]; - pPriv = GetScreenPrivate(pScreen); - if (!pPriv) - return; - if (pPriv->attr) - kind = ScreenSaverExternal; - else if (ScreenSaverBlanking != DontPreferBlanking) - kind = ScreenSaverBlanked; - else - kind = ScreenSaverInternal; - for (pEv = pPriv->events; pEv; pEv = pEv->next) - { - client = pEv->client; - if (client->clientGone) - continue; - if (!(pEv->mask & mask)) - continue; - ev.type = ScreenSaverNotify + ScreenSaverEventBase; - ev.state = state; - ev.sequenceNumber = client->sequence; - ev.timestamp = currentTime.milliseconds; - ev.root = WindowTable[pScreen->myNum]->drawable.id; - ev.window = savedScreenInfo[pScreen->myNum].wid; - ev.kind = kind; - ev.forced = forced; - WriteEventsToClient (client, 1, (xEvent *) &ev); - } -} - -static void -SScreenSaverNotifyEvent (xScreenSaverNotifyEvent *from, - xScreenSaverNotifyEvent *to) -{ - to->type = from->type; - to->state = from->state; - cpswaps (from->sequenceNumber, to->sequenceNumber); - cpswapl (from->timestamp, to->timestamp); - cpswapl (from->root, to->root); - cpswapl (from->window, to->window); - to->kind = from->kind; - to->forced = from->forced; -} - -static void -UninstallSaverColormap (ScreenPtr pScreen) -{ - SetupScreen(pScreen); - ColormapPtr pCmap; - int rc; - - if (pPriv && pPriv->installedMap != None) - { - rc = dixLookupResourceByType((pointer *)&pCmap, pPriv->installedMap, - RT_COLORMAP, serverClient, - DixUninstallAccess); - if (rc == Success) - (*pCmap->pScreen->UninstallColormap) (pCmap); - pPriv->installedMap = None; - CheckScreenPrivate (pScreen); - } -} - -static Bool -CreateSaverWindow (ScreenPtr pScreen) -{ - SetupScreen (pScreen); - ScreenSaverStuffPtr pSaver; - ScreenSaverAttrPtr pAttr; - WindowPtr pWin; - int result; - unsigned long mask; - Colormap *installedMaps; - int numInstalled; - int i; - Colormap wantMap; - ColormapPtr pCmap; - - pSaver = &savedScreenInfo[pScreen->myNum]; - if (pSaver->pWindow) - { - pSaver->pWindow = NullWindow; - FreeResource (pSaver->wid, RT_NONE); - if (pPriv) - { - UninstallSaverColormap (pScreen); - pPriv->hasWindow = FALSE; - CheckScreenPrivate (pScreen); - } - } - - if (!pPriv || !(pAttr = pPriv->attr)) - return FALSE; - - pPriv->installedMap = None; - - if (GrabInProgress && GrabInProgress != pAttr->client->index) - return FALSE; - - pWin = CreateWindow (pSaver->wid, WindowTable[pScreen->myNum], - pAttr->x, pAttr->y, pAttr->width, pAttr->height, - pAttr->borderWidth, pAttr->class, - pAttr->mask, (XID *)pAttr->values, - pAttr->depth, serverClient, pAttr->visual, - &result); - if (!pWin) - return FALSE; - - if (!AddResource(pWin->drawable.id, RT_WINDOW, pWin)) - return FALSE; - - mask = 0; - if (pAttr->pBackgroundPixmap) - { - pWin->backgroundState = BackgroundPixmap; - pWin->background.pixmap = pAttr->pBackgroundPixmap; - pAttr->pBackgroundPixmap->refcnt++; - mask |= CWBackPixmap; - } - if (pAttr->pBorderPixmap) - { - pWin->borderIsPixel = FALSE; - pWin->border.pixmap = pAttr->pBorderPixmap; - pAttr->pBorderPixmap->refcnt++; - mask |= CWBorderPixmap; - } - if (pAttr->pCursor) - { - if (!pWin->optional) - if (!MakeWindowOptional (pWin)) - { - FreeResource (pWin->drawable.id, RT_NONE); - return FALSE; - } - if (pWin->optional->cursor) - FreeCursor (pWin->optional->cursor, (Cursor)0); - pWin->optional->cursor = pAttr->pCursor; - pAttr->pCursor->refcnt++; - pWin->cursorIsNone = FALSE; - CheckWindowOptionalNeed (pWin); - mask |= CWCursor; - } - if (mask) - (*pScreen->ChangeWindowAttributes) (pWin, mask); - - if (pAttr->colormap != None) - (void) ChangeWindowAttributes (pWin, CWColormap, &pAttr->colormap, - serverClient); - - MapWindow (pWin, serverClient); - - pPriv->hasWindow = TRUE; - pSaver->pWindow = pWin; - - /* check and install our own colormap if it isn't installed now */ - wantMap = wColormap (pWin); - if (wantMap == None) - return TRUE; - installedMaps = xalloc (pScreen->maxInstalledCmaps * sizeof (Colormap)); - numInstalled = (*pWin->drawable.pScreen->ListInstalledColormaps) - (pScreen, installedMaps); - for (i = 0; i < numInstalled; i++) - if (installedMaps[i] == wantMap) - break; - - xfree ((char *) installedMaps); - - if (i < numInstalled) - return TRUE; - - result = dixLookupResourceByType((pointer *)&pCmap, wantMap, RT_COLORMAP, - serverClient, DixInstallAccess); - if (result != Success) - return TRUE; - - pPriv->installedMap = wantMap; - - (*pCmap->pScreen->InstallColormap) (pCmap); - - return TRUE; -} - -static Bool -DestroySaverWindow (ScreenPtr pScreen) -{ - SetupScreen(pScreen); - ScreenSaverStuffPtr pSaver; - - if (!pPriv || !pPriv->hasWindow) - return FALSE; - - pSaver = &savedScreenInfo[pScreen->myNum]; - if (pSaver->pWindow) - { - pSaver->pWindow = NullWindow; - FreeResource (pSaver->wid, RT_NONE); - } - pPriv->hasWindow = FALSE; - CheckScreenPrivate (pScreen); - UninstallSaverColormap (pScreen); - return TRUE; -} - -static Bool -ScreenSaverHandle (ScreenPtr pScreen, int xstate, Bool force) -{ - int state = 0; - Bool ret = FALSE; - ScreenSaverScreenPrivatePtr pPriv; - - switch (xstate) - { - case SCREEN_SAVER_ON: - state = ScreenSaverOn; - ret = CreateSaverWindow (pScreen); - break; - case SCREEN_SAVER_OFF: - state = ScreenSaverOff; - ret = DestroySaverWindow (pScreen); - break; - case SCREEN_SAVER_CYCLE: - state = ScreenSaverCycle; - pPriv = GetScreenPrivate (pScreen); - if (pPriv && pPriv->hasWindow) - ret = TRUE; - - } -#ifdef PANORAMIX - if(noPanoramiXExtension || !pScreen->myNum) -#endif - SendScreenSaverNotify (pScreen, state, force); - return ret; -} - -static int -ProcScreenSaverQueryVersion (ClientPtr client) -{ - xScreenSaverQueryVersionReply rep; - int n; - - REQUEST_SIZE_MATCH (xScreenSaverQueryVersionReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.majorVersion = SERVER_SAVER_MAJOR_VERSION; - rep.minorVersion = SERVER_SAVER_MINOR_VERSION; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - } - WriteToClient(client, sizeof (xScreenSaverQueryVersionReply), (char *)&rep); - return (client->noClientException); -} - -static int -ProcScreenSaverQueryInfo (ClientPtr client) -{ - REQUEST(xScreenSaverQueryInfoReq); - xScreenSaverQueryInfoReply rep; - int n, rc; - ScreenSaverStuffPtr pSaver; - DrawablePtr pDraw; - CARD32 lastInput; - ScreenSaverScreenPrivatePtr pPriv; - - REQUEST_SIZE_MATCH (xScreenSaverQueryInfoReq); - rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, - DixGetAttrAccess); - if (rc != Success) - return rc; - rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen, - DixGetAttrAccess); - if (rc != Success) - return rc; - - pSaver = &savedScreenInfo[pDraw->pScreen->myNum]; - pPriv = GetScreenPrivate (pDraw->pScreen); - - UpdateCurrentTime (); - lastInput = GetTimeInMillis() - lastDeviceEventTime.milliseconds; - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.window = pSaver->wid; - if (screenIsSaved != SCREEN_SAVER_OFF) - { - rep.state = ScreenSaverOn; - if (ScreenSaverTime) - rep.tilOrSince = lastInput - ScreenSaverTime; - else - rep.tilOrSince = 0; - } - else - { - if (ScreenSaverTime) - { - rep.state = ScreenSaverOff; - if (ScreenSaverTime < lastInput) - rep.tilOrSince = 0; - else - rep.tilOrSince = ScreenSaverTime - lastInput; - } - else - { - rep.state = ScreenSaverDisabled; - rep.tilOrSince = 0; - } - } - rep.idle = lastInput; - rep.eventMask = getEventMask (pDraw->pScreen, client); - if (pPriv && pPriv->attr) - rep.kind = ScreenSaverExternal; - else if (ScreenSaverBlanking != DontPreferBlanking) - rep.kind = ScreenSaverBlanked; - else - rep.kind = ScreenSaverInternal; - if (client->swapped) - { - swaps (&rep.sequenceNumber, n); - swapl (&rep.length, n); - swapl (&rep.window, n); - swapl (&rep.tilOrSince, n); - swapl (&rep.idle, n); - swapl (&rep.eventMask, n); - } - WriteToClient(client, sizeof (xScreenSaverQueryInfoReply), (char *)&rep); - return (client->noClientException); -} - -static int -ProcScreenSaverSelectInput (ClientPtr client) -{ - REQUEST(xScreenSaverSelectInputReq); - DrawablePtr pDraw; - int rc; - - REQUEST_SIZE_MATCH (xScreenSaverSelectInputReq); - rc = dixLookupDrawable (&pDraw, stuff->drawable, client, 0, - DixGetAttrAccess); - if (rc != Success) - return rc; - - rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen, - DixSetAttrAccess); - if (rc != Success) - return rc; - - if (!setEventMask (pDraw->pScreen, client, stuff->eventMask)) - return BadAlloc; - return Success; -} - -static int -ScreenSaverSetAttributes (ClientPtr client) -{ - REQUEST(xScreenSaverSetAttributesReq); - DrawablePtr pDraw; - WindowPtr pParent; - ScreenPtr pScreen; - ScreenSaverScreenPrivatePtr pPriv = 0; - ScreenSaverAttrPtr pAttr = 0; - int ret, len, class, bw, depth; - unsigned long visual; - int idepth, ivisual; - Bool fOK; - DepthPtr pDepth; - WindowOptPtr ancwopt; - unsigned int *pVlist; - unsigned long *values = 0; - unsigned long tmask, imask; - unsigned long val; - Pixmap pixID; - PixmapPtr pPixmap; - Cursor cursorID; - CursorPtr pCursor; - Colormap cmap; - ColormapPtr pCmap; - - REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq); - ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, - DixGetAttrAccess); - if (ret != Success) - return ret; - pScreen = pDraw->pScreen; - pParent = WindowTable[pScreen->myNum]; - - ret = XaceHook(XACE_SCREENSAVER_ACCESS, client, pScreen, DixSetAttrAccess); - if (ret != Success) - return ret; - - len = stuff->length - bytes_to_int32(sizeof(xScreenSaverSetAttributesReq)); - if (Ones(stuff->mask) != len) - return BadLength; - if (!stuff->width || !stuff->height) - { - client->errorValue = 0; - return BadValue; - } - switch (class = stuff->c_class) - { - case CopyFromParent: - case InputOnly: - case InputOutput: - break; - default: - client->errorValue = class; - return BadValue; - } - bw = stuff->borderWidth; - depth = stuff->depth; - visual = stuff->visualID; - - /* copied directly from CreateWindow */ - - if (class == CopyFromParent) - class = pParent->drawable.class; - - if ((class != InputOutput) && (class != InputOnly)) - { - client->errorValue = class; - return BadValue; - } - - if ((class != InputOnly) && (pParent->drawable.class == InputOnly)) - return BadMatch; - - if ((class == InputOnly) && ((bw != 0) || (depth != 0))) - return BadMatch; - - if ((class == InputOutput) && (depth == 0)) - depth = pParent->drawable.depth; - ancwopt = pParent->optional; - if (!ancwopt) - ancwopt = FindWindowWithOptional(pParent)->optional; - if (visual == CopyFromParent) - visual = ancwopt->visual; - - /* Find out if the depth and visual are acceptable for this Screen */ - if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) - { - fOK = FALSE; - for(idepth = 0; idepth < pScreen->numDepths; idepth++) - { - pDepth = (DepthPtr) &pScreen->allowedDepths[idepth]; - if ((depth == pDepth->depth) || (depth == 0)) - { - for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) - { - if (visual == pDepth->vids[ivisual]) - { - fOK = TRUE; - break; - } - } - } - } - if (fOK == FALSE) - return BadMatch; - } - - if (((stuff->mask & (CWBorderPixmap | CWBorderPixel)) == 0) && - (class != InputOnly) && - (depth != pParent->drawable.depth)) - { - return BadMatch; - } - - if (((stuff->mask & CWColormap) == 0) && - (class != InputOnly) && - ((visual != ancwopt->visual) || (ancwopt->colormap == None))) - { - return BadMatch; - } - - /* end of errors from CreateWindow */ - - pPriv = GetScreenPrivate (pScreen); - if (pPriv && pPriv->attr) - { - if (pPriv->attr->client != client) - return BadAccess; - } - if (!pPriv) - { - pPriv = MakeScreenPrivate (pScreen); - if (!pPriv) - return FALSE; - } - pAttr = New (ScreenSaverAttrRec); - if (!pAttr) - { - ret = BadAlloc; - goto bail; - } - /* over allocate for override redirect */ - values = xalloc ((len + 1) * sizeof (unsigned long)); - if (!values) - { - ret = BadAlloc; - goto bail; - } - pAttr->screen = pScreen; - pAttr->client = client; - pAttr->x = stuff->x; - pAttr->y = stuff->y; - pAttr->width = stuff->width; - pAttr->height = stuff->height; - pAttr->borderWidth = stuff->borderWidth; - pAttr->class = stuff->c_class; - pAttr->depth = depth; - pAttr->visual = visual; - pAttr->colormap = None; - pAttr->pCursor = NullCursor; - pAttr->pBackgroundPixmap = NullPixmap; - pAttr->pBorderPixmap = NullPixmap; - pAttr->values = values; - /* - * go through the mask, checking the values, - * looking up pixmaps and cursors and hold a reference - * to them. - */ - pAttr->mask = tmask = stuff->mask | CWOverrideRedirect; - pVlist = (unsigned int *) (stuff + 1); - while (tmask) { - imask = lowbit (tmask); - tmask &= ~imask; - switch (imask) - { - case CWBackPixmap: - pixID = (Pixmap )*pVlist; - if (pixID == None) - { - *values++ = None; - } - else if (pixID == ParentRelative) - { - if (depth != pParent->drawable.depth) - { - ret = BadMatch; - goto PatchUp; - } - *values++ = ParentRelative; - } - else - { - ret = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP, - client, DixReadAccess); - if (ret == Success) - { - if ((pPixmap->drawable.depth != depth) || - (pPixmap->drawable.pScreen != pScreen)) - { - ret = BadMatch; - goto PatchUp; - } - pAttr->pBackgroundPixmap = pPixmap; - pPixmap->refcnt++; - pAttr->mask &= ~CWBackPixmap; - } - else - { - ret = (ret == BadValue) ? BadPixmap : ret; - client->errorValue = pixID; - goto PatchUp; - } - } - break; - case CWBackPixel: - *values++ = (CARD32) *pVlist; - break; - case CWBorderPixmap: - pixID = (Pixmap ) *pVlist; - if (pixID == CopyFromParent) - { - if (depth != pParent->drawable.depth) - { - ret = BadMatch; - goto PatchUp; - } - *values++ = CopyFromParent; - } - else - { - ret = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP, - client, DixReadAccess); - if (ret == Success) - { - if ((pPixmap->drawable.depth != depth) || - (pPixmap->drawable.pScreen != pScreen)) - { - ret = BadMatch; - goto PatchUp; - } - pAttr->pBorderPixmap = pPixmap; - pPixmap->refcnt++; - pAttr->mask &= ~CWBorderPixmap; - } - else - { - ret = (ret == BadValue) ? BadPixmap : ret; - client->errorValue = pixID; - goto PatchUp; - } - } - break; - case CWBorderPixel: - *values++ = (CARD32) *pVlist; - break; - case CWBitGravity: - val = (CARD8 )*pVlist; - if (val > StaticGravity) - { - ret = BadValue; - client->errorValue = val; - goto PatchUp; - } - *values++ = val; - break; - case CWWinGravity: - val = (CARD8 )*pVlist; - if (val > StaticGravity) - { - ret = BadValue; - client->errorValue = val; - goto PatchUp; - } - *values++ = val; - break; - case CWBackingStore: - val = (CARD8 )*pVlist; - if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) - { - ret = BadValue; - client->errorValue = val; - goto PatchUp; - } - *values++ = val; - break; - case CWBackingPlanes: - *values++ = (CARD32) *pVlist; - break; - case CWBackingPixel: - *values++ = (CARD32) *pVlist; - break; - case CWSaveUnder: - val = (BOOL) *pVlist; - if ((val != xTrue) && (val != xFalse)) - { - ret = BadValue; - client->errorValue = val; - goto PatchUp; - } - *values++ = val; - break; - case CWEventMask: - *values++ = (CARD32) *pVlist; - break; - case CWDontPropagate: - *values++ = (CARD32) *pVlist; - break; - case CWOverrideRedirect: - if (!(stuff->mask & CWOverrideRedirect)) - pVlist--; - else - { - val = (BOOL ) *pVlist; - if ((val != xTrue) && (val != xFalse)) - { - ret = BadValue; - client->errorValue = val; - goto PatchUp; - } - } - *values++ = xTrue; - break; - case CWColormap: - cmap = (Colormap) *pVlist; - ret = dixLookupResourceByType((pointer *)&pCmap, cmap, RT_COLORMAP, - client, DixUseAccess); - if (ret != Success) - { - ret = (ret == BadValue) ? BadColor : ret; - client->errorValue = cmap; - goto PatchUp; - } - if (pCmap->pVisual->vid != visual || pCmap->pScreen != pScreen) - { - ret = BadMatch; - goto PatchUp; - } - pAttr->colormap = cmap; - pAttr->mask &= ~CWColormap; - break; - case CWCursor: - cursorID = (Cursor ) *pVlist; - if ( cursorID == None) - { - *values++ = None; - } - else - { - ret = dixLookupResourceByType((pointer *)&pCursor, cursorID, - RT_CURSOR, client, DixUseAccess); - if (ret != Success) - { - ret = (ret == BadValue) ? BadCursor : ret; - client->errorValue = cursorID; - goto PatchUp; - } - pCursor->refcnt++; - pAttr->pCursor = pCursor; - pAttr->mask &= ~CWCursor; - } - break; - default: - ret = BadValue; - client->errorValue = stuff->mask; - goto PatchUp; - } - pVlist++; - } - if (pPriv->attr) - FreeScreenAttr (pPriv->attr); - pPriv->attr = pAttr; - pAttr->resource = FakeClientID (client->index); - if (!AddResource (pAttr->resource, AttrType, (pointer) pAttr)) - return BadAlloc; - return Success; -PatchUp: - FreeAttrs (pAttr); -bail: - CheckScreenPrivate (pScreen); - if (pAttr) xfree (pAttr->values); - xfree (pAttr); - return ret; -} - -static int -ScreenSaverUnsetAttributes (ClientPtr client) -{ - REQUEST(xScreenSaverSetAttributesReq); - DrawablePtr pDraw; - ScreenSaverScreenPrivatePtr pPriv; - int rc; - - REQUEST_SIZE_MATCH (xScreenSaverUnsetAttributesReq); - rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, - DixGetAttrAccess); - if (rc != Success) - return rc; - pPriv = GetScreenPrivate (pDraw->pScreen); - if (pPriv && pPriv->attr && pPriv->attr->client == client) - { - FreeResource (pPriv->attr->resource, AttrType); - FreeScreenAttr (pPriv->attr); - pPriv->attr = NULL; - CheckScreenPrivate (pDraw->pScreen); - } - return Success; -} - -static int -ProcScreenSaverSetAttributes (ClientPtr client) -{ -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - REQUEST(xScreenSaverSetAttributesReq); - PanoramiXRes *draw; - PanoramiXRes *backPix = NULL; - PanoramiXRes *bordPix = NULL; - PanoramiXRes *cmap = NULL; - int i, status, len; - int pback_offset = 0, pbord_offset = 0, cmap_offset = 0; - XID orig_visual, tmp; - - REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq); - - status = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, - XRC_DRAWABLE, client, DixWriteAccess); - if (status != Success) - return (status == BadValue) ? BadDrawable : status; - - len = stuff->length - bytes_to_int32(sizeof(xScreenSaverSetAttributesReq)); - if (Ones(stuff->mask) != len) - return BadLength; - - if((Mask)stuff->mask & CWBackPixmap) { - pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1)); - tmp = *((CARD32 *) &stuff[1] + pback_offset); - if ((tmp != None) && (tmp != ParentRelative)) { - status = dixLookupResourceByType((pointer *)&backPix, tmp, - XRT_PIXMAP, client, - DixReadAccess); - if (status != Success) - return (status == BadValue) ? BadPixmap : status; - } - } - - if ((Mask)stuff->mask & CWBorderPixmap) { - pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1)); - tmp = *((CARD32 *) &stuff[1] + pbord_offset); - if (tmp != CopyFromParent) { - status = dixLookupResourceByType((pointer *)&bordPix, tmp, - XRT_PIXMAP, client, - DixReadAccess); - if (status != Success) - return (status == BadValue) ? BadPixmap : status; - } - } - - if ((Mask)stuff->mask & CWColormap) { - cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1)); - tmp = *((CARD32 *) &stuff[1] + cmap_offset); - if ((tmp != CopyFromParent) && (tmp != None)) { - status = dixLookupResourceByType((pointer *)&cmap, tmp, - XRT_COLORMAP, client, - DixReadAccess); - if (status != Success) - return (status == BadValue) ? BadColor : status; - } - } - - orig_visual = stuff->visualID; - - FOR_NSCREENS_BACKWARD(i) { - stuff->drawable = draw->info[i].id; - if (backPix) - *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[i].id; - if (bordPix) - *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[i].id; - if (cmap) - *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[i].id; - - if (orig_visual != CopyFromParent) - stuff->visualID = PanoramiXTranslateVisualID(i, orig_visual); - - status = ScreenSaverSetAttributes(client); - } - - return status; - } -#endif - - return ScreenSaverSetAttributes(client); -} - -static int -ProcScreenSaverUnsetAttributes (ClientPtr client) -{ -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - REQUEST(xScreenSaverUnsetAttributesReq); - PanoramiXRes *draw; - int rc, i; - - rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, - XRC_DRAWABLE, client, DixWriteAccess); - if (rc != Success) - return (rc == BadValue) ? BadDrawable : rc; - - for(i = PanoramiXNumScreens - 1; i > 0; i--) { - stuff->drawable = draw->info[i].id; - ScreenSaverUnsetAttributes(client); - } - - stuff->drawable = draw->info[0].id; - } -#endif - - return ScreenSaverUnsetAttributes(client); -} - -static int -ProcScreenSaverSuspend (ClientPtr client) -{ - ScreenSaverSuspensionPtr *prev, this; - - REQUEST(xScreenSaverSuspendReq); - REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); - - /* Check if this client is suspending the screensaver */ - for (prev = &suspendingClients; (this = *prev); prev = &this->next) - if (this->pClient == client) - break; - - if (this) - { - if (stuff->suspend == TRUE) - this->count++; - else if (--this->count == 0) - FreeResource (this->clientResource, RT_NONE); - - return Success; - } - - /* If we get to this point, this client isn't suspending the screensaver */ - if (stuff->suspend == FALSE) - return Success; - - /* - * Allocate a suspension record for the client, and stop the screensaver - * if it isn't already suspended by another client. We attach a resource ID - * to the record, so the screensaver will be reenabled and the record freed - * if the client disconnects without reenabling it first. - */ - this = xalloc (sizeof (ScreenSaverSuspensionRec)); - - if (!this) - return BadAlloc; - - this->next = NULL; - this->pClient = client; - this->count = 1; - this->clientResource = FakeClientID (client->index); - - if (!AddResource (this->clientResource, SuspendType, (pointer) this)) - { - xfree (this); - return BadAlloc; - } - - *prev = this; - if (!screenSaverSuspended) - { - screenSaverSuspended = TRUE; - FreeScreenSaverTimer(); - } - - return (client->noClientException); -} - -static DISPATCH_PROC((*NormalVector[])) = { - ProcScreenSaverQueryVersion, - ProcScreenSaverQueryInfo, - ProcScreenSaverSelectInput, - ProcScreenSaverSetAttributes, - ProcScreenSaverUnsetAttributes, - ProcScreenSaverSuspend, -}; - -#define NUM_REQUESTS ((sizeof NormalVector) / (sizeof NormalVector[0])) - -static int -ProcScreenSaverDispatch (ClientPtr client) -{ - REQUEST(xReq); - - if (stuff->data < NUM_REQUESTS) - return (*NormalVector[stuff->data])(client); - return BadRequest; -} - -static int -SProcScreenSaverQueryVersion (ClientPtr client) -{ - REQUEST(xScreenSaverQueryVersionReq); - int n; - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq); - return ProcScreenSaverQueryVersion (client); -} - -static int -SProcScreenSaverQueryInfo (ClientPtr client) -{ - REQUEST(xScreenSaverQueryInfoReq); - int n; - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq); - swapl (&stuff->drawable, n); - return ProcScreenSaverQueryInfo (client); -} - -static int -SProcScreenSaverSelectInput (ClientPtr client) -{ - REQUEST(xScreenSaverSelectInputReq); - int n; - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq); - swapl (&stuff->drawable, n); - swapl (&stuff->eventMask, n); - return ProcScreenSaverSelectInput (client); -} - -static int -SProcScreenSaverSetAttributes (ClientPtr client) -{ - REQUEST(xScreenSaverSetAttributesReq); - int n; - - swaps (&stuff->length, n); - REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq); - swapl (&stuff->drawable, n); - swaps (&stuff->x, n); - swaps (&stuff->y, n); - swaps (&stuff->width, n); - swaps (&stuff->height, n); - swaps (&stuff->borderWidth, n); - swapl (&stuff->visualID, n); - swapl (&stuff->mask, n); - SwapRestL(stuff); - return ProcScreenSaverSetAttributes (client); -} - -static int -SProcScreenSaverUnsetAttributes (ClientPtr client) -{ - REQUEST(xScreenSaverUnsetAttributesReq); - int n; - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq); - swapl (&stuff->drawable, n); - return ProcScreenSaverUnsetAttributes (client); -} - -static int -SProcScreenSaverSuspend (ClientPtr client) -{ - int n; - REQUEST(xScreenSaverSuspendReq); - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); - swapl(&stuff->suspend, n); - return ProcScreenSaverSuspend (client); -} - -static DISPATCH_PROC((*SwappedVector[])) = { - SProcScreenSaverQueryVersion, - SProcScreenSaverQueryInfo, - SProcScreenSaverSelectInput, - SProcScreenSaverSetAttributes, - SProcScreenSaverUnsetAttributes, - SProcScreenSaverSuspend, -}; - -static int -SProcScreenSaverDispatch (ClientPtr client) -{ - REQUEST(xReq); - - if (stuff->data < NUM_REQUESTS) - return (*SwappedVector[stuff->data])(client); - return BadRequest; -} +/*
+ *
+Copyright (c) 1992 X Consortium
+
+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
+X CONSORTIUM 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 X Consortium 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 X Consortium.
+ *
+ * Author: Keith Packard, MIT X Consortium
+ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#else
+#define SCREENSAVER
+#endif
+
+#ifdef CreateWindow
+#undef CreateWindow
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+#include <X11/extensions/saverproto.h>
+#include "gcstruct.h"
+#include "cursorstr.h"
+#include "colormapst.h"
+#include "xace.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#ifdef DPMSExtension
+#include <X11/extensions/dpmsconst.h>
+#endif
+#include "protocol-versions.h"
+
+#include <stdio.h>
+
+#include "modinit.h"
+
+static int ScreenSaverEventBase = 0;
+
+static DISPATCH_PROC(ProcScreenSaverQueryInfo);
+static DISPATCH_PROC(ProcScreenSaverDispatch);
+static DISPATCH_PROC(ProcScreenSaverQueryVersion);
+static DISPATCH_PROC(ProcScreenSaverSelectInput);
+static DISPATCH_PROC(ProcScreenSaverSetAttributes);
+static DISPATCH_PROC(ProcScreenSaverUnsetAttributes);
+static DISPATCH_PROC(ProcScreenSaverSuspend);
+static DISPATCH_PROC(SProcScreenSaverDispatch);
+static DISPATCH_PROC(SProcScreenSaverQueryInfo);
+static DISPATCH_PROC(SProcScreenSaverQueryVersion);
+static DISPATCH_PROC(SProcScreenSaverSelectInput);
+static DISPATCH_PROC(SProcScreenSaverSetAttributes);
+static DISPATCH_PROC(SProcScreenSaverUnsetAttributes);
+static DISPATCH_PROC(SProcScreenSaverSuspend);
+
+static Bool ScreenSaverHandle (
+ ScreenPtr /* pScreen */,
+ int /* xstate */,
+ Bool /* force */
+ );
+
+static Bool
+CreateSaverWindow (
+ ScreenPtr /* pScreen */
+ );
+
+static Bool
+DestroySaverWindow (
+ ScreenPtr /* pScreen */
+ );
+
+static void
+UninstallSaverColormap (
+ ScreenPtr /* pScreen */
+ );
+
+static void
+CheckScreenPrivate (
+ ScreenPtr /* pScreen */
+ );
+
+static void SScreenSaverNotifyEvent (
+ xScreenSaverNotifyEvent * /* from */,
+ xScreenSaverNotifyEvent * /* to */
+ );
+
+static RESTYPE SuspendType; /* resource type for suspension records */
+
+typedef struct _ScreenSaverSuspension *ScreenSaverSuspensionPtr;
+
+/* List of clients that are suspending the screensaver. */
+static ScreenSaverSuspensionPtr suspendingClients = NULL;
+
+/*
+ * clientResource is a resource ID that's added when the record is
+ * allocated, so the record is freed and the screensaver resumed when
+ * the client disconnects. count is the number of times the client has
+ * requested the screensaver be suspended.
+ */
+typedef struct _ScreenSaverSuspension
+{
+ ScreenSaverSuspensionPtr next;
+ ClientPtr pClient;
+ XID clientResource;
+ int count;
+} ScreenSaverSuspensionRec;
+
+static int ScreenSaverFreeSuspend(
+ pointer /*value */,
+ XID /* id */
+);
+
+/*
+ * each screen has a list of clients requesting
+ * ScreenSaverNotify events. Each client has a resource
+ * for each screen it selects ScreenSaverNotify input for,
+ * this resource is used to delete the ScreenSaverNotifyRec
+ * entry from the per-screen queue.
+ */
+
+static RESTYPE SaverEventType; /* resource type for event masks */
+
+typedef struct _ScreenSaverEvent *ScreenSaverEventPtr;
+
+typedef struct _ScreenSaverEvent {
+ ScreenSaverEventPtr next;
+ ClientPtr client;
+ ScreenPtr screen;
+ XID resource;
+ CARD32 mask;
+} ScreenSaverEventRec;
+
+static int ScreenSaverFreeEvents(
+ pointer /* value */,
+ XID /* id */
+);
+
+static Bool setEventMask (
+ ScreenPtr /* pScreen */,
+ ClientPtr /* client */,
+ unsigned long /* mask */
+);
+
+static unsigned long getEventMask (
+ ScreenPtr /* pScreen */,
+ ClientPtr /* client */
+);
+
+/*
+ * when a client sets the screen saver attributes, a resource is
+ * kept to be freed when the client exits
+ */
+
+static RESTYPE AttrType; /* resource type for attributes */
+
+typedef struct _ScreenSaverAttr {
+ ScreenPtr screen;
+ ClientPtr client;
+ XID resource;
+ short x, y;
+ unsigned short width, height, borderWidth;
+ unsigned char class;
+ unsigned char depth;
+ VisualID visual;
+ CursorPtr pCursor;
+ PixmapPtr pBackgroundPixmap;
+ PixmapPtr pBorderPixmap;
+ Colormap colormap;
+ unsigned long mask; /* no pixmaps or cursors */
+ unsigned long *values;
+} ScreenSaverAttrRec, *ScreenSaverAttrPtr;
+
+static int ScreenSaverFreeAttr (
+ pointer /* value */,
+ XID /* id */
+);
+
+static void FreeAttrs (
+ ScreenSaverAttrPtr /* pAttr */
+);
+
+static void FreeScreenAttr (
+ ScreenSaverAttrPtr /* pAttr */
+);
+
+static void
+SendScreenSaverNotify (
+ ScreenPtr /* pScreen */,
+ int /* state */,
+ Bool /* forced */
+);
+
+typedef struct _ScreenSaverScreenPrivate {
+ ScreenSaverEventPtr events;
+ ScreenSaverAttrPtr attr;
+ Bool hasWindow;
+ Colormap installedMap;
+} ScreenSaverScreenPrivateRec, *ScreenSaverScreenPrivatePtr;
+
+static ScreenSaverScreenPrivatePtr
+MakeScreenPrivate (
+ ScreenPtr /* pScreen */
+ );
+
+static int ScreenPrivateKeyIndex;
+static DevPrivateKey ScreenPrivateKey = &ScreenPrivateKeyIndex;
+
+#define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr) \
+ dixLookupPrivate(&(s)->devPrivates, ScreenPrivateKey))
+#define SetScreenPrivate(s,v) \
+ dixSetPrivate(&(s)->devPrivates, ScreenPrivateKey, v);
+#define SetupScreen(s) ScreenSaverScreenPrivatePtr pPriv = (s ? GetScreenPrivate(s) : NULL)
+
+#define New(t) (xalloc (sizeof (t)))
+
+/****************
+ * ScreenSaverExtensionInit
+ *
+ * Called from InitExtensions in main() or from QueryExtension() if the
+ * extension is dynamically loaded.
+ *
+ ****************/
+
+void
+ScreenSaverExtensionInit(INITARGS)
+{
+ ExtensionEntry *extEntry;
+ int i;
+ ScreenPtr pScreen;
+
+ AttrType = CreateNewResourceType(ScreenSaverFreeAttr, "SaverAttr");
+ SaverEventType = CreateNewResourceType(ScreenSaverFreeEvents,
+ "SaverEvent");
+ SuspendType = CreateNewResourceType(ScreenSaverFreeSuspend,
+ "SaverSuspend");
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ pScreen = screenInfo.screens[i];
+ SetScreenPrivate (pScreen, NULL);
+ }
+ if (AttrType && SaverEventType && SuspendType &&
+ (extEntry = AddExtension(ScreenSaverName, ScreenSaverNumberEvents, 0,
+ ProcScreenSaverDispatch, SProcScreenSaverDispatch,
+ NULL, StandardMinorOpcode)))
+ {
+ ScreenSaverEventBase = extEntry->eventBase;
+ EventSwapVector[ScreenSaverEventBase] = (EventSwapPtr) SScreenSaverNotifyEvent;
+ }
+}
+
+static void
+CheckScreenPrivate (ScreenPtr pScreen)
+{
+ SetupScreen (pScreen);
+
+ if (!pPriv)
+ return;
+ if (!pPriv->attr && !pPriv->events &&
+ !pPriv->hasWindow && pPriv->installedMap == None)
+ {
+ xfree (pPriv);
+ SetScreenPrivate (pScreen, NULL);
+ savedScreenInfo[pScreen->myNum].ExternalScreenSaver = NULL;
+ }
+}
+
+static ScreenSaverScreenPrivatePtr
+MakeScreenPrivate (ScreenPtr pScreen)
+{
+ SetupScreen (pScreen);
+
+ if (pPriv)
+ return pPriv;
+ pPriv = New (ScreenSaverScreenPrivateRec);
+ if (!pPriv)
+ return 0;
+ pPriv->events = 0;
+ pPriv->attr = 0;
+ pPriv->hasWindow = FALSE;
+ pPriv->installedMap = None;
+ SetScreenPrivate (pScreen, pPriv);
+ savedScreenInfo[pScreen->myNum].ExternalScreenSaver = ScreenSaverHandle;
+ return pPriv;
+}
+
+static unsigned long
+getEventMask (ScreenPtr pScreen, ClientPtr client)
+{
+ SetupScreen(pScreen);
+ ScreenSaverEventPtr pEv;
+
+ if (!pPriv)
+ return 0;
+ for (pEv = pPriv->events; pEv; pEv = pEv->next)
+ if (pEv->client == client)
+ return pEv->mask;
+ return 0;
+}
+
+static Bool
+setEventMask (ScreenPtr pScreen, ClientPtr client, unsigned long mask)
+{
+ SetupScreen(pScreen);
+ ScreenSaverEventPtr pEv, *pPrev;
+
+ if (getEventMask (pScreen, client) == mask)
+ return TRUE;
+ if (!pPriv)
+ {
+ pPriv = MakeScreenPrivate (pScreen);
+ if (!pPriv)
+ return FALSE;
+ }
+ for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next)
+ if (pEv->client == client)
+ break;
+ if (mask == 0)
+ {
+ FreeResource (pEv->resource, SaverEventType);
+ *pPrev = pEv->next;
+ xfree (pEv);
+ CheckScreenPrivate (pScreen);
+ }
+ else
+ {
+ if (!pEv)
+ {
+ pEv = New (ScreenSaverEventRec);
+ if (!pEv)
+ {
+ CheckScreenPrivate (pScreen);
+ return FALSE;
+ }
+ *pPrev = pEv;
+ pEv->next = NULL;
+ pEv->client = client;
+ pEv->screen = pScreen;
+ pEv->resource = FakeClientID (client->index);
+ if (!AddResource (pEv->resource, SaverEventType, (pointer) pEv))
+ return FALSE;
+ }
+ pEv->mask = mask;
+ }
+ return TRUE;
+}
+
+static void
+FreeAttrs (ScreenSaverAttrPtr pAttr)
+{
+ PixmapPtr pPixmap;
+ CursorPtr pCursor;
+
+ if ((pPixmap = pAttr->pBackgroundPixmap) != 0)
+ (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+ if ((pPixmap = pAttr->pBorderPixmap) != 0)
+ (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+ if ((pCursor = pAttr->pCursor) != 0)
+ FreeCursor (pCursor, (Cursor) 0);
+}
+
+static void
+FreeScreenAttr (ScreenSaverAttrPtr pAttr)
+{
+ FreeAttrs (pAttr);
+ xfree (pAttr->values);
+ xfree (pAttr);
+}
+
+static int
+ScreenSaverFreeEvents (pointer value, XID id)
+{
+ ScreenSaverEventPtr pOld = (ScreenSaverEventPtr)value;
+ ScreenPtr pScreen = pOld->screen;
+ SetupScreen (pScreen);
+ ScreenSaverEventPtr pEv, *pPrev;
+
+ if (!pPriv)
+ return TRUE;
+ for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next)
+ if (pEv == pOld)
+ break;
+ if (!pEv)
+ return TRUE;
+ *pPrev = pEv->next;
+ xfree (pEv);
+ CheckScreenPrivate (pScreen);
+ return TRUE;
+}
+
+static int
+ScreenSaverFreeAttr (pointer value, XID id)
+{
+ ScreenSaverAttrPtr pOldAttr = (ScreenSaverAttrPtr)value;
+ ScreenPtr pScreen = pOldAttr->screen;
+ SetupScreen (pScreen);
+
+ if (!pPriv)
+ return TRUE;
+ if (pPriv->attr != pOldAttr)
+ return TRUE;
+ FreeScreenAttr (pOldAttr);
+ pPriv->attr = NULL;
+ if (pPriv->hasWindow)
+ {
+ dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
+ dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverActive);
+ }
+ CheckScreenPrivate (pScreen);
+ return TRUE;
+}
+
+static int
+ScreenSaverFreeSuspend (pointer value, XID id)
+{
+ ScreenSaverSuspensionPtr data = (ScreenSaverSuspensionPtr) value;
+ ScreenSaverSuspensionPtr *prev, this;
+
+ /* Unlink and free the suspension record for the client */
+ for (prev = &suspendingClients; (this = *prev); prev = &this->next)
+ {
+ if (this == data)
+ {
+ *prev = this->next;
+ xfree (this);
+ break;
+ }
+ }
+
+ /* Reenable the screensaver if this was the last client suspending it. */
+ if (screenSaverSuspended && suspendingClients == NULL)
+ {
+ screenSaverSuspended = FALSE;
+
+ /* The screensaver could be active, since suspending it (by design)
+ doesn't prevent it from being forceably activated */
+#ifdef DPMSExtension
+ if (screenIsSaved != SCREEN_SAVER_ON && DPMSPowerLevel == DPMSModeOn)
+#else
+ if (screenIsSaved != SCREEN_SAVER_ON)
+#endif
+ {
+ UpdateCurrentTimeIf();
+ lastDeviceEventTime = currentTime;
+ SetScreenSaverTimer();
+ }
+ }
+
+ return Success;
+}
+
+static void
+SendScreenSaverNotify (ScreenPtr pScreen, int state, Bool forced)
+{
+ ScreenSaverScreenPrivatePtr pPriv;
+ ScreenSaverEventPtr pEv;
+ unsigned long mask;
+ xScreenSaverNotifyEvent ev;
+ ClientPtr client;
+ int kind;
+
+ UpdateCurrentTimeIf ();
+ mask = ScreenSaverNotifyMask;
+ if (state == ScreenSaverCycle)
+ mask = ScreenSaverCycleMask;
+ pScreen = screenInfo.screens[pScreen->myNum];
+ pPriv = GetScreenPrivate(pScreen);
+ if (!pPriv)
+ return;
+ if (pPriv->attr)
+ kind = ScreenSaverExternal;
+ else if (ScreenSaverBlanking != DontPreferBlanking)
+ kind = ScreenSaverBlanked;
+ else
+ kind = ScreenSaverInternal;
+ for (pEv = pPriv->events; pEv; pEv = pEv->next)
+ {
+ client = pEv->client;
+ if (client->clientGone)
+ continue;
+ if (!(pEv->mask & mask))
+ continue;
+ ev.type = ScreenSaverNotify + ScreenSaverEventBase;
+ ev.state = state;
+ ev.sequenceNumber = client->sequence;
+ ev.timestamp = currentTime.milliseconds;
+ ev.root = WindowTable[pScreen->myNum]->drawable.id;
+ ev.window = savedScreenInfo[pScreen->myNum].wid;
+ ev.kind = kind;
+ ev.forced = forced;
+ WriteEventsToClient (client, 1, (xEvent *) &ev);
+ }
+}
+
+static void
+SScreenSaverNotifyEvent (xScreenSaverNotifyEvent *from,
+ xScreenSaverNotifyEvent *to)
+{
+ to->type = from->type;
+ to->state = from->state;
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswapl (from->timestamp, to->timestamp);
+ cpswapl (from->root, to->root);
+ cpswapl (from->window, to->window);
+ to->kind = from->kind;
+ to->forced = from->forced;
+}
+
+static void
+UninstallSaverColormap (ScreenPtr pScreen)
+{
+ SetupScreen(pScreen);
+ ColormapPtr pCmap;
+ int rc;
+
+ if (pPriv && pPriv->installedMap != None)
+ {
+ rc = dixLookupResourceByType((pointer *)&pCmap, pPriv->installedMap,
+ RT_COLORMAP, serverClient,
+ DixUninstallAccess);
+ if (rc == Success)
+ (*pCmap->pScreen->UninstallColormap) (pCmap);
+ pPriv->installedMap = None;
+ CheckScreenPrivate (pScreen);
+ }
+}
+
+static Bool
+CreateSaverWindow (ScreenPtr pScreen)
+{
+ SetupScreen (pScreen);
+ ScreenSaverStuffPtr pSaver;
+ ScreenSaverAttrPtr pAttr;
+ WindowPtr pWin;
+ int result;
+ unsigned long mask;
+ Colormap *installedMaps;
+ int numInstalled;
+ int i;
+ Colormap wantMap;
+ ColormapPtr pCmap;
+
+ pSaver = &savedScreenInfo[pScreen->myNum];
+ if (pSaver->pWindow)
+ {
+ pSaver->pWindow = NullWindow;
+ FreeResource (pSaver->wid, RT_NONE);
+ if (pPriv)
+ {
+ UninstallSaverColormap (pScreen);
+ pPriv->hasWindow = FALSE;
+ CheckScreenPrivate (pScreen);
+ }
+ }
+
+ if (!pPriv || !(pAttr = pPriv->attr))
+ return FALSE;
+
+ pPriv->installedMap = None;
+
+ if (GrabInProgress && GrabInProgress != pAttr->client->index)
+ return FALSE;
+
+ pWin = CreateWindow (pSaver->wid, WindowTable[pScreen->myNum],
+ pAttr->x, pAttr->y, pAttr->width, pAttr->height,
+ pAttr->borderWidth, pAttr->class,
+ pAttr->mask, (XID *)pAttr->values,
+ pAttr->depth, serverClient, pAttr->visual,
+ &result);
+ if (!pWin)
+ return FALSE;
+
+ if (!AddResource(pWin->drawable.id, RT_WINDOW, pWin))
+ return FALSE;
+
+ mask = 0;
+ if (pAttr->pBackgroundPixmap)
+ {
+ pWin->backgroundState = BackgroundPixmap;
+ pWin->background.pixmap = pAttr->pBackgroundPixmap;
+ pAttr->pBackgroundPixmap->refcnt++;
+ mask |= CWBackPixmap;
+ }
+ if (pAttr->pBorderPixmap)
+ {
+ pWin->borderIsPixel = FALSE;
+ pWin->border.pixmap = pAttr->pBorderPixmap;
+ pAttr->pBorderPixmap->refcnt++;
+ mask |= CWBorderPixmap;
+ }
+ if (pAttr->pCursor)
+ {
+ if (!pWin->optional)
+ if (!MakeWindowOptional (pWin))
+ {
+ FreeResource (pWin->drawable.id, RT_NONE);
+ return FALSE;
+ }
+ if (pWin->optional->cursor)
+ FreeCursor (pWin->optional->cursor, (Cursor)0);
+ pWin->optional->cursor = pAttr->pCursor;
+ pAttr->pCursor->refcnt++;
+ pWin->cursorIsNone = FALSE;
+ CheckWindowOptionalNeed (pWin);
+ mask |= CWCursor;
+ }
+ if (mask)
+ (*pScreen->ChangeWindowAttributes) (pWin, mask);
+
+ if (pAttr->colormap != None)
+ (void) ChangeWindowAttributes (pWin, CWColormap, &pAttr->colormap,
+ serverClient);
+
+ MapWindow (pWin, serverClient);
+
+ pPriv->hasWindow = TRUE;
+ pSaver->pWindow = pWin;
+
+ /* check and install our own colormap if it isn't installed now */
+ wantMap = wColormap (pWin);
+ if (wantMap == None)
+ return TRUE;
+ installedMaps = xalloc (pScreen->maxInstalledCmaps * sizeof (Colormap));
+ numInstalled = (*pWin->drawable.pScreen->ListInstalledColormaps)
+ (pScreen, installedMaps);
+ for (i = 0; i < numInstalled; i++)
+ if (installedMaps[i] == wantMap)
+ break;
+
+ xfree ((char *) installedMaps);
+
+ if (i < numInstalled)
+ return TRUE;
+
+ result = dixLookupResourceByType((pointer *)&pCmap, wantMap, RT_COLORMAP,
+ serverClient, DixInstallAccess);
+ if (result != Success)
+ return TRUE;
+
+ pPriv->installedMap = wantMap;
+
+ (*pCmap->pScreen->InstallColormap) (pCmap);
+
+ return TRUE;
+}
+
+static Bool
+DestroySaverWindow (ScreenPtr pScreen)
+{
+ SetupScreen(pScreen);
+ ScreenSaverStuffPtr pSaver;
+
+ if (!pPriv || !pPriv->hasWindow)
+ return FALSE;
+
+ pSaver = &savedScreenInfo[pScreen->myNum];
+ if (pSaver->pWindow)
+ {
+ pSaver->pWindow = NullWindow;
+ FreeResource (pSaver->wid, RT_NONE);
+ }
+ pPriv->hasWindow = FALSE;
+ CheckScreenPrivate (pScreen);
+ UninstallSaverColormap (pScreen);
+ return TRUE;
+}
+
+static Bool
+ScreenSaverHandle (ScreenPtr pScreen, int xstate, Bool force)
+{
+ int state = 0;
+ Bool ret = FALSE;
+ ScreenSaverScreenPrivatePtr pPriv;
+
+ switch (xstate)
+ {
+ case SCREEN_SAVER_ON:
+ state = ScreenSaverOn;
+ ret = CreateSaverWindow (pScreen);
+ break;
+ case SCREEN_SAVER_OFF:
+ state = ScreenSaverOff;
+ ret = DestroySaverWindow (pScreen);
+ break;
+ case SCREEN_SAVER_CYCLE:
+ state = ScreenSaverCycle;
+ pPriv = GetScreenPrivate (pScreen);
+ if (pPriv && pPriv->hasWindow)
+ ret = TRUE;
+
+ }
+#ifdef PANORAMIX
+ if(noPanoramiXExtension || !pScreen->myNum)
+#endif
+ SendScreenSaverNotify (pScreen, state, force);
+ return ret;
+}
+
+static int
+ProcScreenSaverQueryVersion (ClientPtr client)
+{
+ xScreenSaverQueryVersionReply rep;
+ int n;
+
+ REQUEST_SIZE_MATCH (xScreenSaverQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_SAVER_MAJOR_VERSION;
+ rep.minorVersion = SERVER_SAVER_MINOR_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+ WriteToClient(client, sizeof (xScreenSaverQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+static int
+ProcScreenSaverQueryInfo (ClientPtr client)
+{
+ REQUEST(xScreenSaverQueryInfoReq);
+ xScreenSaverQueryInfoReply rep;
+ int n, rc;
+ ScreenSaverStuffPtr pSaver;
+ DrawablePtr pDraw;
+ CARD32 lastInput;
+ ScreenSaverScreenPrivatePtr pPriv;
+
+ REQUEST_SIZE_MATCH (xScreenSaverQueryInfoReq);
+ rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
+ DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen,
+ DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ pSaver = &savedScreenInfo[pDraw->pScreen->myNum];
+ pPriv = GetScreenPrivate (pDraw->pScreen);
+
+ UpdateCurrentTime ();
+ lastInput = GetTimeInMillis() - lastDeviceEventTime.milliseconds;
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.window = pSaver->wid;
+ if (screenIsSaved != SCREEN_SAVER_OFF)
+ {
+ rep.state = ScreenSaverOn;
+ if (ScreenSaverTime)
+ rep.tilOrSince = lastInput - ScreenSaverTime;
+ else
+ rep.tilOrSince = 0;
+ }
+ else
+ {
+ if (ScreenSaverTime)
+ {
+ rep.state = ScreenSaverOff;
+ if (ScreenSaverTime < lastInput)
+ rep.tilOrSince = 0;
+ else
+ rep.tilOrSince = ScreenSaverTime - lastInput;
+ }
+ else
+ {
+ rep.state = ScreenSaverDisabled;
+ rep.tilOrSince = 0;
+ }
+ }
+ rep.idle = lastInput;
+ rep.eventMask = getEventMask (pDraw->pScreen, client);
+ if (pPriv && pPriv->attr)
+ rep.kind = ScreenSaverExternal;
+ else if (ScreenSaverBlanking != DontPreferBlanking)
+ rep.kind = ScreenSaverBlanked;
+ else
+ rep.kind = ScreenSaverInternal;
+ if (client->swapped)
+ {
+ swaps (&rep.sequenceNumber, n);
+ swapl (&rep.length, n);
+ swapl (&rep.window, n);
+ swapl (&rep.tilOrSince, n);
+ swapl (&rep.idle, n);
+ swapl (&rep.eventMask, n);
+ }
+ WriteToClient(client, sizeof (xScreenSaverQueryInfoReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+static int
+ProcScreenSaverSelectInput (ClientPtr client)
+{
+ REQUEST(xScreenSaverSelectInputReq);
+ DrawablePtr pDraw;
+ int rc;
+
+ REQUEST_SIZE_MATCH (xScreenSaverSelectInputReq);
+ rc = dixLookupDrawable (&pDraw, stuff->drawable, client, 0,
+ DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen,
+ DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!setEventMask (pDraw->pScreen, client, stuff->eventMask))
+ return BadAlloc;
+ return Success;
+}
+
+static int
+ScreenSaverSetAttributes (ClientPtr client)
+{
+ REQUEST(xScreenSaverSetAttributesReq);
+ DrawablePtr pDraw;
+ WindowPtr pParent;
+ ScreenPtr pScreen;
+ ScreenSaverScreenPrivatePtr pPriv = 0;
+ ScreenSaverAttrPtr pAttr = 0;
+ int ret, len, class, bw, depth;
+ unsigned long visual;
+ int idepth, ivisual;
+ Bool fOK;
+ DepthPtr pDepth;
+ WindowOptPtr ancwopt;
+ unsigned int *pVlist;
+ unsigned long *values = 0;
+ unsigned long tmask, imask;
+ unsigned long val;
+ Pixmap pixID;
+ PixmapPtr pPixmap;
+ Cursor cursorID;
+ CursorPtr pCursor;
+ Colormap cmap;
+ ColormapPtr pCmap;
+
+ REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq);
+ ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
+ DixGetAttrAccess);
+ if (ret != Success)
+ return ret;
+ pScreen = pDraw->pScreen;
+ pParent = WindowTable[pScreen->myNum];
+
+ ret = XaceHook(XACE_SCREENSAVER_ACCESS, client, pScreen, DixSetAttrAccess);
+ if (ret != Success)
+ return ret;
+
+ len = stuff->length - bytes_to_int32(sizeof(xScreenSaverSetAttributesReq));
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ switch (class = stuff->c_class)
+ {
+ case CopyFromParent:
+ case InputOnly:
+ case InputOutput:
+ break;
+ default:
+ client->errorValue = class;
+ return BadValue;
+ }
+ bw = stuff->borderWidth;
+ depth = stuff->depth;
+ visual = stuff->visualID;
+
+ /* copied directly from CreateWindow */
+
+ if (class == CopyFromParent)
+ class = pParent->drawable.class;
+
+ if ((class != InputOutput) && (class != InputOnly))
+ {
+ client->errorValue = class;
+ return BadValue;
+ }
+
+ if ((class != InputOnly) && (pParent->drawable.class == InputOnly))
+ return BadMatch;
+
+ if ((class == InputOnly) && ((bw != 0) || (depth != 0)))
+ return BadMatch;
+
+ if ((class == InputOutput) && (depth == 0))
+ depth = pParent->drawable.depth;
+ ancwopt = pParent->optional;
+ if (!ancwopt)
+ ancwopt = FindWindowWithOptional(pParent)->optional;
+ if (visual == CopyFromParent)
+ visual = ancwopt->visual;
+
+ /* Find out if the depth and visual are acceptable for this Screen */
+ if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth))
+ {
+ fOK = FALSE;
+ for(idepth = 0; idepth < pScreen->numDepths; idepth++)
+ {
+ pDepth = (DepthPtr) &pScreen->allowedDepths[idepth];
+ if ((depth == pDepth->depth) || (depth == 0))
+ {
+ for (ivisual = 0; ivisual < pDepth->numVids; ivisual++)
+ {
+ if (visual == pDepth->vids[ivisual])
+ {
+ fOK = TRUE;
+ break;
+ }
+ }
+ }
+ }
+ if (fOK == FALSE)
+ return BadMatch;
+ }
+
+ if (((stuff->mask & (CWBorderPixmap | CWBorderPixel)) == 0) &&
+ (class != InputOnly) &&
+ (depth != pParent->drawable.depth))
+ {
+ return BadMatch;
+ }
+
+ if (((stuff->mask & CWColormap) == 0) &&
+ (class != InputOnly) &&
+ ((visual != ancwopt->visual) || (ancwopt->colormap == None)))
+ {
+ return BadMatch;
+ }
+
+ /* end of errors from CreateWindow */
+
+ pPriv = GetScreenPrivate (pScreen);
+ if (pPriv && pPriv->attr)
+ {
+ if (pPriv->attr->client != client)
+ return BadAccess;
+ }
+ if (!pPriv)
+ {
+ pPriv = MakeScreenPrivate (pScreen);
+ if (!pPriv)
+ return FALSE;
+ }
+ pAttr = New (ScreenSaverAttrRec);
+ if (!pAttr)
+ {
+ ret = BadAlloc;
+ goto bail;
+ }
+ /* over allocate for override redirect */
+ values = xalloc ((len + 1) * sizeof (unsigned long));
+ if (!values)
+ {
+ ret = BadAlloc;
+ goto bail;
+ }
+ pAttr->screen = pScreen;
+ pAttr->client = client;
+ pAttr->x = stuff->x;
+ pAttr->y = stuff->y;
+ pAttr->width = stuff->width;
+ pAttr->height = stuff->height;
+ pAttr->borderWidth = stuff->borderWidth;
+ pAttr->class = stuff->c_class;
+ pAttr->depth = depth;
+ pAttr->visual = visual;
+ pAttr->colormap = None;
+ pAttr->pCursor = NullCursor;
+ pAttr->pBackgroundPixmap = NullPixmap;
+ pAttr->pBorderPixmap = NullPixmap;
+ pAttr->values = values;
+ /*
+ * go through the mask, checking the values,
+ * looking up pixmaps and cursors and hold a reference
+ * to them.
+ */
+ pAttr->mask = tmask = stuff->mask | CWOverrideRedirect;
+ pVlist = (unsigned int *) (stuff + 1);
+ while (tmask) {
+ imask = lowbit (tmask);
+ tmask &= ~imask;
+ switch (imask)
+ {
+ case CWBackPixmap:
+ pixID = (Pixmap )*pVlist;
+ if (pixID == None)
+ {
+ *values++ = None;
+ }
+ else if (pixID == ParentRelative)
+ {
+ if (depth != pParent->drawable.depth)
+ {
+ ret = BadMatch;
+ goto PatchUp;
+ }
+ *values++ = ParentRelative;
+ }
+ else
+ {
+ ret = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP,
+ client, DixReadAccess);
+ if (ret == Success)
+ {
+ if ((pPixmap->drawable.depth != depth) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ ret = BadMatch;
+ goto PatchUp;
+ }
+ pAttr->pBackgroundPixmap = pPixmap;
+ pPixmap->refcnt++;
+ pAttr->mask &= ~CWBackPixmap;
+ }
+ else
+ {
+ ret = (ret == BadValue) ? BadPixmap : ret;
+ client->errorValue = pixID;
+ goto PatchUp;
+ }
+ }
+ break;
+ case CWBackPixel:
+ *values++ = (CARD32) *pVlist;
+ break;
+ case CWBorderPixmap:
+ pixID = (Pixmap ) *pVlist;
+ if (pixID == CopyFromParent)
+ {
+ if (depth != pParent->drawable.depth)
+ {
+ ret = BadMatch;
+ goto PatchUp;
+ }
+ *values++ = CopyFromParent;
+ }
+ else
+ {
+ ret = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP,
+ client, DixReadAccess);
+ if (ret == Success)
+ {
+ if ((pPixmap->drawable.depth != depth) ||
+ (pPixmap->drawable.pScreen != pScreen))
+ {
+ ret = BadMatch;
+ goto PatchUp;
+ }
+ pAttr->pBorderPixmap = pPixmap;
+ pPixmap->refcnt++;
+ pAttr->mask &= ~CWBorderPixmap;
+ }
+ else
+ {
+ ret = (ret == BadValue) ? BadPixmap : ret;
+ client->errorValue = pixID;
+ goto PatchUp;
+ }
+ }
+ break;
+ case CWBorderPixel:
+ *values++ = (CARD32) *pVlist;
+ break;
+ case CWBitGravity:
+ val = (CARD8 )*pVlist;
+ if (val > StaticGravity)
+ {
+ ret = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ *values++ = val;
+ break;
+ case CWWinGravity:
+ val = (CARD8 )*pVlist;
+ if (val > StaticGravity)
+ {
+ ret = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ *values++ = val;
+ break;
+ case CWBackingStore:
+ val = (CARD8 )*pVlist;
+ if ((val != NotUseful) && (val != WhenMapped) && (val != Always))
+ {
+ ret = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ *values++ = val;
+ break;
+ case CWBackingPlanes:
+ *values++ = (CARD32) *pVlist;
+ break;
+ case CWBackingPixel:
+ *values++ = (CARD32) *pVlist;
+ break;
+ case CWSaveUnder:
+ val = (BOOL) *pVlist;
+ if ((val != xTrue) && (val != xFalse))
+ {
+ ret = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ *values++ = val;
+ break;
+ case CWEventMask:
+ *values++ = (CARD32) *pVlist;
+ break;
+ case CWDontPropagate:
+ *values++ = (CARD32) *pVlist;
+ break;
+ case CWOverrideRedirect:
+ if (!(stuff->mask & CWOverrideRedirect))
+ pVlist--;
+ else
+ {
+ val = (BOOL ) *pVlist;
+ if ((val != xTrue) && (val != xFalse))
+ {
+ ret = BadValue;
+ client->errorValue = val;
+ goto PatchUp;
+ }
+ }
+ *values++ = xTrue;
+ break;
+ case CWColormap:
+ cmap = (Colormap) *pVlist;
+ ret = dixLookupResourceByType((pointer *)&pCmap, cmap, RT_COLORMAP,
+ client, DixUseAccess);
+ if (ret != Success)
+ {
+ ret = (ret == BadValue) ? BadColor : ret;
+ client->errorValue = cmap;
+ goto PatchUp;
+ }
+ if (pCmap->pVisual->vid != visual || pCmap->pScreen != pScreen)
+ {
+ ret = BadMatch;
+ goto PatchUp;
+ }
+ pAttr->colormap = cmap;
+ pAttr->mask &= ~CWColormap;
+ break;
+ case CWCursor:
+ cursorID = (Cursor ) *pVlist;
+ if ( cursorID == None)
+ {
+ *values++ = None;
+ }
+ else
+ {
+ ret = dixLookupResourceByType((pointer *)&pCursor, cursorID,
+ RT_CURSOR, client, DixUseAccess);
+ if (ret != Success)
+ {
+ ret = (ret == BadValue) ? BadCursor : ret;
+ client->errorValue = cursorID;
+ goto PatchUp;
+ }
+ pCursor->refcnt++;
+ pAttr->pCursor = pCursor;
+ pAttr->mask &= ~CWCursor;
+ }
+ break;
+ default:
+ ret = BadValue;
+ client->errorValue = stuff->mask;
+ goto PatchUp;
+ }
+ pVlist++;
+ }
+ if (pPriv->attr)
+ FreeScreenAttr (pPriv->attr);
+ pPriv->attr = pAttr;
+ pAttr->resource = FakeClientID (client->index);
+ if (!AddResource (pAttr->resource, AttrType, (pointer) pAttr))
+ return BadAlloc;
+ return Success;
+PatchUp:
+ FreeAttrs (pAttr);
+bail:
+ CheckScreenPrivate (pScreen);
+ if (pAttr) xfree (pAttr->values);
+ xfree (pAttr);
+ return ret;
+}
+
+static int
+ScreenSaverUnsetAttributes (ClientPtr client)
+{
+ REQUEST(xScreenSaverSetAttributesReq);
+ DrawablePtr pDraw;
+ ScreenSaverScreenPrivatePtr pPriv;
+ int rc;
+
+ REQUEST_SIZE_MATCH (xScreenSaverUnsetAttributesReq);
+ rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
+ DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ pPriv = GetScreenPrivate (pDraw->pScreen);
+ if (pPriv && pPriv->attr && pPriv->attr->client == client)
+ {
+ FreeResource (pPriv->attr->resource, AttrType);
+ FreeScreenAttr (pPriv->attr);
+ pPriv->attr = NULL;
+ CheckScreenPrivate (pDraw->pScreen);
+ }
+ return Success;
+}
+
+static int
+ProcScreenSaverSetAttributes (ClientPtr client)
+{
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ REQUEST(xScreenSaverSetAttributesReq);
+ PanoramiXRes *draw;
+ PanoramiXRes *backPix = NULL;
+ PanoramiXRes *bordPix = NULL;
+ PanoramiXRes *cmap = NULL;
+ int i, status, len;
+ int pback_offset = 0, pbord_offset = 0, cmap_offset = 0;
+ XID orig_visual, tmp;
+
+ REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq);
+
+ status = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
+ XRC_DRAWABLE, client, DixWriteAccess);
+ if (status != Success)
+ return (status == BadValue) ? BadDrawable : status;
+
+ len = stuff->length - bytes_to_int32(sizeof(xScreenSaverSetAttributesReq));
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+
+ if((Mask)stuff->mask & CWBackPixmap) {
+ pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1));
+ tmp = *((CARD32 *) &stuff[1] + pback_offset);
+ if ((tmp != None) && (tmp != ParentRelative)) {
+ status = dixLookupResourceByType((pointer *)&backPix, tmp,
+ XRT_PIXMAP, client,
+ DixReadAccess);
+ if (status != Success)
+ return (status == BadValue) ? BadPixmap : status;
+ }
+ }
+
+ if ((Mask)stuff->mask & CWBorderPixmap) {
+ pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1));
+ tmp = *((CARD32 *) &stuff[1] + pbord_offset);
+ if (tmp != CopyFromParent) {
+ status = dixLookupResourceByType((pointer *)&bordPix, tmp,
+ XRT_PIXMAP, client,
+ DixReadAccess);
+ if (status != Success)
+ return (status == BadValue) ? BadPixmap : status;
+ }
+ }
+
+ if ((Mask)stuff->mask & CWColormap) {
+ cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1));
+ tmp = *((CARD32 *) &stuff[1] + cmap_offset);
+ if ((tmp != CopyFromParent) && (tmp != None)) {
+ status = dixLookupResourceByType((pointer *)&cmap, tmp,
+ XRT_COLORMAP, client,
+ DixReadAccess);
+ if (status != Success)
+ return (status == BadValue) ? BadColor : status;
+ }
+ }
+
+ orig_visual = stuff->visualID;
+
+ FOR_NSCREENS_BACKWARD(i) {
+ stuff->drawable = draw->info[i].id;
+ if (backPix)
+ *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[i].id;
+ if (bordPix)
+ *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[i].id;
+ if (cmap)
+ *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[i].id;
+
+ if (orig_visual != CopyFromParent)
+ stuff->visualID = PanoramiXTranslateVisualID(i, orig_visual);
+
+ status = ScreenSaverSetAttributes(client);
+ }
+
+ return status;
+ }
+#endif
+
+ return ScreenSaverSetAttributes(client);
+}
+
+static int
+ProcScreenSaverUnsetAttributes (ClientPtr client)
+{
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ REQUEST(xScreenSaverUnsetAttributesReq);
+ PanoramiXRes *draw;
+ int rc, i;
+
+ rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
+ XRC_DRAWABLE, client, DixWriteAccess);
+ if (rc != Success)
+ return (rc == BadValue) ? BadDrawable : rc;
+
+ for(i = PanoramiXNumScreens - 1; i > 0; i--) {
+ stuff->drawable = draw->info[i].id;
+ ScreenSaverUnsetAttributes(client);
+ }
+
+ stuff->drawable = draw->info[0].id;
+ }
+#endif
+
+ return ScreenSaverUnsetAttributes(client);
+}
+
+static int
+ProcScreenSaverSuspend (ClientPtr client)
+{
+ ScreenSaverSuspensionPtr *prev, this;
+
+ REQUEST(xScreenSaverSuspendReq);
+ REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
+
+ /* Check if this client is suspending the screensaver */
+ for (prev = &suspendingClients; (this = *prev); prev = &this->next)
+ if (this->pClient == client)
+ break;
+
+ if (this)
+ {
+ if (stuff->suspend == TRUE)
+ this->count++;
+ else if (--this->count == 0)
+ FreeResource (this->clientResource, RT_NONE);
+
+ return Success;
+ }
+
+ /* If we get to this point, this client isn't suspending the screensaver */
+ if (stuff->suspend == FALSE)
+ return Success;
+
+ /*
+ * Allocate a suspension record for the client, and stop the screensaver
+ * if it isn't already suspended by another client. We attach a resource ID
+ * to the record, so the screensaver will be reenabled and the record freed
+ * if the client disconnects without reenabling it first.
+ */
+ this = xalloc (sizeof (ScreenSaverSuspensionRec));
+
+ if (!this)
+ return BadAlloc;
+
+ this->next = NULL;
+ this->pClient = client;
+ this->count = 1;
+ this->clientResource = FakeClientID (client->index);
+
+ if (!AddResource (this->clientResource, SuspendType, (pointer) this))
+ {
+ xfree (this);
+ return BadAlloc;
+ }
+
+ *prev = this;
+ if (!screenSaverSuspended)
+ {
+ screenSaverSuspended = TRUE;
+ FreeScreenSaverTimer();
+ }
+
+ return (client->noClientException);
+}
+
+static DISPATCH_PROC((*NormalVector[])) = {
+ ProcScreenSaverQueryVersion,
+ ProcScreenSaverQueryInfo,
+ ProcScreenSaverSelectInput,
+ ProcScreenSaverSetAttributes,
+ ProcScreenSaverUnsetAttributes,
+ ProcScreenSaverSuspend,
+};
+
+#define NUM_REQUESTS ((sizeof NormalVector) / (sizeof NormalVector[0]))
+
+static int
+ProcScreenSaverDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+
+ if (stuff->data < NUM_REQUESTS)
+ return (*NormalVector[stuff->data])(client);
+ return BadRequest;
+}
+
+static int
+SProcScreenSaverQueryVersion (ClientPtr client)
+{
+ REQUEST(xScreenSaverQueryVersionReq);
+ int n;
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq);
+ return ProcScreenSaverQueryVersion (client);
+}
+
+static int
+SProcScreenSaverQueryInfo (ClientPtr client)
+{
+ REQUEST(xScreenSaverQueryInfoReq);
+ int n;
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq);
+ swapl (&stuff->drawable, n);
+ return ProcScreenSaverQueryInfo (client);
+}
+
+static int
+SProcScreenSaverSelectInput (ClientPtr client)
+{
+ REQUEST(xScreenSaverSelectInputReq);
+ int n;
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq);
+ swapl (&stuff->drawable, n);
+ swapl (&stuff->eventMask, n);
+ return ProcScreenSaverSelectInput (client);
+}
+
+static int
+SProcScreenSaverSetAttributes (ClientPtr client)
+{
+ REQUEST(xScreenSaverSetAttributesReq);
+ int n;
+
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq);
+ swapl (&stuff->drawable, n);
+ swaps (&stuff->x, n);
+ swaps (&stuff->y, n);
+ swaps (&stuff->width, n);
+ swaps (&stuff->height, n);
+ swaps (&stuff->borderWidth, n);
+ swapl (&stuff->visualID, n);
+ swapl (&stuff->mask, n);
+ SwapRestL(stuff);
+ return ProcScreenSaverSetAttributes (client);
+}
+
+static int
+SProcScreenSaverUnsetAttributes (ClientPtr client)
+{
+ REQUEST(xScreenSaverUnsetAttributesReq);
+ int n;
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq);
+ swapl (&stuff->drawable, n);
+ return ProcScreenSaverUnsetAttributes (client);
+}
+
+static int
+SProcScreenSaverSuspend (ClientPtr client)
+{
+ int n;
+ REQUEST(xScreenSaverSuspendReq);
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xScreenSaverSuspendReq);
+ swapl(&stuff->suspend, n);
+ return ProcScreenSaverSuspend (client);
+}
+
+static DISPATCH_PROC((*SwappedVector[])) = {
+ SProcScreenSaverQueryVersion,
+ SProcScreenSaverQueryInfo,
+ SProcScreenSaverSelectInput,
+ SProcScreenSaverSetAttributes,
+ SProcScreenSaverUnsetAttributes,
+ SProcScreenSaverSuspend,
+};
+
+static int
+SProcScreenSaverDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+
+ if (stuff->data < NUM_REQUESTS)
+ return (*SwappedVector[stuff->data])(client);
+ return BadRequest;
+}
diff --git a/xorg-server/Xext/security.c b/xorg-server/Xext/security.c index af8d2052f..e5de81913 100644 --- a/xorg-server/Xext/security.c +++ b/xorg-server/Xext/security.c @@ -1,1154 +1,1156 @@ -/* - -Copyright 1996, 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. - -*/ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include "scrnintstr.h" -#include "inputstr.h" -#include "windowstr.h" -#include "propertyst.h" -#include "colormapst.h" -#include "privates.h" -#include "registry.h" -#include "xacestr.h" -#include "securitysrv.h" -#include <X11/extensions/securproto.h> -#include "modinit.h" -#include "protocol-versions.h" - -/* Extension stuff */ -static int SecurityErrorBase; /* first Security error number */ -static int SecurityEventBase; /* first Security event number */ - -RESTYPE SecurityAuthorizationResType; /* resource type for authorizations */ -static RESTYPE RTEventClient; - -static CallbackListPtr SecurityValidateGroupCallback = NULL; - -/* Private state record */ -static int stateKeyIndex; -static DevPrivateKey stateKey = &stateKeyIndex; - -/* This is what we store as client security state */ -typedef struct { - int haveState; - unsigned int trustLevel; - XID authId; -} SecurityStateRec; - -/* Extensions that untrusted clients shouldn't have access to */ -static char *SecurityTrustedExtensions[] = { - "XC-MISC", - "BIG-REQUESTS", - "XpExtension", - NULL -}; - -/* - * Access modes that untrusted clients are allowed on trusted objects. - */ -static const Mask SecurityResourceMask = - DixGetAttrAccess | DixReceiveAccess | DixListPropAccess | - DixGetPropAccess | DixListAccess; -static const Mask SecurityWindowExtraMask = DixRemoveAccess; -static const Mask SecurityRootWindowExtraMask = - DixReceiveAccess | DixSendAccess | DixAddAccess | DixRemoveAccess; -static const Mask SecurityDeviceMask = - DixGetAttrAccess | DixReceiveAccess | DixGetFocusAccess | - DixGrabAccess | DixSetAttrAccess | DixUseAccess; -static const Mask SecurityServerMask = DixGetAttrAccess | DixGrabAccess; -static const Mask SecurityClientMask = DixGetAttrAccess; - - -/* SecurityAudit - * - * Arguments: - * format is the formatting string to be used to interpret the - * remaining arguments. - * - * Returns: nothing. - * - * Side Effects: - * Writes the message to the log file if security logging is on. - */ - -static void -SecurityAudit(char *format, ...) -{ - va_list args; - - if (auditTrailLevel < SECURITY_AUDIT_LEVEL) - return; - va_start(args, format); - VAuditF(format, args); - va_end(args); -} /* SecurityAudit */ - -/* - * Performs a Security permission check. - */ -static int -SecurityDoCheck(SecurityStateRec *subj, SecurityStateRec *obj, - Mask requested, Mask allowed) -{ - if (!subj->haveState || !obj->haveState) - return Success; - if (subj->trustLevel == XSecurityClientTrusted) - return Success; - if (obj->trustLevel != XSecurityClientTrusted) - return Success; - if ((requested | allowed) == allowed) - return Success; - - return BadAccess; -} - -/* - * Labels initial server objects. - */ -static void -SecurityLabelInitial(void) -{ - SecurityStateRec *state; - - /* Do the serverClient */ - state = dixLookupPrivate(&serverClient->devPrivates, stateKey); - state->trustLevel = XSecurityClientTrusted; - state->haveState = TRUE; -} - -/* - * Looks up a request name - */ -static _X_INLINE const char * -SecurityLookupRequestName(ClientPtr client) -{ - int major = ((xReq *)client->requestBuffer)->reqType; - int minor = MinorOpcodeOfRequest(client); - return LookupRequestName(major, minor); -} - - -#define rClient(obj) (clients[CLIENT_ID((obj)->resource)]) - -/* SecurityDeleteAuthorization - * - * Arguments: - * value is the authorization to delete. - * id is its resource ID. - * - * Returns: Success. - * - * Side Effects: - * Frees everything associated with the authorization. - */ - -static int -SecurityDeleteAuthorization( - pointer value, - XID id) -{ - SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)value; - unsigned short name_len, data_len; - char *name, *data; - int status; - int i; - OtherClientsPtr pEventClient; - - /* Remove the auth using the os layer auth manager */ - - status = AuthorizationFromID(pAuth->id, &name_len, &name, - &data_len, &data); - assert(status); - status = RemoveAuthorization(name_len, name, data_len, data); - assert(status); - (void)status; - - /* free the auth timer if there is one */ - - if (pAuth->timer) TimerFree(pAuth->timer); - - /* send revoke events */ - - while ((pEventClient = pAuth->eventClients)) - { - /* send revocation event event */ - ClientPtr client = rClient(pEventClient); - - if (!client->clientGone) - { - xSecurityAuthorizationRevokedEvent are; - are.type = SecurityEventBase + XSecurityAuthorizationRevoked; - are.sequenceNumber = client->sequence; - are.authId = pAuth->id; - WriteEventsToClient(client, 1, (xEvent *)&are); - } - FreeResource(pEventClient->resource, RT_NONE); - } - - /* kill all clients using this auth */ - - for (i = 1; i<currentMaxClients; i++) - if (clients[i]) { - SecurityStateRec *state; - state = dixLookupPrivate(&clients[i]->devPrivates, stateKey); - if (state->haveState && state->authId == pAuth->id) - CloseDownClient(clients[i]); - } - - SecurityAudit("revoked authorization ID %d\n", pAuth->id); - xfree(pAuth); - return Success; - -} /* SecurityDeleteAuthorization */ - - -/* resource delete function for RTEventClient */ -static int -SecurityDeleteAuthorizationEventClient( - pointer value, - XID id) -{ - OtherClientsPtr pEventClient, prev = NULL; - SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)value; - - for (pEventClient = pAuth->eventClients; - pEventClient; - pEventClient = pEventClient->next) - { - if (pEventClient->resource == id) - { - if (prev) - prev->next = pEventClient->next; - else - pAuth->eventClients = pEventClient->next; - xfree(pEventClient); - return(Success); - } - prev = pEventClient; - } - /*NOTREACHED*/ - return -1; /* make compiler happy */ -} /* SecurityDeleteAuthorizationEventClient */ - - -/* SecurityComputeAuthorizationTimeout - * - * Arguments: - * pAuth is the authorization for which we are computing the timeout - * seconds is the number of seconds we want to wait - * - * Returns: - * the number of milliseconds that the auth timer should be set to - * - * Side Effects: - * Sets pAuth->secondsRemaining to any "overflow" amount of time - * that didn't fit in 32 bits worth of milliseconds - */ - -static CARD32 -SecurityComputeAuthorizationTimeout( - SecurityAuthorizationPtr pAuth, - unsigned int seconds) -{ - /* maxSecs is the number of full seconds that can be expressed in - * 32 bits worth of milliseconds - */ - CARD32 maxSecs = (CARD32)(~0) / (CARD32)MILLI_PER_SECOND; - - if (seconds > maxSecs) - { /* only come here if we want to wait more than 49 days */ - pAuth->secondsRemaining = seconds - maxSecs; - return maxSecs * MILLI_PER_SECOND; - } - else - { /* by far the common case */ - pAuth->secondsRemaining = 0; - return seconds * MILLI_PER_SECOND; - } -} /* SecurityStartAuthorizationTimer */ - -/* SecurityAuthorizationExpired - * - * This function is passed as an argument to TimerSet and gets called from - * the timer manager in the os layer when its time is up. - * - * Arguments: - * timer is the timer for this authorization. - * time is the current time. - * pval is the authorization whose time is up. - * - * Returns: - * A new time delay in milliseconds if the timer should wait some - * more, else zero. - * - * Side Effects: - * Frees the authorization resource if the timeout period is really - * over, otherwise recomputes pAuth->secondsRemaining. - */ - -static CARD32 -SecurityAuthorizationExpired( - OsTimerPtr timer, - CARD32 time, - pointer pval) -{ - SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)pval; - - assert(pAuth->timer == timer); - - if (pAuth->secondsRemaining) - { - return SecurityComputeAuthorizationTimeout(pAuth, - pAuth->secondsRemaining); - } - else - { - FreeResource(pAuth->id, RT_NONE); - return 0; - } -} /* SecurityAuthorizationExpired */ - -/* SecurityStartAuthorizationTimer - * - * Arguments: - * pAuth is the authorization whose timer should be started. - * - * Returns: nothing. - * - * Side Effects: - * A timer is started, set to expire after the timeout period for - * this authorization. When it expires, the function - * SecurityAuthorizationExpired will be called. - */ - -static void -SecurityStartAuthorizationTimer( - SecurityAuthorizationPtr pAuth) -{ - pAuth->timer = TimerSet(pAuth->timer, 0, - SecurityComputeAuthorizationTimeout(pAuth, pAuth->timeout), - SecurityAuthorizationExpired, pAuth); -} /* SecurityStartAuthorizationTimer */ - - -/* Proc functions all take a client argument, execute the request in - * client->requestBuffer, and return a protocol error status. - */ - -static int -ProcSecurityQueryVersion( - ClientPtr client) -{ - /* REQUEST(xSecurityQueryVersionReq); */ - xSecurityQueryVersionReply rep; - - REQUEST_SIZE_MATCH(xSecurityQueryVersionReq); - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.majorVersion = SERVER_SECURITY_MAJOR_VERSION; - rep.minorVersion = SERVER_SECURITY_MINOR_VERSION; - if(client->swapped) - { - char n; - swaps(&rep.sequenceNumber, n); - swaps(&rep.majorVersion, n); - swaps(&rep.minorVersion, n); - } - (void)WriteToClient(client, SIZEOF(xSecurityQueryVersionReply), - (char *)&rep); - return (client->noClientException); -} /* ProcSecurityQueryVersion */ - - -static int -SecurityEventSelectForAuthorization( - SecurityAuthorizationPtr pAuth, - ClientPtr client, - Mask mask) -{ - OtherClients *pEventClient; - - for (pEventClient = pAuth->eventClients; - pEventClient; - pEventClient = pEventClient->next) - { - if (SameClient(pEventClient, client)) - { - if (mask == 0) - FreeResource(pEventClient->resource, RT_NONE); - else - pEventClient->mask = mask; - return Success; - } - } - - pEventClient = xalloc(sizeof(OtherClients)); - if (!pEventClient) - return BadAlloc; - pEventClient->mask = mask; - pEventClient->resource = FakeClientID(client->index); - pEventClient->next = pAuth->eventClients; - if (!AddResource(pEventClient->resource, RTEventClient, - (pointer)pAuth)) - { - xfree(pEventClient); - return BadAlloc; - } - pAuth->eventClients = pEventClient; - - return Success; -} /* SecurityEventSelectForAuthorization */ - - -static int -ProcSecurityGenerateAuthorization( - ClientPtr client) -{ - REQUEST(xSecurityGenerateAuthorizationReq); - int len; /* request length in CARD32s*/ - Bool removeAuth = FALSE; /* if bailout, call RemoveAuthorization? */ - SecurityAuthorizationPtr pAuth = NULL; /* auth we are creating */ - int err; /* error to return from this function */ - XID authId; /* authorization ID assigned by os layer */ - xSecurityGenerateAuthorizationReply rep; /* reply struct */ - unsigned int trustLevel; /* trust level of new auth */ - XID group; /* group of new auth */ - CARD32 timeout; /* timeout of new auth */ - CARD32 *values; /* list of supplied attributes */ - char *protoname; /* auth proto name sent in request */ - char *protodata; /* auth proto data sent in request */ - unsigned int authdata_len; /* # bytes of generated auth data */ - char *pAuthdata; /* generated auth data */ - Mask eventMask; /* what events on this auth does client want */ - - /* check request length */ - - REQUEST_AT_LEAST_SIZE(xSecurityGenerateAuthorizationReq); - len = bytes_to_int32(SIZEOF(xSecurityGenerateAuthorizationReq)); - len += bytes_to_int32(stuff->nbytesAuthProto); - len += bytes_to_int32(stuff->nbytesAuthData); - values = ((CARD32 *)stuff) + len; - len += Ones(stuff->valueMask); - if (client->req_len != len) - return BadLength; - - /* check valuemask */ - if (stuff->valueMask & ~XSecurityAllAuthorizationAttributes) - { - client->errorValue = stuff->valueMask; - return BadValue; - } - - /* check timeout */ - timeout = 60; - if (stuff->valueMask & XSecurityTimeout) - { - timeout = *values++; - } - - /* check trustLevel */ - trustLevel = XSecurityClientUntrusted; - if (stuff->valueMask & XSecurityTrustLevel) - { - trustLevel = *values++; - if (trustLevel != XSecurityClientTrusted && - trustLevel != XSecurityClientUntrusted) - { - client->errorValue = trustLevel; - return BadValue; - } - } - - /* check group */ - group = None; - if (stuff->valueMask & XSecurityGroup) - { - group = *values++; - if (SecurityValidateGroupCallback) - { - SecurityValidateGroupInfoRec vgi; - vgi.group = group; - vgi.valid = FALSE; - CallCallbacks(&SecurityValidateGroupCallback, (pointer)&vgi); - - /* if nobody said they recognized it, it's an error */ - - if (!vgi.valid) - { - client->errorValue = group; - return BadValue; - } - } - } - - /* check event mask */ - eventMask = 0; - if (stuff->valueMask & XSecurityEventMask) - { - eventMask = *values++; - if (eventMask & ~XSecurityAllEventMasks) - { - client->errorValue = eventMask; - return BadValue; - } - } - - protoname = (char *)&stuff[1]; - protodata = protoname + bytes_to_int32(stuff->nbytesAuthProto); - - /* call os layer to generate the authorization */ - - authId = GenerateAuthorization(stuff->nbytesAuthProto, protoname, - stuff->nbytesAuthData, protodata, - &authdata_len, &pAuthdata); - if ((XID) ~0L == authId) - { - err = SecurityErrorBase + XSecurityBadAuthorizationProtocol; - goto bailout; - } - - /* now that we've added the auth, remember to remove it if we have to - * abort the request for some reason (like allocation failure) - */ - removeAuth = TRUE; - - /* associate additional information with this auth ID */ - - pAuth = xalloc(sizeof(SecurityAuthorizationRec)); - if (!pAuth) - { - err = BadAlloc; - goto bailout; - } - - /* fill in the auth fields */ - - pAuth->id = authId; - pAuth->timeout = timeout; - pAuth->group = group; - pAuth->trustLevel = trustLevel; - pAuth->refcnt = 0; /* the auth was just created; nobody's using it yet */ - pAuth->secondsRemaining = 0; - pAuth->timer = NULL; - pAuth->eventClients = NULL; - - /* handle event selection */ - if (eventMask) - { - err = SecurityEventSelectForAuthorization(pAuth, client, eventMask); - if (err != Success) - goto bailout; - } - - if (!AddResource(authId, SecurityAuthorizationResType, pAuth)) - { - err = BadAlloc; - goto bailout; - } - - /* start the timer ticking */ - - if (pAuth->timeout != 0) - SecurityStartAuthorizationTimer(pAuth); - - /* tell client the auth id and data */ - - rep.type = X_Reply; - rep.length = bytes_to_int32(authdata_len); - rep.sequenceNumber = client->sequence; - rep.authId = authId; - rep.dataLength = authdata_len; - - if (client->swapped) - { - char n; - swapl(&rep.length, n); - swaps(&rep.sequenceNumber, n); - swapl(&rep.authId, n); - swaps(&rep.dataLength, n); - } - - WriteToClient(client, SIZEOF(xSecurityGenerateAuthorizationReply), - (char *)&rep); - WriteToClient(client, authdata_len, pAuthdata); - - SecurityAudit("client %d generated authorization %d trust %d timeout %d group %d events %d\n", - client->index, pAuth->id, pAuth->trustLevel, pAuth->timeout, - pAuth->group, eventMask); - - /* the request succeeded; don't call RemoveAuthorization or free pAuth */ - - removeAuth = FALSE; - pAuth = NULL; - err = client->noClientException; - -bailout: - if (removeAuth) - RemoveAuthorization(stuff->nbytesAuthProto, protoname, - authdata_len, pAuthdata); - if (pAuth) xfree(pAuth); - return err; - -} /* ProcSecurityGenerateAuthorization */ - -static int -ProcSecurityRevokeAuthorization( - ClientPtr client) -{ - REQUEST(xSecurityRevokeAuthorizationReq); - SecurityAuthorizationPtr pAuth; - int rc; - - REQUEST_SIZE_MATCH(xSecurityRevokeAuthorizationReq); - - rc = dixLookupResourceByType((pointer *)&pAuth, stuff->authId, - SecurityAuthorizationResType, client, - DixDestroyAccess); - if (rc != Success) - return (rc == BadValue) ? - SecurityErrorBase + XSecurityBadAuthorization : rc; - - FreeResource(stuff->authId, RT_NONE); - return Success; -} /* ProcSecurityRevokeAuthorization */ - - -static int -ProcSecurityDispatch( - ClientPtr client) -{ - REQUEST(xReq); - - switch (stuff->data) - { - case X_SecurityQueryVersion: - return ProcSecurityQueryVersion(client); - case X_SecurityGenerateAuthorization: - return ProcSecurityGenerateAuthorization(client); - case X_SecurityRevokeAuthorization: - return ProcSecurityRevokeAuthorization(client); - default: - return BadRequest; - } -} /* ProcSecurityDispatch */ - -static int -SProcSecurityQueryVersion( - ClientPtr client) -{ - REQUEST(xSecurityQueryVersionReq); - char n; - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xSecurityQueryVersionReq); - swaps(&stuff->majorVersion, n); - swaps(&stuff->minorVersion,n); - return ProcSecurityQueryVersion(client); -} /* SProcSecurityQueryVersion */ - - -static int -SProcSecurityGenerateAuthorization( - ClientPtr client) -{ - REQUEST(xSecurityGenerateAuthorizationReq); - char n; - CARD32 *values; - unsigned long nvalues; - int values_offset; - - swaps(&stuff->length, n); - REQUEST_AT_LEAST_SIZE(xSecurityGenerateAuthorizationReq); - swaps(&stuff->nbytesAuthProto, n); - swaps(&stuff->nbytesAuthData, n); - swapl(&stuff->valueMask, n); - values_offset = bytes_to_int32(stuff->nbytesAuthProto) + - bytes_to_int32(stuff->nbytesAuthData); - if (values_offset > - stuff->length - bytes_to_int32(sz_xSecurityGenerateAuthorizationReq)) - return BadLength; - values = (CARD32 *)(&stuff[1]) + values_offset; - nvalues = (((CARD32 *)stuff) + stuff->length) - values; - SwapLongs(values, nvalues); - return ProcSecurityGenerateAuthorization(client); -} /* SProcSecurityGenerateAuthorization */ - - -static int -SProcSecurityRevokeAuthorization( - ClientPtr client) -{ - REQUEST(xSecurityRevokeAuthorizationReq); - char n; - - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xSecurityRevokeAuthorizationReq); - swapl(&stuff->authId, n); - return ProcSecurityRevokeAuthorization(client); -} /* SProcSecurityRevokeAuthorization */ - - -static int -SProcSecurityDispatch( - ClientPtr client) -{ - REQUEST(xReq); - - switch (stuff->data) - { - case X_SecurityQueryVersion: - return SProcSecurityQueryVersion(client); - case X_SecurityGenerateAuthorization: - return SProcSecurityGenerateAuthorization(client); - case X_SecurityRevokeAuthorization: - return SProcSecurityRevokeAuthorization(client); - default: - return BadRequest; - } -} /* SProcSecurityDispatch */ - -static void -SwapSecurityAuthorizationRevokedEvent( - xSecurityAuthorizationRevokedEvent *from, - xSecurityAuthorizationRevokedEvent *to) -{ - to->type = from->type; - to->detail = from->detail; - cpswaps(from->sequenceNumber, to->sequenceNumber); - cpswapl(from->authId, to->authId); -} - -/* SecurityCheckDeviceAccess - * - * Arguments: - * client is the client attempting to access a device. - * dev is the device being accessed. - * fromRequest is TRUE if the device access is a direct result of - * the client executing some request and FALSE if it is a - * result of the server trying to send an event (e.g. KeymapNotify) - * to the client. - * Returns: - * TRUE if the device access should be allowed, else FALSE. - * - * Side Effects: - * An audit message is generated if access is denied. - */ - -static void -SecurityDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata) -{ - XaceDeviceAccessRec *rec = calldata; - SecurityStateRec *subj, *obj; - Mask requested = rec->access_mode; - Mask allowed = SecurityDeviceMask; - - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&serverClient->devPrivates, stateKey); - - if (rec->dev != inputInfo.keyboard) - /* this extension only supports the core keyboard */ - allowed = requested; - - if (SecurityDoCheck(subj, obj, requested, allowed) != Success) { - SecurityAudit("Security denied client %d keyboard access on request " - "%s\n", rec->client->index, - SecurityLookupRequestName(rec->client)); - rec->status = BadAccess; - } -} - -/* SecurityResource - * - * This function gets plugged into client->CheckAccess and is called from - * SecurityLookupIDByType/Class to determine if the client can access the - * resource. - * - * Arguments: - * client is the client doing the resource access. - * id is the resource id. - * rtype is its type or class. - * access_mode represents the intended use of the resource; see - * resource.h. - * res is a pointer to the resource structure for this resource. - * - * Returns: - * If access is granted, the value of rval that was passed in, else FALSE. - * - * Side Effects: - * Disallowed resource accesses are audited. - */ - -static void -SecurityResource(CallbackListPtr *pcbl, pointer unused, pointer calldata) -{ - XaceResourceAccessRec *rec = calldata; - SecurityStateRec *subj, *obj; - int cid = CLIENT_ID(rec->id); - Mask requested = rec->access_mode; - Mask allowed = SecurityResourceMask; - - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&clients[cid]->devPrivates, stateKey); - - /* disable background None for untrusted windows */ - if ((requested & DixCreateAccess) && (rec->rtype == RT_WINDOW)) - if (subj->haveState && subj->trustLevel != XSecurityClientTrusted) - ((WindowPtr)rec->res)->forcedBG = TRUE; - - /* additional permissions for specific resource types */ - if (rec->rtype == RT_WINDOW) - allowed |= SecurityWindowExtraMask; - - /* special checks for server-owned resources */ - if (cid == 0) { - if (rec->rtype & RC_DRAWABLE) - /* additional operations allowed on root windows */ - allowed |= SecurityRootWindowExtraMask; - - else if (rec->rtype == RT_COLORMAP) - /* allow access to default colormaps */ - allowed = requested; - - else - /* allow read access to other server-owned resources */ - allowed |= DixReadAccess; - } - - if (SecurityDoCheck(subj, obj, requested, allowed) == Success) - return; - - SecurityAudit("Security: denied client %d access %x to resource 0x%x " - "of client %d on request %s\n", rec->client->index, - requested, rec->id, cid, - SecurityLookupRequestName(rec->client)); - rec->status = BadAccess; /* deny access */ -} - - -static void -SecurityExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata) -{ - XaceExtAccessRec *rec = calldata; - SecurityStateRec *subj; - int i = 0; - - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - - if (subj->haveState && subj->trustLevel == XSecurityClientTrusted) - return; - - while (SecurityTrustedExtensions[i]) - if (!strcmp(SecurityTrustedExtensions[i++], rec->ext->name)) - return; - - SecurityAudit("Security: denied client %d access to extension " - "%s on request %s\n", - rec->client->index, rec->ext->name, - SecurityLookupRequestName(rec->client)); - rec->status = BadAccess; -} - -static void -SecurityServer(CallbackListPtr *pcbl, pointer unused, pointer calldata) -{ - XaceServerAccessRec *rec = calldata; - SecurityStateRec *subj, *obj; - Mask requested = rec->access_mode; - Mask allowed = SecurityServerMask; - - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&serverClient->devPrivates, stateKey); - - if (SecurityDoCheck(subj, obj, requested, allowed) != Success) { - SecurityAudit("Security: denied client %d access to server " - "configuration request %s\n", rec->client->index, - SecurityLookupRequestName(rec->client)); - rec->status = BadAccess; - } -} - -static void -SecurityClient(CallbackListPtr *pcbl, pointer unused, pointer calldata) -{ - XaceClientAccessRec *rec = calldata; - SecurityStateRec *subj, *obj; - Mask requested = rec->access_mode; - Mask allowed = SecurityClientMask; - - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&rec->target->devPrivates, stateKey); - - if (SecurityDoCheck(subj, obj, requested, allowed) != Success) { - SecurityAudit("Security: denied client %d access to client %d on " - "request %s\n", rec->client->index, rec->target->index, - SecurityLookupRequestName(rec->client)); - rec->status = BadAccess; - } -} - -static void -SecurityProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata) -{ - XacePropertyAccessRec *rec = calldata; - SecurityStateRec *subj, *obj; - ATOM name = (*rec->ppProp)->propertyName; - Mask requested = rec->access_mode; - Mask allowed = SecurityResourceMask | DixReadAccess; - - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&wClient(rec->pWin)->devPrivates, stateKey); - - if (SecurityDoCheck(subj, obj, requested, allowed) != Success) { - SecurityAudit("Security: denied client %d access to property %s " - "(atom 0x%x) window 0x%x of client %d on request %s\n", - rec->client->index, NameForAtom(name), name, - rec->pWin->drawable.id, wClient(rec->pWin)->index, - SecurityLookupRequestName(rec->client)); - rec->status = BadAccess; - } -} - -static void -SecuritySend(CallbackListPtr *pcbl, pointer unused, pointer calldata) -{ - XaceSendAccessRec *rec = calldata; - SecurityStateRec *subj, *obj; - - if (rec->client) { - int i; - - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&wClient(rec->pWin)->devPrivates, stateKey); - - if (SecurityDoCheck(subj, obj, DixSendAccess, 0) == Success) - return; - - for (i = 0; i < rec->count; i++) - if (rec->events[i].u.u.type != UnmapNotify && - rec->events[i].u.u.type != ConfigureRequest && - rec->events[i].u.u.type != ClientMessage) { - - SecurityAudit("Security: denied client %d from sending event " - "of type %s to window 0x%x of client %d\n", - rec->client->index, - LookupEventName(rec->events[i].u.u.type), - rec->pWin->drawable.id, - wClient(rec->pWin)->index); - rec->status = BadAccess; - return; - } - } -} - -static void -SecurityReceive(CallbackListPtr *pcbl, pointer unused, pointer calldata) -{ - XaceReceiveAccessRec *rec = calldata; - SecurityStateRec *subj, *obj; - - subj = dixLookupPrivate(&rec->client->devPrivates, stateKey); - obj = dixLookupPrivate(&wClient(rec->pWin)->devPrivates, stateKey); - - if (SecurityDoCheck(subj, obj, DixReceiveAccess, 0) == Success) - return; - - SecurityAudit("Security: denied client %d from receiving an event " - "sent to window 0x%x of client %d\n", - rec->client->index, rec->pWin->drawable.id, - wClient(rec->pWin)->index); - rec->status = BadAccess; -} - -/* SecurityClientStateCallback - * - * Arguments: - * pcbl is &ClientStateCallback. - * nullata is NULL. - * calldata is a pointer to a NewClientInfoRec (include/dixstruct.h) - * which contains information about client state changes. - * - * Returns: nothing. - * - * Side Effects: - * - * If a new client is connecting, its authorization ID is copied to - * client->authID. If this is a generated authorization, its reference - * count is bumped, its timer is cancelled if it was running, and its - * trustlevel is copied to TRUSTLEVEL(client). - * - * If a client is disconnecting and the client was using a generated - * authorization, the authorization's reference count is decremented, and - * if it is now zero, the timer for this authorization is started. - */ - -static void -SecurityClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata) -{ - NewClientInfoRec *pci = calldata; - SecurityStateRec *state; - SecurityAuthorizationPtr pAuth; - int rc; - - state = dixLookupPrivate(&pci->client->devPrivates, stateKey); - - switch (pci->client->clientState) { - case ClientStateInitial: - state->trustLevel = XSecurityClientTrusted; - state->authId = None; - state->haveState = TRUE; - break; - - case ClientStateRunning: - state->authId = AuthorizationIDOfClient(pci->client); - rc = dixLookupResourceByType((pointer *)&pAuth, state->authId, - SecurityAuthorizationResType, serverClient, - DixGetAttrAccess); - if (rc == Success) { - /* it is a generated authorization */ - pAuth->refcnt++; - if (pAuth->refcnt == 1 && pAuth->timer) - TimerCancel(pAuth->timer); - - state->trustLevel = pAuth->trustLevel; - } - break; - - case ClientStateGone: - case ClientStateRetained: - rc = dixLookupResourceByType((pointer *)&pAuth, state->authId, - SecurityAuthorizationResType, serverClient, - DixGetAttrAccess); - if (rc == Success) { - /* it is a generated authorization */ - pAuth->refcnt--; - if (pAuth->refcnt == 0) - SecurityStartAuthorizationTimer(pAuth); - } - break; - - default: - break; - } -} - -/* SecurityResetProc - * - * Arguments: - * extEntry is the extension information for the security extension. - * - * Returns: nothing. - * - * Side Effects: - * Performs any cleanup needed by Security at server shutdown time. - */ - -static void -SecurityResetProc( - ExtensionEntry *extEntry) -{ - /* Unregister callbacks */ - DeleteCallback(&ClientStateCallback, SecurityClientState, NULL); - - XaceDeleteCallback(XACE_EXT_DISPATCH, SecurityExtension, NULL); - XaceDeleteCallback(XACE_RESOURCE_ACCESS, SecurityResource, NULL); - XaceDeleteCallback(XACE_DEVICE_ACCESS, SecurityDevice, NULL); - XaceDeleteCallback(XACE_PROPERTY_ACCESS, SecurityProperty, NULL); - XaceDeleteCallback(XACE_SEND_ACCESS, SecuritySend, NULL); - XaceDeleteCallback(XACE_RECEIVE_ACCESS, SecurityReceive, NULL); - XaceDeleteCallback(XACE_CLIENT_ACCESS, SecurityClient, NULL); - XaceDeleteCallback(XACE_EXT_ACCESS, SecurityExtension, NULL); - XaceDeleteCallback(XACE_SERVER_ACCESS, SecurityServer, NULL); -} - - -/* SecurityExtensionInit - * - * Arguments: none. - * - * Returns: nothing. - * - * Side Effects: - * Enables the Security extension if possible. - */ - -void -SecurityExtensionInit(INITARGS) -{ - ExtensionEntry *extEntry; - int ret = TRUE; - - SecurityAuthorizationResType = - CreateNewResourceType(SecurityDeleteAuthorization, - "SecurityAuthorization"); - - RTEventClient = - CreateNewResourceType(SecurityDeleteAuthorizationEventClient, - "SecurityEventClient"); - - if (!SecurityAuthorizationResType || !RTEventClient) - return; - - RTEventClient |= RC_NEVERRETAIN; - - /* Allocate the private storage */ - if (!dixRequestPrivate(stateKey, sizeof(SecurityStateRec))) - FatalError("SecurityExtensionSetup: Can't allocate client private.\n"); - - /* Register callbacks */ - ret &= AddCallback(&ClientStateCallback, SecurityClientState, NULL); - - ret &= XaceRegisterCallback(XACE_EXT_DISPATCH, SecurityExtension, NULL); - ret &= XaceRegisterCallback(XACE_RESOURCE_ACCESS, SecurityResource, NULL); - ret &= XaceRegisterCallback(XACE_DEVICE_ACCESS, SecurityDevice, NULL); - ret &= XaceRegisterCallback(XACE_PROPERTY_ACCESS, SecurityProperty, NULL); - ret &= XaceRegisterCallback(XACE_SEND_ACCESS, SecuritySend, NULL); - ret &= XaceRegisterCallback(XACE_RECEIVE_ACCESS, SecurityReceive, NULL); - ret &= XaceRegisterCallback(XACE_CLIENT_ACCESS, SecurityClient, NULL); - ret &= XaceRegisterCallback(XACE_EXT_ACCESS, SecurityExtension, NULL); - ret &= XaceRegisterCallback(XACE_SERVER_ACCESS, SecurityServer, NULL); - - if (!ret) - FatalError("SecurityExtensionSetup: Failed to register callbacks\n"); - - /* Add extension to server */ - extEntry = AddExtension(SECURITY_EXTENSION_NAME, - XSecurityNumberEvents, XSecurityNumberErrors, - ProcSecurityDispatch, SProcSecurityDispatch, - SecurityResetProc, StandardMinorOpcode); - - SecurityErrorBase = extEntry->errorBase; - SecurityEventBase = extEntry->eventBase; - - EventSwapVector[SecurityEventBase + XSecurityAuthorizationRevoked] = - (EventSwapPtr)SwapSecurityAuthorizationRevokedEvent; - - /* Label objects that were created before we could register ourself */ - SecurityLabelInitial(); -} +/*
+
+Copyright 1996, 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.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#else
+#define XACE
+#endif
+
+#include "scrnintstr.h"
+#include "inputstr.h"
+#include "windowstr.h"
+#include "propertyst.h"
+#include "colormapst.h"
+#include "privates.h"
+#include "registry.h"
+#include "xacestr.h"
+#include "securitysrv.h"
+#include <X11/extensions/securproto.h>
+#include "modinit.h"
+#include "protocol-versions.h"
+
+/* Extension stuff */
+static int SecurityErrorBase; /* first Security error number */
+static int SecurityEventBase; /* first Security event number */
+
+RESTYPE SecurityAuthorizationResType; /* resource type for authorizations */
+static RESTYPE RTEventClient;
+
+static CallbackListPtr SecurityValidateGroupCallback = NULL;
+
+/* Private state record */
+static int stateKeyIndex;
+static DevPrivateKey stateKey = &stateKeyIndex;
+
+/* This is what we store as client security state */
+typedef struct {
+ int haveState;
+ unsigned int trustLevel;
+ XID authId;
+} SecurityStateRec;
+
+/* Extensions that untrusted clients shouldn't have access to */
+static char *SecurityTrustedExtensions[] = {
+ "XC-MISC",
+ "BIG-REQUESTS",
+ "XpExtension",
+ NULL
+};
+
+/*
+ * Access modes that untrusted clients are allowed on trusted objects.
+ */
+static const Mask SecurityResourceMask =
+ DixGetAttrAccess | DixReceiveAccess | DixListPropAccess |
+ DixGetPropAccess | DixListAccess;
+static const Mask SecurityWindowExtraMask = DixRemoveAccess;
+static const Mask SecurityRootWindowExtraMask =
+ DixReceiveAccess | DixSendAccess | DixAddAccess | DixRemoveAccess;
+static const Mask SecurityDeviceMask =
+ DixGetAttrAccess | DixReceiveAccess | DixGetFocusAccess |
+ DixGrabAccess | DixSetAttrAccess | DixUseAccess;
+static const Mask SecurityServerMask = DixGetAttrAccess | DixGrabAccess;
+static const Mask SecurityClientMask = DixGetAttrAccess;
+
+
+/* SecurityAudit
+ *
+ * Arguments:
+ * format is the formatting string to be used to interpret the
+ * remaining arguments.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Writes the message to the log file if security logging is on.
+ */
+
+static void
+SecurityAudit(char *format, ...)
+{
+ va_list args;
+
+ if (auditTrailLevel < SECURITY_AUDIT_LEVEL)
+ return;
+ va_start(args, format);
+ VAuditF(format, args);
+ va_end(args);
+} /* SecurityAudit */
+
+/*
+ * Performs a Security permission check.
+ */
+static int
+SecurityDoCheck(SecurityStateRec *subj, SecurityStateRec *obj,
+ Mask requested, Mask allowed)
+{
+ if (!subj->haveState || !obj->haveState)
+ return Success;
+ if (subj->trustLevel == XSecurityClientTrusted)
+ return Success;
+ if (obj->trustLevel != XSecurityClientTrusted)
+ return Success;
+ if ((requested | allowed) == allowed)
+ return Success;
+
+ return BadAccess;
+}
+
+/*
+ * Labels initial server objects.
+ */
+static void
+SecurityLabelInitial(void)
+{
+ SecurityStateRec *state;
+
+ /* Do the serverClient */
+ state = dixLookupPrivate(&serverClient->devPrivates, stateKey);
+ state->trustLevel = XSecurityClientTrusted;
+ state->haveState = TRUE;
+}
+
+/*
+ * Looks up a request name
+ */
+static _X_INLINE const char *
+SecurityLookupRequestName(ClientPtr client)
+{
+ int major = ((xReq *)client->requestBuffer)->reqType;
+ int minor = MinorOpcodeOfRequest(client);
+ return LookupRequestName(major, minor);
+}
+
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+/* SecurityDeleteAuthorization
+ *
+ * Arguments:
+ * value is the authorization to delete.
+ * id is its resource ID.
+ *
+ * Returns: Success.
+ *
+ * Side Effects:
+ * Frees everything associated with the authorization.
+ */
+
+static int
+SecurityDeleteAuthorization(
+ pointer value,
+ XID id)
+{
+ SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)value;
+ unsigned short name_len, data_len;
+ char *name, *data;
+ int status;
+ int i;
+ OtherClientsPtr pEventClient;
+
+ /* Remove the auth using the os layer auth manager */
+
+ status = AuthorizationFromID(pAuth->id, &name_len, &name,
+ &data_len, &data);
+ assert(status);
+ status = RemoveAuthorization(name_len, name, data_len, data);
+ assert(status);
+ (void)status;
+
+ /* free the auth timer if there is one */
+
+ if (pAuth->timer) TimerFree(pAuth->timer);
+
+ /* send revoke events */
+
+ while ((pEventClient = pAuth->eventClients))
+ {
+ /* send revocation event event */
+ ClientPtr client = rClient(pEventClient);
+
+ if (!client->clientGone)
+ {
+ xSecurityAuthorizationRevokedEvent are;
+ are.type = SecurityEventBase + XSecurityAuthorizationRevoked;
+ are.sequenceNumber = client->sequence;
+ are.authId = pAuth->id;
+ WriteEventsToClient(client, 1, (xEvent *)&are);
+ }
+ FreeResource(pEventClient->resource, RT_NONE);
+ }
+
+ /* kill all clients using this auth */
+
+ for (i = 1; i<currentMaxClients; i++)
+ if (clients[i]) {
+ SecurityStateRec *state;
+ state = dixLookupPrivate(&clients[i]->devPrivates, stateKey);
+ if (state->haveState && state->authId == pAuth->id)
+ CloseDownClient(clients[i]);
+ }
+
+ SecurityAudit("revoked authorization ID %d\n", pAuth->id);
+ xfree(pAuth);
+ return Success;
+
+} /* SecurityDeleteAuthorization */
+
+
+/* resource delete function for RTEventClient */
+static int
+SecurityDeleteAuthorizationEventClient(
+ pointer value,
+ XID id)
+{
+ OtherClientsPtr pEventClient, prev = NULL;
+ SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)value;
+
+ for (pEventClient = pAuth->eventClients;
+ pEventClient;
+ pEventClient = pEventClient->next)
+ {
+ if (pEventClient->resource == id)
+ {
+ if (prev)
+ prev->next = pEventClient->next;
+ else
+ pAuth->eventClients = pEventClient->next;
+ xfree(pEventClient);
+ return(Success);
+ }
+ prev = pEventClient;
+ }
+ /*NOTREACHED*/
+ return -1; /* make compiler happy */
+} /* SecurityDeleteAuthorizationEventClient */
+
+
+/* SecurityComputeAuthorizationTimeout
+ *
+ * Arguments:
+ * pAuth is the authorization for which we are computing the timeout
+ * seconds is the number of seconds we want to wait
+ *
+ * Returns:
+ * the number of milliseconds that the auth timer should be set to
+ *
+ * Side Effects:
+ * Sets pAuth->secondsRemaining to any "overflow" amount of time
+ * that didn't fit in 32 bits worth of milliseconds
+ */
+
+static CARD32
+SecurityComputeAuthorizationTimeout(
+ SecurityAuthorizationPtr pAuth,
+ unsigned int seconds)
+{
+ /* maxSecs is the number of full seconds that can be expressed in
+ * 32 bits worth of milliseconds
+ */
+ CARD32 maxSecs = (CARD32)(~0) / (CARD32)MILLI_PER_SECOND;
+
+ if (seconds > maxSecs)
+ { /* only come here if we want to wait more than 49 days */
+ pAuth->secondsRemaining = seconds - maxSecs;
+ return maxSecs * MILLI_PER_SECOND;
+ }
+ else
+ { /* by far the common case */
+ pAuth->secondsRemaining = 0;
+ return seconds * MILLI_PER_SECOND;
+ }
+} /* SecurityStartAuthorizationTimer */
+
+/* SecurityAuthorizationExpired
+ *
+ * This function is passed as an argument to TimerSet and gets called from
+ * the timer manager in the os layer when its time is up.
+ *
+ * Arguments:
+ * timer is the timer for this authorization.
+ * time is the current time.
+ * pval is the authorization whose time is up.
+ *
+ * Returns:
+ * A new time delay in milliseconds if the timer should wait some
+ * more, else zero.
+ *
+ * Side Effects:
+ * Frees the authorization resource if the timeout period is really
+ * over, otherwise recomputes pAuth->secondsRemaining.
+ */
+
+static CARD32
+SecurityAuthorizationExpired(
+ OsTimerPtr timer,
+ CARD32 time,
+ pointer pval)
+{
+ SecurityAuthorizationPtr pAuth = (SecurityAuthorizationPtr)pval;
+
+ assert(pAuth->timer == timer);
+
+ if (pAuth->secondsRemaining)
+ {
+ return SecurityComputeAuthorizationTimeout(pAuth,
+ pAuth->secondsRemaining);
+ }
+ else
+ {
+ FreeResource(pAuth->id, RT_NONE);
+ return 0;
+ }
+} /* SecurityAuthorizationExpired */
+
+/* SecurityStartAuthorizationTimer
+ *
+ * Arguments:
+ * pAuth is the authorization whose timer should be started.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * A timer is started, set to expire after the timeout period for
+ * this authorization. When it expires, the function
+ * SecurityAuthorizationExpired will be called.
+ */
+
+static void
+SecurityStartAuthorizationTimer(
+ SecurityAuthorizationPtr pAuth)
+{
+ pAuth->timer = TimerSet(pAuth->timer, 0,
+ SecurityComputeAuthorizationTimeout(pAuth, pAuth->timeout),
+ SecurityAuthorizationExpired, pAuth);
+} /* SecurityStartAuthorizationTimer */
+
+
+/* Proc functions all take a client argument, execute the request in
+ * client->requestBuffer, and return a protocol error status.
+ */
+
+static int
+ProcSecurityQueryVersion(
+ ClientPtr client)
+{
+ /* REQUEST(xSecurityQueryVersionReq); */
+ xSecurityQueryVersionReply rep;
+
+ REQUEST_SIZE_MATCH(xSecurityQueryVersionReq);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.majorVersion = SERVER_SECURITY_MAJOR_VERSION;
+ rep.minorVersion = SERVER_SECURITY_MINOR_VERSION;
+ if(client->swapped)
+ {
+ char n;
+ swaps(&rep.sequenceNumber, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ }
+ (void)WriteToClient(client, SIZEOF(xSecurityQueryVersionReply),
+ (char *)&rep);
+ return (client->noClientException);
+} /* ProcSecurityQueryVersion */
+
+
+static int
+SecurityEventSelectForAuthorization(
+ SecurityAuthorizationPtr pAuth,
+ ClientPtr client,
+ Mask mask)
+{
+ OtherClients *pEventClient;
+
+ for (pEventClient = pAuth->eventClients;
+ pEventClient;
+ pEventClient = pEventClient->next)
+ {
+ if (SameClient(pEventClient, client))
+ {
+ if (mask == 0)
+ FreeResource(pEventClient->resource, RT_NONE);
+ else
+ pEventClient->mask = mask;
+ return Success;
+ }
+ }
+
+ pEventClient = xalloc(sizeof(OtherClients));
+ if (!pEventClient)
+ return BadAlloc;
+ pEventClient->mask = mask;
+ pEventClient->resource = FakeClientID(client->index);
+ pEventClient->next = pAuth->eventClients;
+ if (!AddResource(pEventClient->resource, RTEventClient,
+ (pointer)pAuth))
+ {
+ xfree(pEventClient);
+ return BadAlloc;
+ }
+ pAuth->eventClients = pEventClient;
+
+ return Success;
+} /* SecurityEventSelectForAuthorization */
+
+
+static int
+ProcSecurityGenerateAuthorization(
+ ClientPtr client)
+{
+ REQUEST(xSecurityGenerateAuthorizationReq);
+ int len; /* request length in CARD32s*/
+ Bool removeAuth = FALSE; /* if bailout, call RemoveAuthorization? */
+ SecurityAuthorizationPtr pAuth = NULL; /* auth we are creating */
+ int err; /* error to return from this function */
+ XID authId; /* authorization ID assigned by os layer */
+ xSecurityGenerateAuthorizationReply rep; /* reply struct */
+ unsigned int trustLevel; /* trust level of new auth */
+ XID group; /* group of new auth */
+ CARD32 timeout; /* timeout of new auth */
+ CARD32 *values; /* list of supplied attributes */
+ char *protoname; /* auth proto name sent in request */
+ char *protodata; /* auth proto data sent in request */
+ unsigned int authdata_len; /* # bytes of generated auth data */
+ char *pAuthdata; /* generated auth data */
+ Mask eventMask; /* what events on this auth does client want */
+
+ /* check request length */
+
+ REQUEST_AT_LEAST_SIZE(xSecurityGenerateAuthorizationReq);
+ len = bytes_to_int32(SIZEOF(xSecurityGenerateAuthorizationReq));
+ len += bytes_to_int32(stuff->nbytesAuthProto);
+ len += bytes_to_int32(stuff->nbytesAuthData);
+ values = ((CARD32 *)stuff) + len;
+ len += Ones(stuff->valueMask);
+ if (client->req_len != len)
+ return BadLength;
+
+ /* check valuemask */
+ if (stuff->valueMask & ~XSecurityAllAuthorizationAttributes)
+ {
+ client->errorValue = stuff->valueMask;
+ return BadValue;
+ }
+
+ /* check timeout */
+ timeout = 60;
+ if (stuff->valueMask & XSecurityTimeout)
+ {
+ timeout = *values++;
+ }
+
+ /* check trustLevel */
+ trustLevel = XSecurityClientUntrusted;
+ if (stuff->valueMask & XSecurityTrustLevel)
+ {
+ trustLevel = *values++;
+ if (trustLevel != XSecurityClientTrusted &&
+ trustLevel != XSecurityClientUntrusted)
+ {
+ client->errorValue = trustLevel;
+ return BadValue;
+ }
+ }
+
+ /* check group */
+ group = None;
+ if (stuff->valueMask & XSecurityGroup)
+ {
+ group = *values++;
+ if (SecurityValidateGroupCallback)
+ {
+ SecurityValidateGroupInfoRec vgi;
+ vgi.group = group;
+ vgi.valid = FALSE;
+ CallCallbacks(&SecurityValidateGroupCallback, (pointer)&vgi);
+
+ /* if nobody said they recognized it, it's an error */
+
+ if (!vgi.valid)
+ {
+ client->errorValue = group;
+ return BadValue;
+ }
+ }
+ }
+
+ /* check event mask */
+ eventMask = 0;
+ if (stuff->valueMask & XSecurityEventMask)
+ {
+ eventMask = *values++;
+ if (eventMask & ~XSecurityAllEventMasks)
+ {
+ client->errorValue = eventMask;
+ return BadValue;
+ }
+ }
+
+ protoname = (char *)&stuff[1];
+ protodata = protoname + bytes_to_int32(stuff->nbytesAuthProto);
+
+ /* call os layer to generate the authorization */
+
+ authId = GenerateAuthorization(stuff->nbytesAuthProto, protoname,
+ stuff->nbytesAuthData, protodata,
+ &authdata_len, &pAuthdata);
+ if ((XID) ~0L == authId)
+ {
+ err = SecurityErrorBase + XSecurityBadAuthorizationProtocol;
+ goto bailout;
+ }
+
+ /* now that we've added the auth, remember to remove it if we have to
+ * abort the request for some reason (like allocation failure)
+ */
+ removeAuth = TRUE;
+
+ /* associate additional information with this auth ID */
+
+ pAuth = xalloc(sizeof(SecurityAuthorizationRec));
+ if (!pAuth)
+ {
+ err = BadAlloc;
+ goto bailout;
+ }
+
+ /* fill in the auth fields */
+
+ pAuth->id = authId;
+ pAuth->timeout = timeout;
+ pAuth->group = group;
+ pAuth->trustLevel = trustLevel;
+ pAuth->refcnt = 0; /* the auth was just created; nobody's using it yet */
+ pAuth->secondsRemaining = 0;
+ pAuth->timer = NULL;
+ pAuth->eventClients = NULL;
+
+ /* handle event selection */
+ if (eventMask)
+ {
+ err = SecurityEventSelectForAuthorization(pAuth, client, eventMask);
+ if (err != Success)
+ goto bailout;
+ }
+
+ if (!AddResource(authId, SecurityAuthorizationResType, pAuth))
+ {
+ err = BadAlloc;
+ goto bailout;
+ }
+
+ /* start the timer ticking */
+
+ if (pAuth->timeout != 0)
+ SecurityStartAuthorizationTimer(pAuth);
+
+ /* tell client the auth id and data */
+
+ rep.type = X_Reply;
+ rep.length = bytes_to_int32(authdata_len);
+ rep.sequenceNumber = client->sequence;
+ rep.authId = authId;
+ rep.dataLength = authdata_len;
+
+ if (client->swapped)
+ {
+ char n;
+ swapl(&rep.length, n);
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.authId, n);
+ swaps(&rep.dataLength, n);
+ }
+
+ WriteToClient(client, SIZEOF(xSecurityGenerateAuthorizationReply),
+ (char *)&rep);
+ WriteToClient(client, authdata_len, pAuthdata);
+
+ SecurityAudit("client %d generated authorization %d trust %d timeout %d group %d events %d\n",
+ client->index, pAuth->id, pAuth->trustLevel, pAuth->timeout,
+ pAuth->group, eventMask);
+
+ /* the request succeeded; don't call RemoveAuthorization or free pAuth */
+
+ removeAuth = FALSE;
+ pAuth = NULL;
+ err = client->noClientException;
+
+bailout:
+ if (removeAuth)
+ RemoveAuthorization(stuff->nbytesAuthProto, protoname,
+ authdata_len, pAuthdata);
+ if (pAuth) xfree(pAuth);
+ return err;
+
+} /* ProcSecurityGenerateAuthorization */
+
+static int
+ProcSecurityRevokeAuthorization(
+ ClientPtr client)
+{
+ REQUEST(xSecurityRevokeAuthorizationReq);
+ SecurityAuthorizationPtr pAuth;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xSecurityRevokeAuthorizationReq);
+
+ rc = dixLookupResourceByType((pointer *)&pAuth, stuff->authId,
+ SecurityAuthorizationResType, client,
+ DixDestroyAccess);
+ if (rc != Success)
+ return (rc == BadValue) ?
+ SecurityErrorBase + XSecurityBadAuthorization : rc;
+
+ FreeResource(stuff->authId, RT_NONE);
+ return Success;
+} /* ProcSecurityRevokeAuthorization */
+
+
+static int
+ProcSecurityDispatch(
+ ClientPtr client)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_SecurityQueryVersion:
+ return ProcSecurityQueryVersion(client);
+ case X_SecurityGenerateAuthorization:
+ return ProcSecurityGenerateAuthorization(client);
+ case X_SecurityRevokeAuthorization:
+ return ProcSecurityRevokeAuthorization(client);
+ default:
+ return BadRequest;
+ }
+} /* ProcSecurityDispatch */
+
+static int
+SProcSecurityQueryVersion(
+ ClientPtr client)
+{
+ REQUEST(xSecurityQueryVersionReq);
+ char n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xSecurityQueryVersionReq);
+ swaps(&stuff->majorVersion, n);
+ swaps(&stuff->minorVersion,n);
+ return ProcSecurityQueryVersion(client);
+} /* SProcSecurityQueryVersion */
+
+
+static int
+SProcSecurityGenerateAuthorization(
+ ClientPtr client)
+{
+ REQUEST(xSecurityGenerateAuthorizationReq);
+ char n;
+ CARD32 *values;
+ unsigned long nvalues;
+ int values_offset;
+
+ swaps(&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xSecurityGenerateAuthorizationReq);
+ swaps(&stuff->nbytesAuthProto, n);
+ swaps(&stuff->nbytesAuthData, n);
+ swapl(&stuff->valueMask, n);
+ values_offset = bytes_to_int32(stuff->nbytesAuthProto) +
+ bytes_to_int32(stuff->nbytesAuthData);
+ if (values_offset >
+ stuff->length - bytes_to_int32(sz_xSecurityGenerateAuthorizationReq))
+ return BadLength;
+ values = (CARD32 *)(&stuff[1]) + values_offset;
+ nvalues = (((CARD32 *)stuff) + stuff->length) - values;
+ SwapLongs(values, nvalues);
+ return ProcSecurityGenerateAuthorization(client);
+} /* SProcSecurityGenerateAuthorization */
+
+
+static int
+SProcSecurityRevokeAuthorization(
+ ClientPtr client)
+{
+ REQUEST(xSecurityRevokeAuthorizationReq);
+ char n;
+
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xSecurityRevokeAuthorizationReq);
+ swapl(&stuff->authId, n);
+ return ProcSecurityRevokeAuthorization(client);
+} /* SProcSecurityRevokeAuthorization */
+
+
+static int
+SProcSecurityDispatch(
+ ClientPtr client)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_SecurityQueryVersion:
+ return SProcSecurityQueryVersion(client);
+ case X_SecurityGenerateAuthorization:
+ return SProcSecurityGenerateAuthorization(client);
+ case X_SecurityRevokeAuthorization:
+ return SProcSecurityRevokeAuthorization(client);
+ default:
+ return BadRequest;
+ }
+} /* SProcSecurityDispatch */
+
+static void
+SwapSecurityAuthorizationRevokedEvent(
+ xSecurityAuthorizationRevokedEvent *from,
+ xSecurityAuthorizationRevokedEvent *to)
+{
+ to->type = from->type;
+ to->detail = from->detail;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->authId, to->authId);
+}
+
+/* SecurityCheckDeviceAccess
+ *
+ * Arguments:
+ * client is the client attempting to access a device.
+ * dev is the device being accessed.
+ * fromRequest is TRUE if the device access is a direct result of
+ * the client executing some request and FALSE if it is a
+ * result of the server trying to send an event (e.g. KeymapNotify)
+ * to the client.
+ * Returns:
+ * TRUE if the device access should be allowed, else FALSE.
+ *
+ * Side Effects:
+ * An audit message is generated if access is denied.
+ */
+
+static void
+SecurityDevice(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceDeviceAccessRec *rec = calldata;
+ SecurityStateRec *subj, *obj;
+ Mask requested = rec->access_mode;
+ Mask allowed = SecurityDeviceMask;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, stateKey);
+ obj = dixLookupPrivate(&serverClient->devPrivates, stateKey);
+
+ if (rec->dev != inputInfo.keyboard)
+ /* this extension only supports the core keyboard */
+ allowed = requested;
+
+ if (SecurityDoCheck(subj, obj, requested, allowed) != Success) {
+ SecurityAudit("Security denied client %d keyboard access on request "
+ "%s\n", rec->client->index,
+ SecurityLookupRequestName(rec->client));
+ rec->status = BadAccess;
+ }
+}
+
+/* SecurityResource
+ *
+ * This function gets plugged into client->CheckAccess and is called from
+ * SecurityLookupIDByType/Class to determine if the client can access the
+ * resource.
+ *
+ * Arguments:
+ * client is the client doing the resource access.
+ * id is the resource id.
+ * rtype is its type or class.
+ * access_mode represents the intended use of the resource; see
+ * resource.h.
+ * res is a pointer to the resource structure for this resource.
+ *
+ * Returns:
+ * If access is granted, the value of rval that was passed in, else FALSE.
+ *
+ * Side Effects:
+ * Disallowed resource accesses are audited.
+ */
+
+static void
+SecurityResource(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceResourceAccessRec *rec = calldata;
+ SecurityStateRec *subj, *obj;
+ int cid = CLIENT_ID(rec->id);
+ Mask requested = rec->access_mode;
+ Mask allowed = SecurityResourceMask;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, stateKey);
+ obj = dixLookupPrivate(&clients[cid]->devPrivates, stateKey);
+
+ /* disable background None for untrusted windows */
+ if ((requested & DixCreateAccess) && (rec->rtype == RT_WINDOW))
+ if (subj->haveState && subj->trustLevel != XSecurityClientTrusted)
+ ((WindowPtr)rec->res)->forcedBG = TRUE;
+
+ /* additional permissions for specific resource types */
+ if (rec->rtype == RT_WINDOW)
+ allowed |= SecurityWindowExtraMask;
+
+ /* special checks for server-owned resources */
+ if (cid == 0) {
+ if (rec->rtype & RC_DRAWABLE)
+ /* additional operations allowed on root windows */
+ allowed |= SecurityRootWindowExtraMask;
+
+ else if (rec->rtype == RT_COLORMAP)
+ /* allow access to default colormaps */
+ allowed = requested;
+
+ else
+ /* allow read access to other server-owned resources */
+ allowed |= DixReadAccess;
+ }
+
+ if (SecurityDoCheck(subj, obj, requested, allowed) == Success)
+ return;
+
+ SecurityAudit("Security: denied client %d access %x to resource 0x%x "
+ "of client %d on request %s\n", rec->client->index,
+ requested, rec->id, cid,
+ SecurityLookupRequestName(rec->client));
+ rec->status = BadAccess; /* deny access */
+}
+
+
+static void
+SecurityExtension(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceExtAccessRec *rec = calldata;
+ SecurityStateRec *subj;
+ int i = 0;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, stateKey);
+
+ if (subj->haveState && subj->trustLevel == XSecurityClientTrusted)
+ return;
+
+ while (SecurityTrustedExtensions[i])
+ if (!strcmp(SecurityTrustedExtensions[i++], rec->ext->name))
+ return;
+
+ SecurityAudit("Security: denied client %d access to extension "
+ "%s on request %s\n",
+ rec->client->index, rec->ext->name,
+ SecurityLookupRequestName(rec->client));
+ rec->status = BadAccess;
+}
+
+static void
+SecurityServer(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceServerAccessRec *rec = calldata;
+ SecurityStateRec *subj, *obj;
+ Mask requested = rec->access_mode;
+ Mask allowed = SecurityServerMask;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, stateKey);
+ obj = dixLookupPrivate(&serverClient->devPrivates, stateKey);
+
+ if (SecurityDoCheck(subj, obj, requested, allowed) != Success) {
+ SecurityAudit("Security: denied client %d access to server "
+ "configuration request %s\n", rec->client->index,
+ SecurityLookupRequestName(rec->client));
+ rec->status = BadAccess;
+ }
+}
+
+static void
+SecurityClient(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceClientAccessRec *rec = calldata;
+ SecurityStateRec *subj, *obj;
+ Mask requested = rec->access_mode;
+ Mask allowed = SecurityClientMask;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, stateKey);
+ obj = dixLookupPrivate(&rec->target->devPrivates, stateKey);
+
+ if (SecurityDoCheck(subj, obj, requested, allowed) != Success) {
+ SecurityAudit("Security: denied client %d access to client %d on "
+ "request %s\n", rec->client->index, rec->target->index,
+ SecurityLookupRequestName(rec->client));
+ rec->status = BadAccess;
+ }
+}
+
+static void
+SecurityProperty(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XacePropertyAccessRec *rec = calldata;
+ SecurityStateRec *subj, *obj;
+ ATOM name = (*rec->ppProp)->propertyName;
+ Mask requested = rec->access_mode;
+ Mask allowed = SecurityResourceMask | DixReadAccess;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, stateKey);
+ obj = dixLookupPrivate(&wClient(rec->pWin)->devPrivates, stateKey);
+
+ if (SecurityDoCheck(subj, obj, requested, allowed) != Success) {
+ SecurityAudit("Security: denied client %d access to property %s "
+ "(atom 0x%x) window 0x%x of client %d on request %s\n",
+ rec->client->index, NameForAtom(name), name,
+ rec->pWin->drawable.id, wClient(rec->pWin)->index,
+ SecurityLookupRequestName(rec->client));
+ rec->status = BadAccess;
+ }
+}
+
+static void
+SecuritySend(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceSendAccessRec *rec = calldata;
+ SecurityStateRec *subj, *obj;
+
+ if (rec->client) {
+ int i;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, stateKey);
+ obj = dixLookupPrivate(&wClient(rec->pWin)->devPrivates, stateKey);
+
+ if (SecurityDoCheck(subj, obj, DixSendAccess, 0) == Success)
+ return;
+
+ for (i = 0; i < rec->count; i++)
+ if (rec->events[i].u.u.type != UnmapNotify &&
+ rec->events[i].u.u.type != ConfigureRequest &&
+ rec->events[i].u.u.type != ClientMessage) {
+
+ SecurityAudit("Security: denied client %d from sending event "
+ "of type %s to window 0x%x of client %d\n",
+ rec->client->index,
+ LookupEventName(rec->events[i].u.u.type),
+ rec->pWin->drawable.id,
+ wClient(rec->pWin)->index);
+ rec->status = BadAccess;
+ return;
+ }
+ }
+}
+
+static void
+SecurityReceive(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ XaceReceiveAccessRec *rec = calldata;
+ SecurityStateRec *subj, *obj;
+
+ subj = dixLookupPrivate(&rec->client->devPrivates, stateKey);
+ obj = dixLookupPrivate(&wClient(rec->pWin)->devPrivates, stateKey);
+
+ if (SecurityDoCheck(subj, obj, DixReceiveAccess, 0) == Success)
+ return;
+
+ SecurityAudit("Security: denied client %d from receiving an event "
+ "sent to window 0x%x of client %d\n",
+ rec->client->index, rec->pWin->drawable.id,
+ wClient(rec->pWin)->index);
+ rec->status = BadAccess;
+}
+
+/* SecurityClientStateCallback
+ *
+ * Arguments:
+ * pcbl is &ClientStateCallback.
+ * nullata is NULL.
+ * calldata is a pointer to a NewClientInfoRec (include/dixstruct.h)
+ * which contains information about client state changes.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ *
+ * If a new client is connecting, its authorization ID is copied to
+ * client->authID. If this is a generated authorization, its reference
+ * count is bumped, its timer is cancelled if it was running, and its
+ * trustlevel is copied to TRUSTLEVEL(client).
+ *
+ * If a client is disconnecting and the client was using a generated
+ * authorization, the authorization's reference count is decremented, and
+ * if it is now zero, the timer for this authorization is started.
+ */
+
+static void
+SecurityClientState(CallbackListPtr *pcbl, pointer unused, pointer calldata)
+{
+ NewClientInfoRec *pci = calldata;
+ SecurityStateRec *state;
+ SecurityAuthorizationPtr pAuth;
+ int rc;
+
+ state = dixLookupPrivate(&pci->client->devPrivates, stateKey);
+
+ switch (pci->client->clientState) {
+ case ClientStateInitial:
+ state->trustLevel = XSecurityClientTrusted;
+ state->authId = None;
+ state->haveState = TRUE;
+ break;
+
+ case ClientStateRunning:
+ state->authId = AuthorizationIDOfClient(pci->client);
+ rc = dixLookupResourceByType((pointer *)&pAuth, state->authId,
+ SecurityAuthorizationResType, serverClient,
+ DixGetAttrAccess);
+ if (rc == Success) {
+ /* it is a generated authorization */
+ pAuth->refcnt++;
+ if (pAuth->refcnt == 1 && pAuth->timer)
+ TimerCancel(pAuth->timer);
+
+ state->trustLevel = pAuth->trustLevel;
+ }
+ break;
+
+ case ClientStateGone:
+ case ClientStateRetained:
+ rc = dixLookupResourceByType((pointer *)&pAuth, state->authId,
+ SecurityAuthorizationResType, serverClient,
+ DixGetAttrAccess);
+ if (rc == Success) {
+ /* it is a generated authorization */
+ pAuth->refcnt--;
+ if (pAuth->refcnt == 0)
+ SecurityStartAuthorizationTimer(pAuth);
+ }
+ break;
+
+ default:
+ break;
+ }
+}
+
+/* SecurityResetProc
+ *
+ * Arguments:
+ * extEntry is the extension information for the security extension.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Performs any cleanup needed by Security at server shutdown time.
+ */
+
+static void
+SecurityResetProc(
+ ExtensionEntry *extEntry)
+{
+ /* Unregister callbacks */
+ DeleteCallback(&ClientStateCallback, SecurityClientState, NULL);
+
+ XaceDeleteCallback(XACE_EXT_DISPATCH, SecurityExtension, NULL);
+ XaceDeleteCallback(XACE_RESOURCE_ACCESS, SecurityResource, NULL);
+ XaceDeleteCallback(XACE_DEVICE_ACCESS, SecurityDevice, NULL);
+ XaceDeleteCallback(XACE_PROPERTY_ACCESS, SecurityProperty, NULL);
+ XaceDeleteCallback(XACE_SEND_ACCESS, SecuritySend, NULL);
+ XaceDeleteCallback(XACE_RECEIVE_ACCESS, SecurityReceive, NULL);
+ XaceDeleteCallback(XACE_CLIENT_ACCESS, SecurityClient, NULL);
+ XaceDeleteCallback(XACE_EXT_ACCESS, SecurityExtension, NULL);
+ XaceDeleteCallback(XACE_SERVER_ACCESS, SecurityServer, NULL);
+}
+
+
+/* SecurityExtensionInit
+ *
+ * Arguments: none.
+ *
+ * Returns: nothing.
+ *
+ * Side Effects:
+ * Enables the Security extension if possible.
+ */
+
+void
+SecurityExtensionInit(INITARGS)
+{
+ ExtensionEntry *extEntry;
+ int ret = TRUE;
+
+ SecurityAuthorizationResType =
+ CreateNewResourceType(SecurityDeleteAuthorization,
+ "SecurityAuthorization");
+
+ RTEventClient =
+ CreateNewResourceType(SecurityDeleteAuthorizationEventClient,
+ "SecurityEventClient");
+
+ if (!SecurityAuthorizationResType || !RTEventClient)
+ return;
+
+ RTEventClient |= RC_NEVERRETAIN;
+
+ /* Allocate the private storage */
+ if (!dixRequestPrivate(stateKey, sizeof(SecurityStateRec)))
+ FatalError("SecurityExtensionSetup: Can't allocate client private.\n");
+
+ /* Register callbacks */
+ ret &= AddCallback(&ClientStateCallback, SecurityClientState, NULL);
+
+ ret &= XaceRegisterCallback(XACE_EXT_DISPATCH, SecurityExtension, NULL);
+ ret &= XaceRegisterCallback(XACE_RESOURCE_ACCESS, SecurityResource, NULL);
+ ret &= XaceRegisterCallback(XACE_DEVICE_ACCESS, SecurityDevice, NULL);
+ ret &= XaceRegisterCallback(XACE_PROPERTY_ACCESS, SecurityProperty, NULL);
+ ret &= XaceRegisterCallback(XACE_SEND_ACCESS, SecuritySend, NULL);
+ ret &= XaceRegisterCallback(XACE_RECEIVE_ACCESS, SecurityReceive, NULL);
+ ret &= XaceRegisterCallback(XACE_CLIENT_ACCESS, SecurityClient, NULL);
+ ret &= XaceRegisterCallback(XACE_EXT_ACCESS, SecurityExtension, NULL);
+ ret &= XaceRegisterCallback(XACE_SERVER_ACCESS, SecurityServer, NULL);
+
+ if (!ret)
+ FatalError("SecurityExtensionSetup: Failed to register callbacks\n");
+
+ /* Add extension to server */
+ extEntry = AddExtension(SECURITY_EXTENSION_NAME,
+ XSecurityNumberEvents, XSecurityNumberErrors,
+ ProcSecurityDispatch, SProcSecurityDispatch,
+ SecurityResetProc, StandardMinorOpcode);
+
+ SecurityErrorBase = extEntry->errorBase;
+ SecurityEventBase = extEntry->eventBase;
+
+ EventSwapVector[SecurityEventBase + XSecurityAuthorizationRevoked] =
+ (EventSwapPtr)SwapSecurityAuthorizationRevokedEvent;
+
+ /* Label objects that were created before we could register ourself */
+ SecurityLabelInitial();
+}
diff --git a/xorg-server/Xext/shape.c b/xorg-server/Xext/shape.c index cb4126b44..85cc9b932 100644 --- a/xorg-server/Xext/shape.c +++ b/xorg-server/Xext/shape.c @@ -1,1293 +1,1295 @@ -/************************************************************ - -Copyright 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. - -********************************************************/ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <stdlib.h> - -#include <X11/X.h> -#include <X11/Xproto.h> -#include "misc.h" -#include "os.h" -#include "windowstr.h" -#include "scrnintstr.h" -#include "pixmapstr.h" -#include "extnsionst.h" -#include "dixstruct.h" -#include "resource.h" -#include "opaque.h" -#include <X11/extensions/shapeproto.h> -#include "regionstr.h" -#include "gcstruct.h" -#include "modinit.h" -#include "protocol-versions.h" - -typedef RegionPtr (*CreateDftPtr)( - WindowPtr /* pWin */ - ); - -static int ShapeFreeClient( - pointer /* data */, - XID /* id */ - ); -static int ShapeFreeEvents( - pointer /* data */, - XID /* id */ - ); -static void SShapeNotifyEvent( - xShapeNotifyEvent * /* from */, - xShapeNotifyEvent * /* to */ - ); - -/* SendShapeNotify, CreateBoundingShape and CreateClipShape are used - * externally by the Xfixes extension and are now defined in window.h - */ - -static DISPATCH_PROC(ProcShapeCombine); -static DISPATCH_PROC(ProcShapeDispatch); -static DISPATCH_PROC(ProcShapeGetRectangles); -static DISPATCH_PROC(ProcShapeInputSelected); -static DISPATCH_PROC(ProcShapeMask); -static DISPATCH_PROC(ProcShapeOffset); -static DISPATCH_PROC(ProcShapeQueryExtents); -static DISPATCH_PROC(ProcShapeQueryVersion); -static DISPATCH_PROC(ProcShapeRectangles); -static DISPATCH_PROC(ProcShapeSelectInput); -static DISPATCH_PROC(SProcShapeCombine); -static DISPATCH_PROC(SProcShapeDispatch); -static DISPATCH_PROC(SProcShapeGetRectangles); -static DISPATCH_PROC(SProcShapeInputSelected); -static DISPATCH_PROC(SProcShapeMask); -static DISPATCH_PROC(SProcShapeOffset); -static DISPATCH_PROC(SProcShapeQueryExtents); -static DISPATCH_PROC(SProcShapeQueryVersion); -static DISPATCH_PROC(SProcShapeRectangles); -static DISPATCH_PROC(SProcShapeSelectInput); - -#ifdef PANORAMIX -#include "panoramiX.h" -#include "panoramiXsrv.h" -#endif - -static int ShapeEventBase = 0; -static RESTYPE ClientType, ShapeEventType; /* resource types for event masks */ - -/* - * each window has a list of clients requesting - * ShapeNotify events. Each client has a resource - * for each window it selects ShapeNotify input for, - * this resource is used to delete the ShapeNotifyRec - * entry from the per-window queue. - */ - -typedef struct _ShapeEvent *ShapeEventPtr; - -typedef struct _ShapeEvent { - ShapeEventPtr next; - ClientPtr client; - WindowPtr window; - XID clientResource; -} ShapeEventRec; - -/**************** - * ShapeExtensionInit - * - * Called from InitExtensions in main() or from QueryExtension() if the - * extension is dynamically loaded. - * - ****************/ - -void -ShapeExtensionInit(void) -{ - ExtensionEntry *extEntry; - - ClientType = CreateNewResourceType(ShapeFreeClient, "ShapeClient"); - ShapeEventType = CreateNewResourceType(ShapeFreeEvents, "ShapeEvent"); - if (ClientType && ShapeEventType && - (extEntry = AddExtension(SHAPENAME, ShapeNumberEvents, 0, - ProcShapeDispatch, SProcShapeDispatch, - NULL, StandardMinorOpcode))) - { - ShapeEventBase = extEntry->eventBase; - EventSwapVector[ShapeEventBase] = (EventSwapPtr) SShapeNotifyEvent; - } -} - -static int -RegionOperate ( - ClientPtr client, - WindowPtr pWin, - int kind, - RegionPtr *destRgnp, - RegionPtr srcRgn, - int op, - int xoff, int yoff, - CreateDftPtr create) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - - if (srcRgn && (xoff || yoff)) - REGION_TRANSLATE(pScreen, srcRgn, xoff, yoff); - if (!pWin->parent) - { - if (srcRgn) - REGION_DESTROY(pScreen, srcRgn); - return Success; - } - - /* May/30/2001: - * The shape.PS specs say if src is None, existing shape is to be - * removed (and so the op-code has no meaning in such removal); - * see shape.PS, page 3, ShapeMask. - */ - if (srcRgn == NULL) { - if (*destRgnp != NULL) { - REGION_DESTROY (pScreen, *destRgnp); - *destRgnp = 0; - /* go on to remove shape and generate ShapeNotify */ - } - else { - /* May/30/2001: - * The target currently has no shape in effect, so nothing to - * do here. The specs say that ShapeNotify is generated whenever - * the client region is "modified"; since no modification is done - * here, we do not generate that event. The specs does not say - * "it is an error to request removal when there is no shape in - * effect", so we return good status. - */ - return Success; - } - } - else switch (op) { - case ShapeSet: - if (*destRgnp) - REGION_DESTROY(pScreen, *destRgnp); - *destRgnp = srcRgn; - srcRgn = 0; - break; - case ShapeUnion: - if (*destRgnp) - REGION_UNION(pScreen, *destRgnp, *destRgnp, srcRgn); - break; - case ShapeIntersect: - if (*destRgnp) - REGION_INTERSECT(pScreen, *destRgnp, *destRgnp, srcRgn); - else { - *destRgnp = srcRgn; - srcRgn = 0; - } - break; - case ShapeSubtract: - if (!*destRgnp) - *destRgnp = (*create)(pWin); - REGION_SUBTRACT(pScreen, *destRgnp, *destRgnp, srcRgn); - break; - case ShapeInvert: - if (!*destRgnp) - *destRgnp = REGION_CREATE(pScreen, (BoxPtr) 0, 0); - else - REGION_SUBTRACT(pScreen, *destRgnp, srcRgn, *destRgnp); - break; - default: - client->errorValue = op; - return BadValue; - } - if (srcRgn) - REGION_DESTROY(pScreen, srcRgn); - (*pScreen->SetShape) (pWin); - SendShapeNotify (pWin, kind); - return Success; -} - -RegionPtr -CreateBoundingShape (WindowPtr pWin) -{ - BoxRec extents; - - extents.x1 = -wBorderWidth (pWin); - extents.y1 = -wBorderWidth (pWin); - extents.x2 = pWin->drawable.width + wBorderWidth (pWin); - extents.y2 = pWin->drawable.height + wBorderWidth (pWin); - return REGION_CREATE(pWin->drawable.pScreen, &extents, 1); -} - -RegionPtr -CreateClipShape (WindowPtr pWin) -{ - BoxRec extents; - - extents.x1 = 0; - extents.y1 = 0; - extents.x2 = pWin->drawable.width; - extents.y2 = pWin->drawable.height; - return REGION_CREATE(pWin->drawable.pScreen, &extents, 1); -} - -static int -ProcShapeQueryVersion (ClientPtr client) -{ - xShapeQueryVersionReply rep; - int n; - - REQUEST_SIZE_MATCH (xShapeQueryVersionReq); - memset(&rep, 0, sizeof(xShapeQueryVersionReply)); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.majorVersion = SERVER_SHAPE_MAJOR_VERSION; - rep.minorVersion = SERVER_SHAPE_MINOR_VERSION; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.majorVersion, n); - swaps(&rep.minorVersion, n); - } - WriteToClient(client, sizeof (xShapeQueryVersionReply), (char *)&rep); - return (client->noClientException); -} - -/***************** - * ProcShapeRectangles - * - *****************/ - -static int -ProcShapeRectangles (ClientPtr client) -{ - WindowPtr pWin; - ScreenPtr pScreen; - REQUEST(xShapeRectanglesReq); - xRectangle *prects; - int nrects, ctype, rc; - RegionPtr srcRgn; - RegionPtr *destRgn; - CreateDftPtr createDefault; - - REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq); - UpdateCurrentTime(); - rc = dixLookupWindow(&pWin, stuff->dest, client, DixSetAttrAccess); - if (rc != Success) - return rc; - switch (stuff->destKind) { - case ShapeBounding: - createDefault = CreateBoundingShape; - break; - case ShapeClip: - createDefault = CreateClipShape; - break; - case ShapeInput: - createDefault = CreateBoundingShape; - break; - default: - client->errorValue = stuff->destKind; - return BadValue; - } - if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) && - (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) - { - client->errorValue = stuff->ordering; - return BadValue; - } - pScreen = pWin->drawable.pScreen; - nrects = ((stuff->length << 2) - sizeof(xShapeRectanglesReq)); - if (nrects & 4) - return BadLength; - nrects >>= 3; - prects = (xRectangle *) &stuff[1]; - ctype = VerifyRectOrder(nrects, prects, (int)stuff->ordering); - if (ctype < 0) - return BadMatch; - srcRgn = RECTS_TO_REGION(pScreen, nrects, prects, ctype); - - if (!pWin->optional) - MakeWindowOptional (pWin); - switch (stuff->destKind) { - case ShapeBounding: - destRgn = &pWin->optional->boundingShape; - break; - case ShapeClip: - destRgn = &pWin->optional->clipShape; - break; - case ShapeInput: - destRgn = &pWin->optional->inputShape; - break; - default: - return BadValue; - } - - return RegionOperate (client, pWin, (int)stuff->destKind, - destRgn, srcRgn, (int)stuff->op, - stuff->xOff, stuff->yOff, createDefault); -} - -#ifdef PANORAMIX -static int -ProcPanoramiXShapeRectangles( - ClientPtr client) -{ - REQUEST(xShapeRectanglesReq); - PanoramiXRes *win; - int j, result; - - REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq); - - result = dixLookupResourceByType((pointer *)&win, stuff->dest, XRT_WINDOW, - client, DixWriteAccess); - if (result != Success) - return (result == BadValue) ? BadWindow : result; - - FOR_NSCREENS(j) { - stuff->dest = win->info[j].id; - result = ProcShapeRectangles (client); - BREAK_IF(result != Success); - } - return (result); -} -#endif - - -/************** - * ProcShapeMask - **************/ - - -static int -ProcShapeMask (ClientPtr client) -{ - WindowPtr pWin; - ScreenPtr pScreen; - REQUEST(xShapeMaskReq); - RegionPtr srcRgn; - RegionPtr *destRgn; - PixmapPtr pPixmap; - CreateDftPtr createDefault; - int rc; - - REQUEST_SIZE_MATCH (xShapeMaskReq); - UpdateCurrentTime(); - rc = dixLookupWindow(&pWin, stuff->dest, client, DixSetAttrAccess); - if (rc != Success) - return rc; - switch (stuff->destKind) { - case ShapeBounding: - createDefault = CreateBoundingShape; - break; - case ShapeClip: - createDefault = CreateClipShape; - break; - case ShapeInput: - createDefault = CreateBoundingShape; - break; - default: - client->errorValue = stuff->destKind; - return BadValue; - } - pScreen = pWin->drawable.pScreen; - if (stuff->src == None) - srcRgn = 0; - else { - rc = dixLookupResourceByType((pointer *)&pPixmap, stuff->src, RT_PIXMAP, - client, DixReadAccess); - if (rc != Success) - return (rc == BadValue) ? BadPixmap : rc; - if (pPixmap->drawable.pScreen != pScreen || - pPixmap->drawable.depth != 1) - return BadMatch; - srcRgn = BITMAP_TO_REGION(pScreen, pPixmap); - if (!srcRgn) - return BadAlloc; - } - - if (!pWin->optional) - MakeWindowOptional (pWin); - switch (stuff->destKind) { - case ShapeBounding: - destRgn = &pWin->optional->boundingShape; - break; - case ShapeClip: - destRgn = &pWin->optional->clipShape; - break; - case ShapeInput: - destRgn = &pWin->optional->inputShape; - break; - default: - return BadValue; - } - - return RegionOperate (client, pWin, (int)stuff->destKind, - destRgn, srcRgn, (int)stuff->op, - stuff->xOff, stuff->yOff, createDefault); -} - -#ifdef PANORAMIX -static int -ProcPanoramiXShapeMask( - ClientPtr client) -{ - REQUEST(xShapeMaskReq); - PanoramiXRes *win, *pmap; - int j, result; - - REQUEST_SIZE_MATCH (xShapeMaskReq); - - result = dixLookupResourceByType((pointer *)&win, stuff->dest, XRT_WINDOW, - client, DixWriteAccess); - if (result != Success) - return (result == BadValue) ? BadWindow : result; - - if(stuff->src != None) { - result = dixLookupResourceByType((pointer *)&pmap, stuff->src, - XRT_PIXMAP, client, DixReadAccess); - if (result != Success) - return (result == BadValue) ? BadPixmap : result; - } else - pmap = NULL; - - FOR_NSCREENS(j) { - stuff->dest = win->info[j].id; - if(pmap) - stuff->src = pmap->info[j].id; - result = ProcShapeMask (client); - BREAK_IF(result != Success); - } - return (result); -} -#endif - - -/************ - * ProcShapeCombine - ************/ - -static int -ProcShapeCombine (ClientPtr client) -{ - WindowPtr pSrcWin, pDestWin; - ScreenPtr pScreen; - REQUEST(xShapeCombineReq); - RegionPtr srcRgn; - RegionPtr *destRgn; - CreateDftPtr createDefault; - CreateDftPtr createSrc; - RegionPtr tmp; - int rc; - - REQUEST_SIZE_MATCH (xShapeCombineReq); - UpdateCurrentTime(); - rc = dixLookupWindow(&pDestWin, stuff->dest, client, DixSetAttrAccess); - if (rc != Success) - return rc; - if (!pDestWin->optional) - MakeWindowOptional (pDestWin); - switch (stuff->destKind) { - case ShapeBounding: - createDefault = CreateBoundingShape; - break; - case ShapeClip: - createDefault = CreateClipShape; - break; - case ShapeInput: - createDefault = CreateBoundingShape; - break; - default: - client->errorValue = stuff->destKind; - return BadValue; - } - pScreen = pDestWin->drawable.pScreen; - - rc = dixLookupWindow(&pSrcWin, stuff->src, client, DixGetAttrAccess); - if (rc != Success) - return rc; - switch (stuff->srcKind) { - case ShapeBounding: - srcRgn = wBoundingShape (pSrcWin); - createSrc = CreateBoundingShape; - break; - case ShapeClip: - srcRgn = wClipShape (pSrcWin); - createSrc = CreateClipShape; - break; - case ShapeInput: - srcRgn = wInputShape (pSrcWin); - createSrc = CreateBoundingShape; - break; - default: - client->errorValue = stuff->srcKind; - return BadValue; - } - if (pSrcWin->drawable.pScreen != pScreen) - { - return BadMatch; - } - - if (srcRgn) { - tmp = REGION_CREATE(pScreen, (BoxPtr) 0, 0); - REGION_COPY(pScreen, tmp, srcRgn); - srcRgn = tmp; - } else - srcRgn = (*createSrc) (pSrcWin); - - if (!pDestWin->optional) - MakeWindowOptional (pDestWin); - switch (stuff->destKind) { - case ShapeBounding: - destRgn = &pDestWin->optional->boundingShape; - break; - case ShapeClip: - destRgn = &pDestWin->optional->clipShape; - break; - case ShapeInput: - destRgn = &pDestWin->optional->inputShape; - break; - default: - return BadValue; - } - - return RegionOperate (client, pDestWin, (int)stuff->destKind, - destRgn, srcRgn, (int)stuff->op, - stuff->xOff, stuff->yOff, createDefault); -} - - -#ifdef PANORAMIX -static int -ProcPanoramiXShapeCombine( - ClientPtr client) -{ - REQUEST(xShapeCombineReq); - PanoramiXRes *win, *win2; - int j, result; - - REQUEST_AT_LEAST_SIZE (xShapeCombineReq); - - result = dixLookupResourceByType((pointer *)&win, stuff->dest, XRT_WINDOW, - client, DixWriteAccess); - if (result != Success) - return (result == BadValue) ? BadWindow : result; - - result = dixLookupResourceByType((pointer *)&win2, stuff->src, XRT_WINDOW, - client, DixReadAccess); - if (result != Success) - return (result == BadValue) ? BadWindow : result; - - FOR_NSCREENS(j) { - stuff->dest = win->info[j].id; - stuff->src = win2->info[j].id; - result = ProcShapeCombine (client); - BREAK_IF(result != Success); - } - return (result); -} -#endif - -/************* - * ProcShapeOffset - *************/ - -static int -ProcShapeOffset (ClientPtr client) -{ - WindowPtr pWin; - ScreenPtr pScreen; - REQUEST(xShapeOffsetReq); - RegionPtr srcRgn; - int rc; - - REQUEST_SIZE_MATCH (xShapeOffsetReq); - UpdateCurrentTime(); - rc = dixLookupWindow(&pWin, stuff->dest, client, DixSetAttrAccess); - if (rc != Success) - return rc; - switch (stuff->destKind) { - case ShapeBounding: - srcRgn = wBoundingShape (pWin); - break; - case ShapeClip: - srcRgn = wClipShape(pWin); - break; - case ShapeInput: - srcRgn = wInputShape (pWin); - break; - default: - client->errorValue = stuff->destKind; - return BadValue; - } - pScreen = pWin->drawable.pScreen; - if (srcRgn) - { - REGION_TRANSLATE(pScreen, srcRgn, stuff->xOff, stuff->yOff); - (*pScreen->SetShape) (pWin); - } - SendShapeNotify (pWin, (int)stuff->destKind); - return Success; -} - - -#ifdef PANORAMIX -static int -ProcPanoramiXShapeOffset( - ClientPtr client) -{ - REQUEST(xShapeOffsetReq); - PanoramiXRes *win; - int j, result; - - REQUEST_AT_LEAST_SIZE (xShapeOffsetReq); - - result = dixLookupResourceByType((pointer *)&win, stuff->dest, XRT_WINDOW, - client, DixWriteAccess); - if (result != Success) - return (result == BadValue) ? BadWindow : result; - - FOR_NSCREENS(j) { - stuff->dest = win->info[j].id; - result = ProcShapeOffset (client); - if(result != Success) break; - } - return (result); -} -#endif - - -static int -ProcShapeQueryExtents (ClientPtr client) -{ - REQUEST(xShapeQueryExtentsReq); - WindowPtr pWin; - xShapeQueryExtentsReply rep; - BoxRec extents, *pExtents; - int n, rc; - RegionPtr region; - - REQUEST_SIZE_MATCH (xShapeQueryExtentsReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - memset(&rep, 0, sizeof(xShapeQueryExtentsReply)); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.boundingShaped = (wBoundingShape(pWin) != 0); - rep.clipShaped = (wClipShape(pWin) != 0); - if ((region = wBoundingShape(pWin))) { - /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */ - pExtents = REGION_EXTENTS(pWin->drawable.pScreen, region); - extents = *pExtents; - } else { - extents.x1 = -wBorderWidth (pWin); - extents.y1 = -wBorderWidth (pWin); - extents.x2 = pWin->drawable.width + wBorderWidth (pWin); - extents.y2 = pWin->drawable.height + wBorderWidth (pWin); - } - rep.xBoundingShape = extents.x1; - rep.yBoundingShape = extents.y1; - rep.widthBoundingShape = extents.x2 - extents.x1; - rep.heightBoundingShape = extents.y2 - extents.y1; - if ((region = wClipShape(pWin))) { - /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */ - pExtents = REGION_EXTENTS(pWin->drawable.pScreen, region); - extents = *pExtents; - } else { - extents.x1 = 0; - extents.y1 = 0; - extents.x2 = pWin->drawable.width; - extents.y2 = pWin->drawable.height; - } - rep.xClipShape = extents.x1; - rep.yClipShape = extents.y1; - rep.widthClipShape = extents.x2 - extents.x1; - rep.heightClipShape = extents.y2 - extents.y1; - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.xBoundingShape, n); - swaps(&rep.yBoundingShape, n); - swaps(&rep.widthBoundingShape, n); - swaps(&rep.heightBoundingShape, n); - swaps(&rep.xClipShape, n); - swaps(&rep.yClipShape, n); - swaps(&rep.widthClipShape, n); - swaps(&rep.heightClipShape, n); - } - WriteToClient(client, sizeof (xShapeQueryExtentsReply), (char *)&rep); - return (client->noClientException); -} - -/*ARGSUSED*/ -static int -ShapeFreeClient (pointer data, XID id) -{ - ShapeEventPtr pShapeEvent; - WindowPtr pWin; - ShapeEventPtr *pHead, pCur, pPrev; - int rc; - - pShapeEvent = (ShapeEventPtr) data; - pWin = pShapeEvent->window; - rc = dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id, - ShapeEventType, serverClient, DixReadAccess); - if (rc == Success) { - pPrev = 0; - for (pCur = *pHead; pCur && pCur != pShapeEvent; pCur=pCur->next) - pPrev = pCur; - if (pCur) - { - if (pPrev) - pPrev->next = pShapeEvent->next; - else - *pHead = pShapeEvent->next; - } - } - xfree ((pointer) pShapeEvent); - return 1; -} - -/*ARGSUSED*/ -static int -ShapeFreeEvents (pointer data, XID id) -{ - ShapeEventPtr *pHead, pCur, pNext; - - pHead = (ShapeEventPtr *) data; - for (pCur = *pHead; pCur; pCur = pNext) { - pNext = pCur->next; - FreeResource (pCur->clientResource, ClientType); - xfree ((pointer) pCur); - } - xfree ((pointer) pHead); - return 1; -} - -static int -ProcShapeSelectInput (ClientPtr client) -{ - REQUEST(xShapeSelectInputReq); - WindowPtr pWin; - ShapeEventPtr pShapeEvent, pNewShapeEvent, *pHead; - XID clientResource; - int rc; - - REQUEST_SIZE_MATCH (xShapeSelectInputReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess); - if (rc != Success) - return rc; - rc = dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id, - ShapeEventType, client, DixWriteAccess); - if (rc != Success && rc != BadValue) - return rc; - - switch (stuff->enable) { - case xTrue: - if (pHead) { - - /* check for existing entry. */ - for (pShapeEvent = *pHead; - pShapeEvent; - pShapeEvent = pShapeEvent->next) - { - if (pShapeEvent->client == client) - return Success; - } - } - - /* build the entry */ - pNewShapeEvent = xalloc (sizeof (ShapeEventRec)); - if (!pNewShapeEvent) - return BadAlloc; - pNewShapeEvent->next = 0; - pNewShapeEvent->client = client; - pNewShapeEvent->window = pWin; - /* - * add a resource that will be deleted when - * the client goes away - */ - clientResource = FakeClientID (client->index); - pNewShapeEvent->clientResource = clientResource; - if (!AddResource (clientResource, ClientType, (pointer)pNewShapeEvent)) - return BadAlloc; - /* - * create a resource to contain a pointer to the list - * of clients selecting input. This must be indirect as - * the list may be arbitrarily rearranged which cannot be - * done through the resource database. - */ - if (!pHead) - { - pHead = xalloc (sizeof (ShapeEventPtr)); - if (!pHead || - !AddResource (pWin->drawable.id, ShapeEventType, (pointer)pHead)) - { - FreeResource (clientResource, RT_NONE); - return BadAlloc; - } - *pHead = 0; - } - pNewShapeEvent->next = *pHead; - *pHead = pNewShapeEvent; - break; - case xFalse: - /* delete the interest */ - if (pHead) { - pNewShapeEvent = 0; - for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) { - if (pShapeEvent->client == client) - break; - pNewShapeEvent = pShapeEvent; - } - if (pShapeEvent) { - FreeResource (pShapeEvent->clientResource, ClientType); - if (pNewShapeEvent) - pNewShapeEvent->next = pShapeEvent->next; - else - *pHead = pShapeEvent->next; - xfree (pShapeEvent); - } - } - break; - default: - client->errorValue = stuff->enable; - return BadValue; - } - return Success; -} - -/* - * deliver the event - */ - -void -SendShapeNotify (WindowPtr pWin, int which) -{ - ShapeEventPtr *pHead, pShapeEvent; - ClientPtr client; - xShapeNotifyEvent se; - BoxRec extents; - RegionPtr region; - BYTE shaped; - int rc; - - rc = dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id, - ShapeEventType, serverClient, DixReadAccess); - if (rc != Success) - return; - switch (which) { - case ShapeBounding: - region = wBoundingShape(pWin); - if (region) { - extents = *REGION_EXTENTS(pWin->drawable.pScreen, region); - shaped = xTrue; - } else { - extents.x1 = -wBorderWidth (pWin); - extents.y1 = -wBorderWidth (pWin); - extents.x2 = pWin->drawable.width + wBorderWidth (pWin); - extents.y2 = pWin->drawable.height + wBorderWidth (pWin); - shaped = xFalse; - } - break; - case ShapeClip: - region = wClipShape(pWin); - if (region) { - extents = *REGION_EXTENTS(pWin->drawable.pScreen, region); - shaped = xTrue; - } else { - extents.x1 = 0; - extents.y1 = 0; - extents.x2 = pWin->drawable.width; - extents.y2 = pWin->drawable.height; - shaped = xFalse; - } - break; - case ShapeInput: - region = wInputShape(pWin); - if (region) { - extents = *REGION_EXTENTS(pWin->drawable.pScreen, region); - shaped = xTrue; - } else { - extents.x1 = -wBorderWidth (pWin); - extents.y1 = -wBorderWidth (pWin); - extents.x2 = pWin->drawable.width + wBorderWidth (pWin); - extents.y2 = pWin->drawable.height + wBorderWidth (pWin); - shaped = xFalse; - } - break; - default: - return; - } - for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) { - client = pShapeEvent->client; - if (client == serverClient || client->clientGone) - continue; - se.type = ShapeNotify + ShapeEventBase; - se.kind = which; - se.window = pWin->drawable.id; - se.sequenceNumber = client->sequence; - se.x = extents.x1; - se.y = extents.y1; - se.width = extents.x2 - extents.x1; - se.height = extents.y2 - extents.y1; - se.time = currentTime.milliseconds; - se.shaped = shaped; - WriteEventsToClient (client, 1, (xEvent *) &se); - } -} - -static int -ProcShapeInputSelected (ClientPtr client) -{ - REQUEST(xShapeInputSelectedReq); - WindowPtr pWin; - ShapeEventPtr pShapeEvent, *pHead; - int enabled, rc; - xShapeInputSelectedReply rep; - int n; - - REQUEST_SIZE_MATCH (xShapeInputSelectedReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - rc = dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id, - ShapeEventType, client, DixReadAccess); - if (rc != Success && rc != BadValue) - return rc; - enabled = xFalse; - if (pHead) { - for (pShapeEvent = *pHead; - pShapeEvent; - pShapeEvent = pShapeEvent->next) - { - if (pShapeEvent->client == client) { - enabled = xTrue; - break; - } - } - } - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.enabled = enabled; - if (client->swapped) { - swaps (&rep.sequenceNumber, n); - swapl (&rep.length, n); - } - WriteToClient (client, sizeof (xShapeInputSelectedReply), (char *) &rep); - return (client->noClientException); -} - -static int -ProcShapeGetRectangles (ClientPtr client) -{ - REQUEST(xShapeGetRectanglesReq); - WindowPtr pWin; - xShapeGetRectanglesReply rep; - xRectangle *rects; - int nrects, i, rc; - RegionPtr region; - int n; - - REQUEST_SIZE_MATCH(xShapeGetRectanglesReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - switch (stuff->kind) { - case ShapeBounding: - region = wBoundingShape(pWin); - break; - case ShapeClip: - region = wClipShape(pWin); - break; - case ShapeInput: - region = wInputShape (pWin); - break; - default: - client->errorValue = stuff->kind; - return BadValue; - } - if (!region) { - nrects = 1; - rects = xalloc (sizeof (xRectangle)); - if (!rects) - return BadAlloc; - switch (stuff->kind) { - case ShapeBounding: - rects->x = - (int) wBorderWidth (pWin); - rects->y = - (int) wBorderWidth (pWin); - rects->width = pWin->drawable.width + wBorderWidth (pWin); - rects->height = pWin->drawable.height + wBorderWidth (pWin); - break; - case ShapeClip: - rects->x = 0; - rects->y = 0; - rects->width = pWin->drawable.width; - rects->height = pWin->drawable.height; - break; - case ShapeInput: - rects->x = - (int) wBorderWidth (pWin); - rects->y = - (int) wBorderWidth (pWin); - rects->width = pWin->drawable.width + wBorderWidth (pWin); - rects->height = pWin->drawable.height + wBorderWidth (pWin); - break; - } - } else { - BoxPtr box; - nrects = REGION_NUM_RECTS(region); - box = REGION_RECTS(region); - rects = xalloc (nrects * sizeof (xRectangle)); - if (!rects && nrects) - return BadAlloc; - for (i = 0; i < nrects; i++, box++) { - rects[i].x = box->x1; - rects[i].y = box->y1; - rects[i].width = box->x2 - box->x1; - rects[i].height = box->y2 - box->y1; - } - } - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = bytes_to_int32(nrects * sizeof (xRectangle)); - rep.ordering = YXBanded; - rep.nrects = nrects; - if (client->swapped) { - swaps (&rep.sequenceNumber, n); - swapl (&rep.length, n); - swapl (&rep.nrects, n); - SwapShorts ((short *)rects, (unsigned long)nrects * 4); - } - WriteToClient (client, sizeof (rep), (char *) &rep); - WriteToClient (client, nrects * sizeof (xRectangle), (char *) rects); - xfree (rects); - return client->noClientException; -} - -static int -ProcShapeDispatch (ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) { - case X_ShapeQueryVersion: - return ProcShapeQueryVersion (client); - case X_ShapeRectangles: -#ifdef PANORAMIX - if ( !noPanoramiXExtension ) - return ProcPanoramiXShapeRectangles (client); - else -#endif - return ProcShapeRectangles (client); - case X_ShapeMask: -#ifdef PANORAMIX - if ( !noPanoramiXExtension ) - return ProcPanoramiXShapeMask (client); - else -#endif - return ProcShapeMask (client); - case X_ShapeCombine: -#ifdef PANORAMIX - if ( !noPanoramiXExtension ) - return ProcPanoramiXShapeCombine (client); - else -#endif - return ProcShapeCombine (client); - case X_ShapeOffset: -#ifdef PANORAMIX - if ( !noPanoramiXExtension ) - return ProcPanoramiXShapeOffset (client); - else -#endif - return ProcShapeOffset (client); - case X_ShapeQueryExtents: - return ProcShapeQueryExtents (client); - case X_ShapeSelectInput: - return ProcShapeSelectInput (client); - case X_ShapeInputSelected: - return ProcShapeInputSelected (client); - case X_ShapeGetRectangles: - return ProcShapeGetRectangles (client); - default: - return BadRequest; - } -} - -static void -SShapeNotifyEvent(xShapeNotifyEvent *from, xShapeNotifyEvent *to) -{ - to->type = from->type; - to->kind = from->kind; - cpswapl (from->window, to->window); - cpswaps (from->sequenceNumber, to->sequenceNumber); - cpswaps (from->x, to->x); - cpswaps (from->y, to->y); - cpswaps (from->width, to->width); - cpswaps (from->height, to->height); - cpswapl (from->time, to->time); - to->shaped = from->shaped; -} - -static int -SProcShapeQueryVersion (ClientPtr client) -{ - int n; - REQUEST (xShapeQueryVersionReq); - - swaps (&stuff->length, n); - return ProcShapeQueryVersion (client); -} - -static int -SProcShapeRectangles (ClientPtr client) -{ - char n; - REQUEST (xShapeRectanglesReq); - - swaps (&stuff->length, n); - REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq); - swapl (&stuff->dest, n); - swaps (&stuff->xOff, n); - swaps (&stuff->yOff, n); - SwapRestS(stuff); - return ProcShapeRectangles (client); -} - -static int -SProcShapeMask (ClientPtr client) -{ - char n; - REQUEST (xShapeMaskReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH (xShapeMaskReq); - swapl (&stuff->dest, n); - swaps (&stuff->xOff, n); - swaps (&stuff->yOff, n); - swapl (&stuff->src, n); - return ProcShapeMask (client); -} - -static int -SProcShapeCombine (ClientPtr client) -{ - char n; - REQUEST (xShapeCombineReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH (xShapeCombineReq); - swapl (&stuff->dest, n); - swaps (&stuff->xOff, n); - swaps (&stuff->yOff, n); - swapl (&stuff->src, n); - return ProcShapeCombine (client); -} - -static int -SProcShapeOffset (ClientPtr client) -{ - char n; - REQUEST (xShapeOffsetReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH (xShapeOffsetReq); - swapl (&stuff->dest, n); - swaps (&stuff->xOff, n); - swaps (&stuff->yOff, n); - return ProcShapeOffset (client); -} - -static int -SProcShapeQueryExtents (ClientPtr client) -{ - char n; - REQUEST (xShapeQueryExtentsReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH (xShapeQueryExtentsReq); - swapl (&stuff->window, n); - return ProcShapeQueryExtents (client); -} - -static int -SProcShapeSelectInput (ClientPtr client) -{ - char n; - REQUEST (xShapeSelectInputReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH (xShapeSelectInputReq); - swapl (&stuff->window, n); - return ProcShapeSelectInput (client); -} - -static int -SProcShapeInputSelected (ClientPtr client) -{ - int n; - REQUEST (xShapeInputSelectedReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH (xShapeInputSelectedReq); - swapl (&stuff->window, n); - return ProcShapeInputSelected (client); -} - -static int -SProcShapeGetRectangles (ClientPtr client) -{ - REQUEST(xShapeGetRectanglesReq); - char n; - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xShapeGetRectanglesReq); - swapl (&stuff->window, n); - return ProcShapeGetRectangles (client); -} - -static int -SProcShapeDispatch (ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) { - case X_ShapeQueryVersion: - return SProcShapeQueryVersion (client); - case X_ShapeRectangles: - return SProcShapeRectangles (client); - case X_ShapeMask: - return SProcShapeMask (client); - case X_ShapeCombine: - return SProcShapeCombine (client); - case X_ShapeOffset: - return SProcShapeOffset (client); - case X_ShapeQueryExtents: - return SProcShapeQueryExtents (client); - case X_ShapeSelectInput: - return SProcShapeSelectInput (client); - case X_ShapeInputSelected: - return SProcShapeInputSelected (client); - case X_ShapeGetRectangles: - return SProcShapeGetRectangles (client); - default: - return BadRequest; - } -} +/************************************************************
+
+Copyright 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.
+
+********************************************************/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#else
+#define SHAPE
+#endif
+
+#include <stdlib.h>
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "extnsionst.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "opaque.h"
+#include <X11/extensions/shapeproto.h>
+#include "regionstr.h"
+#include "gcstruct.h"
+#include "modinit.h"
+#include "protocol-versions.h"
+
+typedef RegionPtr (*CreateDftPtr)(
+ WindowPtr /* pWin */
+ );
+
+static int ShapeFreeClient(
+ pointer /* data */,
+ XID /* id */
+ );
+static int ShapeFreeEvents(
+ pointer /* data */,
+ XID /* id */
+ );
+static void SShapeNotifyEvent(
+ xShapeNotifyEvent * /* from */,
+ xShapeNotifyEvent * /* to */
+ );
+
+/* SendShapeNotify, CreateBoundingShape and CreateClipShape are used
+ * externally by the Xfixes extension and are now defined in window.h
+ */
+
+static DISPATCH_PROC(ProcShapeCombine);
+static DISPATCH_PROC(ProcShapeDispatch);
+static DISPATCH_PROC(ProcShapeGetRectangles);
+static DISPATCH_PROC(ProcShapeInputSelected);
+static DISPATCH_PROC(ProcShapeMask);
+static DISPATCH_PROC(ProcShapeOffset);
+static DISPATCH_PROC(ProcShapeQueryExtents);
+static DISPATCH_PROC(ProcShapeQueryVersion);
+static DISPATCH_PROC(ProcShapeRectangles);
+static DISPATCH_PROC(ProcShapeSelectInput);
+static DISPATCH_PROC(SProcShapeCombine);
+static DISPATCH_PROC(SProcShapeDispatch);
+static DISPATCH_PROC(SProcShapeGetRectangles);
+static DISPATCH_PROC(SProcShapeInputSelected);
+static DISPATCH_PROC(SProcShapeMask);
+static DISPATCH_PROC(SProcShapeOffset);
+static DISPATCH_PROC(SProcShapeQueryExtents);
+static DISPATCH_PROC(SProcShapeQueryVersion);
+static DISPATCH_PROC(SProcShapeRectangles);
+static DISPATCH_PROC(SProcShapeSelectInput);
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+static int ShapeEventBase = 0;
+static RESTYPE ClientType, ShapeEventType; /* resource types for event masks */
+
+/*
+ * each window has a list of clients requesting
+ * ShapeNotify events. Each client has a resource
+ * for each window it selects ShapeNotify input for,
+ * this resource is used to delete the ShapeNotifyRec
+ * entry from the per-window queue.
+ */
+
+typedef struct _ShapeEvent *ShapeEventPtr;
+
+typedef struct _ShapeEvent {
+ ShapeEventPtr next;
+ ClientPtr client;
+ WindowPtr window;
+ XID clientResource;
+} ShapeEventRec;
+
+/****************
+ * ShapeExtensionInit
+ *
+ * Called from InitExtensions in main() or from QueryExtension() if the
+ * extension is dynamically loaded.
+ *
+ ****************/
+
+void
+ShapeExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+
+ ClientType = CreateNewResourceType(ShapeFreeClient, "ShapeClient");
+ ShapeEventType = CreateNewResourceType(ShapeFreeEvents, "ShapeEvent");
+ if (ClientType && ShapeEventType &&
+ (extEntry = AddExtension(SHAPENAME, ShapeNumberEvents, 0,
+ ProcShapeDispatch, SProcShapeDispatch,
+ NULL, StandardMinorOpcode)))
+ {
+ ShapeEventBase = extEntry->eventBase;
+ EventSwapVector[ShapeEventBase] = (EventSwapPtr) SShapeNotifyEvent;
+ }
+}
+
+static int
+RegionOperate (
+ ClientPtr client,
+ WindowPtr pWin,
+ int kind,
+ RegionPtr *destRgnp,
+ RegionPtr srcRgn,
+ int op,
+ int xoff, int yoff,
+ CreateDftPtr create)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+
+ if (srcRgn && (xoff || yoff))
+ REGION_TRANSLATE(pScreen, srcRgn, xoff, yoff);
+ if (!pWin->parent)
+ {
+ if (srcRgn)
+ REGION_DESTROY(pScreen, srcRgn);
+ return Success;
+ }
+
+ /* May/30/2001:
+ * The shape.PS specs say if src is None, existing shape is to be
+ * removed (and so the op-code has no meaning in such removal);
+ * see shape.PS, page 3, ShapeMask.
+ */
+ if (srcRgn == NULL) {
+ if (*destRgnp != NULL) {
+ REGION_DESTROY (pScreen, *destRgnp);
+ *destRgnp = 0;
+ /* go on to remove shape and generate ShapeNotify */
+ }
+ else {
+ /* May/30/2001:
+ * The target currently has no shape in effect, so nothing to
+ * do here. The specs say that ShapeNotify is generated whenever
+ * the client region is "modified"; since no modification is done
+ * here, we do not generate that event. The specs does not say
+ * "it is an error to request removal when there is no shape in
+ * effect", so we return good status.
+ */
+ return Success;
+ }
+ }
+ else switch (op) {
+ case ShapeSet:
+ if (*destRgnp)
+ REGION_DESTROY(pScreen, *destRgnp);
+ *destRgnp = srcRgn;
+ srcRgn = 0;
+ break;
+ case ShapeUnion:
+ if (*destRgnp)
+ REGION_UNION(pScreen, *destRgnp, *destRgnp, srcRgn);
+ break;
+ case ShapeIntersect:
+ if (*destRgnp)
+ REGION_INTERSECT(pScreen, *destRgnp, *destRgnp, srcRgn);
+ else {
+ *destRgnp = srcRgn;
+ srcRgn = 0;
+ }
+ break;
+ case ShapeSubtract:
+ if (!*destRgnp)
+ *destRgnp = (*create)(pWin);
+ REGION_SUBTRACT(pScreen, *destRgnp, *destRgnp, srcRgn);
+ break;
+ case ShapeInvert:
+ if (!*destRgnp)
+ *destRgnp = REGION_CREATE(pScreen, (BoxPtr) 0, 0);
+ else
+ REGION_SUBTRACT(pScreen, *destRgnp, srcRgn, *destRgnp);
+ break;
+ default:
+ client->errorValue = op;
+ return BadValue;
+ }
+ if (srcRgn)
+ REGION_DESTROY(pScreen, srcRgn);
+ (*pScreen->SetShape) (pWin);
+ SendShapeNotify (pWin, kind);
+ return Success;
+}
+
+RegionPtr
+CreateBoundingShape (WindowPtr pWin)
+{
+ BoxRec extents;
+
+ extents.x1 = -wBorderWidth (pWin);
+ extents.y1 = -wBorderWidth (pWin);
+ extents.x2 = pWin->drawable.width + wBorderWidth (pWin);
+ extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
+ return REGION_CREATE(pWin->drawable.pScreen, &extents, 1);
+}
+
+RegionPtr
+CreateClipShape (WindowPtr pWin)
+{
+ BoxRec extents;
+
+ extents.x1 = 0;
+ extents.y1 = 0;
+ extents.x2 = pWin->drawable.width;
+ extents.y2 = pWin->drawable.height;
+ return REGION_CREATE(pWin->drawable.pScreen, &extents, 1);
+}
+
+static int
+ProcShapeQueryVersion (ClientPtr client)
+{
+ xShapeQueryVersionReply rep;
+ int n;
+
+ REQUEST_SIZE_MATCH (xShapeQueryVersionReq);
+ memset(&rep, 0, sizeof(xShapeQueryVersionReply));
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_SHAPE_MAJOR_VERSION;
+ rep.minorVersion = SERVER_SHAPE_MINOR_VERSION;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ }
+ WriteToClient(client, sizeof (xShapeQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+/*****************
+ * ProcShapeRectangles
+ *
+ *****************/
+
+static int
+ProcShapeRectangles (ClientPtr client)
+{
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xShapeRectanglesReq);
+ xRectangle *prects;
+ int nrects, ctype, rc;
+ RegionPtr srcRgn;
+ RegionPtr *destRgn;
+ CreateDftPtr createDefault;
+
+ REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq);
+ UpdateCurrentTime();
+ rc = dixLookupWindow(&pWin, stuff->dest, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ createDefault = CreateBoundingShape;
+ break;
+ case ShapeClip:
+ createDefault = CreateClipShape;
+ break;
+ case ShapeInput:
+ createDefault = CreateBoundingShape;
+ break;
+ default:
+ client->errorValue = stuff->destKind;
+ return BadValue;
+ }
+ if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
+ (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
+ {
+ client->errorValue = stuff->ordering;
+ return BadValue;
+ }
+ pScreen = pWin->drawable.pScreen;
+ nrects = ((stuff->length << 2) - sizeof(xShapeRectanglesReq));
+ if (nrects & 4)
+ return BadLength;
+ nrects >>= 3;
+ prects = (xRectangle *) &stuff[1];
+ ctype = VerifyRectOrder(nrects, prects, (int)stuff->ordering);
+ if (ctype < 0)
+ return BadMatch;
+ srcRgn = RECTS_TO_REGION(pScreen, nrects, prects, ctype);
+
+ if (!pWin->optional)
+ MakeWindowOptional (pWin);
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ destRgn = &pWin->optional->boundingShape;
+ break;
+ case ShapeClip:
+ destRgn = &pWin->optional->clipShape;
+ break;
+ case ShapeInput:
+ destRgn = &pWin->optional->inputShape;
+ break;
+ default:
+ return BadValue;
+ }
+
+ return RegionOperate (client, pWin, (int)stuff->destKind,
+ destRgn, srcRgn, (int)stuff->op,
+ stuff->xOff, stuff->yOff, createDefault);
+}
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShapeRectangles(
+ ClientPtr client)
+{
+ REQUEST(xShapeRectanglesReq);
+ PanoramiXRes *win;
+ int j, result;
+
+ REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq);
+
+ result = dixLookupResourceByType((pointer *)&win, stuff->dest, XRT_WINDOW,
+ client, DixWriteAccess);
+ if (result != Success)
+ return (result == BadValue) ? BadWindow : result;
+
+ FOR_NSCREENS(j) {
+ stuff->dest = win->info[j].id;
+ result = ProcShapeRectangles (client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+#endif
+
+
+/**************
+ * ProcShapeMask
+ **************/
+
+
+static int
+ProcShapeMask (ClientPtr client)
+{
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xShapeMaskReq);
+ RegionPtr srcRgn;
+ RegionPtr *destRgn;
+ PixmapPtr pPixmap;
+ CreateDftPtr createDefault;
+ int rc;
+
+ REQUEST_SIZE_MATCH (xShapeMaskReq);
+ UpdateCurrentTime();
+ rc = dixLookupWindow(&pWin, stuff->dest, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ createDefault = CreateBoundingShape;
+ break;
+ case ShapeClip:
+ createDefault = CreateClipShape;
+ break;
+ case ShapeInput:
+ createDefault = CreateBoundingShape;
+ break;
+ default:
+ client->errorValue = stuff->destKind;
+ return BadValue;
+ }
+ pScreen = pWin->drawable.pScreen;
+ if (stuff->src == None)
+ srcRgn = 0;
+ else {
+ rc = dixLookupResourceByType((pointer *)&pPixmap, stuff->src, RT_PIXMAP,
+ client, DixReadAccess);
+ if (rc != Success)
+ return (rc == BadValue) ? BadPixmap : rc;
+ if (pPixmap->drawable.pScreen != pScreen ||
+ pPixmap->drawable.depth != 1)
+ return BadMatch;
+ srcRgn = BITMAP_TO_REGION(pScreen, pPixmap);
+ if (!srcRgn)
+ return BadAlloc;
+ }
+
+ if (!pWin->optional)
+ MakeWindowOptional (pWin);
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ destRgn = &pWin->optional->boundingShape;
+ break;
+ case ShapeClip:
+ destRgn = &pWin->optional->clipShape;
+ break;
+ case ShapeInput:
+ destRgn = &pWin->optional->inputShape;
+ break;
+ default:
+ return BadValue;
+ }
+
+ return RegionOperate (client, pWin, (int)stuff->destKind,
+ destRgn, srcRgn, (int)stuff->op,
+ stuff->xOff, stuff->yOff, createDefault);
+}
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShapeMask(
+ ClientPtr client)
+{
+ REQUEST(xShapeMaskReq);
+ PanoramiXRes *win, *pmap;
+ int j, result;
+
+ REQUEST_SIZE_MATCH (xShapeMaskReq);
+
+ result = dixLookupResourceByType((pointer *)&win, stuff->dest, XRT_WINDOW,
+ client, DixWriteAccess);
+ if (result != Success)
+ return (result == BadValue) ? BadWindow : result;
+
+ if(stuff->src != None) {
+ result = dixLookupResourceByType((pointer *)&pmap, stuff->src,
+ XRT_PIXMAP, client, DixReadAccess);
+ if (result != Success)
+ return (result == BadValue) ? BadPixmap : result;
+ } else
+ pmap = NULL;
+
+ FOR_NSCREENS(j) {
+ stuff->dest = win->info[j].id;
+ if(pmap)
+ stuff->src = pmap->info[j].id;
+ result = ProcShapeMask (client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+#endif
+
+
+/************
+ * ProcShapeCombine
+ ************/
+
+static int
+ProcShapeCombine (ClientPtr client)
+{
+ WindowPtr pSrcWin, pDestWin;
+ ScreenPtr pScreen;
+ REQUEST(xShapeCombineReq);
+ RegionPtr srcRgn;
+ RegionPtr *destRgn;
+ CreateDftPtr createDefault;
+ CreateDftPtr createSrc;
+ RegionPtr tmp;
+ int rc;
+
+ REQUEST_SIZE_MATCH (xShapeCombineReq);
+ UpdateCurrentTime();
+ rc = dixLookupWindow(&pDestWin, stuff->dest, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ if (!pDestWin->optional)
+ MakeWindowOptional (pDestWin);
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ createDefault = CreateBoundingShape;
+ break;
+ case ShapeClip:
+ createDefault = CreateClipShape;
+ break;
+ case ShapeInput:
+ createDefault = CreateBoundingShape;
+ break;
+ default:
+ client->errorValue = stuff->destKind;
+ return BadValue;
+ }
+ pScreen = pDestWin->drawable.pScreen;
+
+ rc = dixLookupWindow(&pSrcWin, stuff->src, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ switch (stuff->srcKind) {
+ case ShapeBounding:
+ srcRgn = wBoundingShape (pSrcWin);
+ createSrc = CreateBoundingShape;
+ break;
+ case ShapeClip:
+ srcRgn = wClipShape (pSrcWin);
+ createSrc = CreateClipShape;
+ break;
+ case ShapeInput:
+ srcRgn = wInputShape (pSrcWin);
+ createSrc = CreateBoundingShape;
+ break;
+ default:
+ client->errorValue = stuff->srcKind;
+ return BadValue;
+ }
+ if (pSrcWin->drawable.pScreen != pScreen)
+ {
+ return BadMatch;
+ }
+
+ if (srcRgn) {
+ tmp = REGION_CREATE(pScreen, (BoxPtr) 0, 0);
+ REGION_COPY(pScreen, tmp, srcRgn);
+ srcRgn = tmp;
+ } else
+ srcRgn = (*createSrc) (pSrcWin);
+
+ if (!pDestWin->optional)
+ MakeWindowOptional (pDestWin);
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ destRgn = &pDestWin->optional->boundingShape;
+ break;
+ case ShapeClip:
+ destRgn = &pDestWin->optional->clipShape;
+ break;
+ case ShapeInput:
+ destRgn = &pDestWin->optional->inputShape;
+ break;
+ default:
+ return BadValue;
+ }
+
+ return RegionOperate (client, pDestWin, (int)stuff->destKind,
+ destRgn, srcRgn, (int)stuff->op,
+ stuff->xOff, stuff->yOff, createDefault);
+}
+
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShapeCombine(
+ ClientPtr client)
+{
+ REQUEST(xShapeCombineReq);
+ PanoramiXRes *win, *win2;
+ int j, result;
+
+ REQUEST_AT_LEAST_SIZE (xShapeCombineReq);
+
+ result = dixLookupResourceByType((pointer *)&win, stuff->dest, XRT_WINDOW,
+ client, DixWriteAccess);
+ if (result != Success)
+ return (result == BadValue) ? BadWindow : result;
+
+ result = dixLookupResourceByType((pointer *)&win2, stuff->src, XRT_WINDOW,
+ client, DixReadAccess);
+ if (result != Success)
+ return (result == BadValue) ? BadWindow : result;
+
+ FOR_NSCREENS(j) {
+ stuff->dest = win->info[j].id;
+ stuff->src = win2->info[j].id;
+ result = ProcShapeCombine (client);
+ BREAK_IF(result != Success);
+ }
+ return (result);
+}
+#endif
+
+/*************
+ * ProcShapeOffset
+ *************/
+
+static int
+ProcShapeOffset (ClientPtr client)
+{
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xShapeOffsetReq);
+ RegionPtr srcRgn;
+ int rc;
+
+ REQUEST_SIZE_MATCH (xShapeOffsetReq);
+ UpdateCurrentTime();
+ rc = dixLookupWindow(&pWin, stuff->dest, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ switch (stuff->destKind) {
+ case ShapeBounding:
+ srcRgn = wBoundingShape (pWin);
+ break;
+ case ShapeClip:
+ srcRgn = wClipShape(pWin);
+ break;
+ case ShapeInput:
+ srcRgn = wInputShape (pWin);
+ break;
+ default:
+ client->errorValue = stuff->destKind;
+ return BadValue;
+ }
+ pScreen = pWin->drawable.pScreen;
+ if (srcRgn)
+ {
+ REGION_TRANSLATE(pScreen, srcRgn, stuff->xOff, stuff->yOff);
+ (*pScreen->SetShape) (pWin);
+ }
+ SendShapeNotify (pWin, (int)stuff->destKind);
+ return Success;
+}
+
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShapeOffset(
+ ClientPtr client)
+{
+ REQUEST(xShapeOffsetReq);
+ PanoramiXRes *win;
+ int j, result;
+
+ REQUEST_AT_LEAST_SIZE (xShapeOffsetReq);
+
+ result = dixLookupResourceByType((pointer *)&win, stuff->dest, XRT_WINDOW,
+ client, DixWriteAccess);
+ if (result != Success)
+ return (result == BadValue) ? BadWindow : result;
+
+ FOR_NSCREENS(j) {
+ stuff->dest = win->info[j].id;
+ result = ProcShapeOffset (client);
+ if(result != Success) break;
+ }
+ return (result);
+}
+#endif
+
+
+static int
+ProcShapeQueryExtents (ClientPtr client)
+{
+ REQUEST(xShapeQueryExtentsReq);
+ WindowPtr pWin;
+ xShapeQueryExtentsReply rep;
+ BoxRec extents, *pExtents;
+ int n, rc;
+ RegionPtr region;
+
+ REQUEST_SIZE_MATCH (xShapeQueryExtentsReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ memset(&rep, 0, sizeof(xShapeQueryExtentsReply));
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.boundingShaped = (wBoundingShape(pWin) != 0);
+ rep.clipShaped = (wClipShape(pWin) != 0);
+ if ((region = wBoundingShape(pWin))) {
+ /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */
+ pExtents = REGION_EXTENTS(pWin->drawable.pScreen, region);
+ extents = *pExtents;
+ } else {
+ extents.x1 = -wBorderWidth (pWin);
+ extents.y1 = -wBorderWidth (pWin);
+ extents.x2 = pWin->drawable.width + wBorderWidth (pWin);
+ extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
+ }
+ rep.xBoundingShape = extents.x1;
+ rep.yBoundingShape = extents.y1;
+ rep.widthBoundingShape = extents.x2 - extents.x1;
+ rep.heightBoundingShape = extents.y2 - extents.y1;
+ if ((region = wClipShape(pWin))) {
+ /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */
+ pExtents = REGION_EXTENTS(pWin->drawable.pScreen, region);
+ extents = *pExtents;
+ } else {
+ extents.x1 = 0;
+ extents.y1 = 0;
+ extents.x2 = pWin->drawable.width;
+ extents.y2 = pWin->drawable.height;
+ }
+ rep.xClipShape = extents.x1;
+ rep.yClipShape = extents.y1;
+ rep.widthClipShape = extents.x2 - extents.x1;
+ rep.heightClipShape = extents.y2 - extents.y1;
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.xBoundingShape, n);
+ swaps(&rep.yBoundingShape, n);
+ swaps(&rep.widthBoundingShape, n);
+ swaps(&rep.heightBoundingShape, n);
+ swaps(&rep.xClipShape, n);
+ swaps(&rep.yClipShape, n);
+ swaps(&rep.widthClipShape, n);
+ swaps(&rep.heightClipShape, n);
+ }
+ WriteToClient(client, sizeof (xShapeQueryExtentsReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+/*ARGSUSED*/
+static int
+ShapeFreeClient (pointer data, XID id)
+{
+ ShapeEventPtr pShapeEvent;
+ WindowPtr pWin;
+ ShapeEventPtr *pHead, pCur, pPrev;
+ int rc;
+
+ pShapeEvent = (ShapeEventPtr) data;
+ pWin = pShapeEvent->window;
+ rc = dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id,
+ ShapeEventType, serverClient, DixReadAccess);
+ if (rc == Success) {
+ pPrev = 0;
+ for (pCur = *pHead; pCur && pCur != pShapeEvent; pCur=pCur->next)
+ pPrev = pCur;
+ if (pCur)
+ {
+ if (pPrev)
+ pPrev->next = pShapeEvent->next;
+ else
+ *pHead = pShapeEvent->next;
+ }
+ }
+ xfree ((pointer) pShapeEvent);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+ShapeFreeEvents (pointer data, XID id)
+{
+ ShapeEventPtr *pHead, pCur, pNext;
+
+ pHead = (ShapeEventPtr *) data;
+ for (pCur = *pHead; pCur; pCur = pNext) {
+ pNext = pCur->next;
+ FreeResource (pCur->clientResource, ClientType);
+ xfree ((pointer) pCur);
+ }
+ xfree ((pointer) pHead);
+ return 1;
+}
+
+static int
+ProcShapeSelectInput (ClientPtr client)
+{
+ REQUEST(xShapeSelectInputReq);
+ WindowPtr pWin;
+ ShapeEventPtr pShapeEvent, pNewShapeEvent, *pHead;
+ XID clientResource;
+ int rc;
+
+ REQUEST_SIZE_MATCH (xShapeSelectInputReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess);
+ if (rc != Success)
+ return rc;
+ rc = dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id,
+ ShapeEventType, client, DixWriteAccess);
+ if (rc != Success && rc != BadValue)
+ return rc;
+
+ switch (stuff->enable) {
+ case xTrue:
+ if (pHead) {
+
+ /* check for existing entry. */
+ for (pShapeEvent = *pHead;
+ pShapeEvent;
+ pShapeEvent = pShapeEvent->next)
+ {
+ if (pShapeEvent->client == client)
+ return Success;
+ }
+ }
+
+ /* build the entry */
+ pNewShapeEvent = xalloc (sizeof (ShapeEventRec));
+ if (!pNewShapeEvent)
+ return BadAlloc;
+ pNewShapeEvent->next = 0;
+ pNewShapeEvent->client = client;
+ pNewShapeEvent->window = pWin;
+ /*
+ * add a resource that will be deleted when
+ * the client goes away
+ */
+ clientResource = FakeClientID (client->index);
+ pNewShapeEvent->clientResource = clientResource;
+ if (!AddResource (clientResource, ClientType, (pointer)pNewShapeEvent))
+ return BadAlloc;
+ /*
+ * create a resource to contain a pointer to the list
+ * of clients selecting input. This must be indirect as
+ * the list may be arbitrarily rearranged which cannot be
+ * done through the resource database.
+ */
+ if (!pHead)
+ {
+ pHead = xalloc (sizeof (ShapeEventPtr));
+ if (!pHead ||
+ !AddResource (pWin->drawable.id, ShapeEventType, (pointer)pHead))
+ {
+ FreeResource (clientResource, RT_NONE);
+ return BadAlloc;
+ }
+ *pHead = 0;
+ }
+ pNewShapeEvent->next = *pHead;
+ *pHead = pNewShapeEvent;
+ break;
+ case xFalse:
+ /* delete the interest */
+ if (pHead) {
+ pNewShapeEvent = 0;
+ for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) {
+ if (pShapeEvent->client == client)
+ break;
+ pNewShapeEvent = pShapeEvent;
+ }
+ if (pShapeEvent) {
+ FreeResource (pShapeEvent->clientResource, ClientType);
+ if (pNewShapeEvent)
+ pNewShapeEvent->next = pShapeEvent->next;
+ else
+ *pHead = pShapeEvent->next;
+ xfree (pShapeEvent);
+ }
+ }
+ break;
+ default:
+ client->errorValue = stuff->enable;
+ return BadValue;
+ }
+ return Success;
+}
+
+/*
+ * deliver the event
+ */
+
+void
+SendShapeNotify (WindowPtr pWin, int which)
+{
+ ShapeEventPtr *pHead, pShapeEvent;
+ ClientPtr client;
+ xShapeNotifyEvent se;
+ BoxRec extents;
+ RegionPtr region;
+ BYTE shaped;
+ int rc;
+
+ rc = dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id,
+ ShapeEventType, serverClient, DixReadAccess);
+ if (rc != Success)
+ return;
+ switch (which) {
+ case ShapeBounding:
+ region = wBoundingShape(pWin);
+ if (region) {
+ extents = *REGION_EXTENTS(pWin->drawable.pScreen, region);
+ shaped = xTrue;
+ } else {
+ extents.x1 = -wBorderWidth (pWin);
+ extents.y1 = -wBorderWidth (pWin);
+ extents.x2 = pWin->drawable.width + wBorderWidth (pWin);
+ extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
+ shaped = xFalse;
+ }
+ break;
+ case ShapeClip:
+ region = wClipShape(pWin);
+ if (region) {
+ extents = *REGION_EXTENTS(pWin->drawable.pScreen, region);
+ shaped = xTrue;
+ } else {
+ extents.x1 = 0;
+ extents.y1 = 0;
+ extents.x2 = pWin->drawable.width;
+ extents.y2 = pWin->drawable.height;
+ shaped = xFalse;
+ }
+ break;
+ case ShapeInput:
+ region = wInputShape(pWin);
+ if (region) {
+ extents = *REGION_EXTENTS(pWin->drawable.pScreen, region);
+ shaped = xTrue;
+ } else {
+ extents.x1 = -wBorderWidth (pWin);
+ extents.y1 = -wBorderWidth (pWin);
+ extents.x2 = pWin->drawable.width + wBorderWidth (pWin);
+ extents.y2 = pWin->drawable.height + wBorderWidth (pWin);
+ shaped = xFalse;
+ }
+ break;
+ default:
+ return;
+ }
+ for (pShapeEvent = *pHead; pShapeEvent; pShapeEvent = pShapeEvent->next) {
+ client = pShapeEvent->client;
+ if (client == serverClient || client->clientGone)
+ continue;
+ se.type = ShapeNotify + ShapeEventBase;
+ se.kind = which;
+ se.window = pWin->drawable.id;
+ se.sequenceNumber = client->sequence;
+ se.x = extents.x1;
+ se.y = extents.y1;
+ se.width = extents.x2 - extents.x1;
+ se.height = extents.y2 - extents.y1;
+ se.time = currentTime.milliseconds;
+ se.shaped = shaped;
+ WriteEventsToClient (client, 1, (xEvent *) &se);
+ }
+}
+
+static int
+ProcShapeInputSelected (ClientPtr client)
+{
+ REQUEST(xShapeInputSelectedReq);
+ WindowPtr pWin;
+ ShapeEventPtr pShapeEvent, *pHead;
+ int enabled, rc;
+ xShapeInputSelectedReply rep;
+ int n;
+
+ REQUEST_SIZE_MATCH (xShapeInputSelectedReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ rc = dixLookupResourceByType((pointer *)&pHead, pWin->drawable.id,
+ ShapeEventType, client, DixReadAccess);
+ if (rc != Success && rc != BadValue)
+ return rc;
+ enabled = xFalse;
+ if (pHead) {
+ for (pShapeEvent = *pHead;
+ pShapeEvent;
+ pShapeEvent = pShapeEvent->next)
+ {
+ if (pShapeEvent->client == client) {
+ enabled = xTrue;
+ break;
+ }
+ }
+ }
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.enabled = enabled;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber, n);
+ swapl (&rep.length, n);
+ }
+ WriteToClient (client, sizeof (xShapeInputSelectedReply), (char *) &rep);
+ return (client->noClientException);
+}
+
+static int
+ProcShapeGetRectangles (ClientPtr client)
+{
+ REQUEST(xShapeGetRectanglesReq);
+ WindowPtr pWin;
+ xShapeGetRectanglesReply rep;
+ xRectangle *rects;
+ int nrects, i, rc;
+ RegionPtr region;
+ int n;
+
+ REQUEST_SIZE_MATCH(xShapeGetRectanglesReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ switch (stuff->kind) {
+ case ShapeBounding:
+ region = wBoundingShape(pWin);
+ break;
+ case ShapeClip:
+ region = wClipShape(pWin);
+ break;
+ case ShapeInput:
+ region = wInputShape (pWin);
+ break;
+ default:
+ client->errorValue = stuff->kind;
+ return BadValue;
+ }
+ if (!region) {
+ nrects = 1;
+ rects = xalloc (sizeof (xRectangle));
+ if (!rects)
+ return BadAlloc;
+ switch (stuff->kind) {
+ case ShapeBounding:
+ rects->x = - (int) wBorderWidth (pWin);
+ rects->y = - (int) wBorderWidth (pWin);
+ rects->width = pWin->drawable.width + wBorderWidth (pWin);
+ rects->height = pWin->drawable.height + wBorderWidth (pWin);
+ break;
+ case ShapeClip:
+ rects->x = 0;
+ rects->y = 0;
+ rects->width = pWin->drawable.width;
+ rects->height = pWin->drawable.height;
+ break;
+ case ShapeInput:
+ rects->x = - (int) wBorderWidth (pWin);
+ rects->y = - (int) wBorderWidth (pWin);
+ rects->width = pWin->drawable.width + wBorderWidth (pWin);
+ rects->height = pWin->drawable.height + wBorderWidth (pWin);
+ break;
+ }
+ } else {
+ BoxPtr box;
+ nrects = REGION_NUM_RECTS(region);
+ box = REGION_RECTS(region);
+ rects = xalloc (nrects * sizeof (xRectangle));
+ if (!rects && nrects)
+ return BadAlloc;
+ for (i = 0; i < nrects; i++, box++) {
+ rects[i].x = box->x1;
+ rects[i].y = box->y1;
+ rects[i].width = box->x2 - box->x1;
+ rects[i].height = box->y2 - box->y1;
+ }
+ }
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = bytes_to_int32(nrects * sizeof (xRectangle));
+ rep.ordering = YXBanded;
+ rep.nrects = nrects;
+ if (client->swapped) {
+ swaps (&rep.sequenceNumber, n);
+ swapl (&rep.length, n);
+ swapl (&rep.nrects, n);
+ SwapShorts ((short *)rects, (unsigned long)nrects * 4);
+ }
+ WriteToClient (client, sizeof (rep), (char *) &rep);
+ WriteToClient (client, nrects * sizeof (xRectangle), (char *) rects);
+ xfree (rects);
+ return client->noClientException;
+}
+
+static int
+ProcShapeDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_ShapeQueryVersion:
+ return ProcShapeQueryVersion (client);
+ case X_ShapeRectangles:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShapeRectangles (client);
+ else
+#endif
+ return ProcShapeRectangles (client);
+ case X_ShapeMask:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShapeMask (client);
+ else
+#endif
+ return ProcShapeMask (client);
+ case X_ShapeCombine:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShapeCombine (client);
+ else
+#endif
+ return ProcShapeCombine (client);
+ case X_ShapeOffset:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShapeOffset (client);
+ else
+#endif
+ return ProcShapeOffset (client);
+ case X_ShapeQueryExtents:
+ return ProcShapeQueryExtents (client);
+ case X_ShapeSelectInput:
+ return ProcShapeSelectInput (client);
+ case X_ShapeInputSelected:
+ return ProcShapeInputSelected (client);
+ case X_ShapeGetRectangles:
+ return ProcShapeGetRectangles (client);
+ default:
+ return BadRequest;
+ }
+}
+
+static void
+SShapeNotifyEvent(xShapeNotifyEvent *from, xShapeNotifyEvent *to)
+{
+ to->type = from->type;
+ to->kind = from->kind;
+ cpswapl (from->window, to->window);
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswaps (from->x, to->x);
+ cpswaps (from->y, to->y);
+ cpswaps (from->width, to->width);
+ cpswaps (from->height, to->height);
+ cpswapl (from->time, to->time);
+ to->shaped = from->shaped;
+}
+
+static int
+SProcShapeQueryVersion (ClientPtr client)
+{
+ int n;
+ REQUEST (xShapeQueryVersionReq);
+
+ swaps (&stuff->length, n);
+ return ProcShapeQueryVersion (client);
+}
+
+static int
+SProcShapeRectangles (ClientPtr client)
+{
+ char n;
+ REQUEST (xShapeRectanglesReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE (xShapeRectanglesReq);
+ swapl (&stuff->dest, n);
+ swaps (&stuff->xOff, n);
+ swaps (&stuff->yOff, n);
+ SwapRestS(stuff);
+ return ProcShapeRectangles (client);
+}
+
+static int
+SProcShapeMask (ClientPtr client)
+{
+ char n;
+ REQUEST (xShapeMaskReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xShapeMaskReq);
+ swapl (&stuff->dest, n);
+ swaps (&stuff->xOff, n);
+ swaps (&stuff->yOff, n);
+ swapl (&stuff->src, n);
+ return ProcShapeMask (client);
+}
+
+static int
+SProcShapeCombine (ClientPtr client)
+{
+ char n;
+ REQUEST (xShapeCombineReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xShapeCombineReq);
+ swapl (&stuff->dest, n);
+ swaps (&stuff->xOff, n);
+ swaps (&stuff->yOff, n);
+ swapl (&stuff->src, n);
+ return ProcShapeCombine (client);
+}
+
+static int
+SProcShapeOffset (ClientPtr client)
+{
+ char n;
+ REQUEST (xShapeOffsetReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xShapeOffsetReq);
+ swapl (&stuff->dest, n);
+ swaps (&stuff->xOff, n);
+ swaps (&stuff->yOff, n);
+ return ProcShapeOffset (client);
+}
+
+static int
+SProcShapeQueryExtents (ClientPtr client)
+{
+ char n;
+ REQUEST (xShapeQueryExtentsReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xShapeQueryExtentsReq);
+ swapl (&stuff->window, n);
+ return ProcShapeQueryExtents (client);
+}
+
+static int
+SProcShapeSelectInput (ClientPtr client)
+{
+ char n;
+ REQUEST (xShapeSelectInputReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xShapeSelectInputReq);
+ swapl (&stuff->window, n);
+ return ProcShapeSelectInput (client);
+}
+
+static int
+SProcShapeInputSelected (ClientPtr client)
+{
+ int n;
+ REQUEST (xShapeInputSelectedReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xShapeInputSelectedReq);
+ swapl (&stuff->window, n);
+ return ProcShapeInputSelected (client);
+}
+
+static int
+SProcShapeGetRectangles (ClientPtr client)
+{
+ REQUEST(xShapeGetRectanglesReq);
+ char n;
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xShapeGetRectanglesReq);
+ swapl (&stuff->window, n);
+ return ProcShapeGetRectangles (client);
+}
+
+static int
+SProcShapeDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data) {
+ case X_ShapeQueryVersion:
+ return SProcShapeQueryVersion (client);
+ case X_ShapeRectangles:
+ return SProcShapeRectangles (client);
+ case X_ShapeMask:
+ return SProcShapeMask (client);
+ case X_ShapeCombine:
+ return SProcShapeCombine (client);
+ case X_ShapeOffset:
+ return SProcShapeOffset (client);
+ case X_ShapeQueryExtents:
+ return SProcShapeQueryExtents (client);
+ case X_ShapeSelectInput:
+ return SProcShapeSelectInput (client);
+ case X_ShapeInputSelected:
+ return SProcShapeInputSelected (client);
+ case X_ShapeGetRectangles:
+ return SProcShapeGetRectangles (client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/xorg-server/Xext/shm.c b/xorg-server/Xext/shm.c index ab58c2750..d7572c24a 100644 --- a/xorg-server/Xext/shm.c +++ b/xorg-server/Xext/shm.c @@ -1,1329 +1,1348 @@ -/************************************************************ - -Copyright 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. - -********************************************************/ - -/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */ - - -#define SHM - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <sys/types.h> -#include <sys/ipc.h> -#include <sys/shm.h> -#include <unistd.h> -#include <sys/stat.h> -#include <X11/X.h> -#include <X11/Xproto.h> -#include "misc.h" -#include "os.h" -#include "dixstruct.h" -#include "resource.h" -#include "scrnintstr.h" -#include "windowstr.h" -#include "pixmapstr.h" -#include "gcstruct.h" -#include "extnsionst.h" -#include "servermd.h" -#include "shmint.h" -#include "xace.h" -#include <X11/extensions/shmproto.h> -#include <X11/Xfuncproto.h> -#include "protocol-versions.h" - -/* Needed for Solaris cross-zone shared memory extension */ -#ifdef HAVE_SHMCTL64 -#include <sys/ipc_impl.h> -#define SHMSTAT(id, buf) shmctl64(id, IPC_STAT64, buf) -#define SHMSTAT_TYPE struct shmid_ds64 -#define SHMPERM_TYPE struct ipc_perm64 -#define SHM_PERM(buf) buf.shmx_perm -#define SHM_SEGSZ(buf) buf.shmx_segsz -#define SHMPERM_UID(p) p->ipcx_uid -#define SHMPERM_CUID(p) p->ipcx_cuid -#define SHMPERM_GID(p) p->ipcx_gid -#define SHMPERM_CGID(p) p->ipcx_cgid -#define SHMPERM_MODE(p) p->ipcx_mode -#define SHMPERM_ZONEID(p) p->ipcx_zoneid -#else -#define SHMSTAT(id, buf) shmctl(id, IPC_STAT, buf) -#define SHMSTAT_TYPE struct shmid_ds -#define SHMPERM_TYPE struct ipc_perm -#define SHM_PERM(buf) buf.shm_perm -#define SHM_SEGSZ(buf) buf.shm_segsz -#define SHMPERM_UID(p) p->uid -#define SHMPERM_CUID(p) p->cuid -#define SHMPERM_GID(p) p->gid -#define SHMPERM_CGID(p) p->cgid -#define SHMPERM_MODE(p) p->mode -#endif - -#ifdef PANORAMIX -#include "panoramiX.h" -#include "panoramiXsrv.h" -#endif - -#include "modinit.h" - -typedef struct _ShmDesc { - struct _ShmDesc *next; - int shmid; - int refcnt; - char *addr; - Bool writable; - unsigned long size; -} ShmDescRec, *ShmDescPtr; - -typedef struct _ShmScrPrivateRec { - CloseScreenProcPtr CloseScreen; - ShmFuncsPtr shmFuncs; - DestroyPixmapProcPtr destroyPixmap; -} ShmScrPrivateRec; - -static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS); -static int ShmDetachSegment( - pointer /* value */, - XID /* shmseg */ - ); -static void ShmResetProc( - ExtensionEntry * /* extEntry */ - ); -static void SShmCompletionEvent( - xShmCompletionEvent * /* from */, - xShmCompletionEvent * /* to */ - ); - -static Bool ShmDestroyPixmap (PixmapPtr pPixmap); - -static DISPATCH_PROC(ProcShmAttach); -static DISPATCH_PROC(ProcShmCreatePixmap); -static DISPATCH_PROC(ProcShmDetach); -static DISPATCH_PROC(ProcShmDispatch); -static DISPATCH_PROC(ProcShmGetImage); -static DISPATCH_PROC(ProcShmPutImage); -static DISPATCH_PROC(ProcShmQueryVersion); -static DISPATCH_PROC(SProcShmAttach); -static DISPATCH_PROC(SProcShmCreatePixmap); -static DISPATCH_PROC(SProcShmDetach); -static DISPATCH_PROC(SProcShmDispatch); -static DISPATCH_PROC(SProcShmGetImage); -static DISPATCH_PROC(SProcShmPutImage); -static DISPATCH_PROC(SProcShmQueryVersion); - -static unsigned char ShmReqCode; -int ShmCompletionCode; -int BadShmSegCode; -RESTYPE ShmSegType; -static ShmDescPtr Shmsegs; -static Bool sharedPixmaps; -static int shmScrPrivateKeyIndex; -static DevPrivateKey shmScrPrivateKey = &shmScrPrivateKeyIndex; -static int shmPixmapPrivateIndex; -static DevPrivateKey shmPixmapPrivate = &shmPixmapPrivateIndex; -static ShmFuncs miFuncs = {NULL, NULL}; -static ShmFuncs fbFuncs = {fbShmCreatePixmap, NULL}; - -#define ShmGetScreenPriv(s) ((ShmScrPrivateRec *)dixLookupPrivate(&(s)->devPrivates, shmScrPrivateKey)) - -#define VERIFY_SHMSEG(shmseg,shmdesc,client) \ -{ \ - int rc; \ - rc = dixLookupResourceByType((pointer *)&(shmdesc), shmseg, ShmSegType, \ - client, DixReadAccess); \ - if (rc != Success) \ - return (rc == BadValue) ? BadShmSegCode : rc; \ -} - -#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \ -{ \ - VERIFY_SHMSEG(shmseg, shmdesc, client); \ - if ((offset & 3) || (offset > shmdesc->size)) \ - { \ - client->errorValue = offset; \ - return BadValue; \ - } \ - if (needwrite && !shmdesc->writable) \ - return BadAccess; \ -} - -#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \ -{ \ - if ((offset + len) > shmdesc->size) \ - { \ - return BadAccess; \ - } \ -} - - -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__DragonFly__) -#include <sys/signal.h> - -static Bool badSysCall = FALSE; - -static void -SigSysHandler(int signo) -{ - badSysCall = TRUE; -} - -static Bool CheckForShmSyscall(void) -{ - void (*oldHandler)(); - int shmid = -1; - - /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */ - oldHandler = signal(SIGSYS, SigSysHandler); - - badSysCall = FALSE; - shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT); - - if (shmid != -1) - { - /* Successful allocation - clean up */ - shmctl(shmid, IPC_RMID, NULL); - } - else - { - /* Allocation failed */ - badSysCall = TRUE; - } - signal(SIGSYS, oldHandler); - return(!badSysCall); -} - -#define MUST_CHECK_FOR_SHM_SYSCALL - -#endif - -static Bool -ShmCloseScreen(int i, ScreenPtr pScreen) -{ - ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen); - pScreen->CloseScreen = screen_priv->CloseScreen; - dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, NULL); - xfree (screen_priv); - return (*pScreen->CloseScreen) (i, pScreen); -} - -static ShmScrPrivateRec * -ShmInitScreenPriv(ScreenPtr pScreen) -{ - ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen); - if (!screen_priv) - { - screen_priv = xcalloc (1, sizeof (ShmScrPrivateRec)); - screen_priv->CloseScreen = pScreen->CloseScreen; - dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, screen_priv); - pScreen->CloseScreen = ShmCloseScreen; - } - return screen_priv; -} - -void -ShmExtensionInit(INITARGS) -{ - ExtensionEntry *extEntry; - int i; - -#ifdef MUST_CHECK_FOR_SHM_SYSCALL - if (!CheckForShmSyscall()) - { - ErrorF("MIT-SHM extension disabled due to lack of kernel support\n"); - return; - } -#endif - - sharedPixmaps = xFalse; - { - sharedPixmaps = xTrue; - for (i = 0; i < screenInfo.numScreens; i++) - { - ShmScrPrivateRec *screen_priv = ShmInitScreenPriv(screenInfo.screens[i]); - if (!screen_priv->shmFuncs) - screen_priv->shmFuncs = &miFuncs; - if (!screen_priv->shmFuncs->CreatePixmap) - sharedPixmaps = xFalse; - } - if (sharedPixmaps) - for (i = 0; i < screenInfo.numScreens; i++) - { - ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(screenInfo.screens[i]); - screen_priv->destroyPixmap = screenInfo.screens[i]->DestroyPixmap; - screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap; - } - } - ShmSegType = CreateNewResourceType(ShmDetachSegment, "ShmSeg"); - if (ShmSegType && - (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors, - ProcShmDispatch, SProcShmDispatch, - ShmResetProc, StandardMinorOpcode))) - { - ShmReqCode = (unsigned char)extEntry->base; - ShmCompletionCode = extEntry->eventBase; - BadShmSegCode = extEntry->errorBase; - EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent; - } -} - -/*ARGSUSED*/ -static void -ShmResetProc(ExtensionEntry *extEntry) -{ - int i; - for (i = 0; i < screenInfo.numScreens; i++) - ShmRegisterFuncs(screenInfo.screens[i], NULL); -} - -void -ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs) -{ - ShmInitScreenPriv(pScreen)->shmFuncs = funcs; -} - -static Bool -ShmDestroyPixmap (PixmapPtr pPixmap) -{ - ScreenPtr pScreen = pPixmap->drawable.pScreen; - ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen); - Bool ret; - if (pPixmap->refcnt == 1) - { - ShmDescPtr shmdesc; - shmdesc = (ShmDescPtr)dixLookupPrivate(&pPixmap->devPrivates, - shmPixmapPrivate); - if (shmdesc) - ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id); - } - - pScreen->DestroyPixmap = screen_priv->destroyPixmap; - ret = (*pScreen->DestroyPixmap) (pPixmap); - screen_priv->destroyPixmap = pScreen->DestroyPixmap; - pScreen->DestroyPixmap = ShmDestroyPixmap; - return ret; -} - -void -ShmRegisterFbFuncs(ScreenPtr pScreen) -{ - ShmRegisterFuncs(pScreen, &fbFuncs); -} - -static int -ProcShmQueryVersion(ClientPtr client) -{ - xShmQueryVersionReply rep; - int n; - - REQUEST_SIZE_MATCH(xShmQueryVersionReq); - memset(&rep, 0, sizeof(xShmQueryVersionReply)); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.sharedPixmaps = sharedPixmaps; - rep.pixmapFormat = sharedPixmaps ? ZPixmap : 0; - rep.majorVersion = SERVER_SHM_MAJOR_VERSION; - rep.minorVersion = SERVER_SHM_MINOR_VERSION; - rep.uid = geteuid(); - rep.gid = getegid(); - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - swaps(&rep.majorVersion, n); - swaps(&rep.minorVersion, n); - swaps(&rep.uid, n); - swaps(&rep.gid, n); - } - WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep); - return (client->noClientException); -} - -/* - * Simulate the access() system call for a shared memory segement, - * using the credentials from the client if available - */ -static int -shm_access(ClientPtr client, SHMPERM_TYPE *perm, int readonly) -{ - int uid, gid; - mode_t mask; - int uidset = 0, gidset = 0; - LocalClientCredRec *lcc; - - if (GetLocalClientCreds(client, &lcc) != -1) { - - if (lcc->fieldsSet & LCC_UID_SET) { - uid = lcc->euid; - uidset = 1; - } - if (lcc->fieldsSet & LCC_GID_SET) { - gid = lcc->egid; - gidset = 1; - } - -#if defined(HAVE_GETZONEID) && defined(SHMPERM_ZONEID) - if ( ((lcc->fieldsSet & LCC_ZID_SET) == 0) || (lcc->zoneid == -1) - || (lcc->zoneid != SHMPERM_ZONEID(perm))) { - uidset = 0; - gidset = 0; - } -#endif - FreeLocalClientCreds(lcc); - - if (uidset) { - /* User id 0 always gets access */ - if (uid == 0) { - return 0; - } - /* Check the owner */ - if (SHMPERM_UID(perm) == uid || SHMPERM_CUID(perm) == uid) { - mask = S_IRUSR; - if (!readonly) { - mask |= S_IWUSR; - } - return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1; - } - } - - if (gidset) { - /* Check the group */ - if (SHMPERM_GID(perm) == gid || SHMPERM_CGID(perm) == gid) { - mask = S_IRGRP; - if (!readonly) { - mask |= S_IWGRP; - } - return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1; - } - } - } - /* Otherwise, check everyone else */ - mask = S_IROTH; - if (!readonly) { - mask |= S_IWOTH; - } - return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1; -} - -static int -ProcShmAttach(ClientPtr client) -{ - SHMSTAT_TYPE buf; - ShmDescPtr shmdesc; - REQUEST(xShmAttachReq); - - REQUEST_SIZE_MATCH(xShmAttachReq); - LEGAL_NEW_RESOURCE(stuff->shmseg, client); - if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse)) - { - client->errorValue = stuff->readOnly; - return(BadValue); - } - for (shmdesc = Shmsegs; - shmdesc && (shmdesc->shmid != stuff->shmid); - shmdesc = shmdesc->next) - ; - if (shmdesc) - { - if (!stuff->readOnly && !shmdesc->writable) - return BadAccess; - shmdesc->refcnt++; - } - else - { - shmdesc = xalloc(sizeof(ShmDescRec)); - if (!shmdesc) - return BadAlloc; - shmdesc->addr = shmat(stuff->shmid, 0, - stuff->readOnly ? SHM_RDONLY : 0); - if ((shmdesc->addr == ((char *)-1)) || - SHMSTAT(stuff->shmid, &buf)) - { - xfree(shmdesc); - return BadAccess; - } - - /* The attach was performed with root privs. We must - * do manual checking of access rights for the credentials - * of the client */ - - if (shm_access(client, &(SHM_PERM(buf)), stuff->readOnly) == -1) { - shmdt(shmdesc->addr); - xfree(shmdesc); - return BadAccess; - } - - shmdesc->shmid = stuff->shmid; - shmdesc->refcnt = 1; - shmdesc->writable = !stuff->readOnly; - shmdesc->size = SHM_SEGSZ(buf); - shmdesc->next = Shmsegs; - Shmsegs = shmdesc; - } - if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc)) - return BadAlloc; - return(client->noClientException); -} - -/*ARGSUSED*/ -static int -ShmDetachSegment(pointer value, /* must conform to DeleteType */ - XID shmseg) -{ - ShmDescPtr shmdesc = (ShmDescPtr)value; - ShmDescPtr *prev; - - if (--shmdesc->refcnt) - return TRUE; - shmdt(shmdesc->addr); - for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next) - ; - *prev = shmdesc->next; - xfree(shmdesc); - return Success; -} - -static int -ProcShmDetach(ClientPtr client) -{ - ShmDescPtr shmdesc; - REQUEST(xShmDetachReq); - - REQUEST_SIZE_MATCH(xShmDetachReq); - VERIFY_SHMSEG(stuff->shmseg, shmdesc, client); - FreeResource(stuff->shmseg, RT_NONE); - return(client->noClientException); -} - -/* - * If the given request doesn't exactly match PutImage's constraints, - * wrap the image in a scratch pixmap header and let CopyArea sort it out. - */ -static void -doShmPutImage(DrawablePtr dst, GCPtr pGC, - int depth, unsigned int format, - int w, int h, int sx, int sy, int sw, int sh, int dx, int dy, - char *data) -{ - PixmapPtr pPixmap; - - if (format == ZPixmap || depth == 1) { - pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth, - BitsPerPixel(depth), - PixmapBytePad(w, depth), - data); - if (!pPixmap) - return; - pGC->ops->CopyArea((DrawablePtr)pPixmap, dst, pGC, sx, sy, sw, sh, dx, dy); - FreeScratchPixmapHeader(pPixmap); - } else { - GCPtr putGC = GetScratchGC(depth, dst->pScreen); - - if (!putGC) - return; - - pPixmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth, - CREATE_PIXMAP_USAGE_SCRATCH); - if (!pPixmap) { - FreeScratchGC(putGC); - return; - } - ValidateGC(&pPixmap->drawable, putGC); - (*putGC->ops->PutImage)(&pPixmap->drawable, putGC, depth, -sx, -sy, w, h, 0, - (format == XYPixmap) ? XYPixmap : ZPixmap, data); - FreeScratchGC(putGC); - if (format == XYBitmap) - (void)(*pGC->ops->CopyPlane)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh, - dx, dy, 1L); - else - (void)(*pGC->ops->CopyArea)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh, - dx, dy); - (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); - } -} - -#ifdef PANORAMIX -static int -ProcPanoramiXShmPutImage(ClientPtr client) -{ - int j, result, orig_x, orig_y; - PanoramiXRes *draw, *gc; - Bool sendEvent, isRoot; - - REQUEST(xShmPutImageReq); - REQUEST_SIZE_MATCH(xShmPutImageReq); - - result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, - XRC_DRAWABLE, client, DixWriteAccess); - if (result != Success) - return (result == BadValue) ? BadDrawable : result; - - result = dixLookupResourceByType((pointer *)&gc, stuff->gc, - XRT_GC, client, DixReadAccess); - if (result != Success) - return (result == BadValue) ? BadGC : result; - - isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; - - orig_x = stuff->dstX; - orig_y = stuff->dstY; - sendEvent = stuff->sendEvent; - stuff->sendEvent = 0; - FOR_NSCREENS(j) { - if(!j) stuff->sendEvent = sendEvent; - stuff->drawable = draw->info[j].id; - stuff->gc = gc->info[j].id; - if (isRoot) { - stuff->dstX = orig_x - panoramiXdataPtr[j].x; - stuff->dstY = orig_y - panoramiXdataPtr[j].y; - } - result = ProcShmPutImage(client); - if(result != client->noClientException) break; - } - return(result); -} - -static int -ProcPanoramiXShmGetImage(ClientPtr client) -{ - PanoramiXRes *draw; - DrawablePtr *drawables; - DrawablePtr pDraw; - xShmGetImageReply xgi; - ShmDescPtr shmdesc; - int i, x, y, w, h, format, rc; - Mask plane = 0, planemask; - long lenPer = 0, length, widthBytesLine; - Bool isRoot; - - REQUEST(xShmGetImageReq); - - REQUEST_SIZE_MATCH(xShmGetImageReq); - - if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) { - client->errorValue = stuff->format; - return(BadValue); - } - - rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, - XRC_DRAWABLE, client, DixWriteAccess); - if (rc != Success) - return (rc == BadValue) ? BadDrawable : rc; - - if (draw->type == XRT_PIXMAP) - return ProcShmGetImage(client); - - rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, - DixReadAccess); - if (rc != Success) - return rc; - - VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); - - x = stuff->x; - y = stuff->y; - w = stuff->width; - h = stuff->height; - format = stuff->format; - planemask = stuff->planeMask; - - isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root; - - if(isRoot) { - if( /* check for being onscreen */ - x < 0 || x + w > PanoramiXPixWidth || - y < 0 || y + h > PanoramiXPixHeight ) - return(BadMatch); - } else { - if( /* check for being onscreen */ - panoramiXdataPtr[0].x + pDraw->x + x < 0 || - panoramiXdataPtr[0].x + pDraw->x + x + w > PanoramiXPixWidth || - panoramiXdataPtr[0].y + pDraw->y + y < 0 || - panoramiXdataPtr[0].y + pDraw->y + y + h > PanoramiXPixHeight || - /* check for being inside of border */ - x < - wBorderWidth((WindowPtr)pDraw) || - x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || - y < -wBorderWidth((WindowPtr)pDraw) || - y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height) - return(BadMatch); - } - - drawables = xcalloc(PanoramiXNumScreens, sizeof(DrawablePtr)); - if(!drawables) - return(BadAlloc); - - drawables[0] = pDraw; - for(i = 1; i < PanoramiXNumScreens; i++) { - rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0, - DixReadAccess); - if (rc != Success) - { - xfree(drawables); - return rc; - } - } - - xgi.visual = wVisual(((WindowPtr)pDraw)); - xgi.type = X_Reply; - xgi.length = 0; - xgi.sequenceNumber = client->sequence; - xgi.depth = pDraw->depth; - - if(format == ZPixmap) { - widthBytesLine = PixmapBytePad(w, pDraw->depth); - length = widthBytesLine * h; - } else { - widthBytesLine = PixmapBytePad(w, 1); - lenPer = widthBytesLine * h; - plane = ((Mask)1) << (pDraw->depth - 1); - length = lenPer * Ones(planemask & (plane | (plane - 1))); - } - - VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client); - xgi.size = length; - - if (length == 0) {/* nothing to do */ } - else if (format == ZPixmap) { - XineramaGetImageData(drawables, x, y, w, h, format, planemask, - shmdesc->addr + stuff->offset, - widthBytesLine, isRoot); - } else { - - length = stuff->offset; - for (; plane; plane >>= 1) { - if (planemask & plane) { - XineramaGetImageData(drawables, x, y, w, h, - format, plane, shmdesc->addr + length, - widthBytesLine, isRoot); - length += lenPer; - } - } - } - xfree(drawables); - - if (client->swapped) { - int n; - swaps(&xgi.sequenceNumber, n); - swapl(&xgi.length, n); - swapl(&xgi.visual, n); - swapl(&xgi.size, n); - } - WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi); - - return(client->noClientException); -} - -static int -ProcPanoramiXShmCreatePixmap(ClientPtr client) -{ - ScreenPtr pScreen = NULL; - PixmapPtr pMap = NULL; - DrawablePtr pDraw; - DepthPtr pDepth; - int i, j, result, rc; - ShmDescPtr shmdesc; - REQUEST(xShmCreatePixmapReq); - unsigned int width, height, depth; - unsigned long size; - PanoramiXRes *newPix; - - REQUEST_SIZE_MATCH(xShmCreatePixmapReq); - client->errorValue = stuff->pid; - if (!sharedPixmaps) - return BadImplementation; - LEGAL_NEW_RESOURCE(stuff->pid, client); - rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, - DixGetAttrAccess); - if (rc != Success) - return rc; - - VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); - - width = stuff->width; - height = stuff->height; - depth = stuff->depth; - if (!width || !height || !depth) - { - client->errorValue = 0; - return BadValue; - } - if (width > 32767 || height > 32767) - return BadAlloc; - - if (stuff->depth != 1) - { - pDepth = pDraw->pScreen->allowedDepths; - for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) - if (pDepth->depth == stuff->depth) - goto CreatePmap; - client->errorValue = stuff->depth; - return BadValue; - } - -CreatePmap: - size = PixmapBytePad(width, depth) * height; - if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) { - if (size < width * height) - return BadAlloc; - } - /* thankfully, offset is unsigned */ - if (stuff->offset + size < size) - return BadAlloc; - - VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client); - - if(!(newPix = xalloc(sizeof(PanoramiXRes)))) - return BadAlloc; - - newPix->type = XRT_PIXMAP; - newPix->u.pix.shared = TRUE; - newPix->info[0].id = stuff->pid; - for(j = 1; j < PanoramiXNumScreens; j++) - newPix->info[j].id = FakeClientID(client->index); - - result = (client->noClientException); - - FOR_NSCREENS(j) { - ShmScrPrivateRec *screen_priv; - pScreen = screenInfo.screens[j]; - - screen_priv = ShmGetScreenPriv(pScreen); - pMap = (*screen_priv->shmFuncs->CreatePixmap)(pScreen, - stuff->width, stuff->height, stuff->depth, - shmdesc->addr + stuff->offset); - - if (pMap) { - dixSetPrivate(&pMap->devPrivates, shmPixmapPrivate, shmdesc); - shmdesc->refcnt++; - pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; - pMap->drawable.id = newPix->info[j].id; - if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) { - (*pScreen->DestroyPixmap)(pMap); - result = BadAlloc; - break; - } - } else { - result = BadAlloc; - break; - } - } - - if(result == BadAlloc) { - while(j--) { - (*pScreen->DestroyPixmap)(pMap); - FreeResource(newPix->info[j].id, RT_NONE); - } - xfree(newPix); - } else - AddResource(stuff->pid, XRT_PIXMAP, newPix); - - return result; -} - -#endif - -static int -ProcShmPutImage(ClientPtr client) -{ - GCPtr pGC; - DrawablePtr pDraw; - long length; - ShmDescPtr shmdesc; - REQUEST(xShmPutImageReq); - - REQUEST_SIZE_MATCH(xShmPutImageReq); - VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client); - if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse)) - return BadValue; - if (stuff->format == XYBitmap) - { - if (stuff->depth != 1) - return BadMatch; - length = PixmapBytePad(stuff->totalWidth, 1); - } - else if (stuff->format == XYPixmap) - { - if (pDraw->depth != stuff->depth) - return BadMatch; - length = PixmapBytePad(stuff->totalWidth, 1); - length *= stuff->depth; - } - else if (stuff->format == ZPixmap) - { - if (pDraw->depth != stuff->depth) - return BadMatch; - length = PixmapBytePad(stuff->totalWidth, stuff->depth); - } - else - { - client->errorValue = stuff->format; - return BadValue; - } - - /* - * There's a potential integer overflow in this check: - * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight, - * client); - * the version below ought to avoid it - */ - if (stuff->totalHeight != 0 && - length > (shmdesc->size - stuff->offset)/stuff->totalHeight) { - client->errorValue = stuff->totalWidth; - return BadValue; - } - if (stuff->srcX > stuff->totalWidth) - { - client->errorValue = stuff->srcX; - return BadValue; - } - if (stuff->srcY > stuff->totalHeight) - { - client->errorValue = stuff->srcY; - return BadValue; - } - if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth) - { - client->errorValue = stuff->srcWidth; - return BadValue; - } - if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight) - { - client->errorValue = stuff->srcHeight; - return BadValue; - } - - if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) || - ((stuff->format != ZPixmap) && - (stuff->srcX < screenInfo.bitmapScanlinePad) && - ((stuff->format == XYBitmap) || - ((stuff->srcY == 0) && - (stuff->srcHeight == stuff->totalHeight))))) && - ((stuff->srcX + stuff->srcWidth) == stuff->totalWidth)) - (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, - stuff->dstX, stuff->dstY, - stuff->totalWidth, stuff->srcHeight, - stuff->srcX, stuff->format, - shmdesc->addr + stuff->offset + - (stuff->srcY * length)); - else - doShmPutImage(pDraw, pGC, stuff->depth, stuff->format, - stuff->totalWidth, stuff->totalHeight, - stuff->srcX, stuff->srcY, - stuff->srcWidth, stuff->srcHeight, - stuff->dstX, stuff->dstY, - shmdesc->addr + stuff->offset); - - if (stuff->sendEvent) - { - xShmCompletionEvent ev; - - ev.type = ShmCompletionCode; - ev.drawable = stuff->drawable; - ev.sequenceNumber = client->sequence; - ev.minorEvent = X_ShmPutImage; - ev.majorEvent = ShmReqCode; - ev.shmseg = stuff->shmseg; - ev.offset = stuff->offset; - WriteEventsToClient(client, 1, (xEvent *) &ev); - } - - return (client->noClientException); -} - - - -static int -ProcShmGetImage(ClientPtr client) -{ - DrawablePtr pDraw; - long lenPer = 0, length; - Mask plane = 0; - xShmGetImageReply xgi; - ShmDescPtr shmdesc; - int n, rc; - - REQUEST(xShmGetImageReq); - - REQUEST_SIZE_MATCH(xShmGetImageReq); - if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) - { - client->errorValue = stuff->format; - return(BadValue); - } - rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, - DixReadAccess); - if (rc != Success) - return rc; - VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); - if (pDraw->type == DRAWABLE_WINDOW) - { - if( /* check for being viewable */ - !((WindowPtr) pDraw)->realized || - /* check for being on screen */ - pDraw->x + stuff->x < 0 || - pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width || - pDraw->y + stuff->y < 0 || - pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height || - /* check for being inside of border */ - stuff->x < - wBorderWidth((WindowPtr)pDraw) || - stuff->x + (int)stuff->width > - wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || - stuff->y < -wBorderWidth((WindowPtr)pDraw) || - stuff->y + (int)stuff->height > - wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height - ) - return(BadMatch); - xgi.visual = wVisual(((WindowPtr)pDraw)); - } - else - { - if (stuff->x < 0 || - stuff->x+(int)stuff->width > pDraw->width || - stuff->y < 0 || - stuff->y+(int)stuff->height > pDraw->height - ) - return(BadMatch); - xgi.visual = None; - } - xgi.type = X_Reply; - xgi.length = 0; - xgi.sequenceNumber = client->sequence; - xgi.depth = pDraw->depth; - if(stuff->format == ZPixmap) - { - length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height; - } - else - { - lenPer = PixmapBytePad(stuff->width, 1) * stuff->height; - plane = ((Mask)1) << (pDraw->depth - 1); - /* only planes asked for */ - length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1))); - } - - VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client); - xgi.size = length; - - if (length == 0) - { - /* nothing to do */ - } - else if (stuff->format == ZPixmap) - { - (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y, - stuff->width, stuff->height, - stuff->format, stuff->planeMask, - shmdesc->addr + stuff->offset); - } - else - { - - length = stuff->offset; - for (; plane; plane >>= 1) - { - if (stuff->planeMask & plane) - { - (*pDraw->pScreen->GetImage)(pDraw, - stuff->x, stuff->y, - stuff->width, stuff->height, - stuff->format, plane, - shmdesc->addr + length); - length += lenPer; - } - } - } - - if (client->swapped) { - swaps(&xgi.sequenceNumber, n); - swapl(&xgi.length, n); - swapl(&xgi.visual, n); - swapl(&xgi.size, n); - } - WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi); - - return(client->noClientException); -} - -static PixmapPtr -fbShmCreatePixmap (ScreenPtr pScreen, - int width, int height, int depth, char *addr) -{ - PixmapPtr pPixmap; - - pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0); - if (!pPixmap) - return NullPixmap; - - if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth, - BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) { - (*pScreen->DestroyPixmap)(pPixmap); - return NullPixmap; - } - return pPixmap; -} - -static int -ProcShmCreatePixmap(ClientPtr client) -{ - PixmapPtr pMap; - DrawablePtr pDraw; - DepthPtr pDepth; - int i, rc; - ShmDescPtr shmdesc; - ShmScrPrivateRec *screen_priv; - REQUEST(xShmCreatePixmapReq); - unsigned int width, height, depth; - unsigned long size; - - REQUEST_SIZE_MATCH(xShmCreatePixmapReq); - client->errorValue = stuff->pid; - if (!sharedPixmaps) - return BadImplementation; - LEGAL_NEW_RESOURCE(stuff->pid, client); - rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, - DixGetAttrAccess); - if (rc != Success) - return rc; - - VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client); - - width = stuff->width; - height = stuff->height; - depth = stuff->depth; - if (!width || !height || !depth) - { - client->errorValue = 0; - return BadValue; - } - if (width > 32767 || height > 32767) - return BadAlloc; - - if (stuff->depth != 1) - { - pDepth = pDraw->pScreen->allowedDepths; - for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) - if (pDepth->depth == stuff->depth) - goto CreatePmap; - client->errorValue = stuff->depth; - return BadValue; - } - -CreatePmap: - size = PixmapBytePad(width, depth) * height; - if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) { - if (size < width * height) - return BadAlloc; - } - /* thankfully, offset is unsigned */ - if (stuff->offset + size < size) - return BadAlloc; - - VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client); - screen_priv = ShmGetScreenPriv(pDraw->pScreen); - pMap = (*screen_priv->shmFuncs->CreatePixmap)( - pDraw->pScreen, stuff->width, - stuff->height, stuff->depth, - shmdesc->addr + stuff->offset); - if (pMap) - { - rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP, - pMap, RT_NONE, NULL, DixCreateAccess); - if (rc != Success) { - pDraw->pScreen->DestroyPixmap(pMap); - return rc; - } - dixSetPrivate(&pMap->devPrivates, shmPixmapPrivate, shmdesc); - shmdesc->refcnt++; - pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; - pMap->drawable.id = stuff->pid; - if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap)) - { - return(client->noClientException); - } - pDraw->pScreen->DestroyPixmap(pMap); - } - return (BadAlloc); -} - -static int -ProcShmDispatch (ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) - { - case X_ShmQueryVersion: - return ProcShmQueryVersion(client); - case X_ShmAttach: - return ProcShmAttach(client); - case X_ShmDetach: - return ProcShmDetach(client); - case X_ShmPutImage: -#ifdef PANORAMIX - if ( !noPanoramiXExtension ) - return ProcPanoramiXShmPutImage(client); -#endif - return ProcShmPutImage(client); - case X_ShmGetImage: -#ifdef PANORAMIX - if ( !noPanoramiXExtension ) - return ProcPanoramiXShmGetImage(client); -#endif - return ProcShmGetImage(client); - case X_ShmCreatePixmap: -#ifdef PANORAMIX - if ( !noPanoramiXExtension ) - return ProcPanoramiXShmCreatePixmap(client); -#endif - return ProcShmCreatePixmap(client); - default: - return BadRequest; - } -} - -static void -SShmCompletionEvent(xShmCompletionEvent *from, xShmCompletionEvent *to) -{ - to->type = from->type; - cpswaps(from->sequenceNumber, to->sequenceNumber); - cpswapl(from->drawable, to->drawable); - cpswaps(from->minorEvent, to->minorEvent); - to->majorEvent = from->majorEvent; - cpswapl(from->shmseg, to->shmseg); - cpswapl(from->offset, to->offset); -} - -static int -SProcShmQueryVersion(ClientPtr client) -{ - int n; - REQUEST(xShmQueryVersionReq); - - swaps(&stuff->length, n); - return ProcShmQueryVersion(client); -} - -static int -SProcShmAttach(ClientPtr client) -{ - int n; - REQUEST(xShmAttachReq); - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xShmAttachReq); - swapl(&stuff->shmseg, n); - swapl(&stuff->shmid, n); - return ProcShmAttach(client); -} - -static int -SProcShmDetach(ClientPtr client) -{ - int n; - REQUEST(xShmDetachReq); - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xShmDetachReq); - swapl(&stuff->shmseg, n); - return ProcShmDetach(client); -} - -static int -SProcShmPutImage(ClientPtr client) -{ - int n; - REQUEST(xShmPutImageReq); - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xShmPutImageReq); - swapl(&stuff->drawable, n); - swapl(&stuff->gc, n); - swaps(&stuff->totalWidth, n); - swaps(&stuff->totalHeight, n); - swaps(&stuff->srcX, n); - swaps(&stuff->srcY, n); - swaps(&stuff->srcWidth, n); - swaps(&stuff->srcHeight, n); - swaps(&stuff->dstX, n); - swaps(&stuff->dstY, n); - swapl(&stuff->shmseg, n); - swapl(&stuff->offset, n); - return ProcShmPutImage(client); -} - -static int -SProcShmGetImage(ClientPtr client) -{ - int n; - REQUEST(xShmGetImageReq); - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xShmGetImageReq); - swapl(&stuff->drawable, n); - swaps(&stuff->x, n); - swaps(&stuff->y, n); - swaps(&stuff->width, n); - swaps(&stuff->height, n); - swapl(&stuff->planeMask, n); - swapl(&stuff->shmseg, n); - swapl(&stuff->offset, n); - return ProcShmGetImage(client); -} - -static int -SProcShmCreatePixmap(ClientPtr client) -{ - int n; - REQUEST(xShmCreatePixmapReq); - swaps(&stuff->length, n); - REQUEST_SIZE_MATCH(xShmCreatePixmapReq); - swapl(&stuff->pid, n); - swapl(&stuff->drawable, n); - swaps(&stuff->width, n); - swaps(&stuff->height, n); - swapl(&stuff->shmseg, n); - swapl(&stuff->offset, n); - return ProcShmCreatePixmap(client); -} - -static int -SProcShmDispatch (ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) - { - case X_ShmQueryVersion: - return SProcShmQueryVersion(client); - case X_ShmAttach: - return SProcShmAttach(client); - case X_ShmDetach: - return SProcShmDetach(client); - case X_ShmPutImage: - return SProcShmPutImage(client); - case X_ShmGetImage: - return SProcShmGetImage(client); - case X_ShmCreatePixmap: - return SProcShmCreatePixmap(client); - default: - return BadRequest; - } -} +/************************************************************
+
+Copyright 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.
+
+********************************************************/
+
+/* THIS IS NOT AN X CONSORTIUM STANDARD OR AN X PROJECT TEAM SPECIFICATION */
+
+
+#define SHM
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <sys/types.h>
+#if !defined(_MSC_VER)
+#include <sys/ipc.h>
+#include <sys/shm.h>
+#endif
+#include <unistd.h>
+#include <sys/stat.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "os.h"
+#include "dixstruct.h"
+#include "resource.h"
+#include "scrnintstr.h"
+#include "windowstr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "extnsionst.h"
+#include "servermd.h"
+#include "shmint.h"
+#include "xace.h"
+#include <X11/extensions/shmproto.h>
+#include <X11/Xfuncproto.h>
+#include "protocol-versions.h"
+
+/* Needed for Solaris cross-zone shared memory extension */
+#ifdef HAVE_SHMCTL64
+#include <sys/ipc_impl.h>
+#define SHMSTAT(id, buf) shmctl64(id, IPC_STAT64, buf)
+#define SHMSTAT_TYPE struct shmid_ds64
+#define SHMPERM_TYPE struct ipc_perm64
+#define SHM_PERM(buf) buf.shmx_perm
+#define SHM_SEGSZ(buf) buf.shmx_segsz
+#define SHMPERM_UID(p) p->ipcx_uid
+#define SHMPERM_CUID(p) p->ipcx_cuid
+#define SHMPERM_GID(p) p->ipcx_gid
+#define SHMPERM_CGID(p) p->ipcx_cgid
+#define SHMPERM_MODE(p) p->ipcx_mode
+#define SHMPERM_ZONEID(p) p->ipcx_zoneid
+#else
+#define SHMSTAT(id, buf) shmctl(id, IPC_STAT, buf)
+#define SHMSTAT_TYPE struct shmid_ds
+#define SHMPERM_TYPE struct ipc_perm
+#define SHM_PERM(buf) buf.shm_perm
+#define SHM_SEGSZ(buf) buf.shm_segsz
+#define SHMPERM_UID(p) p->uid
+#define SHMPERM_CUID(p) p->cuid
+#define SHMPERM_GID(p) p->gid
+#define SHMPERM_CGID(p) p->cgid
+#define SHMPERM_MODE(p) p->mode
+#endif
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+#include "modinit.h"
+
+typedef struct _ShmDesc {
+ struct _ShmDesc *next;
+ int shmid;
+ int refcnt;
+ char *addr;
+ Bool writable;
+ unsigned long size;
+} ShmDescRec, *ShmDescPtr;
+
+typedef struct _ShmScrPrivateRec {
+ CloseScreenProcPtr CloseScreen;
+ ShmFuncsPtr shmFuncs;
+ DestroyPixmapProcPtr destroyPixmap;
+} ShmScrPrivateRec;
+
+static PixmapPtr fbShmCreatePixmap(XSHM_CREATE_PIXMAP_ARGS);
+static int ShmDetachSegment(
+ pointer /* value */,
+ XID /* shmseg */
+ );
+static void ShmResetProc(
+ ExtensionEntry * /* extEntry */
+ );
+static void SShmCompletionEvent(
+ xShmCompletionEvent * /* from */,
+ xShmCompletionEvent * /* to */
+ );
+
+static Bool ShmDestroyPixmap (PixmapPtr pPixmap);
+
+static DISPATCH_PROC(ProcShmAttach);
+static DISPATCH_PROC(ProcShmCreatePixmap);
+static DISPATCH_PROC(ProcShmDetach);
+static DISPATCH_PROC(ProcShmDispatch);
+static DISPATCH_PROC(ProcShmGetImage);
+static DISPATCH_PROC(ProcShmPutImage);
+static DISPATCH_PROC(ProcShmQueryVersion);
+static DISPATCH_PROC(SProcShmAttach);
+static DISPATCH_PROC(SProcShmCreatePixmap);
+static DISPATCH_PROC(SProcShmDetach);
+static DISPATCH_PROC(SProcShmDispatch);
+static DISPATCH_PROC(SProcShmGetImage);
+static DISPATCH_PROC(SProcShmPutImage);
+static DISPATCH_PROC(SProcShmQueryVersion);
+
+static unsigned char ShmReqCode;
+int ShmCompletionCode;
+int BadShmSegCode;
+RESTYPE ShmSegType;
+static ShmDescPtr Shmsegs;
+static Bool sharedPixmaps;
+static int shmScrPrivateKeyIndex;
+static DevPrivateKey shmScrPrivateKey = &shmScrPrivateKeyIndex;
+static int shmPixmapPrivateIndex;
+static DevPrivateKey shmPixmapPrivate = &shmPixmapPrivateIndex;
+static ShmFuncs miFuncs = {NULL, NULL};
+static ShmFuncs fbFuncs = {fbShmCreatePixmap, NULL};
+
+#define ShmGetScreenPriv(s) ((ShmScrPrivateRec *)dixLookupPrivate(&(s)->devPrivates, shmScrPrivateKey))
+
+#define VERIFY_SHMSEG(shmseg,shmdesc,client) \
+{ \
+ int rc; \
+ rc = dixLookupResourceByType((pointer *)&(shmdesc), shmseg, ShmSegType, \
+ client, DixReadAccess); \
+ if (rc != Success) \
+ return (rc == BadValue) ? BadShmSegCode : rc; \
+}
+
+#define VERIFY_SHMPTR(shmseg,offset,needwrite,shmdesc,client) \
+{ \
+ VERIFY_SHMSEG(shmseg, shmdesc, client); \
+ if ((offset & 3) || (offset > shmdesc->size)) \
+ { \
+ client->errorValue = offset; \
+ return BadValue; \
+ } \
+ if (needwrite && !shmdesc->writable) \
+ return BadAccess; \
+}
+
+#define VERIFY_SHMSIZE(shmdesc,offset,len,client) \
+{ \
+ if ((offset + len) > shmdesc->size) \
+ { \
+ return BadAccess; \
+ } \
+}
+
+
+#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__CYGWIN__) || defined(__DragonFly__)
+#include <sys/signal.h>
+
+static Bool badSysCall = FALSE;
+
+static void
+SigSysHandler(int signo)
+{
+ badSysCall = TRUE;
+}
+
+static Bool CheckForShmSyscall(void)
+{
+ void (*oldHandler)();
+ int shmid = -1;
+
+ /* If no SHM support in the kernel, the bad syscall will generate SIGSYS */
+ oldHandler = signal(SIGSYS, SigSysHandler);
+
+ badSysCall = FALSE;
+ shmid = shmget(IPC_PRIVATE, 4096, IPC_CREAT);
+
+ if (shmid != -1)
+ {
+ /* Successful allocation - clean up */
+ shmctl(shmid, IPC_RMID, NULL);
+ }
+ else
+ {
+ /* Allocation failed */
+ badSysCall = TRUE;
+ }
+ signal(SIGSYS, oldHandler);
+ return(!badSysCall);
+}
+
+#define MUST_CHECK_FOR_SHM_SYSCALL
+
+#endif
+
+static Bool
+ShmCloseScreen(int i, ScreenPtr pScreen)
+{
+ ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen);
+ pScreen->CloseScreen = screen_priv->CloseScreen;
+ dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, NULL);
+ xfree (screen_priv);
+ return (*pScreen->CloseScreen) (i, pScreen);
+}
+
+static ShmScrPrivateRec *
+ShmInitScreenPriv(ScreenPtr pScreen)
+{
+ ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen);
+ if (!screen_priv)
+ {
+ screen_priv = xcalloc (1, sizeof (ShmScrPrivateRec));
+ screen_priv->CloseScreen = pScreen->CloseScreen;
+ dixSetPrivate(&pScreen->devPrivates, shmScrPrivateKey, screen_priv);
+ pScreen->CloseScreen = ShmCloseScreen;
+ }
+ return screen_priv;
+}
+
+void
+ShmExtensionInit(INITARGS)
+{
+ ExtensionEntry *extEntry;
+ int i;
+
+#ifdef MUST_CHECK_FOR_SHM_SYSCALL
+ if (!CheckForShmSyscall())
+ {
+ ErrorF("MIT-SHM extension disabled due to lack of kernel support\n");
+ return;
+ }
+#endif
+
+ sharedPixmaps = xFalse;
+ {
+ sharedPixmaps = xTrue;
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ ShmScrPrivateRec *screen_priv = ShmInitScreenPriv(screenInfo.screens[i]);
+ if (!screen_priv->shmFuncs)
+ screen_priv->shmFuncs = &miFuncs;
+ if (!screen_priv->shmFuncs->CreatePixmap)
+ sharedPixmaps = xFalse;
+ }
+ if (sharedPixmaps)
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(screenInfo.screens[i]);
+ screen_priv->destroyPixmap = screenInfo.screens[i]->DestroyPixmap;
+ screenInfo.screens[i]->DestroyPixmap = ShmDestroyPixmap;
+ }
+ }
+ ShmSegType = CreateNewResourceType(ShmDetachSegment, "ShmSeg");
+ if (ShmSegType &&
+ (extEntry = AddExtension(SHMNAME, ShmNumberEvents, ShmNumberErrors,
+ ProcShmDispatch, SProcShmDispatch,
+ ShmResetProc, StandardMinorOpcode)))
+ {
+ ShmReqCode = (unsigned char)extEntry->base;
+ ShmCompletionCode = extEntry->eventBase;
+ BadShmSegCode = extEntry->errorBase;
+ EventSwapVector[ShmCompletionCode] = (EventSwapPtr) SShmCompletionEvent;
+ }
+}
+
+/*ARGSUSED*/
+static void
+ShmResetProc(ExtensionEntry *extEntry)
+{
+ int i;
+ for (i = 0; i < screenInfo.numScreens; i++)
+ ShmRegisterFuncs(screenInfo.screens[i], NULL);
+}
+
+void
+ShmRegisterFuncs(ScreenPtr pScreen, ShmFuncsPtr funcs)
+{
+ ShmInitScreenPriv(pScreen)->shmFuncs = funcs;
+}
+
+static Bool
+ShmDestroyPixmap (PixmapPtr pPixmap)
+{
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ ShmScrPrivateRec *screen_priv = ShmGetScreenPriv(pScreen);
+ Bool ret;
+ if (pPixmap->refcnt == 1)
+ {
+ ShmDescPtr shmdesc;
+ shmdesc = (ShmDescPtr)dixLookupPrivate(&pPixmap->devPrivates,
+ shmPixmapPrivate);
+ if (shmdesc)
+ ShmDetachSegment ((pointer) shmdesc, pPixmap->drawable.id);
+ }
+
+ pScreen->DestroyPixmap = screen_priv->destroyPixmap;
+ ret = (*pScreen->DestroyPixmap) (pPixmap);
+ screen_priv->destroyPixmap = pScreen->DestroyPixmap;
+ pScreen->DestroyPixmap = ShmDestroyPixmap;
+ return ret;
+}
+
+void
+ShmRegisterFbFuncs(ScreenPtr pScreen)
+{
+ ShmRegisterFuncs(pScreen, &fbFuncs);
+}
+
+static int
+ProcShmQueryVersion(ClientPtr client)
+{
+ xShmQueryVersionReply rep;
+ int n;
+
+ REQUEST_SIZE_MATCH(xShmQueryVersionReq);
+ memset(&rep, 0, sizeof(xShmQueryVersionReply));
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.sharedPixmaps = sharedPixmaps;
+ rep.pixmapFormat = sharedPixmaps ? ZPixmap : 0;
+ rep.majorVersion = SERVER_SHM_MAJOR_VERSION;
+ rep.minorVersion = SERVER_SHM_MINOR_VERSION;
+#ifndef _MSC_VER
+ rep.uid = geteuid();
+ rep.gid = getegid();
+#endif
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ swaps(&rep.majorVersion, n);
+ swaps(&rep.minorVersion, n);
+ swaps(&rep.uid, n);
+ swaps(&rep.gid, n);
+ }
+ WriteToClient(client, sizeof(xShmQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+/*
+ * Simulate the access() system call for a shared memory segement,
+ * using the credentials from the client if available
+ */
+static int
+shm_access(ClientPtr client, SHMPERM_TYPE *perm, int readonly)
+{
+ int uid, gid;
+ mode_t mask;
+ int uidset = 0, gidset = 0;
+ LocalClientCredRec *lcc;
+
+ if (GetLocalClientCreds(client, &lcc) != -1) {
+
+ if (lcc->fieldsSet & LCC_UID_SET) {
+ uid = lcc->euid;
+ uidset = 1;
+ }
+ if (lcc->fieldsSet & LCC_GID_SET) {
+ gid = lcc->egid;
+ gidset = 1;
+ }
+
+#if defined(HAVE_GETZONEID) && defined(SHMPERM_ZONEID)
+ if ( ((lcc->fieldsSet & LCC_ZID_SET) == 0) || (lcc->zoneid == -1)
+ || (lcc->zoneid != SHMPERM_ZONEID(perm))) {
+ uidset = 0;
+ gidset = 0;
+ }
+#endif
+ FreeLocalClientCreds(lcc);
+
+ if (uidset) {
+ /* User id 0 always gets access */
+ if (uid == 0) {
+ return 0;
+ }
+ #ifdef _MSC_VER
+ __asm int 3;
+ #else
+ /* Check the owner */
+ if (SHMPERM_UID(perm) == uid || SHMPERM_CUID(perm) == uid) {
+ mask = S_IRUSR;
+ if (!readonly) {
+ mask |= S_IWUSR;
+ }
+ return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
+ }
+ #endif
+ }
+
+ if (gidset) {
+ /* Check the group */
+ #ifdef _MSC_VER
+ __asm int 3;
+ #else
+ if (SHMPERM_GID(perm) == gid || SHMPERM_CGID(perm) == gid) {
+ mask = S_IRGRP;
+ if (!readonly) {
+ mask |= S_IWGRP;
+ }
+ return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
+ }
+ #endif
+ }
+ }
+ #ifdef _MSC_VER
+ __asm int 3;
+ return -1;
+ #else
+ /* Otherwise, check everyone else */
+ mask = S_IROTH;
+ if (!readonly) {
+ mask |= S_IWOTH;
+ }
+ return (SHMPERM_MODE(perm) & mask) == mask ? 0 : -1;
+ #endif
+}
+
+static int
+ProcShmAttach(ClientPtr client)
+{
+ SHMSTAT_TYPE buf;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmAttachReq);
+
+ REQUEST_SIZE_MATCH(xShmAttachReq);
+ LEGAL_NEW_RESOURCE(stuff->shmseg, client);
+ if ((stuff->readOnly != xTrue) && (stuff->readOnly != xFalse))
+ {
+ client->errorValue = stuff->readOnly;
+ return(BadValue);
+ }
+ for (shmdesc = Shmsegs;
+ shmdesc && (shmdesc->shmid != stuff->shmid);
+ shmdesc = shmdesc->next)
+ ;
+ if (shmdesc)
+ {
+ if (!stuff->readOnly && !shmdesc->writable)
+ return BadAccess;
+ shmdesc->refcnt++;
+ }
+ else
+ {
+ shmdesc = xalloc(sizeof(ShmDescRec));
+ if (!shmdesc)
+ return BadAlloc;
+ shmdesc->addr = shmat(stuff->shmid, 0,
+ stuff->readOnly ? SHM_RDONLY : 0);
+ if ((shmdesc->addr == ((char *)-1)) ||
+ SHMSTAT(stuff->shmid, &buf))
+ {
+ xfree(shmdesc);
+ return BadAccess;
+ }
+
+ /* The attach was performed with root privs. We must
+ * do manual checking of access rights for the credentials
+ * of the client */
+
+ if (shm_access(client, &(SHM_PERM(buf)), stuff->readOnly) == -1) {
+ shmdt(shmdesc->addr);
+ xfree(shmdesc);
+ return BadAccess;
+ }
+
+ shmdesc->shmid = stuff->shmid;
+ shmdesc->refcnt = 1;
+ shmdesc->writable = !stuff->readOnly;
+ shmdesc->size = SHM_SEGSZ(buf);
+ shmdesc->next = Shmsegs;
+ Shmsegs = shmdesc;
+ }
+ if (!AddResource(stuff->shmseg, ShmSegType, (pointer)shmdesc))
+ return BadAlloc;
+ return(client->noClientException);
+}
+
+/*ARGSUSED*/
+static int
+ShmDetachSegment(pointer value, /* must conform to DeleteType */
+ XID shmseg)
+{
+ ShmDescPtr shmdesc = (ShmDescPtr)value;
+ ShmDescPtr *prev;
+
+ if (--shmdesc->refcnt)
+ return TRUE;
+#ifndef _MSC_VER
+ shmdt(shmdesc->addr);
+#endif
+ for (prev = &Shmsegs; *prev != shmdesc; prev = &(*prev)->next)
+ ;
+ *prev = shmdesc->next;
+ xfree(shmdesc);
+ return Success;
+}
+
+static int
+ProcShmDetach(ClientPtr client)
+{
+ ShmDescPtr shmdesc;
+ REQUEST(xShmDetachReq);
+
+ REQUEST_SIZE_MATCH(xShmDetachReq);
+ VERIFY_SHMSEG(stuff->shmseg, shmdesc, client);
+ FreeResource(stuff->shmseg, RT_NONE);
+ return(client->noClientException);
+}
+
+/*
+ * If the given request doesn't exactly match PutImage's constraints,
+ * wrap the image in a scratch pixmap header and let CopyArea sort it out.
+ */
+static void
+doShmPutImage(DrawablePtr dst, GCPtr pGC,
+ int depth, unsigned int format,
+ int w, int h, int sx, int sy, int sw, int sh, int dx, int dy,
+ char *data)
+{
+ PixmapPtr pPixmap;
+
+ if (format == ZPixmap || depth == 1) {
+ pPixmap = GetScratchPixmapHeader(dst->pScreen, w, h, depth,
+ BitsPerPixel(depth),
+ PixmapBytePad(w, depth),
+ data);
+ if (!pPixmap)
+ return;
+ pGC->ops->CopyArea((DrawablePtr)pPixmap, dst, pGC, sx, sy, sw, sh, dx, dy);
+ FreeScratchPixmapHeader(pPixmap);
+ } else {
+ GCPtr putGC = GetScratchGC(depth, dst->pScreen);
+
+ if (!putGC)
+ return;
+
+ pPixmap = (*dst->pScreen->CreatePixmap)(dst->pScreen, sw, sh, depth,
+ CREATE_PIXMAP_USAGE_SCRATCH);
+ if (!pPixmap) {
+ FreeScratchGC(putGC);
+ return;
+ }
+ ValidateGC(&pPixmap->drawable, putGC);
+ (*putGC->ops->PutImage)(&pPixmap->drawable, putGC, depth, -sx, -sy, w, h, 0,
+ (format == XYPixmap) ? XYPixmap : ZPixmap, data);
+ FreeScratchGC(putGC);
+ if (format == XYBitmap)
+ (void)(*pGC->ops->CopyPlane)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh,
+ dx, dy, 1L);
+ else
+ (void)(*pGC->ops->CopyArea)(&pPixmap->drawable, dst, pGC, 0, 0, sw, sh,
+ dx, dy);
+ (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+ }
+}
+
+#ifdef PANORAMIX
+static int
+ProcPanoramiXShmPutImage(ClientPtr client)
+{
+ int j, result, orig_x, orig_y;
+ PanoramiXRes *draw, *gc;
+ Bool sendEvent, isRoot;
+
+ REQUEST(xShmPutImageReq);
+ REQUEST_SIZE_MATCH(xShmPutImageReq);
+
+ result = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
+ XRC_DRAWABLE, client, DixWriteAccess);
+ if (result != Success)
+ return (result == BadValue) ? BadDrawable : result;
+
+ result = dixLookupResourceByType((pointer *)&gc, stuff->gc,
+ XRT_GC, client, DixReadAccess);
+ if (result != Success)
+ return (result == BadValue) ? BadGC : result;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ orig_x = stuff->dstX;
+ orig_y = stuff->dstY;
+ sendEvent = stuff->sendEvent;
+ stuff->sendEvent = 0;
+ FOR_NSCREENS(j) {
+ if(!j) stuff->sendEvent = sendEvent;
+ stuff->drawable = draw->info[j].id;
+ stuff->gc = gc->info[j].id;
+ if (isRoot) {
+ stuff->dstX = orig_x - panoramiXdataPtr[j].x;
+ stuff->dstY = orig_y - panoramiXdataPtr[j].y;
+ }
+ result = ProcShmPutImage(client);
+ if(result != client->noClientException) break;
+ }
+ return(result);
+}
+
+static int
+ProcPanoramiXShmGetImage(ClientPtr client)
+{
+ PanoramiXRes *draw;
+ DrawablePtr *drawables;
+ DrawablePtr pDraw;
+ xShmGetImageReply xgi;
+ ShmDescPtr shmdesc;
+ int i, x, y, w, h, format, rc;
+ Mask plane = 0, planemask;
+ long lenPer = 0, length, widthBytesLine;
+ Bool isRoot;
+
+ REQUEST(xShmGetImageReq);
+
+ REQUEST_SIZE_MATCH(xShmGetImageReq);
+
+ if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
+ client->errorValue = stuff->format;
+ return(BadValue);
+ }
+
+ rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
+ XRC_DRAWABLE, client, DixWriteAccess);
+ if (rc != Success)
+ return (rc == BadValue) ? BadDrawable : rc;
+
+ if (draw->type == XRT_PIXMAP)
+ return ProcShmGetImage(client);
+
+ rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+
+ x = stuff->x;
+ y = stuff->y;
+ w = stuff->width;
+ h = stuff->height;
+ format = stuff->format;
+ planemask = stuff->planeMask;
+
+ isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;
+
+ if(isRoot) {
+ if( /* check for being onscreen */
+ x < 0 || x + w > PanoramiXPixWidth ||
+ y < 0 || y + h > PanoramiXPixHeight )
+ return(BadMatch);
+ } else {
+ if( /* check for being onscreen */
+ panoramiXdataPtr[0].x + pDraw->x + x < 0 ||
+ panoramiXdataPtr[0].x + pDraw->x + x + w > PanoramiXPixWidth ||
+ panoramiXdataPtr[0].y + pDraw->y + y < 0 ||
+ panoramiXdataPtr[0].y + pDraw->y + y + h > PanoramiXPixHeight ||
+ /* check for being inside of border */
+ x < - wBorderWidth((WindowPtr)pDraw) ||
+ x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+ y < -wBorderWidth((WindowPtr)pDraw) ||
+ y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
+ return(BadMatch);
+ }
+
+ drawables = xcalloc(PanoramiXNumScreens, sizeof(DrawablePtr));
+ if(!drawables)
+ return(BadAlloc);
+
+ drawables[0] = pDraw;
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ {
+ xfree(drawables);
+ return rc;
+ }
+ }
+
+ xgi.visual = wVisual(((WindowPtr)pDraw));
+ xgi.type = X_Reply;
+ xgi.length = 0;
+ xgi.sequenceNumber = client->sequence;
+ xgi.depth = pDraw->depth;
+
+ if(format == ZPixmap) {
+ widthBytesLine = PixmapBytePad(w, pDraw->depth);
+ length = widthBytesLine * h;
+ } else {
+ widthBytesLine = PixmapBytePad(w, 1);
+ lenPer = widthBytesLine * h;
+ plane = ((Mask)1) << (pDraw->depth - 1);
+ length = lenPer * Ones(planemask & (plane | (plane - 1)));
+ }
+
+ VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+ xgi.size = length;
+
+ if (length == 0) {/* nothing to do */ }
+ else if (format == ZPixmap) {
+ XineramaGetImageData(drawables, x, y, w, h, format, planemask,
+ shmdesc->addr + stuff->offset,
+ widthBytesLine, isRoot);
+ } else {
+
+ length = stuff->offset;
+ for (; plane; plane >>= 1) {
+ if (planemask & plane) {
+ XineramaGetImageData(drawables, x, y, w, h,
+ format, plane, shmdesc->addr + length,
+ widthBytesLine, isRoot);
+ length += lenPer;
+ }
+ }
+ }
+ xfree(drawables);
+
+ if (client->swapped) {
+ int n;
+ swaps(&xgi.sequenceNumber, n);
+ swapl(&xgi.length, n);
+ swapl(&xgi.visual, n);
+ swapl(&xgi.size, n);
+ }
+ WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
+
+ return(client->noClientException);
+}
+
+static int
+ProcPanoramiXShmCreatePixmap(ClientPtr client)
+{
+ ScreenPtr pScreen = NULL;
+ PixmapPtr pMap = NULL;
+ DrawablePtr pDraw;
+ DepthPtr pDepth;
+ int i, j, result, rc;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmCreatePixmapReq);
+ unsigned int width, height, depth;
+ unsigned long size;
+ PanoramiXRes *newPix;
+
+ REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ if (!sharedPixmaps)
+ return BadImplementation;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
+ DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+
+ width = stuff->width;
+ height = stuff->height;
+ depth = stuff->depth;
+ if (!width || !height || !depth)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ if (width > 32767 || height > 32767)
+ return BadAlloc;
+
+ if (stuff->depth != 1)
+ {
+ pDepth = pDraw->pScreen->allowedDepths;
+ for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+ if (pDepth->depth == stuff->depth)
+ goto CreatePmap;
+ client->errorValue = stuff->depth;
+ return BadValue;
+ }
+
+CreatePmap:
+ size = PixmapBytePad(width, depth) * height;
+ if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
+ if (size < width * height)
+ return BadAlloc;
+ }
+ /* thankfully, offset is unsigned */
+ if (stuff->offset + size < size)
+ return BadAlloc;
+
+ VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
+
+ if(!(newPix = xalloc(sizeof(PanoramiXRes))))
+ return BadAlloc;
+
+ newPix->type = XRT_PIXMAP;
+ newPix->u.pix.shared = TRUE;
+ newPix->info[0].id = stuff->pid;
+ for(j = 1; j < PanoramiXNumScreens; j++)
+ newPix->info[j].id = FakeClientID(client->index);
+
+ result = (client->noClientException);
+
+ FOR_NSCREENS(j) {
+ ShmScrPrivateRec *screen_priv;
+ pScreen = screenInfo.screens[j];
+
+ screen_priv = ShmGetScreenPriv(pScreen);
+ pMap = (*screen_priv->shmFuncs->CreatePixmap)(pScreen,
+ stuff->width, stuff->height, stuff->depth,
+ shmdesc->addr + stuff->offset);
+
+ if (pMap) {
+ dixSetPrivate(&pMap->devPrivates, shmPixmapPrivate, shmdesc);
+ shmdesc->refcnt++;
+ pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pMap->drawable.id = newPix->info[j].id;
+ if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) {
+ (*pScreen->DestroyPixmap)(pMap);
+ result = BadAlloc;
+ break;
+ }
+ } else {
+ result = BadAlloc;
+ break;
+ }
+ }
+
+ if(result == BadAlloc) {
+ while(j--) {
+ (*pScreen->DestroyPixmap)(pMap);
+ FreeResource(newPix->info[j].id, RT_NONE);
+ }
+ xfree(newPix);
+ } else
+ AddResource(stuff->pid, XRT_PIXMAP, newPix);
+
+ return result;
+}
+
+#endif
+
+static int
+ProcShmPutImage(ClientPtr client)
+{
+ GCPtr pGC;
+ DrawablePtr pDraw;
+ long length;
+ ShmDescPtr shmdesc;
+ REQUEST(xShmPutImageReq);
+
+ REQUEST_SIZE_MATCH(xShmPutImageReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
+ if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
+ return BadValue;
+ if (stuff->format == XYBitmap)
+ {
+ if (stuff->depth != 1)
+ return BadMatch;
+ length = PixmapBytePad(stuff->totalWidth, 1);
+ }
+ else if (stuff->format == XYPixmap)
+ {
+ if (pDraw->depth != stuff->depth)
+ return BadMatch;
+ length = PixmapBytePad(stuff->totalWidth, 1);
+ length *= stuff->depth;
+ }
+ else if (stuff->format == ZPixmap)
+ {
+ if (pDraw->depth != stuff->depth)
+ return BadMatch;
+ length = PixmapBytePad(stuff->totalWidth, stuff->depth);
+ }
+ else
+ {
+ client->errorValue = stuff->format;
+ return BadValue;
+ }
+
+ /*
+ * There's a potential integer overflow in this check:
+ * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
+ * client);
+ * the version below ought to avoid it
+ */
+ if (stuff->totalHeight != 0 &&
+ length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
+ client->errorValue = stuff->totalWidth;
+ return BadValue;
+ }
+ if (stuff->srcX > stuff->totalWidth)
+ {
+ client->errorValue = stuff->srcX;
+ return BadValue;
+ }
+ if (stuff->srcY > stuff->totalHeight)
+ {
+ client->errorValue = stuff->srcY;
+ return BadValue;
+ }
+ if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
+ {
+ client->errorValue = stuff->srcWidth;
+ return BadValue;
+ }
+ if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
+ {
+ client->errorValue = stuff->srcHeight;
+ return BadValue;
+ }
+
+ if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) ||
+ ((stuff->format != ZPixmap) &&
+ (stuff->srcX < screenInfo.bitmapScanlinePad) &&
+ ((stuff->format == XYBitmap) ||
+ ((stuff->srcY == 0) &&
+ (stuff->srcHeight == stuff->totalHeight))))) &&
+ ((stuff->srcX + stuff->srcWidth) == stuff->totalWidth))
+ (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth,
+ stuff->dstX, stuff->dstY,
+ stuff->totalWidth, stuff->srcHeight,
+ stuff->srcX, stuff->format,
+ shmdesc->addr + stuff->offset +
+ (stuff->srcY * length));
+ else
+ doShmPutImage(pDraw, pGC, stuff->depth, stuff->format,
+ stuff->totalWidth, stuff->totalHeight,
+ stuff->srcX, stuff->srcY,
+ stuff->srcWidth, stuff->srcHeight,
+ stuff->dstX, stuff->dstY,
+ shmdesc->addr + stuff->offset);
+
+ if (stuff->sendEvent)
+ {
+ xShmCompletionEvent ev;
+
+ ev.type = ShmCompletionCode;
+ ev.drawable = stuff->drawable;
+ ev.sequenceNumber = client->sequence;
+ ev.minorEvent = X_ShmPutImage;
+ ev.majorEvent = ShmReqCode;
+ ev.shmseg = stuff->shmseg;
+ ev.offset = stuff->offset;
+ WriteEventsToClient(client, 1, (xEvent *) &ev);
+ }
+
+ return (client->noClientException);
+}
+
+
+
+static int
+ProcShmGetImage(ClientPtr client)
+{
+ DrawablePtr pDraw;
+ long lenPer = 0, length;
+ Mask plane = 0;
+ xShmGetImageReply xgi;
+ ShmDescPtr shmdesc;
+ int n, rc;
+
+ REQUEST(xShmGetImageReq);
+
+ REQUEST_SIZE_MATCH(xShmGetImageReq);
+ if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
+ {
+ client->errorValue = stuff->format;
+ return(BadValue);
+ }
+ rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+ if (pDraw->type == DRAWABLE_WINDOW)
+ {
+ if( /* check for being viewable */
+ !((WindowPtr) pDraw)->realized ||
+ /* check for being on screen */
+ pDraw->x + stuff->x < 0 ||
+ pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
+ pDraw->y + stuff->y < 0 ||
+ pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
+ /* check for being inside of border */
+ stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
+ stuff->x + (int)stuff->width >
+ wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
+ stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
+ stuff->y + (int)stuff->height >
+ wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = wVisual(((WindowPtr)pDraw));
+ }
+ else
+ {
+ if (stuff->x < 0 ||
+ stuff->x+(int)stuff->width > pDraw->width ||
+ stuff->y < 0 ||
+ stuff->y+(int)stuff->height > pDraw->height
+ )
+ return(BadMatch);
+ xgi.visual = None;
+ }
+ xgi.type = X_Reply;
+ xgi.length = 0;
+ xgi.sequenceNumber = client->sequence;
+ xgi.depth = pDraw->depth;
+ if(stuff->format == ZPixmap)
+ {
+ length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
+ }
+ else
+ {
+ lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
+ plane = ((Mask)1) << (pDraw->depth - 1);
+ /* only planes asked for */
+ length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
+ }
+
+ VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
+ xgi.size = length;
+
+ if (length == 0)
+ {
+ /* nothing to do */
+ }
+ else if (stuff->format == ZPixmap)
+ {
+ (*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ stuff->format, stuff->planeMask,
+ shmdesc->addr + stuff->offset);
+ }
+ else
+ {
+
+ length = stuff->offset;
+ for (; plane; plane >>= 1)
+ {
+ if (stuff->planeMask & plane)
+ {
+ (*pDraw->pScreen->GetImage)(pDraw,
+ stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ stuff->format, plane,
+ shmdesc->addr + length);
+ length += lenPer;
+ }
+ }
+ }
+
+ if (client->swapped) {
+ swaps(&xgi.sequenceNumber, n);
+ swapl(&xgi.length, n);
+ swapl(&xgi.visual, n);
+ swapl(&xgi.size, n);
+ }
+ WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);
+
+ return(client->noClientException);
+}
+
+static PixmapPtr
+fbShmCreatePixmap (ScreenPtr pScreen,
+ int width, int height, int depth, char *addr)
+{
+ PixmapPtr pPixmap;
+
+ pPixmap = (*pScreen->CreatePixmap)(pScreen, 0, 0, pScreen->rootDepth, 0);
+ if (!pPixmap)
+ return NullPixmap;
+
+ if (!(*pScreen->ModifyPixmapHeader)(pPixmap, width, height, depth,
+ BitsPerPixel(depth), PixmapBytePad(width, depth), (pointer)addr)) {
+ (*pScreen->DestroyPixmap)(pPixmap);
+ return NullPixmap;
+ }
+ return pPixmap;
+}
+
+static int
+ProcShmCreatePixmap(ClientPtr client)
+{
+ PixmapPtr pMap;
+ DrawablePtr pDraw;
+ DepthPtr pDepth;
+ int i, rc;
+ ShmDescPtr shmdesc;
+ ShmScrPrivateRec *screen_priv;
+ REQUEST(xShmCreatePixmapReq);
+ unsigned int width, height, depth;
+ unsigned long size;
+
+ REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ if (!sharedPixmaps)
+ return BadImplementation;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+ rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
+ DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
+
+ width = stuff->width;
+ height = stuff->height;
+ depth = stuff->depth;
+ if (!width || !height || !depth)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ if (width > 32767 || height > 32767)
+ return BadAlloc;
+
+ if (stuff->depth != 1)
+ {
+ pDepth = pDraw->pScreen->allowedDepths;
+ for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+ if (pDepth->depth == stuff->depth)
+ goto CreatePmap;
+ client->errorValue = stuff->depth;
+ return BadValue;
+ }
+
+CreatePmap:
+ size = PixmapBytePad(width, depth) * height;
+ if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
+ if (size < width * height)
+ return BadAlloc;
+ }
+ /* thankfully, offset is unsigned */
+ if (stuff->offset + size < size)
+ return BadAlloc;
+
+ VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
+ screen_priv = ShmGetScreenPriv(pDraw->pScreen);
+ pMap = (*screen_priv->shmFuncs->CreatePixmap)(
+ pDraw->pScreen, stuff->width,
+ stuff->height, stuff->depth,
+ shmdesc->addr + stuff->offset);
+ if (pMap)
+ {
+ rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
+ pMap, RT_NONE, NULL, DixCreateAccess);
+ if (rc != Success) {
+ pDraw->pScreen->DestroyPixmap(pMap);
+ return rc;
+ }
+ dixSetPrivate(&pMap->devPrivates, shmPixmapPrivate, shmdesc);
+ shmdesc->refcnt++;
+ pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pMap->drawable.id = stuff->pid;
+ if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+ {
+ return(client->noClientException);
+ }
+ pDraw->pScreen->DestroyPixmap(pMap);
+ }
+ return (BadAlloc);
+}
+
+static int
+ProcShmDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_ShmQueryVersion:
+ return ProcShmQueryVersion(client);
+ case X_ShmAttach:
+ return ProcShmAttach(client);
+ case X_ShmDetach:
+ return ProcShmDetach(client);
+ case X_ShmPutImage:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShmPutImage(client);
+#endif
+ return ProcShmPutImage(client);
+ case X_ShmGetImage:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShmGetImage(client);
+#endif
+ return ProcShmGetImage(client);
+ case X_ShmCreatePixmap:
+#ifdef PANORAMIX
+ if ( !noPanoramiXExtension )
+ return ProcPanoramiXShmCreatePixmap(client);
+#endif
+ return ProcShmCreatePixmap(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static void
+SShmCompletionEvent(xShmCompletionEvent *from, xShmCompletionEvent *to)
+{
+ to->type = from->type;
+ cpswaps(from->sequenceNumber, to->sequenceNumber);
+ cpswapl(from->drawable, to->drawable);
+ cpswaps(from->minorEvent, to->minorEvent);
+ to->majorEvent = from->majorEvent;
+ cpswapl(from->shmseg, to->shmseg);
+ cpswapl(from->offset, to->offset);
+}
+
+static int
+SProcShmQueryVersion(ClientPtr client)
+{
+ int n;
+ REQUEST(xShmQueryVersionReq);
+
+ swaps(&stuff->length, n);
+ return ProcShmQueryVersion(client);
+}
+
+static int
+SProcShmAttach(ClientPtr client)
+{
+ int n;
+ REQUEST(xShmAttachReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xShmAttachReq);
+ swapl(&stuff->shmseg, n);
+ swapl(&stuff->shmid, n);
+ return ProcShmAttach(client);
+}
+
+static int
+SProcShmDetach(ClientPtr client)
+{
+ int n;
+ REQUEST(xShmDetachReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xShmDetachReq);
+ swapl(&stuff->shmseg, n);
+ return ProcShmDetach(client);
+}
+
+static int
+SProcShmPutImage(ClientPtr client)
+{
+ int n;
+ REQUEST(xShmPutImageReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xShmPutImageReq);
+ swapl(&stuff->drawable, n);
+ swapl(&stuff->gc, n);
+ swaps(&stuff->totalWidth, n);
+ swaps(&stuff->totalHeight, n);
+ swaps(&stuff->srcX, n);
+ swaps(&stuff->srcY, n);
+ swaps(&stuff->srcWidth, n);
+ swaps(&stuff->srcHeight, n);
+ swaps(&stuff->dstX, n);
+ swaps(&stuff->dstY, n);
+ swapl(&stuff->shmseg, n);
+ swapl(&stuff->offset, n);
+ return ProcShmPutImage(client);
+}
+
+static int
+SProcShmGetImage(ClientPtr client)
+{
+ int n;
+ REQUEST(xShmGetImageReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xShmGetImageReq);
+ swapl(&stuff->drawable, n);
+ swaps(&stuff->x, n);
+ swaps(&stuff->y, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ swapl(&stuff->planeMask, n);
+ swapl(&stuff->shmseg, n);
+ swapl(&stuff->offset, n);
+ return ProcShmGetImage(client);
+}
+
+static int
+SProcShmCreatePixmap(ClientPtr client)
+{
+ int n;
+ REQUEST(xShmCreatePixmapReq);
+ swaps(&stuff->length, n);
+ REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
+ swapl(&stuff->pid, n);
+ swapl(&stuff->drawable, n);
+ swaps(&stuff->width, n);
+ swaps(&stuff->height, n);
+ swapl(&stuff->shmseg, n);
+ swapl(&stuff->offset, n);
+ return ProcShmCreatePixmap(client);
+}
+
+static int
+SProcShmDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_ShmQueryVersion:
+ return SProcShmQueryVersion(client);
+ case X_ShmAttach:
+ return SProcShmAttach(client);
+ case X_ShmDetach:
+ return SProcShmDetach(client);
+ case X_ShmPutImage:
+ return SProcShmPutImage(client);
+ case X_ShmGetImage:
+ return SProcShmGetImage(client);
+ case X_ShmCreatePixmap:
+ return SProcShmCreatePixmap(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/xorg-server/Xext/sync.c b/xorg-server/Xext/sync.c index ce6531467..d8374fe96 100644 --- a/xorg-server/Xext/sync.c +++ b/xorg-server/Xext/sync.c @@ -1095,6 +1095,10 @@ FreeAwait(void *addr, XID id) return Success; } +#ifdef _MSC_VER +#pragma warning(disable:4715) /* Not all control paths return a value */ +#endif + /* loosely based on dix/events.c/OtherClientGone */ static int FreeAlarmClient(void *value, XID id) diff --git a/xorg-server/Xext/xace.c b/xorg-server/Xext/xace.c index bf0e98fb0..02a0c1ebc 100644 --- a/xorg-server/Xext/xace.c +++ b/xorg-server/Xext/xace.c @@ -19,6 +19,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else +#define XACE #endif #include <stdarg.h> diff --git a/xorg-server/Xext/xvmain.c b/xorg-server/Xext/xvmain.c index 05a68907a..3c2454b01 100644 --- a/xorg-server/Xext/xvmain.c +++ b/xorg-server/Xext/xvmain.c @@ -277,7 +277,7 @@ XvScreenInit(ScreenPtr pScreen) /* ALLOCATE SCREEN PRIVATE RECORD */ - pxvs = xalloc (sizeof (XvScreenRec)); + pxvs = xcalloc (1,sizeof (XvScreenRec)); if (!pxvs) { ErrorF("XvScreenInit: Unable to allocate screen private structure\n"); @@ -312,7 +312,7 @@ XvCloseScreen( pScreen->DestroyWindow = pxvs->DestroyWindow; pScreen->CloseScreen = pxvs->CloseScreen; - (* pxvs->ddCloseScreen)(ii, pScreen); + if (pxvs->ddCloseScreen) (* pxvs->ddCloseScreen)(ii, pScreen); xfree(pxvs); diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c index 7c105eb94..4aae7d6c5 100644 --- a/xorg-server/Xi/exevents.c +++ b/xorg-server/Xi/exevents.c @@ -1,2213 +1,2219 @@ -/************************************************************ - -Copyright 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 1989 by Hewlett-Packard Company, Palo Alto, California. - - 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 Hewlett-Packard not be -used in advertising or publicity pertaining to distribution of the -software without specific, written prior permission. - -HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL -HEWLETT-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. - -********************************************************/ - -/******************************************************************** - * - * Routines to register and initialize extension input devices. - * This also contains ProcessOtherEvent, the routine called from DDX - * to route extension events. - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include "inputstr.h" -#include <X11/X.h> -#include <X11/Xproto.h> -#include <X11/extensions/XI.h> -#include <X11/extensions/XIproto.h> -#include <X11/extensions/XI2proto.h> -#include <X11/extensions/geproto.h> -#include "windowstr.h" -#include "miscstruct.h" -#include "region.h" -#include "exevents.h" -#include "extnsionst.h" -#include "exglobals.h" -#include "dixevents.h" /* DeliverFocusedEvent */ -#include "dixgrabs.h" /* CreateGrab() */ -#include "scrnintstr.h" -#include "listdev.h" /* for CopySwapXXXClass */ -#include "xace.h" -#include "xiquerydevice.h" /* For List*Info */ -#include "eventconvert.h" -#include "eventstr.h" - -#include <X11/extensions/XKBproto.h> -#include "xkbsrv.h" - -#define WID(w) ((w) ? ((w)->drawable.id) : 0) -#define AllModifiersMask ( \ - ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \ - Mod3Mask | Mod4Mask | Mod5Mask ) -#define AllButtonsMask ( \ - Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) - -Bool ShouldFreeInputMasks(WindowPtr /* pWin */ , - Bool /* ignoreSelectedEvents */ - ); -static Bool MakeInputMasks(WindowPtr /* pWin */ - ); - -/* Used to sture classes currently not in use by an MD */ -extern DevPrivateKey UnusedClassesPrivateKey; - -/* - * Only let the given client know of core events which will affect its - * interpretation of input events, if the client's ClientPointer (or the - * paired keyboard) is the current device. - */ -int -XIShouldNotify(ClientPtr client, DeviceIntPtr dev) -{ - DeviceIntPtr current_ptr = PickPointer(client); - DeviceIntPtr current_kbd = GetPairedDevice(current_ptr); - - if (dev == current_kbd || dev == current_ptr) - return 1; - - return 0; -} - -void -RegisterOtherDevice(DeviceIntPtr device) -{ - device->public.processInputProc = ProcessOtherEvent; - device->public.realInputProc = ProcessOtherEvent; -} - -Bool -IsPointerEvent(InternalEvent* event) -{ - switch(event->any.type) - { - case ET_ButtonPress: - case ET_ButtonRelease: - case ET_Motion: - /* XXX: enter/leave ?? */ - return TRUE; - default: - break; - } - return FALSE; -} - -/** - * @return the device matching the deviceid of the device set in the event, or - * NULL if the event is not an XInput event. - */ -DeviceIntPtr -XIGetDevice(xEvent* xE) -{ - DeviceIntPtr pDev = NULL; - - if (xE->u.u.type == DeviceButtonPress || - xE->u.u.type == DeviceButtonRelease || - xE->u.u.type == DeviceMotionNotify || - xE->u.u.type == ProximityIn || - xE->u.u.type == ProximityOut || - xE->u.u.type == DevicePropertyNotify) - { - int rc; - int id; - - id = ((deviceKeyButtonPointer*)xE)->deviceid & ~MORE_EVENTS; - - rc = dixLookupDevice(&pDev, id, serverClient, DixUnknownAccess); - if (rc != Success) - ErrorF("[dix] XIGetDevice failed on XACE restrictions (%d)\n", rc); - } - return pDev; -} - - -/** - * Copy the device->key into master->key and send a mapping notify to the - * clients if appropriate. - * master->key needs to be allocated by the caller. - * - * Device is the slave device. If it is attached to a master device, we may - * need to send a mapping notify to the client because it causes the MD - * to change state. - * - * Mapping notify needs to be sent in the following cases: - * - different slave device on same master - * - different master - * - * XXX: They way how the code is we also send a map notify if the slave device - * stays the same, but the master changes. This isn't really necessary though. - * - * XXX: this gives you funny behaviour with the ClientPointer. When a - * MappingNotify is sent to the client, the client usually responds with a - * GetKeyboardMapping. This will retrieve the ClientPointer's keyboard - * mapping, regardless of which keyboard sent the last mapping notify request. - * So depending on the CP setting, your keyboard may change layout in each - * app... - * - * This code is basically the old SwitchCoreKeyboard. - */ - -void -CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master) -{ - KeyClassPtr mk = master->key; - KeyClassPtr dk = device->key; - int i; - - if (device == master) - return; - - mk->sourceid = device->id; - - for (i = 0; i < 8; i++) - mk->modifierKeyCount[i] = dk->modifierKeyCount[i]; - - if (!XkbCopyDeviceKeymap(master, device)) - FatalError("Couldn't pivot keymap from device to core!\n"); -} - -/** - * Copies the feedback classes from device "from" into device "to". Classes - * are duplicated (not just flipping the pointers). All feedback classes are - * linked lists, the full list is duplicated. - */ -static void -DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to) -{ - ClassesPtr classes; - - - if (from->intfeed) - { - IntegerFeedbackPtr *i, it; - - if (!to->intfeed) - { - classes = dixLookupPrivate(&to->devPrivates, - UnusedClassesPrivateKey); - to->intfeed = classes->intfeed; - } - - i = &to->intfeed; - for (it = from->intfeed; it; it = it->next) - { - if (!(*i)) - { - *i = xcalloc(1, sizeof(IntegerFeedbackClassRec)); - if (!(*i)) - { - ErrorF("[Xi] Cannot alloc memory for class copy."); - return; - } - } - (*i)->CtrlProc = it->CtrlProc; - (*i)->ctrl = it->ctrl; - - i = &(*i)->next; - } - } else if (to->intfeed && !from->intfeed) - { - ClassesPtr classes; - classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); - classes->intfeed = to->intfeed; - to->intfeed = NULL; - } - - if (from->stringfeed) - { - StringFeedbackPtr *s, it; - - if (!to->stringfeed) - { - classes = dixLookupPrivate(&to->devPrivates, - UnusedClassesPrivateKey); - to->stringfeed = classes->stringfeed; - } - - s = &to->stringfeed; - for (it = from->stringfeed; it; it = it->next) - { - if (!(*s)) - { - *s = xcalloc(1, sizeof(StringFeedbackClassRec)); - if (!(*s)) - { - ErrorF("[Xi] Cannot alloc memory for class copy."); - return; - } - } - (*s)->CtrlProc = it->CtrlProc; - (*s)->ctrl = it->ctrl; - - s = &(*s)->next; - } - } else if (to->stringfeed && !from->stringfeed) - { - ClassesPtr classes; - classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); - classes->stringfeed = to->stringfeed; - to->stringfeed = NULL; - } - - if (from->bell) - { - BellFeedbackPtr *b, it; - - if (!to->bell) - { - classes = dixLookupPrivate(&to->devPrivates, - UnusedClassesPrivateKey); - to->bell = classes->bell; - } - - b = &to->bell; - for (it = from->bell; it; it = it->next) - { - if (!(*b)) - { - *b = xcalloc(1, sizeof(BellFeedbackClassRec)); - if (!(*b)) - { - ErrorF("[Xi] Cannot alloc memory for class copy."); - return; - } - } - (*b)->BellProc = it->BellProc; - (*b)->CtrlProc = it->CtrlProc; - (*b)->ctrl = it->ctrl; - - b = &(*b)->next; - } - } else if (to->bell && !from->bell) - { - ClassesPtr classes; - classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); - classes->bell = to->bell; - to->bell = NULL; - } - - if (from->leds) - { - LedFeedbackPtr *l, it; - - if (!to->leds) - { - classes = dixLookupPrivate(&to->devPrivates, - UnusedClassesPrivateKey); - to->leds = classes->leds; - } - - l = &to->leds; - for (it = from->leds; it; it = it->next) - { - if (!(*l)) - { - *l = xcalloc(1, sizeof(LedFeedbackClassRec)); - if (!(*l)) - { - ErrorF("[Xi] Cannot alloc memory for class copy."); - return; - } - } - (*l)->CtrlProc = it->CtrlProc; - (*l)->ctrl = it->ctrl; - if ((*l)->xkb_sli) - XkbFreeSrvLedInfo((*l)->xkb_sli); - (*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l); - - l = &(*l)->next; - } - } else if (to->leds && !from->leds) - { - ClassesPtr classes; - classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); - classes->leds = to->leds; - to->leds = NULL; - } -} - -static void -DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to) -{ - ClassesPtr classes; - - /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the - * kbdfeed to be set up properly, so let's do the feedback classes first. - */ - if (from->kbdfeed) - { - KbdFeedbackPtr *k, it; - - if (!to->kbdfeed) - { - classes = dixLookupPrivate(&to->devPrivates, - UnusedClassesPrivateKey); - - to->kbdfeed = classes->kbdfeed; - if (!to->kbdfeed) - InitKeyboardDeviceStruct(to, NULL, NULL, NULL); - } - - k = &to->kbdfeed; - for(it = from->kbdfeed; it; it = it->next) - { - if (!(*k)) - { - *k = xcalloc(1, sizeof(KbdFeedbackClassRec)); - if (!*k) - { - ErrorF("[Xi] Cannot alloc memory for class copy."); - return; - } - } - (*k)->BellProc = it->BellProc; - (*k)->CtrlProc = it->CtrlProc; - (*k)->ctrl = it->ctrl; - if ((*k)->xkb_sli) - XkbFreeSrvLedInfo((*k)->xkb_sli); - (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL); - - k = &(*k)->next; - } - } else if (to->kbdfeed && !from->kbdfeed) - { - ClassesPtr classes; - classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); - classes->kbdfeed = to->kbdfeed; - to->kbdfeed = NULL; - } - - if (from->key) - { - if (!to->key) - { - classes = dixLookupPrivate(&to->devPrivates, - UnusedClassesPrivateKey); - to->key = classes->key; - if (!to->key) - InitKeyboardDeviceStruct(to, NULL, NULL, NULL); - else - classes->key = NULL; - } - - CopyKeyClass(from, to); - } else if (to->key && !from->key) - { - ClassesPtr classes; - classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); - classes->key = to->key; - to->key = NULL; - } - - /* If a SrvLedInfoPtr's flags are XkbSLI_IsDefault, the names and maps - * pointer point into the xkbInfo->desc struct. XkbCopySrvLedInfo - * didn't update the pointers so we need to do it manually here. - */ - if (to->kbdfeed) - { - KbdFeedbackPtr k; - - for (k = to->kbdfeed; k; k = k->next) - { - if (!k->xkb_sli) - continue; - if (k->xkb_sli->flags & XkbSLI_IsDefault) - { - k->xkb_sli->names = to->key->xkbInfo->desc->names->indicators; - k->xkb_sli->maps = to->key->xkbInfo->desc->indicators->maps; - } - } - } - - /* We can't just copy over the focus class. When an app sets the focus, - * it'll do so on the master device. Copying the SDs focus means losing - * the focus. - * So we only copy the focus class if the device didn't have one, - * otherwise we leave it as it is. - */ - if (from->focus) - { - if (!to->focus) - { - WindowPtr *oldTrace; - - classes = dixLookupPrivate(&to->devPrivates, - UnusedClassesPrivateKey); - to->focus = classes->focus; - if (!to->focus) - { - to->focus = xcalloc(1, sizeof(FocusClassRec)); - if (!to->focus) - FatalError("[Xi] no memory for class shift.\n"); - } else - classes->focus = NULL; - - oldTrace = to->focus->trace; - memcpy(to->focus, from->focus, sizeof(FocusClassRec)); - to->focus->trace = xrealloc(oldTrace, - to->focus->traceSize * sizeof(WindowPtr)); - if (!to->focus->trace && to->focus->traceSize) - FatalError("[Xi] no memory for trace.\n"); - memcpy(to->focus->trace, from->focus->trace, - from->focus->traceSize * sizeof(WindowPtr)); - to->focus->sourceid = from->id; - } - } else if (to->focus) - { - ClassesPtr classes; - classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); - classes->focus = to->focus; - to->focus = NULL; - } - -} - -static void -DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to) -{ - ClassesPtr classes; - - /* Feedback classes must be copied first */ - if (from->ptrfeed) - { - PtrFeedbackPtr *p, it; - if (!to->ptrfeed) - { - classes = dixLookupPrivate(&to->devPrivates, - UnusedClassesPrivateKey); - to->ptrfeed = classes->ptrfeed; - } - - p = &to->ptrfeed; - for (it = from->ptrfeed; it; it = it->next) - { - if (!(*p)) - { - *p = xcalloc(1, sizeof(PtrFeedbackClassRec)); - if (!*p) - { - ErrorF("[Xi] Cannot alloc memory for class copy."); - return; - } - } - (*p)->CtrlProc = it->CtrlProc; - (*p)->ctrl = it->ctrl; - - p = &(*p)->next; - } - } else if (to->ptrfeed && !from->ptrfeed) - { - ClassesPtr classes; - classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); - classes->ptrfeed = to->ptrfeed; - to->ptrfeed = NULL; - } - - if (from->valuator) - { - ValuatorClassPtr v; - if (!to->valuator) - { - classes = dixLookupPrivate(&to->devPrivates, - UnusedClassesPrivateKey); - to->valuator = classes->valuator; - if (to->valuator) - classes->valuator = NULL; - } - - to->valuator = xrealloc(to->valuator, sizeof(ValuatorClassRec) + - from->valuator->numAxes * sizeof(AxisInfo) + - from->valuator->numAxes * sizeof(double)); - v = to->valuator; - if (!v) - FatalError("[Xi] no memory for class shift.\n"); - - v->numAxes = from->valuator->numAxes; - v->axes = (AxisInfoPtr)&v[1]; - memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo)); - - v->axisVal = (double*)(v->axes + from->valuator->numAxes); - v->sourceid = from->id; - v->mode = from->valuator->mode; - } else if (to->valuator && !from->valuator) - { - ClassesPtr classes; - classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); - classes->valuator = to->valuator; - to->valuator = NULL; - } - - if (from->button) - { - if (!to->button) - { - classes = dixLookupPrivate(&to->devPrivates, - UnusedClassesPrivateKey); - to->button = classes->button; - if (!to->button) - { - to->button = xcalloc(1, sizeof(ButtonClassRec)); - if (!to->button) - FatalError("[Xi] no memory for class shift.\n"); - } else - classes->button = NULL; - } - - if (from->button->xkb_acts) - { - if (!to->button->xkb_acts) - { - to->button->xkb_acts = xcalloc(1, sizeof(XkbAction)); - if (!to->button->xkb_acts) - FatalError("[Xi] not enough memory for xkb_acts.\n"); - } - memcpy(to->button->xkb_acts, from->button->xkb_acts, - sizeof(XkbAction)); - } else - xfree(to->button->xkb_acts); - - memcpy(to->button->labels, from->button->labels, - from->button->numButtons * sizeof(Atom)); - to->button->sourceid = from->id; - } else if (to->button && !from->button) - { - ClassesPtr classes; - classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); - classes->button = to->button; - to->button = NULL; - } - - if (from->proximity) - { - if (!to->proximity) - { - classes = dixLookupPrivate(&to->devPrivates, - UnusedClassesPrivateKey); - to->proximity = classes->proximity; - if (!to->proximity) - { - to->proximity = xcalloc(1, sizeof(ProximityClassRec)); - if (!to->proximity) - FatalError("[Xi] no memory for class shift.\n"); - } else - classes->proximity = NULL; - } - memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec)); - to->proximity->sourceid = from->id; - } else if (to->proximity) - { - ClassesPtr classes; - classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); - classes->proximity = to->proximity; - to->proximity = NULL; - } - - if (from->absolute) - { - if (!to->absolute) - { - classes = dixLookupPrivate(&to->devPrivates, - UnusedClassesPrivateKey); - to->absolute = classes->absolute; - if (!to->absolute) - { - to->absolute = xcalloc(1, sizeof(AbsoluteClassRec)); - if (!to->absolute) - FatalError("[Xi] no memory for class shift.\n"); - } else - classes->absolute = NULL; - } - memcpy(to->absolute, from->absolute, sizeof(AbsoluteClassRec)); - to->absolute->sourceid = from->id; - } else if (to->absolute) - { - ClassesPtr classes; - classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey); - classes->absolute = to->absolute; - to->absolute = NULL; - } -} - -/** - * Copies the CONTENT of the classes of device from into the classes in device - * to. From and to are identical after finishing. - * - * If to does not have classes from currenly has, the classes are stored in - * to's devPrivates system. Later, we recover it again from there if needed. - * Saves a few memory allocations. - */ -void -DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dce) -{ - /* generic feedback classes, not tied to pointer and/or keyboard */ - DeepCopyFeedbackClasses(from, to); - - if ((dce->flags & DEVCHANGE_KEYBOARD_EVENT)) - DeepCopyKeyboardClasses(from, to); - if ((dce->flags & DEVCHANGE_POINTER_EVENT)) - DeepCopyPointerClasses(from, to); -} - - -/** - * Send an XI2 DeviceChangedEvent to all interested clients. - */ -void -XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChangedEvent *dce) -{ - xXIDeviceChangedEvent *dcce; - int rc; - - rc = EventToXI2((InternalEvent*)dce, (xEvent**)&dcce); - if (rc != Success) - { - ErrorF("[Xi] event conversion from DCE failed with code %d\n", rc); - return; - } - - /* we don't actually swap if there's a NullClient, swapping is done - * later when event is delivered. */ - SendEventToAllWindows(master, XI_DeviceChangedMask, (xEvent*)dcce, 1); - xfree(dcce); -} - -static void -ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce) -{ - DeviceIntPtr slave; - int rc; - - /* For now, we don't have devices that change physically. */ - if (!IsMaster(device)) - return; - - rc = dixLookupDevice(&slave, dce->sourceid, serverClient, DixReadAccess); - - if (rc != Success) - return; /* Device has disappeared */ - - if (!slave->u.master) - return; /* set floating since the event */ - - if (slave->u.master->id != dce->masterid) - return; /* not our slave anymore, don't care */ - - /* FIXME: we probably need to send a DCE for the new slave now */ - - device->public.devicePrivate = slave->public.devicePrivate; - - /* FIXME: the classes may have changed since we generated the event. */ - DeepCopyDeviceClasses(slave, device, dce); - XISendDeviceChangedEvent(slave, device, dce); -} - -/** - * Update the device state according to the data in the event. - * - * return values are - * DEFAULT ... process as normal - * DONT_PROCESS ... return immediately from caller - */ -#define DEFAULT 0 -#define DONT_PROCESS 1 -int -UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event) -{ - int i; - int key = 0, - bit = 0, - last_valuator; - - KeyClassPtr k = NULL; - ButtonClassPtr b = NULL; - ValuatorClassPtr v = NULL; - BYTE *kptr = NULL; - - /* This event is always the first we get, before the actual events with - * the data. However, the way how the DDX is set up, "device" will - * actually be the slave device that caused the event. - */ - switch(event->type) - { - case ET_DeviceChanged: - ChangeMasterDeviceClasses(device, (DeviceChangedEvent*)event); - return DONT_PROCESS; /* event has been sent already */ - case ET_Motion: - case ET_ButtonPress: - case ET_ButtonRelease: - case ET_KeyPress: - case ET_KeyRelease: - case ET_ProximityIn: - case ET_ProximityOut: - break; - default: - /* other events don't update the device */ - return DEFAULT; - } - - k = device->key; - v = device->valuator; - b = device->button; - - key = event->detail.key; - bit = 1 << (key & 7); - - /* Update device axis */ - /* Check valuators first */ - last_valuator = -1; - for (i = 0; i < MAX_VALUATORS; i++) - { - if (BitIsOn(&event->valuators.mask, i)) - { - if (!v) - { - ErrorF("[Xi] Valuators reported for non-valuator device '%s'. " - "Ignoring event.\n", device->name); - return DONT_PROCESS; - } else if (v->numAxes < i) - { - ErrorF("[Xi] Too many valuators reported for device '%s'. " - "Ignoring event.\n", device->name); - return DONT_PROCESS; - } - last_valuator = i; - } - } - - for (i = 0; i <= last_valuator && i < v->numAxes; i++) - { - if (BitIsOn(&event->valuators.mask, i)) - { - /* XXX: Relative/Absolute mode */ - v->axisVal[i] = event->valuators.data[i]; - v->axisVal[i] += (event->valuators.data_frac[i] * 1.0f / (1 << 16) / (1 << 16)); - } - } - - if (event->type == ET_KeyPress) { - if (!k) - return DONT_PROCESS; - - kptr = &k->down[key >> 3]; - /* don't allow ddx to generate multiple downs, but repeats are okay */ - if ((*kptr & bit) && !event->key_repeat) - return DONT_PROCESS; - if (device->valuator) - device->valuator->motionHintWindow = NullWindow; - *kptr |= bit; - } else if (event->type == ET_KeyRelease) { - if (!k) - return DONT_PROCESS; - - kptr = &k->down[key >> 3]; - if (!(*kptr & bit)) /* guard against duplicates */ - return DONT_PROCESS; - if (device->valuator) - device->valuator->motionHintWindow = NullWindow; - *kptr &= ~bit; - } else if (event->type == ET_ButtonPress) { - Mask mask; - if (!b) - return DONT_PROCESS; - - kptr = &b->down[key >> 3]; - if ((*kptr & bit) != 0) - return DONT_PROCESS; - *kptr |= bit; - if (device->valuator) - device->valuator->motionHintWindow = NullWindow; - if (!b->map[key]) - return DONT_PROCESS; - b->buttonsDown++; - b->motionMask = DeviceButtonMotionMask; - if (b->map[key] <= 5) - b->state |= (Button1Mask >> 1) << b->map[key]; - - /* Add state and motionMask to the filter for this event */ - mask = DevicePointerMotionMask | b->state | b->motionMask; - SetMaskForEvent(device->id, mask, DeviceMotionNotify); - mask = PointerMotionMask | b->state | b->motionMask; - SetMaskForEvent(device->id, mask, MotionNotify); - } else if (event->type == ET_ButtonRelease) { - Mask mask; - if (!b) - return DONT_PROCESS; - - kptr = &b->down[key>>3]; - if (!(*kptr & bit)) - return DONT_PROCESS; - if (IsMaster(device)) { - DeviceIntPtr sd; - - /* - * Leave the button down if any slave has the - * button still down. Note that this depends on the - * event being delivered through the slave first - */ - for (sd = inputInfo.devices; sd; sd = sd->next) { - if (IsMaster(sd) || sd->u.master != device) - continue; - if (!sd->button) - continue; - if ((sd->button->down[key>>3] & bit) != 0) - return DONT_PROCESS; - } - } - *kptr &= ~bit; - if (device->valuator) - device->valuator->motionHintWindow = NullWindow; - if (!b->map[key]) - return DONT_PROCESS; - if (b->buttonsDown >= 1 && !--b->buttonsDown) - b->motionMask = 0; - if (b->map[key] <= 5) - b->state &= ~((Button1Mask >> 1) << b->map[key]); - - /* Add state and motionMask to the filter for this event */ - mask = DevicePointerMotionMask | b->state | b->motionMask; - SetMaskForEvent(device->id, mask, DeviceMotionNotify); - mask = PointerMotionMask | b->state | b->motionMask; - SetMaskForEvent(device->id, mask, MotionNotify); - } else if (event->type == ET_ProximityIn) - device->valuator->mode &= ~OutOfProximity; - else if (event->type == ET_ProximityOut) - device->valuator->mode |= OutOfProximity; - - return DEFAULT; -} - -static void -ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device) -{ - GrabPtr grab = device->deviceGrab.grab; - - if (grab) - DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE); - else { /* deliver to all root windows */ - xEvent *xi; - int i; - - i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi); - if (i != Success) - { - ErrorF("[Xi] %s: XI2 conversion failed in ProcessRawEvent (%d)\n", - device->name, i); - return; - } - - for (i = 0; i < screenInfo.numScreens; i++) - DeliverEventsToWindow(device, WindowTable[i], xi, 1, - GetEventFilter(device, xi), NULL); - xfree(xi); - } -} - -/** - * Main device event processing function. - * Called from when processing the events from the event queue. - * - */ -void -ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device) -{ - GrabPtr grab; - Bool deactivateDeviceGrab = FALSE; - int key = 0, rootX, rootY; - ButtonClassPtr b; - KeyClassPtr k; - ValuatorClassPtr v; - int ret = 0; - int state, i; - DeviceIntPtr mouse = NULL, kbd = NULL; - DeviceEvent *event = &ev->device_event; - - CHECKEVENT(ev); - - if (ev->any.type == ET_RawKeyPress || - ev->any.type == ET_RawKeyRelease || - ev->any.type == ET_RawButtonPress || - ev->any.type == ET_RawButtonRelease || - ev->any.type == ET_RawMotion) - { - ProcessRawEvent(&ev->raw_event, device); - return; - } - - if (IsPointerDevice(device)) - { - kbd = GetPairedDevice(device); - mouse = device; - if (!kbd->key) /* can happen with floating SDs */ - kbd = NULL; - } else - { - mouse = GetPairedDevice(device); - kbd = device; - if (!mouse->valuator || !mouse->button) /* may be float. SDs */ - mouse = NULL; - } - - /* State needs to be assembled BEFORE the device is updated. */ - state = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0; - state |= (mouse && mouse->button) ? (mouse->button->state) : 0; - - for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) - if (BitIsOn(mouse->button->down, i)) - SetBit(event->buttons, i); - - if (kbd && kbd->key) - { - XkbStatePtr state; - /* we need the state before the event happens */ - if (event->type == ET_KeyPress || event->type == ET_KeyRelease) - state = &kbd->key->xkbInfo->prev_state; - else - state = &kbd->key->xkbInfo->state; - - event->mods.base = state->base_mods; - event->mods.latched = state->latched_mods; - event->mods.locked = state->locked_mods; - event->mods.effective = state->mods; - - event->group.base = state->base_group; - event->group.latched = state->latched_group; - event->group.locked = state->locked_group; - event->group.effective = state->group; - } - - ret = UpdateDeviceState(device, event); - if (ret == DONT_PROCESS) - return; - - v = device->valuator; - b = device->button; - k = device->key; - - if (IsMaster(device) || !device->u.master) - CheckMotion(event, device); - - switch (event->type) - { - case ET_Motion: - case ET_ButtonPress: - case ET_ButtonRelease: - case ET_KeyPress: - case ET_KeyRelease: - case ET_ProximityIn: - case ET_ProximityOut: - GetSpritePosition(device, &rootX, &rootY); - event->root_x = rootX; - event->root_y = rootY; - NoticeEventTime((InternalEvent*)event); - event->corestate = state; - key = event->detail.key; - break; - default: - break; - } - - if (DeviceEventCallback) { - DeviceEventInfoRec eventinfo; - SpritePtr pSprite = device->spriteInfo->sprite; - xEvent *xi_events = NULL; - int count; - - /* see comment in EnqueueEvents regarding the next three lines */ - if (ev->any.type == ET_Motion) - ev->device_event.root = - WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id; - - /* SDs send XI events only. MDs send both an XI event and a core - * event. - */ - EventToXI(ev, &xi_events, &count); - - eventinfo.events = (xEventPtr)xi_events; - eventinfo.count = count; - ErrorF("POE xi root is %lx\n", xi_events->u.keyButtonPointer.root); - CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); - xfree(xi_events); - - if (IsMaster(device)) - { - xEvent core; - EventToCore(ev, &core); - eventinfo.events = (xEventPtr)&core; - eventinfo.count = 1; - ErrorF("POE core root is %lx\n", core.u.keyButtonPointer.root); - CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); - } - - } - grab = device->deviceGrab.grab; - - switch(event->type) - { - case ET_KeyPress: - if (!grab && CheckDeviceGrabs(device, event, 0)) { - device->deviceGrab.activatingKey = key; - return; - } - break; - case ET_KeyRelease: - if (grab && device->deviceGrab.fromPassiveGrab && - (key == device->deviceGrab.activatingKey) && - (device->deviceGrab.grab->type == KeyPress || - device->deviceGrab.grab->type == DeviceKeyPress || - device->deviceGrab.grab->type == XI_KeyPress)) - deactivateDeviceGrab = TRUE; - break; - case ET_ButtonPress: - event->detail.button = b->map[key]; - if (!event->detail.button) { /* there's no button 0 */ - event->detail.button = key; - return; - } - if (!grab && CheckDeviceGrabs(device, event, 0)) - { - /* if a passive grab was activated, the event has been sent - * already */ - return; - } - break; - case ET_ButtonRelease: - event->detail.button = b->map[key]; - if (!event->detail.button) { /* there's no button 0 */ - event->detail.button = key; - return; - } - if (grab && !b->buttonsDown && - device->deviceGrab.fromPassiveGrab && - (device->deviceGrab.grab->type == ButtonPress || - device->deviceGrab.grab->type == DeviceButtonPress || - device->deviceGrab.grab->type == XI_ButtonPress)) - deactivateDeviceGrab = TRUE; - default: - break; - } - - - if (grab) - DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab); - else if (device->focus && !IsPointerEvent((InternalEvent*)ev)) - DeliverFocusedEvent(device, (InternalEvent*)event, - GetSpriteWindow(device)); - else - DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent*)event, - NullGrab, NullWindow, device); - - if (deactivateDeviceGrab == TRUE) - (*device->deviceGrab.DeactivateGrab) (device); - event->detail.key = key; -} - -int -InitProximityClassDeviceStruct(DeviceIntPtr dev) -{ - ProximityClassPtr proxc; - - proxc = (ProximityClassPtr) xalloc(sizeof(ProximityClassRec)); - if (!proxc) - return FALSE; - proxc->sourceid = dev->id; - dev->proximity = proxc; - return TRUE; -} - -/** - * Initialise the device's valuators. The memory must already be allocated, - * this function merely inits the matching axis (specified through axnum) to - * sane values. - * - * It is a condition that (minval < maxval). - * - * @see InitValuatorClassDeviceStruct - */ -void -InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval, - int resolution, int min_res, int max_res) -{ - AxisInfoPtr ax; - - if (!dev || !dev->valuator || minval > maxval) - return; - if (axnum >= dev->valuator->numAxes) - return; - - ax = dev->valuator->axes + axnum; - - ax->min_value = minval; - ax->max_value = maxval; - ax->resolution = resolution; - ax->min_resolution = min_res; - ax->max_resolution = max_res; - ax->label = label; -} - -static void -FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k, - ButtonClassPtr b, ValuatorClassPtr v, int first) -{ - ev->type = DeviceStateNotify; - ev->deviceid = dev->id; - ev->time = currentTime.milliseconds; - ev->classes_reported = 0; - ev->num_keys = 0; - ev->num_buttons = 0; - ev->num_valuators = 0; - - if (b) { - ev->classes_reported |= (1 << ButtonClass); - ev->num_buttons = b->numButtons; - memcpy((char*)ev->buttons, (char*)b->down, 4); - } else if (k) { - ev->classes_reported |= (1 << KeyClass); - ev->num_keys = k->xkbInfo->desc->max_key_code - - k->xkbInfo->desc->min_key_code; - memmove((char *)&ev->keys[0], (char *)k->down, 4); - } - if (v) { - int nval = v->numAxes - first; - - ev->classes_reported |= (1 << ValuatorClass); - ev->classes_reported |= (dev->valuator->mode << ModeBitsShift); - ev->num_valuators = nval < 3 ? nval : 3; - switch (ev->num_valuators) { - case 3: - ev->valuator2 = v->axisVal[first + 2]; - case 2: - ev->valuator1 = v->axisVal[first + 1]; - case 1: - ev->valuator0 = v->axisVal[first]; - break; - } - } -} - -static void -FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v, - int first) -{ - int nval = v->numAxes - first; - - ev->type = DeviceValuator; - ev->deviceid = dev->id; - ev->num_valuators = nval < 3 ? nval : 3; - ev->first_valuator = first; - switch (ev->num_valuators) { - case 3: - ev->valuator2 = v->axisVal[first + 2]; - case 2: - ev->valuator1 = v->axisVal[first + 1]; - case 1: - ev->valuator0 = v->axisVal[first]; - break; - } - first += ev->num_valuators; -} - -void -DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, - WindowPtr pWin) -{ - deviceFocus event; - xXIFocusInEvent *xi2event; - DeviceIntPtr mouse; - int btlen, len, i; - - mouse = (IsMaster(dev) || dev->u.master) ? GetMaster(dev, MASTER_POINTER) : dev; - - /* XI 2 event */ - btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; - btlen = bytes_to_int32(btlen); - len = sizeof(xXIFocusInEvent) + btlen * 4; - - xi2event = xcalloc(1, len); - xi2event->type = GenericEvent; - xi2event->extension = IReqCode; - xi2event->evtype = type; - xi2event->length = bytes_to_int32(len - sizeof(xEvent)); - xi2event->buttons_len = btlen; - xi2event->detail = detail; - xi2event->time = currentTime.milliseconds; - xi2event->deviceid = dev->id; - xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */ - xi2event->mode = mode; - xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0); - xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0); - - for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) - if (BitIsOn(mouse->button->down, i)) - SetBit(&xi2event[1], i); - - if (dev->key) - { - xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods; - xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods; - xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods; - xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods; - - xi2event->group.base_group = dev->key->xkbInfo->state.base_group; - xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group; - xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group; - xi2event->group.effective_group = dev->key->xkbInfo->state.group; - } - - FixUpEventFromWindow(dev, (xEvent*)xi2event, pWin, None, FALSE); - - DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1, - GetEventFilter(dev, (xEvent*)xi2event), NullGrab); - - xfree(xi2event); - - /* XI 1.x event */ - event.deviceid = dev->id; - event.mode = mode; - event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut; - event.detail = detail; - event.window = pWin->drawable.id; - event.time = currentTime.milliseconds; - - DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1, - DeviceFocusChangeMask, NullGrab); - - if ((type == DeviceFocusIn) && - (wOtherInputMasks(pWin)) && - (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask)) - { - int evcount = 1; - deviceStateNotify *ev, *sev; - deviceKeyStateNotify *kev; - deviceButtonStateNotify *bev; - - KeyClassPtr k; - ButtonClassPtr b; - ValuatorClassPtr v; - int nval = 0, nkeys = 0, nbuttons = 0, first = 0; - - if ((b = dev->button) != NULL) { - nbuttons = b->numButtons; - if (nbuttons > 32) - evcount++; - } - if ((k = dev->key) != NULL) { - nkeys = k->xkbInfo->desc->max_key_code - - k->xkbInfo->desc->min_key_code; - if (nkeys > 32) - evcount++; - if (nbuttons > 0) { - evcount++; - } - } - if ((v = dev->valuator) != NULL) { - nval = v->numAxes; - - if (nval > 3) - evcount++; - if (nval > 6) { - if (!(k && b)) - evcount++; - if (nval > 9) - evcount += ((nval - 7) / 3); - } - } - - sev = ev = (deviceStateNotify *) xalloc(evcount * sizeof(xEvent)); - FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first); - - if (b != NULL) { - FixDeviceStateNotify(dev, ev++, NULL, b, v, first); - first += 3; - nval -= 3; - if (nbuttons > 32) { - (ev - 1)->deviceid |= MORE_EVENTS; - bev = (deviceButtonStateNotify *) ev++; - bev->type = DeviceButtonStateNotify; - bev->deviceid = dev->id; - memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4); - } - if (nval > 0) { - (ev - 1)->deviceid |= MORE_EVENTS; - FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); - first += 3; - nval -= 3; - } - } - - if (k != NULL) { - FixDeviceStateNotify(dev, ev++, k, NULL, v, first); - first += 3; - nval -= 3; - if (nkeys > 32) { - (ev - 1)->deviceid |= MORE_EVENTS; - kev = (deviceKeyStateNotify *) ev++; - kev->type = DeviceKeyStateNotify; - kev->deviceid = dev->id; - memmove((char *)&kev->keys[0], (char *)&k->down[4], 28); - } - if (nval > 0) { - (ev - 1)->deviceid |= MORE_EVENTS; - FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); - first += 3; - nval -= 3; - } - } - - while (nval > 0) { - FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first); - first += 3; - nval -= 3; - if (nval > 0) { - (ev - 1)->deviceid |= MORE_EVENTS; - FixDeviceValuator(dev, (deviceValuator *) ev++, v, first); - first += 3; - nval -= 3; - } - } - - DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount, - DeviceStateNotifyMask, NullGrab); - xfree(sev); - } -} - -int -CheckGrabValues(ClientPtr client, GrabParameters* param) -{ - if (param->grabtype != GRABTYPE_CORE && - param->grabtype != GRABTYPE_XI && - param->grabtype != GRABTYPE_XI2) - { - ErrorF("[Xi] grabtype is invalid. This is a bug.\n"); - return BadImplementation; - } - - if ((param->this_device_mode != GrabModeSync) && - (param->this_device_mode != GrabModeAsync)) { - client->errorValue = param->this_device_mode; - return BadValue; - } - if ((param->other_devices_mode != GrabModeSync) && - (param->other_devices_mode != GrabModeAsync)) { - client->errorValue = param->other_devices_mode; - return BadValue; - } - - if (param->grabtype != GRABTYPE_XI2 && (param->modifiers != AnyModifier) && - (param->modifiers & ~AllModifiersMask)) { - client->errorValue = param->modifiers; - return BadValue; - } - - if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) { - client->errorValue = param->ownerEvents; - return BadValue; - } - return Success; -} - -int -GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, - int button, GrabParameters *param, GrabType grabtype, - GrabMask *mask) -{ - WindowPtr pWin, confineTo; - CursorPtr cursor; - GrabPtr grab; - int rc, type = -1; - Mask access_mode = DixGrabAccess; - - rc = CheckGrabValues(client, param); - if (rc != Success) - return rc; - if (param->confineTo == None) - confineTo = NullWindow; - else { - rc = dixLookupWindow(&confineTo, param->confineTo, client, DixSetAttrAccess); - if (rc != Success) - return rc; - } - if (param->cursor == None) - cursor = NullCursor; - else { - rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, - RT_CURSOR, client, DixUseAccess); - if (rc != Success) - { - client->errorValue = param->cursor; - return (rc == BadValue) ? BadCursor : rc; - } - access_mode |= DixForceAccess; - } - if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) - access_mode |= DixFreezeAccess; - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); - if (rc != Success) - return rc; - rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); - if (rc != Success) - return rc; - - if (grabtype == GRABTYPE_XI) - type = DeviceButtonPress; - else if (grabtype == GRABTYPE_XI2) - type = XI_ButtonPress; - - grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, - mask, param, type, button, confineTo, cursor); - if (!grab) - return BadAlloc; - return AddPassiveGrabToList(client, grab); -} - -/** - * Grab the given key. If grabtype is GRABTYPE_XI, the key is a keycode. If - * grabtype is GRABTYPE_XI2, the key is a keysym. - */ -int -GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device, - int key, GrabParameters *param, GrabType grabtype, GrabMask *mask) -{ - WindowPtr pWin; - GrabPtr grab; - KeyClassPtr k = dev->key; - Mask access_mode = DixGrabAccess; - int rc, type = -1; - - rc = CheckGrabValues(client, param); - if (rc != Success) - return rc; - if (k == NULL) - return BadMatch; - if (grabtype == GRABTYPE_XI) - { - if ((key > k->xkbInfo->desc->max_key_code || - key < k->xkbInfo->desc->min_key_code) - && (key != AnyKey)) { - client->errorValue = key; - return BadValue; - } - type = DeviceKeyPress; - } else if (grabtype == GRABTYPE_XI2) - type = XI_KeyPress; - - rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); - if (rc != Success) - return rc; - if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) - access_mode |= DixFreezeAccess; - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); - if (rc != Success) - return rc; - - grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype, - mask, param, type, key, NULL, NULL); - if (!grab) - return BadAlloc; - return AddPassiveGrabToList(client, grab); -} - -/* Enter/FocusIn grab */ -int -GrabWindow(ClientPtr client, DeviceIntPtr dev, int type, - GrabParameters *param, GrabMask *mask) -{ - WindowPtr pWin; - CursorPtr cursor; - GrabPtr grab; - Mask access_mode = DixGrabAccess; - int rc; - - rc = CheckGrabValues(client, param); - if (rc != Success) - return rc; - - rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess); - if (rc != Success) - return rc; - if (param->cursor == None) - cursor = NullCursor; - else { - rc = dixLookupResourceByType((pointer *)&cursor, param->cursor, - RT_CURSOR, client, DixUseAccess); - if (rc != Success) - { - client->errorValue = param->cursor; - return (rc == BadValue) ? BadCursor : rc; - } - access_mode |= DixForceAccess; - } - if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync) - access_mode |= DixFreezeAccess; - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); - if (rc != Success) - return rc; - - grab = CreateGrab(client->index, dev, dev, pWin, GRABTYPE_XI2, - mask, param, (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn, - 0, NULL, cursor); - - if (!grab) - return BadAlloc; - - return AddPassiveGrabToList(client, grab); -} - -int -SelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client, - Mask mask, Mask exclusivemasks) -{ - int mskidx = dev->id; - int i, ret; - Mask check; - InputClientsPtr others; - - check = (mask & exclusivemasks); - if (wOtherInputMasks(pWin)) { - if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different - * clients to select on any of the - * events for maskcheck. However, - * it is OK, for some client to - * continue selecting on one of those - * events. */ - for (others = wOtherInputMasks(pWin)->inputClients; others; - others = others->next) { - if (!SameClient(others, client) && (check & - others->mask[mskidx])) - return BadAccess; - } - } - for (others = wOtherInputMasks(pWin)->inputClients; others; - others = others->next) { - if (SameClient(others, client)) { - check = others->mask[mskidx]; - others->mask[mskidx] = mask; - if (mask == 0) { - for (i = 0; i < EMASKSIZE; i++) - if (i != mskidx && others->mask[i] != 0) - break; - if (i == EMASKSIZE) { - RecalculateDeviceDeliverableEvents(pWin); - if (ShouldFreeInputMasks(pWin, FALSE)) - FreeResource(others->resource, RT_NONE); - return Success; - } - } - goto maskSet; - } - } - } - check = 0; - if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success) - return ret; - maskSet: - if (dev->valuator) - if ((dev->valuator->motionHintWindow == pWin) && - (mask & DevicePointerMotionHintMask) && - !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab) - dev->valuator->motionHintWindow = NullWindow; - RecalculateDeviceDeliverableEvents(pWin); - return Success; -} - -int -AddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx) -{ - InputClientsPtr others; - - if (!pWin->optional && !MakeWindowOptional(pWin)) - return BadAlloc; - others = xcalloc(1, sizeof(InputClients)); - if (!others) - return BadAlloc; - if (!pWin->optional->inputMasks && !MakeInputMasks(pWin)) - return BadAlloc; - others->mask[mskidx] = mask; - others->resource = FakeClientID(client->index); - others->next = pWin->optional->inputMasks->inputClients; - pWin->optional->inputMasks->inputClients = others; - if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin)) - return BadAlloc; - return Success; -} - -static Bool -MakeInputMasks(WindowPtr pWin) -{ - struct _OtherInputMasks *imasks; - - imasks = xcalloc(1, sizeof(struct _OtherInputMasks)); - if (!imasks) - return FALSE; - pWin->optional->inputMasks = imasks; - return TRUE; -} - -void -RecalculateDeviceDeliverableEvents(WindowPtr pWin) -{ - InputClientsPtr others; - struct _OtherInputMasks *inputMasks; /* default: NULL */ - WindowPtr pChild, tmp; - int i, j; - - pChild = pWin; - while (1) { - if ((inputMasks = wOtherInputMasks(pChild)) != 0) { - for (i = 0; i < EMASKSIZE; i++) - memset(inputMasks->xi2mask[i], 0, sizeof(inputMasks->xi2mask[i])); - for (others = inputMasks->inputClients; others; - others = others->next) { - for (i = 0; i < EMASKSIZE; i++) - inputMasks->inputEvents[i] |= others->mask[i]; - for (i = 0; i < EMASKSIZE; i++) - for (j = 0; j < XI2MASKSIZE; j++) - inputMasks->xi2mask[i][j] |= others->xi2mask[i][j]; - } - for (i = 0; i < EMASKSIZE; i++) - inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i]; - for (tmp = pChild->parent; tmp; tmp = tmp->parent) - if (wOtherInputMasks(tmp)) - for (i = 0; i < EMASKSIZE; i++) - inputMasks->deliverableEvents[i] |= - (wOtherInputMasks(tmp)->deliverableEvents[i] - & ~inputMasks-> - dontPropagateMask[i] & PropagateMask[i]); - } - if (pChild->firstChild) { - pChild = pChild->firstChild; - continue; - } - while (!pChild->nextSib && (pChild != pWin)) - pChild = pChild->parent; - if (pChild == pWin) - break; - pChild = pChild->nextSib; - } -} - -int -InputClientGone(WindowPtr pWin, XID id) -{ - InputClientsPtr other, prev; - - if (!wOtherInputMasks(pWin)) - return (Success); - prev = 0; - for (other = wOtherInputMasks(pWin)->inputClients; other; - other = other->next) { - if (other->resource == id) { - if (prev) { - prev->next = other->next; - xfree(other); - } else if (!(other->next)) { - if (ShouldFreeInputMasks(pWin, TRUE)) { - wOtherInputMasks(pWin)->inputClients = other->next; - xfree(wOtherInputMasks(pWin)); - pWin->optional->inputMasks = (OtherInputMasks *) NULL; - CheckWindowOptionalNeed(pWin); - xfree(other); - } else { - other->resource = FakeClientID(0); - if (!AddResource(other->resource, RT_INPUTCLIENT, - (pointer) pWin)) - return BadAlloc; - } - } else { - wOtherInputMasks(pWin)->inputClients = other->next; - xfree(other); - } - RecalculateDeviceDeliverableEvents(pWin); - return (Success); - } - prev = other; - } - FatalError("client not on device event list"); -} - -int -SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate, - xEvent * ev, Mask mask, int count) -{ - WindowPtr pWin; - WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ - WindowPtr spriteWin = GetSpriteWindow(d); - - if (dest == PointerWindow) - pWin = spriteWin; - else if (dest == InputFocus) { - WindowPtr inputFocus; - - if (!d->focus) - inputFocus = spriteWin; - else - inputFocus = d->focus->win; - - if (inputFocus == FollowKeyboardWin) - inputFocus = inputInfo.keyboard->focus->win; - - if (inputFocus == NoneWin) - return Success; - - /* If the input focus is PointerRootWin, send the event to where - * the pointer is if possible, then perhaps propogate up to root. */ - if (inputFocus == PointerRootWin) - inputFocus = GetCurrentRootWindow(d); - - if (IsParent(inputFocus, spriteWin)) { - effectiveFocus = inputFocus; - pWin = spriteWin; - } else - effectiveFocus = pWin = inputFocus; - } else - dixLookupWindow(&pWin, dest, client, DixSendAccess); - if (!pWin) - return BadWindow; - if ((propagate != xFalse) && (propagate != xTrue)) { - client->errorValue = propagate; - return BadValue; - } - ev->u.u.type |= 0x80; - if (propagate) { - for (; pWin; pWin = pWin->parent) { - if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab)) - return Success; - if (pWin == effectiveFocus) - return Success; - if (wOtherInputMasks(pWin)) - mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id]; - if (!mask) - break; - } - } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count)) - DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab); - return Success; -} - -int -SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map) -{ - int i; - ButtonClassPtr b = dev->button; - - if (b == NULL) - return BadMatch; - - if (nElts != b->numButtons) { - client->errorValue = nElts; - return BadValue; - } - if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue)) - return BadValue; - for (i = 0; i < nElts; i++) - if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1)) - return MappingBusy; - for (i = 0; i < nElts; i++) - b->map[i + 1] = map[i]; - return Success; -} - -int -ChangeKeyMapping(ClientPtr client, - DeviceIntPtr dev, - unsigned len, - int type, - KeyCode firstKeyCode, - CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map) -{ - KeySymsRec keysyms; - KeyClassPtr k = dev->key; - - if (k == NULL) - return (BadMatch); - - if (len != (keyCodes * keySymsPerKeyCode)) - return BadLength; - - if ((firstKeyCode < k->xkbInfo->desc->min_key_code) || - (firstKeyCode + keyCodes - 1 > k->xkbInfo->desc->max_key_code)) { - client->errorValue = firstKeyCode; - return BadValue; - } - if (keySymsPerKeyCode == 0) { - client->errorValue = 0; - return BadValue; - } - keysyms.minKeyCode = firstKeyCode; - keysyms.maxKeyCode = firstKeyCode + keyCodes - 1; - keysyms.mapWidth = keySymsPerKeyCode; - keysyms.map = map; - - XkbApplyMappingChange(dev, &keysyms, firstKeyCode, keyCodes, NULL, - serverClient); - - return client->noClientException; -} - -static void -DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev) -{ - WindowPtr parent; - - /* Deactivate any grabs performed on this window, before making - * any input focus changes. - * Deactivating a device grab should cause focus events. */ - - if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin)) - (*dev->deviceGrab.DeactivateGrab) (dev); - - /* If the focus window is a root window (ie. has no parent) - * then don't delete the focus from it. */ - - if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) { - int focusEventMode = NotifyNormal; - - /* If a grab is in progress, then alter the mode of focus events. */ - - if (dev->deviceGrab.grab) - focusEventMode = NotifyWhileGrabbed; - - switch (dev->focus->revert) { - case RevertToNone: - if (!ActivateFocusInGrab(dev, pWin, NoneWin)) - DoFocusEvents(dev, pWin, NoneWin, focusEventMode); - dev->focus->win = NoneWin; - dev->focus->traceGood = 0; - break; - case RevertToParent: - parent = pWin; - do { - parent = parent->parent; - dev->focus->traceGood--; - } - while (!parent->realized); - if (!ActivateFocusInGrab(dev, pWin, parent)) - DoFocusEvents(dev, pWin, parent, focusEventMode); - dev->focus->win = parent; - dev->focus->revert = RevertToNone; - break; - case RevertToPointerRoot: - if (!ActivateFocusInGrab(dev, pWin, PointerRootWin)) - DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode); - dev->focus->win = PointerRootWin; - dev->focus->traceGood = 0; - break; - case RevertToFollowKeyboard: - { - DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD); - if (!kbd || (kbd == dev && kbd != inputInfo.keyboard)) - kbd = inputInfo.keyboard; - if (kbd->focus->win) { - if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win)) - DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode); - dev->focus->win = FollowKeyboardWin; - dev->focus->traceGood = 0; - } else { - if (!ActivateFocusInGrab(dev, pWin, NoneWin)) - DoFocusEvents(dev, pWin, NoneWin, focusEventMode); - dev->focus->win = NoneWin; - dev->focus->traceGood = 0; - } - } - break; - } - } - - if (dev->valuator) - if (dev->valuator->motionHintWindow == pWin) - dev->valuator->motionHintWindow = NullWindow; -} - -void -DeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources) -{ - int i; - DeviceIntPtr dev; - InputClientsPtr ic; - struct _OtherInputMasks *inputMasks; - - for (dev = inputInfo.devices; dev; dev = dev->next) { - DeleteDeviceFromAnyExtEvents(pWin, dev); - } - - for (dev = inputInfo.off_devices; dev; dev = dev->next) - DeleteDeviceFromAnyExtEvents(pWin, dev); - - if (freeResources) - while ((inputMasks = wOtherInputMasks(pWin)) != 0) { - ic = inputMasks->inputClients; - for (i = 0; i < EMASKSIZE; i++) - inputMasks->dontPropagateMask[i] = 0; - FreeResource(ic->resource, RT_NONE); - } -} - -int -MaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer * pEvents, Mask mask) -{ - DeviceIntPtr dev; - - dixLookupDevice(&dev, pEvents->deviceid & DEVICE_BITS, serverClient, - DixReadAccess); - if (!dev) - return 0; - - if (pEvents->type == DeviceMotionNotify) { - if (mask & DevicePointerMotionHintMask) { - if (WID(dev->valuator->motionHintWindow) == pEvents->event) { - return 1; /* don't send, but pretend we did */ - } - pEvents->detail = NotifyHint; - } else { - pEvents->detail = NotifyNormal; - } - } - return (0); -} - -void -CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type, - deviceKeyButtonPointer * xE, GrabPtr grab, - ClientPtr client, Mask deliveryMask) -{ - DeviceIntPtr dev; - - dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient, - DixGrabAccess); - if (!dev) - return; - - if (type == DeviceMotionNotify) - dev->valuator->motionHintWindow = pWin; - else if ((type == DeviceButtonPress) && (!grab) && - (deliveryMask & DeviceButtonGrabMask)) { - GrabRec tempGrab; - - tempGrab.device = dev; - tempGrab.resource = client->clientAsMask; - tempGrab.window = pWin; - tempGrab.ownerEvents = - (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE; - tempGrab.eventMask = deliveryMask; - tempGrab.keyboardMode = GrabModeAsync; - tempGrab.pointerMode = GrabModeAsync; - tempGrab.confineTo = NullWindow; - tempGrab.cursor = NullCursor; - tempGrab.next = NULL; - (*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE); - } -} - -static Mask -DeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client) -{ - InputClientsPtr other; - - if (!wOtherInputMasks(pWin)) - return 0; - for (other = wOtherInputMasks(pWin)->inputClients; other; - other = other->next) { - if (SameClient(other, client)) - return other->mask[dev->id]; - } - return 0; -} - -void -MaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client) -{ - WindowPtr pWin; - GrabPtr grab = dev->deviceGrab.grab; - - pWin = dev->valuator->motionHintWindow; - - if ((grab && SameClient(grab, client) && - ((grab->eventMask & DevicePointerMotionHintMask) || - (grab->ownerEvents && - (DeviceEventMaskForClient(dev, pWin, client) & - DevicePointerMotionHintMask)))) || - (!grab && - (DeviceEventMaskForClient(dev, pWin, client) & - DevicePointerMotionHintMask))) - dev->valuator->motionHintWindow = NullWindow; -} - -int -DeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask, - int maskndx) -{ - struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); - - if (mask & ~PropagateMask[maskndx]) { - client->errorValue = mask; - return BadValue; - } - - if (mask == 0) { - if (inputMasks) - inputMasks->dontPropagateMask[maskndx] = mask; - } else { - if (!inputMasks) - AddExtensionClient(pWin, client, 0, 0); - inputMasks = wOtherInputMasks(pWin); - inputMasks->dontPropagateMask[maskndx] = mask; - } - RecalculateDeviceDeliverableEvents(pWin); - if (ShouldFreeInputMasks(pWin, FALSE)) - FreeResource(inputMasks->inputClients->resource, RT_NONE); - return Success; -} - -Bool -ShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents) -{ - int i; - Mask allInputEventMasks = 0; - struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin); - - for (i = 0; i < EMASKSIZE; i++) - allInputEventMasks |= inputMasks->dontPropagateMask[i]; - if (!ignoreSelectedEvents) - for (i = 0; i < EMASKSIZE; i++) - allInputEventMasks |= inputMasks->inputEvents[i]; - if (allInputEventMasks == 0) - return TRUE; - else - return FALSE; -} - -/*********************************************************************** - * - * Walk through the window tree, finding all clients that want to know - * about the Event. - * - */ - -static void -FindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask, - xEvent * ev, int count) -{ - WindowPtr p2; - - while (p1) { - p2 = p1->firstChild; - DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab); - FindInterestedChildren(dev, p2, mask, ev, count); - p1 = p1->nextSib; - } -} - -/*********************************************************************** - * - * Send an event to interested clients in all windows on all screens. - * - */ - -void -SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count) -{ - int i; - WindowPtr pWin, p1; - - for (i = 0; i < screenInfo.numScreens; i++) { - pWin = WindowTable[i]; - if (!pWin) - continue; - DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab); - p1 = pWin->firstChild; - FindInterestedChildren(dev, p1, mask, ev, count); - } -} - -/** - * Set the XI2 mask for the given client on the given window. - * @param dev The device to set the mask for. - * @param win The window to set the mask on. - * @param client The client setting the mask. - * @param len Number of bytes in mask. - * @param mask Event mask in the form of (1 << eventtype) - */ -int -XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client, - unsigned int len, unsigned char* mask) -{ - OtherInputMasks *masks; - InputClientsPtr others = NULL; - - masks = wOtherInputMasks(win); - if (masks) - { - for (others = wOtherInputMasks(win)->inputClients; others; - others = others->next) { - if (SameClient(others, client)) { - memset(others->xi2mask[dev->id], 0, - sizeof(others->xi2mask[dev->id])); - break; - } - } - } - - len = min(len, sizeof(others->xi2mask[dev->id])); - - if (len && !others) - { - if (AddExtensionClient(win, client, 0, 0) != Success) - return BadAlloc; - others= wOtherInputMasks(win)->inputClients; - } - - if (others) - memset(others->xi2mask[dev->id], 0, sizeof(others->xi2mask[dev->id])); - - if (len) - memcpy(others->xi2mask[dev->id], mask, len); - - RecalculateDeviceDeliverableEvents(win); - - return Success; -} +/************************************************************
+
+Copyright 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 1989 by Hewlett-Packard Company, Palo Alto, California.
+
+ 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 Hewlett-Packard not be
+used in advertising or publicity pertaining to distribution of the
+software without specific, written prior permission.
+
+HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
+ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
+HEWLETT-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.
+
+********************************************************/
+
+/********************************************************************
+ *
+ * Routines to register and initialize extension input devices.
+ * This also contains ProcessOtherEvent, the routine called from DDX
+ * to route extension events.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#else
+#define XINPUT
+#endif
+
+#include "inputstr.h"
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
+#include <X11/extensions/geproto.h>
+#include "windowstr.h"
+#include "miscstruct.h"
+#include "region.h"
+#include "exevents.h"
+#include "extnsionst.h"
+#include "exglobals.h"
+#include "dixevents.h" /* DeliverFocusedEvent */
+#include "dixgrabs.h" /* CreateGrab() */
+#include "scrnintstr.h"
+#include "listdev.h" /* for CopySwapXXXClass */
+#include "xace.h"
+#include "xiquerydevice.h" /* For List*Info */
+#include "eventconvert.h"
+#include "eventstr.h"
+
+#include <X11/extensions/XKBproto.h>
+#include "xkbsrv.h"
+
+#define WID(w) ((w) ? ((w)->drawable.id) : 0)
+#define AllModifiersMask ( \
+ ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+ Mod3Mask | Mod4Mask | Mod5Mask )
+#define AllButtonsMask ( \
+ Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
+
+Bool ShouldFreeInputMasks(WindowPtr /* pWin */ ,
+ Bool /* ignoreSelectedEvents */
+ );
+static Bool MakeInputMasks(WindowPtr /* pWin */
+ );
+
+/* Used to sture classes currently not in use by an MD */
+extern DevPrivateKey UnusedClassesPrivateKey;
+
+/*
+ * Only let the given client know of core events which will affect its
+ * interpretation of input events, if the client's ClientPointer (or the
+ * paired keyboard) is the current device.
+ */
+int
+XIShouldNotify(ClientPtr client, DeviceIntPtr dev)
+{
+ DeviceIntPtr current_ptr = PickPointer(client);
+ DeviceIntPtr current_kbd = GetPairedDevice(current_ptr);
+
+ if (dev == current_kbd || dev == current_ptr)
+ return 1;
+
+ return 0;
+}
+
+void
+RegisterOtherDevice(DeviceIntPtr device)
+{
+ device->public.processInputProc = ProcessOtherEvent;
+ device->public.realInputProc = ProcessOtherEvent;
+}
+
+Bool
+IsPointerEvent(InternalEvent* event)
+{
+ switch(event->any.type)
+ {
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_Motion:
+ /* XXX: enter/leave ?? */
+ return TRUE;
+ default:
+ break;
+ }
+ return FALSE;
+}
+
+/**
+ * @return the device matching the deviceid of the device set in the event, or
+ * NULL if the event is not an XInput event.
+ */
+DeviceIntPtr
+XIGetDevice(xEvent* xE)
+{
+ DeviceIntPtr pDev = NULL;
+
+ if (xE->u.u.type == DeviceButtonPress ||
+ xE->u.u.type == DeviceButtonRelease ||
+ xE->u.u.type == DeviceMotionNotify ||
+ xE->u.u.type == ProximityIn ||
+ xE->u.u.type == ProximityOut ||
+ xE->u.u.type == DevicePropertyNotify)
+ {
+ int rc;
+ int id;
+
+ id = ((deviceKeyButtonPointer*)xE)->deviceid & ~MORE_EVENTS;
+
+ rc = dixLookupDevice(&pDev, id, serverClient, DixUnknownAccess);
+ if (rc != Success)
+ ErrorF("[dix] XIGetDevice failed on XACE restrictions (%d)\n", rc);
+ }
+ return pDev;
+}
+
+
+/**
+ * Copy the device->key into master->key and send a mapping notify to the
+ * clients if appropriate.
+ * master->key needs to be allocated by the caller.
+ *
+ * Device is the slave device. If it is attached to a master device, we may
+ * need to send a mapping notify to the client because it causes the MD
+ * to change state.
+ *
+ * Mapping notify needs to be sent in the following cases:
+ * - different slave device on same master
+ * - different master
+ *
+ * XXX: They way how the code is we also send a map notify if the slave device
+ * stays the same, but the master changes. This isn't really necessary though.
+ *
+ * XXX: this gives you funny behaviour with the ClientPointer. When a
+ * MappingNotify is sent to the client, the client usually responds with a
+ * GetKeyboardMapping. This will retrieve the ClientPointer's keyboard
+ * mapping, regardless of which keyboard sent the last mapping notify request.
+ * So depending on the CP setting, your keyboard may change layout in each
+ * app...
+ *
+ * This code is basically the old SwitchCoreKeyboard.
+ */
+
+void
+CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
+{
+ KeyClassPtr mk = master->key;
+ KeyClassPtr dk = device->key;
+ int i;
+
+ if (device == master)
+ return;
+
+ mk->sourceid = device->id;
+
+ for (i = 0; i < 8; i++)
+ mk->modifierKeyCount[i] = dk->modifierKeyCount[i];
+
+ if (!XkbCopyDeviceKeymap(master, device))
+ FatalError("Couldn't pivot keymap from device to core!\n");
+}
+
+/**
+ * Copies the feedback classes from device "from" into device "to". Classes
+ * are duplicated (not just flipping the pointers). All feedback classes are
+ * linked lists, the full list is duplicated.
+ */
+static void
+DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
+{
+ ClassesPtr classes;
+
+
+ if (from->intfeed)
+ {
+ IntegerFeedbackPtr *i, it;
+
+ if (!to->intfeed)
+ {
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+ to->intfeed = classes->intfeed;
+ }
+
+ i = &to->intfeed;
+ for (it = from->intfeed; it; it = it->next)
+ {
+ if (!(*i))
+ {
+ *i = xcalloc(1, sizeof(IntegerFeedbackClassRec));
+ if (!(*i))
+ {
+ ErrorF("[Xi] Cannot alloc memory for class copy.");
+ return;
+ }
+ }
+ (*i)->CtrlProc = it->CtrlProc;
+ (*i)->ctrl = it->ctrl;
+
+ i = &(*i)->next;
+ }
+ } else if (to->intfeed && !from->intfeed)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->intfeed = to->intfeed;
+ to->intfeed = NULL;
+ }
+
+ if (from->stringfeed)
+ {
+ StringFeedbackPtr *s, it;
+
+ if (!to->stringfeed)
+ {
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+ to->stringfeed = classes->stringfeed;
+ }
+
+ s = &to->stringfeed;
+ for (it = from->stringfeed; it; it = it->next)
+ {
+ if (!(*s))
+ {
+ *s = xcalloc(1, sizeof(StringFeedbackClassRec));
+ if (!(*s))
+ {
+ ErrorF("[Xi] Cannot alloc memory for class copy.");
+ return;
+ }
+ }
+ (*s)->CtrlProc = it->CtrlProc;
+ (*s)->ctrl = it->ctrl;
+
+ s = &(*s)->next;
+ }
+ } else if (to->stringfeed && !from->stringfeed)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->stringfeed = to->stringfeed;
+ to->stringfeed = NULL;
+ }
+
+ if (from->bell)
+ {
+ BellFeedbackPtr *b, it;
+
+ if (!to->bell)
+ {
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+ to->bell = classes->bell;
+ }
+
+ b = &to->bell;
+ for (it = from->bell; it; it = it->next)
+ {
+ if (!(*b))
+ {
+ *b = xcalloc(1, sizeof(BellFeedbackClassRec));
+ if (!(*b))
+ {
+ ErrorF("[Xi] Cannot alloc memory for class copy.");
+ return;
+ }
+ }
+ (*b)->BellProc = it->BellProc;
+ (*b)->CtrlProc = it->CtrlProc;
+ (*b)->ctrl = it->ctrl;
+
+ b = &(*b)->next;
+ }
+ } else if (to->bell && !from->bell)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->bell = to->bell;
+ to->bell = NULL;
+ }
+
+ if (from->leds)
+ {
+ LedFeedbackPtr *l, it;
+
+ if (!to->leds)
+ {
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+ to->leds = classes->leds;
+ }
+
+ l = &to->leds;
+ for (it = from->leds; it; it = it->next)
+ {
+ if (!(*l))
+ {
+ *l = xcalloc(1, sizeof(LedFeedbackClassRec));
+ if (!(*l))
+ {
+ ErrorF("[Xi] Cannot alloc memory for class copy.");
+ return;
+ }
+ }
+ (*l)->CtrlProc = it->CtrlProc;
+ (*l)->ctrl = it->ctrl;
+ if ((*l)->xkb_sli)
+ XkbFreeSrvLedInfo((*l)->xkb_sli);
+ (*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l);
+
+ l = &(*l)->next;
+ }
+ } else if (to->leds && !from->leds)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->leds = to->leds;
+ to->leds = NULL;
+ }
+}
+
+static void
+DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to)
+{
+ ClassesPtr classes;
+
+ /* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the
+ * kbdfeed to be set up properly, so let's do the feedback classes first.
+ */
+ if (from->kbdfeed)
+ {
+ KbdFeedbackPtr *k, it;
+
+ if (!to->kbdfeed)
+ {
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+
+ to->kbdfeed = classes->kbdfeed;
+ if (!to->kbdfeed)
+ InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
+ }
+
+ k = &to->kbdfeed;
+ for(it = from->kbdfeed; it; it = it->next)
+ {
+ if (!(*k))
+ {
+ *k = xcalloc(1, sizeof(KbdFeedbackClassRec));
+ if (!*k)
+ {
+ ErrorF("[Xi] Cannot alloc memory for class copy.");
+ return;
+ }
+ }
+ (*k)->BellProc = it->BellProc;
+ (*k)->CtrlProc = it->CtrlProc;
+ (*k)->ctrl = it->ctrl;
+ if ((*k)->xkb_sli)
+ XkbFreeSrvLedInfo((*k)->xkb_sli);
+ (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL);
+
+ k = &(*k)->next;
+ }
+ } else if (to->kbdfeed && !from->kbdfeed)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->kbdfeed = to->kbdfeed;
+ to->kbdfeed = NULL;
+ }
+
+ if (from->key)
+ {
+ if (!to->key)
+ {
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+ to->key = classes->key;
+ if (!to->key)
+ InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
+ else
+ classes->key = NULL;
+ }
+
+ CopyKeyClass(from, to);
+ } else if (to->key && !from->key)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->key = to->key;
+ to->key = NULL;
+ }
+
+ /* If a SrvLedInfoPtr's flags are XkbSLI_IsDefault, the names and maps
+ * pointer point into the xkbInfo->desc struct. XkbCopySrvLedInfo
+ * didn't update the pointers so we need to do it manually here.
+ */
+ if (to->kbdfeed)
+ {
+ KbdFeedbackPtr k;
+
+ for (k = to->kbdfeed; k; k = k->next)
+ {
+ if (!k->xkb_sli)
+ continue;
+ if (k->xkb_sli->flags & XkbSLI_IsDefault)
+ {
+ k->xkb_sli->names = to->key->xkbInfo->desc->names->indicators;
+ k->xkb_sli->maps = to->key->xkbInfo->desc->indicators->maps;
+ }
+ }
+ }
+
+ /* We can't just copy over the focus class. When an app sets the focus,
+ * it'll do so on the master device. Copying the SDs focus means losing
+ * the focus.
+ * So we only copy the focus class if the device didn't have one,
+ * otherwise we leave it as it is.
+ */
+ if (from->focus)
+ {
+ if (!to->focus)
+ {
+ WindowPtr *oldTrace;
+
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+ to->focus = classes->focus;
+ if (!to->focus)
+ {
+ to->focus = xcalloc(1, sizeof(FocusClassRec));
+ if (!to->focus)
+ FatalError("[Xi] no memory for class shift.\n");
+ } else
+ classes->focus = NULL;
+
+ oldTrace = to->focus->trace;
+ memcpy(to->focus, from->focus, sizeof(FocusClassRec));
+ to->focus->trace = xrealloc(oldTrace,
+ to->focus->traceSize * sizeof(WindowPtr));
+ if (!to->focus->trace && to->focus->traceSize)
+ FatalError("[Xi] no memory for trace.\n");
+ memcpy(to->focus->trace, from->focus->trace,
+ from->focus->traceSize * sizeof(WindowPtr));
+ to->focus->sourceid = from->id;
+ }
+ } else if (to->focus)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->focus = to->focus;
+ to->focus = NULL;
+ }
+
+}
+
+static void
+DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
+{
+ ClassesPtr classes;
+
+ /* Feedback classes must be copied first */
+ if (from->ptrfeed)
+ {
+ PtrFeedbackPtr *p, it;
+ if (!to->ptrfeed)
+ {
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+ to->ptrfeed = classes->ptrfeed;
+ }
+
+ p = &to->ptrfeed;
+ for (it = from->ptrfeed; it; it = it->next)
+ {
+ if (!(*p))
+ {
+ *p = xcalloc(1, sizeof(PtrFeedbackClassRec));
+ if (!*p)
+ {
+ ErrorF("[Xi] Cannot alloc memory for class copy.");
+ return;
+ }
+ }
+ (*p)->CtrlProc = it->CtrlProc;
+ (*p)->ctrl = it->ctrl;
+
+ p = &(*p)->next;
+ }
+ } else if (to->ptrfeed && !from->ptrfeed)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->ptrfeed = to->ptrfeed;
+ to->ptrfeed = NULL;
+ }
+
+ if (from->valuator)
+ {
+ ValuatorClassPtr v;
+ if (!to->valuator)
+ {
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+ to->valuator = classes->valuator;
+ if (to->valuator)
+ classes->valuator = NULL;
+ }
+
+ to->valuator = xrealloc(to->valuator, sizeof(ValuatorClassRec) +
+ from->valuator->numAxes * sizeof(AxisInfo) +
+ from->valuator->numAxes * sizeof(double));
+ v = to->valuator;
+ if (!v)
+ FatalError("[Xi] no memory for class shift.\n");
+
+ v->numAxes = from->valuator->numAxes;
+ v->axes = (AxisInfoPtr)&v[1];
+ memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo));
+
+ v->axisVal = (double*)(v->axes + from->valuator->numAxes);
+ v->sourceid = from->id;
+ v->mode = from->valuator->mode;
+ } else if (to->valuator && !from->valuator)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->valuator = to->valuator;
+ to->valuator = NULL;
+ }
+
+ if (from->button)
+ {
+ if (!to->button)
+ {
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+ to->button = classes->button;
+ if (!to->button)
+ {
+ to->button = xcalloc(1, sizeof(ButtonClassRec));
+ if (!to->button)
+ FatalError("[Xi] no memory for class shift.\n");
+ } else
+ classes->button = NULL;
+ }
+
+ if (from->button->xkb_acts)
+ {
+ if (!to->button->xkb_acts)
+ {
+ to->button->xkb_acts = xcalloc(1, sizeof(XkbAction));
+ if (!to->button->xkb_acts)
+ FatalError("[Xi] not enough memory for xkb_acts.\n");
+ }
+ memcpy(to->button->xkb_acts, from->button->xkb_acts,
+ sizeof(XkbAction));
+ } else
+ xfree(to->button->xkb_acts);
+
+ memcpy(to->button->labels, from->button->labels,
+ from->button->numButtons * sizeof(Atom));
+ to->button->sourceid = from->id;
+ } else if (to->button && !from->button)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->button = to->button;
+ to->button = NULL;
+ }
+
+ if (from->proximity)
+ {
+ if (!to->proximity)
+ {
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+ to->proximity = classes->proximity;
+ if (!to->proximity)
+ {
+ to->proximity = xcalloc(1, sizeof(ProximityClassRec));
+ if (!to->proximity)
+ FatalError("[Xi] no memory for class shift.\n");
+ } else
+ classes->proximity = NULL;
+ }
+ memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec));
+ to->proximity->sourceid = from->id;
+ } else if (to->proximity)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->proximity = to->proximity;
+ to->proximity = NULL;
+ }
+
+ if (from->absolute)
+ {
+ if (!to->absolute)
+ {
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+ to->absolute = classes->absolute;
+ if (!to->absolute)
+ {
+ to->absolute = xcalloc(1, sizeof(AbsoluteClassRec));
+ if (!to->absolute)
+ FatalError("[Xi] no memory for class shift.\n");
+ } else
+ classes->absolute = NULL;
+ }
+ memcpy(to->absolute, from->absolute, sizeof(AbsoluteClassRec));
+ to->absolute->sourceid = from->id;
+ } else if (to->absolute)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->absolute = to->absolute;
+ to->absolute = NULL;
+ }
+}
+
+/**
+ * Copies the CONTENT of the classes of device from into the classes in device
+ * to. From and to are identical after finishing.
+ *
+ * If to does not have classes from currenly has, the classes are stored in
+ * to's devPrivates system. Later, we recover it again from there if needed.
+ * Saves a few memory allocations.
+ */
+void
+DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dce)
+{
+ /* generic feedback classes, not tied to pointer and/or keyboard */
+ DeepCopyFeedbackClasses(from, to);
+
+ if ((dce->flags & DEVCHANGE_KEYBOARD_EVENT))
+ DeepCopyKeyboardClasses(from, to);
+ if ((dce->flags & DEVCHANGE_POINTER_EVENT))
+ DeepCopyPointerClasses(from, to);
+}
+
+
+/**
+ * Send an XI2 DeviceChangedEvent to all interested clients.
+ */
+void
+XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChangedEvent *dce)
+{
+ xXIDeviceChangedEvent *dcce;
+ int rc;
+
+ rc = EventToXI2((InternalEvent*)dce, (xEvent**)&dcce);
+ if (rc != Success)
+ {
+ ErrorF("[Xi] event conversion from DCE failed with code %d\n", rc);
+ return;
+ }
+
+ /* we don't actually swap if there's a NullClient, swapping is done
+ * later when event is delivered. */
+ SendEventToAllWindows(master, XI_DeviceChangedMask, (xEvent*)dcce, 1);
+ xfree(dcce);
+}
+
+static void
+ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce)
+{
+ DeviceIntPtr slave;
+ int rc;
+
+ /* For now, we don't have devices that change physically. */
+ if (!IsMaster(device))
+ return;
+
+ rc = dixLookupDevice(&slave, dce->sourceid, serverClient, DixReadAccess);
+
+ if (rc != Success)
+ return; /* Device has disappeared */
+
+ if (!slave->u.master)
+ return; /* set floating since the event */
+
+ if (slave->u.master->id != dce->masterid)
+ return; /* not our slave anymore, don't care */
+
+ /* FIXME: we probably need to send a DCE for the new slave now */
+
+ device->public.devicePrivate = slave->public.devicePrivate;
+
+ /* FIXME: the classes may have changed since we generated the event. */
+ DeepCopyDeviceClasses(slave, device, dce);
+ XISendDeviceChangedEvent(slave, device, dce);
+}
+
+/**
+ * Update the device state according to the data in the event.
+ *
+ * return values are
+ * DEFAULT ... process as normal
+ * DONT_PROCESS ... return immediately from caller
+ */
+#define DEFAULT 0
+#define DONT_PROCESS 1
+int
+UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
+{
+ int i;
+ int key = 0,
+ bit = 0,
+ last_valuator;
+
+ KeyClassPtr k = NULL;
+ ButtonClassPtr b = NULL;
+ ValuatorClassPtr v = NULL;
+ BYTE *kptr = NULL;
+
+ /* This event is always the first we get, before the actual events with
+ * the data. However, the way how the DDX is set up, "device" will
+ * actually be the slave device that caused the event.
+ */
+ switch(event->type)
+ {
+ case ET_DeviceChanged:
+ ChangeMasterDeviceClasses(device, (DeviceChangedEvent*)event);
+ return DONT_PROCESS; /* event has been sent already */
+ case ET_Motion:
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_KeyPress:
+ case ET_KeyRelease:
+ case ET_ProximityIn:
+ case ET_ProximityOut:
+ break;
+ default:
+ /* other events don't update the device */
+ return DEFAULT;
+ }
+
+ k = device->key;
+ v = device->valuator;
+ b = device->button;
+
+ key = event->detail.key;
+ bit = 1 << (key & 7);
+
+ /* Update device axis */
+ /* Check valuators first */
+ last_valuator = -1;
+ for (i = 0; i < MAX_VALUATORS; i++)
+ {
+ if (BitIsOn(&event->valuators.mask, i))
+ {
+ if (!v)
+ {
+ ErrorF("[Xi] Valuators reported for non-valuator device '%s'. "
+ "Ignoring event.\n", device->name);
+ return DONT_PROCESS;
+ } else if (v->numAxes < i)
+ {
+ ErrorF("[Xi] Too many valuators reported for device '%s'. "
+ "Ignoring event.\n", device->name);
+ return DONT_PROCESS;
+ }
+ last_valuator = i;
+ }
+ }
+
+ for (i = 0; i <= last_valuator && i < v->numAxes; i++)
+ {
+ if (BitIsOn(&event->valuators.mask, i))
+ {
+ /* XXX: Relative/Absolute mode */
+ v->axisVal[i] = event->valuators.data[i];
+ v->axisVal[i] += (event->valuators.data_frac[i] * 1.0f / (1 << 16) / (1 << 16));
+ }
+ }
+
+ if (event->type == ET_KeyPress) {
+ if (!k)
+ return DONT_PROCESS;
+
+ kptr = &k->down[key >> 3];
+ /* don't allow ddx to generate multiple downs, but repeats are okay */
+ if ((*kptr & bit) && !event->key_repeat)
+ return DONT_PROCESS;
+ if (device->valuator)
+ device->valuator->motionHintWindow = NullWindow;
+ *kptr |= bit;
+ } else if (event->type == ET_KeyRelease) {
+ if (!k)
+ return DONT_PROCESS;
+
+ kptr = &k->down[key >> 3];
+ if (!(*kptr & bit)) /* guard against duplicates */
+ return DONT_PROCESS;
+ if (device->valuator)
+ device->valuator->motionHintWindow = NullWindow;
+ *kptr &= ~bit;
+ } else if (event->type == ET_ButtonPress) {
+ Mask mask;
+ if (!b)
+ return DONT_PROCESS;
+
+ kptr = &b->down[key >> 3];
+ if ((*kptr & bit) != 0)
+ return DONT_PROCESS;
+ *kptr |= bit;
+ if (device->valuator)
+ device->valuator->motionHintWindow = NullWindow;
+ if (!b->map[key])
+ return DONT_PROCESS;
+ b->buttonsDown++;
+ b->motionMask = DeviceButtonMotionMask;
+ if (b->map[key] <= 5)
+ b->state |= (Button1Mask >> 1) << b->map[key];
+
+ /* Add state and motionMask to the filter for this event */
+ mask = DevicePointerMotionMask | b->state | b->motionMask;
+ SetMaskForEvent(device->id, mask, DeviceMotionNotify);
+ mask = PointerMotionMask | b->state | b->motionMask;
+ SetMaskForEvent(device->id, mask, MotionNotify);
+ } else if (event->type == ET_ButtonRelease) {
+ Mask mask;
+ if (!b)
+ return DONT_PROCESS;
+
+ kptr = &b->down[key>>3];
+ if (!(*kptr & bit))
+ return DONT_PROCESS;
+ if (IsMaster(device)) {
+ DeviceIntPtr sd;
+
+ /*
+ * Leave the button down if any slave has the
+ * button still down. Note that this depends on the
+ * event being delivered through the slave first
+ */
+ for (sd = inputInfo.devices; sd; sd = sd->next) {
+ if (IsMaster(sd) || sd->u.master != device)
+ continue;
+ if (!sd->button)
+ continue;
+ if ((sd->button->down[key>>3] & bit) != 0)
+ return DONT_PROCESS;
+ }
+ }
+ *kptr &= ~bit;
+ if (device->valuator)
+ device->valuator->motionHintWindow = NullWindow;
+ if (!b->map[key])
+ return DONT_PROCESS;
+ if (b->buttonsDown >= 1 && !--b->buttonsDown)
+ b->motionMask = 0;
+ if (b->map[key] <= 5)
+ b->state &= ~((Button1Mask >> 1) << b->map[key]);
+
+ /* Add state and motionMask to the filter for this event */
+ mask = DevicePointerMotionMask | b->state | b->motionMask;
+ SetMaskForEvent(device->id, mask, DeviceMotionNotify);
+ mask = PointerMotionMask | b->state | b->motionMask;
+ SetMaskForEvent(device->id, mask, MotionNotify);
+ } else if (event->type == ET_ProximityIn)
+ device->valuator->mode &= ~OutOfProximity;
+ else if (event->type == ET_ProximityOut)
+ device->valuator->mode |= OutOfProximity;
+
+ return DEFAULT;
+}
+
+static void
+ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
+{
+ GrabPtr grab = device->deviceGrab.grab;
+
+ if (grab)
+ DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE);
+ else { /* deliver to all root windows */
+ xEvent *xi;
+ int i;
+
+ i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi);
+ if (i != Success)
+ {
+ ErrorF("[Xi] %s: XI2 conversion failed in ProcessRawEvent (%d)\n",
+ device->name, i);
+ return;
+ }
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ DeliverEventsToWindow(device, WindowTable[i], xi, 1,
+ GetEventFilter(device, xi), NULL);
+ xfree(xi);
+ }
+}
+
+/**
+ * Main device event processing function.
+ * Called from when processing the events from the event queue.
+ *
+ */
+void
+ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
+{
+ GrabPtr grab;
+ Bool deactivateDeviceGrab = FALSE;
+ int key = 0, rootX, rootY;
+ ButtonClassPtr b;
+ KeyClassPtr k;
+ ValuatorClassPtr v;
+ int ret = 0;
+ int state, i;
+ DeviceIntPtr mouse = NULL, kbd = NULL;
+ DeviceEvent *event = &ev->device_event;
+
+ CHECKEVENT(ev);
+
+ if (ev->any.type == ET_RawKeyPress ||
+ ev->any.type == ET_RawKeyRelease ||
+ ev->any.type == ET_RawButtonPress ||
+ ev->any.type == ET_RawButtonRelease ||
+ ev->any.type == ET_RawMotion)
+ {
+ ProcessRawEvent(&ev->raw_event, device);
+ return;
+ }
+
+ if (IsPointerDevice(device))
+ {
+ kbd = GetPairedDevice(device);
+ mouse = device;
+ if (!kbd->key) /* can happen with floating SDs */
+ kbd = NULL;
+ } else
+ {
+ mouse = GetPairedDevice(device);
+ kbd = device;
+ if (!mouse->valuator || !mouse->button) /* may be float. SDs */
+ mouse = NULL;
+ }
+
+ /* State needs to be assembled BEFORE the device is updated. */
+ state = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0;
+ state |= (mouse && mouse->button) ? (mouse->button->state) : 0;
+
+ for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
+ if (BitIsOn(mouse->button->down, i))
+ SetBit(event->buttons, i);
+
+ if (kbd && kbd->key)
+ {
+ XkbStatePtr state;
+ /* we need the state before the event happens */
+ if (event->type == ET_KeyPress || event->type == ET_KeyRelease)
+ state = &kbd->key->xkbInfo->prev_state;
+ else
+ state = &kbd->key->xkbInfo->state;
+
+ event->mods.base = state->base_mods;
+ event->mods.latched = state->latched_mods;
+ event->mods.locked = state->locked_mods;
+ event->mods.effective = state->mods;
+
+ event->group.base = state->base_group;
+ event->group.latched = state->latched_group;
+ event->group.locked = state->locked_group;
+ event->group.effective = state->group;
+ }
+
+ ret = UpdateDeviceState(device, event);
+ if (ret == DONT_PROCESS)
+ return;
+
+ v = device->valuator;
+ b = device->button;
+ k = device->key;
+
+ if (IsMaster(device) || !device->u.master)
+ CheckMotion(event, device);
+
+ switch (event->type)
+ {
+ case ET_Motion:
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_KeyPress:
+ case ET_KeyRelease:
+ case ET_ProximityIn:
+ case ET_ProximityOut:
+ GetSpritePosition(device, &rootX, &rootY);
+ event->root_x = rootX;
+ event->root_y = rootY;
+ NoticeEventTime((InternalEvent*)event);
+ event->corestate = state;
+ key = event->detail.key;
+ break;
+ default:
+ break;
+ }
+
+ if (DeviceEventCallback) {
+ DeviceEventInfoRec eventinfo;
+ SpritePtr pSprite = device->spriteInfo->sprite;
+ xEvent *xi_events = NULL;
+ int count;
+
+ /* see comment in EnqueueEvents regarding the next three lines */
+ if (ev->any.type == ET_Motion)
+ ev->device_event.root =
+ WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id;
+
+ /* SDs send XI events only. MDs send both an XI event and a core
+ * event.
+ */
+ EventToXI(ev, &xi_events, &count);
+
+ eventinfo.events = (xEventPtr)xi_events;
+ eventinfo.count = count;
+ ErrorF("POE xi root is %lx\n", xi_events->u.keyButtonPointer.root);
+ CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo);
+ xfree(xi_events);
+
+ if (IsMaster(device))
+ {
+ xEvent core;
+ EventToCore(ev, &core);
+ eventinfo.events = (xEventPtr)&core;
+ eventinfo.count = 1;
+ ErrorF("POE core root is %lx\n", core.u.keyButtonPointer.root);
+ CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo);
+ }
+
+ }
+ grab = device->deviceGrab.grab;
+
+ switch(event->type)
+ {
+ case ET_KeyPress:
+ if (!grab && CheckDeviceGrabs(device, event, 0)) {
+ device->deviceGrab.activatingKey = key;
+ return;
+ }
+ break;
+ case ET_KeyRelease:
+ if (grab && device->deviceGrab.fromPassiveGrab &&
+ (key == device->deviceGrab.activatingKey) &&
+ (device->deviceGrab.grab->type == KeyPress ||
+ device->deviceGrab.grab->type == DeviceKeyPress ||
+ device->deviceGrab.grab->type == XI_KeyPress))
+ deactivateDeviceGrab = TRUE;
+ break;
+ case ET_ButtonPress:
+ event->detail.button = b->map[key];
+ if (!event->detail.button) { /* there's no button 0 */
+ event->detail.button = key;
+ return;
+ }
+ if (!grab && CheckDeviceGrabs(device, event, 0))
+ {
+ /* if a passive grab was activated, the event has been sent
+ * already */
+ return;
+ }
+ break;
+ case ET_ButtonRelease:
+ event->detail.button = b->map[key];
+ if (!event->detail.button) { /* there's no button 0 */
+ event->detail.button = key;
+ return;
+ }
+ if (grab && !b->buttonsDown &&
+ device->deviceGrab.fromPassiveGrab &&
+ (device->deviceGrab.grab->type == ButtonPress ||
+ device->deviceGrab.grab->type == DeviceButtonPress ||
+ device->deviceGrab.grab->type == XI_ButtonPress))
+ deactivateDeviceGrab = TRUE;
+ default:
+ break;
+ }
+
+
+ if (grab)
+ DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab);
+ else if (device->focus && !IsPointerEvent((InternalEvent*)ev))
+ DeliverFocusedEvent(device, (InternalEvent*)event,
+ GetSpriteWindow(device));
+ else
+ DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent*)event,
+ NullGrab, NullWindow, device);
+
+ if (deactivateDeviceGrab == TRUE)
+ (*device->deviceGrab.DeactivateGrab) (device);
+ event->detail.key = key;
+}
+
+int
+InitProximityClassDeviceStruct(DeviceIntPtr dev)
+{
+ ProximityClassPtr proxc;
+
+ proxc = (ProximityClassPtr) xalloc(sizeof(ProximityClassRec));
+ if (!proxc)
+ return FALSE;
+ proxc->sourceid = dev->id;
+ dev->proximity = proxc;
+ return TRUE;
+}
+
+/**
+ * Initialise the device's valuators. The memory must already be allocated,
+ * this function merely inits the matching axis (specified through axnum) to
+ * sane values.
+ *
+ * It is a condition that (minval < maxval).
+ *
+ * @see InitValuatorClassDeviceStruct
+ */
+void
+InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
+ int resolution, int min_res, int max_res)
+{
+ AxisInfoPtr ax;
+
+ if (!dev || !dev->valuator || minval > maxval)
+ return;
+ if (axnum >= dev->valuator->numAxes)
+ return;
+
+ ax = dev->valuator->axes + axnum;
+
+ ax->min_value = minval;
+ ax->max_value = maxval;
+ ax->resolution = resolution;
+ ax->min_resolution = min_res;
+ ax->max_resolution = max_res;
+ ax->label = label;
+}
+
+static void
+FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
+ ButtonClassPtr b, ValuatorClassPtr v, int first)
+{
+ ev->type = DeviceStateNotify;
+ ev->deviceid = dev->id;
+ ev->time = currentTime.milliseconds;
+ ev->classes_reported = 0;
+ ev->num_keys = 0;
+ ev->num_buttons = 0;
+ ev->num_valuators = 0;
+
+ if (b) {
+ ev->classes_reported |= (1 << ButtonClass);
+ ev->num_buttons = b->numButtons;
+ memcpy((char*)ev->buttons, (char*)b->down, 4);
+ } else if (k) {
+ ev->classes_reported |= (1 << KeyClass);
+ ev->num_keys = k->xkbInfo->desc->max_key_code -
+ k->xkbInfo->desc->min_key_code;
+ memmove((char *)&ev->keys[0], (char *)k->down, 4);
+ }
+ if (v) {
+ int nval = v->numAxes - first;
+
+ ev->classes_reported |= (1 << ValuatorClass);
+ ev->classes_reported |= (dev->valuator->mode << ModeBitsShift);
+ ev->num_valuators = nval < 3 ? nval : 3;
+ switch (ev->num_valuators) {
+ case 3:
+ ev->valuator2 = v->axisVal[first + 2];
+ case 2:
+ ev->valuator1 = v->axisVal[first + 1];
+ case 1:
+ ev->valuator0 = v->axisVal[first];
+ break;
+ }
+ }
+}
+
+static void
+FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
+ int first)
+{
+ int nval = v->numAxes - first;
+
+ ev->type = DeviceValuator;
+ ev->deviceid = dev->id;
+ ev->num_valuators = nval < 3 ? nval : 3;
+ ev->first_valuator = first;
+ switch (ev->num_valuators) {
+ case 3:
+ ev->valuator2 = v->axisVal[first + 2];
+ case 2:
+ ev->valuator1 = v->axisVal[first + 1];
+ case 1:
+ ev->valuator0 = v->axisVal[first];
+ break;
+ }
+ first += ev->num_valuators;
+}
+
+void
+DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
+ WindowPtr pWin)
+{
+ deviceFocus event;
+ xXIFocusInEvent *xi2event;
+ DeviceIntPtr mouse;
+ int btlen, len, i;
+
+ mouse = (IsMaster(dev) || dev->u.master) ? GetMaster(dev, MASTER_POINTER) : dev;
+
+ /* XI 2 event */
+ btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0;
+ btlen = bytes_to_int32(btlen);
+ len = sizeof(xXIFocusInEvent) + btlen * 4;
+
+ xi2event = xcalloc(1, len);
+ xi2event->type = GenericEvent;
+ xi2event->extension = IReqCode;
+ xi2event->evtype = type;
+ xi2event->length = bytes_to_int32(len - sizeof(xEvent));
+ xi2event->buttons_len = btlen;
+ xi2event->detail = detail;
+ xi2event->time = currentTime.milliseconds;
+ xi2event->deviceid = dev->id;
+ xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */
+ xi2event->mode = mode;
+ xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0);
+ xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0);
+
+ for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
+ if (BitIsOn(mouse->button->down, i))
+ SetBit(&xi2event[1], i);
+
+ if (dev->key)
+ {
+ xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods;
+ xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods;
+ xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods;
+ xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods;
+
+ xi2event->group.base_group = dev->key->xkbInfo->state.base_group;
+ xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group;
+ xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group;
+ xi2event->group.effective_group = dev->key->xkbInfo->state.group;
+ }
+
+ FixUpEventFromWindow(dev, (xEvent*)xi2event, pWin, None, FALSE);
+
+ DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1,
+ GetEventFilter(dev, (xEvent*)xi2event), NullGrab);
+
+ xfree(xi2event);
+
+ /* XI 1.x event */
+ event.deviceid = dev->id;
+ event.mode = mode;
+ event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut;
+ event.detail = detail;
+ event.window = pWin->drawable.id;
+ event.time = currentTime.milliseconds;
+
+ DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1,
+ DeviceFocusChangeMask, NullGrab);
+
+ if ((type == DeviceFocusIn) &&
+ (wOtherInputMasks(pWin)) &&
+ (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask))
+ {
+ int evcount = 1;
+ deviceStateNotify *ev, *sev;
+ deviceKeyStateNotify *kev;
+ deviceButtonStateNotify *bev;
+
+ KeyClassPtr k;
+ ButtonClassPtr b;
+ ValuatorClassPtr v;
+ int nval = 0, nkeys = 0, nbuttons = 0, first = 0;
+
+ if ((b = dev->button) != NULL) {
+ nbuttons = b->numButtons;
+ if (nbuttons > 32)
+ evcount++;
+ }
+ if ((k = dev->key) != NULL) {
+ nkeys = k->xkbInfo->desc->max_key_code -
+ k->xkbInfo->desc->min_key_code;
+ if (nkeys > 32)
+ evcount++;
+ if (nbuttons > 0) {
+ evcount++;
+ }
+ }
+ if ((v = dev->valuator) != NULL) {
+ nval = v->numAxes;
+
+ if (nval > 3)
+ evcount++;
+ if (nval > 6) {
+ if (!(k && b))
+ evcount++;
+ if (nval > 9)
+ evcount += ((nval - 7) / 3);
+ }
+ }
+
+ sev = ev = (deviceStateNotify *) xalloc(evcount * sizeof(xEvent));
+ FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
+
+ if (b != NULL) {
+ FixDeviceStateNotify(dev, ev++, NULL, b, v, first);
+ first += 3;
+ nval -= 3;
+ if (nbuttons > 32) {
+ (ev - 1)->deviceid |= MORE_EVENTS;
+ bev = (deviceButtonStateNotify *) ev++;
+ bev->type = DeviceButtonStateNotify;
+ bev->deviceid = dev->id;
+ memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4);
+ }
+ if (nval > 0) {
+ (ev - 1)->deviceid |= MORE_EVENTS;
+ FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
+ first += 3;
+ nval -= 3;
+ }
+ }
+
+ if (k != NULL) {
+ FixDeviceStateNotify(dev, ev++, k, NULL, v, first);
+ first += 3;
+ nval -= 3;
+ if (nkeys > 32) {
+ (ev - 1)->deviceid |= MORE_EVENTS;
+ kev = (deviceKeyStateNotify *) ev++;
+ kev->type = DeviceKeyStateNotify;
+ kev->deviceid = dev->id;
+ memmove((char *)&kev->keys[0], (char *)&k->down[4], 28);
+ }
+ if (nval > 0) {
+ (ev - 1)->deviceid |= MORE_EVENTS;
+ FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
+ first += 3;
+ nval -= 3;
+ }
+ }
+
+ while (nval > 0) {
+ FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first);
+ first += 3;
+ nval -= 3;
+ if (nval > 0) {
+ (ev - 1)->deviceid |= MORE_EVENTS;
+ FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
+ first += 3;
+ nval -= 3;
+ }
+ }
+
+ DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount,
+ DeviceStateNotifyMask, NullGrab);
+ xfree(sev);
+ }
+}
+
+int
+CheckGrabValues(ClientPtr client, GrabParameters* param)
+{
+ if (param->grabtype != GRABTYPE_CORE &&
+ param->grabtype != GRABTYPE_XI &&
+ param->grabtype != GRABTYPE_XI2)
+ {
+ ErrorF("[Xi] grabtype is invalid. This is a bug.\n");
+ return BadImplementation;
+ }
+
+ if ((param->this_device_mode != GrabModeSync) &&
+ (param->this_device_mode != GrabModeAsync)) {
+ client->errorValue = param->this_device_mode;
+ return BadValue;
+ }
+ if ((param->other_devices_mode != GrabModeSync) &&
+ (param->other_devices_mode != GrabModeAsync)) {
+ client->errorValue = param->other_devices_mode;
+ return BadValue;
+ }
+
+ if (param->grabtype != GRABTYPE_XI2 && (param->modifiers != AnyModifier) &&
+ (param->modifiers & ~AllModifiersMask)) {
+ client->errorValue = param->modifiers;
+ return BadValue;
+ }
+
+ if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) {
+ client->errorValue = param->ownerEvents;
+ return BadValue;
+ }
+ return Success;
+}
+
+int
+GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
+ int button, GrabParameters *param, GrabType grabtype,
+ GrabMask *mask)
+{
+ WindowPtr pWin, confineTo;
+ CursorPtr cursor;
+ GrabPtr grab;
+ int rc, type = -1;
+ Mask access_mode = DixGrabAccess;
+
+ rc = CheckGrabValues(client, param);
+ if (rc != Success)
+ return rc;
+ if (param->confineTo == None)
+ confineTo = NullWindow;
+ else {
+ rc = dixLookupWindow(&confineTo, param->confineTo, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ }
+ if (param->cursor == None)
+ cursor = NullCursor;
+ else {
+ rc = dixLookupResourceByType((pointer *)&cursor, param->cursor,
+ RT_CURSOR, client, DixUseAccess);
+ if (rc != Success)
+ {
+ client->errorValue = param->cursor;
+ return (rc == BadValue) ? BadCursor : rc;
+ }
+ access_mode |= DixForceAccess;
+ }
+ if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync)
+ access_mode |= DixFreezeAccess;
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
+ if (rc != Success)
+ return rc;
+ rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ if (grabtype == GRABTYPE_XI)
+ type = DeviceButtonPress;
+ else if (grabtype == GRABTYPE_XI2)
+ type = XI_ButtonPress;
+
+ grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype,
+ mask, param, type, button, confineTo, cursor);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(client, grab);
+}
+
+/**
+ * Grab the given key. If grabtype is GRABTYPE_XI, the key is a keycode. If
+ * grabtype is GRABTYPE_XI2, the key is a keysym.
+ */
+int
+GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
+ int key, GrabParameters *param, GrabType grabtype, GrabMask *mask)
+{
+ WindowPtr pWin;
+ GrabPtr grab;
+ KeyClassPtr k = dev->key;
+ Mask access_mode = DixGrabAccess;
+ int rc, type = -1;
+
+ rc = CheckGrabValues(client, param);
+ if (rc != Success)
+ return rc;
+ if (k == NULL)
+ return BadMatch;
+ if (grabtype == GRABTYPE_XI)
+ {
+ if ((key > k->xkbInfo->desc->max_key_code ||
+ key < k->xkbInfo->desc->min_key_code)
+ && (key != AnyKey)) {
+ client->errorValue = key;
+ return BadValue;
+ }
+ type = DeviceKeyPress;
+ } else if (grabtype == GRABTYPE_XI2)
+ type = XI_KeyPress;
+
+ rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync)
+ access_mode |= DixFreezeAccess;
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
+ if (rc != Success)
+ return rc;
+
+ grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype,
+ mask, param, type, key, NULL, NULL);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(client, grab);
+}
+
+/* Enter/FocusIn grab */
+int
+GrabWindow(ClientPtr client, DeviceIntPtr dev, int type,
+ GrabParameters *param, GrabMask *mask)
+{
+ WindowPtr pWin;
+ CursorPtr cursor;
+ GrabPtr grab;
+ Mask access_mode = DixGrabAccess;
+ int rc;
+
+ rc = CheckGrabValues(client, param);
+ if (rc != Success)
+ return rc;
+
+ rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ if (param->cursor == None)
+ cursor = NullCursor;
+ else {
+ rc = dixLookupResourceByType((pointer *)&cursor, param->cursor,
+ RT_CURSOR, client, DixUseAccess);
+ if (rc != Success)
+ {
+ client->errorValue = param->cursor;
+ return (rc == BadValue) ? BadCursor : rc;
+ }
+ access_mode |= DixForceAccess;
+ }
+ if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync)
+ access_mode |= DixFreezeAccess;
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
+ if (rc != Success)
+ return rc;
+
+ grab = CreateGrab(client->index, dev, dev, pWin, GRABTYPE_XI2,
+ mask, param, (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn,
+ 0, NULL, cursor);
+
+ if (!grab)
+ return BadAlloc;
+
+ return AddPassiveGrabToList(client, grab);
+}
+
+int
+SelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client,
+ Mask mask, Mask exclusivemasks)
+{
+ int mskidx = dev->id;
+ int i, ret;
+ Mask check;
+ InputClientsPtr others;
+
+ check = (mask & exclusivemasks);
+ if (wOtherInputMasks(pWin)) {
+ if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different
+ * clients to select on any of the
+ * events for maskcheck. However,
+ * it is OK, for some client to
+ * continue selecting on one of those
+ * events. */
+ for (others = wOtherInputMasks(pWin)->inputClients; others;
+ others = others->next) {
+ if (!SameClient(others, client) && (check &
+ others->mask[mskidx]))
+ return BadAccess;
+ }
+ }
+ for (others = wOtherInputMasks(pWin)->inputClients; others;
+ others = others->next) {
+ if (SameClient(others, client)) {
+ check = others->mask[mskidx];
+ others->mask[mskidx] = mask;
+ if (mask == 0) {
+ for (i = 0; i < EMASKSIZE; i++)
+ if (i != mskidx && others->mask[i] != 0)
+ break;
+ if (i == EMASKSIZE) {
+ RecalculateDeviceDeliverableEvents(pWin);
+ if (ShouldFreeInputMasks(pWin, FALSE))
+ FreeResource(others->resource, RT_NONE);
+ return Success;
+ }
+ }
+ goto maskSet;
+ }
+ }
+ }
+ check = 0;
+ if ((ret = AddExtensionClient(pWin, client, mask, mskidx)) != Success)
+ return ret;
+ maskSet:
+ if (dev->valuator)
+ if ((dev->valuator->motionHintWindow == pWin) &&
+ (mask & DevicePointerMotionHintMask) &&
+ !(check & DevicePointerMotionHintMask) && !dev->deviceGrab.grab)
+ dev->valuator->motionHintWindow = NullWindow;
+ RecalculateDeviceDeliverableEvents(pWin);
+ return Success;
+}
+
+int
+AddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx)
+{
+ InputClientsPtr others;
+
+ if (!pWin->optional && !MakeWindowOptional(pWin))
+ return BadAlloc;
+ others = xcalloc(1, sizeof(InputClients));
+ if (!others)
+ return BadAlloc;
+ if (!pWin->optional->inputMasks && !MakeInputMasks(pWin))
+ return BadAlloc;
+ others->mask[mskidx] = mask;
+ others->resource = FakeClientID(client->index);
+ others->next = pWin->optional->inputMasks->inputClients;
+ pWin->optional->inputMasks->inputClients = others;
+ if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer) pWin))
+ return BadAlloc;
+ return Success;
+}
+
+static Bool
+MakeInputMasks(WindowPtr pWin)
+{
+ struct _OtherInputMasks *imasks;
+
+ imasks = xcalloc(1, sizeof(struct _OtherInputMasks));
+ if (!imasks)
+ return FALSE;
+ pWin->optional->inputMasks = imasks;
+ return TRUE;
+}
+
+void
+RecalculateDeviceDeliverableEvents(WindowPtr pWin)
+{
+ InputClientsPtr others;
+ struct _OtherInputMasks *inputMasks; /* default: NULL */
+ WindowPtr pChild, tmp;
+ int i, j;
+
+ pChild = pWin;
+ while (1) {
+ if ((inputMasks = wOtherInputMasks(pChild)) != 0) {
+ for (i = 0; i < EMASKSIZE; i++)
+ memset(inputMasks->xi2mask[i], 0, sizeof(inputMasks->xi2mask[i]));
+ for (others = inputMasks->inputClients; others;
+ others = others->next) {
+ for (i = 0; i < EMASKSIZE; i++)
+ inputMasks->inputEvents[i] |= others->mask[i];
+ for (i = 0; i < EMASKSIZE; i++)
+ for (j = 0; j < XI2MASKSIZE; j++)
+ inputMasks->xi2mask[i][j] |= others->xi2mask[i][j];
+ }
+ for (i = 0; i < EMASKSIZE; i++)
+ inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i];
+ for (tmp = pChild->parent; tmp; tmp = tmp->parent)
+ if (wOtherInputMasks(tmp))
+ for (i = 0; i < EMASKSIZE; i++)
+ inputMasks->deliverableEvents[i] |=
+ (wOtherInputMasks(tmp)->deliverableEvents[i]
+ & ~inputMasks->
+ dontPropagateMask[i] & PropagateMask[i]);
+ }
+ if (pChild->firstChild) {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+#ifdef _MSC_VER
+#pragma warning(disable:4715) /* Not all control paths return a value */
+#endif
+
+int
+InputClientGone(WindowPtr pWin, XID id)
+{
+ InputClientsPtr other, prev;
+
+ if (!wOtherInputMasks(pWin))
+ return (Success);
+ prev = 0;
+ for (other = wOtherInputMasks(pWin)->inputClients; other;
+ other = other->next) {
+ if (other->resource == id) {
+ if (prev) {
+ prev->next = other->next;
+ xfree(other);
+ } else if (!(other->next)) {
+ if (ShouldFreeInputMasks(pWin, TRUE)) {
+ wOtherInputMasks(pWin)->inputClients = other->next;
+ xfree(wOtherInputMasks(pWin));
+ pWin->optional->inputMasks = (OtherInputMasks *) NULL;
+ CheckWindowOptionalNeed(pWin);
+ xfree(other);
+ } else {
+ other->resource = FakeClientID(0);
+ if (!AddResource(other->resource, RT_INPUTCLIENT,
+ (pointer) pWin))
+ return BadAlloc;
+ }
+ } else {
+ wOtherInputMasks(pWin)->inputClients = other->next;
+ xfree(other);
+ }
+ RecalculateDeviceDeliverableEvents(pWin);
+ return (Success);
+ }
+ prev = other;
+ }
+ FatalError("client not on device event list");
+}
+
+int
+SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate,
+ xEvent * ev, Mask mask, int count)
+{
+ WindowPtr pWin;
+ WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+ WindowPtr spriteWin = GetSpriteWindow(d);
+
+ if (dest == PointerWindow)
+ pWin = spriteWin;
+ else if (dest == InputFocus) {
+ WindowPtr inputFocus;
+
+ if (!d->focus)
+ inputFocus = spriteWin;
+ else
+ inputFocus = d->focus->win;
+
+ if (inputFocus == FollowKeyboardWin)
+ inputFocus = inputInfo.keyboard->focus->win;
+
+ if (inputFocus == NoneWin)
+ return Success;
+
+ /* If the input focus is PointerRootWin, send the event to where
+ * the pointer is if possible, then perhaps propogate up to root. */
+ if (inputFocus == PointerRootWin)
+ inputFocus = GetCurrentRootWindow(d);
+
+ if (IsParent(inputFocus, spriteWin)) {
+ effectiveFocus = inputFocus;
+ pWin = spriteWin;
+ } else
+ effectiveFocus = pWin = inputFocus;
+ } else
+ dixLookupWindow(&pWin, dest, client, DixSendAccess);
+ if (!pWin)
+ return BadWindow;
+ if ((propagate != xFalse) && (propagate != xTrue)) {
+ client->errorValue = propagate;
+ return BadValue;
+ }
+ ev->u.u.type |= 0x80;
+ if (propagate) {
+ for (; pWin; pWin = pWin->parent) {
+ if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab))
+ return Success;
+ if (pWin == effectiveFocus)
+ return Success;
+ if (wOtherInputMasks(pWin))
+ mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id];
+ if (!mask)
+ break;
+ }
+ } else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count))
+ DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab);
+ return Success;
+}
+
+int
+SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map)
+{
+ int i;
+ ButtonClassPtr b = dev->button;
+
+ if (b == NULL)
+ return BadMatch;
+
+ if (nElts != b->numButtons) {
+ client->errorValue = nElts;
+ return BadValue;
+ }
+ if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue))
+ return BadValue;
+ for (i = 0; i < nElts; i++)
+ if ((b->map[i + 1] != map[i]) && BitIsOn(b->down, i + 1))
+ return MappingBusy;
+ for (i = 0; i < nElts; i++)
+ b->map[i + 1] = map[i];
+ return Success;
+}
+
+int
+ChangeKeyMapping(ClientPtr client,
+ DeviceIntPtr dev,
+ unsigned len,
+ int type,
+ KeyCode firstKeyCode,
+ CARD8 keyCodes, CARD8 keySymsPerKeyCode, KeySym * map)
+{
+ KeySymsRec keysyms;
+ KeyClassPtr k = dev->key;
+
+ if (k == NULL)
+ return (BadMatch);
+
+ if (len != (keyCodes * keySymsPerKeyCode))
+ return BadLength;
+
+ if ((firstKeyCode < k->xkbInfo->desc->min_key_code) ||
+ (firstKeyCode + keyCodes - 1 > k->xkbInfo->desc->max_key_code)) {
+ client->errorValue = firstKeyCode;
+ return BadValue;
+ }
+ if (keySymsPerKeyCode == 0) {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ keysyms.minKeyCode = firstKeyCode;
+ keysyms.maxKeyCode = firstKeyCode + keyCodes - 1;
+ keysyms.mapWidth = keySymsPerKeyCode;
+ keysyms.map = map;
+
+ XkbApplyMappingChange(dev, &keysyms, firstKeyCode, keyCodes, NULL,
+ serverClient);
+
+ return client->noClientException;
+}
+
+static void
+DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
+{
+ WindowPtr parent;
+
+ /* Deactivate any grabs performed on this window, before making
+ * any input focus changes.
+ * Deactivating a device grab should cause focus events. */
+
+ if (dev->deviceGrab.grab && (dev->deviceGrab.grab->window == pWin))
+ (*dev->deviceGrab.DeactivateGrab) (dev);
+
+ /* If the focus window is a root window (ie. has no parent)
+ * then don't delete the focus from it. */
+
+ if (dev->focus && (pWin == dev->focus->win) && (pWin->parent != NullWindow)) {
+ int focusEventMode = NotifyNormal;
+
+ /* If a grab is in progress, then alter the mode of focus events. */
+
+ if (dev->deviceGrab.grab)
+ focusEventMode = NotifyWhileGrabbed;
+
+ switch (dev->focus->revert) {
+ case RevertToNone:
+ if (!ActivateFocusInGrab(dev, pWin, NoneWin))
+ DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
+ dev->focus->win = NoneWin;
+ dev->focus->traceGood = 0;
+ break;
+ case RevertToParent:
+ parent = pWin;
+ do {
+ parent = parent->parent;
+ dev->focus->traceGood--;
+ }
+ while (!parent->realized);
+ if (!ActivateFocusInGrab(dev, pWin, parent))
+ DoFocusEvents(dev, pWin, parent, focusEventMode);
+ dev->focus->win = parent;
+ dev->focus->revert = RevertToNone;
+ break;
+ case RevertToPointerRoot:
+ if (!ActivateFocusInGrab(dev, pWin, PointerRootWin))
+ DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode);
+ dev->focus->win = PointerRootWin;
+ dev->focus->traceGood = 0;
+ break;
+ case RevertToFollowKeyboard:
+ {
+ DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD);
+ if (!kbd || (kbd == dev && kbd != inputInfo.keyboard))
+ kbd = inputInfo.keyboard;
+ if (kbd->focus->win) {
+ if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win))
+ DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode);
+ dev->focus->win = FollowKeyboardWin;
+ dev->focus->traceGood = 0;
+ } else {
+ if (!ActivateFocusInGrab(dev, pWin, NoneWin))
+ DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
+ dev->focus->win = NoneWin;
+ dev->focus->traceGood = 0;
+ }
+ }
+ break;
+ }
+ }
+
+ if (dev->valuator)
+ if (dev->valuator->motionHintWindow == pWin)
+ dev->valuator->motionHintWindow = NullWindow;
+}
+
+void
+DeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources)
+{
+ int i;
+ DeviceIntPtr dev;
+ InputClientsPtr ic;
+ struct _OtherInputMasks *inputMasks;
+
+ for (dev = inputInfo.devices; dev; dev = dev->next) {
+ DeleteDeviceFromAnyExtEvents(pWin, dev);
+ }
+
+ for (dev = inputInfo.off_devices; dev; dev = dev->next)
+ DeleteDeviceFromAnyExtEvents(pWin, dev);
+
+ if (freeResources)
+ while ((inputMasks = wOtherInputMasks(pWin)) != 0) {
+ ic = inputMasks->inputClients;
+ for (i = 0; i < EMASKSIZE; i++)
+ inputMasks->dontPropagateMask[i] = 0;
+ FreeResource(ic->resource, RT_NONE);
+ }
+}
+
+int
+MaybeSendDeviceMotionNotifyHint(deviceKeyButtonPointer * pEvents, Mask mask)
+{
+ DeviceIntPtr dev;
+
+ dixLookupDevice(&dev, pEvents->deviceid & DEVICE_BITS, serverClient,
+ DixReadAccess);
+ if (!dev)
+ return 0;
+
+ if (pEvents->type == DeviceMotionNotify) {
+ if (mask & DevicePointerMotionHintMask) {
+ if (WID(dev->valuator->motionHintWindow) == pEvents->event) {
+ return 1; /* don't send, but pretend we did */
+ }
+ pEvents->detail = NotifyHint;
+ } else {
+ pEvents->detail = NotifyNormal;
+ }
+ }
+ return (0);
+}
+
+void
+CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type,
+ deviceKeyButtonPointer * xE, GrabPtr grab,
+ ClientPtr client, Mask deliveryMask)
+{
+ DeviceIntPtr dev;
+
+ dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient,
+ DixGrabAccess);
+ if (!dev)
+ return;
+
+ if (type == DeviceMotionNotify)
+ dev->valuator->motionHintWindow = pWin;
+ else if ((type == DeviceButtonPress) && (!grab) &&
+ (deliveryMask & DeviceButtonGrabMask)) {
+ GrabRec tempGrab;
+
+ tempGrab.device = dev;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.window = pWin;
+ tempGrab.ownerEvents =
+ (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE;
+ tempGrab.eventMask = deliveryMask;
+ tempGrab.keyboardMode = GrabModeAsync;
+ tempGrab.pointerMode = GrabModeAsync;
+ tempGrab.confineTo = NullWindow;
+ tempGrab.cursor = NullCursor;
+ tempGrab.next = NULL;
+ (*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE);
+ }
+}
+
+static Mask
+DeviceEventMaskForClient(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client)
+{
+ InputClientsPtr other;
+
+ if (!wOtherInputMasks(pWin))
+ return 0;
+ for (other = wOtherInputMasks(pWin)->inputClients; other;
+ other = other->next) {
+ if (SameClient(other, client))
+ return other->mask[dev->id];
+ }
+ return 0;
+}
+
+void
+MaybeStopDeviceHint(DeviceIntPtr dev, ClientPtr client)
+{
+ WindowPtr pWin;
+ GrabPtr grab = dev->deviceGrab.grab;
+
+ pWin = dev->valuator->motionHintWindow;
+
+ if ((grab && SameClient(grab, client) &&
+ ((grab->eventMask & DevicePointerMotionHintMask) ||
+ (grab->ownerEvents &&
+ (DeviceEventMaskForClient(dev, pWin, client) &
+ DevicePointerMotionHintMask)))) ||
+ (!grab &&
+ (DeviceEventMaskForClient(dev, pWin, client) &
+ DevicePointerMotionHintMask)))
+ dev->valuator->motionHintWindow = NullWindow;
+}
+
+int
+DeviceEventSuppressForWindow(WindowPtr pWin, ClientPtr client, Mask mask,
+ int maskndx)
+{
+ struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
+
+ if (mask & ~PropagateMask[maskndx]) {
+ client->errorValue = mask;
+ return BadValue;
+ }
+
+ if (mask == 0) {
+ if (inputMasks)
+ inputMasks->dontPropagateMask[maskndx] = mask;
+ } else {
+ if (!inputMasks)
+ AddExtensionClient(pWin, client, 0, 0);
+ inputMasks = wOtherInputMasks(pWin);
+ inputMasks->dontPropagateMask[maskndx] = mask;
+ }
+ RecalculateDeviceDeliverableEvents(pWin);
+ if (ShouldFreeInputMasks(pWin, FALSE))
+ FreeResource(inputMasks->inputClients->resource, RT_NONE);
+ return Success;
+}
+
+Bool
+ShouldFreeInputMasks(WindowPtr pWin, Bool ignoreSelectedEvents)
+{
+ int i;
+ Mask allInputEventMasks = 0;
+ struct _OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
+
+ for (i = 0; i < EMASKSIZE; i++)
+ allInputEventMasks |= inputMasks->dontPropagateMask[i];
+ if (!ignoreSelectedEvents)
+ for (i = 0; i < EMASKSIZE; i++)
+ allInputEventMasks |= inputMasks->inputEvents[i];
+ if (allInputEventMasks == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+/***********************************************************************
+ *
+ * Walk through the window tree, finding all clients that want to know
+ * about the Event.
+ *
+ */
+
+static void
+FindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask,
+ xEvent * ev, int count)
+{
+ WindowPtr p2;
+
+ while (p1) {
+ p2 = p1->firstChild;
+ DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab);
+ FindInterestedChildren(dev, p2, mask, ev, count);
+ p1 = p1->nextSib;
+ }
+}
+
+/***********************************************************************
+ *
+ * Send an event to interested clients in all windows on all screens.
+ *
+ */
+
+void
+SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count)
+{
+ int i;
+ WindowPtr pWin, p1;
+
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ pWin = WindowTable[i];
+ if (!pWin)
+ continue;
+ DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab);
+ p1 = pWin->firstChild;
+ FindInterestedChildren(dev, p1, mask, ev, count);
+ }
+}
+
+/**
+ * Set the XI2 mask for the given client on the given window.
+ * @param dev The device to set the mask for.
+ * @param win The window to set the mask on.
+ * @param client The client setting the mask.
+ * @param len Number of bytes in mask.
+ * @param mask Event mask in the form of (1 << eventtype)
+ */
+int
+XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client,
+ unsigned int len, unsigned char* mask)
+{
+ OtherInputMasks *masks;
+ InputClientsPtr others = NULL;
+
+ masks = wOtherInputMasks(win);
+ if (masks)
+ {
+ for (others = wOtherInputMasks(win)->inputClients; others;
+ others = others->next) {
+ if (SameClient(others, client)) {
+ memset(others->xi2mask[dev->id], 0,
+ sizeof(others->xi2mask[dev->id]));
+ break;
+ }
+ }
+ }
+
+ len = min(len, sizeof(others->xi2mask[dev->id]));
+
+ if (len && !others)
+ {
+ if (AddExtensionClient(win, client, 0, 0) != Success)
+ return BadAlloc;
+ others= wOtherInputMasks(win)->inputClients;
+ }
+
+ if (others)
+ memset(others->xi2mask[dev->id], 0, sizeof(others->xi2mask[dev->id]));
+
+ if (len)
+ memcpy(others->xi2mask[dev->id], mask, len);
+
+ RecalculateDeviceDeliverableEvents(win);
+
+ return Success;
+}
diff --git a/xorg-server/Xi/makefile b/xorg-server/Xi/makefile new file mode 100644 index 000000000..a466c84f0 --- /dev/null +++ b/xorg-server/Xi/makefile @@ -0,0 +1,55 @@ +CSRCS=allowev.c \ + chgdctl.c \ + chgfctl.c \ + chgkbd.c \ + chgkmap.c \ + chgprop.c \ + chgptr.c \ + closedev.c \ + devbell.c \ + exevents.c \ + extinit.c \ + getbmap.c \ + getdctl.c \ + getfctl.c \ + getfocus.c \ + getkmap.c \ + getmmap.c \ + getprop.c \ + getselev.c \ + getvers.c \ + grabdev.c \ + grabdevb.c \ + grabdevk.c \ + gtmotion.c \ + listdev.c \ + opendev.c \ + queryst.c \ + selectev.c \ + sendexev.c \ + setbmap.c \ + setdval.c \ + setfocus.c \ + setmmap.c \ + setmode.c \ + ungrdev.c \ + ungrdevb.c \ + ungrdevk.c \ + xiallowev.c \ + xichangecursor.c \ + xichangehierarchy.c \ + xigetclientpointer.c \ + xigrabdev.c \ + xipassivegrab.c \ + xiproperty.c \ + xiquerydevice.c \ + xiquerypointer.c \ + xiqueryversion.c \ + xiselectev.c \ + xisetclientpointer.c \ + xisetdevfocus.c \ + xiwarppointer.c \ + stubs.c + +LIBRARY=libXi + diff --git a/xorg-server/composite/compalloc.c b/xorg-server/composite/compalloc.c index 73adc72d0..978fe5c17 100644 --- a/xorg-server/composite/compalloc.c +++ b/xorg-server/composite/compalloc.c @@ -1,647 +1,647 @@ -/* - * Copyright © 2006 Sun Microsystems, 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 (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. - * - * Copyright © 2003 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 <dix-config.h> -#endif - -#include "compint.h" - -static void -compReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure) -{ - WindowPtr pWin = (WindowPtr) closure; - ScreenPtr pScreen = pWin->drawable.pScreen; - CompScreenPtr cs = GetCompScreen (pScreen); - CompWindowPtr cw = GetCompWindow (pWin); - - cs->damaged = TRUE; - cw->damaged = TRUE; -} - -static void -compDestroyDamage (DamagePtr pDamage, void *closure) -{ - WindowPtr pWin = (WindowPtr) closure; - CompWindowPtr cw = GetCompWindow (pWin); - - cw->damage = 0; -} - -/* - * Redirect one window for one client - */ -int -compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update) -{ - CompWindowPtr cw = GetCompWindow (pWin); - CompClientWindowPtr ccw; - Bool wasMapped = pWin->mapped; - CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen); - - if (pWin == cs->pOverlayWin) { - return Success; - } - - if (!pWin->parent) - return BadMatch; - - /* - * Only one Manual update is allowed - */ - if (cw && update == CompositeRedirectManual) - for (ccw = cw->clients; ccw; ccw = ccw->next) - if (ccw->update == CompositeRedirectManual) - return BadAccess; - - /* - * Allocate per-client per-window structure - * The client *could* allocate multiple, but while supported, - * it is not expected to be common - */ - ccw = xalloc (sizeof (CompClientWindowRec)); - if (!ccw) - return BadAlloc; - ccw->id = FakeClientID (pClient->index); - ccw->update = update; - /* - * Now make sure there's a per-window structure to hang this from - */ - if (!cw) - { - cw = xalloc (sizeof (CompWindowRec)); - if (!cw) - { - xfree (ccw); - return BadAlloc; - } - cw->damage = DamageCreate (compReportDamage, - compDestroyDamage, - DamageReportNonEmpty, - FALSE, - pWin->drawable.pScreen, - pWin); - if (!cw->damage) - { - xfree (ccw); - xfree (cw); - return BadAlloc; - } - if (wasMapped) - { - DisableMapUnmapEvents (pWin); - UnmapWindow (pWin, FALSE); - EnableMapUnmapEvents (pWin); - } - - REGION_NULL (pScreen, &cw->borderClip); - cw->borderClipX = 0; - cw->borderClipY = 0; - cw->update = CompositeRedirectAutomatic; - cw->clients = 0; - cw->oldx = COMP_ORIGIN_INVALID; - cw->oldy = COMP_ORIGIN_INVALID; - cw->damageRegistered = FALSE; - cw->damaged = FALSE; - dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, cw); - } - ccw->next = cw->clients; - cw->clients = ccw; - if (!AddResource (ccw->id, CompositeClientWindowType, pWin)) - return BadAlloc; - if (ccw->update == CompositeRedirectManual) - { - /* If the window was CompositeRedirectAutomatic, then - * unmap the window so that the parent clip list will - * be correctly recomputed. - */ - if (pWin->mapped) - { - DisableMapUnmapEvents (pWin); - UnmapWindow (pWin, FALSE); - EnableMapUnmapEvents (pWin); - } - if (cw->damageRegistered) - { - DamageUnregister (&pWin->drawable, cw->damage); - cw->damageRegistered = FALSE; - } - cw->update = CompositeRedirectManual; - } - - if (!compCheckRedirect (pWin)) - { - FreeResource (ccw->id, RT_NONE); - return BadAlloc; - } - if (wasMapped && !pWin->mapped) - { - Bool overrideRedirect = pWin->overrideRedirect; - pWin->overrideRedirect = TRUE; - DisableMapUnmapEvents (pWin); - MapWindow (pWin, pClient); - EnableMapUnmapEvents (pWin); - pWin->overrideRedirect = overrideRedirect; - } - - return Success; -} - -/* - * Free one of the per-client per-window resources, clearing - * redirect and the per-window pointer as appropriate - */ -void -compFreeClientWindow (WindowPtr pWin, XID id) -{ - CompWindowPtr cw = GetCompWindow (pWin); - CompClientWindowPtr ccw, *prev; - Bool wasMapped = pWin->mapped; - - if (!cw) - return; - for (prev = &cw->clients; (ccw = *prev); prev = &ccw->next) - { - if (ccw->id == id) - { - *prev = ccw->next; - if (ccw->update == CompositeRedirectManual) - cw->update = CompositeRedirectAutomatic; - xfree (ccw); - break; - } - } - if (!cw->clients) - { - if (wasMapped) - { - DisableMapUnmapEvents (pWin); - UnmapWindow (pWin, FALSE); - EnableMapUnmapEvents (pWin); - } - - if (pWin->redirectDraw != RedirectDrawNone) - compFreePixmap (pWin); - - if (cw->damage) - DamageDestroy (cw->damage); - - REGION_UNINIT (pScreen, &cw->borderClip); - - dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, NULL); - xfree (cw); - } - else if (cw->update == CompositeRedirectAutomatic && - !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone) - { - DamageRegister (&pWin->drawable, cw->damage); - cw->damageRegistered = TRUE; - pWin->redirectDraw = RedirectDrawAutomatic; - DamageRegionAppend(&pWin->drawable, &pWin->borderSize); - } - if (wasMapped && !pWin->mapped) - { - Bool overrideRedirect = pWin->overrideRedirect; - pWin->overrideRedirect = TRUE; - DisableMapUnmapEvents (pWin); - MapWindow (pWin, clients[CLIENT_ID(id)]); - EnableMapUnmapEvents (pWin); - pWin->overrideRedirect = overrideRedirect; - } -} - -/* - * This is easy, just free the appropriate resource. - */ - -int -compUnredirectWindow (ClientPtr pClient, WindowPtr pWin, int update) -{ - CompWindowPtr cw = GetCompWindow (pWin); - CompClientWindowPtr ccw; - - if (!cw) - return BadValue; - - for (ccw = cw->clients; ccw; ccw = ccw->next) - if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index) - { - FreeResource (ccw->id, RT_NONE); - return Success; - } - return BadValue; -} - -/* - * Redirect all subwindows for one client - */ - -int -compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update) -{ - CompSubwindowsPtr csw = GetCompSubwindows (pWin); - CompClientWindowPtr ccw; - WindowPtr pChild; - - /* - * Only one Manual update is allowed - */ - if (csw && update == CompositeRedirectManual) - for (ccw = csw->clients; ccw; ccw = ccw->next) - if (ccw->update == CompositeRedirectManual) - return BadAccess; - /* - * Allocate per-client per-window structure - * The client *could* allocate multiple, but while supported, - * it is not expected to be common - */ - ccw = xalloc (sizeof (CompClientWindowRec)); - if (!ccw) - return BadAlloc; - ccw->id = FakeClientID (pClient->index); - ccw->update = update; - /* - * Now make sure there's a per-window structure to hang this from - */ - if (!csw) - { - csw = xalloc (sizeof (CompSubwindowsRec)); - if (!csw) - { - xfree (ccw); - return BadAlloc; - } - csw->update = CompositeRedirectAutomatic; - csw->clients = 0; - dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, csw); - } - /* - * Redirect all existing windows - */ - for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib) - { - int ret = compRedirectWindow (pClient, pChild, update); - if (ret != Success) - { - for (pChild = pChild->nextSib; pChild; pChild = pChild->nextSib) - (void) compUnredirectWindow (pClient, pChild, update); - if (!csw->clients) - { - xfree (csw); - dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, 0); - } - xfree (ccw); - return ret; - } - } - /* - * Hook into subwindows list - */ - ccw->next = csw->clients; - csw->clients = ccw; - if (!AddResource (ccw->id, CompositeClientSubwindowsType, pWin)) - return BadAlloc; - if (ccw->update == CompositeRedirectManual) - { - csw->update = CompositeRedirectManual; - /* - * tell damage extension that damage events for this client are - * critical output - */ - DamageExtSetCritical (pClient, TRUE); - } - return Success; -} - -/* - * Free one of the per-client per-subwindows resources, - * which frees one redirect per subwindow - */ -void -compFreeClientSubwindows (WindowPtr pWin, XID id) -{ - CompSubwindowsPtr csw = GetCompSubwindows (pWin); - CompClientWindowPtr ccw, *prev; - WindowPtr pChild; - - if (!csw) - return; - for (prev = &csw->clients; (ccw = *prev); prev = &ccw->next) - { - if (ccw->id == id) - { - ClientPtr pClient = clients[CLIENT_ID(id)]; - - *prev = ccw->next; - if (ccw->update == CompositeRedirectManual) - { - /* - * tell damage extension that damage events for this client are - * critical output - */ - DamageExtSetCritical (pClient, FALSE); - csw->update = CompositeRedirectAutomatic; - if (pWin->mapped) - (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, TRUE); - } - - /* - * Unredirect all existing subwindows - */ - for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib) - (void) compUnredirectWindow (pClient, pChild, ccw->update); - - xfree (ccw); - break; - } - } - - /* - * Check if all of the per-client records are gone - */ - if (!csw->clients) - { - dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, NULL); - xfree (csw); - } -} - -/* - * This is easy, just free the appropriate resource. - */ - -int -compUnredirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update) -{ - CompSubwindowsPtr csw = GetCompSubwindows (pWin); - CompClientWindowPtr ccw; - - if (!csw) - return BadValue; - for (ccw = csw->clients; ccw; ccw = ccw->next) - if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index) - { - FreeResource (ccw->id, RT_NONE); - return Success; - } - return BadValue; -} - -/* - * Add redirection information for one subwindow (during reparent) - */ - -int -compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin) -{ - CompSubwindowsPtr csw = GetCompSubwindows (pParent); - CompClientWindowPtr ccw; - - if (!csw) - return Success; - for (ccw = csw->clients; ccw; ccw = ccw->next) - { - int ret = compRedirectWindow (clients[CLIENT_ID(ccw->id)], - pWin, ccw->update); - if (ret != Success) - return ret; - } - return Success; -} - -/* - * Remove redirection information for one subwindow (during reparent) - */ - -int -compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin) -{ - CompSubwindowsPtr csw = GetCompSubwindows (pParent); - CompClientWindowPtr ccw; - - if (!csw) - return Success; - for (ccw = csw->clients; ccw; ccw = ccw->next) - { - int ret = compUnredirectWindow (clients[CLIENT_ID(ccw->id)], - pWin, ccw->update); - if (ret != Success) - return ret; - } - return Success; -} - -static PixmapPtr -compNewPixmap (WindowPtr pWin, int x, int y, int w, int h) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - WindowPtr pParent = pWin->parent; - PixmapPtr pPixmap; - - pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth, - CREATE_PIXMAP_USAGE_BACKING_PIXMAP); - - if (!pPixmap) - return 0; - - pPixmap->screen_x = x; - pPixmap->screen_y = y; - - if (pParent->drawable.depth == pWin->drawable.depth) - { - GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen); - - /* - * Copy bits from the parent into the new pixmap so that it will - * have "reasonable" contents in case for background None areas. - */ - if (pGC) - { - XID val = IncludeInferiors; - - ValidateGC(&pPixmap->drawable, pGC); - dixChangeGC (serverClient, pGC, GCSubwindowMode, &val, NULL); - (*pGC->ops->CopyArea) (&pParent->drawable, - &pPixmap->drawable, - pGC, - x - pParent->drawable.x, - y - pParent->drawable.y, - w, h, 0, 0); - FreeScratchGC (pGC); - } - } - else - { - PictFormatPtr pSrcFormat = compWindowFormat (pParent); - PictFormatPtr pDstFormat = compWindowFormat (pWin); - XID inferiors = IncludeInferiors; - int error; - - PicturePtr pSrcPicture = CreatePicture (None, - &pParent->drawable, - pSrcFormat, - CPSubwindowMode, - &inferiors, - serverClient, &error); - - PicturePtr pDstPicture = CreatePicture (None, - &pPixmap->drawable, - pDstFormat, - 0, 0, - serverClient, &error); - - if (pSrcPicture && pDstPicture) - { - CompositePicture (PictOpSrc, - pSrcPicture, - NULL, - pDstPicture, - x - pParent->drawable.x, - y - pParent->drawable.y, - 0, 0, 0, 0, w, h); - } - if (pSrcPicture) - FreePicture (pSrcPicture, 0); - if (pDstPicture) - FreePicture (pDstPicture, 0); - } - return pPixmap; -} - -Bool -compAllocPixmap (WindowPtr pWin) -{ - int bw = (int) pWin->borderWidth; - int x = pWin->drawable.x - bw; - int y = pWin->drawable.y - bw; - int w = pWin->drawable.width + (bw << 1); - int h = pWin->drawable.height + (bw << 1); - PixmapPtr pPixmap = compNewPixmap (pWin, x, y, w, h); - CompWindowPtr cw = GetCompWindow (pWin); - - if (!pPixmap) - return FALSE; - if (cw->update == CompositeRedirectAutomatic) - pWin->redirectDraw = RedirectDrawAutomatic; - else - pWin->redirectDraw = RedirectDrawManual; - - compSetPixmap (pWin, pPixmap); - cw->oldx = COMP_ORIGIN_INVALID; - cw->oldy = COMP_ORIGIN_INVALID; - cw->damageRegistered = FALSE; - if (cw->update == CompositeRedirectAutomatic) - { - DamageRegister (&pWin->drawable, cw->damage); - cw->damageRegistered = TRUE; - } - return TRUE; -} - -void -compFreePixmap (WindowPtr pWin) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - PixmapPtr pRedirectPixmap, pParentPixmap; - CompWindowPtr cw = GetCompWindow (pWin); - - if (cw->damageRegistered) - { - DamageUnregister (&pWin->drawable, cw->damage); - cw->damageRegistered = FALSE; - DamageEmpty (cw->damage); - } - /* - * Move the parent-constrained border clip region back into - * the window so that ValidateTree will handle the unmap - * case correctly. Unmap adds the window borderClip to the - * parent exposed area; regions beyond the parent cause crashes - */ - REGION_COPY (pScreen, &pWin->borderClip, &cw->borderClip); - pRedirectPixmap = (*pScreen->GetWindowPixmap) (pWin); - pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent); - pWin->redirectDraw = RedirectDrawNone; - compSetPixmap (pWin, pParentPixmap); - (*pScreen->DestroyPixmap) (pRedirectPixmap); -} - -/* - * Make sure the pixmap is the right size and offset. Allocate a new - * pixmap to change size, adjust origin to change offset, leaving the - * old pixmap in cw->pOldPixmap so bits can be recovered - */ -Bool -compReallocPixmap (WindowPtr pWin, int draw_x, int draw_y, - unsigned int w, unsigned int h, int bw) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - PixmapPtr pOld = (*pScreen->GetWindowPixmap) (pWin); - PixmapPtr pNew; - CompWindowPtr cw = GetCompWindow (pWin); - int pix_x, pix_y; - int pix_w, pix_h; - - assert (cw && pWin->redirectDraw != RedirectDrawNone); - cw->oldx = pOld->screen_x; - cw->oldy = pOld->screen_y; - pix_x = draw_x - bw; - pix_y = draw_y - bw; - pix_w = w + (bw << 1); - pix_h = h + (bw << 1); - if (pix_w != pOld->drawable.width || pix_h != pOld->drawable.height) - { - pNew = compNewPixmap (pWin, pix_x, pix_y, pix_w, pix_h); - if (!pNew) - return FALSE; - cw->pOldPixmap = pOld; - compSetPixmap (pWin, pNew); - } - else - { - pNew = pOld; - cw->pOldPixmap = 0; - } - pNew->screen_x = pix_x; - pNew->screen_y = pix_y; - return TRUE; -} +/*
+ * Copyright © 2006 Sun Microsystems, 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 (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.
+ *
+ * Copyright © 2003 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 <dix-config.h>
+#endif
+
+#include "compint.h"
+
+static void
+compReportDamage (DamagePtr pDamage, RegionPtr pRegion, void *closure)
+{
+ WindowPtr pWin = (WindowPtr) closure;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+ CompWindowPtr cw = GetCompWindow (pWin);
+
+ cs->damaged = TRUE;
+ cw->damaged = TRUE;
+}
+
+static void
+compDestroyDamage (DamagePtr pDamage, void *closure)
+{
+ WindowPtr pWin = (WindowPtr) closure;
+ CompWindowPtr cw = GetCompWindow (pWin);
+
+ cw->damage = 0;
+}
+
+/*
+ * Redirect one window for one client
+ */
+int
+compRedirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
+{
+ CompWindowPtr cw = GetCompWindow (pWin);
+ CompClientWindowPtr ccw;
+ Bool wasMapped = pWin->mapped;
+ CompScreenPtr cs = GetCompScreen(pWin->drawable.pScreen);
+
+ if (pWin == cs->pOverlayWin) {
+ return Success;
+ }
+
+ if (!pWin->parent)
+ return BadMatch;
+
+ /*
+ * Only one Manual update is allowed
+ */
+ if (cw && update == CompositeRedirectManual)
+ for (ccw = cw->clients; ccw; ccw = ccw->next)
+ if (ccw->update == CompositeRedirectManual)
+ return BadAccess;
+
+ /*
+ * Allocate per-client per-window structure
+ * The client *could* allocate multiple, but while supported,
+ * it is not expected to be common
+ */
+ ccw = xalloc (sizeof (CompClientWindowRec));
+ if (!ccw)
+ return BadAlloc;
+ ccw->id = FakeClientID (pClient->index);
+ ccw->update = update;
+ /*
+ * Now make sure there's a per-window structure to hang this from
+ */
+ if (!cw)
+ {
+ cw = xcalloc (1,sizeof (CompWindowRec));
+ if (!cw)
+ {
+ xfree (ccw);
+ return BadAlloc;
+ }
+ cw->damage = DamageCreate (compReportDamage,
+ compDestroyDamage,
+ DamageReportNonEmpty,
+ FALSE,
+ pWin->drawable.pScreen,
+ pWin);
+ if (!cw->damage)
+ {
+ xfree (ccw);
+ xfree (cw);
+ return BadAlloc;
+ }
+ if (wasMapped)
+ {
+ DisableMapUnmapEvents (pWin);
+ UnmapWindow (pWin, FALSE);
+ EnableMapUnmapEvents (pWin);
+ }
+
+ REGION_NULL (pScreen, &cw->borderClip);
+ cw->borderClipX = 0;
+ cw->borderClipY = 0;
+ cw->update = CompositeRedirectAutomatic;
+ cw->clients = 0;
+ cw->oldx = COMP_ORIGIN_INVALID;
+ cw->oldy = COMP_ORIGIN_INVALID;
+ cw->damageRegistered = FALSE;
+ cw->damaged = FALSE;
+ dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, cw);
+ }
+ ccw->next = cw->clients;
+ cw->clients = ccw;
+ if (!AddResource (ccw->id, CompositeClientWindowType, pWin))
+ return BadAlloc;
+ if (ccw->update == CompositeRedirectManual)
+ {
+ /* If the window was CompositeRedirectAutomatic, then
+ * unmap the window so that the parent clip list will
+ * be correctly recomputed.
+ */
+ if (pWin->mapped)
+ {
+ DisableMapUnmapEvents (pWin);
+ UnmapWindow (pWin, FALSE);
+ EnableMapUnmapEvents (pWin);
+ }
+ if (cw->damageRegistered)
+ {
+ DamageUnregister (&pWin->drawable, cw->damage);
+ cw->damageRegistered = FALSE;
+ }
+ cw->update = CompositeRedirectManual;
+ }
+
+ if (!compCheckRedirect (pWin))
+ {
+ FreeResource (ccw->id, RT_NONE);
+ return BadAlloc;
+ }
+ if (wasMapped && !pWin->mapped)
+ {
+ Bool overrideRedirect = pWin->overrideRedirect;
+ pWin->overrideRedirect = TRUE;
+ DisableMapUnmapEvents (pWin);
+ MapWindow (pWin, pClient);
+ EnableMapUnmapEvents (pWin);
+ pWin->overrideRedirect = overrideRedirect;
+ }
+
+ return Success;
+}
+
+/*
+ * Free one of the per-client per-window resources, clearing
+ * redirect and the per-window pointer as appropriate
+ */
+void
+compFreeClientWindow (WindowPtr pWin, XID id)
+{
+ CompWindowPtr cw = GetCompWindow (pWin);
+ CompClientWindowPtr ccw, *prev;
+ Bool wasMapped = pWin->mapped;
+
+ if (!cw)
+ return;
+ for (prev = &cw->clients; (ccw = *prev); prev = &ccw->next)
+ {
+ if (ccw->id == id)
+ {
+ *prev = ccw->next;
+ if (ccw->update == CompositeRedirectManual)
+ cw->update = CompositeRedirectAutomatic;
+ xfree (ccw);
+ break;
+ }
+ }
+ if (!cw->clients)
+ {
+ if (wasMapped)
+ {
+ DisableMapUnmapEvents (pWin);
+ UnmapWindow (pWin, FALSE);
+ EnableMapUnmapEvents (pWin);
+ }
+
+ if (pWin->redirectDraw != RedirectDrawNone)
+ compFreePixmap (pWin);
+
+ if (cw->damage)
+ DamageDestroy (cw->damage);
+
+ REGION_UNINIT (pScreen, &cw->borderClip);
+
+ dixSetPrivate(&pWin->devPrivates, CompWindowPrivateKey, NULL);
+ xfree (cw);
+ }
+ else if (cw->update == CompositeRedirectAutomatic &&
+ !cw->damageRegistered && pWin->redirectDraw != RedirectDrawNone)
+ {
+ DamageRegister (&pWin->drawable, cw->damage);
+ cw->damageRegistered = TRUE;
+ pWin->redirectDraw = RedirectDrawAutomatic;
+ DamageRegionAppend(&pWin->drawable, &pWin->borderSize);
+ }
+ if (wasMapped && !pWin->mapped)
+ {
+ Bool overrideRedirect = pWin->overrideRedirect;
+ pWin->overrideRedirect = TRUE;
+ DisableMapUnmapEvents (pWin);
+ MapWindow (pWin, clients[CLIENT_ID(id)]);
+ EnableMapUnmapEvents (pWin);
+ pWin->overrideRedirect = overrideRedirect;
+ }
+}
+
+/*
+ * This is easy, just free the appropriate resource.
+ */
+
+int
+compUnredirectWindow (ClientPtr pClient, WindowPtr pWin, int update)
+{
+ CompWindowPtr cw = GetCompWindow (pWin);
+ CompClientWindowPtr ccw;
+
+ if (!cw)
+ return BadValue;
+
+ for (ccw = cw->clients; ccw; ccw = ccw->next)
+ if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index)
+ {
+ FreeResource (ccw->id, RT_NONE);
+ return Success;
+ }
+ return BadValue;
+}
+
+/*
+ * Redirect all subwindows for one client
+ */
+
+int
+compRedirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update)
+{
+ CompSubwindowsPtr csw = GetCompSubwindows (pWin);
+ CompClientWindowPtr ccw;
+ WindowPtr pChild;
+
+ /*
+ * Only one Manual update is allowed
+ */
+ if (csw && update == CompositeRedirectManual)
+ for (ccw = csw->clients; ccw; ccw = ccw->next)
+ if (ccw->update == CompositeRedirectManual)
+ return BadAccess;
+ /*
+ * Allocate per-client per-window structure
+ * The client *could* allocate multiple, but while supported,
+ * it is not expected to be common
+ */
+ ccw = xalloc (sizeof (CompClientWindowRec));
+ if (!ccw)
+ return BadAlloc;
+ ccw->id = FakeClientID (pClient->index);
+ ccw->update = update;
+ /*
+ * Now make sure there's a per-window structure to hang this from
+ */
+ if (!csw)
+ {
+ csw = xalloc (sizeof (CompSubwindowsRec));
+ if (!csw)
+ {
+ xfree (ccw);
+ return BadAlloc;
+ }
+ csw->update = CompositeRedirectAutomatic;
+ csw->clients = 0;
+ dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, csw);
+ }
+ /*
+ * Redirect all existing windows
+ */
+ for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
+ {
+ int ret = compRedirectWindow (pClient, pChild, update);
+ if (ret != Success)
+ {
+ for (pChild = pChild->nextSib; pChild; pChild = pChild->nextSib)
+ (void) compUnredirectWindow (pClient, pChild, update);
+ if (!csw->clients)
+ {
+ xfree (csw);
+ dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, 0);
+ }
+ xfree (ccw);
+ return ret;
+ }
+ }
+ /*
+ * Hook into subwindows list
+ */
+ ccw->next = csw->clients;
+ csw->clients = ccw;
+ if (!AddResource (ccw->id, CompositeClientSubwindowsType, pWin))
+ return BadAlloc;
+ if (ccw->update == CompositeRedirectManual)
+ {
+ csw->update = CompositeRedirectManual;
+ /*
+ * tell damage extension that damage events for this client are
+ * critical output
+ */
+ DamageExtSetCritical (pClient, TRUE);
+ }
+ return Success;
+}
+
+/*
+ * Free one of the per-client per-subwindows resources,
+ * which frees one redirect per subwindow
+ */
+void
+compFreeClientSubwindows (WindowPtr pWin, XID id)
+{
+ CompSubwindowsPtr csw = GetCompSubwindows (pWin);
+ CompClientWindowPtr ccw, *prev;
+ WindowPtr pChild;
+
+ if (!csw)
+ return;
+ for (prev = &csw->clients; (ccw = *prev); prev = &ccw->next)
+ {
+ if (ccw->id == id)
+ {
+ ClientPtr pClient = clients[CLIENT_ID(id)];
+
+ *prev = ccw->next;
+ if (ccw->update == CompositeRedirectManual)
+ {
+ /*
+ * tell damage extension that damage events for this client are
+ * critical output
+ */
+ DamageExtSetCritical (pClient, FALSE);
+ csw->update = CompositeRedirectAutomatic;
+ if (pWin->mapped)
+ (*pWin->drawable.pScreen->ClearToBackground)(pWin, 0, 0, 0, 0, TRUE);
+ }
+
+ /*
+ * Unredirect all existing subwindows
+ */
+ for (pChild = pWin->lastChild; pChild; pChild = pChild->prevSib)
+ (void) compUnredirectWindow (pClient, pChild, ccw->update);
+
+ xfree (ccw);
+ break;
+ }
+ }
+
+ /*
+ * Check if all of the per-client records are gone
+ */
+ if (!csw->clients)
+ {
+ dixSetPrivate(&pWin->devPrivates, CompSubwindowsPrivateKey, NULL);
+ xfree (csw);
+ }
+}
+
+/*
+ * This is easy, just free the appropriate resource.
+ */
+
+int
+compUnredirectSubwindows (ClientPtr pClient, WindowPtr pWin, int update)
+{
+ CompSubwindowsPtr csw = GetCompSubwindows (pWin);
+ CompClientWindowPtr ccw;
+
+ if (!csw)
+ return BadValue;
+ for (ccw = csw->clients; ccw; ccw = ccw->next)
+ if (ccw->update == update && CLIENT_ID(ccw->id) == pClient->index)
+ {
+ FreeResource (ccw->id, RT_NONE);
+ return Success;
+ }
+ return BadValue;
+}
+
+/*
+ * Add redirection information for one subwindow (during reparent)
+ */
+
+int
+compRedirectOneSubwindow (WindowPtr pParent, WindowPtr pWin)
+{
+ CompSubwindowsPtr csw = GetCompSubwindows (pParent);
+ CompClientWindowPtr ccw;
+
+ if (!csw)
+ return Success;
+ for (ccw = csw->clients; ccw; ccw = ccw->next)
+ {
+ int ret = compRedirectWindow (clients[CLIENT_ID(ccw->id)],
+ pWin, ccw->update);
+ if (ret != Success)
+ return ret;
+ }
+ return Success;
+}
+
+/*
+ * Remove redirection information for one subwindow (during reparent)
+ */
+
+int
+compUnredirectOneSubwindow (WindowPtr pParent, WindowPtr pWin)
+{
+ CompSubwindowsPtr csw = GetCompSubwindows (pParent);
+ CompClientWindowPtr ccw;
+
+ if (!csw)
+ return Success;
+ for (ccw = csw->clients; ccw; ccw = ccw->next)
+ {
+ int ret = compUnredirectWindow (clients[CLIENT_ID(ccw->id)],
+ pWin, ccw->update);
+ if (ret != Success)
+ return ret;
+ }
+ return Success;
+}
+
+static PixmapPtr
+compNewPixmap (WindowPtr pWin, int x, int y, int w, int h)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ WindowPtr pParent = pWin->parent;
+ PixmapPtr pPixmap;
+
+ pPixmap = (*pScreen->CreatePixmap) (pScreen, w, h, pWin->drawable.depth,
+ CREATE_PIXMAP_USAGE_BACKING_PIXMAP);
+
+ if (!pPixmap)
+ return 0;
+
+ pPixmap->screen_x = x;
+ pPixmap->screen_y = y;
+
+ if (pParent->drawable.depth == pWin->drawable.depth)
+ {
+ GCPtr pGC = GetScratchGC (pWin->drawable.depth, pScreen);
+
+ /*
+ * Copy bits from the parent into the new pixmap so that it will
+ * have "reasonable" contents in case for background None areas.
+ */
+ if (pGC)
+ {
+ XID val = IncludeInferiors;
+
+ ValidateGC(&pPixmap->drawable, pGC);
+ dixChangeGC (serverClient, pGC, GCSubwindowMode, &val, NULL);
+ (*pGC->ops->CopyArea) (&pParent->drawable,
+ &pPixmap->drawable,
+ pGC,
+ x - pParent->drawable.x,
+ y - pParent->drawable.y,
+ w, h, 0, 0);
+ FreeScratchGC (pGC);
+ }
+ }
+ else
+ {
+ PictFormatPtr pSrcFormat = compWindowFormat (pParent);
+ PictFormatPtr pDstFormat = compWindowFormat (pWin);
+ XID inferiors = IncludeInferiors;
+ int error;
+
+ PicturePtr pSrcPicture = CreatePicture (None,
+ &pParent->drawable,
+ pSrcFormat,
+ CPSubwindowMode,
+ &inferiors,
+ serverClient, &error);
+
+ PicturePtr pDstPicture = CreatePicture (None,
+ &pPixmap->drawable,
+ pDstFormat,
+ 0, 0,
+ serverClient, &error);
+
+ if (pSrcPicture && pDstPicture)
+ {
+ CompositePicture (PictOpSrc,
+ pSrcPicture,
+ NULL,
+ pDstPicture,
+ x - pParent->drawable.x,
+ y - pParent->drawable.y,
+ 0, 0, 0, 0, w, h);
+ }
+ if (pSrcPicture)
+ FreePicture (pSrcPicture, 0);
+ if (pDstPicture)
+ FreePicture (pDstPicture, 0);
+ }
+ return pPixmap;
+}
+
+Bool
+compAllocPixmap (WindowPtr pWin)
+{
+ int bw = (int) pWin->borderWidth;
+ int x = pWin->drawable.x - bw;
+ int y = pWin->drawable.y - bw;
+ int w = pWin->drawable.width + (bw << 1);
+ int h = pWin->drawable.height + (bw << 1);
+ PixmapPtr pPixmap = compNewPixmap (pWin, x, y, w, h);
+ CompWindowPtr cw = GetCompWindow (pWin);
+
+ if (!pPixmap)
+ return FALSE;
+ if (cw->update == CompositeRedirectAutomatic)
+ pWin->redirectDraw = RedirectDrawAutomatic;
+ else
+ pWin->redirectDraw = RedirectDrawManual;
+
+ compSetPixmap (pWin, pPixmap);
+ cw->oldx = COMP_ORIGIN_INVALID;
+ cw->oldy = COMP_ORIGIN_INVALID;
+ cw->damageRegistered = FALSE;
+ if (cw->update == CompositeRedirectAutomatic)
+ {
+ DamageRegister (&pWin->drawable, cw->damage);
+ cw->damageRegistered = TRUE;
+ }
+ return TRUE;
+}
+
+void
+compFreePixmap (WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ PixmapPtr pRedirectPixmap, pParentPixmap;
+ CompWindowPtr cw = GetCompWindow (pWin);
+
+ if (cw->damageRegistered)
+ {
+ DamageUnregister (&pWin->drawable, cw->damage);
+ cw->damageRegistered = FALSE;
+ DamageEmpty (cw->damage);
+ }
+ /*
+ * Move the parent-constrained border clip region back into
+ * the window so that ValidateTree will handle the unmap
+ * case correctly. Unmap adds the window borderClip to the
+ * parent exposed area; regions beyond the parent cause crashes
+ */
+ REGION_COPY (pScreen, &pWin->borderClip, &cw->borderClip);
+ pRedirectPixmap = (*pScreen->GetWindowPixmap) (pWin);
+ pParentPixmap = (*pScreen->GetWindowPixmap) (pWin->parent);
+ pWin->redirectDraw = RedirectDrawNone;
+ compSetPixmap (pWin, pParentPixmap);
+ (*pScreen->DestroyPixmap) (pRedirectPixmap);
+}
+
+/*
+ * Make sure the pixmap is the right size and offset. Allocate a new
+ * pixmap to change size, adjust origin to change offset, leaving the
+ * old pixmap in cw->pOldPixmap so bits can be recovered
+ */
+Bool
+compReallocPixmap (WindowPtr pWin, int draw_x, int draw_y,
+ unsigned int w, unsigned int h, int bw)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ PixmapPtr pOld = (*pScreen->GetWindowPixmap) (pWin);
+ PixmapPtr pNew;
+ CompWindowPtr cw = GetCompWindow (pWin);
+ int pix_x, pix_y;
+ int pix_w, pix_h;
+
+ assert (cw && pWin->redirectDraw != RedirectDrawNone);
+ cw->oldx = pOld->screen_x;
+ cw->oldy = pOld->screen_y;
+ pix_x = draw_x - bw;
+ pix_y = draw_y - bw;
+ pix_w = w + (bw << 1);
+ pix_h = h + (bw << 1);
+ if (pix_w != pOld->drawable.width || pix_h != pOld->drawable.height)
+ {
+ pNew = compNewPixmap (pWin, pix_x, pix_y, pix_w, pix_h);
+ if (!pNew)
+ return FALSE;
+ cw->pOldPixmap = pOld;
+ compSetPixmap (pWin, pNew);
+ }
+ else
+ {
+ pNew = pOld;
+ cw->pOldPixmap = 0;
+ }
+ pNew->screen_x = pix_x;
+ pNew->screen_y = pix_y;
+ return TRUE;
+}
diff --git a/xorg-server/composite/compoverlay.c b/xorg-server/composite/compoverlay.c index 6d73f003d..ce6db9977 100644 --- a/xorg-server/composite/compoverlay.c +++ b/xorg-server/composite/compoverlay.c @@ -1,160 +1,164 @@ -/* - * Copyright © 2006 Sun Microsystems, 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 (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. - * - * Copyright © 2003 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 <dix-config.h> -#endif - -#include "compint.h" -#include "xace.h" - -/* - * Delete the given overlay client list element from its screen list. - */ -void -compFreeOverlayClient (CompOverlayClientPtr pOcToDel) -{ - ScreenPtr pScreen = pOcToDel->pScreen; - CompScreenPtr cs = GetCompScreen (pScreen); - CompOverlayClientPtr *pPrev, pOc; - - for (pPrev = &cs->pOverlayClients; (pOc = *pPrev); pPrev = &pOc->pNext) - { - if (pOc == pOcToDel) { - *pPrev = pOc->pNext; - xfree (pOc); - break; - } - } - - /* Destroy overlay window when there are no more clients using it */ - if (cs->pOverlayClients == NULL) - compDestroyOverlayWindow (pScreen); -} - -/* - * Return the client's first overlay client rec from the given screen - */ -CompOverlayClientPtr -compFindOverlayClient (ScreenPtr pScreen, ClientPtr pClient) -{ - CompScreenPtr cs = GetCompScreen(pScreen); - CompOverlayClientPtr pOc; - - for (pOc = cs->pOverlayClients; pOc != NULL; pOc = pOc->pNext) - if (pOc->pClient == pClient) - return pOc; - - return NULL; -} - -/* - * Create an overlay client object for the given client - */ -CompOverlayClientPtr -compCreateOverlayClient (ScreenPtr pScreen, ClientPtr pClient) -{ - CompScreenPtr cs = GetCompScreen(pScreen); - CompOverlayClientPtr pOc; - - pOc = (CompOverlayClientPtr) xalloc(sizeof(CompOverlayClientRec)); - if (pOc == NULL) - return NULL; - - pOc->pClient = pClient; - pOc->pScreen = pScreen; - pOc->resource = FakeClientID(pClient->index); - pOc->pNext = cs->pOverlayClients; - cs->pOverlayClients = pOc; - - /* - * Create a resource for this element so it can be deleted - * when the client goes away. - */ - if (!AddResource (pOc->resource, CompositeClientOverlayType, (pointer) pOc)) - return NULL; - - return pOc; -} - -/* - * Create the overlay window and map it - */ -Bool -compCreateOverlayWindow (ScreenPtr pScreen) -{ - CompScreenPtr cs = GetCompScreen(pScreen); - WindowPtr pRoot = WindowTable[pScreen->myNum]; - WindowPtr pWin; - XID attrs[] = { None, TRUE }; /* backPixmap, overrideRedirect */ - int result; - - pWin = cs->pOverlayWin = - CreateWindow (cs->overlayWid, pRoot, - 0, 0, pScreen->width, pScreen->height, 0, - InputOutput, CWBackPixmap | CWOverrideRedirect, &attrs[0], - pRoot->drawable.depth, - serverClient, pScreen->rootVisual, &result); - if (pWin == NULL) - return FALSE; - - if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin)) - return FALSE; - - MapWindow(pWin, serverClient); - - return TRUE; -} - -/* - * Destroy the overlay window - */ -void -compDestroyOverlayWindow (ScreenPtr pScreen) -{ - CompScreenPtr cs = GetCompScreen(pScreen); - - cs->pOverlayWin = NullWindow; - FreeResource (cs->overlayWid, RT_NONE); -} - +/*
+ * Copyright © 2006 Sun Microsystems, 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 (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.
+ *
+ * Copyright © 2003 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 <dix-config.h>
+#endif
+
+#ifdef CreateWindow
+#undef CreateWindow
+#endif
+
+#include "compint.h"
+#include "xace.h"
+
+/*
+ * Delete the given overlay client list element from its screen list.
+ */
+void
+compFreeOverlayClient (CompOverlayClientPtr pOcToDel)
+{
+ ScreenPtr pScreen = pOcToDel->pScreen;
+ CompScreenPtr cs = GetCompScreen (pScreen);
+ CompOverlayClientPtr *pPrev, pOc;
+
+ for (pPrev = &cs->pOverlayClients; (pOc = *pPrev); pPrev = &pOc->pNext)
+ {
+ if (pOc == pOcToDel) {
+ *pPrev = pOc->pNext;
+ xfree (pOc);
+ break;
+ }
+ }
+
+ /* Destroy overlay window when there are no more clients using it */
+ if (cs->pOverlayClients == NULL)
+ compDestroyOverlayWindow (pScreen);
+}
+
+/*
+ * Return the client's first overlay client rec from the given screen
+ */
+CompOverlayClientPtr
+compFindOverlayClient (ScreenPtr pScreen, ClientPtr pClient)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ CompOverlayClientPtr pOc;
+
+ for (pOc = cs->pOverlayClients; pOc != NULL; pOc = pOc->pNext)
+ if (pOc->pClient == pClient)
+ return pOc;
+
+ return NULL;
+}
+
+/*
+ * Create an overlay client object for the given client
+ */
+CompOverlayClientPtr
+compCreateOverlayClient (ScreenPtr pScreen, ClientPtr pClient)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ CompOverlayClientPtr pOc;
+
+ pOc = (CompOverlayClientPtr) xalloc(sizeof(CompOverlayClientRec));
+ if (pOc == NULL)
+ return NULL;
+
+ pOc->pClient = pClient;
+ pOc->pScreen = pScreen;
+ pOc->resource = FakeClientID(pClient->index);
+ pOc->pNext = cs->pOverlayClients;
+ cs->pOverlayClients = pOc;
+
+ /*
+ * Create a resource for this element so it can be deleted
+ * when the client goes away.
+ */
+ if (!AddResource (pOc->resource, CompositeClientOverlayType, (pointer) pOc))
+ return NULL;
+
+ return pOc;
+}
+
+/*
+ * Create the overlay window and map it
+ */
+Bool
+compCreateOverlayWindow (ScreenPtr pScreen)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+ WindowPtr pRoot = WindowTable[pScreen->myNum];
+ WindowPtr pWin;
+ XID attrs[] = { None, TRUE }; /* backPixmap, overrideRedirect */
+ int result;
+
+ pWin = cs->pOverlayWin =
+ CreateWindow (cs->overlayWid, pRoot,
+ 0, 0, pScreen->width, pScreen->height, 0,
+ InputOutput, CWBackPixmap | CWOverrideRedirect, &attrs[0],
+ pRoot->drawable.depth,
+ serverClient, pScreen->rootVisual, &result);
+ if (pWin == NULL)
+ return FALSE;
+
+ if (!AddResource(pWin->drawable.id, RT_WINDOW, (pointer)pWin))
+ return FALSE;
+
+ MapWindow(pWin, serverClient);
+
+ return TRUE;
+}
+
+/*
+ * Destroy the overlay window
+ */
+void
+compDestroyOverlayWindow (ScreenPtr pScreen)
+{
+ CompScreenPtr cs = GetCompScreen(pScreen);
+
+ cs->pOverlayWin = NullWindow;
+ FreeResource (cs->overlayWid, RT_NONE);
+}
+
diff --git a/xorg-server/composite/makefile b/xorg-server/composite/makefile new file mode 100644 index 000000000..1ab95ebba --- /dev/null +++ b/xorg-server/composite/makefile @@ -0,0 +1,9 @@ +
+LIBRARY=libcomposite
+
+CSRCS = \
+ compalloc.c \
+ compext.c \
+ compinit.c \
+ compoverlay.c \
+ compwindow.c
diff --git a/xorg-server/config/makefile b/xorg-server/config/makefile new file mode 100644 index 000000000..937785271 --- /dev/null +++ b/xorg-server/config/makefile @@ -0,0 +1,4 @@ +CSRCS=config.c
+
+LIBRARY=libconfig
+
diff --git a/xorg-server/damageext/makefile b/xorg-server/damageext/makefile new file mode 100644 index 000000000..c8481cd3c --- /dev/null +++ b/xorg-server/damageext/makefile @@ -0,0 +1,4 @@ +CSRCS=damageext.c
+
+LIBRARY=libdamageext
+
diff --git a/xorg-server/dbe/makefile b/xorg-server/dbe/makefile new file mode 100644 index 000000000..70fb81430 --- /dev/null +++ b/xorg-server/dbe/makefile @@ -0,0 +1,4 @@ +CSRCS=dbe.c midbe.c
+
+LIBRARY=libdbe
+
diff --git a/xorg-server/dix/Xserver-dtrace.h b/xorg-server/dix/Xserver-dtrace.h new file mode 100644 index 000000000..b4f27a0bc --- /dev/null +++ b/xorg-server/dix/Xserver-dtrace.h @@ -0,0 +1,75 @@ +/* Copyright 2006 Sun Microsystems, 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, and/or sell copies of the Software, and to permit persons + * to whom the Software is furnished to do so, provided that the above + * copyright notice(s) and this permission notice appear in all copies of + * the Software and that both the above copyright notice(s) and this + * permission notice appear in supporting documentation. + * + * 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 + * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR + * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR 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. + * + * Except as contained in this notice, the name of a copyright holder + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * of the copyright holder. + */ + +/* + * Generated by dtrace(1M), and then modified for backwards compatibility + * with older versions of dtrace. Used if dtrace -h fails. + * (Since _ENABLED support was added after dtrace -h, this assumes if + * dtrace -h fails, _ENABLED will too.) + */ + +#ifndef _XSERVER_DTRACE_H +#define _XSERVER_DTRACE_H + +#include <unistd.h> + +#ifdef __cplusplus +extern "C" { +#endif + +#define XSERVER_CLIENT_AUTH(arg0, arg1, arg2, arg3) \ + winDebug("XSERVER_CLIENT_AUTH: %d %s %d %d\n",arg0, arg1, arg2, arg3) +#define XSERVER_CLIENT_CONNECT(arg0, arg1) \ + winDebug("XSERVER_CLIENT_CONNECT: %d %d\n",arg0, arg1) +#define XSERVER_CLIENT_DISCONNECT(arg0) \ + winDebug("XSERVER_CLIENT_DISCONNECT: %d %d\n",arg0) +#define XSERVER_REQUEST_DONE(arg0, arg1, arg2, arg3, arg4) \ + winDebug("XSERVER_REQUEST_DONE: %s %d %d %d %d\n",arg0, arg1, arg2, arg3, arg4) +#define XSERVER_REQUEST_START(arg0, arg1, arg2, arg3, arg4) \ + winDebug("XSERVER_REQUEST_START: %s %d %d %d ->%p\n",arg0, arg1, arg2, arg3, arg4) +#define XSERVER_RESOURCE_ALLOC(arg0, arg1, arg2, arg3) \ + winDebug("XSERVER_RESOURCE_ALLOC: 0x%x 0x%x ->%p %s\n",arg0, arg1, arg2, arg3) +#define XSERVER_RESOURCE_FREE(arg0, arg1, arg2, arg3) \ + winDebug("XSERVER_RESOURCE_FREE: 0x%x 0x%x ->%p %s\n",arg0, arg1, arg2, arg3) +#define XSERVER_SEND_EVENT(arg0, arg1, arg2) \ + winDebug("XSERVER_SEND_EVENT: 0x%x 0x%x ->%p\n",arg0, arg1, arg2) + +#define XSERVER_CLIENT_AUTH_ENABLED() (1) +#define XSERVER_CLIENT_CONNECT_ENABLED() (1) +#define XSERVER_CLIENT_DISCONNECT_ENABLED() (1) +#define XSERVER_REQUEST_DONE_ENABLED() (1) +#define XSERVER_REQUEST_START_ENABLED() (1) +#define XSERVER_RESOURCE_ALLOC_ENABLED() (1) +#define XSERVER_RESOURCE_FREE_ENABLED() (1) +#define XSERVER_SEND_EVENT_ENABLED() (1) + +#ifdef __cplusplus +} +#endif + +#endif /* _XSERVER_DTRACE_H */ diff --git a/xorg-server/dix/colormap.c b/xorg-server/dix/colormap.c index bf9794125..cd2101e4a 100644 --- a/xorg-server/dix/colormap.c +++ b/xorg-server/dix/colormap.c @@ -1,2759 +1,2763 @@ -/*********************************************************** - -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 <dix-config.h> -#endif - -#include <X11/X.h> -#include <X11/Xproto.h> -#include <stdio.h> -#include <string.h> -#include <strings.h> -#include "misc.h" -#include "dix.h" -#include "colormapst.h" -#include "os.h" -#include "scrnintstr.h" -#include "resource.h" -#include "windowstr.h" -#include "privates.h" -#include "xace.h" - -extern XID clientErrorValue; - -static Pixel FindBestPixel( - EntryPtr /*pentFirst*/, - int /*size*/, - xrgb * /*prgb*/, - int /*channel*/ -); - -static int AllComp( - EntryPtr /*pent*/, - xrgb * /*prgb*/ -); - -static int RedComp( - EntryPtr /*pent*/, - xrgb * /*prgb*/ -); - -static int GreenComp( - EntryPtr /*pent*/, - xrgb * /*prgb*/ -); - -static int BlueComp( - EntryPtr /*pent*/, - xrgb * /*prgb*/ -); - -static void FreePixels( - ColormapPtr /*pmap*/, - int /*client*/ -); - -static void CopyFree( - int /*channel*/, - int /*client*/, - ColormapPtr /*pmapSrc*/, - ColormapPtr /*pmapDst*/ -); - -static void FreeCell( - ColormapPtr /*pmap*/, - Pixel /*i*/, - int /*channel*/ -); - -static void UpdateColors( - ColormapPtr /*pmap*/ -); - -static int AllocDirect( - int /*client*/, - ColormapPtr /*pmap*/, - int /*c*/, - int /*r*/, - int /*g*/, - int /*b*/, - Bool /*contig*/, - Pixel * /*pixels*/, - Pixel * /*prmask*/, - Pixel * /*pgmask*/, - Pixel * /*pbmask*/ -); - -static int AllocPseudo( - int /*client*/, - ColormapPtr /*pmap*/, - int /*c*/, - int /*r*/, - Bool /*contig*/, - Pixel * /*pixels*/, - Pixel * /*pmask*/, - Pixel ** /*pppixFirst*/ -); - -static Bool AllocCP( - ColormapPtr /*pmap*/, - EntryPtr /*pentFirst*/, - int /*count*/, - int /*planes*/, - Bool /*contig*/, - Pixel * /*pixels*/, - Pixel * /*pMask*/ -); - -static Bool AllocShared( - ColormapPtr /*pmap*/, - Pixel * /*ppix*/, - int /*c*/, - int /*r*/, - int /*g*/, - int /*b*/, - Pixel /*rmask*/, - Pixel /*gmask*/, - Pixel /*bmask*/, - Pixel * /*ppixFirst*/ -); - -static int FreeCo( - ColormapPtr /*pmap*/, - int /*client*/, - int /*color*/, - int /*npixIn*/, - Pixel * /*ppixIn*/, - Pixel /*mask*/ -); - -static int TellNoMap( - WindowPtr /*pwin*/, - Colormap * /*pmid*/ -); - -static void FindColorInRootCmap ( - ColormapPtr /* pmap */, - EntryPtr /* pentFirst */, - int /* size */, - xrgb* /* prgb */, - Pixel* /* pPixel */, - int /* channel */, - ColorCompareProcPtr /* comp */ -); - -#define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1) -#define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 1) -#define NUMBLUE(vis) ((vis->blueMask >> vis->offsetBlue) + 1) -#if COMPOSITE -#define ALPHAMASK(vis) ((vis)->nplanes < 32 ? 0 : \ - (CARD32) ~((vis)->redMask|(vis)->greenMask|(vis)->blueMask)) -#else -#define ALPHAMASK(vis) 0 -#endif - -#define RGBMASK(vis) (vis->redMask | vis->greenMask | vis->blueMask | ALPHAMASK(vis)) - -/* GetNextBitsOrBreak(bits, mask, base) -- - * (Suggestion: First read the macro, then read this explanation. - * - * Either generate the next value to OR in to a pixel or break out of this - * while loop - * - * This macro is used when we're trying to generate all 2^n combinations of - * bits in mask. What we're doing here is counting in binary, except that - * the bits we use to count may not be contiguous. This macro will be - * called 2^n times, returning a different value in bits each time. Then - * it will cause us to break out of a surrounding loop. (It will always be - * called from within a while loop.) - * On call: mask is the value we want to find all the combinations for - * base has 1 bit set where the least significant bit of mask is set - * - * For example,if mask is 01010, base should be 0010 and we count like this: - * 00010 (see this isn't so hard), - * then we add base to bits and get 0100. (bits & ~mask) is (0100 & 0100) so - * we add that to bits getting (0100 + 0100) = - * 01000 for our next value. - * then we add 0010 to get - * 01010 and we're done (easy as 1, 2, 3) - */ -#define GetNextBitsOrBreak(bits, mask, base) \ - if((bits) == (mask)) \ - break; \ - (bits) += (base); \ - while((bits) & ~(mask)) \ - (bits) += ((bits) & ~(mask)); -/* ID of server as client */ -#define SERVER_ID 0 - -typedef struct _colorResource -{ - Colormap mid; - int client; -} colorResource; - -/* Invariants: - * refcnt == 0 means entry is empty - * refcnt > 0 means entry is useable by many clients, so it can't be changed - * refcnt == AllocPrivate means entry owned by one client only - * fShared should only be set if refcnt == AllocPrivate, and only in red map - */ - - -/** - * Create and initialize the color map - * - * \param mid resource to use for this colormap - * \param alloc 1 iff all entries are allocated writable - */ -int -CreateColormap (Colormap mid, ScreenPtr pScreen, VisualPtr pVisual, - ColormapPtr *ppcmap, int alloc, int client) -{ - int class, size; - unsigned long sizebytes; - ColormapPtr pmap; - EntryPtr pent; - int i; - Pixel *ppix, **pptr; - - class = pVisual->class; - if(!(class & DynamicClass) && (alloc != AllocNone) && (client != SERVER_ID)) - return (BadMatch); - - size = pVisual->ColormapEntries; - sizebytes = (size * sizeof(Entry)) + - (MAXCLIENTS * sizeof(Pixel *)) + - (MAXCLIENTS * sizeof(int)); - if ((class | DynamicClass) == DirectColor) - sizebytes *= 3; - sizebytes += sizeof(ColormapRec); - pmap = xalloc(sizebytes); - if (!pmap) - return (BadAlloc); -#if defined(_XSERVER64) - pmap->pad0 = 0; - pmap->pad1 = 0; -#if (X_BYTE_ORDER == X_LITTLE_ENDIAN) - pmap->pad2 = 0; -#endif -#endif - pmap->red = (EntryPtr)((char *)pmap + sizeof(ColormapRec)); - sizebytes = size * sizeof(Entry); - pmap->clientPixelsRed = (Pixel **)((char *)pmap->red + sizebytes); - pmap->numPixelsRed = (int *)((char *)pmap->clientPixelsRed + - (MAXCLIENTS * sizeof(Pixel *))); - pmap->mid = mid; - pmap->flags = 0; /* start out with all flags clear */ - if(mid == pScreen->defColormap) - pmap->flags |= IsDefault; - pmap->pScreen = pScreen; - pmap->pVisual = pVisual; - pmap->class = class; - if ((class | DynamicClass) == DirectColor) - size = NUMRED(pVisual); - pmap->freeRed = size; - bzero ((char *) pmap->red, (int)sizebytes); - bzero((char *) pmap->numPixelsRed, MAXCLIENTS * sizeof(int)); - for (pptr = &pmap->clientPixelsRed[MAXCLIENTS]; --pptr >= pmap->clientPixelsRed; ) - *pptr = (Pixel *)NULL; - if (alloc == AllocAll) - { - if (class & DynamicClass) - pmap->flags |= AllAllocated; - for (pent = &pmap->red[size - 1]; pent >= pmap->red; pent--) - pent->refcnt = AllocPrivate; - pmap->freeRed = 0; - ppix = xalloc(size * sizeof(Pixel)); - if (!ppix) - { - xfree(pmap); - return (BadAlloc); - } - pmap->clientPixelsRed[client] = ppix; - for(i = 0; i < size; i++) - ppix[i] = i; - pmap->numPixelsRed[client] = size; - } - - if ((class | DynamicClass) == DirectColor) - { - pmap->freeGreen = NUMGREEN(pVisual); - pmap->green = (EntryPtr)((char *)pmap->numPixelsRed + - (MAXCLIENTS * sizeof(int))); - pmap->clientPixelsGreen = (Pixel **)((char *)pmap->green + sizebytes); - pmap->numPixelsGreen = (int *)((char *)pmap->clientPixelsGreen + - (MAXCLIENTS * sizeof(Pixel *))); - pmap->freeBlue = NUMBLUE(pVisual); - pmap->blue = (EntryPtr)((char *)pmap->numPixelsGreen + - (MAXCLIENTS * sizeof(int))); - pmap->clientPixelsBlue = (Pixel **)((char *)pmap->blue + sizebytes); - pmap->numPixelsBlue = (int *)((char *)pmap->clientPixelsBlue + - (MAXCLIENTS * sizeof(Pixel *))); - - bzero ((char *) pmap->green, (int)sizebytes); - bzero ((char *) pmap->blue, (int)sizebytes); - - memmove((char *) pmap->clientPixelsGreen, - (char *) pmap->clientPixelsRed, - MAXCLIENTS * sizeof(Pixel *)); - memmove((char *) pmap->clientPixelsBlue, - (char *) pmap->clientPixelsRed, - MAXCLIENTS * sizeof(Pixel *)); - bzero((char *) pmap->numPixelsGreen, MAXCLIENTS * sizeof(int)); - bzero((char *) pmap->numPixelsBlue, MAXCLIENTS * sizeof(int)); - - /* If every cell is allocated, mark its refcnt */ - if (alloc == AllocAll) - { - size = pmap->freeGreen; - for(pent = &pmap->green[size-1]; pent >= pmap->green; pent--) - pent->refcnt = AllocPrivate; - pmap->freeGreen = 0; - ppix = xalloc(size * sizeof(Pixel)); - if (!ppix) - { - xfree(pmap->clientPixelsRed[client]); - xfree(pmap); - return(BadAlloc); - } - pmap->clientPixelsGreen[client] = ppix; - for(i = 0; i < size; i++) - ppix[i] = i; - pmap->numPixelsGreen[client] = size; - - size = pmap->freeBlue; - for(pent = &pmap->blue[size-1]; pent >= pmap->blue; pent--) - pent->refcnt = AllocPrivate; - pmap->freeBlue = 0; - ppix = xalloc(size * sizeof(Pixel)); - if (!ppix) - { - xfree(pmap->clientPixelsGreen[client]); - xfree(pmap->clientPixelsRed[client]); - xfree(pmap); - return(BadAlloc); - } - pmap->clientPixelsBlue[client] = ppix; - for(i = 0; i < size; i++) - ppix[i] = i; - pmap->numPixelsBlue[client] = size; - } - } - pmap->devPrivates = NULL; - pmap->flags |= BeingCreated; - - if (!AddResource(mid, RT_COLORMAP, (pointer)pmap)) - return (BadAlloc); - - /* - * Security creation/labeling check - */ - i = XaceHook(XACE_RESOURCE_ACCESS, clients[client], mid, RT_COLORMAP, - pmap, RT_NONE, NULL, DixCreateAccess); - if (i != Success) { - FreeResource(mid, RT_NONE); - return i; - } - - /* If the device wants a chance to initialize the colormap in any way, - * this is it. In specific, if this is a Static colormap, this is the - * time to fill in the colormap's values */ - if (!(*pScreen->CreateColormap)(pmap)) - { - FreeResource (mid, RT_NONE); - return BadAlloc; - } - pmap->flags &= ~BeingCreated; - *ppcmap = pmap; - return (Success); -} - -/** - * - * \param value must conform to DeleteType - */ -int -FreeColormap (pointer value, XID mid) -{ - int i; - EntryPtr pent; - ColormapPtr pmap = (ColormapPtr)value; - - if(CLIENT_ID(mid) != SERVER_ID) - { - (*pmap->pScreen->UninstallColormap) (pmap); - WalkTree(pmap->pScreen, (VisitWindowProcPtr)TellNoMap, (pointer) &mid); - } - - /* This is the device's chance to undo anything it needs to, especially - * to free any storage it allocated */ - (*pmap->pScreen->DestroyColormap)(pmap); - - if(pmap->clientPixelsRed) - { - for(i = 0; i < MAXCLIENTS; i++) - xfree(pmap->clientPixelsRed[i]); - } - - if ((pmap->class == PseudoColor) || (pmap->class == GrayScale)) - { - for(pent = &pmap->red[pmap->pVisual->ColormapEntries - 1]; - pent >= pmap->red; - pent--) - { - if(pent->fShared) - { - if (--pent->co.shco.red->refcnt == 0) - xfree(pent->co.shco.red); - if (--pent->co.shco.green->refcnt == 0) - xfree(pent->co.shco.green); - if (--pent->co.shco.blue->refcnt == 0) - xfree(pent->co.shco.blue); - } - } - } - if((pmap->class | DynamicClass) == DirectColor) - { - for(i = 0; i < MAXCLIENTS; i++) - { - xfree(pmap->clientPixelsGreen[i]); - xfree(pmap->clientPixelsBlue[i]); - } - } - - dixFreePrivates(pmap->devPrivates); - xfree(pmap); - return(Success); -} - -/* Tell window that pmid has disappeared */ -static int -TellNoMap (WindowPtr pwin, Colormap *pmid) -{ - xEvent xE; - - if (wColormap(pwin) == *pmid) - { - /* This should be call to DeliverEvent */ - xE.u.u.type = ColormapNotify; - xE.u.colormap.window = pwin->drawable.id; - xE.u.colormap.colormap = None; - xE.u.colormap.new = TRUE; - xE.u.colormap.state = ColormapUninstalled; -#ifdef PANORAMIX - if(noPanoramiXExtension || !pwin->drawable.pScreen->myNum) -#endif - DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL); - if (pwin->optional) { - pwin->optional->colormap = None; - CheckWindowOptionalNeed (pwin); - } - } - - return (WT_WALKCHILDREN); -} - -/* Tell window that pmid got uninstalled */ -int -TellLostMap (WindowPtr pwin, pointer value) -{ - Colormap *pmid = (Colormap *)value; - xEvent xE; - -#ifdef PANORAMIX - if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum) - return WT_STOPWALKING; -#endif - if (wColormap(pwin) == *pmid) - { - /* This should be call to DeliverEvent */ - xE.u.u.type = ColormapNotify; - xE.u.colormap.window = pwin->drawable.id; - xE.u.colormap.colormap = *pmid; - xE.u.colormap.new = FALSE; - xE.u.colormap.state = ColormapUninstalled; - DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL); - } - - return (WT_WALKCHILDREN); -} - -/* Tell window that pmid got installed */ -int -TellGainedMap (WindowPtr pwin, pointer value) -{ - Colormap *pmid = (Colormap *)value; - xEvent xE; - -#ifdef PANORAMIX - if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum) - return WT_STOPWALKING; -#endif - if (wColormap (pwin) == *pmid) - { - /* This should be call to DeliverEvent */ - xE.u.u.type = ColormapNotify; - xE.u.colormap.window = pwin->drawable.id; - xE.u.colormap.colormap = *pmid; - xE.u.colormap.new = FALSE; - xE.u.colormap.state = ColormapInstalled; - DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL); - } - - return (WT_WALKCHILDREN); -} - - -int -CopyColormapAndFree (Colormap mid, ColormapPtr pSrc, int client) -{ - ColormapPtr pmap = (ColormapPtr) NULL; - int result, alloc, size; - Colormap midSrc; - ScreenPtr pScreen; - VisualPtr pVisual; - - pScreen = pSrc->pScreen; - pVisual = pSrc->pVisual; - midSrc = pSrc->mid; - alloc = ((pSrc->flags & AllAllocated) && CLIENT_ID(midSrc) == client) ? - AllocAll : AllocNone; - size = pVisual->ColormapEntries; - - /* If the create returns non-0, it failed */ - result = CreateColormap (mid, pScreen, pVisual, &pmap, alloc, client); - if(result != Success) - return(result); - if(alloc == AllocAll) - { - memmove((char *)pmap->red, (char *)pSrc->red, size * sizeof(Entry)); - if((pmap->class | DynamicClass) == DirectColor) - { - memmove((char *)pmap->green, (char *)pSrc->green, size * sizeof(Entry)); - memmove((char *)pmap->blue, (char *)pSrc->blue, size * sizeof(Entry)); - } - pSrc->flags &= ~AllAllocated; - FreePixels(pSrc, client); - UpdateColors(pmap); - return(Success); - } - - CopyFree(REDMAP, client, pSrc, pmap); - if ((pmap->class | DynamicClass) == DirectColor) - { - CopyFree(GREENMAP, client, pSrc, pmap); - CopyFree(BLUEMAP, client, pSrc, pmap); - } - if (pmap->class & DynamicClass) - UpdateColors(pmap); - /* XXX should worry about removing any RT_CMAPENTRY resource */ - return(Success); -} - -/* Helper routine for freeing large numbers of cells from a map */ -static void -CopyFree (int channel, int client, ColormapPtr pmapSrc, ColormapPtr pmapDst) -{ - int z, npix; - EntryPtr pentSrcFirst, pentDstFirst; - EntryPtr pentSrc, pentDst; - Pixel *ppix; - int nalloc; - - switch(channel) - { - default: /* so compiler can see that everything gets initialized */ - case REDMAP: - ppix = (pmapSrc->clientPixelsRed)[client]; - npix = (pmapSrc->numPixelsRed)[client]; - pentSrcFirst = pmapSrc->red; - pentDstFirst = pmapDst->red; - break; - case GREENMAP: - ppix = (pmapSrc->clientPixelsGreen)[client]; - npix = (pmapSrc->numPixelsGreen)[client]; - pentSrcFirst = pmapSrc->green; - pentDstFirst = pmapDst->green; - break; - case BLUEMAP: - ppix = (pmapSrc->clientPixelsBlue)[client]; - npix = (pmapSrc->numPixelsBlue)[client]; - pentSrcFirst = pmapSrc->blue; - pentDstFirst = pmapDst->blue; - break; - } - nalloc = 0; - if (pmapSrc->class & DynamicClass) - { - for(z = npix; --z >= 0; ppix++) - { - /* Copy entries */ - pentSrc = pentSrcFirst + *ppix; - pentDst = pentDstFirst + *ppix; - if (pentDst->refcnt > 0) - { - pentDst->refcnt++; - } - else - { - *pentDst = *pentSrc; - nalloc++; - if (pentSrc->refcnt > 0) - pentDst->refcnt = 1; - else - pentSrc->fShared = FALSE; - } - FreeCell(pmapSrc, *ppix, channel); - } - } - - /* Note that FreeCell has already fixed pmapSrc->free{Color} */ - switch(channel) - { - case REDMAP: - pmapDst->freeRed -= nalloc; - (pmapDst->clientPixelsRed)[client] = - (pmapSrc->clientPixelsRed)[client]; - (pmapSrc->clientPixelsRed)[client] = (Pixel *) NULL; - (pmapDst->numPixelsRed)[client] = (pmapSrc->numPixelsRed)[client]; - (pmapSrc->numPixelsRed)[client] = 0; - break; - case GREENMAP: - pmapDst->freeGreen -= nalloc; - (pmapDst->clientPixelsGreen)[client] = - (pmapSrc->clientPixelsGreen)[client]; - (pmapSrc->clientPixelsGreen)[client] = (Pixel *) NULL; - (pmapDst->numPixelsGreen)[client] = (pmapSrc->numPixelsGreen)[client]; - (pmapSrc->numPixelsGreen)[client] = 0; - break; - case BLUEMAP: - pmapDst->freeBlue -= nalloc; - pmapDst->clientPixelsBlue[client] = pmapSrc->clientPixelsBlue[client]; - pmapSrc->clientPixelsBlue[client] = (Pixel *) NULL; - pmapDst->numPixelsBlue[client] = pmapSrc->numPixelsBlue[client]; - pmapSrc->numPixelsBlue[client] = 0; - break; - } -} - -/* Free the ith entry in a color map. Must handle freeing of - * colors allocated through AllocColorPlanes */ -static void -FreeCell (ColormapPtr pmap, Pixel i, int channel) -{ - EntryPtr pent; - int *pCount; - - - switch (channel) - { - default: /* so compiler can see that everything gets initialized */ - case PSEUDOMAP: - case REDMAP: - pent = (EntryPtr) &pmap->red[i]; - pCount = &pmap->freeRed; - break; - case GREENMAP: - pent = (EntryPtr) &pmap->green[i]; - pCount = &pmap->freeGreen; - break; - case BLUEMAP: - pent = (EntryPtr) &pmap->blue[i]; - pCount = &pmap->freeBlue; - break; - } - /* If it's not privately allocated and it's not time to free it, just - * decrement the count */ - if (pent->refcnt > 1) - pent->refcnt--; - else - { - /* If the color type is shared, find the sharedcolor. If decremented - * refcnt is 0, free the shared cell. */ - if (pent->fShared) - { - if(--pent->co.shco.red->refcnt == 0) - xfree(pent->co.shco.red); - if(--pent->co.shco.green->refcnt == 0) - xfree(pent->co.shco.green); - if(--pent->co.shco.blue->refcnt == 0) - xfree(pent->co.shco.blue); - pent->fShared = FALSE; - } - pent->refcnt = 0; - *pCount += 1; - } -} - -static void -UpdateColors (ColormapPtr pmap) -{ - xColorItem *defs; - xColorItem *pdef; - EntryPtr pent; - VisualPtr pVisual; - int i, n, size; - - pVisual = pmap->pVisual; - size = pVisual->ColormapEntries; - defs = xalloc(size * sizeof(xColorItem)); - if (!defs) - return; - n = 0; - pdef = defs; - if (pmap->class == DirectColor) - { - for (i = 0; i < size; i++) - { - if (!pmap->red[i].refcnt && - !pmap->green[i].refcnt && - !pmap->blue[i].refcnt) - continue; - pdef->pixel = ((Pixel)i << pVisual->offsetRed) | - ((Pixel)i << pVisual->offsetGreen) | - ((Pixel)i << pVisual->offsetBlue); - pdef->red = pmap->red[i].co.local.red; - pdef->green = pmap->green[i].co.local.green; - pdef->blue = pmap->blue[i].co.local.blue; - pdef->flags = DoRed|DoGreen|DoBlue; - pdef++; - n++; - } - } - else - { - for (i = 0, pent = pmap->red; i < size; i++, pent++) - { - if (!pent->refcnt) - continue; - pdef->pixel = i; - if(pent->fShared) - { - pdef->red = pent->co.shco.red->color; - pdef->green = pent->co.shco.green->color; - pdef->blue = pent->co.shco.blue->color; - } - else - { - pdef->red = pent->co.local.red; - pdef->green = pent->co.local.green; - pdef->blue = pent->co.local.blue; - } - pdef->flags = DoRed|DoGreen|DoBlue; - pdef++; - n++; - } - } - if (n) - (*pmap->pScreen->StoreColors)(pmap, n, defs); - xfree(defs); -} - -/* Get a read-only color from a ColorMap (probably slow for large maps) - * Returns by changing the value in pred, pgreen, pblue and pPix - */ -int -AllocColor (ColormapPtr pmap, - unsigned short *pred, unsigned short *pgreen, unsigned short *pblue, - Pixel *pPix, int client) -{ - Pixel pixR, pixG, pixB; - int entries; - xrgb rgb; - int class; - VisualPtr pVisual; - int npix; - Pixel *ppix; - - pVisual = pmap->pVisual; - (*pmap->pScreen->ResolveColor) (pred, pgreen, pblue, pVisual); - rgb.red = *pred; - rgb.green = *pgreen; - rgb.blue = *pblue; - class = pmap->class; - entries = pVisual->ColormapEntries; - - /* If the colormap is being created, then we want to be able to change - * the colormap, even if it's a static type. Otherwise, we'd never be - * able to initialize static colormaps - */ - if(pmap->flags & BeingCreated) - class |= DynamicClass; - - /* If this is one of the static storage classes, and we're not initializing - * it, the best we can do is to find the closest color entry to the - * requested one and return that. - */ - switch (class) { - case StaticColor: - case StaticGray: - /* Look up all three components in the same pmap */ - *pPix = pixR = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP); - *pred = pmap->red[pixR].co.local.red; - *pgreen = pmap->red[pixR].co.local.green; - *pblue = pmap->red[pixR].co.local.blue; - npix = pmap->numPixelsRed[client]; - ppix = (Pixel *) xrealloc(pmap->clientPixelsRed[client], - (npix + 1) * sizeof(Pixel)); - if (!ppix) - return (BadAlloc); - ppix[npix] = pixR; - pmap->clientPixelsRed[client] = ppix; - pmap->numPixelsRed[client]++; - break; - - case TrueColor: - /* Look up each component in its own map, then OR them together */ - pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP); - pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP); - pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP); - *pPix = (pixR << pVisual->offsetRed) | - (pixG << pVisual->offsetGreen) | - (pixB << pVisual->offsetBlue) | - ALPHAMASK(pVisual); - - *pred = pmap->red[pixR].co.local.red; - *pgreen = pmap->green[pixG].co.local.green; - *pblue = pmap->blue[pixB].co.local.blue; - npix = pmap->numPixelsRed[client]; - ppix = (Pixel *) xrealloc(pmap->clientPixelsRed[client], - (npix + 1) * sizeof(Pixel)); - if (!ppix) - return (BadAlloc); - ppix[npix] = pixR; - pmap->clientPixelsRed[client] = ppix; - npix = pmap->numPixelsGreen[client]; - ppix = (Pixel *) xrealloc(pmap->clientPixelsGreen[client], - (npix + 1) * sizeof(Pixel)); - if (!ppix) - return (BadAlloc); - ppix[npix] = pixG; - pmap->clientPixelsGreen[client] = ppix; - npix = pmap->numPixelsBlue[client]; - ppix = (Pixel *) xrealloc(pmap->clientPixelsBlue[client], - (npix + 1) * sizeof(Pixel)); - if (!ppix) - return (BadAlloc); - ppix[npix] = pixB; - pmap->clientPixelsBlue[client] = ppix; - pmap->numPixelsRed[client]++; - pmap->numPixelsGreen[client]++; - pmap->numPixelsBlue[client]++; - break; - - case GrayScale: - case PseudoColor: - if (pmap->mid != pmap->pScreen->defColormap && - pmap->pVisual->vid == pmap->pScreen->rootVisual) - { - ColormapPtr prootmap; - dixLookupResourceByType((pointer *)&prootmap, pmap->pScreen->defColormap, - RT_COLORMAP, clients[client], DixReadAccess); - - if (pmap->class == prootmap->class) - FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb, - pPix, PSEUDOMAP, AllComp); - } - if (FindColor(pmap, pmap->red, entries, &rgb, pPix, PSEUDOMAP, - client, AllComp) != Success) - return (BadAlloc); - break; - - case DirectColor: - if (pmap->mid != pmap->pScreen->defColormap && - pmap->pVisual->vid == pmap->pScreen->rootVisual) - { - ColormapPtr prootmap; - dixLookupResourceByType((pointer *)&prootmap, pmap->pScreen->defColormap, - RT_COLORMAP, clients[client], DixReadAccess); - - if (pmap->class == prootmap->class) - { - pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed; - FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb, - &pixR, REDMAP, RedComp); - pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen; - FindColorInRootCmap (prootmap, prootmap->green, entries, &rgb, - &pixG, GREENMAP, GreenComp); - pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue; - FindColorInRootCmap (prootmap, prootmap->blue, entries, &rgb, - &pixB, BLUEMAP, BlueComp); - *pPix = pixR | pixG | pixB; - } - } - - pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed; - if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP, - client, RedComp) != Success) - return (BadAlloc); - pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen; - if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG, - GREENMAP, client, GreenComp) != Success) - { - (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0); - return (BadAlloc); - } - pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue; - if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP, - client, BlueComp) != Success) - { - (void)FreeCo(pmap, client, GREENMAP, 1, &pixG, (Pixel)0); - (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0); - return (BadAlloc); - } - *pPix = pixR | pixG | pixB | ALPHAMASK(pVisual); - - break; - } - - /* if this is the client's first pixel in this colormap, tell the - * resource manager that the client has pixels in this colormap which - * should be freed when the client dies */ - if ((pmap->numPixelsRed[client] == 1) && - (CLIENT_ID(pmap->mid) != client) && - !(pmap->flags & BeingCreated)) - { - colorResource *pcr; - - pcr = xalloc(sizeof(colorResource)); - if (!pcr) - { - (void)FreeColors(pmap, client, 1, pPix, (Pixel)0); - return (BadAlloc); - } - pcr->mid = pmap->mid; - pcr->client = client; - if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr)) - return (BadAlloc); - } - return (Success); -} - -/* - * FakeAllocColor -- fake an AllocColor request by - * returning a free pixel if availible, otherwise returning - * the closest matching pixel. This is used by the mi - * software sprite code to recolor cursors. A nice side-effect - * is that this routine will never return failure. - */ - -void -FakeAllocColor (ColormapPtr pmap, xColorItem *item) -{ - Pixel pixR, pixG, pixB; - Pixel temp; - int entries; - xrgb rgb; - int class; - VisualPtr pVisual; - - pVisual = pmap->pVisual; - rgb.red = item->red; - rgb.green = item->green; - rgb.blue = item->blue; - (*pmap->pScreen->ResolveColor) (&rgb.red, &rgb.green, &rgb.blue, pVisual); - class = pmap->class; - entries = pVisual->ColormapEntries; - - switch (class) { - case GrayScale: - case PseudoColor: - temp = 0; - item->pixel = 0; - if (FindColor(pmap, pmap->red, entries, &rgb, &temp, PSEUDOMAP, - -1, AllComp) == Success) { - item->pixel = temp; - break; - } - /* fall through ... */ - case StaticColor: - case StaticGray: - item->pixel = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP); - break; - - case DirectColor: - /* Look up each component in its own map, then OR them together */ - pixR = (item->pixel & pVisual->redMask) >> pVisual->offsetRed; - pixG = (item->pixel & pVisual->greenMask) >> pVisual->offsetGreen; - pixB = (item->pixel & pVisual->blueMask) >> pVisual->offsetBlue; - if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP, - -1, RedComp) != Success) - pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP) - << pVisual->offsetRed; - if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG, - GREENMAP, -1, GreenComp) != Success) - pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, - GREENMAP) << pVisual->offsetGreen; - if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP, - -1, BlueComp) != Success) - pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP) - << pVisual->offsetBlue; - item->pixel = pixR | pixG | pixB; - break; - - case TrueColor: - /* Look up each component in its own map, then OR them together */ - pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP); - pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP); - pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP); - item->pixel = (pixR << pVisual->offsetRed) | - (pixG << pVisual->offsetGreen) | - (pixB << pVisual->offsetBlue); - break; - } -} - -/* free a pixel value obtained from FakeAllocColor */ -void -FakeFreeColor(ColormapPtr pmap, Pixel pixel) -{ - VisualPtr pVisual; - Pixel pixR, pixG, pixB; - - switch (pmap->class) { - case GrayScale: - case PseudoColor: - if (pmap->red[pixel].refcnt == AllocTemporary) - pmap->red[pixel].refcnt = 0; - break; - case DirectColor: - pVisual = pmap->pVisual; - pixR = (pixel & pVisual->redMask) >> pVisual->offsetRed; - pixG = (pixel & pVisual->greenMask) >> pVisual->offsetGreen; - pixB = (pixel & pVisual->blueMask) >> pVisual->offsetBlue; - if (pmap->red[pixR].refcnt == AllocTemporary) - pmap->red[pixR].refcnt = 0; - if (pmap->green[pixG].refcnt == AllocTemporary) - pmap->green[pixG].refcnt = 0; - if (pmap->blue[pixB].refcnt == AllocTemporary) - pmap->blue[pixB].refcnt = 0; - break; - } -} - -typedef unsigned short BigNumUpper; -typedef unsigned long BigNumLower; - -#define BIGNUMLOWERBITS 24 -#define BIGNUMUPPERBITS 16 -#define BIGNUMLOWER (1 << BIGNUMLOWERBITS) -#define BIGNUMUPPER (1 << BIGNUMUPPERBITS) -#define UPPERPART(i) ((i) >> BIGNUMLOWERBITS) -#define LOWERPART(i) ((i) & (BIGNUMLOWER - 1)) - -typedef struct _bignum { - BigNumUpper upper; - BigNumLower lower; -} BigNumRec, *BigNumPtr; - -#define BigNumGreater(x,y) (((x)->upper > (y)->upper) ||\ - ((x)->upper == (y)->upper && (x)->lower > (y)->lower)) - -#define UnsignedToBigNum(u,r) (((r)->upper = UPPERPART(u)), \ - ((r)->lower = LOWERPART(u))) - -#define MaxBigNum(r) (((r)->upper = BIGNUMUPPER-1), \ - ((r)->lower = BIGNUMLOWER-1)) - -static void -BigNumAdd (BigNumPtr x, BigNumPtr y, BigNumPtr r) -{ - BigNumLower lower, carry = 0; - - lower = x->lower + y->lower; - if (lower >= BIGNUMLOWER) { - lower -= BIGNUMLOWER; - carry = 1; - } - r->lower = lower; - r->upper = x->upper + y->upper + carry; -} - -static Pixel -FindBestPixel(EntryPtr pentFirst, int size, xrgb *prgb, int channel) -{ - EntryPtr pent; - Pixel pixel, final; - long dr, dg, db; - unsigned long sq; - BigNumRec minval, sum, temp; - - final = 0; - MaxBigNum(&minval); - /* look for the minimal difference */ - for (pent = pentFirst, pixel = 0; pixel < size; pent++, pixel++) - { - dr = dg = db = 0; - switch(channel) - { - case PSEUDOMAP: - dg = (long) pent->co.local.green - prgb->green; - db = (long) pent->co.local.blue - prgb->blue; - case REDMAP: - dr = (long) pent->co.local.red - prgb->red; - break; - case GREENMAP: - dg = (long) pent->co.local.green - prgb->green; - break; - case BLUEMAP: - db = (long) pent->co.local.blue - prgb->blue; - break; - } - sq = dr * dr; - UnsignedToBigNum (sq, &sum); - sq = dg * dg; - UnsignedToBigNum (sq, &temp); - BigNumAdd (&sum, &temp, &sum); - sq = db * db; - UnsignedToBigNum (sq, &temp); - BigNumAdd (&sum, &temp, &sum); - if (BigNumGreater (&minval, &sum)) - { - final = pixel; - minval = sum; - } - } - return(final); -} - -static void -FindColorInRootCmap (ColormapPtr pmap, EntryPtr pentFirst, int size, - xrgb *prgb, Pixel *pPixel, int channel, - ColorCompareProcPtr comp) -{ - EntryPtr pent; - Pixel pixel; - int count; - - if ((pixel = *pPixel) >= size) - pixel = 0; - for (pent = pentFirst + pixel, count = size; --count >= 0; pent++, pixel++) - { - if (pent->refcnt > 0 && (*comp) (pent, prgb)) - { - switch (channel) - { - case REDMAP: - pixel <<= pmap->pVisual->offsetRed; - break; - case GREENMAP: - pixel <<= pmap->pVisual->offsetGreen; - break; - case BLUEMAP: - pixel <<= pmap->pVisual->offsetBlue; - break; - default: /* PSEUDOMAP */ - break; - } - *pPixel = pixel; - } - } -} - -/* Tries to find a color in pmap that exactly matches the one requested in prgb - * if it can't it allocates one. - * Starts looking at pentFirst + *pPixel, so if you want a specific pixel, - * load *pPixel with that value, otherwise set it to 0 - */ -int -FindColor (ColormapPtr pmap, EntryPtr pentFirst, int size, xrgb *prgb, - Pixel *pPixel, int channel, int client, - ColorCompareProcPtr comp) -{ - EntryPtr pent; - Bool foundFree; - Pixel pixel, Free = 0; - int npix, count, *nump = NULL; - Pixel **pixp = NULL, *ppix; - xColorItem def; - - foundFree = FALSE; - - if((pixel = *pPixel) >= size) - pixel = 0; - /* see if there is a match, and also look for a free entry */ - for (pent = pentFirst + pixel, count = size; --count >= 0; ) - { - if (pent->refcnt > 0) - { - if ((*comp) (pent, prgb)) - { - if (client >= 0) - pent->refcnt++; - *pPixel = pixel; - switch(channel) - { - case REDMAP: - *pPixel <<= pmap->pVisual->offsetRed; - case PSEUDOMAP: - break; - case GREENMAP: - *pPixel <<= pmap->pVisual->offsetGreen; - break; - case BLUEMAP: - *pPixel <<= pmap->pVisual->offsetBlue; - break; - } - goto gotit; - } - } - else if (!foundFree && pent->refcnt == 0) - { - Free = pixel; - foundFree = TRUE; - /* If we're initializing the colormap, then we are looking for - * the first free cell we can find, not to minimize the number - * of entries we use. So don't look any further. */ - if(pmap->flags & BeingCreated) - break; - } - pixel++; - if(pixel >= size) - { - pent = pentFirst; - pixel = 0; - } - else - pent++; - } - - /* If we got here, we didn't find a match. If we also didn't find - * a free entry, we're out of luck. Otherwise, we'll usurp a free - * entry and fill it in */ - if (!foundFree) - return (BadAlloc); - pent = pentFirst + Free; - pent->fShared = FALSE; - pent->refcnt = (client >= 0) ? 1 : AllocTemporary; - - switch (channel) - { - case PSEUDOMAP: - pent->co.local.red = prgb->red; - pent->co.local.green = prgb->green; - pent->co.local.blue = prgb->blue; - def.red = prgb->red; - def.green = prgb->green; - def.blue = prgb->blue; - def.flags = (DoRed|DoGreen|DoBlue); - if (client >= 0) - pmap->freeRed--; - def.pixel = Free; - break; - - case REDMAP: - pent->co.local.red = prgb->red; - def.red = prgb->red; - def.green = pmap->green[0].co.local.green; - def.blue = pmap->blue[0].co.local.blue; - def.flags = DoRed; - if (client >= 0) - pmap->freeRed--; - def.pixel = Free << pmap->pVisual->offsetRed; - break; - - case GREENMAP: - pent->co.local.green = prgb->green; - def.red = pmap->red[0].co.local.red; - def.green = prgb->green; - def.blue = pmap->blue[0].co.local.blue; - def.flags = DoGreen; - if (client >= 0) - pmap->freeGreen--; - def.pixel = Free << pmap->pVisual->offsetGreen; - break; - - case BLUEMAP: - pent->co.local.blue = prgb->blue; - def.red = pmap->red[0].co.local.red; - def.green = pmap->green[0].co.local.green; - def.blue = prgb->blue; - def.flags = DoBlue; - if (client >= 0) - pmap->freeBlue--; - def.pixel = Free << pmap->pVisual->offsetBlue; - break; - } - (*pmap->pScreen->StoreColors) (pmap, 1, &def); - pixel = Free; - *pPixel = def.pixel; - -gotit: - if (pmap->flags & BeingCreated || client == -1) - return(Success); - /* Now remember the pixel, for freeing later */ - switch (channel) - { - case PSEUDOMAP: - case REDMAP: - nump = pmap->numPixelsRed; - pixp = pmap->clientPixelsRed; - break; - - case GREENMAP: - nump = pmap->numPixelsGreen; - pixp = pmap->clientPixelsGreen; - break; - - case BLUEMAP: - nump = pmap->numPixelsBlue; - pixp = pmap->clientPixelsBlue; - break; - } - npix = nump[client]; - ppix = (Pixel *) xrealloc (pixp[client], (npix + 1) * sizeof(Pixel)); - if (!ppix) - { - pent->refcnt--; - if (!pent->fShared) - switch (channel) - { - case PSEUDOMAP: - case REDMAP: - pmap->freeRed++; - break; - case GREENMAP: - pmap->freeGreen++; - break; - case BLUEMAP: - pmap->freeBlue++; - break; - } - return(BadAlloc); - } - ppix[npix] = pixel; - pixp[client] = ppix; - nump[client]++; - - return(Success); -} - -/* Comparison functions -- passed to FindColor to determine if an - * entry is already the color we're looking for or not */ -static int -AllComp (EntryPtr pent, xrgb *prgb) -{ - if((pent->co.local.red == prgb->red) && - (pent->co.local.green == prgb->green) && - (pent->co.local.blue == prgb->blue) ) - return (1); - return (0); -} - -static int -RedComp (EntryPtr pent, xrgb *prgb) -{ - if (pent->co.local.red == prgb->red) - return (1); - return (0); -} - -static int -GreenComp (EntryPtr pent, xrgb *prgb) -{ - if (pent->co.local.green == prgb->green) - return (1); - return (0); -} - -static int -BlueComp (EntryPtr pent, xrgb *prgb) -{ - if (pent->co.local.blue == prgb->blue) - return (1); - return (0); -} - - -/* Read the color value of a cell */ - -int -QueryColors (ColormapPtr pmap, int count, Pixel *ppixIn, xrgb *prgbList) -{ - Pixel *ppix, pixel; - xrgb *prgb; - VisualPtr pVisual; - EntryPtr pent; - Pixel i; - int errVal = Success; - - pVisual = pmap->pVisual; - if ((pmap->class | DynamicClass) == DirectColor) - { - int numred, numgreen, numblue; - Pixel rgbbad; - - numred = NUMRED(pVisual); - numgreen = NUMGREEN(pVisual); - numblue = NUMBLUE(pVisual); - rgbbad = ~RGBMASK(pVisual); - for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++) - { - pixel = *ppix; - if (pixel & rgbbad) { - clientErrorValue = pixel; - errVal = BadValue; - continue; - } - i = (pixel & pVisual->redMask) >> pVisual->offsetRed; - if (i >= numred) - { - clientErrorValue = pixel; - errVal = BadValue; - continue; - } - prgb->red = pmap->red[i].co.local.red; - i = (pixel & pVisual->greenMask) >> pVisual->offsetGreen; - if (i >= numgreen) - { - clientErrorValue = pixel; - errVal = BadValue; - continue; - } - prgb->green = pmap->green[i].co.local.green; - i = (pixel & pVisual->blueMask) >> pVisual->offsetBlue; - if (i >= numblue) - { - clientErrorValue = pixel; - errVal = BadValue; - continue; - } - prgb->blue = pmap->blue[i].co.local.blue; - } - } - else - { - for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++) - { - pixel = *ppix; - if (pixel >= pVisual->ColormapEntries) - { - clientErrorValue = pixel; - errVal = BadValue; - } - else - { - pent = (EntryPtr)&pmap->red[pixel]; - if (pent->fShared) - { - prgb->red = pent->co.shco.red->color; - prgb->green = pent->co.shco.green->color; - prgb->blue = pent->co.shco.blue->color; - } - else - { - prgb->red = pent->co.local.red; - prgb->green = pent->co.local.green; - prgb->blue = pent->co.local.blue; - } - } - } - } - return (errVal); -} - -static void -FreePixels(ColormapPtr pmap, int client) -{ - Pixel *ppix, *ppixStart; - int n; - int class; - - class = pmap->class; - ppixStart = pmap->clientPixelsRed[client]; - if (class & DynamicClass) - { - n = pmap->numPixelsRed[client]; - for (ppix = ppixStart; --n >= 0; ) - { - FreeCell(pmap, *ppix, REDMAP); - ppix++; - } - } - - xfree(ppixStart); - pmap->clientPixelsRed[client] = (Pixel *) NULL; - pmap->numPixelsRed[client] = 0; - if ((class | DynamicClass) == DirectColor) - { - ppixStart = pmap->clientPixelsGreen[client]; - if (class & DynamicClass) - for (ppix = ppixStart, n = pmap->numPixelsGreen[client]; --n >= 0;) - FreeCell(pmap, *ppix++, GREENMAP); - xfree(ppixStart); - pmap->clientPixelsGreen[client] = (Pixel *) NULL; - pmap->numPixelsGreen[client] = 0; - - ppixStart = pmap->clientPixelsBlue[client]; - if (class & DynamicClass) - for (ppix = ppixStart, n = pmap->numPixelsBlue[client]; --n >= 0; ) - FreeCell(pmap, *ppix++, BLUEMAP); - xfree(ppixStart); - pmap->clientPixelsBlue[client] = (Pixel *) NULL; - pmap->numPixelsBlue[client] = 0; - } -} - -/** - * Frees all of a client's colors and cells. - * - * \param value must conform to DeleteType - * \unused fakeid - */ -int -FreeClientPixels (pointer value, XID fakeid) -{ - pointer pmap; - colorResource *pcr = value; - int rc; - - rc = dixLookupResourceByType(&pmap, pcr->mid, RT_COLORMAP, serverClient, - DixRemoveAccess); - if (rc == Success) - FreePixels((ColormapPtr)pmap, pcr->client); - xfree(pcr); - return Success; -} - -int -AllocColorCells (int client, ColormapPtr pmap, int colors, int planes, - Bool contig, Pixel *ppix, Pixel *masks) -{ - Pixel rmask, gmask, bmask, *ppixFirst, r, g, b; - int n, class; - int ok; - int oldcount; - colorResource *pcr = (colorResource *)NULL; - - class = pmap->class; - if (!(class & DynamicClass)) - return (BadAlloc); /* Shouldn't try on this type */ - oldcount = pmap->numPixelsRed[client]; - if (pmap->class == DirectColor) - oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client]; - if (!oldcount && (CLIENT_ID(pmap->mid) != client)) - { - pcr = xalloc(sizeof(colorResource)); - if (!pcr) - return (BadAlloc); - } - - if (pmap->class == DirectColor) - { - ok = AllocDirect (client, pmap, colors, planes, planes, planes, - contig, ppix, &rmask, &gmask, &bmask); - if(ok == Success) - { - for (r = g = b = 1, n = planes; --n >= 0; r += r, g += g, b += b) - { - while(!(rmask & r)) - r += r; - while(!(gmask & g)) - g += g; - while(!(bmask & b)) - b += b; - *masks++ = r | g | b; - } - } - } - else - { - ok = AllocPseudo (client, pmap, colors, planes, contig, ppix, &rmask, - &ppixFirst); - if(ok == Success) - { - for (r = 1, n = planes; --n >= 0; r += r) - { - while(!(rmask & r)) - r += r; - *masks++ = r; - } - } - } - - /* if this is the client's first pixels in this colormap, tell the - * resource manager that the client has pixels in this colormap which - * should be freed when the client dies */ - if ((ok == Success) && pcr) - { - pcr->mid = pmap->mid; - pcr->client = client; - if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr)) - ok = BadAlloc; - } else if (pcr) - xfree(pcr); - - return (ok); -} - - -int -AllocColorPlanes (int client, ColormapPtr pmap, int colors, - int r, int g, int b, Bool contig, Pixel *pixels, - Pixel *prmask, Pixel *pgmask, Pixel *pbmask) -{ - int ok; - Pixel mask, *ppixFirst; - Pixel shift; - int i; - int class; - int oldcount; - colorResource *pcr = (colorResource *)NULL; - - class = pmap->class; - if (!(class & DynamicClass)) - return (BadAlloc); /* Shouldn't try on this type */ - oldcount = pmap->numPixelsRed[client]; - if (class == DirectColor) - oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client]; - if (!oldcount && (CLIENT_ID(pmap->mid) != client)) - { - pcr = xalloc(sizeof(colorResource)); - if (!pcr) - return (BadAlloc); - } - - if (class == DirectColor) - { - ok = AllocDirect (client, pmap, colors, r, g, b, contig, pixels, - prmask, pgmask, pbmask); - } - else - { - /* Allocate the proper pixels */ - /* XXX This is sort of bad, because of contig is set, we force all - * r + g + b bits to be contiguous. Should only force contiguity - * per mask - */ - ok = AllocPseudo (client, pmap, colors, r + g + b, contig, pixels, - &mask, &ppixFirst); - - if(ok == Success) - { - /* now split that mask into three */ - *prmask = *pgmask = *pbmask = 0; - shift = 1; - for (i = r; --i >= 0; shift += shift) - { - while (!(mask & shift)) - shift += shift; - *prmask |= shift; - } - for (i = g; --i >= 0; shift += shift) - { - while (!(mask & shift)) - shift += shift; - *pgmask |= shift; - } - for (i = b; --i >= 0; shift += shift) - { - while (!(mask & shift)) - shift += shift; - *pbmask |= shift; - } - - /* set up the shared color cells */ - if (!AllocShared(pmap, pixels, colors, r, g, b, - *prmask, *pgmask, *pbmask, ppixFirst)) - { - (void)FreeColors(pmap, client, colors, pixels, mask); - ok = BadAlloc; - } - } - } - - /* if this is the client's first pixels in this colormap, tell the - * resource manager that the client has pixels in this colormap which - * should be freed when the client dies */ - if ((ok == Success) && pcr) - { - pcr->mid = pmap->mid; - pcr->client = client; - if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr)) - ok = BadAlloc; - } else if (pcr) - xfree(pcr); - - return (ok); -} - -static int -AllocDirect (int client, ColormapPtr pmap, int c, int r, int g, int b, Bool contig, - Pixel *pixels, Pixel *prmask, Pixel *pgmask, Pixel *pbmask) -{ - Pixel *ppixRed, *ppixGreen, *ppixBlue; - Pixel *ppix, *pDst, *p; - int npix, npixR, npixG, npixB; - Bool okR, okG, okB; - Pixel *rpix = 0, *gpix = 0, *bpix = 0; - - npixR = c << r; - npixG = c << g; - npixB = c << b; - if ((r >= 32) || (g >= 32) || (b >= 32) || - (npixR > pmap->freeRed) || (npixR < c) || - (npixG > pmap->freeGreen) || (npixG < c) || - (npixB > pmap->freeBlue) || (npixB < c)) - return BadAlloc; - - /* start out with empty pixels */ - for(p = pixels; p < pixels + c; p++) - *p = 0; - - ppixRed = xalloc(npixR * sizeof(Pixel)); - ppixGreen = xalloc(npixG * sizeof(Pixel)); - ppixBlue = xalloc(npixB * sizeof(Pixel)); - if (!ppixRed || !ppixGreen || !ppixBlue) - { - if (ppixBlue) xfree(ppixBlue); - if (ppixGreen) xfree(ppixGreen); - if (ppixRed) xfree(ppixRed); - return(BadAlloc); - } - - okR = AllocCP(pmap, pmap->red, c, r, contig, ppixRed, prmask); - okG = AllocCP(pmap, pmap->green, c, g, contig, ppixGreen, pgmask); - okB = AllocCP(pmap, pmap->blue, c, b, contig, ppixBlue, pbmask); - - if (okR && okG && okB) - { - rpix = (Pixel *) xrealloc(pmap->clientPixelsRed[client], - (pmap->numPixelsRed[client] + (c << r)) * - sizeof(Pixel)); - if (rpix) - pmap->clientPixelsRed[client] = rpix; - gpix = (Pixel *) xrealloc(pmap->clientPixelsGreen[client], - (pmap->numPixelsGreen[client] + (c << g)) * - sizeof(Pixel)); - if (gpix) - pmap->clientPixelsGreen[client] = gpix; - bpix = (Pixel *) xrealloc(pmap->clientPixelsBlue[client], - (pmap->numPixelsBlue[client] + (c << b)) * - sizeof(Pixel)); - if (bpix) - pmap->clientPixelsBlue[client] = bpix; - } - - if (!okR || !okG || !okB || !rpix || !gpix || !bpix) - { - if (okR) - for(ppix = ppixRed, npix = npixR; --npix >= 0; ppix++) - pmap->red[*ppix].refcnt = 0; - if (okG) - for(ppix = ppixGreen, npix = npixG; --npix >= 0; ppix++) - pmap->green[*ppix].refcnt = 0; - if (okB) - for(ppix = ppixBlue, npix = npixB; --npix >= 0; ppix++) - pmap->blue[*ppix].refcnt = 0; - xfree(ppixBlue); - xfree(ppixGreen); - xfree(ppixRed); - return(BadAlloc); - } - - *prmask <<= pmap->pVisual->offsetRed; - *pgmask <<= pmap->pVisual->offsetGreen; - *pbmask <<= pmap->pVisual->offsetBlue; - - ppix = rpix + pmap->numPixelsRed[client]; - for (pDst = pixels, p = ppixRed; p < ppixRed + npixR; p++) - { - *ppix++ = *p; - if(p < ppixRed + c) - *pDst++ |= *p << pmap->pVisual->offsetRed; - } - pmap->numPixelsRed[client] += npixR; - pmap->freeRed -= npixR; - - ppix = gpix + pmap->numPixelsGreen[client]; - for (pDst = pixels, p = ppixGreen; p < ppixGreen + npixG; p++) - { - *ppix++ = *p; - if(p < ppixGreen + c) - *pDst++ |= *p << pmap->pVisual->offsetGreen; - } - pmap->numPixelsGreen[client] += npixG; - pmap->freeGreen -= npixG; - - ppix = bpix + pmap->numPixelsBlue[client]; - for (pDst = pixels, p = ppixBlue; p < ppixBlue + npixB; p++) - { - *ppix++ = *p; - if(p < ppixBlue + c) - *pDst++ |= *p << pmap->pVisual->offsetBlue; - } - pmap->numPixelsBlue[client] += npixB; - pmap->freeBlue -= npixB; - - - for (pDst = pixels; pDst < pixels + c; pDst++) - *pDst |= ALPHAMASK(pmap->pVisual); - - xfree(ppixBlue); - xfree(ppixGreen); - xfree(ppixRed); - - return (Success); -} - -static int -AllocPseudo (int client, ColormapPtr pmap, int c, int r, Bool contig, - Pixel *pixels, Pixel *pmask, Pixel **pppixFirst) -{ - Pixel *ppix, *p, *pDst, *ppixTemp; - int npix; - Bool ok; - - npix = c << r; - if ((r >= 32) || (npix > pmap->freeRed) || (npix < c)) - return(BadAlloc); - if(!(ppixTemp = xalloc(npix * sizeof(Pixel)))) - return(BadAlloc); - ok = AllocCP(pmap, pmap->red, c, r, contig, ppixTemp, pmask); - - if (ok) - { - - /* all the allocated pixels are added to the client pixel list, - * but only the unique ones are returned to the client */ - ppix = (Pixel *)xrealloc(pmap->clientPixelsRed[client], - (pmap->numPixelsRed[client] + npix) * sizeof(Pixel)); - if (!ppix) - { - for (p = ppixTemp; p < ppixTemp + npix; p++) - pmap->red[*p].refcnt = 0; - return (BadAlloc); - } - pmap->clientPixelsRed[client] = ppix; - ppix += pmap->numPixelsRed[client]; - *pppixFirst = ppix; - pDst = pixels; - for (p = ppixTemp; p < ppixTemp + npix; p++) - { - *ppix++ = *p; - if(p < ppixTemp + c) - *pDst++ = *p; - } - pmap->numPixelsRed[client] += npix; - pmap->freeRed -= npix; - } - xfree(ppixTemp); - return (ok ? Success : BadAlloc); -} - -/* Allocates count << planes pixels from colormap pmap for client. If - * contig, then the plane mask is made of consecutive bits. Returns - * all count << pixels in the array pixels. The first count of those - * pixels are the unique pixels. *pMask has the mask to Or with the - * unique pixels to get the rest of them. - * - * Returns True iff all pixels could be allocated - * All cells allocated will have refcnt set to AllocPrivate and shared to FALSE - * (see AllocShared for why we care) - */ -static Bool -AllocCP (ColormapPtr pmap, EntryPtr pentFirst, int count, int planes, - Bool contig, Pixel *pixels, Pixel *pMask) -{ - EntryPtr ent; - Pixel pixel, base, entries, maxp, save; - int dplanes, found; - Pixel *ppix; - Pixel mask; - Pixel finalmask; - - dplanes = pmap->pVisual->nplanes; - - /* Easy case. Allocate pixels only */ - if (planes == 0) - { - /* allocate writable entries */ - ppix = pixels; - ent = pentFirst; - pixel = 0; - while (--count >= 0) - { - /* Just find count unallocated cells */ - while (ent->refcnt) - { - ent++; - pixel++; - } - ent->refcnt = AllocPrivate; - *ppix++ = pixel; - ent->fShared = FALSE; - } - *pMask = 0; - return (TRUE); - } - else if (planes > dplanes) - { - return (FALSE); - } - - /* General case count pixels * 2 ^ planes cells to be allocated */ - - /* make room for new pixels */ - ent = pentFirst; - - /* first try for contiguous planes, since it's fastest */ - for (mask = (((Pixel)1) << planes) - 1, base = 1, dplanes -= (planes - 1); - --dplanes >= 0; - mask += mask, base += base) - { - ppix = pixels; - found = 0; - pixel = 0; - entries = pmap->pVisual->ColormapEntries - mask; - while (pixel < entries) - { - save = pixel; - maxp = pixel + mask + base; - /* check if all are free */ - while (pixel != maxp && ent[pixel].refcnt == 0) - pixel += base; - if (pixel == maxp) - { - /* this one works */ - *ppix++ = save; - found++; - if (found == count) - { - /* found enough, allocate them all */ - while (--count >= 0) - { - pixel = pixels[count]; - maxp = pixel + mask; - while (1) - { - ent[pixel].refcnt = AllocPrivate; - ent[pixel].fShared = FALSE; - if (pixel == maxp) - break; - pixel += base; - *ppix++ = pixel; - } - } - *pMask = mask; - return (TRUE); - } - } - pixel = save + 1; - if (pixel & mask) - pixel += mask; - } - } - - dplanes = pmap->pVisual->nplanes; - if (contig || planes == 1 || dplanes < 3) - return (FALSE); - - /* this will be very slow for large maps, need a better algorithm */ - - /* - we can generate the smallest and largest numbers that fits in dplanes - bits and contain exactly planes bits set as follows. First, we need to - check that it is possible to generate such a mask at all. - (Non-contiguous masks need one more bit than contiguous masks). Then - the smallest such mask consists of the rightmost planes-1 bits set, then - a zero, then a one in position planes + 1. The formula is - (3 << (planes-1)) -1 - The largest such masks consists of the leftmost planes-1 bits set, then - a zero, then a one bit in position dplanes-planes-1. If dplanes is - smaller than 32 (the number of bits in a word) then the formula is: - (1<<dplanes) - (1<<(dplanes-planes+1) + (1<<dplanes-planes-1) - If dplanes = 32, then we can't calculate (1<<dplanes) and we have - to use: - ( (1<<(planes-1)) - 1) << (dplanes-planes+1) + (1<<(dplanes-planes-1)) - - << Thank you, Loretta>>> - - */ - - finalmask = - (((((Pixel)1)<<(planes-1)) - 1) << (dplanes-planes+1)) + - (((Pixel)1)<<(dplanes-planes-1)); - for (mask = (((Pixel)3) << (planes -1)) - 1; mask <= finalmask; mask++) - { - /* next 3 magic statements count number of ones (HAKMEM #169) */ - pixel = (mask >> 1) & 033333333333; - pixel = mask - pixel - ((pixel >> 1) & 033333333333); - if ((((pixel + (pixel >> 3)) & 030707070707) % 077) != planes) - continue; - ppix = pixels; - found = 0; - entries = pmap->pVisual->ColormapEntries - mask; - base = lowbit (mask); - for (pixel = 0; pixel < entries; pixel++) - { - if (pixel & mask) - continue; - maxp = 0; - /* check if all are free */ - while (ent[pixel + maxp].refcnt == 0) - { - GetNextBitsOrBreak(maxp, mask, base); - } - if ((maxp < mask) || (ent[pixel + mask].refcnt != 0)) - continue; - /* this one works */ - *ppix++ = pixel; - found++; - if (found < count) - continue; - /* found enough, allocate them all */ - while (--count >= 0) - { - pixel = (pixels)[count]; - maxp = 0; - while (1) - { - ent[pixel + maxp].refcnt = AllocPrivate; - ent[pixel + maxp].fShared = FALSE; - GetNextBitsOrBreak(maxp, mask, base); - *ppix++ = pixel + maxp; - } - } - - *pMask = mask; - return (TRUE); - } - } - return (FALSE); -} - -/** - * - * \param ppixFirst First of the client's new pixels - */ -static Bool -AllocShared (ColormapPtr pmap, Pixel *ppix, int c, int r, int g, int b, - Pixel rmask, Pixel gmask, Pixel bmask, Pixel *ppixFirst) -{ - Pixel *pptr, *cptr; - int npix, z, npixClientNew, npixShared; - Pixel basemask, base, bits, common; - SHAREDCOLOR *pshared, **ppshared, **psharedList; - - npixClientNew = c << (r + g + b); - npixShared = (c << r) + (c << g) + (c << b); - psharedList = xalloc(npixShared * sizeof(SHAREDCOLOR *)); - if (!psharedList) - return FALSE; - ppshared = psharedList; - for (z = npixShared; --z >= 0; ) - { - if (!(ppshared[z] = xalloc(sizeof(SHAREDCOLOR)))) - { - for (z++ ; z < npixShared; z++) - xfree(ppshared[z]); - return FALSE; - } - } - for(pptr = ppix, npix = c; --npix >= 0; pptr++) - { - basemask = ~(gmask | bmask); - common = *pptr & basemask; - if (rmask) - { - bits = 0; - base = lowbit (rmask); - while(1) - { - pshared = *ppshared++; - pshared->refcnt = 1 << (g + b); - for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++) - { - if ((*cptr & basemask) == (common | bits)) - { - pmap->red[*cptr].fShared = TRUE; - pmap->red[*cptr].co.shco.red = pshared; - } - } - GetNextBitsOrBreak(bits, rmask, base); - } - } - else - { - pshared = *ppshared++; - pshared->refcnt = 1 << (g + b); - for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++) - { - if ((*cptr & basemask) == common) - { - pmap->red[*cptr].fShared = TRUE; - pmap->red[*cptr].co.shco.red = pshared; - } - } - } - basemask = ~(rmask | bmask); - common = *pptr & basemask; - if (gmask) - { - bits = 0; - base = lowbit (gmask); - while(1) - { - pshared = *ppshared++; - pshared->refcnt = 1 << (r + b); - for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++) - { - if ((*cptr & basemask) == (common | bits)) - { - pmap->red[*cptr].co.shco.green = pshared; - } - } - GetNextBitsOrBreak(bits, gmask, base); - } - } - else - { - pshared = *ppshared++; - pshared->refcnt = 1 << (g + b); - for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++) - { - if ((*cptr & basemask) == common) - { - pmap->red[*cptr].co.shco.green = pshared; - } - } - } - basemask = ~(rmask | gmask); - common = *pptr & basemask; - if (bmask) - { - bits = 0; - base = lowbit (bmask); - while(1) - { - pshared = *ppshared++; - pshared->refcnt = 1 << (r + g); - for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++) - { - if ((*cptr & basemask) == (common | bits)) - { - pmap->red[*cptr].co.shco.blue = pshared; - } - } - GetNextBitsOrBreak(bits, bmask, base); - } - } - else - { - pshared = *ppshared++; - pshared->refcnt = 1 << (g + b); - for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++) - { - if ((*cptr & basemask) == common) - { - pmap->red[*cptr].co.shco.blue = pshared; - } - } - } - } - xfree(psharedList); - return TRUE; -} - - -/** FreeColors - * Free colors and/or cells (probably slow for large numbers) - */ -int -FreeColors (ColormapPtr pmap, int client, int count, Pixel *pixels, Pixel mask) -{ - int rval, result, class; - Pixel rmask; - - class = pmap->class; - if (pmap->flags & AllAllocated) - return(BadAccess); - if ((class | DynamicClass) == DirectColor) - { - rmask = mask & RGBMASK(pmap->pVisual); - result = FreeCo(pmap, client, REDMAP, count, pixels, - mask & pmap->pVisual->redMask); - /* If any of the three calls fails, we must report that, if more - * than one fails, it's ok that we report the last one */ - rval = FreeCo(pmap, client, GREENMAP, count, pixels, - mask & pmap->pVisual->greenMask); - if(rval != Success) - result = rval; - rval = FreeCo(pmap, client, BLUEMAP, count, pixels, - mask & pmap->pVisual->blueMask); - if(rval != Success) - result = rval; - } - else - { - rmask = mask & ((((Pixel)1) << pmap->pVisual->nplanes) - 1); - result = FreeCo(pmap, client, PSEUDOMAP, count, pixels, rmask); - } - if ((mask != rmask) && count) - { - clientErrorValue = *pixels | mask; - result = BadValue; - } - /* XXX should worry about removing any RT_CMAPENTRY resource */ - return (result); -} - -/** - * Helper for FreeColors -- frees all combinations of *newpixels and mask bits - * which the client has allocated in channel colormap cells of pmap. - * doesn't change newpixels if it doesn't need to - * - * \param pmap which colormap head - * \param color which sub-map, eg, RED, BLUE, PSEUDO - * \param npixIn number of pixels passed in - * \param ppixIn number of base pixels - * \param mask mask client gave us - */ -static int -FreeCo (ColormapPtr pmap, int client, int color, int npixIn, Pixel *ppixIn, Pixel mask) -{ - Pixel *ppixClient, pixTest; - int npixClient, npixNew, npix; - Pixel bits, base, cmask, rgbbad; - Pixel *pptr, *cptr; - int n, zapped; - int errVal = Success; - int offset, numents; - - if (npixIn == 0) - return (errVal); - bits = 0; - zapped = 0; - base = lowbit (mask); - - switch(color) - { - case REDMAP: - cmask = pmap->pVisual->redMask; - rgbbad = ~RGBMASK(pmap->pVisual); - offset = pmap->pVisual->offsetRed; - numents = (cmask >> offset) + 1; - ppixClient = pmap->clientPixelsRed[client]; - npixClient = pmap->numPixelsRed[client]; - break; - case GREENMAP: - cmask = pmap->pVisual->greenMask; - rgbbad = ~RGBMASK(pmap->pVisual); - offset = pmap->pVisual->offsetGreen; - numents = (cmask >> offset) + 1; - ppixClient = pmap->clientPixelsGreen[client]; - npixClient = pmap->numPixelsGreen[client]; - break; - case BLUEMAP: - cmask = pmap->pVisual->blueMask; - rgbbad = ~RGBMASK(pmap->pVisual); - offset = pmap->pVisual->offsetBlue; - numents = (cmask >> offset) + 1; - ppixClient = pmap->clientPixelsBlue[client]; - npixClient = pmap->numPixelsBlue[client]; - break; - default: /* so compiler can see that everything gets initialized */ - case PSEUDOMAP: - cmask = ~((Pixel)0); - rgbbad = 0; - offset = 0; - numents = pmap->pVisual->ColormapEntries; - ppixClient = pmap->clientPixelsRed[client]; - npixClient = pmap->numPixelsRed[client]; - break; - } - - - /* zap all pixels which match */ - while (1) - { - /* go through pixel list */ - for (pptr = ppixIn, n = npixIn; --n >= 0; pptr++) - { - pixTest = ((*pptr | bits) & cmask) >> offset; - if ((pixTest >= numents) || (*pptr & rgbbad)) - { - clientErrorValue = *pptr | bits; - errVal = BadValue; - continue; - } - - /* find match in client list */ - for (cptr = ppixClient, npix = npixClient; - --npix >= 0 && *cptr != pixTest; - cptr++) ; - - if (npix >= 0) - { - if (pmap->class & DynamicClass) - { - FreeCell(pmap, pixTest, color); - } - *cptr = ~((Pixel)0); - zapped++; - } - else - errVal = BadAccess; - } - /* generate next bits value */ - GetNextBitsOrBreak(bits, mask, base); - } - - /* delete freed pixels from client pixel list */ - if (zapped) - { - npixNew = npixClient - zapped; - if (npixNew) - { - /* Since the list can only get smaller, we can do a copy in - * place and then realloc to a smaller size */ - pptr = cptr = ppixClient; - - /* If we have all the new pixels, we don't have to examine the - * rest of the old ones */ - for(npix = 0; npix < npixNew; cptr++) - { - if (*cptr != ~((Pixel)0)) - { - *pptr++ = *cptr; - npix++; - } - } - pptr = (Pixel *)xrealloc(ppixClient, npixNew * sizeof(Pixel)); - if (pptr) - ppixClient = pptr; - npixClient = npixNew; - } - else - { - npixClient = 0; - xfree(ppixClient); - ppixClient = (Pixel *)NULL; - } - switch(color) - { - case PSEUDOMAP: - case REDMAP: - pmap->clientPixelsRed[client] = ppixClient; - pmap->numPixelsRed[client] = npixClient; - break; - case GREENMAP: - pmap->clientPixelsGreen[client] = ppixClient; - pmap->numPixelsGreen[client] = npixClient; - break; - case BLUEMAP: - pmap->clientPixelsBlue[client] = ppixClient; - pmap->numPixelsBlue[client] = npixClient; - break; - } - } - return (errVal); -} - - - -/* Redefine color values */ -int -StoreColors (ColormapPtr pmap, int count, xColorItem *defs) -{ - Pixel pix; - xColorItem *pdef; - EntryPtr pent, pentT, pentLast; - VisualPtr pVisual; - SHAREDCOLOR *pred, *pgreen, *pblue; - int n, ChgRed, ChgGreen, ChgBlue, idef; - int class, errVal = Success; - int ok; - - - class = pmap->class; - if(!(class & DynamicClass) && !(pmap->flags & BeingCreated)) - { - return(BadAccess); - } - pVisual = pmap->pVisual; - - idef = 0; - if((class | DynamicClass) == DirectColor) - { - int numred, numgreen, numblue; - Pixel rgbbad; - - numred = NUMRED(pVisual); - numgreen = NUMGREEN(pVisual); - numblue = NUMBLUE(pVisual); - rgbbad = ~RGBMASK(pVisual); - for (pdef = defs, n = 0; n < count; pdef++, n++) - { - ok = TRUE; - (*pmap->pScreen->ResolveColor) - (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual); - - if (pdef->pixel & rgbbad) - { - errVal = BadValue; - clientErrorValue = pdef->pixel; - continue; - } - pix = (pdef->pixel & pVisual->redMask) >> pVisual->offsetRed; - if (pix >= numred) - { - errVal = BadValue; - ok = FALSE; - } - else if (pmap->red[pix].refcnt != AllocPrivate) - { - errVal = BadAccess; - ok = FALSE; - } - else if (pdef->flags & DoRed) - { - pmap->red[pix].co.local.red = pdef->red; - } - else - { - pdef->red = pmap->red[pix].co.local.red; - } - - pix = (pdef->pixel & pVisual->greenMask) >> pVisual->offsetGreen; - if (pix >= numgreen) - { - errVal = BadValue; - ok = FALSE; - } - else if (pmap->green[pix].refcnt != AllocPrivate) - { - errVal = BadAccess; - ok = FALSE; - } - else if (pdef->flags & DoGreen) - { - pmap->green[pix].co.local.green = pdef->green; - } - else - { - pdef->green = pmap->green[pix].co.local.green; - } - - pix = (pdef->pixel & pVisual->blueMask) >> pVisual->offsetBlue; - if (pix >= numblue) - { - errVal = BadValue; - ok = FALSE; - } - else if (pmap->blue[pix].refcnt != AllocPrivate) - { - errVal = BadAccess; - ok = FALSE; - } - else if (pdef->flags & DoBlue) - { - pmap->blue[pix].co.local.blue = pdef->blue; - } - else - { - pdef->blue = pmap->blue[pix].co.local.blue; - } - /* If this is an o.k. entry, then it gets added to the list - * to be sent to the hardware. If not, skip it. Once we've - * skipped one, we have to copy all the others. - */ - if(ok) - { - if(idef != n) - defs[idef] = defs[n]; - idef++; - } else - clientErrorValue = pdef->pixel; - } - } - else - { - for (pdef = defs, n = 0; n < count; pdef++, n++) - { - - ok = TRUE; - if (pdef->pixel >= pVisual->ColormapEntries) - { - clientErrorValue = pdef->pixel; - errVal = BadValue; - ok = FALSE; - } - else if (pmap->red[pdef->pixel].refcnt != AllocPrivate) - { - errVal = BadAccess; - ok = FALSE; - } - - /* If this is an o.k. entry, then it gets added to the list - * to be sent to the hardware. If not, skip it. Once we've - * skipped one, we have to copy all the others. - */ - if(ok) - { - if(idef != n) - defs[idef] = defs[n]; - idef++; - } - else - continue; - - (*pmap->pScreen->ResolveColor) - (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual); - - pent = &pmap->red[pdef->pixel]; - - if(pdef->flags & DoRed) - { - if(pent->fShared) - { - pent->co.shco.red->color = pdef->red; - if (pent->co.shco.red->refcnt > 1) - ok = FALSE; - } - else - pent->co.local.red = pdef->red; - } - else - { - if(pent->fShared) - pdef->red = pent->co.shco.red->color; - else - pdef->red = pent->co.local.red; - } - if(pdef->flags & DoGreen) - { - if(pent->fShared) - { - pent->co.shco.green->color = pdef->green; - if (pent->co.shco.green->refcnt > 1) - ok = FALSE; - } - else - pent->co.local.green = pdef->green; - } - else - { - if(pent->fShared) - pdef->green = pent->co.shco.green->color; - else - pdef->green = pent->co.local.green; - } - if(pdef->flags & DoBlue) - { - if(pent->fShared) - { - pent->co.shco.blue->color = pdef->blue; - if (pent->co.shco.blue->refcnt > 1) - ok = FALSE; - } - else - pent->co.local.blue = pdef->blue; - } - else - { - if(pent->fShared) - pdef->blue = pent->co.shco.blue->color; - else - pdef->blue = pent->co.local.blue; - } - - if(!ok) - { - /* have to run through the colormap and change anybody who - * shares this value */ - pred = pent->co.shco.red; - pgreen = pent->co.shco.green; - pblue = pent->co.shco.blue; - ChgRed = pdef->flags & DoRed; - ChgGreen = pdef->flags & DoGreen; - ChgBlue = pdef->flags & DoBlue; - pentLast = pmap->red + pVisual->ColormapEntries; - - for(pentT = pmap->red; pentT < pentLast; pentT++) - { - if(pentT->fShared && (pentT != pent)) - { - xColorItem defChg; - - /* There are, alas, devices in this world too dumb - * to read their own hardware colormaps. Sick, but - * true. So we're going to be really nice and load - * the xColorItem with the proper value for all the - * fields. We will only set the flags for those - * fields that actually change. Smart devices can - * arrange to change only those fields. Dumb devices - * can rest assured that we have provided for them, - * and can change all three fields */ - - defChg.flags = 0; - if(ChgRed && pentT->co.shco.red == pred) - { - defChg.flags |= DoRed; - } - if(ChgGreen && pentT->co.shco.green == pgreen) - { - defChg.flags |= DoGreen; - } - if(ChgBlue && pentT->co.shco.blue == pblue) - { - defChg.flags |= DoBlue; - } - if(defChg.flags != 0) - { - defChg.pixel = pentT - pmap->red; - defChg.red = pentT->co.shco.red->color; - defChg.green = pentT->co.shco.green->color; - defChg.blue = pentT->co.shco.blue->color; - (*pmap->pScreen->StoreColors) (pmap, 1, &defChg); - } - } - } - - } - } - } - /* Note that we use idef, the count of acceptable entries, and not - * count, the count of proposed entries */ - if (idef != 0) - ( *pmap->pScreen->StoreColors) (pmap, idef, defs); - return (errVal); -} - -int -IsMapInstalled(Colormap map, WindowPtr pWin) -{ - Colormap *pmaps; - int imap, nummaps, found; - - pmaps = xalloc(pWin->drawable.pScreen->maxInstalledCmaps*sizeof(Colormap)); - if(!pmaps) - return(FALSE); - nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps) - (pWin->drawable.pScreen, pmaps); - found = FALSE; - for(imap = 0; imap < nummaps; imap++) - { - if(pmaps[imap] == map) - { - found = TRUE; - break; - } - } - xfree(pmaps); - return (found); -} - -struct colormap_lookup_data { - ScreenPtr pScreen; - VisualPtr visuals; -}; - -static void _colormap_find_resource(pointer value, XID id, - pointer cdata) -{ - struct colormap_lookup_data *cmap_data = cdata; - VisualPtr visuals = cmap_data->visuals; - ScreenPtr pScreen = cmap_data->pScreen; - ColormapPtr cmap = value; - int j; - - if (pScreen != cmap->pScreen) - return; - - j = cmap->pVisual - pScreen->visuals; - cmap->pVisual = &visuals[j]; -} - -/* something has realloced the visuals, instead of breaking - ABI fix it up here - glx and compsite did this wrong */ -Bool -ResizeVisualArray(ScreenPtr pScreen, int new_visual_count, - DepthPtr depth) -{ - struct colormap_lookup_data cdata; - int numVisuals; - VisualPtr visuals; - XID *vids, vid; - int first_new_vid, first_new_visual, i; - - first_new_vid = depth->numVids; - first_new_visual = pScreen->numVisuals; - - vids = xrealloc(depth->vids, (depth->numVids + new_visual_count) * sizeof(XID)); - if (!vids) - return FALSE; - - /* its realloced now no going back if we fail the next one */ - depth->vids = vids; - - numVisuals = pScreen->numVisuals + new_visual_count; - visuals = xrealloc(pScreen->visuals, numVisuals * sizeof(VisualRec)); - if (!visuals) { - return FALSE; - } - - cdata.visuals = visuals; - cdata.pScreen = pScreen; - FindClientResourcesByType(serverClient, RT_COLORMAP, _colormap_find_resource, &cdata); - - pScreen->visuals = visuals; - - for (i = 0; i < new_visual_count; i++) { - vid = FakeClientID(0); - pScreen->visuals[first_new_visual + i].vid = vid; - vids[first_new_vid + i] = vid; - } - - depth->numVids += new_visual_count; - pScreen->numVisuals += new_visual_count; - - return TRUE; -} +/***********************************************************
+
+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 <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <stdio.h>
+#include <string.h>
+#include <strings.h>
+#include "misc.h"
+#include "dix.h"
+#include "colormapst.h"
+#include "os.h"
+#include "scrnintstr.h"
+#include "resource.h"
+#include "windowstr.h"
+#include "privates.h"
+#include "xace.h"
+
+#ifdef _MSC_VER
+#define UpdateColors thisUpdateColors
+#endif
+
+extern XID clientErrorValue;
+
+static Pixel FindBestPixel(
+ EntryPtr /*pentFirst*/,
+ int /*size*/,
+ xrgb * /*prgb*/,
+ int /*channel*/
+);
+
+static int AllComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static int RedComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static int GreenComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static int BlueComp(
+ EntryPtr /*pent*/,
+ xrgb * /*prgb*/
+);
+
+static void FreePixels(
+ ColormapPtr /*pmap*/,
+ int /*client*/
+);
+
+static void CopyFree(
+ int /*channel*/,
+ int /*client*/,
+ ColormapPtr /*pmapSrc*/,
+ ColormapPtr /*pmapDst*/
+);
+
+static void FreeCell(
+ ColormapPtr /*pmap*/,
+ Pixel /*i*/,
+ int /*channel*/
+);
+
+static void UpdateColors(
+ ColormapPtr /*pmap*/
+);
+
+static int AllocDirect(
+ int /*client*/,
+ ColormapPtr /*pmap*/,
+ int /*c*/,
+ int /*r*/,
+ int /*g*/,
+ int /*b*/,
+ Bool /*contig*/,
+ Pixel * /*pixels*/,
+ Pixel * /*prmask*/,
+ Pixel * /*pgmask*/,
+ Pixel * /*pbmask*/
+);
+
+static int AllocPseudo(
+ int /*client*/,
+ ColormapPtr /*pmap*/,
+ int /*c*/,
+ int /*r*/,
+ Bool /*contig*/,
+ Pixel * /*pixels*/,
+ Pixel * /*pmask*/,
+ Pixel ** /*pppixFirst*/
+);
+
+static Bool AllocCP(
+ ColormapPtr /*pmap*/,
+ EntryPtr /*pentFirst*/,
+ int /*count*/,
+ int /*planes*/,
+ Bool /*contig*/,
+ Pixel * /*pixels*/,
+ Pixel * /*pMask*/
+);
+
+static Bool AllocShared(
+ ColormapPtr /*pmap*/,
+ Pixel * /*ppix*/,
+ int /*c*/,
+ int /*r*/,
+ int /*g*/,
+ int /*b*/,
+ Pixel /*rmask*/,
+ Pixel /*gmask*/,
+ Pixel /*bmask*/,
+ Pixel * /*ppixFirst*/
+);
+
+static int FreeCo(
+ ColormapPtr /*pmap*/,
+ int /*client*/,
+ int /*color*/,
+ int /*npixIn*/,
+ Pixel * /*ppixIn*/,
+ Pixel /*mask*/
+);
+
+static int TellNoMap(
+ WindowPtr /*pwin*/,
+ Colormap * /*pmid*/
+);
+
+static void FindColorInRootCmap (
+ ColormapPtr /* pmap */,
+ EntryPtr /* pentFirst */,
+ int /* size */,
+ xrgb* /* prgb */,
+ Pixel* /* pPixel */,
+ int /* channel */,
+ ColorCompareProcPtr /* comp */
+);
+
+#define NUMRED(vis) ((vis->redMask >> vis->offsetRed) + 1)
+#define NUMGREEN(vis) ((vis->greenMask >> vis->offsetGreen) + 1)
+#define NUMBLUE(vis) ((vis->blueMask >> vis->offsetBlue) + 1)
+#if COMPOSITE
+#define ALPHAMASK(vis) ((vis)->nplanes < 32 ? 0 : \
+ (CARD32) ~((vis)->redMask|(vis)->greenMask|(vis)->blueMask))
+#else
+#define ALPHAMASK(vis) 0
+#endif
+
+#define RGBMASK(vis) (vis->redMask | vis->greenMask | vis->blueMask | ALPHAMASK(vis))
+
+/* GetNextBitsOrBreak(bits, mask, base) --
+ * (Suggestion: First read the macro, then read this explanation.
+ *
+ * Either generate the next value to OR in to a pixel or break out of this
+ * while loop
+ *
+ * This macro is used when we're trying to generate all 2^n combinations of
+ * bits in mask. What we're doing here is counting in binary, except that
+ * the bits we use to count may not be contiguous. This macro will be
+ * called 2^n times, returning a different value in bits each time. Then
+ * it will cause us to break out of a surrounding loop. (It will always be
+ * called from within a while loop.)
+ * On call: mask is the value we want to find all the combinations for
+ * base has 1 bit set where the least significant bit of mask is set
+ *
+ * For example,if mask is 01010, base should be 0010 and we count like this:
+ * 00010 (see this isn't so hard),
+ * then we add base to bits and get 0100. (bits & ~mask) is (0100 & 0100) so
+ * we add that to bits getting (0100 + 0100) =
+ * 01000 for our next value.
+ * then we add 0010 to get
+ * 01010 and we're done (easy as 1, 2, 3)
+ */
+#define GetNextBitsOrBreak(bits, mask, base) \
+ if((bits) == (mask)) \
+ break; \
+ (bits) += (base); \
+ while((bits) & ~(mask)) \
+ (bits) += ((bits) & ~(mask));
+/* ID of server as client */
+#define SERVER_ID 0
+
+typedef struct _colorResource
+{
+ Colormap mid;
+ int client;
+} colorResource;
+
+/* Invariants:
+ * refcnt == 0 means entry is empty
+ * refcnt > 0 means entry is useable by many clients, so it can't be changed
+ * refcnt == AllocPrivate means entry owned by one client only
+ * fShared should only be set if refcnt == AllocPrivate, and only in red map
+ */
+
+
+/**
+ * Create and initialize the color map
+ *
+ * \param mid resource to use for this colormap
+ * \param alloc 1 iff all entries are allocated writable
+ */
+int
+CreateColormap (Colormap mid, ScreenPtr pScreen, VisualPtr pVisual,
+ ColormapPtr *ppcmap, int alloc, int client)
+{
+ int class, size;
+ unsigned long sizebytes;
+ ColormapPtr pmap;
+ EntryPtr pent;
+ int i;
+ Pixel *ppix, **pptr;
+
+ class = pVisual->class;
+ if(!(class & DynamicClass) && (alloc != AllocNone) && (client != SERVER_ID))
+ return (BadMatch);
+
+ size = pVisual->ColormapEntries;
+ sizebytes = (size * sizeof(Entry)) +
+ (MAXCLIENTS * sizeof(Pixel *)) +
+ (MAXCLIENTS * sizeof(int));
+ if ((class | DynamicClass) == DirectColor)
+ sizebytes *= 3;
+ sizebytes += sizeof(ColormapRec);
+ pmap = xalloc(sizebytes);
+ if (!pmap)
+ return (BadAlloc);
+#if defined(_XSERVER64)
+ pmap->pad0 = 0;
+ pmap->pad1 = 0;
+#if (X_BYTE_ORDER == X_LITTLE_ENDIAN)
+ pmap->pad2 = 0;
+#endif
+#endif
+ pmap->red = (EntryPtr)((char *)pmap + sizeof(ColormapRec));
+ sizebytes = size * sizeof(Entry);
+ pmap->clientPixelsRed = (Pixel **)((char *)pmap->red + sizebytes);
+ pmap->numPixelsRed = (int *)((char *)pmap->clientPixelsRed +
+ (MAXCLIENTS * sizeof(Pixel *)));
+ pmap->mid = mid;
+ pmap->flags = 0; /* start out with all flags clear */
+ if(mid == pScreen->defColormap)
+ pmap->flags |= IsDefault;
+ pmap->pScreen = pScreen;
+ pmap->pVisual = pVisual;
+ pmap->class = class;
+ if ((class | DynamicClass) == DirectColor)
+ size = NUMRED(pVisual);
+ pmap->freeRed = size;
+ bzero ((char *) pmap->red, (int)sizebytes);
+ bzero((char *) pmap->numPixelsRed, MAXCLIENTS * sizeof(int));
+ for (pptr = &pmap->clientPixelsRed[MAXCLIENTS]; --pptr >= pmap->clientPixelsRed; )
+ *pptr = (Pixel *)NULL;
+ if (alloc == AllocAll)
+ {
+ if (class & DynamicClass)
+ pmap->flags |= AllAllocated;
+ for (pent = &pmap->red[size - 1]; pent >= pmap->red; pent--)
+ pent->refcnt = AllocPrivate;
+ pmap->freeRed = 0;
+ ppix = xalloc(size * sizeof(Pixel));
+ if (!ppix)
+ {
+ xfree(pmap);
+ return (BadAlloc);
+ }
+ pmap->clientPixelsRed[client] = ppix;
+ for(i = 0; i < size; i++)
+ ppix[i] = i;
+ pmap->numPixelsRed[client] = size;
+ }
+
+ if ((class | DynamicClass) == DirectColor)
+ {
+ pmap->freeGreen = NUMGREEN(pVisual);
+ pmap->green = (EntryPtr)((char *)pmap->numPixelsRed +
+ (MAXCLIENTS * sizeof(int)));
+ pmap->clientPixelsGreen = (Pixel **)((char *)pmap->green + sizebytes);
+ pmap->numPixelsGreen = (int *)((char *)pmap->clientPixelsGreen +
+ (MAXCLIENTS * sizeof(Pixel *)));
+ pmap->freeBlue = NUMBLUE(pVisual);
+ pmap->blue = (EntryPtr)((char *)pmap->numPixelsGreen +
+ (MAXCLIENTS * sizeof(int)));
+ pmap->clientPixelsBlue = (Pixel **)((char *)pmap->blue + sizebytes);
+ pmap->numPixelsBlue = (int *)((char *)pmap->clientPixelsBlue +
+ (MAXCLIENTS * sizeof(Pixel *)));
+
+ bzero ((char *) pmap->green, (int)sizebytes);
+ bzero ((char *) pmap->blue, (int)sizebytes);
+
+ memmove((char *) pmap->clientPixelsGreen,
+ (char *) pmap->clientPixelsRed,
+ MAXCLIENTS * sizeof(Pixel *));
+ memmove((char *) pmap->clientPixelsBlue,
+ (char *) pmap->clientPixelsRed,
+ MAXCLIENTS * sizeof(Pixel *));
+ bzero((char *) pmap->numPixelsGreen, MAXCLIENTS * sizeof(int));
+ bzero((char *) pmap->numPixelsBlue, MAXCLIENTS * sizeof(int));
+
+ /* If every cell is allocated, mark its refcnt */
+ if (alloc == AllocAll)
+ {
+ size = pmap->freeGreen;
+ for(pent = &pmap->green[size-1]; pent >= pmap->green; pent--)
+ pent->refcnt = AllocPrivate;
+ pmap->freeGreen = 0;
+ ppix = xalloc(size * sizeof(Pixel));
+ if (!ppix)
+ {
+ xfree(pmap->clientPixelsRed[client]);
+ xfree(pmap);
+ return(BadAlloc);
+ }
+ pmap->clientPixelsGreen[client] = ppix;
+ for(i = 0; i < size; i++)
+ ppix[i] = i;
+ pmap->numPixelsGreen[client] = size;
+
+ size = pmap->freeBlue;
+ for(pent = &pmap->blue[size-1]; pent >= pmap->blue; pent--)
+ pent->refcnt = AllocPrivate;
+ pmap->freeBlue = 0;
+ ppix = xalloc(size * sizeof(Pixel));
+ if (!ppix)
+ {
+ xfree(pmap->clientPixelsGreen[client]);
+ xfree(pmap->clientPixelsRed[client]);
+ xfree(pmap);
+ return(BadAlloc);
+ }
+ pmap->clientPixelsBlue[client] = ppix;
+ for(i = 0; i < size; i++)
+ ppix[i] = i;
+ pmap->numPixelsBlue[client] = size;
+ }
+ }
+ pmap->devPrivates = NULL;
+ pmap->flags |= BeingCreated;
+
+ if (!AddResource(mid, RT_COLORMAP, (pointer)pmap))
+ return (BadAlloc);
+
+ /*
+ * Security creation/labeling check
+ */
+ i = XaceHook(XACE_RESOURCE_ACCESS, clients[client], mid, RT_COLORMAP,
+ pmap, RT_NONE, NULL, DixCreateAccess);
+ if (i != Success) {
+ FreeResource(mid, RT_NONE);
+ return i;
+ }
+
+ /* If the device wants a chance to initialize the colormap in any way,
+ * this is it. In specific, if this is a Static colormap, this is the
+ * time to fill in the colormap's values */
+ if (!(*pScreen->CreateColormap)(pmap))
+ {
+ FreeResource (mid, RT_NONE);
+ return BadAlloc;
+ }
+ pmap->flags &= ~BeingCreated;
+ *ppcmap = pmap;
+ return (Success);
+}
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+FreeColormap (pointer value, XID mid)
+{
+ int i;
+ EntryPtr pent;
+ ColormapPtr pmap = (ColormapPtr)value;
+
+ if(CLIENT_ID(mid) != SERVER_ID)
+ {
+ (*pmap->pScreen->UninstallColormap) (pmap);
+ WalkTree(pmap->pScreen, (VisitWindowProcPtr)TellNoMap, (pointer) &mid);
+ }
+
+ /* This is the device's chance to undo anything it needs to, especially
+ * to free any storage it allocated */
+ (*pmap->pScreen->DestroyColormap)(pmap);
+
+ if(pmap->clientPixelsRed)
+ {
+ for(i = 0; i < MAXCLIENTS; i++)
+ xfree(pmap->clientPixelsRed[i]);
+ }
+
+ if ((pmap->class == PseudoColor) || (pmap->class == GrayScale))
+ {
+ for(pent = &pmap->red[pmap->pVisual->ColormapEntries - 1];
+ pent >= pmap->red;
+ pent--)
+ {
+ if(pent->fShared)
+ {
+ if (--pent->co.shco.red->refcnt == 0)
+ xfree(pent->co.shco.red);
+ if (--pent->co.shco.green->refcnt == 0)
+ xfree(pent->co.shco.green);
+ if (--pent->co.shco.blue->refcnt == 0)
+ xfree(pent->co.shco.blue);
+ }
+ }
+ }
+ if((pmap->class | DynamicClass) == DirectColor)
+ {
+ for(i = 0; i < MAXCLIENTS; i++)
+ {
+ xfree(pmap->clientPixelsGreen[i]);
+ xfree(pmap->clientPixelsBlue[i]);
+ }
+ }
+
+ dixFreePrivates(pmap->devPrivates);
+ xfree(pmap);
+ return(Success);
+}
+
+/* Tell window that pmid has disappeared */
+static int
+TellNoMap (WindowPtr pwin, Colormap *pmid)
+{
+ xEvent xE;
+
+ if (wColormap(pwin) == *pmid)
+ {
+ /* This should be call to DeliverEvent */
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pwin->drawable.id;
+ xE.u.colormap.colormap = None;
+ xE.u.colormap.new = TRUE;
+ xE.u.colormap.state = ColormapUninstalled;
+#ifdef PANORAMIX
+ if(noPanoramiXExtension || !pwin->drawable.pScreen->myNum)
+#endif
+ DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
+ if (pwin->optional) {
+ pwin->optional->colormap = None;
+ CheckWindowOptionalNeed (pwin);
+ }
+ }
+
+ return (WT_WALKCHILDREN);
+}
+
+/* Tell window that pmid got uninstalled */
+int
+TellLostMap (WindowPtr pwin, pointer value)
+{
+ Colormap *pmid = (Colormap *)value;
+ xEvent xE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
+ return WT_STOPWALKING;
+#endif
+ if (wColormap(pwin) == *pmid)
+ {
+ /* This should be call to DeliverEvent */
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pwin->drawable.id;
+ xE.u.colormap.colormap = *pmid;
+ xE.u.colormap.new = FALSE;
+ xE.u.colormap.state = ColormapUninstalled;
+ DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
+ }
+
+ return (WT_WALKCHILDREN);
+}
+
+/* Tell window that pmid got installed */
+int
+TellGainedMap (WindowPtr pwin, pointer value)
+{
+ Colormap *pmid = (Colormap *)value;
+ xEvent xE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pwin->drawable.pScreen->myNum)
+ return WT_STOPWALKING;
+#endif
+ if (wColormap (pwin) == *pmid)
+ {
+ /* This should be call to DeliverEvent */
+ xE.u.u.type = ColormapNotify;
+ xE.u.colormap.window = pwin->drawable.id;
+ xE.u.colormap.colormap = *pmid;
+ xE.u.colormap.new = FALSE;
+ xE.u.colormap.state = ColormapInstalled;
+ DeliverEvents(pwin, &xE, 1, (WindowPtr)NULL);
+ }
+
+ return (WT_WALKCHILDREN);
+}
+
+
+int
+CopyColormapAndFree (Colormap mid, ColormapPtr pSrc, int client)
+{
+ ColormapPtr pmap = (ColormapPtr) NULL;
+ int result, alloc, size;
+ Colormap midSrc;
+ ScreenPtr pScreen;
+ VisualPtr pVisual;
+
+ pScreen = pSrc->pScreen;
+ pVisual = pSrc->pVisual;
+ midSrc = pSrc->mid;
+ alloc = ((pSrc->flags & AllAllocated) && CLIENT_ID(midSrc) == client) ?
+ AllocAll : AllocNone;
+ size = pVisual->ColormapEntries;
+
+ /* If the create returns non-0, it failed */
+ result = CreateColormap (mid, pScreen, pVisual, &pmap, alloc, client);
+ if(result != Success)
+ return(result);
+ if(alloc == AllocAll)
+ {
+ memmove((char *)pmap->red, (char *)pSrc->red, size * sizeof(Entry));
+ if((pmap->class | DynamicClass) == DirectColor)
+ {
+ memmove((char *)pmap->green, (char *)pSrc->green, size * sizeof(Entry));
+ memmove((char *)pmap->blue, (char *)pSrc->blue, size * sizeof(Entry));
+ }
+ pSrc->flags &= ~AllAllocated;
+ FreePixels(pSrc, client);
+ UpdateColors(pmap);
+ return(Success);
+ }
+
+ CopyFree(REDMAP, client, pSrc, pmap);
+ if ((pmap->class | DynamicClass) == DirectColor)
+ {
+ CopyFree(GREENMAP, client, pSrc, pmap);
+ CopyFree(BLUEMAP, client, pSrc, pmap);
+ }
+ if (pmap->class & DynamicClass)
+ UpdateColors(pmap);
+ /* XXX should worry about removing any RT_CMAPENTRY resource */
+ return(Success);
+}
+
+/* Helper routine for freeing large numbers of cells from a map */
+static void
+CopyFree (int channel, int client, ColormapPtr pmapSrc, ColormapPtr pmapDst)
+{
+ int z, npix;
+ EntryPtr pentSrcFirst, pentDstFirst;
+ EntryPtr pentSrc, pentDst;
+ Pixel *ppix;
+ int nalloc;
+
+ switch(channel)
+ {
+ default: /* so compiler can see that everything gets initialized */
+ case REDMAP:
+ ppix = (pmapSrc->clientPixelsRed)[client];
+ npix = (pmapSrc->numPixelsRed)[client];
+ pentSrcFirst = pmapSrc->red;
+ pentDstFirst = pmapDst->red;
+ break;
+ case GREENMAP:
+ ppix = (pmapSrc->clientPixelsGreen)[client];
+ npix = (pmapSrc->numPixelsGreen)[client];
+ pentSrcFirst = pmapSrc->green;
+ pentDstFirst = pmapDst->green;
+ break;
+ case BLUEMAP:
+ ppix = (pmapSrc->clientPixelsBlue)[client];
+ npix = (pmapSrc->numPixelsBlue)[client];
+ pentSrcFirst = pmapSrc->blue;
+ pentDstFirst = pmapDst->blue;
+ break;
+ }
+ nalloc = 0;
+ if (pmapSrc->class & DynamicClass)
+ {
+ for(z = npix; --z >= 0; ppix++)
+ {
+ /* Copy entries */
+ pentSrc = pentSrcFirst + *ppix;
+ pentDst = pentDstFirst + *ppix;
+ if (pentDst->refcnt > 0)
+ {
+ pentDst->refcnt++;
+ }
+ else
+ {
+ *pentDst = *pentSrc;
+ nalloc++;
+ if (pentSrc->refcnt > 0)
+ pentDst->refcnt = 1;
+ else
+ pentSrc->fShared = FALSE;
+ }
+ FreeCell(pmapSrc, *ppix, channel);
+ }
+ }
+
+ /* Note that FreeCell has already fixed pmapSrc->free{Color} */
+ switch(channel)
+ {
+ case REDMAP:
+ pmapDst->freeRed -= nalloc;
+ (pmapDst->clientPixelsRed)[client] =
+ (pmapSrc->clientPixelsRed)[client];
+ (pmapSrc->clientPixelsRed)[client] = (Pixel *) NULL;
+ (pmapDst->numPixelsRed)[client] = (pmapSrc->numPixelsRed)[client];
+ (pmapSrc->numPixelsRed)[client] = 0;
+ break;
+ case GREENMAP:
+ pmapDst->freeGreen -= nalloc;
+ (pmapDst->clientPixelsGreen)[client] =
+ (pmapSrc->clientPixelsGreen)[client];
+ (pmapSrc->clientPixelsGreen)[client] = (Pixel *) NULL;
+ (pmapDst->numPixelsGreen)[client] = (pmapSrc->numPixelsGreen)[client];
+ (pmapSrc->numPixelsGreen)[client] = 0;
+ break;
+ case BLUEMAP:
+ pmapDst->freeBlue -= nalloc;
+ pmapDst->clientPixelsBlue[client] = pmapSrc->clientPixelsBlue[client];
+ pmapSrc->clientPixelsBlue[client] = (Pixel *) NULL;
+ pmapDst->numPixelsBlue[client] = pmapSrc->numPixelsBlue[client];
+ pmapSrc->numPixelsBlue[client] = 0;
+ break;
+ }
+}
+
+/* Free the ith entry in a color map. Must handle freeing of
+ * colors allocated through AllocColorPlanes */
+static void
+FreeCell (ColormapPtr pmap, Pixel i, int channel)
+{
+ EntryPtr pent;
+ int *pCount;
+
+
+ switch (channel)
+ {
+ default: /* so compiler can see that everything gets initialized */
+ case PSEUDOMAP:
+ case REDMAP:
+ pent = (EntryPtr) &pmap->red[i];
+ pCount = &pmap->freeRed;
+ break;
+ case GREENMAP:
+ pent = (EntryPtr) &pmap->green[i];
+ pCount = &pmap->freeGreen;
+ break;
+ case BLUEMAP:
+ pent = (EntryPtr) &pmap->blue[i];
+ pCount = &pmap->freeBlue;
+ break;
+ }
+ /* If it's not privately allocated and it's not time to free it, just
+ * decrement the count */
+ if (pent->refcnt > 1)
+ pent->refcnt--;
+ else
+ {
+ /* If the color type is shared, find the sharedcolor. If decremented
+ * refcnt is 0, free the shared cell. */
+ if (pent->fShared)
+ {
+ if(--pent->co.shco.red->refcnt == 0)
+ xfree(pent->co.shco.red);
+ if(--pent->co.shco.green->refcnt == 0)
+ xfree(pent->co.shco.green);
+ if(--pent->co.shco.blue->refcnt == 0)
+ xfree(pent->co.shco.blue);
+ pent->fShared = FALSE;
+ }
+ pent->refcnt = 0;
+ *pCount += 1;
+ }
+}
+
+static void
+UpdateColors (ColormapPtr pmap)
+{
+ xColorItem *defs;
+ xColorItem *pdef;
+ EntryPtr pent;
+ VisualPtr pVisual;
+ int i, n, size;
+
+ pVisual = pmap->pVisual;
+ size = pVisual->ColormapEntries;
+ defs = xalloc(size * sizeof(xColorItem));
+ if (!defs)
+ return;
+ n = 0;
+ pdef = defs;
+ if (pmap->class == DirectColor)
+ {
+ for (i = 0; i < size; i++)
+ {
+ if (!pmap->red[i].refcnt &&
+ !pmap->green[i].refcnt &&
+ !pmap->blue[i].refcnt)
+ continue;
+ pdef->pixel = ((Pixel)i << pVisual->offsetRed) |
+ ((Pixel)i << pVisual->offsetGreen) |
+ ((Pixel)i << pVisual->offsetBlue);
+ pdef->red = pmap->red[i].co.local.red;
+ pdef->green = pmap->green[i].co.local.green;
+ pdef->blue = pmap->blue[i].co.local.blue;
+ pdef->flags = DoRed|DoGreen|DoBlue;
+ pdef++;
+ n++;
+ }
+ }
+ else
+ {
+ for (i = 0, pent = pmap->red; i < size; i++, pent++)
+ {
+ if (!pent->refcnt)
+ continue;
+ pdef->pixel = i;
+ if(pent->fShared)
+ {
+ pdef->red = pent->co.shco.red->color;
+ pdef->green = pent->co.shco.green->color;
+ pdef->blue = pent->co.shco.blue->color;
+ }
+ else
+ {
+ pdef->red = pent->co.local.red;
+ pdef->green = pent->co.local.green;
+ pdef->blue = pent->co.local.blue;
+ }
+ pdef->flags = DoRed|DoGreen|DoBlue;
+ pdef++;
+ n++;
+ }
+ }
+ if (n)
+ (*pmap->pScreen->StoreColors)(pmap, n, defs);
+ xfree(defs);
+}
+
+/* Get a read-only color from a ColorMap (probably slow for large maps)
+ * Returns by changing the value in pred, pgreen, pblue and pPix
+ */
+int
+AllocColor (ColormapPtr pmap,
+ unsigned short *pred, unsigned short *pgreen, unsigned short *pblue,
+ Pixel *pPix, int client)
+{
+ Pixel pixR, pixG, pixB;
+ int entries;
+ xrgb rgb;
+ int class;
+ VisualPtr pVisual;
+ int npix;
+ Pixel *ppix;
+
+ pVisual = pmap->pVisual;
+ (*pmap->pScreen->ResolveColor) (pred, pgreen, pblue, pVisual);
+ rgb.red = *pred;
+ rgb.green = *pgreen;
+ rgb.blue = *pblue;
+ class = pmap->class;
+ entries = pVisual->ColormapEntries;
+
+ /* If the colormap is being created, then we want to be able to change
+ * the colormap, even if it's a static type. Otherwise, we'd never be
+ * able to initialize static colormaps
+ */
+ if(pmap->flags & BeingCreated)
+ class |= DynamicClass;
+
+ /* If this is one of the static storage classes, and we're not initializing
+ * it, the best we can do is to find the closest color entry to the
+ * requested one and return that.
+ */
+ switch (class) {
+ case StaticColor:
+ case StaticGray:
+ /* Look up all three components in the same pmap */
+ *pPix = pixR = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
+ *pred = pmap->red[pixR].co.local.red;
+ *pgreen = pmap->red[pixR].co.local.green;
+ *pblue = pmap->red[pixR].co.local.blue;
+ npix = pmap->numPixelsRed[client];
+ ppix = (Pixel *) xrealloc(pmap->clientPixelsRed[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixR;
+ pmap->clientPixelsRed[client] = ppix;
+ pmap->numPixelsRed[client]++;
+ break;
+
+ case TrueColor:
+ /* Look up each component in its own map, then OR them together */
+ pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
+ pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
+ pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
+ *pPix = (pixR << pVisual->offsetRed) |
+ (pixG << pVisual->offsetGreen) |
+ (pixB << pVisual->offsetBlue) |
+ ALPHAMASK(pVisual);
+
+ *pred = pmap->red[pixR].co.local.red;
+ *pgreen = pmap->green[pixG].co.local.green;
+ *pblue = pmap->blue[pixB].co.local.blue;
+ npix = pmap->numPixelsRed[client];
+ ppix = (Pixel *) xrealloc(pmap->clientPixelsRed[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixR;
+ pmap->clientPixelsRed[client] = ppix;
+ npix = pmap->numPixelsGreen[client];
+ ppix = (Pixel *) xrealloc(pmap->clientPixelsGreen[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixG;
+ pmap->clientPixelsGreen[client] = ppix;
+ npix = pmap->numPixelsBlue[client];
+ ppix = (Pixel *) xrealloc(pmap->clientPixelsBlue[client],
+ (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ return (BadAlloc);
+ ppix[npix] = pixB;
+ pmap->clientPixelsBlue[client] = ppix;
+ pmap->numPixelsRed[client]++;
+ pmap->numPixelsGreen[client]++;
+ pmap->numPixelsBlue[client]++;
+ break;
+
+ case GrayScale:
+ case PseudoColor:
+ if (pmap->mid != pmap->pScreen->defColormap &&
+ pmap->pVisual->vid == pmap->pScreen->rootVisual)
+ {
+ ColormapPtr prootmap;
+ dixLookupResourceByType((pointer *)&prootmap, pmap->pScreen->defColormap,
+ RT_COLORMAP, clients[client], DixReadAccess);
+
+ if (pmap->class == prootmap->class)
+ FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb,
+ pPix, PSEUDOMAP, AllComp);
+ }
+ if (FindColor(pmap, pmap->red, entries, &rgb, pPix, PSEUDOMAP,
+ client, AllComp) != Success)
+ return (BadAlloc);
+ break;
+
+ case DirectColor:
+ if (pmap->mid != pmap->pScreen->defColormap &&
+ pmap->pVisual->vid == pmap->pScreen->rootVisual)
+ {
+ ColormapPtr prootmap;
+ dixLookupResourceByType((pointer *)&prootmap, pmap->pScreen->defColormap,
+ RT_COLORMAP, clients[client], DixReadAccess);
+
+ if (pmap->class == prootmap->class)
+ {
+ pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed;
+ FindColorInRootCmap (prootmap, prootmap->red, entries, &rgb,
+ &pixR, REDMAP, RedComp);
+ pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen;
+ FindColorInRootCmap (prootmap, prootmap->green, entries, &rgb,
+ &pixG, GREENMAP, GreenComp);
+ pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue;
+ FindColorInRootCmap (prootmap, prootmap->blue, entries, &rgb,
+ &pixB, BLUEMAP, BlueComp);
+ *pPix = pixR | pixG | pixB;
+ }
+ }
+
+ pixR = (*pPix & pVisual->redMask) >> pVisual->offsetRed;
+ if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
+ client, RedComp) != Success)
+ return (BadAlloc);
+ pixG = (*pPix & pVisual->greenMask) >> pVisual->offsetGreen;
+ if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
+ GREENMAP, client, GreenComp) != Success)
+ {
+ (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
+ return (BadAlloc);
+ }
+ pixB = (*pPix & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
+ client, BlueComp) != Success)
+ {
+ (void)FreeCo(pmap, client, GREENMAP, 1, &pixG, (Pixel)0);
+ (void)FreeCo(pmap, client, REDMAP, 1, &pixR, (Pixel)0);
+ return (BadAlloc);
+ }
+ *pPix = pixR | pixG | pixB | ALPHAMASK(pVisual);
+
+ break;
+ }
+
+ /* if this is the client's first pixel in this colormap, tell the
+ * resource manager that the client has pixels in this colormap which
+ * should be freed when the client dies */
+ if ((pmap->numPixelsRed[client] == 1) &&
+ (CLIENT_ID(pmap->mid) != client) &&
+ !(pmap->flags & BeingCreated))
+ {
+ colorResource *pcr;
+
+ pcr = xalloc(sizeof(colorResource));
+ if (!pcr)
+ {
+ (void)FreeColors(pmap, client, 1, pPix, (Pixel)0);
+ return (BadAlloc);
+ }
+ pcr->mid = pmap->mid;
+ pcr->client = client;
+ if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
+ return (BadAlloc);
+ }
+ return (Success);
+}
+
+/*
+ * FakeAllocColor -- fake an AllocColor request by
+ * returning a free pixel if availible, otherwise returning
+ * the closest matching pixel. This is used by the mi
+ * software sprite code to recolor cursors. A nice side-effect
+ * is that this routine will never return failure.
+ */
+
+void
+FakeAllocColor (ColormapPtr pmap, xColorItem *item)
+{
+ Pixel pixR, pixG, pixB;
+ Pixel temp;
+ int entries;
+ xrgb rgb;
+ int class;
+ VisualPtr pVisual;
+
+ pVisual = pmap->pVisual;
+ rgb.red = item->red;
+ rgb.green = item->green;
+ rgb.blue = item->blue;
+ (*pmap->pScreen->ResolveColor) (&rgb.red, &rgb.green, &rgb.blue, pVisual);
+ class = pmap->class;
+ entries = pVisual->ColormapEntries;
+
+ switch (class) {
+ case GrayScale:
+ case PseudoColor:
+ temp = 0;
+ item->pixel = 0;
+ if (FindColor(pmap, pmap->red, entries, &rgb, &temp, PSEUDOMAP,
+ -1, AllComp) == Success) {
+ item->pixel = temp;
+ break;
+ }
+ /* fall through ... */
+ case StaticColor:
+ case StaticGray:
+ item->pixel = FindBestPixel(pmap->red, entries, &rgb, PSEUDOMAP);
+ break;
+
+ case DirectColor:
+ /* Look up each component in its own map, then OR them together */
+ pixR = (item->pixel & pVisual->redMask) >> pVisual->offsetRed;
+ pixG = (item->pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ pixB = (item->pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (FindColor(pmap, pmap->red, NUMRED(pVisual), &rgb, &pixR, REDMAP,
+ -1, RedComp) != Success)
+ pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP)
+ << pVisual->offsetRed;
+ if (FindColor(pmap, pmap->green, NUMGREEN(pVisual), &rgb, &pixG,
+ GREENMAP, -1, GreenComp) != Success)
+ pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb,
+ GREENMAP) << pVisual->offsetGreen;
+ if (FindColor(pmap, pmap->blue, NUMBLUE(pVisual), &rgb, &pixB, BLUEMAP,
+ -1, BlueComp) != Success)
+ pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP)
+ << pVisual->offsetBlue;
+ item->pixel = pixR | pixG | pixB;
+ break;
+
+ case TrueColor:
+ /* Look up each component in its own map, then OR them together */
+ pixR = FindBestPixel(pmap->red, NUMRED(pVisual), &rgb, REDMAP);
+ pixG = FindBestPixel(pmap->green, NUMGREEN(pVisual), &rgb, GREENMAP);
+ pixB = FindBestPixel(pmap->blue, NUMBLUE(pVisual), &rgb, BLUEMAP);
+ item->pixel = (pixR << pVisual->offsetRed) |
+ (pixG << pVisual->offsetGreen) |
+ (pixB << pVisual->offsetBlue);
+ break;
+ }
+}
+
+/* free a pixel value obtained from FakeAllocColor */
+void
+FakeFreeColor(ColormapPtr pmap, Pixel pixel)
+{
+ VisualPtr pVisual;
+ Pixel pixR, pixG, pixB;
+
+ switch (pmap->class) {
+ case GrayScale:
+ case PseudoColor:
+ if (pmap->red[pixel].refcnt == AllocTemporary)
+ pmap->red[pixel].refcnt = 0;
+ break;
+ case DirectColor:
+ pVisual = pmap->pVisual;
+ pixR = (pixel & pVisual->redMask) >> pVisual->offsetRed;
+ pixG = (pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ pixB = (pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (pmap->red[pixR].refcnt == AllocTemporary)
+ pmap->red[pixR].refcnt = 0;
+ if (pmap->green[pixG].refcnt == AllocTemporary)
+ pmap->green[pixG].refcnt = 0;
+ if (pmap->blue[pixB].refcnt == AllocTemporary)
+ pmap->blue[pixB].refcnt = 0;
+ break;
+ }
+}
+
+typedef unsigned short BigNumUpper;
+typedef unsigned long BigNumLower;
+
+#define BIGNUMLOWERBITS 24
+#define BIGNUMUPPERBITS 16
+#define BIGNUMLOWER (1 << BIGNUMLOWERBITS)
+#define BIGNUMUPPER (1 << BIGNUMUPPERBITS)
+#define UPPERPART(i) ((i) >> BIGNUMLOWERBITS)
+#define LOWERPART(i) ((i) & (BIGNUMLOWER - 1))
+
+typedef struct _bignum {
+ BigNumUpper upper;
+ BigNumLower lower;
+} BigNumRec, *BigNumPtr;
+
+#define BigNumGreater(x,y) (((x)->upper > (y)->upper) ||\
+ ((x)->upper == (y)->upper && (x)->lower > (y)->lower))
+
+#define UnsignedToBigNum(u,r) (((r)->upper = UPPERPART(u)), \
+ ((r)->lower = LOWERPART(u)))
+
+#define MaxBigNum(r) (((r)->upper = BIGNUMUPPER-1), \
+ ((r)->lower = BIGNUMLOWER-1))
+
+static void
+BigNumAdd (BigNumPtr x, BigNumPtr y, BigNumPtr r)
+{
+ BigNumLower lower, carry = 0;
+
+ lower = x->lower + y->lower;
+ if (lower >= BIGNUMLOWER) {
+ lower -= BIGNUMLOWER;
+ carry = 1;
+ }
+ r->lower = lower;
+ r->upper = x->upper + y->upper + carry;
+}
+
+static Pixel
+FindBestPixel(EntryPtr pentFirst, int size, xrgb *prgb, int channel)
+{
+ EntryPtr pent;
+ Pixel pixel, final;
+ long dr, dg, db;
+ unsigned long sq;
+ BigNumRec minval, sum, temp;
+
+ final = 0;
+ MaxBigNum(&minval);
+ /* look for the minimal difference */
+ for (pent = pentFirst, pixel = 0; pixel < size; pent++, pixel++)
+ {
+ dr = dg = db = 0;
+ switch(channel)
+ {
+ case PSEUDOMAP:
+ dg = (long) pent->co.local.green - prgb->green;
+ db = (long) pent->co.local.blue - prgb->blue;
+ case REDMAP:
+ dr = (long) pent->co.local.red - prgb->red;
+ break;
+ case GREENMAP:
+ dg = (long) pent->co.local.green - prgb->green;
+ break;
+ case BLUEMAP:
+ db = (long) pent->co.local.blue - prgb->blue;
+ break;
+ }
+ sq = dr * dr;
+ UnsignedToBigNum (sq, &sum);
+ sq = dg * dg;
+ UnsignedToBigNum (sq, &temp);
+ BigNumAdd (&sum, &temp, &sum);
+ sq = db * db;
+ UnsignedToBigNum (sq, &temp);
+ BigNumAdd (&sum, &temp, &sum);
+ if (BigNumGreater (&minval, &sum))
+ {
+ final = pixel;
+ minval = sum;
+ }
+ }
+ return(final);
+}
+
+static void
+FindColorInRootCmap (ColormapPtr pmap, EntryPtr pentFirst, int size,
+ xrgb *prgb, Pixel *pPixel, int channel,
+ ColorCompareProcPtr comp)
+{
+ EntryPtr pent;
+ Pixel pixel;
+ int count;
+
+ if ((pixel = *pPixel) >= size)
+ pixel = 0;
+ for (pent = pentFirst + pixel, count = size; --count >= 0; pent++, pixel++)
+ {
+ if (pent->refcnt > 0 && (*comp) (pent, prgb))
+ {
+ switch (channel)
+ {
+ case REDMAP:
+ pixel <<= pmap->pVisual->offsetRed;
+ break;
+ case GREENMAP:
+ pixel <<= pmap->pVisual->offsetGreen;
+ break;
+ case BLUEMAP:
+ pixel <<= pmap->pVisual->offsetBlue;
+ break;
+ default: /* PSEUDOMAP */
+ break;
+ }
+ *pPixel = pixel;
+ }
+ }
+}
+
+/* Tries to find a color in pmap that exactly matches the one requested in prgb
+ * if it can't it allocates one.
+ * Starts looking at pentFirst + *pPixel, so if you want a specific pixel,
+ * load *pPixel with that value, otherwise set it to 0
+ */
+int
+FindColor (ColormapPtr pmap, EntryPtr pentFirst, int size, xrgb *prgb,
+ Pixel *pPixel, int channel, int client,
+ ColorCompareProcPtr comp)
+{
+ EntryPtr pent;
+ Bool foundFree;
+ Pixel pixel, Free = 0;
+ int npix, count, *nump = NULL;
+ Pixel **pixp = NULL, *ppix;
+ xColorItem def;
+
+ foundFree = FALSE;
+
+ if((pixel = *pPixel) >= size)
+ pixel = 0;
+ /* see if there is a match, and also look for a free entry */
+ for (pent = pentFirst + pixel, count = size; --count >= 0; )
+ {
+ if (pent->refcnt > 0)
+ {
+ if ((*comp) (pent, prgb))
+ {
+ if (client >= 0)
+ pent->refcnt++;
+ *pPixel = pixel;
+ switch(channel)
+ {
+ case REDMAP:
+ *pPixel <<= pmap->pVisual->offsetRed;
+ case PSEUDOMAP:
+ break;
+ case GREENMAP:
+ *pPixel <<= pmap->pVisual->offsetGreen;
+ break;
+ case BLUEMAP:
+ *pPixel <<= pmap->pVisual->offsetBlue;
+ break;
+ }
+ goto gotit;
+ }
+ }
+ else if (!foundFree && pent->refcnt == 0)
+ {
+ Free = pixel;
+ foundFree = TRUE;
+ /* If we're initializing the colormap, then we are looking for
+ * the first free cell we can find, not to minimize the number
+ * of entries we use. So don't look any further. */
+ if(pmap->flags & BeingCreated)
+ break;
+ }
+ pixel++;
+ if(pixel >= size)
+ {
+ pent = pentFirst;
+ pixel = 0;
+ }
+ else
+ pent++;
+ }
+
+ /* If we got here, we didn't find a match. If we also didn't find
+ * a free entry, we're out of luck. Otherwise, we'll usurp a free
+ * entry and fill it in */
+ if (!foundFree)
+ return (BadAlloc);
+ pent = pentFirst + Free;
+ pent->fShared = FALSE;
+ pent->refcnt = (client >= 0) ? 1 : AllocTemporary;
+
+ switch (channel)
+ {
+ case PSEUDOMAP:
+ pent->co.local.red = prgb->red;
+ pent->co.local.green = prgb->green;
+ pent->co.local.blue = prgb->blue;
+ def.red = prgb->red;
+ def.green = prgb->green;
+ def.blue = prgb->blue;
+ def.flags = (DoRed|DoGreen|DoBlue);
+ if (client >= 0)
+ pmap->freeRed--;
+ def.pixel = Free;
+ break;
+
+ case REDMAP:
+ pent->co.local.red = prgb->red;
+ def.red = prgb->red;
+ def.green = pmap->green[0].co.local.green;
+ def.blue = pmap->blue[0].co.local.blue;
+ def.flags = DoRed;
+ if (client >= 0)
+ pmap->freeRed--;
+ def.pixel = Free << pmap->pVisual->offsetRed;
+ break;
+
+ case GREENMAP:
+ pent->co.local.green = prgb->green;
+ def.red = pmap->red[0].co.local.red;
+ def.green = prgb->green;
+ def.blue = pmap->blue[0].co.local.blue;
+ def.flags = DoGreen;
+ if (client >= 0)
+ pmap->freeGreen--;
+ def.pixel = Free << pmap->pVisual->offsetGreen;
+ break;
+
+ case BLUEMAP:
+ pent->co.local.blue = prgb->blue;
+ def.red = pmap->red[0].co.local.red;
+ def.green = pmap->green[0].co.local.green;
+ def.blue = prgb->blue;
+ def.flags = DoBlue;
+ if (client >= 0)
+ pmap->freeBlue--;
+ def.pixel = Free << pmap->pVisual->offsetBlue;
+ break;
+ }
+ (*pmap->pScreen->StoreColors) (pmap, 1, &def);
+ pixel = Free;
+ *pPixel = def.pixel;
+
+gotit:
+ if (pmap->flags & BeingCreated || client == -1)
+ return(Success);
+ /* Now remember the pixel, for freeing later */
+ switch (channel)
+ {
+ case PSEUDOMAP:
+ case REDMAP:
+ nump = pmap->numPixelsRed;
+ pixp = pmap->clientPixelsRed;
+ break;
+
+ case GREENMAP:
+ nump = pmap->numPixelsGreen;
+ pixp = pmap->clientPixelsGreen;
+ break;
+
+ case BLUEMAP:
+ nump = pmap->numPixelsBlue;
+ pixp = pmap->clientPixelsBlue;
+ break;
+ }
+ npix = nump[client];
+ ppix = (Pixel *) xrealloc (pixp[client], (npix + 1) * sizeof(Pixel));
+ if (!ppix)
+ {
+ pent->refcnt--;
+ if (!pent->fShared)
+ switch (channel)
+ {
+ case PSEUDOMAP:
+ case REDMAP:
+ pmap->freeRed++;
+ break;
+ case GREENMAP:
+ pmap->freeGreen++;
+ break;
+ case BLUEMAP:
+ pmap->freeBlue++;
+ break;
+ }
+ return(BadAlloc);
+ }
+ ppix[npix] = pixel;
+ pixp[client] = ppix;
+ nump[client]++;
+
+ return(Success);
+}
+
+/* Comparison functions -- passed to FindColor to determine if an
+ * entry is already the color we're looking for or not */
+static int
+AllComp (EntryPtr pent, xrgb *prgb)
+{
+ if((pent->co.local.red == prgb->red) &&
+ (pent->co.local.green == prgb->green) &&
+ (pent->co.local.blue == prgb->blue) )
+ return (1);
+ return (0);
+}
+
+static int
+RedComp (EntryPtr pent, xrgb *prgb)
+{
+ if (pent->co.local.red == prgb->red)
+ return (1);
+ return (0);
+}
+
+static int
+GreenComp (EntryPtr pent, xrgb *prgb)
+{
+ if (pent->co.local.green == prgb->green)
+ return (1);
+ return (0);
+}
+
+static int
+BlueComp (EntryPtr pent, xrgb *prgb)
+{
+ if (pent->co.local.blue == prgb->blue)
+ return (1);
+ return (0);
+}
+
+
+/* Read the color value of a cell */
+
+int
+QueryColors (ColormapPtr pmap, int count, Pixel *ppixIn, xrgb *prgbList)
+{
+ Pixel *ppix, pixel;
+ xrgb *prgb;
+ VisualPtr pVisual;
+ EntryPtr pent;
+ Pixel i;
+ int errVal = Success;
+
+ pVisual = pmap->pVisual;
+ if ((pmap->class | DynamicClass) == DirectColor)
+ {
+ int numred, numgreen, numblue;
+ Pixel rgbbad;
+
+ numred = NUMRED(pVisual);
+ numgreen = NUMGREEN(pVisual);
+ numblue = NUMBLUE(pVisual);
+ rgbbad = ~RGBMASK(pVisual);
+ for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
+ {
+ pixel = *ppix;
+ if (pixel & rgbbad) {
+ clientErrorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ i = (pixel & pVisual->redMask) >> pVisual->offsetRed;
+ if (i >= numred)
+ {
+ clientErrorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ prgb->red = pmap->red[i].co.local.red;
+ i = (pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ if (i >= numgreen)
+ {
+ clientErrorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ prgb->green = pmap->green[i].co.local.green;
+ i = (pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (i >= numblue)
+ {
+ clientErrorValue = pixel;
+ errVal = BadValue;
+ continue;
+ }
+ prgb->blue = pmap->blue[i].co.local.blue;
+ }
+ }
+ else
+ {
+ for( ppix = ppixIn, prgb = prgbList; --count >= 0; ppix++, prgb++)
+ {
+ pixel = *ppix;
+ if (pixel >= pVisual->ColormapEntries)
+ {
+ clientErrorValue = pixel;
+ errVal = BadValue;
+ }
+ else
+ {
+ pent = (EntryPtr)&pmap->red[pixel];
+ if (pent->fShared)
+ {
+ prgb->red = pent->co.shco.red->color;
+ prgb->green = pent->co.shco.green->color;
+ prgb->blue = pent->co.shco.blue->color;
+ }
+ else
+ {
+ prgb->red = pent->co.local.red;
+ prgb->green = pent->co.local.green;
+ prgb->blue = pent->co.local.blue;
+ }
+ }
+ }
+ }
+ return (errVal);
+}
+
+static void
+FreePixels(ColormapPtr pmap, int client)
+{
+ Pixel *ppix, *ppixStart;
+ int n;
+ int class;
+
+ class = pmap->class;
+ ppixStart = pmap->clientPixelsRed[client];
+ if (class & DynamicClass)
+ {
+ n = pmap->numPixelsRed[client];
+ for (ppix = ppixStart; --n >= 0; )
+ {
+ FreeCell(pmap, *ppix, REDMAP);
+ ppix++;
+ }
+ }
+
+ xfree(ppixStart);
+ pmap->clientPixelsRed[client] = (Pixel *) NULL;
+ pmap->numPixelsRed[client] = 0;
+ if ((class | DynamicClass) == DirectColor)
+ {
+ ppixStart = pmap->clientPixelsGreen[client];
+ if (class & DynamicClass)
+ for (ppix = ppixStart, n = pmap->numPixelsGreen[client]; --n >= 0;)
+ FreeCell(pmap, *ppix++, GREENMAP);
+ xfree(ppixStart);
+ pmap->clientPixelsGreen[client] = (Pixel *) NULL;
+ pmap->numPixelsGreen[client] = 0;
+
+ ppixStart = pmap->clientPixelsBlue[client];
+ if (class & DynamicClass)
+ for (ppix = ppixStart, n = pmap->numPixelsBlue[client]; --n >= 0; )
+ FreeCell(pmap, *ppix++, BLUEMAP);
+ xfree(ppixStart);
+ pmap->clientPixelsBlue[client] = (Pixel *) NULL;
+ pmap->numPixelsBlue[client] = 0;
+ }
+}
+
+/**
+ * Frees all of a client's colors and cells.
+ *
+ * \param value must conform to DeleteType
+ * \unused fakeid
+ */
+int
+FreeClientPixels (pointer value, XID fakeid)
+{
+ pointer pmap;
+ colorResource *pcr = value;
+ int rc;
+
+ rc = dixLookupResourceByType(&pmap, pcr->mid, RT_COLORMAP, serverClient,
+ DixRemoveAccess);
+ if (rc == Success)
+ FreePixels((ColormapPtr)pmap, pcr->client);
+ xfree(pcr);
+ return Success;
+}
+
+int
+AllocColorCells (int client, ColormapPtr pmap, int colors, int planes,
+ Bool contig, Pixel *ppix, Pixel *masks)
+{
+ Pixel rmask, gmask, bmask, *ppixFirst, r, g, b;
+ int n, class;
+ int ok;
+ int oldcount;
+ colorResource *pcr = (colorResource *)NULL;
+
+ class = pmap->class;
+ if (!(class & DynamicClass))
+ return (BadAlloc); /* Shouldn't try on this type */
+ oldcount = pmap->numPixelsRed[client];
+ if (pmap->class == DirectColor)
+ oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
+ if (!oldcount && (CLIENT_ID(pmap->mid) != client))
+ {
+ pcr = xalloc(sizeof(colorResource));
+ if (!pcr)
+ return (BadAlloc);
+ }
+
+ if (pmap->class == DirectColor)
+ {
+ ok = AllocDirect (client, pmap, colors, planes, planes, planes,
+ contig, ppix, &rmask, &gmask, &bmask);
+ if(ok == Success)
+ {
+ for (r = g = b = 1, n = planes; --n >= 0; r += r, g += g, b += b)
+ {
+ while(!(rmask & r))
+ r += r;
+ while(!(gmask & g))
+ g += g;
+ while(!(bmask & b))
+ b += b;
+ *masks++ = r | g | b;
+ }
+ }
+ }
+ else
+ {
+ ok = AllocPseudo (client, pmap, colors, planes, contig, ppix, &rmask,
+ &ppixFirst);
+ if(ok == Success)
+ {
+ for (r = 1, n = planes; --n >= 0; r += r)
+ {
+ while(!(rmask & r))
+ r += r;
+ *masks++ = r;
+ }
+ }
+ }
+
+ /* if this is the client's first pixels in this colormap, tell the
+ * resource manager that the client has pixels in this colormap which
+ * should be freed when the client dies */
+ if ((ok == Success) && pcr)
+ {
+ pcr->mid = pmap->mid;
+ pcr->client = client;
+ if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
+ ok = BadAlloc;
+ } else if (pcr)
+ xfree(pcr);
+
+ return (ok);
+}
+
+
+int
+AllocColorPlanes (int client, ColormapPtr pmap, int colors,
+ int r, int g, int b, Bool contig, Pixel *pixels,
+ Pixel *prmask, Pixel *pgmask, Pixel *pbmask)
+{
+ int ok;
+ Pixel mask, *ppixFirst;
+ Pixel shift;
+ int i;
+ int class;
+ int oldcount;
+ colorResource *pcr = (colorResource *)NULL;
+
+ class = pmap->class;
+ if (!(class & DynamicClass))
+ return (BadAlloc); /* Shouldn't try on this type */
+ oldcount = pmap->numPixelsRed[client];
+ if (class == DirectColor)
+ oldcount += pmap->numPixelsGreen[client] + pmap->numPixelsBlue[client];
+ if (!oldcount && (CLIENT_ID(pmap->mid) != client))
+ {
+ pcr = xalloc(sizeof(colorResource));
+ if (!pcr)
+ return (BadAlloc);
+ }
+
+ if (class == DirectColor)
+ {
+ ok = AllocDirect (client, pmap, colors, r, g, b, contig, pixels,
+ prmask, pgmask, pbmask);
+ }
+ else
+ {
+ /* Allocate the proper pixels */
+ /* XXX This is sort of bad, because of contig is set, we force all
+ * r + g + b bits to be contiguous. Should only force contiguity
+ * per mask
+ */
+ ok = AllocPseudo (client, pmap, colors, r + g + b, contig, pixels,
+ &mask, &ppixFirst);
+
+ if(ok == Success)
+ {
+ /* now split that mask into three */
+ *prmask = *pgmask = *pbmask = 0;
+ shift = 1;
+ for (i = r; --i >= 0; shift += shift)
+ {
+ while (!(mask & shift))
+ shift += shift;
+ *prmask |= shift;
+ }
+ for (i = g; --i >= 0; shift += shift)
+ {
+ while (!(mask & shift))
+ shift += shift;
+ *pgmask |= shift;
+ }
+ for (i = b; --i >= 0; shift += shift)
+ {
+ while (!(mask & shift))
+ shift += shift;
+ *pbmask |= shift;
+ }
+
+ /* set up the shared color cells */
+ if (!AllocShared(pmap, pixels, colors, r, g, b,
+ *prmask, *pgmask, *pbmask, ppixFirst))
+ {
+ (void)FreeColors(pmap, client, colors, pixels, mask);
+ ok = BadAlloc;
+ }
+ }
+ }
+
+ /* if this is the client's first pixels in this colormap, tell the
+ * resource manager that the client has pixels in this colormap which
+ * should be freed when the client dies */
+ if ((ok == Success) && pcr)
+ {
+ pcr->mid = pmap->mid;
+ pcr->client = client;
+ if (!AddResource(FakeClientID(client), RT_CMAPENTRY, (pointer)pcr))
+ ok = BadAlloc;
+ } else if (pcr)
+ xfree(pcr);
+
+ return (ok);
+}
+
+static int
+AllocDirect (int client, ColormapPtr pmap, int c, int r, int g, int b, Bool contig,
+ Pixel *pixels, Pixel *prmask, Pixel *pgmask, Pixel *pbmask)
+{
+ Pixel *ppixRed, *ppixGreen, *ppixBlue;
+ Pixel *ppix, *pDst, *p;
+ int npix, npixR, npixG, npixB;
+ Bool okR, okG, okB;
+ Pixel *rpix = 0, *gpix = 0, *bpix = 0;
+
+ npixR = c << r;
+ npixG = c << g;
+ npixB = c << b;
+ if ((r >= 32) || (g >= 32) || (b >= 32) ||
+ (npixR > pmap->freeRed) || (npixR < c) ||
+ (npixG > pmap->freeGreen) || (npixG < c) ||
+ (npixB > pmap->freeBlue) || (npixB < c))
+ return BadAlloc;
+
+ /* start out with empty pixels */
+ for(p = pixels; p < pixels + c; p++)
+ *p = 0;
+
+ ppixRed = xalloc(npixR * sizeof(Pixel));
+ ppixGreen = xalloc(npixG * sizeof(Pixel));
+ ppixBlue = xalloc(npixB * sizeof(Pixel));
+ if (!ppixRed || !ppixGreen || !ppixBlue)
+ {
+ if (ppixBlue) xfree(ppixBlue);
+ if (ppixGreen) xfree(ppixGreen);
+ if (ppixRed) xfree(ppixRed);
+ return(BadAlloc);
+ }
+
+ okR = AllocCP(pmap, pmap->red, c, r, contig, ppixRed, prmask);
+ okG = AllocCP(pmap, pmap->green, c, g, contig, ppixGreen, pgmask);
+ okB = AllocCP(pmap, pmap->blue, c, b, contig, ppixBlue, pbmask);
+
+ if (okR && okG && okB)
+ {
+ rpix = (Pixel *) xrealloc(pmap->clientPixelsRed[client],
+ (pmap->numPixelsRed[client] + (c << r)) *
+ sizeof(Pixel));
+ if (rpix)
+ pmap->clientPixelsRed[client] = rpix;
+ gpix = (Pixel *) xrealloc(pmap->clientPixelsGreen[client],
+ (pmap->numPixelsGreen[client] + (c << g)) *
+ sizeof(Pixel));
+ if (gpix)
+ pmap->clientPixelsGreen[client] = gpix;
+ bpix = (Pixel *) xrealloc(pmap->clientPixelsBlue[client],
+ (pmap->numPixelsBlue[client] + (c << b)) *
+ sizeof(Pixel));
+ if (bpix)
+ pmap->clientPixelsBlue[client] = bpix;
+ }
+
+ if (!okR || !okG || !okB || !rpix || !gpix || !bpix)
+ {
+ if (okR)
+ for(ppix = ppixRed, npix = npixR; --npix >= 0; ppix++)
+ pmap->red[*ppix].refcnt = 0;
+ if (okG)
+ for(ppix = ppixGreen, npix = npixG; --npix >= 0; ppix++)
+ pmap->green[*ppix].refcnt = 0;
+ if (okB)
+ for(ppix = ppixBlue, npix = npixB; --npix >= 0; ppix++)
+ pmap->blue[*ppix].refcnt = 0;
+ xfree(ppixBlue);
+ xfree(ppixGreen);
+ xfree(ppixRed);
+ return(BadAlloc);
+ }
+
+ *prmask <<= pmap->pVisual->offsetRed;
+ *pgmask <<= pmap->pVisual->offsetGreen;
+ *pbmask <<= pmap->pVisual->offsetBlue;
+
+ ppix = rpix + pmap->numPixelsRed[client];
+ for (pDst = pixels, p = ppixRed; p < ppixRed + npixR; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixRed + c)
+ *pDst++ |= *p << pmap->pVisual->offsetRed;
+ }
+ pmap->numPixelsRed[client] += npixR;
+ pmap->freeRed -= npixR;
+
+ ppix = gpix + pmap->numPixelsGreen[client];
+ for (pDst = pixels, p = ppixGreen; p < ppixGreen + npixG; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixGreen + c)
+ *pDst++ |= *p << pmap->pVisual->offsetGreen;
+ }
+ pmap->numPixelsGreen[client] += npixG;
+ pmap->freeGreen -= npixG;
+
+ ppix = bpix + pmap->numPixelsBlue[client];
+ for (pDst = pixels, p = ppixBlue; p < ppixBlue + npixB; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixBlue + c)
+ *pDst++ |= *p << pmap->pVisual->offsetBlue;
+ }
+ pmap->numPixelsBlue[client] += npixB;
+ pmap->freeBlue -= npixB;
+
+
+ for (pDst = pixels; pDst < pixels + c; pDst++)
+ *pDst |= ALPHAMASK(pmap->pVisual);
+
+ xfree(ppixBlue);
+ xfree(ppixGreen);
+ xfree(ppixRed);
+
+ return (Success);
+}
+
+static int
+AllocPseudo (int client, ColormapPtr pmap, int c, int r, Bool contig,
+ Pixel *pixels, Pixel *pmask, Pixel **pppixFirst)
+{
+ Pixel *ppix, *p, *pDst, *ppixTemp;
+ int npix;
+ Bool ok;
+
+ npix = c << r;
+ if ((r >= 32) || (npix > pmap->freeRed) || (npix < c))
+ return(BadAlloc);
+ if(!(ppixTemp = xalloc(npix * sizeof(Pixel))))
+ return(BadAlloc);
+ ok = AllocCP(pmap, pmap->red, c, r, contig, ppixTemp, pmask);
+
+ if (ok)
+ {
+
+ /* all the allocated pixels are added to the client pixel list,
+ * but only the unique ones are returned to the client */
+ ppix = (Pixel *)xrealloc(pmap->clientPixelsRed[client],
+ (pmap->numPixelsRed[client] + npix) * sizeof(Pixel));
+ if (!ppix)
+ {
+ for (p = ppixTemp; p < ppixTemp + npix; p++)
+ pmap->red[*p].refcnt = 0;
+ return (BadAlloc);
+ }
+ pmap->clientPixelsRed[client] = ppix;
+ ppix += pmap->numPixelsRed[client];
+ *pppixFirst = ppix;
+ pDst = pixels;
+ for (p = ppixTemp; p < ppixTemp + npix; p++)
+ {
+ *ppix++ = *p;
+ if(p < ppixTemp + c)
+ *pDst++ = *p;
+ }
+ pmap->numPixelsRed[client] += npix;
+ pmap->freeRed -= npix;
+ }
+ xfree(ppixTemp);
+ return (ok ? Success : BadAlloc);
+}
+
+/* Allocates count << planes pixels from colormap pmap for client. If
+ * contig, then the plane mask is made of consecutive bits. Returns
+ * all count << pixels in the array pixels. The first count of those
+ * pixels are the unique pixels. *pMask has the mask to Or with the
+ * unique pixels to get the rest of them.
+ *
+ * Returns True iff all pixels could be allocated
+ * All cells allocated will have refcnt set to AllocPrivate and shared to FALSE
+ * (see AllocShared for why we care)
+ */
+static Bool
+AllocCP (ColormapPtr pmap, EntryPtr pentFirst, int count, int planes,
+ Bool contig, Pixel *pixels, Pixel *pMask)
+{
+ EntryPtr ent;
+ Pixel pixel, base, entries, maxp, save;
+ int dplanes, found;
+ Pixel *ppix;
+ Pixel mask;
+ Pixel finalmask;
+
+ dplanes = pmap->pVisual->nplanes;
+
+ /* Easy case. Allocate pixels only */
+ if (planes == 0)
+ {
+ /* allocate writable entries */
+ ppix = pixels;
+ ent = pentFirst;
+ pixel = 0;
+ while (--count >= 0)
+ {
+ /* Just find count unallocated cells */
+ while (ent->refcnt)
+ {
+ ent++;
+ pixel++;
+ }
+ ent->refcnt = AllocPrivate;
+ *ppix++ = pixel;
+ ent->fShared = FALSE;
+ }
+ *pMask = 0;
+ return (TRUE);
+ }
+ else if (planes > dplanes)
+ {
+ return (FALSE);
+ }
+
+ /* General case count pixels * 2 ^ planes cells to be allocated */
+
+ /* make room for new pixels */
+ ent = pentFirst;
+
+ /* first try for contiguous planes, since it's fastest */
+ for (mask = (((Pixel)1) << planes) - 1, base = 1, dplanes -= (planes - 1);
+ --dplanes >= 0;
+ mask += mask, base += base)
+ {
+ ppix = pixels;
+ found = 0;
+ pixel = 0;
+ entries = pmap->pVisual->ColormapEntries - mask;
+ while (pixel < entries)
+ {
+ save = pixel;
+ maxp = pixel + mask + base;
+ /* check if all are free */
+ while (pixel != maxp && ent[pixel].refcnt == 0)
+ pixel += base;
+ if (pixel == maxp)
+ {
+ /* this one works */
+ *ppix++ = save;
+ found++;
+ if (found == count)
+ {
+ /* found enough, allocate them all */
+ while (--count >= 0)
+ {
+ pixel = pixels[count];
+ maxp = pixel + mask;
+ while (1)
+ {
+ ent[pixel].refcnt = AllocPrivate;
+ ent[pixel].fShared = FALSE;
+ if (pixel == maxp)
+ break;
+ pixel += base;
+ *ppix++ = pixel;
+ }
+ }
+ *pMask = mask;
+ return (TRUE);
+ }
+ }
+ pixel = save + 1;
+ if (pixel & mask)
+ pixel += mask;
+ }
+ }
+
+ dplanes = pmap->pVisual->nplanes;
+ if (contig || planes == 1 || dplanes < 3)
+ return (FALSE);
+
+ /* this will be very slow for large maps, need a better algorithm */
+
+ /*
+ we can generate the smallest and largest numbers that fits in dplanes
+ bits and contain exactly planes bits set as follows. First, we need to
+ check that it is possible to generate such a mask at all.
+ (Non-contiguous masks need one more bit than contiguous masks). Then
+ the smallest such mask consists of the rightmost planes-1 bits set, then
+ a zero, then a one in position planes + 1. The formula is
+ (3 << (planes-1)) -1
+ The largest such masks consists of the leftmost planes-1 bits set, then
+ a zero, then a one bit in position dplanes-planes-1. If dplanes is
+ smaller than 32 (the number of bits in a word) then the formula is:
+ (1<<dplanes) - (1<<(dplanes-planes+1) + (1<<dplanes-planes-1)
+ If dplanes = 32, then we can't calculate (1<<dplanes) and we have
+ to use:
+ ( (1<<(planes-1)) - 1) << (dplanes-planes+1) + (1<<(dplanes-planes-1))
+
+ << Thank you, Loretta>>>
+
+ */
+
+ finalmask =
+ (((((Pixel)1)<<(planes-1)) - 1) << (dplanes-planes+1)) +
+ (((Pixel)1)<<(dplanes-planes-1));
+ for (mask = (((Pixel)3) << (planes -1)) - 1; mask <= finalmask; mask++)
+ {
+ /* next 3 magic statements count number of ones (HAKMEM #169) */
+ pixel = (mask >> 1) & 033333333333;
+ pixel = mask - pixel - ((pixel >> 1) & 033333333333);
+ if ((((pixel + (pixel >> 3)) & 030707070707) % 077) != planes)
+ continue;
+ ppix = pixels;
+ found = 0;
+ entries = pmap->pVisual->ColormapEntries - mask;
+ base = lowbit (mask);
+ for (pixel = 0; pixel < entries; pixel++)
+ {
+ if (pixel & mask)
+ continue;
+ maxp = 0;
+ /* check if all are free */
+ while (ent[pixel + maxp].refcnt == 0)
+ {
+ GetNextBitsOrBreak(maxp, mask, base);
+ }
+ if ((maxp < mask) || (ent[pixel + mask].refcnt != 0))
+ continue;
+ /* this one works */
+ *ppix++ = pixel;
+ found++;
+ if (found < count)
+ continue;
+ /* found enough, allocate them all */
+ while (--count >= 0)
+ {
+ pixel = (pixels)[count];
+ maxp = 0;
+ while (1)
+ {
+ ent[pixel + maxp].refcnt = AllocPrivate;
+ ent[pixel + maxp].fShared = FALSE;
+ GetNextBitsOrBreak(maxp, mask, base);
+ *ppix++ = pixel + maxp;
+ }
+ }
+
+ *pMask = mask;
+ return (TRUE);
+ }
+ }
+ return (FALSE);
+}
+
+/**
+ *
+ * \param ppixFirst First of the client's new pixels
+ */
+static Bool
+AllocShared (ColormapPtr pmap, Pixel *ppix, int c, int r, int g, int b,
+ Pixel rmask, Pixel gmask, Pixel bmask, Pixel *ppixFirst)
+{
+ Pixel *pptr, *cptr;
+ int npix, z, npixClientNew, npixShared;
+ Pixel basemask, base, bits, common;
+ SHAREDCOLOR *pshared, **ppshared, **psharedList;
+
+ npixClientNew = c << (r + g + b);
+ npixShared = (c << r) + (c << g) + (c << b);
+ psharedList = xalloc(npixShared * sizeof(SHAREDCOLOR *));
+ if (!psharedList)
+ return FALSE;
+ ppshared = psharedList;
+ for (z = npixShared; --z >= 0; )
+ {
+ if (!(ppshared[z] = xalloc(sizeof(SHAREDCOLOR))))
+ {
+ for (z++ ; z < npixShared; z++)
+ xfree(ppshared[z]);
+ return FALSE;
+ }
+ }
+ for(pptr = ppix, npix = c; --npix >= 0; pptr++)
+ {
+ basemask = ~(gmask | bmask);
+ common = *pptr & basemask;
+ if (rmask)
+ {
+ bits = 0;
+ base = lowbit (rmask);
+ while(1)
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == (common | bits))
+ {
+ pmap->red[*cptr].fShared = TRUE;
+ pmap->red[*cptr].co.shco.red = pshared;
+ }
+ }
+ GetNextBitsOrBreak(bits, rmask, base);
+ }
+ }
+ else
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == common)
+ {
+ pmap->red[*cptr].fShared = TRUE;
+ pmap->red[*cptr].co.shco.red = pshared;
+ }
+ }
+ }
+ basemask = ~(rmask | bmask);
+ common = *pptr & basemask;
+ if (gmask)
+ {
+ bits = 0;
+ base = lowbit (gmask);
+ while(1)
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (r + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == (common | bits))
+ {
+ pmap->red[*cptr].co.shco.green = pshared;
+ }
+ }
+ GetNextBitsOrBreak(bits, gmask, base);
+ }
+ }
+ else
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == common)
+ {
+ pmap->red[*cptr].co.shco.green = pshared;
+ }
+ }
+ }
+ basemask = ~(rmask | gmask);
+ common = *pptr & basemask;
+ if (bmask)
+ {
+ bits = 0;
+ base = lowbit (bmask);
+ while(1)
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (r + g);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == (common | bits))
+ {
+ pmap->red[*cptr].co.shco.blue = pshared;
+ }
+ }
+ GetNextBitsOrBreak(bits, bmask, base);
+ }
+ }
+ else
+ {
+ pshared = *ppshared++;
+ pshared->refcnt = 1 << (g + b);
+ for (cptr = ppixFirst, z = npixClientNew; --z >= 0; cptr++)
+ {
+ if ((*cptr & basemask) == common)
+ {
+ pmap->red[*cptr].co.shco.blue = pshared;
+ }
+ }
+ }
+ }
+ xfree(psharedList);
+ return TRUE;
+}
+
+
+/** FreeColors
+ * Free colors and/or cells (probably slow for large numbers)
+ */
+int
+FreeColors (ColormapPtr pmap, int client, int count, Pixel *pixels, Pixel mask)
+{
+ int rval, result, class;
+ Pixel rmask;
+
+ class = pmap->class;
+ if (pmap->flags & AllAllocated)
+ return(BadAccess);
+ if ((class | DynamicClass) == DirectColor)
+ {
+ rmask = mask & RGBMASK(pmap->pVisual);
+ result = FreeCo(pmap, client, REDMAP, count, pixels,
+ mask & pmap->pVisual->redMask);
+ /* If any of the three calls fails, we must report that, if more
+ * than one fails, it's ok that we report the last one */
+ rval = FreeCo(pmap, client, GREENMAP, count, pixels,
+ mask & pmap->pVisual->greenMask);
+ if(rval != Success)
+ result = rval;
+ rval = FreeCo(pmap, client, BLUEMAP, count, pixels,
+ mask & pmap->pVisual->blueMask);
+ if(rval != Success)
+ result = rval;
+ }
+ else
+ {
+ rmask = mask & ((((Pixel)1) << pmap->pVisual->nplanes) - 1);
+ result = FreeCo(pmap, client, PSEUDOMAP, count, pixels, rmask);
+ }
+ if ((mask != rmask) && count)
+ {
+ clientErrorValue = *pixels | mask;
+ result = BadValue;
+ }
+ /* XXX should worry about removing any RT_CMAPENTRY resource */
+ return (result);
+}
+
+/**
+ * Helper for FreeColors -- frees all combinations of *newpixels and mask bits
+ * which the client has allocated in channel colormap cells of pmap.
+ * doesn't change newpixels if it doesn't need to
+ *
+ * \param pmap which colormap head
+ * \param color which sub-map, eg, RED, BLUE, PSEUDO
+ * \param npixIn number of pixels passed in
+ * \param ppixIn number of base pixels
+ * \param mask mask client gave us
+ */
+static int
+FreeCo (ColormapPtr pmap, int client, int color, int npixIn, Pixel *ppixIn, Pixel mask)
+{
+ Pixel *ppixClient, pixTest;
+ int npixClient, npixNew, npix;
+ Pixel bits, base, cmask, rgbbad;
+ Pixel *pptr, *cptr;
+ int n, zapped;
+ int errVal = Success;
+ int offset, numents;
+
+ if (npixIn == 0)
+ return (errVal);
+ bits = 0;
+ zapped = 0;
+ base = lowbit (mask);
+
+ switch(color)
+ {
+ case REDMAP:
+ cmask = pmap->pVisual->redMask;
+ rgbbad = ~RGBMASK(pmap->pVisual);
+ offset = pmap->pVisual->offsetRed;
+ numents = (cmask >> offset) + 1;
+ ppixClient = pmap->clientPixelsRed[client];
+ npixClient = pmap->numPixelsRed[client];
+ break;
+ case GREENMAP:
+ cmask = pmap->pVisual->greenMask;
+ rgbbad = ~RGBMASK(pmap->pVisual);
+ offset = pmap->pVisual->offsetGreen;
+ numents = (cmask >> offset) + 1;
+ ppixClient = pmap->clientPixelsGreen[client];
+ npixClient = pmap->numPixelsGreen[client];
+ break;
+ case BLUEMAP:
+ cmask = pmap->pVisual->blueMask;
+ rgbbad = ~RGBMASK(pmap->pVisual);
+ offset = pmap->pVisual->offsetBlue;
+ numents = (cmask >> offset) + 1;
+ ppixClient = pmap->clientPixelsBlue[client];
+ npixClient = pmap->numPixelsBlue[client];
+ break;
+ default: /* so compiler can see that everything gets initialized */
+ case PSEUDOMAP:
+ cmask = ~((Pixel)0);
+ rgbbad = 0;
+ offset = 0;
+ numents = pmap->pVisual->ColormapEntries;
+ ppixClient = pmap->clientPixelsRed[client];
+ npixClient = pmap->numPixelsRed[client];
+ break;
+ }
+
+
+ /* zap all pixels which match */
+ while (1)
+ {
+ /* go through pixel list */
+ for (pptr = ppixIn, n = npixIn; --n >= 0; pptr++)
+ {
+ pixTest = ((*pptr | bits) & cmask) >> offset;
+ if ((pixTest >= numents) || (*pptr & rgbbad))
+ {
+ clientErrorValue = *pptr | bits;
+ errVal = BadValue;
+ continue;
+ }
+
+ /* find match in client list */
+ for (cptr = ppixClient, npix = npixClient;
+ --npix >= 0 && *cptr != pixTest;
+ cptr++) ;
+
+ if (npix >= 0)
+ {
+ if (pmap->class & DynamicClass)
+ {
+ FreeCell(pmap, pixTest, color);
+ }
+ *cptr = ~((Pixel)0);
+ zapped++;
+ }
+ else
+ errVal = BadAccess;
+ }
+ /* generate next bits value */
+ GetNextBitsOrBreak(bits, mask, base);
+ }
+
+ /* delete freed pixels from client pixel list */
+ if (zapped)
+ {
+ npixNew = npixClient - zapped;
+ if (npixNew)
+ {
+ /* Since the list can only get smaller, we can do a copy in
+ * place and then realloc to a smaller size */
+ pptr = cptr = ppixClient;
+
+ /* If we have all the new pixels, we don't have to examine the
+ * rest of the old ones */
+ for(npix = 0; npix < npixNew; cptr++)
+ {
+ if (*cptr != ~((Pixel)0))
+ {
+ *pptr++ = *cptr;
+ npix++;
+ }
+ }
+ pptr = (Pixel *)xrealloc(ppixClient, npixNew * sizeof(Pixel));
+ if (pptr)
+ ppixClient = pptr;
+ npixClient = npixNew;
+ }
+ else
+ {
+ npixClient = 0;
+ xfree(ppixClient);
+ ppixClient = (Pixel *)NULL;
+ }
+ switch(color)
+ {
+ case PSEUDOMAP:
+ case REDMAP:
+ pmap->clientPixelsRed[client] = ppixClient;
+ pmap->numPixelsRed[client] = npixClient;
+ break;
+ case GREENMAP:
+ pmap->clientPixelsGreen[client] = ppixClient;
+ pmap->numPixelsGreen[client] = npixClient;
+ break;
+ case BLUEMAP:
+ pmap->clientPixelsBlue[client] = ppixClient;
+ pmap->numPixelsBlue[client] = npixClient;
+ break;
+ }
+ }
+ return (errVal);
+}
+
+
+
+/* Redefine color values */
+int
+StoreColors (ColormapPtr pmap, int count, xColorItem *defs)
+{
+ Pixel pix;
+ xColorItem *pdef;
+ EntryPtr pent, pentT, pentLast;
+ VisualPtr pVisual;
+ SHAREDCOLOR *pred, *pgreen, *pblue;
+ int n, ChgRed, ChgGreen, ChgBlue, idef;
+ int class, errVal = Success;
+ int ok;
+
+
+ class = pmap->class;
+ if(!(class & DynamicClass) && !(pmap->flags & BeingCreated))
+ {
+ return(BadAccess);
+ }
+ pVisual = pmap->pVisual;
+
+ idef = 0;
+ if((class | DynamicClass) == DirectColor)
+ {
+ int numred, numgreen, numblue;
+ Pixel rgbbad;
+
+ numred = NUMRED(pVisual);
+ numgreen = NUMGREEN(pVisual);
+ numblue = NUMBLUE(pVisual);
+ rgbbad = ~RGBMASK(pVisual);
+ for (pdef = defs, n = 0; n < count; pdef++, n++)
+ {
+ ok = TRUE;
+ (*pmap->pScreen->ResolveColor)
+ (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
+
+ if (pdef->pixel & rgbbad)
+ {
+ errVal = BadValue;
+ clientErrorValue = pdef->pixel;
+ continue;
+ }
+ pix = (pdef->pixel & pVisual->redMask) >> pVisual->offsetRed;
+ if (pix >= numred)
+ {
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->red[pix].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+ else if (pdef->flags & DoRed)
+ {
+ pmap->red[pix].co.local.red = pdef->red;
+ }
+ else
+ {
+ pdef->red = pmap->red[pix].co.local.red;
+ }
+
+ pix = (pdef->pixel & pVisual->greenMask) >> pVisual->offsetGreen;
+ if (pix >= numgreen)
+ {
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->green[pix].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+ else if (pdef->flags & DoGreen)
+ {
+ pmap->green[pix].co.local.green = pdef->green;
+ }
+ else
+ {
+ pdef->green = pmap->green[pix].co.local.green;
+ }
+
+ pix = (pdef->pixel & pVisual->blueMask) >> pVisual->offsetBlue;
+ if (pix >= numblue)
+ {
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->blue[pix].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+ else if (pdef->flags & DoBlue)
+ {
+ pmap->blue[pix].co.local.blue = pdef->blue;
+ }
+ else
+ {
+ pdef->blue = pmap->blue[pix].co.local.blue;
+ }
+ /* If this is an o.k. entry, then it gets added to the list
+ * to be sent to the hardware. If not, skip it. Once we've
+ * skipped one, we have to copy all the others.
+ */
+ if(ok)
+ {
+ if(idef != n)
+ defs[idef] = defs[n];
+ idef++;
+ } else
+ clientErrorValue = pdef->pixel;
+ }
+ }
+ else
+ {
+ for (pdef = defs, n = 0; n < count; pdef++, n++)
+ {
+
+ ok = TRUE;
+ if (pdef->pixel >= pVisual->ColormapEntries)
+ {
+ clientErrorValue = pdef->pixel;
+ errVal = BadValue;
+ ok = FALSE;
+ }
+ else if (pmap->red[pdef->pixel].refcnt != AllocPrivate)
+ {
+ errVal = BadAccess;
+ ok = FALSE;
+ }
+
+ /* If this is an o.k. entry, then it gets added to the list
+ * to be sent to the hardware. If not, skip it. Once we've
+ * skipped one, we have to copy all the others.
+ */
+ if(ok)
+ {
+ if(idef != n)
+ defs[idef] = defs[n];
+ idef++;
+ }
+ else
+ continue;
+
+ (*pmap->pScreen->ResolveColor)
+ (&pdef->red, &pdef->green, &pdef->blue, pmap->pVisual);
+
+ pent = &pmap->red[pdef->pixel];
+
+ if(pdef->flags & DoRed)
+ {
+ if(pent->fShared)
+ {
+ pent->co.shco.red->color = pdef->red;
+ if (pent->co.shco.red->refcnt > 1)
+ ok = FALSE;
+ }
+ else
+ pent->co.local.red = pdef->red;
+ }
+ else
+ {
+ if(pent->fShared)
+ pdef->red = pent->co.shco.red->color;
+ else
+ pdef->red = pent->co.local.red;
+ }
+ if(pdef->flags & DoGreen)
+ {
+ if(pent->fShared)
+ {
+ pent->co.shco.green->color = pdef->green;
+ if (pent->co.shco.green->refcnt > 1)
+ ok = FALSE;
+ }
+ else
+ pent->co.local.green = pdef->green;
+ }
+ else
+ {
+ if(pent->fShared)
+ pdef->green = pent->co.shco.green->color;
+ else
+ pdef->green = pent->co.local.green;
+ }
+ if(pdef->flags & DoBlue)
+ {
+ if(pent->fShared)
+ {
+ pent->co.shco.blue->color = pdef->blue;
+ if (pent->co.shco.blue->refcnt > 1)
+ ok = FALSE;
+ }
+ else
+ pent->co.local.blue = pdef->blue;
+ }
+ else
+ {
+ if(pent->fShared)
+ pdef->blue = pent->co.shco.blue->color;
+ else
+ pdef->blue = pent->co.local.blue;
+ }
+
+ if(!ok)
+ {
+ /* have to run through the colormap and change anybody who
+ * shares this value */
+ pred = pent->co.shco.red;
+ pgreen = pent->co.shco.green;
+ pblue = pent->co.shco.blue;
+ ChgRed = pdef->flags & DoRed;
+ ChgGreen = pdef->flags & DoGreen;
+ ChgBlue = pdef->flags & DoBlue;
+ pentLast = pmap->red + pVisual->ColormapEntries;
+
+ for(pentT = pmap->red; pentT < pentLast; pentT++)
+ {
+ if(pentT->fShared && (pentT != pent))
+ {
+ xColorItem defChg;
+
+ /* There are, alas, devices in this world too dumb
+ * to read their own hardware colormaps. Sick, but
+ * true. So we're going to be really nice and load
+ * the xColorItem with the proper value for all the
+ * fields. We will only set the flags for those
+ * fields that actually change. Smart devices can
+ * arrange to change only those fields. Dumb devices
+ * can rest assured that we have provided for them,
+ * and can change all three fields */
+
+ defChg.flags = 0;
+ if(ChgRed && pentT->co.shco.red == pred)
+ {
+ defChg.flags |= DoRed;
+ }
+ if(ChgGreen && pentT->co.shco.green == pgreen)
+ {
+ defChg.flags |= DoGreen;
+ }
+ if(ChgBlue && pentT->co.shco.blue == pblue)
+ {
+ defChg.flags |= DoBlue;
+ }
+ if(defChg.flags != 0)
+ {
+ defChg.pixel = pentT - pmap->red;
+ defChg.red = pentT->co.shco.red->color;
+ defChg.green = pentT->co.shco.green->color;
+ defChg.blue = pentT->co.shco.blue->color;
+ (*pmap->pScreen->StoreColors) (pmap, 1, &defChg);
+ }
+ }
+ }
+
+ }
+ }
+ }
+ /* Note that we use idef, the count of acceptable entries, and not
+ * count, the count of proposed entries */
+ if (idef != 0)
+ ( *pmap->pScreen->StoreColors) (pmap, idef, defs);
+ return (errVal);
+}
+
+int
+IsMapInstalled(Colormap map, WindowPtr pWin)
+{
+ Colormap *pmaps;
+ int imap, nummaps, found;
+
+ pmaps = xalloc(pWin->drawable.pScreen->maxInstalledCmaps*sizeof(Colormap));
+ if(!pmaps)
+ return(FALSE);
+ nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+ (pWin->drawable.pScreen, pmaps);
+ found = FALSE;
+ for(imap = 0; imap < nummaps; imap++)
+ {
+ if(pmaps[imap] == map)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+ xfree(pmaps);
+ return (found);
+}
+
+struct colormap_lookup_data {
+ ScreenPtr pScreen;
+ VisualPtr visuals;
+};
+
+static void _colormap_find_resource(pointer value, XID id,
+ pointer cdata)
+{
+ struct colormap_lookup_data *cmap_data = cdata;
+ VisualPtr visuals = cmap_data->visuals;
+ ScreenPtr pScreen = cmap_data->pScreen;
+ ColormapPtr cmap = value;
+ int j;
+
+ if (pScreen != cmap->pScreen)
+ return;
+
+ j = cmap->pVisual - pScreen->visuals;
+ cmap->pVisual = &visuals[j];
+}
+
+/* something has realloced the visuals, instead of breaking
+ ABI fix it up here - glx and compsite did this wrong */
+Bool
+ResizeVisualArray(ScreenPtr pScreen, int new_visual_count,
+ DepthPtr depth)
+{
+ struct colormap_lookup_data cdata;
+ int numVisuals;
+ VisualPtr visuals;
+ XID *vids, vid;
+ int first_new_vid, first_new_visual, i;
+
+ first_new_vid = depth->numVids;
+ first_new_visual = pScreen->numVisuals;
+
+ vids = xrealloc(depth->vids, (depth->numVids + new_visual_count) * sizeof(XID));
+ if (!vids)
+ return FALSE;
+
+ /* its realloced now no going back if we fail the next one */
+ depth->vids = vids;
+
+ numVisuals = pScreen->numVisuals + new_visual_count;
+ visuals = xrealloc(pScreen->visuals, numVisuals * sizeof(VisualRec));
+ if (!visuals) {
+ return FALSE;
+ }
+
+ cdata.visuals = visuals;
+ cdata.pScreen = pScreen;
+ FindClientResourcesByType(serverClient, RT_COLORMAP, _colormap_find_resource, &cdata);
+
+ pScreen->visuals = visuals;
+
+ for (i = 0; i < new_visual_count; i++) {
+ vid = FakeClientID(0);
+ pScreen->visuals[first_new_visual + i].vid = vid;
+ vids[first_new_vid + i] = vid;
+ }
+
+ depth->numVids += new_visual_count;
+ pScreen->numVisuals += new_visual_count;
+
+ return TRUE;
+}
diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c index 982c808c7..b813136c7 100644 --- a/xorg-server/dix/dispatch.c +++ b/xorg-server/dix/dispatch.c @@ -1,4070 +1,4111 @@ -/************************************************************ - -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. - -********************************************************/ - -/* The panoramix components contained the following notice */ -/***************************************************************** - -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. - -******************************************************************/ - -/* XSERVER_DTRACE additions: - * Copyright 2005-2006 Sun Microsystems, 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 (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 <dix-config.h> -#include <version-config.h> -#endif - -#ifdef PANORAMIX_DEBUG -#include <stdio.h> -int ProcInitialConnection(); -#endif - -#include "windowstr.h" -#include <X11/fonts/fontstruct.h> -#include "dixfontstr.h" -#include "gcstruct.h" -#include "selection.h" -#include "colormapst.h" -#include "cursorstr.h" -#include "scrnintstr.h" -#include "opaque.h" -#include "input.h" -#include "servermd.h" -#include "extnsionst.h" -#include "dixfont.h" -#include "dispatch.h" -#include "swaprep.h" -#include "swapreq.h" -#include "privates.h" -#include "xace.h" -#include "inputstr.h" -#include "xkbsrv.h" -#include "site.h" - -#ifdef XSERVER_DTRACE -#include "registry.h" -#include <sys/types.h> -typedef const char *string; -#include "Xserver-dtrace.h" -#endif - -#define mskcnt ((MAXCLIENTS + 31) / 32) -#define BITMASK(i) (1U << ((i) & 31)) -#define MASKIDX(i) ((i) >> 5) -#define MASKWORD(buf, i) buf[MASKIDX(i)] -#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i) -#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i) -#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i)) - -xConnSetupPrefix connSetupPrefix; - -PaddingInfo PixmapWidthPaddingInfo[33]; - -static ClientPtr grabClient; -#define GrabNone 0 -#define GrabActive 1 -#define GrabKickout 2 -static int grabState = GrabNone; -static long grabWaiters[mskcnt]; -CallbackListPtr ServerGrabCallback = NULL; -HWEventQueuePtr checkForInput[2]; -int connBlockScreenStart; - -static void KillAllClients(void); - -static int nextFreeClientID; /* always MIN free client ID */ - -static int nClients; /* number of authorized clients */ - -CallbackListPtr ClientStateCallback; - -/* dispatchException & isItTimeToYield must be declared volatile since they - * are modified by signal handlers - otherwise optimizer may assume it doesn't - * need to actually check value in memory when used and may miss changes from - * signal handlers. - */ -volatile char dispatchException = 0; -volatile char isItTimeToYield; - -/* Various of the DIX function interfaces were not designed to allow - * the client->errorValue to be set on BadValue and other errors. - * Rather than changing interfaces and breaking untold code we introduce - * a new global that dispatch can use. - */ -XID clientErrorValue; /* XXX this is a kludge */ - -#define SAME_SCREENS(a, b) (\ - (a.pScreen == b.pScreen)) - -void -SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1) -{ - checkForInput[0] = c0; - checkForInput[1] = c1; -} - -void -UpdateCurrentTime(void) -{ - TimeStamp systime; - - /* To avoid time running backwards, we must call GetTimeInMillis before - * calling ProcessInputEvents. - */ - systime.months = currentTime.months; - systime.milliseconds = GetTimeInMillis(); - if (systime.milliseconds < currentTime.milliseconds) - systime.months++; - if (*checkForInput[0] != *checkForInput[1]) - ProcessInputEvents(); - if (CompareTimeStamps(systime, currentTime) == LATER) - currentTime = systime; -} - -/* Like UpdateCurrentTime, but can't call ProcessInputEvents */ -void -UpdateCurrentTimeIf(void) -{ - TimeStamp systime; - - systime.months = currentTime.months; - systime.milliseconds = GetTimeInMillis(); - if (systime.milliseconds < currentTime.milliseconds) - systime.months++; - if (*checkForInput[0] == *checkForInput[1]) - currentTime = systime; -} - - -#undef SMART_DEBUG - -#define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */ -#define SMART_SCHEDULE_MAX_SLICE 200 /* ms */ - -Bool SmartScheduleDisable = FALSE; -long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL; -long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL; -long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE; -long SmartScheduleTime; -int SmartScheduleLatencyLimited = 0; -static ClientPtr SmartLastClient; -static int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1]; - -#ifdef SMART_DEBUG -long SmartLastPrint; -#endif - -void Dispatch(void); -void InitProcVectors(void); - -static int -SmartScheduleClient (int *clientReady, int nready) -{ - ClientPtr pClient; - int i; - int client; - int bestPrio, best = 0; - int bestRobin, robin; - long now = SmartScheduleTime; - long idle; - - bestPrio = -0x7fffffff; - bestRobin = 0; - idle = 2 * SmartScheduleSlice; - for (i = 0; i < nready; i++) - { - client = clientReady[i]; - pClient = clients[client]; - /* Praise clients which are idle */ - if ((now - pClient->smart_check_tick) >= idle) - { - if (pClient->smart_priority < 0) - pClient->smart_priority++; - } - pClient->smart_check_tick = now; - - /* check priority to select best client */ - robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff; - if (pClient->smart_priority > bestPrio || - (pClient->smart_priority == bestPrio && robin > bestRobin)) - { - bestPrio = pClient->smart_priority; - bestRobin = robin; - best = client; - } -#ifdef SMART_DEBUG - if ((now - SmartLastPrint) >= 5000) - fprintf (stderr, " %2d: %3d", client, pClient->smart_priority); -#endif - } -#ifdef SMART_DEBUG - if ((now - SmartLastPrint) >= 5000) - { - fprintf (stderr, " use %2d\n", best); - SmartLastPrint = now; - } -#endif - pClient = clients[best]; - SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index; - /* - * Set current client pointer - */ - if (SmartLastClient != pClient) - { - pClient->smart_start_tick = now; - SmartLastClient = pClient; - } - /* - * Adjust slice - */ - if (nready == 1 && SmartScheduleLatencyLimited == 0) - { - /* - * If it's been a long time since another client - * has run, bump the slice up to get maximal - * performance from a single client - */ - if ((now - pClient->smart_start_tick) > 1000 && - SmartScheduleSlice < SmartScheduleMaxSlice) - { - SmartScheduleSlice += SmartScheduleInterval; - } - } - else - { - SmartScheduleSlice = SmartScheduleInterval; - } - return best; -} - -void -EnableLimitedSchedulingLatency(void) -{ - ++SmartScheduleLatencyLimited; - SmartScheduleSlice = SmartScheduleInterval; -} - -void -DisableLimitedSchedulingLatency(void) -{ - --SmartScheduleLatencyLimited; - - /* protect against bugs */ - if (SmartScheduleLatencyLimited < 0) - SmartScheduleLatencyLimited = 0; -} - -#define MAJOROP ((xReq *)client->requestBuffer)->reqType - -void -Dispatch(void) -{ - int *clientReady; /* array of request ready clients */ - int result; - ClientPtr client; - int nready; - HWEventQueuePtr* icheck = checkForInput; - long start_tick; - - nextFreeClientID = 1; - nClients = 0; - - clientReady = xalloc(sizeof(int) * MaxClients); - if (!clientReady) - return; - - SmartScheduleSlice = SmartScheduleInterval; - while (!dispatchException) - { - if (*icheck[0] != *icheck[1]) - { - ProcessInputEvents(); - FlushIfCriticalOutputPending(); - } - - nready = WaitForSomething(clientReady); - - if (nready && !SmartScheduleDisable) - { - clientReady[0] = SmartScheduleClient (clientReady, nready); - nready = 1; - } - /***************** - * Handle events in round robin fashion, doing input between - * each round - *****************/ - - while (!dispatchException && (--nready >= 0)) - { - client = clients[clientReady[nready]]; - if (! client) - { - /* KillClient can cause this to happen */ - continue; - } - /* GrabServer activation can cause this to be true */ - if (grabState == GrabKickout) - { - grabState = GrabActive; - break; - } - isItTimeToYield = FALSE; - - start_tick = SmartScheduleTime; - while (!isItTimeToYield) - { - if (*icheck[0] != *icheck[1]) - ProcessInputEvents(); - - FlushIfCriticalOutputPending(); - if (!SmartScheduleDisable && - (SmartScheduleTime - start_tick) >= SmartScheduleSlice) - { - /* Penalize clients which consume ticks */ - if (client->smart_priority > SMART_MIN_PRIORITY) - client->smart_priority--; - break; - } - /* now, finally, deal with client requests */ - - result = ReadRequestFromClient(client); - if (result <= 0) - { - if (result < 0) - CloseDownClient(client); - break; - } - - client->sequence++; -#ifdef XSERVER_DTRACE - XSERVER_REQUEST_START(LookupMajorName(MAJOROP), MAJOROP, - ((xReq *)client->requestBuffer)->length, - client->index, client->requestBuffer); -#endif - if (result > (maxBigRequestSize << 2)) - result = BadLength; - else { - result = XaceHookDispatch(client, MAJOROP); - if (result == Success) - result = (* client->requestVector[MAJOROP])(client); - XaceHookAuditEnd(client, result); - } -#ifdef XSERVER_DTRACE - XSERVER_REQUEST_DONE(LookupMajorName(MAJOROP), MAJOROP, - client->sequence, client->index, result); -#endif - - if (result != Success) - { - if (client->noClientException != Success) - CloseDownClient(client); - else - SendErrorToClient(client, MAJOROP, - MinorOpcodeOfRequest(client), - client->errorValue, result); - break; - } - } - FlushAllOutput(); - client = clients[clientReady[nready]]; - if (client) - client->smart_stop_tick = SmartScheduleTime; - } - dispatchException &= ~DE_PRIORITYCHANGE; - } -#if defined(DDXBEFORERESET) - ddxBeforeReset (); -#endif - KillAllClients(); - xfree(clientReady); - dispatchException &= ~DE_RESET; - SmartScheduleLatencyLimited = 0; -} - -#undef MAJOROP - -static int VendorRelease = VENDOR_RELEASE; -static char *VendorString = VENDOR_NAME; - -static const int padlength[4] = {0, 3, 2, 1}; - -void -SetVendorRelease(int release) -{ - VendorRelease = release; -} - -void -SetVendorString(char *string) -{ - VendorString = string; -} - -Bool -CreateConnectionBlock(void) -{ - xConnSetup setup; - xWindowRoot root; - xDepth depth; - xVisualType visual; - xPixmapFormat format; - unsigned long vid; - int i, j, k, - lenofblock, - sizesofar = 0; - char *pBuf; - - - memset(&setup, 0, sizeof(xConnSetup)); - /* Leave off the ridBase and ridMask, these must be sent with - connection */ - - setup.release = VendorRelease; - /* - * per-server image and bitmap parameters are defined in Xmd.h - */ - setup.imageByteOrder = screenInfo.imageByteOrder; - - setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit; - setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad; - - setup.bitmapBitOrder = screenInfo.bitmapBitOrder; - setup.motionBufferSize = NumMotionEvents(); - setup.numRoots = screenInfo.numScreens; - setup.nbytesVendor = strlen(VendorString); - setup.numFormats = screenInfo.numPixmapFormats; - setup.maxRequestSize = MAX_REQUEST_SIZE; - QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode); - - lenofblock = sizeof(xConnSetup) + - pad_to_int32(setup.nbytesVendor) + - (setup.numFormats * sizeof(xPixmapFormat)) + - (setup.numRoots * sizeof(xWindowRoot)); - ConnectionInfo = xalloc(lenofblock); - if (!ConnectionInfo) - return FALSE; - - memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup)); - sizesofar = sizeof(xConnSetup); - pBuf = ConnectionInfo + sizeof(xConnSetup); - - memmove(pBuf, VendorString, (int)setup.nbytesVendor); - sizesofar += setup.nbytesVendor; - pBuf += setup.nbytesVendor; - i = padlength[setup.nbytesVendor & 3]; - sizesofar += i; - while (--i >= 0) - *pBuf++ = 0; - - memset(&format, 0, sizeof(xPixmapFormat)); - for (i=0; i<screenInfo.numPixmapFormats; i++) - { - format.depth = screenInfo.formats[i].depth; - format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel; - format.scanLinePad = screenInfo.formats[i].scanlinePad; - memmove(pBuf, (char *)&format, sizeof(xPixmapFormat)); - pBuf += sizeof(xPixmapFormat); - sizesofar += sizeof(xPixmapFormat); - } - - connBlockScreenStart = sizesofar; - memset(&depth, 0, sizeof(xDepth)); - memset(&visual, 0, sizeof(xVisualType)); - for (i=0; i<screenInfo.numScreens; i++) - { - ScreenPtr pScreen; - DepthPtr pDepth; - VisualPtr pVisual; - - pScreen = screenInfo.screens[i]; - root.windowId = WindowTable[i]->drawable.id; - root.defaultColormap = pScreen->defColormap; - root.whitePixel = pScreen->whitePixel; - root.blackPixel = pScreen->blackPixel; - root.currentInputMask = 0; /* filled in when sent */ - root.pixWidth = pScreen->width; - root.pixHeight = pScreen->height; - root.mmWidth = pScreen->mmWidth; - root.mmHeight = pScreen->mmHeight; - root.minInstalledMaps = pScreen->minInstalledCmaps; - root.maxInstalledMaps = pScreen->maxInstalledCmaps; - root.rootVisualID = pScreen->rootVisual; - root.backingStore = pScreen->backingStoreSupport; - root.saveUnders = FALSE; - root.rootDepth = pScreen->rootDepth; - root.nDepths = pScreen->numDepths; - memmove(pBuf, (char *)&root, sizeof(xWindowRoot)); - sizesofar += sizeof(xWindowRoot); - pBuf += sizeof(xWindowRoot); - - pDepth = pScreen->allowedDepths; - for(j = 0; j < pScreen->numDepths; j++, pDepth++) - { - lenofblock += sizeof(xDepth) + - (pDepth->numVids * sizeof(xVisualType)); - pBuf = (char *)xrealloc(ConnectionInfo, lenofblock); - if (!pBuf) - { - xfree(ConnectionInfo); - return FALSE; - } - ConnectionInfo = pBuf; - pBuf += sizesofar; - depth.depth = pDepth->depth; - depth.nVisuals = pDepth->numVids; - memmove(pBuf, (char *)&depth, sizeof(xDepth)); - pBuf += sizeof(xDepth); - sizesofar += sizeof(xDepth); - for(k = 0; k < pDepth->numVids; k++) - { - vid = pDepth->vids[k]; - for (pVisual = pScreen->visuals; - pVisual->vid != vid; - pVisual++) - ; - visual.visualID = vid; - visual.class = pVisual->class; - visual.bitsPerRGB = pVisual->bitsPerRGBValue; - visual.colormapEntries = pVisual->ColormapEntries; - visual.redMask = pVisual->redMask; - visual.greenMask = pVisual->greenMask; - visual.blueMask = pVisual->blueMask; - memmove(pBuf, (char *)&visual, sizeof(xVisualType)); - pBuf += sizeof(xVisualType); - sizesofar += sizeof(xVisualType); - } - } - } - connSetupPrefix.success = xTrue; - connSetupPrefix.length = lenofblock/4; - connSetupPrefix.majorVersion = X_PROTOCOL; - connSetupPrefix.minorVersion = X_PROTOCOL_REVISION; - return TRUE; -} - - -int -ProcBadRequest(ClientPtr client) -{ - return (BadRequest); -} - -int -ProcCreateWindow(ClientPtr client) -{ - WindowPtr pParent, pWin; - REQUEST(xCreateWindowReq); - int len, rc; - - REQUEST_AT_LEAST_SIZE(xCreateWindowReq); - - LEGAL_NEW_RESOURCE(stuff->wid, client); - rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess); - if (rc != Success) - return rc; - len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq)); - if (Ones(stuff->mask) != len) - return BadLength; - if (!stuff->width || !stuff->height) - { - client->errorValue = 0; - return BadValue; - } - pWin = CreateWindow(stuff->wid, pParent, stuff->x, - stuff->y, stuff->width, stuff->height, - stuff->borderWidth, stuff->class, - stuff->mask, (XID *) &stuff[1], - (int)stuff->depth, - client, stuff->visual, &rc); - if (pWin) - { - Mask mask = pWin->eventMask; - - pWin->eventMask = 0; /* subterfuge in case AddResource fails */ - if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin)) - return BadAlloc; - pWin->eventMask = mask; - } - if (client->noClientException != Success) - return(client->noClientException); - else - return rc; -} - -int -ProcChangeWindowAttributes(ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xChangeWindowAttributesReq); - int result, len, rc; - Mask access_mode = 0; - - REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq); - access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0; - access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0; - rc = dixLookupWindow(&pWin, stuff->window, client, access_mode); - if (rc != Success) - return rc; - len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq)); - if (len != Ones(stuff->valueMask)) - return BadLength; - result = ChangeWindowAttributes(pWin, - stuff->valueMask, - (XID *) &stuff[1], - client); - if (client->noClientException != Success) - return(client->noClientException); - else - return(result); -} - -int -ProcGetWindowAttributes(ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xResourceReq); - xGetWindowAttributesReply wa; - int rc; - - REQUEST_SIZE_MATCH(xResourceReq); - rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); - if (rc != Success) - return rc; - memset(&wa, 0, sizeof(xGetWindowAttributesReply)); - GetWindowAttributes(pWin, client, &wa); - WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa); - return(client->noClientException); -} - -int -ProcDestroyWindow(ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xResourceReq); - int rc; - - REQUEST_SIZE_MATCH(xResourceReq); - rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess); - if (rc != Success) - return rc; - if (pWin->parent) { - rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client, - DixRemoveAccess); - if (rc != Success) - return rc; - FreeResource(stuff->id, RT_NONE); - } - return(client->noClientException); -} - -int -ProcDestroySubwindows(ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xResourceReq); - int rc; - - REQUEST_SIZE_MATCH(xResourceReq); - rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess); - if (rc != Success) - return rc; - DestroySubwindows(pWin, client); - return(client->noClientException); -} - -int -ProcChangeSaveSet(ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xChangeSaveSetReq); - int result, rc; - - REQUEST_SIZE_MATCH(xChangeSaveSetReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); - if (rc != Success) - return rc; - if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id))) - return BadMatch; - if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete)) - { - result = AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE); - if (client->noClientException != Success) - return(client->noClientException); - else - return(result); - } - else - { - client->errorValue = stuff->mode; - return( BadValue ); - } -} - -int -ProcReparentWindow(ClientPtr client) -{ - WindowPtr pWin, pParent; - REQUEST(xReparentWindowReq); - int result, rc; - - REQUEST_SIZE_MATCH(xReparentWindowReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); - if (rc != Success) - return rc; - rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess); - if (rc != Success) - return rc; - if (SAME_SCREENS(pWin->drawable, pParent->drawable)) - { - if ((pWin->backgroundState == ParentRelative) && - (pParent->drawable.depth != pWin->drawable.depth)) - return BadMatch; - if ((pWin->drawable.class != InputOnly) && - (pParent->drawable.class == InputOnly)) - return BadMatch; - result = ReparentWindow(pWin, pParent, - (short)stuff->x, (short)stuff->y, client); - if (client->noClientException != Success) - return(client->noClientException); - else - return(result); - } - else - return (BadMatch); -} - -int -ProcMapWindow(ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xResourceReq); - int rc; - - REQUEST_SIZE_MATCH(xResourceReq); - rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess); - if (rc != Success) - return rc; - MapWindow(pWin, client); - /* update cache to say it is mapped */ - return(client->noClientException); -} - -int -ProcMapSubwindows(ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xResourceReq); - int rc; - - REQUEST_SIZE_MATCH(xResourceReq); - rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); - if (rc != Success) - return rc; - MapSubwindows(pWin, client); - /* update cache to say it is mapped */ - return(client->noClientException); -} - -int -ProcUnmapWindow(ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xResourceReq); - int rc; - - REQUEST_SIZE_MATCH(xResourceReq); - rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess); - if (rc != Success) - return rc; - UnmapWindow(pWin, FALSE); - /* update cache to say it is mapped */ - return(client->noClientException); -} - -int -ProcUnmapSubwindows(ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xResourceReq); - int rc; - - REQUEST_SIZE_MATCH(xResourceReq); - rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); - if (rc != Success) - return rc; - UnmapSubwindows(pWin); - return(client->noClientException); -} - -int -ProcConfigureWindow(ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xConfigureWindowReq); - int result; - int len, rc; - - REQUEST_AT_LEAST_SIZE(xConfigureWindowReq); - rc = dixLookupWindow(&pWin, stuff->window, client, - DixManageAccess|DixSetAttrAccess); - if (rc != Success) - return rc; - len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq)); - if (Ones((Mask)stuff->mask) != len) - return BadLength; - result = ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], - client); - if (client->noClientException != Success) - return(client->noClientException); - else - return(result); -} - -int -ProcCirculateWindow(ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xCirculateWindowReq); - int rc; - - REQUEST_SIZE_MATCH(xCirculateWindowReq); - if ((stuff->direction != RaiseLowest) && - (stuff->direction != LowerHighest)) - { - client->errorValue = stuff->direction; - return BadValue; - } - rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); - if (rc != Success) - return rc; - CirculateWindow(pWin, (int)stuff->direction, client); - return(client->noClientException); -} - -static int -GetGeometry(ClientPtr client, xGetGeometryReply *rep) -{ - DrawablePtr pDraw; - int rc; - REQUEST(xResourceReq); - REQUEST_SIZE_MATCH(xResourceReq); - - rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess); - if (rc != Success) - return rc; - - rep->type = X_Reply; - rep->length = 0; - rep->sequenceNumber = client->sequence; - rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id; - rep->depth = pDraw->depth; - rep->width = pDraw->width; - rep->height = pDraw->height; - - /* XXX - Because the pixmap-implementation of the multibuffer extension - * may have the buffer-id's drawable resource value be a pointer - * to the buffer's window instead of the buffer itself - * (this happens if the buffer is the displayed buffer), - * we also have to check that the id matches before we can - * truly say that it is a DRAWABLE_WINDOW. - */ - - if ((pDraw->type == UNDRAWABLE_WINDOW) || - ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id))) - { - WindowPtr pWin = (WindowPtr)pDraw; - rep->x = pWin->origin.x - wBorderWidth (pWin); - rep->y = pWin->origin.y - wBorderWidth (pWin); - rep->borderWidth = pWin->borderWidth; - } - else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */ - { - rep->x = rep->y = rep->borderWidth = 0; - } - - return Success; -} - - -int -ProcGetGeometry(ClientPtr client) -{ - xGetGeometryReply rep; - int status; - - memset(&rep, 0, sizeof(xGetGeometryReply)); - if ((status = GetGeometry(client, &rep)) != Success) - return status; - - WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep); - return(client->noClientException); -} - - -int -ProcQueryTree(ClientPtr client) -{ - xQueryTreeReply reply; - int rc, numChildren = 0; - WindowPtr pChild, pWin, pHead; - Window *childIDs = (Window *)NULL; - REQUEST(xResourceReq); - - REQUEST_SIZE_MATCH(xResourceReq); - rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); - if (rc != Success) - return rc; - memset(&reply, 0, sizeof(xQueryTreeReply)); - reply.type = X_Reply; - reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; - reply.sequenceNumber = client->sequence; - if (pWin->parent) - reply.parent = pWin->parent->drawable.id; - else - reply.parent = (Window)None; - pHead = RealChildHead(pWin); - for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) - numChildren++; - if (numChildren) - { - int curChild = 0; - - childIDs = xalloc(numChildren * sizeof(Window)); - if (!childIDs) - return BadAlloc; - for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) - childIDs[curChild++] = pChild->drawable.id; - } - - reply.nChildren = numChildren; - reply.length = bytes_to_int32(numChildren * sizeof(Window)); - - WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply); - if (numChildren) - { - client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; - WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs); - xfree(childIDs); - } - - return(client->noClientException); -} - -int -ProcInternAtom(ClientPtr client) -{ - Atom atom; - char *tchar; - REQUEST(xInternAtomReq); - - REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes); - if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse)) - { - client->errorValue = stuff->onlyIfExists; - return(BadValue); - } - tchar = (char *) &stuff[1]; - atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists); - if (atom != BAD_RESOURCE) - { - xInternAtomReply reply; - memset(&reply, 0, sizeof(xInternAtomReply)); - reply.type = X_Reply; - reply.length = 0; - reply.sequenceNumber = client->sequence; - reply.atom = atom; - WriteReplyToClient(client, sizeof(xInternAtomReply), &reply); - return(client->noClientException); - } - else - return (BadAlloc); -} - -int -ProcGetAtomName(ClientPtr client) -{ - const char *str; - xGetAtomNameReply reply; - int len; - REQUEST(xResourceReq); - - REQUEST_SIZE_MATCH(xResourceReq); - if ( (str = NameForAtom(stuff->id)) ) - { - len = strlen(str); - memset(&reply, 0, sizeof(xGetAtomNameReply)); - reply.type = X_Reply; - reply.length = bytes_to_int32(len); - reply.sequenceNumber = client->sequence; - reply.nameLength = len; - WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply); - (void)WriteToClient(client, len, str); - return(client->noClientException); - } - else - { - client->errorValue = stuff->id; - return (BadAtom); - } -} - -int -ProcGrabServer(ClientPtr client) -{ - int rc; - REQUEST_SIZE_MATCH(xReq); - if (grabState != GrabNone && client != grabClient) - { - ResetCurrentRequest(client); - client->sequence--; - BITSET(grabWaiters, client->index); - IgnoreClient(client); - return(client->noClientException); - } - rc = OnlyListenToOneClient(client); - if (rc != Success) - return rc; - grabState = GrabKickout; - grabClient = client; - - if (ServerGrabCallback) - { - ServerGrabInfoRec grabinfo; - grabinfo.client = client; - grabinfo.grabstate = SERVER_GRABBED; - CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo); - } - - return(client->noClientException); -} - -static void -UngrabServer(ClientPtr client) -{ - int i; - - grabState = GrabNone; - ListenToAllClients(); - for (i = mskcnt; --i >= 0 && !grabWaiters[i]; ) - ; - if (i >= 0) - { - i <<= 5; - while (!GETBIT(grabWaiters, i)) - i++; - BITCLEAR(grabWaiters, i); - AttendClient(clients[i]); - } - - if (ServerGrabCallback) - { - ServerGrabInfoRec grabinfo; - grabinfo.client = client; - grabinfo.grabstate = SERVER_UNGRABBED; - CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo); - } -} - -int -ProcUngrabServer(ClientPtr client) -{ - REQUEST_SIZE_MATCH(xReq); - UngrabServer(client); - return(client->noClientException); -} - -int -ProcTranslateCoords(ClientPtr client) -{ - REQUEST(xTranslateCoordsReq); - - WindowPtr pWin, pDst; - xTranslateCoordsReply rep; - int rc; - - REQUEST_SIZE_MATCH(xTranslateCoordsReq); - rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess); - if (rc != Success) - return rc; - rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess); - if (rc != Success) - return rc; - memset(&rep, 0, sizeof(xTranslateCoordsReply)); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - if (!SAME_SCREENS(pWin->drawable, pDst->drawable)) - { - rep.sameScreen = xFalse; - rep.child = None; - rep.dstX = rep.dstY = 0; - } - else - { - INT16 x, y; - rep.sameScreen = xTrue; - rep.child = None; - /* computing absolute coordinates -- adjust to destination later */ - x = pWin->drawable.x + stuff->srcX; - y = pWin->drawable.y + stuff->srcY; - pWin = pDst->firstChild; - while (pWin) - { - BoxRec box; - if ((pWin->mapped) && - (x >= pWin->drawable.x - wBorderWidth (pWin)) && - (x < pWin->drawable.x + (int)pWin->drawable.width + - wBorderWidth (pWin)) && - (y >= pWin->drawable.y - wBorderWidth (pWin)) && - (y < pWin->drawable.y + (int)pWin->drawable.height + - wBorderWidth (pWin)) - /* When a window is shaped, a further check - * is made to see if the point is inside - * borderSize - */ - && (!wBoundingShape(pWin) || - POINT_IN_REGION(pWin->drawable.pScreen, - &pWin->borderSize, x, y, &box)) - - && (!wInputShape(pWin) || - POINT_IN_REGION(pWin->drawable.pScreen, - wInputShape(pWin), - x - pWin->drawable.x, - y - pWin->drawable.y, &box)) - ) - { - rep.child = pWin->drawable.id; - pWin = (WindowPtr) NULL; - } - else - pWin = pWin->nextSib; - } - /* adjust to destination coordinates */ - rep.dstX = x - pDst->drawable.x; - rep.dstY = y - pDst->drawable.y; - } - WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep); - return(client->noClientException); -} - -int -ProcOpenFont(ClientPtr client) -{ - int err; - REQUEST(xOpenFontReq); - - REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes); - client->errorValue = stuff->fid; - LEGAL_NEW_RESOURCE(stuff->fid, client); - err = OpenFont(client, stuff->fid, (Mask) 0, - stuff->nbytes, (char *)&stuff[1]); - if (err == Success) - { - return(client->noClientException); - } - else - return err; -} - -int -ProcCloseFont(ClientPtr client) -{ - FontPtr pFont; - int rc; - REQUEST(xResourceReq); - - REQUEST_SIZE_MATCH(xResourceReq); - rc = dixLookupResourceByType((pointer *)&pFont, stuff->id, RT_FONT, - client, DixDestroyAccess); - if (rc == Success) - { - FreeResource(stuff->id, RT_NONE); - return(client->noClientException); - } - else - { - client->errorValue = stuff->id; - return (rc == BadValue) ? BadFont : rc; - } -} - -int -ProcQueryFont(ClientPtr client) -{ - xQueryFontReply *reply; - FontPtr pFont; - GC *pGC; - int rc; - REQUEST(xResourceReq); - REQUEST_SIZE_MATCH(xResourceReq); - - client->errorValue = stuff->id; /* EITHER font or gc */ - rc = dixLookupResourceByType((pointer *)&pFont, stuff->id, RT_FONT, client, - DixGetAttrAccess); - if (rc == BadValue) { - rc = dixLookupResourceByType((pointer *)&pGC, stuff->id, RT_GC, client, - DixGetAttrAccess); - if (rc == Success) - pFont = pGC->font; - } - if (rc != Success) - return (rc == BadValue) ? BadFont: rc; - - { - xCharInfo *pmax = FONTINKMAX(pFont); - xCharInfo *pmin = FONTINKMIN(pFont); - int nprotoxcistructs; - int rlength; - - nprotoxcistructs = ( - pmax->rightSideBearing == pmin->rightSideBearing && - pmax->leftSideBearing == pmin->leftSideBearing && - pmax->descent == pmin->descent && - pmax->ascent == pmin->ascent && - pmax->characterWidth == pmin->characterWidth) ? - 0 : N2dChars(pFont); - - rlength = sizeof(xQueryFontReply) + - FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) + - nprotoxcistructs * sizeof(xCharInfo); - reply = xcalloc(1, rlength); - if(!reply) - { - return(BadAlloc); - } - - reply->type = X_Reply; - reply->length = bytes_to_int32(rlength - sizeof(xGenericReply)); - reply->sequenceNumber = client->sequence; - QueryFont( pFont, reply, nprotoxcistructs); - - WriteReplyToClient(client, rlength, reply); - xfree(reply); - return(client->noClientException); - } -} - -int -ProcQueryTextExtents(ClientPtr client) -{ - xQueryTextExtentsReply reply; - FontPtr pFont; - GC *pGC; - ExtentInfoRec info; - unsigned long length; - int rc; - REQUEST(xQueryTextExtentsReq); - REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq); - - client->errorValue = stuff->fid; /* EITHER font or gc */ - rc = dixLookupResourceByType((pointer *)&pFont, stuff->fid, RT_FONT, client, - DixGetAttrAccess); - if (rc == BadValue) { - rc = dixLookupResourceByType((pointer *)&pGC, stuff->fid, RT_GC, client, - DixGetAttrAccess); - if (rc == Success) - pFont = pGC->font; - } - if (rc != Success) - return (rc == BadValue) ? BadFont: rc; - - length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq)); - length = length << 1; - if (stuff->oddLength) - { - if (length == 0) - return(BadLength); - length--; - } - if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info)) - return(BadAlloc); - reply.type = X_Reply; - reply.length = 0; - reply.sequenceNumber = client->sequence; - reply.drawDirection = info.drawDirection; - reply.fontAscent = info.fontAscent; - reply.fontDescent = info.fontDescent; - reply.overallAscent = info.overallAscent; - reply.overallDescent = info.overallDescent; - reply.overallWidth = info.overallWidth; - reply.overallLeft = info.overallLeft; - reply.overallRight = info.overallRight; - WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply); - return(client->noClientException); -} - -int -ProcListFonts(ClientPtr client) -{ - REQUEST(xListFontsReq); - - REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes); - - return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, - stuff->maxNames); -} - -int -ProcListFontsWithInfo(ClientPtr client) -{ - REQUEST(xListFontsWithInfoReq); - - REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes); - - return StartListFontsWithInfo(client, stuff->nbytes, - (unsigned char *) &stuff[1], stuff->maxNames); -} - -/** - * - * \param value must conform to DeleteType - */ -int -dixDestroyPixmap(pointer value, XID pid) -{ - PixmapPtr pPixmap = (PixmapPtr)value; - return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); -} - -int -ProcCreatePixmap(ClientPtr client) -{ - PixmapPtr pMap; - DrawablePtr pDraw; - REQUEST(xCreatePixmapReq); - DepthPtr pDepth; - int i, rc; - - REQUEST_SIZE_MATCH(xCreatePixmapReq); - client->errorValue = stuff->pid; - LEGAL_NEW_RESOURCE(stuff->pid, client); - - rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, - DixGetAttrAccess); - if (rc != Success) - return rc; - - if (!stuff->width || !stuff->height) - { - client->errorValue = 0; - return BadValue; - } - if (stuff->width > 32767 || stuff->height > 32767) - { - /* It is allowed to try and allocate a pixmap which is larger than - * 32767 in either dimension. However, all of the framebuffer code - * is buggy and does not reliably draw to such big pixmaps, basically - * because the Region data structure operates with signed shorts - * for the rectangles in it. - * - * Furthermore, several places in the X server computes the - * size in bytes of the pixmap and tries to store it in an - * integer. This integer can overflow and cause the allocated size - * to be much smaller. - * - * So, such big pixmaps are rejected here with a BadAlloc - */ - return BadAlloc; - } - if (stuff->depth != 1) - { - pDepth = pDraw->pScreen->allowedDepths; - for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) - if (pDepth->depth == stuff->depth) - goto CreatePmap; - client->errorValue = stuff->depth; - return BadValue; - } -CreatePmap: - pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap) - (pDraw->pScreen, stuff->width, - stuff->height, stuff->depth, 0); - if (pMap) - { - pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; - pMap->drawable.id = stuff->pid; - /* security creation/labeling check */ - rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP, - pMap, RT_NONE, NULL, DixCreateAccess); - if (rc != Success) { - (*pDraw->pScreen->DestroyPixmap)(pMap); - return rc; - } - if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap)) - return(client->noClientException); - (*pDraw->pScreen->DestroyPixmap)(pMap); - } - return (BadAlloc); -} - -int -ProcFreePixmap(ClientPtr client) -{ - PixmapPtr pMap; - int rc; - REQUEST(xResourceReq); - REQUEST_SIZE_MATCH(xResourceReq); - - rc = dixLookupResourceByType((pointer *)&pMap, stuff->id, RT_PIXMAP, client, - DixDestroyAccess); - if (rc == Success) - { - FreeResource(stuff->id, RT_NONE); - return(client->noClientException); - } - else - { - client->errorValue = stuff->id; - return (rc == BadValue) ? BadPixmap : rc; - } -} - -int -ProcCreateGC(ClientPtr client) -{ - int error, rc; - GC *pGC; - DrawablePtr pDraw; - unsigned len; - REQUEST(xCreateGCReq); - - REQUEST_AT_LEAST_SIZE(xCreateGCReq); - client->errorValue = stuff->gc; - LEGAL_NEW_RESOURCE(stuff->gc, client); - rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, - DixGetAttrAccess); - if (rc != Success) - return rc; - - len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq)); - if (len != Ones(stuff->mask)) - return BadLength; - pGC = (GC *)CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error, - stuff->gc, client); - if (error != Success) - return error; - if (!AddResource(stuff->gc, RT_GC, (pointer)pGC)) - return (BadAlloc); - return(client->noClientException); -} - -int -ProcChangeGC(ClientPtr client) -{ - GC *pGC; - int result; - unsigned len; - REQUEST(xChangeGCReq); - REQUEST_AT_LEAST_SIZE(xChangeGCReq); - - result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); - if (result != Success) - return result; - - len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq)); - if (len != Ones(stuff->mask)) - return BadLength; - - result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0); - if (client->noClientException != Success) - return(client->noClientException); - else - { - client->errorValue = clientErrorValue; - return(result); - } -} - -int -ProcCopyGC(ClientPtr client) -{ - GC *dstGC; - GC *pGC; - int result; - REQUEST(xCopyGCReq); - REQUEST_SIZE_MATCH(xCopyGCReq); - - result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess); - if (result != Success) - return result; - result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess); - if (result != Success) - return result; - if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth)) - return (BadMatch); - result = CopyGC(pGC, dstGC, stuff->mask); - if (client->noClientException != Success) - return(client->noClientException); - else - { - client->errorValue = clientErrorValue; - return(result); - } -} - -int -ProcSetDashes(ClientPtr client) -{ - GC *pGC; - int result; - REQUEST(xSetDashesReq); - - REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes); - if (stuff->nDashes == 0) - { - client->errorValue = 0; - return BadValue; - } - - result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess); - if (result != Success) - return result; - - result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes, - (unsigned char *)&stuff[1]); - if (client->noClientException != Success) - return(client->noClientException); - else - { - client->errorValue = clientErrorValue; - return(result); - } -} - -int -ProcSetClipRectangles(ClientPtr client) -{ - int nr, result; - GC *pGC; - REQUEST(xSetClipRectanglesReq); - - REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq); - if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) && - (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) - { - client->errorValue = stuff->ordering; - return BadValue; - } - result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess); - if (result != Success) - return result; - - nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq); - if (nr & 4) - return(BadLength); - nr >>= 3; - result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin, - nr, (xRectangle *)&stuff[1], (int)stuff->ordering); - if (client->noClientException != Success) - return(client->noClientException); - else - return(result); -} - -int -ProcFreeGC(ClientPtr client) -{ - GC *pGC; - int rc; - REQUEST(xResourceReq); - REQUEST_SIZE_MATCH(xResourceReq); - - rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess); - if (rc != Success) - return rc; - - FreeResource(stuff->id, RT_NONE); - return(client->noClientException); -} - -int -ProcClearToBackground(ClientPtr client) -{ - REQUEST(xClearAreaReq); - WindowPtr pWin; - int rc; - - REQUEST_SIZE_MATCH(xClearAreaReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); - if (rc != Success) - return rc; - if (pWin->drawable.class == InputOnly) - { - client->errorValue = stuff->window; - return (BadMatch); - } - if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse)) - { - client->errorValue = stuff->exposures; - return(BadValue); - } - (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y, - stuff->width, stuff->height, - (Bool)stuff->exposures); - return(client->noClientException); -} - -int -ProcCopyArea(ClientPtr client) -{ - DrawablePtr pDst; - DrawablePtr pSrc; - GC *pGC; - REQUEST(xCopyAreaReq); - RegionPtr pRgn; - int rc; - - REQUEST_SIZE_MATCH(xCopyAreaReq); - - VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess); - if (stuff->dstDrawable != stuff->srcDrawable) - { - rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0, - DixReadAccess); - if (rc != Success) - return rc; - if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth)) - { - client->errorValue = stuff->dstDrawable; - return (BadMatch); - } - } - else - pSrc = pDst; - - pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY, - stuff->width, stuff->height, - stuff->dstX, stuff->dstY); - if (pGC->graphicsExposures) - { - (*pDst->pScreen->SendGraphicsExpose) - (client, pRgn, stuff->dstDrawable, X_CopyArea, 0); - if (pRgn) - REGION_DESTROY(pDst->pScreen, pRgn); - } - - return(client->noClientException); -} - -int -ProcCopyPlane(ClientPtr client) -{ - DrawablePtr psrcDraw, pdstDraw; - GC *pGC; - REQUEST(xCopyPlaneReq); - RegionPtr pRgn; - int rc; - - REQUEST_SIZE_MATCH(xCopyPlaneReq); - - VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess); - if (stuff->dstDrawable != stuff->srcDrawable) - { - rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0, - DixReadAccess); - if (rc != Success) - return rc; - - if (pdstDraw->pScreen != psrcDraw->pScreen) - { - client->errorValue = stuff->dstDrawable; - return (BadMatch); - } - } - else - psrcDraw = pdstDraw; - - /* Check to see if stuff->bitPlane has exactly ONE good bit set */ - if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) || - (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) - { - client->errorValue = stuff->bitPlane; - return(BadValue); - } - - pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY, - stuff->width, stuff->height, - stuff->dstX, stuff->dstY, stuff->bitPlane); - if (pGC->graphicsExposures) - { - (*pdstDraw->pScreen->SendGraphicsExpose) - (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0); - if (pRgn) - REGION_DESTROY(pdstDraw->pScreen, pRgn); - } - return(client->noClientException); -} - -int -ProcPolyPoint(ClientPtr client) -{ - int npoint; - GC *pGC; - DrawablePtr pDraw; - REQUEST(xPolyPointReq); - - REQUEST_AT_LEAST_SIZE(xPolyPointReq); - if ((stuff->coordMode != CoordModeOrigin) && - (stuff->coordMode != CoordModePrevious)) - { - client->errorValue = stuff->coordMode; - return BadValue; - } - VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq)); - if (npoint) - (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint, - (xPoint *) &stuff[1]); - return (client->noClientException); -} - -int -ProcPolyLine(ClientPtr client) -{ - int npoint; - GC *pGC; - DrawablePtr pDraw; - REQUEST(xPolyLineReq); - - REQUEST_AT_LEAST_SIZE(xPolyLineReq); - if ((stuff->coordMode != CoordModeOrigin) && - (stuff->coordMode != CoordModePrevious)) - { - client->errorValue = stuff->coordMode; - return BadValue; - } - VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq)); - if (npoint > 1) - (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, - (DDXPointPtr) &stuff[1]); - return(client->noClientException); -} - -int -ProcPolySegment(ClientPtr client) -{ - int nsegs; - GC *pGC; - DrawablePtr pDraw; - REQUEST(xPolySegmentReq); - - REQUEST_AT_LEAST_SIZE(xPolySegmentReq); - VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq); - if (nsegs & 4) - return(BadLength); - nsegs >>= 3; - if (nsegs) - (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]); - return (client->noClientException); -} - -int -ProcPolyRectangle (ClientPtr client) -{ - int nrects; - GC *pGC; - DrawablePtr pDraw; - REQUEST(xPolyRectangleReq); - - REQUEST_AT_LEAST_SIZE(xPolyRectangleReq); - VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq); - if (nrects & 4) - return(BadLength); - nrects >>= 3; - if (nrects) - (*pGC->ops->PolyRectangle)(pDraw, pGC, - nrects, (xRectangle *) &stuff[1]); - return(client->noClientException); -} - -int -ProcPolyArc(ClientPtr client) -{ - int narcs; - GC *pGC; - DrawablePtr pDraw; - REQUEST(xPolyArcReq); - - REQUEST_AT_LEAST_SIZE(xPolyArcReq); - VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - narcs = (client->req_len << 2) - sizeof(xPolyArcReq); - if (narcs % sizeof(xArc)) - return(BadLength); - narcs /= sizeof(xArc); - if (narcs) - (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]); - return (client->noClientException); -} - -int -ProcFillPoly(ClientPtr client) -{ - int things; - GC *pGC; - DrawablePtr pDraw; - REQUEST(xFillPolyReq); - - REQUEST_AT_LEAST_SIZE(xFillPolyReq); - if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) && - (stuff->shape != Convex)) - { - client->errorValue = stuff->shape; - return BadValue; - } - if ((stuff->coordMode != CoordModeOrigin) && - (stuff->coordMode != CoordModePrevious)) - { - client->errorValue = stuff->coordMode; - return BadValue; - } - - VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq)); - if (things) - (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape, - stuff->coordMode, things, - (DDXPointPtr) &stuff[1]); - return(client->noClientException); -} - -int -ProcPolyFillRectangle(ClientPtr client) -{ - int things; - GC *pGC; - DrawablePtr pDraw; - REQUEST(xPolyFillRectangleReq); - - REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq); - VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq); - if (things & 4) - return(BadLength); - things >>= 3; - - if (things) - (*pGC->ops->PolyFillRect) (pDraw, pGC, things, - (xRectangle *) &stuff[1]); - return (client->noClientException); -} - -int -ProcPolyFillArc(ClientPtr client) -{ - int narcs; - GC *pGC; - DrawablePtr pDraw; - REQUEST(xPolyFillArcReq); - - REQUEST_AT_LEAST_SIZE(xPolyFillArcReq); - VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq); - if (narcs % sizeof(xArc)) - return(BadLength); - narcs /= sizeof(xArc); - if (narcs) - (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]); - return (client->noClientException); -} - -#ifdef MATCH_CLIENT_ENDIAN - -int -ServerOrder (void) -{ - int whichbyte = 1; - - if (*((char *) &whichbyte)) - return LSBFirst; - return MSBFirst; -} - -#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder()) - -void -ReformatImage (char *base, int nbytes, int bpp, int order) -{ - switch (bpp) { - case 1: /* yuck */ - if (BITMAP_BIT_ORDER != order) - BitOrderInvert ((unsigned char *) base, nbytes); -#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8 - ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order); -#endif - break; - case 4: - break; /* yuck */ - case 8: - break; - case 16: - if (IMAGE_BYTE_ORDER != order) - TwoByteSwap ((unsigned char *) base, nbytes); - break; - case 32: - if (IMAGE_BYTE_ORDER != order) - FourByteSwap ((unsigned char *) base, nbytes); - break; - } -} -#else -#define ReformatImage(b,n,bpp,o) -#endif - -/* 64-bit server notes: the protocol restricts padding of images to - * 8-, 16-, or 32-bits. We would like to have 64-bits for the server - * to use internally. Removes need for internal alignment checking. - * All of the PutImage functions could be changed individually, but - * as currently written, they call other routines which require things - * to be 64-bit padded on scanlines, so we changed things here. - * If an image would be padded differently for 64- versus 32-, then - * copy each scanline to a 64-bit padded scanline. - * Also, we need to make sure that the image is aligned on a 64-bit - * boundary, even if the scanlines are padded to our satisfaction. - */ -int -ProcPutImage(ClientPtr client) -{ - GC *pGC; - DrawablePtr pDraw; - long length; /* length of scanline server padded */ - long lengthProto; /* length of scanline protocol padded */ - char *tmpImage; - REQUEST(xPutImageReq); - - REQUEST_AT_LEAST_SIZE(xPutImageReq); - VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - if (stuff->format == XYBitmap) - { - if ((stuff->depth != 1) || - (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad)) - return BadMatch; - length = BitmapBytePad(stuff->width + stuff->leftPad); - } - else if (stuff->format == XYPixmap) - { - if ((pDraw->depth != stuff->depth) || - (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad)) - return BadMatch; - length = BitmapBytePad(stuff->width + stuff->leftPad); - length *= stuff->depth; - } - else if (stuff->format == ZPixmap) - { - if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0)) - return BadMatch; - length = PixmapBytePad(stuff->width, stuff->depth); - } - else - { - client->errorValue = stuff->format; - return BadValue; - } - - tmpImage = (char *)&stuff[1]; - lengthProto = length; - - if ((bytes_to_int32(lengthProto * stuff->height) + - bytes_to_int32(sizeof(xPutImageReq))) != client->req_len) - return BadLength; - - ReformatImage (tmpImage, lengthProto * stuff->height, - stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1, - ClientOrder(client)); - - (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY, - stuff->width, stuff->height, - stuff->leftPad, stuff->format, tmpImage); - - return (client->noClientException); -} - -static int -DoGetImage(ClientPtr client, int format, Drawable drawable, - int x, int y, int width, int height, - Mask planemask, xGetImageReply **im_return) -{ - DrawablePtr pDraw, pBoundingDraw; - int nlines, linesPerBuf, rc; - int linesDone; - /* coordinates relative to the bounding drawable */ - int relx, rely; - long widthBytesLine, length; - Mask plane = 0; - char *pBuf; - xGetImageReply xgi; - RegionPtr pVisibleRegion = NULL; - - if ((format != XYPixmap) && (format != ZPixmap)) - { - client->errorValue = format; - return(BadValue); - } - rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess); - if (rc != Success) - return rc; - - memset(&xgi, 0, sizeof(xGetImageReply)); - - relx = x; - rely = y; - - if(pDraw->type == DRAWABLE_WINDOW) - { - WindowPtr pWin = (WindowPtr)pDraw; - - /* "If the drawable is a window, the window must be viewable ... or a - * BadMatch error results" */ - if (!pWin->viewable) - return BadMatch; - - relx += pDraw->x; - rely += pDraw->y; - - if (pDraw->pScreen->GetWindowPixmap) { - PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin); - - pBoundingDraw = &pPix->drawable; -#ifdef COMPOSITE - relx -= pPix->screen_x; - rely -= pPix->screen_y; -#endif - } - else - { - pBoundingDraw = (DrawablePtr)WindowTable[pDraw->pScreen->myNum]; - } - - xgi.visual = wVisual (pWin); - } - else - { - pBoundingDraw = pDraw; - xgi.visual = None; - } - - /* "If the drawable is a pixmap, the given rectangle must be wholly - * contained within the pixmap, or a BadMatch error results. If the - * drawable is a window [...] it must be the case that if there were no - * inferiors or overlapping windows, the specified rectangle of the window - * would be fully visible on the screen and wholly contained within the - * outside edges of the window, or a BadMatch error results." - * - * We relax the window case slightly to mean that the rectangle must exist - * within the bounds of the window's backing pixmap. In particular, this - * means that a GetImage request may succeed or fail with BadMatch depending - * on whether any of its ancestor windows are redirected. */ - if(relx < 0 || relx + width > (int)pBoundingDraw->width || - rely < 0 || rely + height > (int)pBoundingDraw->height) - return BadMatch; - - xgi.type = X_Reply; - xgi.sequenceNumber = client->sequence; - xgi.depth = pDraw->depth; - if(format == ZPixmap) - { - widthBytesLine = PixmapBytePad(width, pDraw->depth); - length = widthBytesLine * height; - - } - else - { - widthBytesLine = BitmapBytePad(width); - plane = ((Mask)1) << (pDraw->depth - 1); - /* only planes asked for */ - length = widthBytesLine * height * - Ones(planemask & (plane | (plane - 1))); - - } - - xgi.length = length; - - if (im_return) { - pBuf = xcalloc(1, sz_xGetImageReply + length); - if (!pBuf) - return (BadAlloc); - if (widthBytesLine == 0) - linesPerBuf = 0; - else - linesPerBuf = height; - *im_return = (xGetImageReply *)pBuf; - *(xGetImageReply *)pBuf = xgi; - pBuf += sz_xGetImageReply; - } else { - xgi.length = bytes_to_int32(xgi.length); - if (widthBytesLine == 0 || height == 0) - linesPerBuf = 0; - else if (widthBytesLine >= IMAGE_BUFSIZE) - linesPerBuf = 1; - else - { - linesPerBuf = IMAGE_BUFSIZE / widthBytesLine; - if (linesPerBuf > height) - linesPerBuf = height; - } - length = linesPerBuf * widthBytesLine; - if (linesPerBuf < height) - { - /* we have to make sure intermediate buffers don't need padding */ - while ((linesPerBuf > 1) && - (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))) - { - linesPerBuf--; - length -= widthBytesLine; - } - while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)) - { - linesPerBuf++; - length += widthBytesLine; - } - } - if(!(pBuf = xcalloc(1, length))) - return (BadAlloc); - WriteReplyToClient(client, sizeof (xGetImageReply), &xgi); - } - - if (pDraw->type == DRAWABLE_WINDOW) - { - pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw); - if (pVisibleRegion) - { - REGION_TRANSLATE(pDraw->pScreen, pVisibleRegion, - -pDraw->x, -pDraw->y); - } - } - - if (linesPerBuf == 0) - { - /* nothing to do */ - } - else if (format == ZPixmap) - { - linesDone = 0; - while (height - linesDone > 0) - { - nlines = min(linesPerBuf, height - linesDone); - (*pDraw->pScreen->GetImage) (pDraw, - x, - y + linesDone, - width, - nlines, - format, - planemask, - (pointer) pBuf); - if (pVisibleRegion) - XaceCensorImage(client, pVisibleRegion, widthBytesLine, - pDraw, x, y + linesDone, width, - nlines, format, pBuf); - - /* Note that this is NOT a call to WriteSwappedDataToClient, - as we do NOT byte swap */ - if (!im_return) - { - ReformatImage (pBuf, (int)(nlines * widthBytesLine), - BitsPerPixel (pDraw->depth), - ClientOrder(client)); - -/* Don't split me, gcc pukes when you do */ - (void)WriteToClient(client, - (int)(nlines * widthBytesLine), - pBuf); - } - linesDone += nlines; - } - } - else /* XYPixmap */ - { - for (; plane; plane >>= 1) - { - if (planemask & plane) - { - linesDone = 0; - while (height - linesDone > 0) - { - nlines = min(linesPerBuf, height - linesDone); - (*pDraw->pScreen->GetImage) (pDraw, - x, - y + linesDone, - width, - nlines, - format, - plane, - (pointer)pBuf); - if (pVisibleRegion) - XaceCensorImage(client, pVisibleRegion, - widthBytesLine, - pDraw, x, y + linesDone, width, - nlines, format, pBuf); - - /* Note: NOT a call to WriteSwappedDataToClient, - as we do NOT byte swap */ - if (im_return) { - pBuf += nlines * widthBytesLine; - } else { - ReformatImage (pBuf, - (int)(nlines * widthBytesLine), - 1, - ClientOrder (client)); - -/* Don't split me, gcc pukes when you do */ - (void)WriteToClient(client, - (int)(nlines * widthBytesLine), - pBuf); - } - linesDone += nlines; - } - } - } - } - if (pVisibleRegion) - REGION_DESTROY(pDraw->pScreen, pVisibleRegion); - if (!im_return) - xfree(pBuf); - return (client->noClientException); -} - -int -ProcGetImage(ClientPtr client) -{ - REQUEST(xGetImageReq); - - REQUEST_SIZE_MATCH(xGetImageReq); - - return DoGetImage(client, stuff->format, stuff->drawable, - stuff->x, stuff->y, - (int)stuff->width, (int)stuff->height, - stuff->planeMask, (xGetImageReply **)NULL); -} - -int -ProcPolyText(ClientPtr client) -{ - int err; - REQUEST(xPolyTextReq); - DrawablePtr pDraw; - GC *pGC; - - REQUEST_AT_LEAST_SIZE(xPolyTextReq); - VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - - err = PolyText(client, - pDraw, - pGC, - (unsigned char *)&stuff[1], - ((unsigned char *) stuff) + (client->req_len << 2), - stuff->x, - stuff->y, - stuff->reqType, - stuff->drawable); - - if (err == Success) - { - return(client->noClientException); - } - else - return err; -} - -int -ProcImageText8(ClientPtr client) -{ - int err; - DrawablePtr pDraw; - GC *pGC; - - REQUEST(xImageTextReq); - - REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars); - VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - - err = ImageText(client, - pDraw, - pGC, - stuff->nChars, - (unsigned char *)&stuff[1], - stuff->x, - stuff->y, - stuff->reqType, - stuff->drawable); - - if (err == Success) - { - return(client->noClientException); - } - else - return err; -} - -int -ProcImageText16(ClientPtr client) -{ - int err; - DrawablePtr pDraw; - GC *pGC; - - REQUEST(xImageTextReq); - - REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1); - VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); - - err = ImageText(client, - pDraw, - pGC, - stuff->nChars, - (unsigned char *)&stuff[1], - stuff->x, - stuff->y, - stuff->reqType, - stuff->drawable); - - if (err == Success) - { - return(client->noClientException); - } - else - return err; -} - - -int -ProcCreateColormap(ClientPtr client) -{ - VisualPtr pVisual; - ColormapPtr pmap; - Colormap mid; - WindowPtr pWin; - ScreenPtr pScreen; - REQUEST(xCreateColormapReq); - int i, result; - - REQUEST_SIZE_MATCH(xCreateColormapReq); - - if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll)) - { - client->errorValue = stuff->alloc; - return(BadValue); - } - mid = stuff->mid; - LEGAL_NEW_RESOURCE(mid, client); - result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (result != Success) - return result; - - pScreen = pWin->drawable.pScreen; - for (i = 0, pVisual = pScreen->visuals; - i < pScreen->numVisuals; - i++, pVisual++) - { - if (pVisual->vid != stuff->visual) - continue; - result = CreateColormap(mid, pScreen, pVisual, &pmap, - (int)stuff->alloc, client->index); - if (client->noClientException != Success) - return(client->noClientException); - else - return(result); - } - client->errorValue = stuff->visual; - return(BadMatch); -} - -int -ProcFreeColormap(ClientPtr client) -{ - ColormapPtr pmap; - int rc; - REQUEST(xResourceReq); - - REQUEST_SIZE_MATCH(xResourceReq); - rc = dixLookupResourceByType((pointer *)&pmap, stuff->id, RT_COLORMAP, client, - DixDestroyAccess); - if (rc == Success) - { - /* Freeing a default colormap is a no-op */ - if (!(pmap->flags & IsDefault)) - FreeResource(stuff->id, RT_NONE); - return (client->noClientException); - } - else - { - client->errorValue = stuff->id; - return (rc == BadValue) ? BadColor : rc; - } -} - - -int -ProcCopyColormapAndFree(ClientPtr client) -{ - Colormap mid; - ColormapPtr pSrcMap; - REQUEST(xCopyColormapAndFreeReq); - int rc; - - REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq); - mid = stuff->mid; - LEGAL_NEW_RESOURCE(mid, client); - rc = dixLookupResourceByType((pointer *)&pSrcMap, stuff->srcCmap, RT_COLORMAP, - client, DixReadAccess|DixRemoveAccess); - if (rc == Success) - { - rc = CopyColormapAndFree(mid, pSrcMap, client->index); - if (client->noClientException != Success) - return(client->noClientException); - else - return rc; - } - else - { - client->errorValue = stuff->srcCmap; - return (rc == BadValue) ? BadColor : rc; - } -} - -int -ProcInstallColormap(ClientPtr client) -{ - ColormapPtr pcmp; - int rc; - REQUEST(xResourceReq); - REQUEST_SIZE_MATCH(xResourceReq); - - rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client, - DixInstallAccess); - if (rc != Success) - goto out; - - rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); - if (rc != Success) - goto out; - - (*(pcmp->pScreen->InstallColormap)) (pcmp); - - rc = client->noClientException; -out: - client->errorValue = stuff->id; - return (rc == BadValue) ? BadColor : rc; -} - -int -ProcUninstallColormap(ClientPtr client) -{ - ColormapPtr pcmp; - int rc; - REQUEST(xResourceReq); - REQUEST_SIZE_MATCH(xResourceReq); - - rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client, - DixUninstallAccess); - if (rc != Success) - goto out; - - rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); - if (rc != Success) - goto out; - - if(pcmp->mid != pcmp->pScreen->defColormap) - (*(pcmp->pScreen->UninstallColormap)) (pcmp); - - rc = client->noClientException; -out: - client->errorValue = stuff->id; - return (rc == BadValue) ? BadColor : rc; -} - -int -ProcListInstalledColormaps(ClientPtr client) -{ - xListInstalledColormapsReply *preply; - int nummaps, rc; - WindowPtr pWin; - REQUEST(xResourceReq); - REQUEST_SIZE_MATCH(xResourceReq); - - rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); - if (rc != Success) - goto out; - - rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen, - DixGetAttrAccess); - if (rc != Success) - goto out; - - preply = xalloc(sizeof(xListInstalledColormapsReply) + - pWin->drawable.pScreen->maxInstalledCmaps * - sizeof(Colormap)); - if(!preply) - return(BadAlloc); - - preply->type = X_Reply; - preply->sequenceNumber = client->sequence; - nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps) - (pWin->drawable.pScreen, (Colormap *)&preply[1]); - preply->nColormaps = nummaps; - preply->length = nummaps; - WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply); - client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; - WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]); - xfree(preply); - rc = client->noClientException; -out: - return rc; -} - -int -ProcAllocColor (ClientPtr client) -{ - ColormapPtr pmap; - int rc; - xAllocColorReply acr; - REQUEST(xAllocColorReq); - - REQUEST_SIZE_MATCH(xAllocColorReq); - rc = dixLookupResourceByType((pointer *)&pmap, stuff->cmap, RT_COLORMAP, client, - DixAddAccess); - if (rc == Success) - { - acr.type = X_Reply; - acr.length = 0; - acr.sequenceNumber = client->sequence; - acr.red = stuff->red; - acr.green = stuff->green; - acr.blue = stuff->blue; - acr.pixel = 0; - if( (rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue, - &acr.pixel, client->index)) ) - { - if (client->noClientException != Success) - return(client->noClientException); - else - return rc; - } -#ifdef PANORAMIX - if (noPanoramiXExtension || !pmap->pScreen->myNum) -#endif - WriteReplyToClient(client, sizeof(xAllocColorReply), &acr); - return (client->noClientException); - - } - else - { - client->errorValue = stuff->cmap; - return (rc == BadValue) ? BadColor : rc; - } -} - -int -ProcAllocNamedColor (ClientPtr client) -{ - ColormapPtr pcmp; - int rc; - REQUEST(xAllocNamedColorReq); - - REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes); - rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, - DixAddAccess); - if (rc == Success) - { - xAllocNamedColorReply ancr; - - ancr.type = X_Reply; - ancr.length = 0; - ancr.sequenceNumber = client->sequence; - - if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes, - &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue)) - { - ancr.screenRed = ancr.exactRed; - ancr.screenGreen = ancr.exactGreen; - ancr.screenBlue = ancr.exactBlue; - ancr.pixel = 0; - if( (rc = AllocColor(pcmp, - &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue, - &ancr.pixel, client->index)) ) - { - if (client->noClientException != Success) - return(client->noClientException); - else - return rc; - } -#ifdef PANORAMIX - if (noPanoramiXExtension || !pcmp->pScreen->myNum) -#endif - WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr); - return (client->noClientException); - } - else - return(BadName); - - } - else - { - client->errorValue = stuff->cmap; - return (rc == BadValue) ? BadColor : rc; - } -} - -int -ProcAllocColorCells (ClientPtr client) -{ - ColormapPtr pcmp; - int rc; - REQUEST(xAllocColorCellsReq); - - REQUEST_SIZE_MATCH(xAllocColorCellsReq); - rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, - DixAddAccess); - if (rc == Success) - { - xAllocColorCellsReply accr; - int npixels, nmasks; - long length; - Pixel *ppixels, *pmasks; - - npixels = stuff->colors; - if (!npixels) - { - client->errorValue = npixels; - return (BadValue); - } - if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) - { - client->errorValue = stuff->contiguous; - return (BadValue); - } - nmasks = stuff->planes; - length = ((long)npixels + (long)nmasks) * sizeof(Pixel); - ppixels = xalloc(length); - if(!ppixels) - return(BadAlloc); - pmasks = ppixels + npixels; - - if( (rc = AllocColorCells(client->index, pcmp, npixels, nmasks, - (Bool)stuff->contiguous, ppixels, pmasks)) ) - { - xfree(ppixels); - if (client->noClientException != Success) - return(client->noClientException); - else - return rc; - } -#ifdef PANORAMIX - if (noPanoramiXExtension || !pcmp->pScreen->myNum) -#endif - { - accr.type = X_Reply; - accr.length = bytes_to_int32(length); - accr.sequenceNumber = client->sequence; - accr.nPixels = npixels; - accr.nMasks = nmasks; - WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr); - client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; - WriteSwappedDataToClient(client, length, ppixels); - } - xfree(ppixels); - return (client->noClientException); - } - else - { - client->errorValue = stuff->cmap; - return (rc == BadValue) ? BadColor : rc; - } -} - -int -ProcAllocColorPlanes(ClientPtr client) -{ - ColormapPtr pcmp; - int rc; - REQUEST(xAllocColorPlanesReq); - - REQUEST_SIZE_MATCH(xAllocColorPlanesReq); - rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, - DixAddAccess); - if (rc == Success) - { - xAllocColorPlanesReply acpr; - int npixels; - long length; - Pixel *ppixels; - - npixels = stuff->colors; - if (!npixels) - { - client->errorValue = npixels; - return (BadValue); - } - if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) - { - client->errorValue = stuff->contiguous; - return (BadValue); - } - acpr.type = X_Reply; - acpr.sequenceNumber = client->sequence; - acpr.nPixels = npixels; - length = (long)npixels * sizeof(Pixel); - ppixels = xalloc(length); - if(!ppixels) - return(BadAlloc); - if( (rc = AllocColorPlanes(client->index, pcmp, npixels, - (int)stuff->red, (int)stuff->green, (int)stuff->blue, - (Bool)stuff->contiguous, ppixels, - &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) ) - { - xfree(ppixels); - if (client->noClientException != Success) - return(client->noClientException); - else - return rc; - } - acpr.length = bytes_to_int32(length); -#ifdef PANORAMIX - if (noPanoramiXExtension || !pcmp->pScreen->myNum) -#endif - { - WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr); - client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; - WriteSwappedDataToClient(client, length, ppixels); - } - xfree(ppixels); - return (client->noClientException); - } - else - { - client->errorValue = stuff->cmap; - return (rc == BadValue) ? BadColor : rc; - } -} - -int -ProcFreeColors(ClientPtr client) -{ - ColormapPtr pcmp; - int rc; - REQUEST(xFreeColorsReq); - - REQUEST_AT_LEAST_SIZE(xFreeColorsReq); - rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, - DixRemoveAccess); - if (rc == Success) - { - int count; - - if(pcmp->flags & AllAllocated) - return(BadAccess); - count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq)); - rc = FreeColors(pcmp, client->index, count, - (Pixel *)&stuff[1], (Pixel)stuff->planeMask); - if (client->noClientException != Success) - return(client->noClientException); - else - { - client->errorValue = clientErrorValue; - return rc; - } - - } - else - { - client->errorValue = stuff->cmap; - return (rc == BadValue) ? BadColor : rc; - } -} - -int -ProcStoreColors (ClientPtr client) -{ - ColormapPtr pcmp; - int rc; - REQUEST(xStoreColorsReq); - - REQUEST_AT_LEAST_SIZE(xStoreColorsReq); - rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, - DixWriteAccess); - if (rc == Success) - { - int count; - - count = (client->req_len << 2) - sizeof(xStoreColorsReq); - if (count % sizeof(xColorItem)) - return(BadLength); - count /= sizeof(xColorItem); - rc = StoreColors(pcmp, count, (xColorItem *)&stuff[1]); - if (client->noClientException != Success) - return(client->noClientException); - else - { - client->errorValue = clientErrorValue; - return rc; - } - } - else - { - client->errorValue = stuff->cmap; - return (rc == BadValue) ? BadColor : rc; - } -} - -int -ProcStoreNamedColor (ClientPtr client) -{ - ColormapPtr pcmp; - int rc; - REQUEST(xStoreNamedColorReq); - - REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes); - rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, - DixWriteAccess); - if (rc == Success) - { - xColorItem def; - - if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], - stuff->nbytes, &def.red, &def.green, &def.blue)) - { - def.flags = stuff->flags; - def.pixel = stuff->pixel; - rc = StoreColors(pcmp, 1, &def); - if (client->noClientException != Success) - return(client->noClientException); - else - return rc; - } - return (BadName); - } - else - { - client->errorValue = stuff->cmap; - return (rc == BadValue) ? BadColor : rc; - } -} - -int -ProcQueryColors(ClientPtr client) -{ - ColormapPtr pcmp; - int rc; - REQUEST(xQueryColorsReq); - - REQUEST_AT_LEAST_SIZE(xQueryColorsReq); - rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, - DixReadAccess); - if (rc == Success) - { - int count; - xrgb *prgbs; - xQueryColorsReply qcr; - - count = bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq)); - prgbs = xcalloc(1, count * sizeof(xrgb)); - if(!prgbs && count) - return(BadAlloc); - if( (rc = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) ) - { - if (prgbs) xfree(prgbs); - if (client->noClientException != Success) - return(client->noClientException); - else - { - client->errorValue = clientErrorValue; - return rc; - } - } - memset(&qcr, 0, sizeof(xQueryColorsReply)); - qcr.type = X_Reply; - qcr.length = bytes_to_int32(count * sizeof(xrgb)); - qcr.sequenceNumber = client->sequence; - qcr.nColors = count; - WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr); - if (count) - { - client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend; - WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs); - } - if (prgbs) xfree(prgbs); - return(client->noClientException); - - } - else - { - client->errorValue = stuff->cmap; - return (rc == BadValue) ? BadColor : rc; - } -} - -int -ProcLookupColor(ClientPtr client) -{ - ColormapPtr pcmp; - int rc; - REQUEST(xLookupColorReq); - - REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes); - rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, - DixReadAccess); - if (rc == Success) - { - xLookupColorReply lcr; - - if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes, - &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue)) - { - lcr.type = X_Reply; - lcr.length = 0; - lcr.sequenceNumber = client->sequence; - lcr.screenRed = lcr.exactRed; - lcr.screenGreen = lcr.exactGreen; - lcr.screenBlue = lcr.exactBlue; - (*pcmp->pScreen->ResolveColor)(&lcr.screenRed, - &lcr.screenGreen, - &lcr.screenBlue, - pcmp->pVisual); - WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr); - return(client->noClientException); - } - return (BadName); - } - else - { - client->errorValue = stuff->cmap; - return (rc == BadValue) ? BadColor : rc; - } -} - -int -ProcCreateCursor (ClientPtr client) -{ - CursorPtr pCursor; - PixmapPtr src; - PixmapPtr msk; - unsigned char * srcbits; - unsigned char * mskbits; - unsigned short width, height; - long n; - CursorMetricRec cm; - int rc; - - REQUEST(xCreateCursorReq); - - REQUEST_SIZE_MATCH(xCreateCursorReq); - LEGAL_NEW_RESOURCE(stuff->cid, client); - - rc = dixLookupResourceByType((pointer *)&src, stuff->source, RT_PIXMAP, client, - DixReadAccess); - if (rc != Success) { - client->errorValue = stuff->source; - return (rc == BadValue) ? BadPixmap : rc; - } - - rc = dixLookupResourceByType((pointer *)&msk, stuff->mask, RT_PIXMAP, client, - DixReadAccess); - if (rc != Success) - { - if (stuff->mask != None) - { - client->errorValue = stuff->mask; - return (rc == BadValue) ? BadPixmap : rc; - } - } - else if ( src->drawable.width != msk->drawable.width - || src->drawable.height != msk->drawable.height - || src->drawable.depth != 1 - || msk->drawable.depth != 1) - return (BadMatch); - - width = src->drawable.width; - height = src->drawable.height; - - if ( stuff->x > width - || stuff->y > height ) - return (BadMatch); - - n = BitmapBytePad(width)*height; - srcbits = xcalloc(1, n); - if (!srcbits) - return (BadAlloc); - mskbits = xalloc(n); - if (!mskbits) - { - xfree(srcbits); - return (BadAlloc); - } - - (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height, - XYPixmap, 1, (pointer)srcbits); - if ( msk == (PixmapPtr)NULL) - { - unsigned char *bits = mskbits; - while (--n >= 0) - *bits++ = ~0; - } - else - { - /* zeroing the (pad) bits helps some ddx cursor handling */ - bzero((char *)mskbits, n); - (* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width, - height, XYPixmap, 1, (pointer)mskbits); - } - cm.width = width; - cm.height = height; - cm.xhot = stuff->x; - cm.yhot = stuff->y; - rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm, - stuff->foreRed, stuff->foreGreen, stuff->foreBlue, - stuff->backRed, stuff->backGreen, stuff->backBlue, - &pCursor, client, stuff->cid); - - if (rc != Success) - return rc; - if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) - return BadAlloc; - - return client->noClientException; -} - -int -ProcCreateGlyphCursor (ClientPtr client) -{ - CursorPtr pCursor; - int res; - - REQUEST(xCreateGlyphCursorReq); - - REQUEST_SIZE_MATCH(xCreateGlyphCursorReq); - LEGAL_NEW_RESOURCE(stuff->cid, client); - - res = AllocGlyphCursor(stuff->source, stuff->sourceChar, - stuff->mask, stuff->maskChar, - stuff->foreRed, stuff->foreGreen, stuff->foreBlue, - stuff->backRed, stuff->backGreen, stuff->backBlue, - &pCursor, client, stuff->cid); - if (res != Success) - return res; - if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) - return client->noClientException; - return BadAlloc; -} - - -int -ProcFreeCursor (ClientPtr client) -{ - CursorPtr pCursor; - int rc; - REQUEST(xResourceReq); - - REQUEST_SIZE_MATCH(xResourceReq); - rc = dixLookupResourceByType((pointer *)&pCursor, stuff->id, RT_CURSOR, client, - DixDestroyAccess); - if (rc == Success) - { - FreeResource(stuff->id, RT_NONE); - return (client->noClientException); - } - else - { - client->errorValue = stuff->id; - return (rc == BadValue) ? BadCursor : rc; - } -} - -int -ProcQueryBestSize (ClientPtr client) -{ - xQueryBestSizeReply reply; - DrawablePtr pDraw; - ScreenPtr pScreen; - int rc; - REQUEST(xQueryBestSizeReq); - REQUEST_SIZE_MATCH(xQueryBestSizeReq); - - if ((stuff->class != CursorShape) && - (stuff->class != TileShape) && - (stuff->class != StippleShape)) - { - client->errorValue = stuff->class; - return(BadValue); - } - - rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, - DixGetAttrAccess); - if (rc != Success) - return rc; - if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW) - return (BadMatch); - pScreen = pDraw->pScreen; - rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess); - if (rc != Success) - return rc; - (* pScreen->QueryBestSize)(stuff->class, &stuff->width, - &stuff->height, pScreen); - memset(&reply, 0, sizeof(xQueryBestSizeReply)); - reply.type = X_Reply; - reply.length = 0; - reply.sequenceNumber = client->sequence; - reply.width = stuff->width; - reply.height = stuff->height; - WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply); - return (client->noClientException); -} - - -int -ProcSetScreenSaver (ClientPtr client) -{ - int rc, i, blankingOption, exposureOption; - REQUEST(xSetScreenSaverReq); - REQUEST_SIZE_MATCH(xSetScreenSaverReq); - - for (i = 0; i < screenInfo.numScreens; i++) { - rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], - DixSetAttrAccess); - if (rc != Success) - return rc; - } - - blankingOption = stuff->preferBlank; - if ((blankingOption != DontPreferBlanking) && - (blankingOption != PreferBlanking) && - (blankingOption != DefaultBlanking)) - { - client->errorValue = blankingOption; - return BadValue; - } - exposureOption = stuff->allowExpose; - if ((exposureOption != DontAllowExposures) && - (exposureOption != AllowExposures) && - (exposureOption != DefaultExposures)) - { - client->errorValue = exposureOption; - return BadValue; - } - if (stuff->timeout < -1) - { - client->errorValue = stuff->timeout; - return BadValue; - } - if (stuff->interval < -1) - { - client->errorValue = stuff->interval; - return BadValue; - } - - if (blankingOption == DefaultBlanking) - ScreenSaverBlanking = defaultScreenSaverBlanking; - else - ScreenSaverBlanking = blankingOption; - if (exposureOption == DefaultExposures) - ScreenSaverAllowExposures = defaultScreenSaverAllowExposures; - else - ScreenSaverAllowExposures = exposureOption; - - if (stuff->timeout >= 0) - ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND; - else - ScreenSaverTime = defaultScreenSaverTime; - if (stuff->interval >= 0) - ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND; - else - ScreenSaverInterval = defaultScreenSaverInterval; - - SetScreenSaverTimer(); - return (client->noClientException); -} - -int -ProcGetScreenSaver(ClientPtr client) -{ - xGetScreenSaverReply rep; - int rc, i; - REQUEST_SIZE_MATCH(xReq); - - for (i = 0; i < screenInfo.numScreens; i++) { - rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], - DixGetAttrAccess); - if (rc != Success) - return rc; - } - - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.timeout = ScreenSaverTime / MILLI_PER_SECOND; - rep.interval = ScreenSaverInterval / MILLI_PER_SECOND; - rep.preferBlanking = ScreenSaverBlanking; - rep.allowExposures = ScreenSaverAllowExposures; - WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep); - return (client->noClientException); -} - -int -ProcChangeHosts(ClientPtr client) -{ - REQUEST(xChangeHostsReq); - int result; - - REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength); - - if(stuff->mode == HostInsert) - result = AddHost(client, (int)stuff->hostFamily, - stuff->hostLength, (pointer)&stuff[1]); - else if (stuff->mode == HostDelete) - result = RemoveHost(client, (int)stuff->hostFamily, - stuff->hostLength, (pointer)&stuff[1]); - else - { - client->errorValue = stuff->mode; - return BadValue; - } - if (!result) - result = client->noClientException; - return (result); -} - -int -ProcListHosts(ClientPtr client) -{ - xListHostsReply reply; - int len, nHosts, result; - pointer pdata; - /* REQUEST(xListHostsReq); */ - - REQUEST_SIZE_MATCH(xListHostsReq); - - /* untrusted clients can't list hosts */ - result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess); - if (result != Success) - return result; - - result = GetHosts(&pdata, &nHosts, &len, &reply.enabled); - if (result != Success) - return(result); - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.nHosts = nHosts; - reply.length = bytes_to_int32(len); - WriteReplyToClient(client, sizeof(xListHostsReply), &reply); - if (nHosts) - { - client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend; - WriteSwappedDataToClient(client, len, pdata); - } - xfree(pdata); - return (client->noClientException); -} - -int -ProcChangeAccessControl(ClientPtr client) -{ - int result; - REQUEST(xSetAccessControlReq); - - REQUEST_SIZE_MATCH(xSetAccessControlReq); - if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess)) - { - client->errorValue = stuff->mode; - return BadValue; - } - result = ChangeAccessControl(client, stuff->mode == EnableAccess); - if (!result) - result = client->noClientException; - return (result); -} - -/********************* - * CloseDownRetainedResources - * - * Find all clients that are gone and have terminated in RetainTemporary - * and destroy their resources. - *********************/ - -static void -CloseDownRetainedResources(void) -{ - int i; - ClientPtr client; - - for (i=1; i<currentMaxClients; i++) - { - client = clients[i]; - if (client && (client->closeDownMode == RetainTemporary) - && (client->clientGone)) - CloseDownClient(client); - } -} - -int -ProcKillClient(ClientPtr client) -{ - REQUEST(xResourceReq); - ClientPtr killclient; - int rc; - - REQUEST_SIZE_MATCH(xResourceReq); - if (stuff->id == AllTemporary) - { - CloseDownRetainedResources(); - return (client->noClientException); - } - - rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess); - if (rc == Success) { - CloseDownClient(killclient); - /* if an LBX proxy gets killed, isItTimeToYield will be set */ - if (isItTimeToYield || (client == killclient)) - { - /* force yield and return Success, so that Dispatch() - * doesn't try to touch client - */ - isItTimeToYield = TRUE; - return (Success); - } - return (client->noClientException); - } - else - return rc; -} - -int -ProcSetFontPath(ClientPtr client) -{ - unsigned char *ptr; - unsigned long nbytes, total; - long nfonts; - int n, result; - int error; - REQUEST(xSetFontPathReq); - - REQUEST_AT_LEAST_SIZE(xSetFontPathReq); - - nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq); - total = nbytes; - ptr = (unsigned char *)&stuff[1]; - nfonts = stuff->nFonts; - while (--nfonts >= 0) - { - if ((total == 0) || (total < (n = (*ptr + 1)))) - return(BadLength); - total -= n; - ptr += n; - } - if (total >= 4) - return(BadLength); - result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1], - &error); - if (!result) - { - result = client->noClientException; - client->errorValue = error; - } - return (result); -} - -int -ProcGetFontPath(ClientPtr client) -{ - xGetFontPathReply reply; - int rc, stringLens, numpaths; - unsigned char *bufferStart; - /* REQUEST (xReq); */ - - REQUEST_SIZE_MATCH(xReq); - rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart); - if (rc != Success) - return rc; - - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = bytes_to_int32(stringLens + numpaths); - reply.nPaths = numpaths; - - WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply); - if (stringLens || numpaths) - (void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart); - return(client->noClientException); -} - -int -ProcChangeCloseDownMode(ClientPtr client) -{ - int rc; - REQUEST(xSetCloseDownModeReq); - REQUEST_SIZE_MATCH(xSetCloseDownModeReq); - - rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess); - if (rc != Success) - return rc; - - if ((stuff->mode == AllTemporary) || - (stuff->mode == RetainPermanent) || - (stuff->mode == RetainTemporary)) - { - client->closeDownMode = stuff->mode; - return (client->noClientException); - } - else - { - client->errorValue = stuff->mode; - return (BadValue); - } -} - -int ProcForceScreenSaver(ClientPtr client) -{ - int rc; - REQUEST(xForceScreenSaverReq); - - REQUEST_SIZE_MATCH(xForceScreenSaverReq); - - if ((stuff->mode != ScreenSaverReset) && - (stuff->mode != ScreenSaverActive)) - { - client->errorValue = stuff->mode; - return BadValue; - } - rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int)stuff->mode); - if (rc != Success) - return rc; - return client->noClientException; -} - -int ProcNoOperation(ClientPtr client) -{ - REQUEST_AT_LEAST_SIZE(xReq); - - /* noop -- don't do anything */ - return(client->noClientException); -} - -void -InitProcVectors(void) -{ - int i; - for (i = 0; i<256; i++) - { - if(!ProcVector[i]) - { - ProcVector[i] = SwappedProcVector[i] = ProcBadRequest; - ReplySwapVector[i] = ReplyNotSwappd; - } - } - for(i = LASTEvent; i < 128; i++) - { - EventSwapVector[i] = NotImplemented; - } - -} - -/********************** - * CloseDownClient - * - * Client can either mark his resources destroy or retain. If retained and - * then killed again, the client is really destroyed. - *********************/ - -char dispatchExceptionAtReset = DE_RESET; - -void -CloseDownClient(ClientPtr client) -{ - Bool really_close_down = client->clientGone || - client->closeDownMode == DestroyAll; - - if (!client->clientGone) - { - /* ungrab server if grabbing client dies */ - if (grabState != GrabNone && grabClient == client) - { - UngrabServer(client); - } - BITCLEAR(grabWaiters, client->index); - DeleteClientFromAnySelections(client); - ReleaseActiveGrabs(client); - DeleteClientFontStuff(client); - if (!really_close_down) - { - /* This frees resources that should never be retained - * no matter what the close down mode is. Actually we - * could do this unconditionally, but it's probably - * better not to traverse all the client's resources - * twice (once here, once a few lines down in - * FreeClientResources) in the common case of - * really_close_down == TRUE. - */ - FreeClientNeverRetainResources(client); - client->clientState = ClientStateRetained; - if (ClientStateCallback) - { - NewClientInfoRec clientinfo; - - clientinfo.client = client; - clientinfo.prefix = (xConnSetupPrefix *)NULL; - clientinfo.setup = (xConnSetup *) NULL; - CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); - } - } - client->clientGone = TRUE; /* so events aren't sent to client */ - if (ClientIsAsleep(client)) - ClientSignal (client); - ProcessWorkQueueZombies(); - CloseDownConnection(client); - - /* If the client made it to the Running stage, nClients has - * been incremented on its behalf, so we need to decrement it - * now. If it hasn't gotten to Running, nClients has *not* - * been incremented, so *don't* decrement it. - */ - if (client->clientState != ClientStateInitial && - client->clientState != ClientStateAuthenticating ) - { - --nClients; - } - } - - if (really_close_down) - { - if (client->clientState == ClientStateRunning && nClients == 0) - dispatchException |= dispatchExceptionAtReset; - - client->clientState = ClientStateGone; - if (ClientStateCallback) - { - NewClientInfoRec clientinfo; - - clientinfo.client = client; - clientinfo.prefix = (xConnSetupPrefix *)NULL; - clientinfo.setup = (xConnSetup *) NULL; - CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); - } - FreeClientResources(client); -#ifdef XSERVER_DTRACE - XSERVER_CLIENT_DISCONNECT(client->index); -#endif - if (client->index < nextFreeClientID) - nextFreeClientID = client->index; - clients[client->index] = NullClient; - SmartLastClient = NullClient; - dixFreePrivates(client->devPrivates); - xfree(client); - - while (!clients[currentMaxClients-1]) - currentMaxClients--; - } -} - -static void -KillAllClients(void) -{ - int i; - for (i=1; i<currentMaxClients; i++) - if (clients[i]) { - /* Make sure Retained clients are released. */ - clients[i]->closeDownMode = DestroyAll; - CloseDownClient(clients[i]); - } -} - -void InitClient(ClientPtr client, int i, pointer ospriv) -{ - memset(client, 0, sizeof(*client)); - client->index = i; - client->clientAsMask = ((Mask)i) << CLIENTOFFSET; - client->closeDownMode = i ? DestroyAll : RetainPermanent; - client->requestVector = InitialVector; - client->osPrivate = ospriv; - QueryMinMaxKeyCodes(&client->minKC,&client->maxKC); - client->smart_start_tick = SmartScheduleTime; - client->smart_stop_tick = SmartScheduleTime; - client->smart_check_tick = SmartScheduleTime; -} - -/************************ - * int NextAvailableClient(ospriv) - * - * OS dependent portion can't assign client id's because of CloseDownModes. - * Returns NULL if there are no free clients. - *************************/ - -ClientPtr NextAvailableClient(pointer ospriv) -{ - int i; - ClientPtr client; - xReq data; - - i = nextFreeClientID; - if (i == MAXCLIENTS) - return (ClientPtr)NULL; - clients[i] = client = xalloc(sizeof(ClientRec)); - if (!client) - return (ClientPtr)NULL; - InitClient(client, i, ospriv); - if (!InitClientResources(client)) - { - xfree(client); - return (ClientPtr)NULL; - } - data.reqType = 1; - data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix); - if (!InsertFakeRequest(client, (char *)&data, sz_xReq)) - { - FreeClientResources(client); - xfree(client); - return (ClientPtr)NULL; - } - if (i == currentMaxClients) - currentMaxClients++; - while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID]) - nextFreeClientID++; - if (ClientStateCallback) - { - NewClientInfoRec clientinfo; - - clientinfo.client = client; - clientinfo.prefix = (xConnSetupPrefix *)NULL; - clientinfo.setup = (xConnSetup *) NULL; - CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); - } - return(client); -} - -int -ProcInitialConnection(ClientPtr client) -{ - REQUEST(xReq); - xConnClientPrefix *prefix; - int whichbyte = 1; - - prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); - if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B')) - return (client->noClientException = -1); - if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) || - (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) - { - client->swapped = TRUE; - SwapConnClientPrefix(prefix); - } - stuff->reqType = 2; - stuff->length += bytes_to_int32(prefix->nbytesAuthProto) + - bytes_to_int32(prefix->nbytesAuthString); - if (client->swapped) - { - swaps(&stuff->length, whichbyte); - } - ResetCurrentRequest(client); - return (client->noClientException); -} - -static int -SendConnSetup(ClientPtr client, char *reason) -{ - xWindowRoot *root; - int i; - int numScreens; - char* lConnectionInfo; - xConnSetupPrefix* lconnSetupPrefix; - - if (reason) - { - xConnSetupPrefix csp; - - csp.success = xFalse; - csp.lengthReason = strlen(reason); - csp.length = bytes_to_int32(csp.lengthReason); - csp.majorVersion = X_PROTOCOL; - csp.minorVersion = X_PROTOCOL_REVISION; - if (client->swapped) - WriteSConnSetupPrefix(client, &csp); - else - (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp); - (void)WriteToClient(client, (int)csp.lengthReason, reason); - return (client->noClientException = -1); - } - - numScreens = screenInfo.numScreens; - lConnectionInfo = ConnectionInfo; - lconnSetupPrefix = &connSetupPrefix; - - /* We're about to start speaking X protocol back to the client by - * sending the connection setup info. This means the authorization - * step is complete, and we can count the client as an - * authorized one. - */ - nClients++; - - client->requestVector = client->swapped ? SwappedProcVector : ProcVector; - client->sequence = 0; - ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask; - ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK; -#ifdef MATCH_CLIENT_ENDIAN - ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client); - ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client); -#endif - /* fill in the "currentInputMask" */ - root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart); -#ifdef PANORAMIX - if (noPanoramiXExtension) - numScreens = screenInfo.numScreens; - else - numScreens = ((xConnSetup *)ConnectionInfo)->numRoots; -#endif - - for (i=0; i<numScreens; i++) - { - unsigned int j; - xDepth *pDepth; - - root->currentInputMask = WindowTable[i]->eventMask | - wOtherEventMasks (WindowTable[i]); - pDepth = (xDepth *)(root + 1); - for (j = 0; j < root->nDepths; j++) - { - pDepth = (xDepth *)(((char *)(pDepth + 1)) + - pDepth->nVisuals * sizeof(xVisualType)); - } - root = (xWindowRoot *)pDepth; - } - - if (client->swapped) - { - WriteSConnSetupPrefix(client, lconnSetupPrefix); - WriteSConnectionInfo(client, - (unsigned long)(lconnSetupPrefix->length << 2), - lConnectionInfo); - } - else - { - (void)WriteToClient(client, sizeof(xConnSetupPrefix), - (char *) lconnSetupPrefix); - (void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2), - lConnectionInfo); - } - client->clientState = ClientStateRunning; - if (ClientStateCallback) - { - NewClientInfoRec clientinfo; - - clientinfo.client = client; - clientinfo.prefix = lconnSetupPrefix; - clientinfo.setup = (xConnSetup *)lConnectionInfo; - CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); - } - return (client->noClientException); -} - -int -ProcEstablishConnection(ClientPtr client) -{ - char *reason, *auth_proto, *auth_string; - xConnClientPrefix *prefix; - REQUEST(xReq); - - prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); - auth_proto = (char *)prefix + sz_xConnClientPrefix; - auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto); - if ((prefix->majorVersion != X_PROTOCOL) || - (prefix->minorVersion != X_PROTOCOL_REVISION)) - reason = "Protocol version mismatch"; - else - reason = ClientAuthorized(client, - (unsigned short)prefix->nbytesAuthProto, - auth_proto, - (unsigned short)prefix->nbytesAuthString, - auth_string); - /* - * If Kerberos is being used for this client, the clientState - * will be set to ClientStateAuthenticating at this point. - * More messages need to be exchanged among the X server, Kerberos - * server, and client to figure out if everyone is authorized. - * So we don't want to send the connection setup info yet, since - * the auth step isn't really done. - */ - if (client->clientState == ClientStateCheckingSecurity) - client->clientState = ClientStateCheckedSecurity; - else if (client->clientState != ClientStateAuthenticating) - return(SendConnSetup(client, reason)); - return(client->noClientException); -} - -void -SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, - XID resId, int errorCode) -{ - xError rep; - - memset(&rep, 0, sizeof(xError)); - rep.type = X_Error; - rep.sequenceNumber = client->sequence; - rep.errorCode = errorCode; - rep.majorCode = majorCode; - rep.minorCode = minorCode; - rep.resourceID = resId; - - WriteEventsToClient (client, 1, (xEvent *)&rep); -} - -void -MarkClientException(ClientPtr client) -{ - client->noClientException = -1; -} - -/* - * This array encodes the answer to the question "what is the log base 2 - * of the number of pixels that fit in a scanline pad unit?" - * Note that ~0 is an invalid entry (mostly for the benefit of the reader). - */ -static int answer[6][4] = { - /* pad pad pad pad*/ - /* 8 16 32 64 */ - - { 3, 4, 5 , 6 }, /* 1 bit per pixel */ - { 1, 2, 3 , 4 }, /* 4 bits per pixel */ - { 0, 1, 2 , 3 }, /* 8 bits per pixel */ - { ~0, 0, 1 , 2 }, /* 16 bits per pixel */ - { ~0, ~0, 0 , 1 }, /* 24 bits per pixel */ - { ~0, ~0, 0 , 1 } /* 32 bits per pixel */ -}; - -/* - * This array gives the answer to the question "what is the first index for - * the answer array above given the number of bits per pixel?" - * Note that ~0 is an invalid entry (mostly for the benefit of the reader). - */ -static int indexForBitsPerPixel[ 33 ] = { - ~0, 0, ~0, ~0, /* 1 bit per pixel */ - 1, ~0, ~0, ~0, /* 4 bits per pixel */ - 2, ~0, ~0, ~0, /* 8 bits per pixel */ - ~0,~0, ~0, ~0, - 3, ~0, ~0, ~0, /* 16 bits per pixel */ - ~0,~0, ~0, ~0, - 4, ~0, ~0, ~0, /* 24 bits per pixel */ - ~0,~0, ~0, ~0, - 5 /* 32 bits per pixel */ -}; - -/* - * This array gives the bytesperPixel value for cases where the number - * of bits per pixel is a multiple of 8 but not a power of 2. - */ -static int answerBytesPerPixel[ 33 ] = { - ~0, 0, ~0, ~0, /* 1 bit per pixel */ - 0, ~0, ~0, ~0, /* 4 bits per pixel */ - 0, ~0, ~0, ~0, /* 8 bits per pixel */ - ~0,~0, ~0, ~0, - 0, ~0, ~0, ~0, /* 16 bits per pixel */ - ~0,~0, ~0, ~0, - 3, ~0, ~0, ~0, /* 24 bits per pixel */ - ~0,~0, ~0, ~0, - 0 /* 32 bits per pixel */ -}; - -/* - * This array gives the answer to the question "what is the second index for - * the answer array above given the number of bits per scanline pad unit?" - * Note that ~0 is an invalid entry (mostly for the benefit of the reader). - */ -static int indexForScanlinePad[ 65 ] = { - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */ - ~0, ~0, ~0, ~0, - 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */ - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */ - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - ~0, ~0, ~0, ~0, - 3 /* 64 bits per scanline pad unit */ -}; - -/* - grow the array of screenRecs if necessary. - call the device-supplied initialization procedure -with its screen number, a pointer to its ScreenRec, argc, and argv. - return the number of successfully installed screens. - -*/ - -int -AddScreen( - Bool (* pfnInit)( - int /*index*/, - ScreenPtr /*pScreen*/, - int /*argc*/, - char ** /*argv*/ - ), - int argc, - char **argv) -{ - - int i; - int scanlinepad, format, depth, bitsPerPixel, j, k; - ScreenPtr pScreen; - - i = screenInfo.numScreens; - if (i == MAXSCREENS) - return -1; - - pScreen = (ScreenPtr) xcalloc(1, sizeof(ScreenRec)); - if (!pScreen) - return -1; - - pScreen->devPrivates = NULL; - pScreen->myNum = i; - pScreen->totalPixmapSize = BitmapBytePad(sizeof(PixmapRec)*8); - pScreen->ClipNotify = 0; /* for R4 ddx compatibility */ - pScreen->CreateScreenResources = 0; - - /* - * This loop gets run once for every Screen that gets added, - * but thats ok. If the ddx layer initializes the formats - * one at a time calling AddScreen() after each, then each - * iteration will make it a little more accurate. Worst case - * we do this loop N * numPixmapFormats where N is # of screens. - * Anyway, this must be called after InitOutput and before the - * screen init routine is called. - */ - for (format=0; format<screenInfo.numPixmapFormats; format++) - { - depth = screenInfo.formats[format].depth; - bitsPerPixel = screenInfo.formats[format].bitsPerPixel; - scanlinepad = screenInfo.formats[format].scanlinePad; - j = indexForBitsPerPixel[ bitsPerPixel ]; - k = indexForScanlinePad[ scanlinepad ]; - PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k]; - PixmapWidthPaddingInfo[ depth ].padRoundUp = - (scanlinepad/bitsPerPixel) - 1; - j = indexForBitsPerPixel[ 8 ]; /* bits per byte */ - PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k]; - PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel; - if (answerBytesPerPixel[bitsPerPixel]) - { - PixmapWidthPaddingInfo[ depth ].notPower2 = 1; - PixmapWidthPaddingInfo[ depth ].bytesPerPixel = - answerBytesPerPixel[bitsPerPixel]; - } - else - { - PixmapWidthPaddingInfo[ depth ].notPower2 = 0; - } - } - - /* This is where screen specific stuff gets initialized. Load the - screen structure, call the hardware, whatever. - This is also where the default colormap should be allocated and - also pixel values for blackPixel, whitePixel, and the cursor - Note that InitScreen is NOT allowed to modify argc, argv, or - any of the strings pointed to by argv. They may be passed to - multiple screens. - */ - pScreen->rgf = ~0L; /* there are no scratch GCs yet*/ - WindowTable[i] = NullWindow; - screenInfo.screens[i] = pScreen; - screenInfo.numScreens++; - if (!(*pfnInit)(i, pScreen, argc, argv)) - { - dixFreePrivates(pScreen->devPrivates); - xfree(pScreen); - screenInfo.numScreens--; - return -1; - } - return i; -} +/************************************************************
+
+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.
+
+********************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/* XSERVER_DTRACE additions:
+ * Copyright 2005-2006 Sun Microsystems, 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 (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 <dix-config.h>
+#include <version-config.h>
+#endif
+
+#ifdef CreateWindow
+#undef CreateWindow
+#endif
+
+#ifdef PANORAMIX_DEBUG
+#include <stdio.h>
+int ProcInitialConnection();
+#endif
+
+#include "windowstr.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "gcstruct.h"
+#include "selection.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "opaque.h"
+#include "input.h"
+#include "servermd.h"
+#include "extnsionst.h"
+#include "dixfont.h"
+#include "dispatch.h"
+#include "swaprep.h"
+#include "swapreq.h"
+#include "privates.h"
+#include "xace.h"
+#include "inputstr.h"
+#include "xkbsrv.h"
+#include "site.h"
+
+#ifdef XSERVER_DTRACE
+#include "registry.h"
+#include <sys/types.h>
+typedef const char *string;
+#include "Xserver-dtrace.h"
+#endif
+
+#define mskcnt ((MAXCLIENTS + 31) / 32)
+#define BITMASK(i) (1U << ((i) & 31))
+#define MASKIDX(i) ((i) >> 5)
+#define MASKWORD(buf, i) buf[MASKIDX(i)]
+#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
+#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
+#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
+
+xConnSetupPrefix connSetupPrefix;
+
+PaddingInfo PixmapWidthPaddingInfo[33];
+
+static ClientPtr grabClient;
+#define GrabNone 0
+#define GrabActive 1
+#define GrabKickout 2
+static int grabState = GrabNone;
+static long grabWaiters[mskcnt];
+CallbackListPtr ServerGrabCallback = NULL;
+HWEventQueuePtr checkForInput[2];
+int connBlockScreenStart;
+
+static void KillAllClients(void);
+
+static int nextFreeClientID; /* always MIN free client ID */
+
+static int nClients; /* number of authorized clients */
+
+CallbackListPtr ClientStateCallback;
+
+/* dispatchException & isItTimeToYield must be declared volatile since they
+ * are modified by signal handlers - otherwise optimizer may assume it doesn't
+ * need to actually check value in memory when used and may miss changes from
+ * signal handlers.
+ */
+volatile char dispatchException = 0;
+volatile char isItTimeToYield;
+
+/* Various of the DIX function interfaces were not designed to allow
+ * the client->errorValue to be set on BadValue and other errors.
+ * Rather than changing interfaces and breaking untold code we introduce
+ * a new global that dispatch can use.
+ */
+XID clientErrorValue; /* XXX this is a kludge */
+
+#define SAME_SCREENS(a, b) (\
+ (a.pScreen == b.pScreen))
+
+void
+SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
+{
+ checkForInput[0] = c0;
+ checkForInput[1] = c1;
+}
+
+void
+UpdateCurrentTime(void)
+{
+ TimeStamp systime;
+
+ /* To avoid time running backwards, we must call GetTimeInMillis before
+ * calling ProcessInputEvents.
+ */
+ systime.months = currentTime.months;
+ systime.milliseconds = GetTimeInMillis();
+ if (systime.milliseconds < currentTime.milliseconds)
+ systime.months++;
+ if (*checkForInput[0] != *checkForInput[1])
+ ProcessInputEvents();
+ if (CompareTimeStamps(systime, currentTime) == LATER)
+ currentTime = systime;
+}
+
+/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
+void
+UpdateCurrentTimeIf(void)
+{
+ TimeStamp systime;
+
+ systime.months = currentTime.months;
+ systime.milliseconds = GetTimeInMillis();
+ if (systime.milliseconds < currentTime.milliseconds)
+ systime.months++;
+ if (*checkForInput[0] == *checkForInput[1])
+ currentTime = systime;
+}
+
+
+#undef SMART_DEBUG
+
+#define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */
+#define SMART_SCHEDULE_MAX_SLICE 200 /* ms */
+
+Bool SmartScheduleDisable = FALSE;
+long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
+long SmartScheduleTime;
+int SmartScheduleLatencyLimited = 0;
+static ClientPtr SmartLastClient;
+static int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
+
+#ifdef SMART_DEBUG
+long SmartLastPrint;
+#endif
+
+void Dispatch(void);
+void InitProcVectors(void);
+
+static int
+SmartScheduleClient (int *clientReady, int nready)
+{
+ ClientPtr pClient;
+ int i;
+ int client;
+ int bestPrio, best = 0;
+ int bestRobin, robin;
+ long now = SmartScheduleTime;
+ long idle;
+
+ bestPrio = -0x7fffffff;
+ bestRobin = 0;
+ idle = 2 * SmartScheduleSlice;
+ for (i = 0; i < nready; i++)
+ {
+ client = clientReady[i];
+ pClient = clients[client];
+ /* Praise clients which are idle */
+ if ((now - pClient->smart_check_tick) >= idle)
+ {
+ if (pClient->smart_priority < 0)
+ pClient->smart_priority++;
+ }
+ pClient->smart_check_tick = now;
+
+ /* check priority to select best client */
+ robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff;
+ if (pClient->smart_priority > bestPrio ||
+ (pClient->smart_priority == bestPrio && robin > bestRobin))
+ {
+ bestPrio = pClient->smart_priority;
+ bestRobin = robin;
+ best = client;
+ }
+#ifdef SMART_DEBUG
+ if ((now - SmartLastPrint) >= 5000)
+ fprintf (stderr, " %2d: %3d", client, pClient->smart_priority);
+#endif
+ }
+#ifdef SMART_DEBUG
+ if ((now - SmartLastPrint) >= 5000)
+ {
+ fprintf (stderr, " use %2d\n", best);
+ SmartLastPrint = now;
+ }
+#endif
+ pClient = clients[best];
+ SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index;
+ /*
+ * Set current client pointer
+ */
+ if (SmartLastClient != pClient)
+ {
+ pClient->smart_start_tick = now;
+ SmartLastClient = pClient;
+ }
+ /*
+ * Adjust slice
+ */
+ if (nready == 1 && SmartScheduleLatencyLimited == 0)
+ {
+ /*
+ * If it's been a long time since another client
+ * has run, bump the slice up to get maximal
+ * performance from a single client
+ */
+ if ((now - pClient->smart_start_tick) > 1000 &&
+ SmartScheduleSlice < SmartScheduleMaxSlice)
+ {
+ SmartScheduleSlice += SmartScheduleInterval;
+ }
+ }
+ else
+ {
+ SmartScheduleSlice = SmartScheduleInterval;
+ }
+ return best;
+}
+
+void
+EnableLimitedSchedulingLatency(void)
+{
+ ++SmartScheduleLatencyLimited;
+ SmartScheduleSlice = SmartScheduleInterval;
+}
+
+void
+DisableLimitedSchedulingLatency(void)
+{
+ --SmartScheduleLatencyLimited;
+
+ /* protect against bugs */
+ if (SmartScheduleLatencyLimited < 0)
+ SmartScheduleLatencyLimited = 0;
+}
+
+#define MAJOROP ((xReq *)client->requestBuffer)->reqType
+
+void
+Dispatch(void)
+{
+ int *clientReady; /* array of request ready clients */
+ int result;
+ ClientPtr client;
+ int nready;
+ HWEventQueuePtr* icheck = checkForInput;
+ long start_tick;
+
+ nextFreeClientID = 1;
+ nClients = 0;
+
+ clientReady = xalloc(sizeof(int) * MaxClients);
+ if (!clientReady)
+ return;
+
+ SmartScheduleSlice = SmartScheduleInterval;
+ while (!dispatchException)
+ {
+ if (*icheck[0] != *icheck[1])
+ {
+ ProcessInputEvents();
+ FlushIfCriticalOutputPending();
+ }
+
+ nready = WaitForSomething(clientReady);
+
+ if (nready && !SmartScheduleDisable)
+ {
+ clientReady[0] = SmartScheduleClient (clientReady, nready);
+ nready = 1;
+ }
+ /*****************
+ * Handle events in round robin fashion, doing input between
+ * each round
+ *****************/
+
+ while (!dispatchException && (--nready >= 0))
+ {
+ client = clients[clientReady[nready]];
+ if (! client)
+ {
+ /* KillClient can cause this to happen */
+ continue;
+ }
+ /* GrabServer activation can cause this to be true */
+ if (grabState == GrabKickout)
+ {
+ grabState = GrabActive;
+ break;
+ }
+ isItTimeToYield = FALSE;
+
+ start_tick = SmartScheduleTime;
+ while (!isItTimeToYield)
+ {
+#ifdef XSERVER_DTRACE
+ CARD8 StartMajorOp;
+#endif
+ if (*icheck[0] != *icheck[1])
+ ProcessInputEvents();
+
+ FlushIfCriticalOutputPending();
+ if (!SmartScheduleDisable &&
+ (SmartScheduleTime - start_tick) >= SmartScheduleSlice)
+ {
+ /* Penalize clients which consume ticks */
+ if (client->smart_priority > SMART_MIN_PRIORITY)
+ client->smart_priority--;
+ break;
+ }
+ /* now, finally, deal with client requests */
+
+ result = ReadRequestFromClient(client);
+ if (result <= 0)
+ {
+ if (result < 0)
+ CloseDownClient(client);
+ break;
+ }
+
+ client->sequence++;
+#ifdef XSERVER_DTRACE
+ StartMajorOp=MAJOROP;
+ XSERVER_REQUEST_START(LookupMajorName(StartMajorOp), StartMajorOp,
+ ((xReq *)client->requestBuffer)->length,
+ client->index, client->requestBuffer);
+#endif
+ if (result > (maxBigRequestSize << 2))
+ result = BadLength;
+ else {
+ result = XaceHookDispatch(client, MAJOROP);
+ if (result == Success)
+ result = (* client->requestVector[MAJOROP])(client);
+ XaceHookAuditEnd(client, result);
+ }
+#ifdef XSERVER_DTRACE
+ if (result!=Success)
+ {
+ char Message[255];
+ sprintf(Message,"ERROR: %s (0x%x)",LookupMajorName(StartMajorOp),client->errorValue);
+ XSERVER_REQUEST_DONE(Message, MAJOROP,
+ client->sequence, client->index, result);
+ }
+ else
+ {
+ if (StartMajorOp!=MAJOROP)
+ {
+ char Message[255];
+ sprintf(Message,"Changed request: %s -> %s",LookupMajorName(StartMajorOp),LookupMajorName(MAJOROP));
+ XSERVER_REQUEST_DONE(Message, MAJOROP,
+ client->sequence, client->index, result);
+ }
+ else
+ {
+ XSERVER_REQUEST_DONE(LookupMajorName(MAJOROP), MAJOROP,
+ client->sequence, client->index, result);
+ }
+ }
+#endif
+
+ if (result != Success)
+ {
+ if (client->noClientException != Success)
+ CloseDownClient(client);
+ else
+ SendErrorToClient(client, MAJOROP,
+ MinorOpcodeOfRequest(client),
+ client->errorValue, result);
+ break;
+ }
+ }
+ FlushAllOutput();
+ client = clients[clientReady[nready]];
+ if (client)
+ client->smart_stop_tick = SmartScheduleTime;
+ }
+ dispatchException &= ~DE_PRIORITYCHANGE;
+ }
+#if defined(DDXBEFORERESET)
+ ddxBeforeReset ();
+#endif
+ KillAllClients();
+ xfree(clientReady);
+ dispatchException &= ~DE_RESET;
+ SmartScheduleLatencyLimited = 0;
+}
+
+#undef MAJOROP
+
+static int VendorRelease = VENDOR_RELEASE;
+static char *VendorString = VENDOR_NAME;
+
+static const int padlength[4] = {0, 3, 2, 1};
+
+void
+SetVendorRelease(int release)
+{
+ VendorRelease = release;
+}
+
+void
+SetVendorString(char *string)
+{
+ VendorString = string;
+}
+
+Bool
+CreateConnectionBlock(void)
+{
+ xConnSetup setup;
+ xWindowRoot root;
+ xDepth depth;
+ xVisualType visual;
+ xPixmapFormat format;
+ unsigned long vid;
+ int i, j, k,
+ lenofblock,
+ sizesofar = 0;
+ char *pBuf;
+
+
+ memset(&setup, 0, sizeof(xConnSetup));
+ /* Leave off the ridBase and ridMask, these must be sent with
+ connection */
+
+ setup.release = VendorRelease;
+ /*
+ * per-server image and bitmap parameters are defined in Xmd.h
+ */
+ setup.imageByteOrder = screenInfo.imageByteOrder;
+
+ setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
+ setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
+
+ setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
+ setup.motionBufferSize = NumMotionEvents();
+ setup.numRoots = screenInfo.numScreens;
+ setup.nbytesVendor = strlen(VendorString);
+ setup.numFormats = screenInfo.numPixmapFormats;
+ setup.maxRequestSize = MAX_REQUEST_SIZE;
+ QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
+
+ lenofblock = sizeof(xConnSetup) +
+ pad_to_int32(setup.nbytesVendor) +
+ (setup.numFormats * sizeof(xPixmapFormat)) +
+ (setup.numRoots * sizeof(xWindowRoot));
+ ConnectionInfo = xalloc(lenofblock);
+ if (!ConnectionInfo)
+ return FALSE;
+
+ memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup));
+ sizesofar = sizeof(xConnSetup);
+ pBuf = ConnectionInfo + sizeof(xConnSetup);
+
+ memmove(pBuf, VendorString, (int)setup.nbytesVendor);
+ sizesofar += setup.nbytesVendor;
+ pBuf += setup.nbytesVendor;
+ i = padlength[setup.nbytesVendor & 3];
+ sizesofar += i;
+ while (--i >= 0)
+ *pBuf++ = 0;
+
+ memset(&format, 0, sizeof(xPixmapFormat));
+ for (i=0; i<screenInfo.numPixmapFormats; i++)
+ {
+ format.depth = screenInfo.formats[i].depth;
+ format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
+ format.scanLinePad = screenInfo.formats[i].scanlinePad;
+ memmove(pBuf, (char *)&format, sizeof(xPixmapFormat));
+ pBuf += sizeof(xPixmapFormat);
+ sizesofar += sizeof(xPixmapFormat);
+ }
+
+ connBlockScreenStart = sizesofar;
+ memset(&depth, 0, sizeof(xDepth));
+ memset(&visual, 0, sizeof(xVisualType));
+ for (i=0; i<screenInfo.numScreens; i++)
+ {
+ ScreenPtr pScreen;
+ DepthPtr pDepth;
+ VisualPtr pVisual;
+
+ pScreen = screenInfo.screens[i];
+ root.windowId = WindowTable[i]->drawable.id;
+ root.defaultColormap = pScreen->defColormap;
+ root.whitePixel = pScreen->whitePixel;
+ root.blackPixel = pScreen->blackPixel;
+ root.currentInputMask = 0; /* filled in when sent */
+ root.pixWidth = pScreen->width;
+ root.pixHeight = pScreen->height;
+ root.mmWidth = pScreen->mmWidth;
+ root.mmHeight = pScreen->mmHeight;
+ root.minInstalledMaps = pScreen->minInstalledCmaps;
+ root.maxInstalledMaps = pScreen->maxInstalledCmaps;
+ root.rootVisualID = pScreen->rootVisual;
+ root.backingStore = pScreen->backingStoreSupport;
+ root.saveUnders = FALSE;
+ root.rootDepth = pScreen->rootDepth;
+ root.nDepths = pScreen->numDepths;
+ memmove(pBuf, (char *)&root, sizeof(xWindowRoot));
+ sizesofar += sizeof(xWindowRoot);
+ pBuf += sizeof(xWindowRoot);
+
+ pDepth = pScreen->allowedDepths;
+ for(j = 0; j < pScreen->numDepths; j++, pDepth++)
+ {
+ lenofblock += sizeof(xDepth) +
+ (pDepth->numVids * sizeof(xVisualType));
+ pBuf = (char *)xrealloc(ConnectionInfo, lenofblock);
+ if (!pBuf)
+ {
+ xfree(ConnectionInfo);
+ return FALSE;
+ }
+ ConnectionInfo = pBuf;
+ pBuf += sizesofar;
+ depth.depth = pDepth->depth;
+ depth.nVisuals = pDepth->numVids;
+ memmove(pBuf, (char *)&depth, sizeof(xDepth));
+ pBuf += sizeof(xDepth);
+ sizesofar += sizeof(xDepth);
+ for(k = 0; k < pDepth->numVids; k++)
+ {
+ vid = pDepth->vids[k];
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != vid;
+ pVisual++)
+ ;
+ visual.visualID = vid;
+ visual.class = pVisual->class;
+ visual.bitsPerRGB = pVisual->bitsPerRGBValue;
+ visual.colormapEntries = pVisual->ColormapEntries;
+ visual.redMask = pVisual->redMask;
+ visual.greenMask = pVisual->greenMask;
+ visual.blueMask = pVisual->blueMask;
+ memmove(pBuf, (char *)&visual, sizeof(xVisualType));
+ pBuf += sizeof(xVisualType);
+ sizesofar += sizeof(xVisualType);
+ }
+ }
+ }
+ connSetupPrefix.success = xTrue;
+ connSetupPrefix.length = lenofblock/4;
+ connSetupPrefix.majorVersion = X_PROTOCOL;
+ connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
+ return TRUE;
+}
+
+
+int
+ProcBadRequest(ClientPtr client)
+{
+ return (BadRequest);
+}
+
+int
+ProcCreateWindow(ClientPtr client)
+{
+ WindowPtr pParent, pWin;
+ REQUEST(xCreateWindowReq);
+ int len, rc;
+
+ REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
+
+ LEGAL_NEW_RESOURCE(stuff->wid, client);
+ rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
+ if (rc != Success)
+ return rc;
+ len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq));
+ if (Ones(stuff->mask) != len)
+ return BadLength;
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ pWin = CreateWindow(stuff->wid, pParent, stuff->x,
+ stuff->y, stuff->width, stuff->height,
+ stuff->borderWidth, stuff->class,
+ stuff->mask, (XID *) &stuff[1],
+ (int)stuff->depth,
+ client, stuff->visual, &rc);
+ if (pWin)
+ {
+ Mask mask = pWin->eventMask;
+
+ pWin->eventMask = 0; /* subterfuge in case AddResource fails */
+ if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin))
+ return BadAlloc;
+ pWin->eventMask = mask;
+ }
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return rc;
+}
+
+int
+ProcChangeWindowAttributes(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xChangeWindowAttributesReq);
+ int result, len, rc;
+ Mask access_mode = 0;
+
+ REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
+ access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0;
+ access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0;
+ rc = dixLookupWindow(&pWin, stuff->window, client, access_mode);
+ if (rc != Success)
+ return rc;
+ len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq));
+ if (len != Ones(stuff->valueMask))
+ return BadLength;
+ result = ChangeWindowAttributes(pWin,
+ stuff->valueMask,
+ (XID *) &stuff[1],
+ client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcGetWindowAttributes(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xResourceReq);
+ xGetWindowAttributesReply wa;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ memset(&wa, 0, sizeof(xGetWindowAttributesReply));
+ GetWindowAttributes(pWin, client, &wa);
+ WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
+ return(client->noClientException);
+}
+
+int
+ProcDestroyWindow(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xResourceReq);
+ int rc;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
+ if (rc != Success)
+ return rc;
+ if (pWin->parent) {
+ rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client,
+ DixRemoveAccess);
+ if (rc != Success)
+ return rc;
+ FreeResource(stuff->id, RT_NONE);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcDestroySubwindows(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xResourceReq);
+ int rc;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess);
+ if (rc != Success)
+ return rc;
+ DestroySubwindows(pWin, client);
+ return(client->noClientException);
+}
+
+int
+ProcChangeSaveSet(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xChangeSaveSetReq);
+ int result, rc;
+
+ REQUEST_SIZE_MATCH(xChangeSaveSetReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
+ if (rc != Success)
+ return rc;
+ if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
+ return BadMatch;
+ if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
+ {
+ result = AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ {
+ client->errorValue = stuff->mode;
+ return( BadValue );
+ }
+}
+
+int
+ProcReparentWindow(ClientPtr client)
+{
+ WindowPtr pWin, pParent;
+ REQUEST(xReparentWindowReq);
+ int result, rc;
+
+ REQUEST_SIZE_MATCH(xReparentWindowReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
+ if (rc != Success)
+ return rc;
+ rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
+ if (rc != Success)
+ return rc;
+ if (SAME_SCREENS(pWin->drawable, pParent->drawable))
+ {
+ if ((pWin->backgroundState == ParentRelative) &&
+ (pParent->drawable.depth != pWin->drawable.depth))
+ return BadMatch;
+ if ((pWin->drawable.class != InputOnly) &&
+ (pParent->drawable.class == InputOnly))
+ return BadMatch;
+ result = ReparentWindow(pWin, pParent,
+ (short)stuff->x, (short)stuff->y, client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ else
+ return (BadMatch);
+}
+
+int
+ProcMapWindow(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xResourceReq);
+ int rc;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess);
+ if (rc != Success)
+ return rc;
+ MapWindow(pWin, client);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcMapSubwindows(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xResourceReq);
+ int rc;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
+ if (rc != Success)
+ return rc;
+ MapSubwindows(pWin, client);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcUnmapWindow(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xResourceReq);
+ int rc;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess);
+ if (rc != Success)
+ return rc;
+ UnmapWindow(pWin, FALSE);
+ /* update cache to say it is mapped */
+ return(client->noClientException);
+}
+
+int
+ProcUnmapSubwindows(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xResourceReq);
+ int rc;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
+ if (rc != Success)
+ return rc;
+ UnmapSubwindows(pWin);
+ return(client->noClientException);
+}
+
+int
+ProcConfigureWindow(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xConfigureWindowReq);
+ int result;
+ int len, rc;
+
+ REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client,
+ DixManageAccess|DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq));
+ if (Ones((Mask)stuff->mask) != len)
+ return BadLength;
+ result = ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1],
+ client);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcCirculateWindow(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xCirculateWindowReq);
+ int rc;
+
+ REQUEST_SIZE_MATCH(xCirculateWindowReq);
+ if ((stuff->direction != RaiseLowest) &&
+ (stuff->direction != LowerHighest))
+ {
+ client->errorValue = stuff->direction;
+ return BadValue;
+ }
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
+ if (rc != Success)
+ return rc;
+ CirculateWindow(pWin, (int)stuff->direction, client);
+ return(client->noClientException);
+}
+
+static int
+GetGeometry(ClientPtr client, xGetGeometryReply *rep)
+{
+ DrawablePtr pDraw;
+ int rc;
+ REQUEST(xResourceReq);
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ rep->type = X_Reply;
+ rep->length = 0;
+ rep->sequenceNumber = client->sequence;
+ rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id;
+ rep->depth = pDraw->depth;
+ rep->width = pDraw->width;
+ rep->height = pDraw->height;
+
+ /* XXX - Because the pixmap-implementation of the multibuffer extension
+ * may have the buffer-id's drawable resource value be a pointer
+ * to the buffer's window instead of the buffer itself
+ * (this happens if the buffer is the displayed buffer),
+ * we also have to check that the id matches before we can
+ * truly say that it is a DRAWABLE_WINDOW.
+ */
+
+ if ((pDraw->type == UNDRAWABLE_WINDOW) ||
+ ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id)))
+ {
+ WindowPtr pWin = (WindowPtr)pDraw;
+ rep->x = pWin->origin.x - wBorderWidth (pWin);
+ rep->y = pWin->origin.y - wBorderWidth (pWin);
+ rep->borderWidth = pWin->borderWidth;
+ }
+ else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */
+ {
+ rep->x = rep->y = rep->borderWidth = 0;
+ }
+
+ return Success;
+}
+
+
+int
+ProcGetGeometry(ClientPtr client)
+{
+ xGetGeometryReply rep;
+ int status;
+
+ memset(&rep, 0, sizeof(xGetGeometryReply));
+ if ((status = GetGeometry(client, &rep)) != Success)
+ return status;
+
+ WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
+ return(client->noClientException);
+}
+
+#ifdef WIN32
+/* Do not return the clipboard window in ProcQueryTree, cause this may cause
+ the clipboard client being closed when connecting through xdmcp.
+*/
+extern int g_iClipboardWindow;
+
+#endif
+
+int
+ProcQueryTree(ClientPtr client)
+{
+ xQueryTreeReply reply;
+ int rc, numChildren = 0;
+ WindowPtr pChild, pWin, pHead;
+ Window *childIDs = (Window *)NULL;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
+ if (rc != Success)
+ return rc;
+ memset(&reply, 0, sizeof(xQueryTreeReply));
+ reply.type = X_Reply;
+ reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
+ reply.sequenceNumber = client->sequence;
+ if (pWin->parent)
+ reply.parent = pWin->parent->drawable.id;
+ else
+ reply.parent = (Window)None;
+ pHead = RealChildHead(pWin);
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+#ifdef WIN32
+ if (pChild->drawable.id!=g_iClipboardWindow)
+#endif
+ numChildren++;
+ if (numChildren)
+ {
+ int curChild = 0;
+
+ childIDs = xalloc(numChildren * sizeof(Window));
+ if (!childIDs)
+ return BadAlloc;
+ for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
+#ifdef WIN32
+ if (pChild->drawable.id!=g_iClipboardWindow)
+#endif
+ childIDs[curChild++] = pChild->drawable.id;
+ }
+
+ reply.nChildren = numChildren;
+ reply.length = bytes_to_int32(numChildren * sizeof(Window));
+
+ WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
+ if (numChildren)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs);
+ xfree(childIDs);
+ }
+
+ return(client->noClientException);
+}
+
+int
+ProcInternAtom(ClientPtr client)
+{
+ Atom atom;
+ char *tchar;
+ REQUEST(xInternAtomReq);
+
+ REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
+ if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse))
+ {
+ client->errorValue = stuff->onlyIfExists;
+ return(BadValue);
+ }
+ tchar = (char *) &stuff[1];
+ atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
+ if (atom != BAD_RESOURCE)
+ {
+ xInternAtomReply reply;
+ memset(&reply, 0, sizeof(xInternAtomReply));
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.atom = atom;
+ WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
+ return(client->noClientException);
+ }
+ else
+ return (BadAlloc);
+}
+
+int
+ProcGetAtomName(ClientPtr client)
+{
+ const char *str;
+ xGetAtomNameReply reply;
+ int len;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if ( (str = NameForAtom(stuff->id)) )
+ {
+ len = strlen(str);
+ memset(&reply, 0, sizeof(xGetAtomNameReply));
+ reply.type = X_Reply;
+ reply.length = bytes_to_int32(len);
+ reply.sequenceNumber = client->sequence;
+ reply.nameLength = len;
+ WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
+ (void)WriteToClient(client, len, str);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (BadAtom);
+ }
+}
+
+int
+ProcGrabServer(ClientPtr client)
+{
+ int rc;
+ REQUEST_SIZE_MATCH(xReq);
+ if (grabState != GrabNone && client != grabClient)
+ {
+ ResetCurrentRequest(client);
+ client->sequence--;
+ BITSET(grabWaiters, client->index);
+ IgnoreClient(client);
+ return(client->noClientException);
+ }
+ rc = OnlyListenToOneClient(client);
+ if (rc != Success)
+ return rc;
+ grabState = GrabKickout;
+ grabClient = client;
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = SERVER_GRABBED;
+ CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+ }
+
+ return(client->noClientException);
+}
+
+static void
+UngrabServer(ClientPtr client)
+{
+ int i;
+
+ grabState = GrabNone;
+ ListenToAllClients();
+ for (i = mskcnt; --i >= 0 && !grabWaiters[i]; )
+ ;
+ if (i >= 0)
+ {
+ i <<= 5;
+ while (!GETBIT(grabWaiters, i))
+ i++;
+ BITCLEAR(grabWaiters, i);
+ AttendClient(clients[i]);
+ }
+
+ if (ServerGrabCallback)
+ {
+ ServerGrabInfoRec grabinfo;
+ grabinfo.client = client;
+ grabinfo.grabstate = SERVER_UNGRABBED;
+ CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo);
+ }
+}
+
+int
+ProcUngrabServer(ClientPtr client)
+{
+ REQUEST_SIZE_MATCH(xReq);
+ UngrabServer(client);
+ return(client->noClientException);
+}
+
+int
+ProcTranslateCoords(ClientPtr client)
+{
+ REQUEST(xTranslateCoordsReq);
+
+ WindowPtr pWin, pDst;
+ xTranslateCoordsReply rep;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xTranslateCoordsReq);
+ rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ memset(&rep, 0, sizeof(xTranslateCoordsReply));
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (!SAME_SCREENS(pWin->drawable, pDst->drawable))
+ {
+ rep.sameScreen = xFalse;
+ rep.child = None;
+ rep.dstX = rep.dstY = 0;
+ }
+ else
+ {
+ INT16 x, y;
+ rep.sameScreen = xTrue;
+ rep.child = None;
+ /* computing absolute coordinates -- adjust to destination later */
+ x = pWin->drawable.x + stuff->srcX;
+ y = pWin->drawable.y + stuff->srcY;
+ pWin = pDst->firstChild;
+ while (pWin)
+ {
+ BoxRec box;
+ if ((pWin->mapped) &&
+ (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+ (x < pWin->drawable.x + (int)pWin->drawable.width +
+ wBorderWidth (pWin)) &&
+ (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+ (y < pWin->drawable.y + (int)pWin->drawable.height +
+ wBorderWidth (pWin))
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ &pWin->borderSize, x, y, &box))
+
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
+ )
+ {
+ rep.child = pWin->drawable.id;
+ pWin = (WindowPtr) NULL;
+ }
+ else
+ pWin = pWin->nextSib;
+ }
+ /* adjust to destination coordinates */
+ rep.dstX = x - pDst->drawable.x;
+ rep.dstY = y - pDst->drawable.y;
+ }
+ WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
+ return(client->noClientException);
+}
+
+int
+ProcOpenFont(ClientPtr client)
+{
+ int err;
+ REQUEST(xOpenFontReq);
+
+ REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
+ client->errorValue = stuff->fid;
+ LEGAL_NEW_RESOURCE(stuff->fid, client);
+ err = OpenFont(client, stuff->fid, (Mask) 0,
+ stuff->nbytes, (char *)&stuff[1]);
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcCloseFont(ClientPtr client)
+{
+ FontPtr pFont;
+ int rc;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ rc = dixLookupResourceByType((pointer *)&pFont, stuff->id, RT_FONT,
+ client, DixDestroyAccess);
+ if (rc == Success)
+ {
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (rc == BadValue) ? BadFont : rc;
+ }
+}
+
+int
+ProcQueryFont(ClientPtr client)
+{
+ xQueryFontReply *reply;
+ FontPtr pFont;
+ GC *pGC;
+ int rc;
+ REQUEST(xResourceReq);
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ client->errorValue = stuff->id; /* EITHER font or gc */
+ rc = dixLookupResourceByType((pointer *)&pFont, stuff->id, RT_FONT, client,
+ DixGetAttrAccess);
+ if (rc == BadValue) {
+ rc = dixLookupResourceByType((pointer *)&pGC, stuff->id, RT_GC, client,
+ DixGetAttrAccess);
+ if (rc == Success)
+ pFont = pGC->font;
+ }
+ if (rc != Success)
+ return (rc == BadValue) ? BadFont: rc;
+
+ {
+ xCharInfo *pmax = FONTINKMAX(pFont);
+ xCharInfo *pmin = FONTINKMIN(pFont);
+ int nprotoxcistructs;
+ int rlength;
+
+ nprotoxcistructs = (
+ pmax->rightSideBearing == pmin->rightSideBearing &&
+ pmax->leftSideBearing == pmin->leftSideBearing &&
+ pmax->descent == pmin->descent &&
+ pmax->ascent == pmin->ascent &&
+ pmax->characterWidth == pmin->characterWidth) ?
+ 0 : N2dChars(pFont);
+
+ rlength = sizeof(xQueryFontReply) +
+ FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) +
+ nprotoxcistructs * sizeof(xCharInfo);
+ reply = xcalloc(1, rlength);
+ if(!reply)
+ {
+ return(BadAlloc);
+ }
+
+ reply->type = X_Reply;
+ reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
+ reply->sequenceNumber = client->sequence;
+ QueryFont( pFont, reply, nprotoxcistructs);
+
+ WriteReplyToClient(client, rlength, reply);
+ xfree(reply);
+ return(client->noClientException);
+ }
+}
+
+int
+ProcQueryTextExtents(ClientPtr client)
+{
+ xQueryTextExtentsReply reply;
+ FontPtr pFont;
+ GC *pGC;
+ ExtentInfoRec info;
+ unsigned long length;
+ int rc;
+ REQUEST(xQueryTextExtentsReq);
+ REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
+
+ client->errorValue = stuff->fid; /* EITHER font or gc */
+ rc = dixLookupResourceByType((pointer *)&pFont, stuff->fid, RT_FONT, client,
+ DixGetAttrAccess);
+ if (rc == BadValue) {
+ rc = dixLookupResourceByType((pointer *)&pGC, stuff->fid, RT_GC, client,
+ DixGetAttrAccess);
+ if (rc == Success)
+ pFont = pGC->font;
+ }
+ if (rc != Success)
+ return (rc == BadValue) ? BadFont: rc;
+
+ length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq));
+ length = length << 1;
+ if (stuff->oddLength)
+ {
+ if (length == 0)
+ return(BadLength);
+ length--;
+ }
+ if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info))
+ return(BadAlloc);
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.drawDirection = info.drawDirection;
+ reply.fontAscent = info.fontAscent;
+ reply.fontDescent = info.fontDescent;
+ reply.overallAscent = info.overallAscent;
+ reply.overallDescent = info.overallDescent;
+ reply.overallWidth = info.overallWidth;
+ reply.overallLeft = info.overallLeft;
+ reply.overallRight = info.overallRight;
+ WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
+ return(client->noClientException);
+}
+
+int
+ProcListFonts(ClientPtr client)
+{
+ REQUEST(xListFontsReq);
+
+ REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
+
+ return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
+ stuff->maxNames);
+}
+
+int
+ProcListFontsWithInfo(ClientPtr client)
+{
+ REQUEST(xListFontsWithInfoReq);
+
+ REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
+
+ return StartListFontsWithInfo(client, stuff->nbytes,
+ (unsigned char *) &stuff[1], stuff->maxNames);
+}
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+dixDestroyPixmap(pointer value, XID pid)
+{
+ PixmapPtr pPixmap = (PixmapPtr)value;
+ return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap);
+}
+
+int
+ProcCreatePixmap(ClientPtr client)
+{
+ PixmapPtr pMap;
+ DrawablePtr pDraw;
+ REQUEST(xCreatePixmapReq);
+ DepthPtr pDepth;
+ int i, rc;
+
+ REQUEST_SIZE_MATCH(xCreatePixmapReq);
+ client->errorValue = stuff->pid;
+ LEGAL_NEW_RESOURCE(stuff->pid, client);
+
+ rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
+ DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!stuff->width || !stuff->height)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+ if (stuff->width > 32767 || stuff->height > 32767)
+ {
+ /* It is allowed to try and allocate a pixmap which is larger than
+ * 32767 in either dimension. However, all of the framebuffer code
+ * is buggy and does not reliably draw to such big pixmaps, basically
+ * because the Region data structure operates with signed shorts
+ * for the rectangles in it.
+ *
+ * Furthermore, several places in the X server computes the
+ * size in bytes of the pixmap and tries to store it in an
+ * integer. This integer can overflow and cause the allocated size
+ * to be much smaller.
+ *
+ * So, such big pixmaps are rejected here with a BadAlloc
+ */
+ return BadAlloc;
+ }
+ if (stuff->depth != 1)
+ {
+ pDepth = pDraw->pScreen->allowedDepths;
+ for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
+ if (pDepth->depth == stuff->depth)
+ goto CreatePmap;
+ client->errorValue = stuff->depth;
+ return BadValue;
+ }
+CreatePmap:
+ pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap)
+ (pDraw->pScreen, stuff->width,
+ stuff->height, stuff->depth, 0);
+ if (pMap)
+ {
+ pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ pMap->drawable.id = stuff->pid;
+ /* security creation/labeling check */
+ rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
+ pMap, RT_NONE, NULL, DixCreateAccess);
+ if (rc != Success) {
+ (*pDraw->pScreen->DestroyPixmap)(pMap);
+ return rc;
+ }
+ if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
+ return(client->noClientException);
+ (*pDraw->pScreen->DestroyPixmap)(pMap);
+ }
+ return (BadAlloc);
+}
+
+int
+ProcFreePixmap(ClientPtr client)
+{
+ PixmapPtr pMap;
+ int rc;
+ REQUEST(xResourceReq);
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ rc = dixLookupResourceByType((pointer *)&pMap, stuff->id, RT_PIXMAP, client,
+ DixDestroyAccess);
+ if (rc == Success)
+ {
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (rc == BadValue) ? BadPixmap : rc;
+ }
+}
+
+int
+ProcCreateGC(ClientPtr client)
+{
+ int error, rc;
+ GC *pGC;
+ DrawablePtr pDraw;
+ unsigned len;
+ REQUEST(xCreateGCReq);
+
+ REQUEST_AT_LEAST_SIZE(xCreateGCReq);
+ client->errorValue = stuff->gc;
+ LEGAL_NEW_RESOURCE(stuff->gc, client);
+ rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
+ DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq));
+ if (len != Ones(stuff->mask))
+ return BadLength;
+ pGC = (GC *)CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error,
+ stuff->gc, client);
+ if (error != Success)
+ return error;
+ if (!AddResource(stuff->gc, RT_GC, (pointer)pGC))
+ return (BadAlloc);
+ return(client->noClientException);
+}
+
+int
+ProcChangeGC(ClientPtr client)
+{
+ GC *pGC;
+ int result;
+ unsigned len;
+ REQUEST(xChangeGCReq);
+ REQUEST_AT_LEAST_SIZE(xChangeGCReq);
+
+ result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
+ if (result != Success)
+ return result;
+
+ len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq));
+ if (len != Ones(stuff->mask))
+ return BadLength;
+
+ result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcCopyGC(ClientPtr client)
+{
+ GC *dstGC;
+ GC *pGC;
+ int result;
+ REQUEST(xCopyGCReq);
+ REQUEST_SIZE_MATCH(xCopyGCReq);
+
+ result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess);
+ if (result != Success)
+ return result;
+ result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess);
+ if (result != Success)
+ return result;
+ if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
+ return (BadMatch);
+ result = CopyGC(pGC, dstGC, stuff->mask);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcSetDashes(ClientPtr client)
+{
+ GC *pGC;
+ int result;
+ REQUEST(xSetDashesReq);
+
+ REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
+ if (stuff->nDashes == 0)
+ {
+ client->errorValue = 0;
+ return BadValue;
+ }
+
+ result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess);
+ if (result != Success)
+ return result;
+
+ result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
+ (unsigned char *)&stuff[1]);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return(result);
+ }
+}
+
+int
+ProcSetClipRectangles(ClientPtr client)
+{
+ int nr, result;
+ GC *pGC;
+ REQUEST(xSetClipRectanglesReq);
+
+ REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
+ if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
+ (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded))
+ {
+ client->errorValue = stuff->ordering;
+ return BadValue;
+ }
+ result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess);
+ if (result != Success)
+ return result;
+
+ nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
+ if (nr & 4)
+ return(BadLength);
+ nr >>= 3;
+ result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
+ nr, (xRectangle *)&stuff[1], (int)stuff->ordering);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+}
+
+int
+ProcFreeGC(ClientPtr client)
+{
+ GC *pGC;
+ int rc;
+ REQUEST(xResourceReq);
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess);
+ if (rc != Success)
+ return rc;
+
+ FreeResource(stuff->id, RT_NONE);
+ return(client->noClientException);
+}
+
+int
+ProcClearToBackground(ClientPtr client)
+{
+ REQUEST(xClearAreaReq);
+ WindowPtr pWin;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xClearAreaReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
+ if (rc != Success)
+ return rc;
+ if (pWin->drawable.class == InputOnly)
+ {
+ client->errorValue = stuff->window;
+ return (BadMatch);
+ }
+ if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse))
+ {
+ client->errorValue = stuff->exposures;
+ return(BadValue);
+ }
+ (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y,
+ stuff->width, stuff->height,
+ (Bool)stuff->exposures);
+ return(client->noClientException);
+}
+
+int
+ProcCopyArea(ClientPtr client)
+{
+ DrawablePtr pDst;
+ DrawablePtr pSrc;
+ GC *pGC;
+ REQUEST(xCopyAreaReq);
+ RegionPtr pRgn;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xCopyAreaReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess);
+ if (stuff->dstDrawable != stuff->srcDrawable)
+ {
+ rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+ if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth))
+ {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ }
+ else
+ pSrc = pDst;
+
+ pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
+ stuff->width, stuff->height,
+ stuff->dstX, stuff->dstY);
+ if (pGC->graphicsExposures)
+ {
+ (*pDst->pScreen->SendGraphicsExpose)
+ (client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
+ if (pRgn)
+ REGION_DESTROY(pDst->pScreen, pRgn);
+ }
+
+ return(client->noClientException);
+}
+
+int
+ProcCopyPlane(ClientPtr client)
+{
+ DrawablePtr psrcDraw, pdstDraw;
+ GC *pGC;
+ REQUEST(xCopyPlaneReq);
+ RegionPtr pRgn;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xCopyPlaneReq);
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
+ if (stuff->dstDrawable != stuff->srcDrawable)
+ {
+ rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
+ DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ if (pdstDraw->pScreen != psrcDraw->pScreen)
+ {
+ client->errorValue = stuff->dstDrawable;
+ return (BadMatch);
+ }
+ }
+ else
+ psrcDraw = pdstDraw;
+
+ /* Check to see if stuff->bitPlane has exactly ONE good bit set */
+ if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
+ (stuff->bitPlane > (1L << (psrcDraw->depth - 1))))
+ {
+ client->errorValue = stuff->bitPlane;
+ return(BadValue);
+ }
+
+ pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY,
+ stuff->width, stuff->height,
+ stuff->dstX, stuff->dstY, stuff->bitPlane);
+ if (pGC->graphicsExposures)
+ {
+ (*pdstDraw->pScreen->SendGraphicsExpose)
+ (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
+ if (pRgn)
+ REGION_DESTROY(pdstDraw->pScreen, pRgn);
+ }
+ return(client->noClientException);
+}
+
+int
+ProcPolyPoint(ClientPtr client)
+{
+ int npoint;
+ GC *pGC;
+ DrawablePtr pDraw;
+ REQUEST(xPolyPointReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyPointReq);
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
+ npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
+ if (npoint)
+ (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
+ (xPoint *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcPolyLine(ClientPtr client)
+{
+ int npoint;
+ GC *pGC;
+ DrawablePtr pDraw;
+ REQUEST(xPolyLineReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyLineReq);
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
+ npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
+ if (npoint > 1)
+ (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint,
+ (DDXPointPtr) &stuff[1]);
+ return(client->noClientException);
+}
+
+int
+ProcPolySegment(ClientPtr client)
+{
+ int nsegs;
+ GC *pGC;
+ DrawablePtr pDraw;
+ REQUEST(xPolySegmentReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
+ nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
+ if (nsegs & 4)
+ return(BadLength);
+ nsegs >>= 3;
+ if (nsegs)
+ (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcPolyRectangle (ClientPtr client)
+{
+ int nrects;
+ GC *pGC;
+ DrawablePtr pDraw;
+ REQUEST(xPolyRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
+ nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
+ if (nrects & 4)
+ return(BadLength);
+ nrects >>= 3;
+ if (nrects)
+ (*pGC->ops->PolyRectangle)(pDraw, pGC,
+ nrects, (xRectangle *) &stuff[1]);
+ return(client->noClientException);
+}
+
+int
+ProcPolyArc(ClientPtr client)
+{
+ int narcs;
+ GC *pGC;
+ DrawablePtr pDraw;
+ REQUEST(xPolyArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyArcReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
+ narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
+ if (narcs % sizeof(xArc))
+ return(BadLength);
+ narcs /= sizeof(xArc);
+ if (narcs)
+ (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcFillPoly(ClientPtr client)
+{
+ int things;
+ GC *pGC;
+ DrawablePtr pDraw;
+ REQUEST(xFillPolyReq);
+
+ REQUEST_AT_LEAST_SIZE(xFillPolyReq);
+ if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
+ (stuff->shape != Convex))
+ {
+ client->errorValue = stuff->shape;
+ return BadValue;
+ }
+ if ((stuff->coordMode != CoordModeOrigin) &&
+ (stuff->coordMode != CoordModePrevious))
+ {
+ client->errorValue = stuff->coordMode;
+ return BadValue;
+ }
+
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
+ things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
+ if (things)
+ (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
+ stuff->coordMode, things,
+ (DDXPointPtr) &stuff[1]);
+ return(client->noClientException);
+}
+
+int
+ProcPolyFillRectangle(ClientPtr client)
+{
+ int things;
+ GC *pGC;
+ DrawablePtr pDraw;
+ REQUEST(xPolyFillRectangleReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
+ things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
+ if (things & 4)
+ return(BadLength);
+ things >>= 3;
+
+ if (things)
+ (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
+ (xRectangle *) &stuff[1]);
+ return (client->noClientException);
+}
+
+int
+ProcPolyFillArc(ClientPtr client)
+{
+ int narcs;
+ GC *pGC;
+ DrawablePtr pDraw;
+ REQUEST(xPolyFillArcReq);
+
+ REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
+ narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
+ if (narcs % sizeof(xArc))
+ return(BadLength);
+ narcs /= sizeof(xArc);
+ if (narcs)
+ (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
+ return (client->noClientException);
+}
+
+#ifdef MATCH_CLIENT_ENDIAN
+
+int
+ServerOrder (void)
+{
+ int whichbyte = 1;
+
+ if (*((char *) &whichbyte))
+ return LSBFirst;
+ return MSBFirst;
+}
+
+#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
+
+void
+ReformatImage (char *base, int nbytes, int bpp, int order)
+{
+ switch (bpp) {
+ case 1: /* yuck */
+ if (BITMAP_BIT_ORDER != order)
+ BitOrderInvert ((unsigned char *) base, nbytes);
+#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
+ ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order);
+#endif
+ break;
+ case 4:
+ break; /* yuck */
+ case 8:
+ break;
+ case 16:
+ if (IMAGE_BYTE_ORDER != order)
+ TwoByteSwap ((unsigned char *) base, nbytes);
+ break;
+ case 32:
+ if (IMAGE_BYTE_ORDER != order)
+ FourByteSwap ((unsigned char *) base, nbytes);
+ break;
+ }
+}
+#else
+#define ReformatImage(b,n,bpp,o)
+#endif
+
+/* 64-bit server notes: the protocol restricts padding of images to
+ * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
+ * to use internally. Removes need for internal alignment checking.
+ * All of the PutImage functions could be changed individually, but
+ * as currently written, they call other routines which require things
+ * to be 64-bit padded on scanlines, so we changed things here.
+ * If an image would be padded differently for 64- versus 32-, then
+ * copy each scanline to a 64-bit padded scanline.
+ * Also, we need to make sure that the image is aligned on a 64-bit
+ * boundary, even if the scanlines are padded to our satisfaction.
+ */
+int
+ProcPutImage(ClientPtr client)
+{
+ GC *pGC;
+ DrawablePtr pDraw;
+ long length; /* length of scanline server padded */
+ long lengthProto; /* length of scanline protocol padded */
+ char *tmpImage;
+ REQUEST(xPutImageReq);
+
+ REQUEST_AT_LEAST_SIZE(xPutImageReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
+ if (stuff->format == XYBitmap)
+ {
+ if ((stuff->depth != 1) ||
+ (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+ return BadMatch;
+ length = BitmapBytePad(stuff->width + stuff->leftPad);
+ }
+ else if (stuff->format == XYPixmap)
+ {
+ if ((pDraw->depth != stuff->depth) ||
+ (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad))
+ return BadMatch;
+ length = BitmapBytePad(stuff->width + stuff->leftPad);
+ length *= stuff->depth;
+ }
+ else if (stuff->format == ZPixmap)
+ {
+ if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
+ return BadMatch;
+ length = PixmapBytePad(stuff->width, stuff->depth);
+ }
+ else
+ {
+ client->errorValue = stuff->format;
+ return BadValue;
+ }
+
+ tmpImage = (char *)&stuff[1];
+ lengthProto = length;
+
+ if ((bytes_to_int32(lengthProto * stuff->height) +
+ bytes_to_int32(sizeof(xPutImageReq))) != client->req_len)
+ return BadLength;
+
+ ReformatImage (tmpImage, lengthProto * stuff->height,
+ stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1,
+ ClientOrder(client));
+
+ (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
+ stuff->width, stuff->height,
+ stuff->leftPad, stuff->format, tmpImage);
+
+ return (client->noClientException);
+}
+
+static int
+DoGetImage(ClientPtr client, int format, Drawable drawable,
+ int x, int y, int width, int height,
+ Mask planemask, xGetImageReply **im_return)
+{
+ DrawablePtr pDraw, pBoundingDraw;
+ int nlines, linesPerBuf, rc;
+ int linesDone;
+ /* coordinates relative to the bounding drawable */
+ int relx, rely;
+ long widthBytesLine, length;
+ Mask plane = 0;
+ char *pBuf;
+ xGetImageReply xgi;
+ RegionPtr pVisibleRegion = NULL;
+
+ if ((format != XYPixmap) && (format != ZPixmap))
+ {
+ client->errorValue = format;
+ return(BadValue);
+ }
+ rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ memset(&xgi, 0, sizeof(xGetImageReply));
+
+ relx = x;
+ rely = y;
+
+ if(pDraw->type == DRAWABLE_WINDOW)
+ {
+ WindowPtr pWin = (WindowPtr)pDraw;
+
+ /* "If the drawable is a window, the window must be viewable ... or a
+ * BadMatch error results" */
+ if (!pWin->viewable)
+ return BadMatch;
+
+ relx += pDraw->x;
+ rely += pDraw->y;
+
+ if (pDraw->pScreen->GetWindowPixmap) {
+ PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin);
+
+ pBoundingDraw = &pPix->drawable;
+#ifdef COMPOSITE
+ relx -= pPix->screen_x;
+ rely -= pPix->screen_y;
+#endif
+ }
+ else
+ {
+ pBoundingDraw = (DrawablePtr)WindowTable[pDraw->pScreen->myNum];
+ }
+
+ xgi.visual = wVisual (pWin);
+ }
+ else
+ {
+ pBoundingDraw = pDraw;
+ xgi.visual = None;
+ }
+
+ /* "If the drawable is a pixmap, the given rectangle must be wholly
+ * contained within the pixmap, or a BadMatch error results. If the
+ * drawable is a window [...] it must be the case that if there were no
+ * inferiors or overlapping windows, the specified rectangle of the window
+ * would be fully visible on the screen and wholly contained within the
+ * outside edges of the window, or a BadMatch error results."
+ *
+ * We relax the window case slightly to mean that the rectangle must exist
+ * within the bounds of the window's backing pixmap. In particular, this
+ * means that a GetImage request may succeed or fail with BadMatch depending
+ * on whether any of its ancestor windows are redirected. */
+ if(relx < 0 || relx + width > (int)pBoundingDraw->width ||
+ rely < 0 || rely + height > (int)pBoundingDraw->height)
+ return BadMatch;
+
+ xgi.type = X_Reply;
+ xgi.sequenceNumber = client->sequence;
+ xgi.depth = pDraw->depth;
+ if(format == ZPixmap)
+ {
+ widthBytesLine = PixmapBytePad(width, pDraw->depth);
+ length = widthBytesLine * height;
+
+ }
+ else
+ {
+ widthBytesLine = BitmapBytePad(width);
+ plane = ((Mask)1) << (pDraw->depth - 1);
+ /* only planes asked for */
+ length = widthBytesLine * height *
+ Ones(planemask & (plane | (plane - 1)));
+
+ }
+
+ xgi.length = length;
+
+ if (im_return) {
+ pBuf = xcalloc(1, sz_xGetImageReply + length);
+ if (!pBuf)
+ return (BadAlloc);
+ if (widthBytesLine == 0)
+ linesPerBuf = 0;
+ else
+ linesPerBuf = height;
+ *im_return = (xGetImageReply *)pBuf;
+ *(xGetImageReply *)pBuf = xgi;
+ pBuf += sz_xGetImageReply;
+ } else {
+ xgi.length = bytes_to_int32(xgi.length);
+ if (widthBytesLine == 0 || height == 0)
+ linesPerBuf = 0;
+ else if (widthBytesLine >= IMAGE_BUFSIZE)
+ linesPerBuf = 1;
+ else
+ {
+ linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
+ if (linesPerBuf > height)
+ linesPerBuf = height;
+ }
+ length = linesPerBuf * widthBytesLine;
+ if (linesPerBuf < height)
+ {
+ /* we have to make sure intermediate buffers don't need padding */
+ while ((linesPerBuf > 1) &&
+ (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)))
+ {
+ linesPerBuf--;
+ length -= widthBytesLine;
+ }
+ while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))
+ {
+ linesPerBuf++;
+ length += widthBytesLine;
+ }
+ }
+ if(!(pBuf = xcalloc(1, length)))
+ return (BadAlloc);
+ WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
+ }
+
+ if (pDraw->type == DRAWABLE_WINDOW)
+ {
+ pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw);
+ if (pVisibleRegion)
+ {
+ REGION_TRANSLATE(pDraw->pScreen, pVisibleRegion,
+ -pDraw->x, -pDraw->y);
+ }
+ }
+
+ if (linesPerBuf == 0)
+ {
+ /* nothing to do */
+ }
+ else if (format == ZPixmap)
+ {
+ linesDone = 0;
+ while (height - linesDone > 0)
+ {
+ nlines = min(linesPerBuf, height - linesDone);
+ (*pDraw->pScreen->GetImage) (pDraw,
+ x,
+ y + linesDone,
+ width,
+ nlines,
+ format,
+ planemask,
+ (pointer) pBuf);
+ if (pVisibleRegion)
+ XaceCensorImage(client, pVisibleRegion, widthBytesLine,
+ pDraw, x, y + linesDone, width,
+ nlines, format, pBuf);
+
+ /* Note that this is NOT a call to WriteSwappedDataToClient,
+ as we do NOT byte swap */
+ if (!im_return)
+ {
+ ReformatImage (pBuf, (int)(nlines * widthBytesLine),
+ BitsPerPixel (pDraw->depth),
+ ClientOrder(client));
+
+/* Don't split me, gcc pukes when you do */
+ (void)WriteToClient(client,
+ (int)(nlines * widthBytesLine),
+ pBuf);
+ }
+ linesDone += nlines;
+ }
+ }
+ else /* XYPixmap */
+ {
+ for (; plane; plane >>= 1)
+ {
+ if (planemask & plane)
+ {
+ linesDone = 0;
+ while (height - linesDone > 0)
+ {
+ nlines = min(linesPerBuf, height - linesDone);
+ (*pDraw->pScreen->GetImage) (pDraw,
+ x,
+ y + linesDone,
+ width,
+ nlines,
+ format,
+ plane,
+ (pointer)pBuf);
+ if (pVisibleRegion)
+ XaceCensorImage(client, pVisibleRegion,
+ widthBytesLine,
+ pDraw, x, y + linesDone, width,
+ nlines, format, pBuf);
+
+ /* Note: NOT a call to WriteSwappedDataToClient,
+ as we do NOT byte swap */
+ if (im_return) {
+ pBuf += nlines * widthBytesLine;
+ } else {
+ ReformatImage (pBuf,
+ (int)(nlines * widthBytesLine),
+ 1,
+ ClientOrder (client));
+
+/* Don't split me, gcc pukes when you do */
+ (void)WriteToClient(client,
+ (int)(nlines * widthBytesLine),
+ pBuf);
+ }
+ linesDone += nlines;
+ }
+ }
+ }
+ }
+ if (pVisibleRegion)
+ REGION_DESTROY(pDraw->pScreen, pVisibleRegion);
+ if (!im_return)
+ xfree(pBuf);
+ return (client->noClientException);
+}
+
+int
+ProcGetImage(ClientPtr client)
+{
+ REQUEST(xGetImageReq);
+
+ REQUEST_SIZE_MATCH(xGetImageReq);
+
+ return DoGetImage(client, stuff->format, stuff->drawable,
+ stuff->x, stuff->y,
+ (int)stuff->width, (int)stuff->height,
+ stuff->planeMask, (xGetImageReply **)NULL);
+}
+
+int
+ProcPolyText(ClientPtr client)
+{
+ int err;
+ REQUEST(xPolyTextReq);
+ DrawablePtr pDraw;
+ GC *pGC;
+
+ REQUEST_AT_LEAST_SIZE(xPolyTextReq);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
+
+ err = PolyText(client,
+ pDraw,
+ pGC,
+ (unsigned char *)&stuff[1],
+ ((unsigned char *) stuff) + (client->req_len << 2),
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcImageText8(ClientPtr client)
+{
+ int err;
+ DrawablePtr pDraw;
+ GC *pGC;
+
+ REQUEST(xImageTextReq);
+
+ REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
+
+ err = ImageText(client,
+ pDraw,
+ pGC,
+ stuff->nChars,
+ (unsigned char *)&stuff[1],
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+int
+ProcImageText16(ClientPtr client)
+{
+ int err;
+ DrawablePtr pDraw;
+ GC *pGC;
+
+ REQUEST(xImageTextReq);
+
+ REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
+ VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
+
+ err = ImageText(client,
+ pDraw,
+ pGC,
+ stuff->nChars,
+ (unsigned char *)&stuff[1],
+ stuff->x,
+ stuff->y,
+ stuff->reqType,
+ stuff->drawable);
+
+ if (err == Success)
+ {
+ return(client->noClientException);
+ }
+ else
+ return err;
+}
+
+
+int
+ProcCreateColormap(ClientPtr client)
+{
+ VisualPtr pVisual;
+ ColormapPtr pmap;
+ Colormap mid;
+ WindowPtr pWin;
+ ScreenPtr pScreen;
+ REQUEST(xCreateColormapReq);
+ int i, result;
+
+ REQUEST_SIZE_MATCH(xCreateColormapReq);
+
+ if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll))
+ {
+ client->errorValue = stuff->alloc;
+ return(BadValue);
+ }
+ mid = stuff->mid;
+ LEGAL_NEW_RESOURCE(mid, client);
+ result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (result != Success)
+ return result;
+
+ pScreen = pWin->drawable.pScreen;
+ for (i = 0, pVisual = pScreen->visuals;
+ i < pScreen->numVisuals;
+ i++, pVisual++)
+ {
+ if (pVisual->vid != stuff->visual)
+ continue;
+ result = CreateColormap(mid, pScreen, pVisual, &pmap,
+ (int)stuff->alloc, client->index);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return(result);
+ }
+ client->errorValue = stuff->visual;
+ return(BadMatch);
+}
+
+int
+ProcFreeColormap(ClientPtr client)
+{
+ ColormapPtr pmap;
+ int rc;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ rc = dixLookupResourceByType((pointer *)&pmap, stuff->id, RT_COLORMAP, client,
+ DixDestroyAccess);
+ if (rc == Success)
+ {
+ /* Freeing a default colormap is a no-op */
+ if (!(pmap->flags & IsDefault))
+ FreeResource(stuff->id, RT_NONE);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (rc == BadValue) ? BadColor : rc;
+ }
+}
+
+
+int
+ProcCopyColormapAndFree(ClientPtr client)
+{
+ Colormap mid;
+ ColormapPtr pSrcMap;
+ REQUEST(xCopyColormapAndFreeReq);
+ int rc;
+
+ REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
+ mid = stuff->mid;
+ LEGAL_NEW_RESOURCE(mid, client);
+ rc = dixLookupResourceByType((pointer *)&pSrcMap, stuff->srcCmap, RT_COLORMAP,
+ client, DixReadAccess|DixRemoveAccess);
+ if (rc == Success)
+ {
+ rc = CopyColormapAndFree(mid, pSrcMap, client->index);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return rc;
+ }
+ else
+ {
+ client->errorValue = stuff->srcCmap;
+ return (rc == BadValue) ? BadColor : rc;
+ }
+}
+
+int
+ProcInstallColormap(ClientPtr client)
+{
+ ColormapPtr pcmp;
+ int rc;
+ REQUEST(xResourceReq);
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client,
+ DixInstallAccess);
+ if (rc != Success)
+ goto out;
+
+ rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
+ if (rc != Success)
+ goto out;
+
+ (*(pcmp->pScreen->InstallColormap)) (pcmp);
+
+ rc = client->noClientException;
+out:
+ client->errorValue = stuff->id;
+ return (rc == BadValue) ? BadColor : rc;
+}
+
+int
+ProcUninstallColormap(ClientPtr client)
+{
+ ColormapPtr pcmp;
+ int rc;
+ REQUEST(xResourceReq);
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client,
+ DixUninstallAccess);
+ if (rc != Success)
+ goto out;
+
+ rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
+ if (rc != Success)
+ goto out;
+
+ if(pcmp->mid != pcmp->pScreen->defColormap)
+ (*(pcmp->pScreen->UninstallColormap)) (pcmp);
+
+ rc = client->noClientException;
+out:
+ client->errorValue = stuff->id;
+ return (rc == BadValue) ? BadColor : rc;
+}
+
+int
+ProcListInstalledColormaps(ClientPtr client)
+{
+ xListInstalledColormapsReply *preply;
+ int nummaps, rc;
+ WindowPtr pWin;
+ REQUEST(xResourceReq);
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
+ if (rc != Success)
+ goto out;
+
+ rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen,
+ DixGetAttrAccess);
+ if (rc != Success)
+ goto out;
+
+ preply = xalloc(sizeof(xListInstalledColormapsReply) +
+ pWin->drawable.pScreen->maxInstalledCmaps *
+ sizeof(Colormap));
+ if(!preply)
+ return(BadAlloc);
+
+ preply->type = X_Reply;
+ preply->sequenceNumber = client->sequence;
+ nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
+ (pWin->drawable.pScreen, (Colormap *)&preply[1]);
+ preply->nColormaps = nummaps;
+ preply->length = nummaps;
+ WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
+ xfree(preply);
+ rc = client->noClientException;
+out:
+ return rc;
+}
+
+int
+ProcAllocColor (ClientPtr client)
+{
+ ColormapPtr pmap;
+ int rc;
+ xAllocColorReply acr;
+ REQUEST(xAllocColorReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorReq);
+ rc = dixLookupResourceByType((pointer *)&pmap, stuff->cmap, RT_COLORMAP, client,
+ DixAddAccess);
+ if (rc == Success)
+ {
+ acr.type = X_Reply;
+ acr.length = 0;
+ acr.sequenceNumber = client->sequence;
+ acr.red = stuff->red;
+ acr.green = stuff->green;
+ acr.blue = stuff->blue;
+ acr.pixel = 0;
+ if( (rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
+ &acr.pixel, client->index)) )
+ {
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return rc;
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pmap->pScreen->myNum)
+#endif
+ WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
+ return (client->noClientException);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (rc == BadValue) ? BadColor : rc;
+ }
+}
+
+int
+ProcAllocNamedColor (ClientPtr client)
+{
+ ColormapPtr pcmp;
+ int rc;
+ REQUEST(xAllocNamedColorReq);
+
+ REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
+ rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
+ DixAddAccess);
+ if (rc == Success)
+ {
+ xAllocNamedColorReply ancr;
+
+ ancr.type = X_Reply;
+ ancr.length = 0;
+ ancr.sequenceNumber = client->sequence;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+ &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue))
+ {
+ ancr.screenRed = ancr.exactRed;
+ ancr.screenGreen = ancr.exactGreen;
+ ancr.screenBlue = ancr.exactBlue;
+ ancr.pixel = 0;
+ if( (rc = AllocColor(pcmp,
+ &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue,
+ &ancr.pixel, client->index)) )
+ {
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return rc;
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr);
+ return (client->noClientException);
+ }
+ else
+ return(BadName);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (rc == BadValue) ? BadColor : rc;
+ }
+}
+
+int
+ProcAllocColorCells (ClientPtr client)
+{
+ ColormapPtr pcmp;
+ int rc;
+ REQUEST(xAllocColorCellsReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorCellsReq);
+ rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
+ DixAddAccess);
+ if (rc == Success)
+ {
+ xAllocColorCellsReply accr;
+ int npixels, nmasks;
+ long length;
+ Pixel *ppixels, *pmasks;
+
+ npixels = stuff->colors;
+ if (!npixels)
+ {
+ client->errorValue = npixels;
+ return (BadValue);
+ }
+ if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+ {
+ client->errorValue = stuff->contiguous;
+ return (BadValue);
+ }
+ nmasks = stuff->planes;
+ length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
+ ppixels = xalloc(length);
+ if(!ppixels)
+ return(BadAlloc);
+ pmasks = ppixels + npixels;
+
+ if( (rc = AllocColorCells(client->index, pcmp, npixels, nmasks,
+ (Bool)stuff->contiguous, ppixels, pmasks)) )
+ {
+ xfree(ppixels);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return rc;
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ {
+ accr.type = X_Reply;
+ accr.length = bytes_to_int32(length);
+ accr.sequenceNumber = client->sequence;
+ accr.nPixels = npixels;
+ accr.nMasks = nmasks;
+ WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, length, ppixels);
+ }
+ xfree(ppixels);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (rc == BadValue) ? BadColor : rc;
+ }
+}
+
+int
+ProcAllocColorPlanes(ClientPtr client)
+{
+ ColormapPtr pcmp;
+ int rc;
+ REQUEST(xAllocColorPlanesReq);
+
+ REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
+ rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
+ DixAddAccess);
+ if (rc == Success)
+ {
+ xAllocColorPlanesReply acpr;
+ int npixels;
+ long length;
+ Pixel *ppixels;
+
+ npixels = stuff->colors;
+ if (!npixels)
+ {
+ client->errorValue = npixels;
+ return (BadValue);
+ }
+ if (stuff->contiguous != xTrue && stuff->contiguous != xFalse)
+ {
+ client->errorValue = stuff->contiguous;
+ return (BadValue);
+ }
+ acpr.type = X_Reply;
+ acpr.sequenceNumber = client->sequence;
+ acpr.nPixels = npixels;
+ length = (long)npixels * sizeof(Pixel);
+ ppixels = xalloc(length);
+ if(!ppixels)
+ return(BadAlloc);
+ if( (rc = AllocColorPlanes(client->index, pcmp, npixels,
+ (int)stuff->red, (int)stuff->green, (int)stuff->blue,
+ (Bool)stuff->contiguous, ppixels,
+ &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) )
+ {
+ xfree(ppixels);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return rc;
+ }
+ acpr.length = bytes_to_int32(length);
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !pcmp->pScreen->myNum)
+#endif
+ {
+ WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
+ client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
+ WriteSwappedDataToClient(client, length, ppixels);
+ }
+ xfree(ppixels);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (rc == BadValue) ? BadColor : rc;
+ }
+}
+
+int
+ProcFreeColors(ClientPtr client)
+{
+ ColormapPtr pcmp;
+ int rc;
+ REQUEST(xFreeColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
+ rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
+ DixRemoveAccess);
+ if (rc == Success)
+ {
+ int count;
+
+ if(pcmp->flags & AllAllocated)
+ return(BadAccess);
+ count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq));
+ rc = FreeColors(pcmp, client->index, count,
+ (Pixel *)&stuff[1], (Pixel)stuff->planeMask);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return rc;
+ }
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (rc == BadValue) ? BadColor : rc;
+ }
+}
+
+int
+ProcStoreColors (ClientPtr client)
+{
+ ColormapPtr pcmp;
+ int rc;
+ REQUEST(xStoreColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
+ rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
+ DixWriteAccess);
+ if (rc == Success)
+ {
+ int count;
+
+ count = (client->req_len << 2) - sizeof(xStoreColorsReq);
+ if (count % sizeof(xColorItem))
+ return(BadLength);
+ count /= sizeof(xColorItem);
+ rc = StoreColors(pcmp, count, (xColorItem *)&stuff[1]);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return rc;
+ }
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (rc == BadValue) ? BadColor : rc;
+ }
+}
+
+int
+ProcStoreNamedColor (ClientPtr client)
+{
+ ColormapPtr pcmp;
+ int rc;
+ REQUEST(xStoreNamedColorReq);
+
+ REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
+ rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
+ DixWriteAccess);
+ if (rc == Success)
+ {
+ xColorItem def;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1],
+ stuff->nbytes, &def.red, &def.green, &def.blue))
+ {
+ def.flags = stuff->flags;
+ def.pixel = stuff->pixel;
+ rc = StoreColors(pcmp, 1, &def);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ return rc;
+ }
+ return (BadName);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (rc == BadValue) ? BadColor : rc;
+ }
+}
+
+int
+ProcQueryColors(ClientPtr client)
+{
+ ColormapPtr pcmp;
+ int rc;
+ REQUEST(xQueryColorsReq);
+
+ REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
+ rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
+ DixReadAccess);
+ if (rc == Success)
+ {
+ int count;
+ xrgb *prgbs;
+ xQueryColorsReply qcr;
+
+ count = bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq));
+ prgbs = xcalloc(1, count * sizeof(xrgb));
+ if(!prgbs && count)
+ return(BadAlloc);
+ if( (rc = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
+ {
+ if (prgbs) xfree(prgbs);
+ if (client->noClientException != Success)
+ return(client->noClientException);
+ else
+ {
+ client->errorValue = clientErrorValue;
+ return rc;
+ }
+ }
+ memset(&qcr, 0, sizeof(xQueryColorsReply));
+ qcr.type = X_Reply;
+ qcr.length = bytes_to_int32(count * sizeof(xrgb));
+ qcr.sequenceNumber = client->sequence;
+ qcr.nColors = count;
+ WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
+ if (count)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
+ WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
+ }
+ if (prgbs) xfree(prgbs);
+ return(client->noClientException);
+
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (rc == BadValue) ? BadColor : rc;
+ }
+}
+
+int
+ProcLookupColor(ClientPtr client)
+{
+ ColormapPtr pcmp;
+ int rc;
+ REQUEST(xLookupColorReq);
+
+ REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
+ rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client,
+ DixReadAccess);
+ if (rc == Success)
+ {
+ xLookupColorReply lcr;
+
+ if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes,
+ &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue))
+ {
+ lcr.type = X_Reply;
+ lcr.length = 0;
+ lcr.sequenceNumber = client->sequence;
+ lcr.screenRed = lcr.exactRed;
+ lcr.screenGreen = lcr.exactGreen;
+ lcr.screenBlue = lcr.exactBlue;
+ (*pcmp->pScreen->ResolveColor)(&lcr.screenRed,
+ &lcr.screenGreen,
+ &lcr.screenBlue,
+ pcmp->pVisual);
+ WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
+ return(client->noClientException);
+ }
+ return (BadName);
+ }
+ else
+ {
+ client->errorValue = stuff->cmap;
+ return (rc == BadValue) ? BadColor : rc;
+ }
+}
+
+int
+ProcCreateCursor (ClientPtr client)
+{
+ CursorPtr pCursor;
+ PixmapPtr src;
+ PixmapPtr msk;
+ unsigned char * srcbits;
+ unsigned char * mskbits;
+ unsigned short width, height;
+ long n;
+ CursorMetricRec cm;
+ int rc;
+
+ REQUEST(xCreateCursorReq);
+
+ REQUEST_SIZE_MATCH(xCreateCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ rc = dixLookupResourceByType((pointer *)&src, stuff->source, RT_PIXMAP, client,
+ DixReadAccess);
+ if (rc != Success) {
+ client->errorValue = stuff->source;
+ return (rc == BadValue) ? BadPixmap : rc;
+ }
+
+ rc = dixLookupResourceByType((pointer *)&msk, stuff->mask, RT_PIXMAP, client,
+ DixReadAccess);
+ if (rc != Success)
+ {
+ if (stuff->mask != None)
+ {
+ client->errorValue = stuff->mask;
+ return (rc == BadValue) ? BadPixmap : rc;
+ }
+ }
+ else if ( src->drawable.width != msk->drawable.width
+ || src->drawable.height != msk->drawable.height
+ || src->drawable.depth != 1
+ || msk->drawable.depth != 1)
+ return (BadMatch);
+
+ width = src->drawable.width;
+ height = src->drawable.height;
+
+ if ( stuff->x > width
+ || stuff->y > height )
+ return (BadMatch);
+
+ n = BitmapBytePad(width)*height;
+ srcbits = xcalloc(1, n);
+ if (!srcbits)
+ return (BadAlloc);
+ mskbits = xalloc(n);
+ if (!mskbits)
+ {
+ xfree(srcbits);
+ return (BadAlloc);
+ }
+
+ (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height,
+ XYPixmap, 1, (pointer)srcbits);
+ if ( msk == (PixmapPtr)NULL)
+ {
+ unsigned char *bits = mskbits;
+ while (--n >= 0)
+ *bits++ = ~0;
+ }
+ else
+ {
+ /* zeroing the (pad) bits helps some ddx cursor handling */
+ bzero((char *)mskbits, n);
+ (* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width,
+ height, XYPixmap, 1, (pointer)mskbits);
+ }
+ cm.width = width;
+ cm.height = height;
+ cm.xhot = stuff->x;
+ cm.yhot = stuff->y;
+ rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm,
+ stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+ stuff->backRed, stuff->backGreen, stuff->backBlue,
+ &pCursor, client, stuff->cid);
+
+ if (rc != Success)
+ return rc;
+ if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+ return BadAlloc;
+
+ return client->noClientException;
+}
+
+int
+ProcCreateGlyphCursor (ClientPtr client)
+{
+ CursorPtr pCursor;
+ int res;
+
+ REQUEST(xCreateGlyphCursorReq);
+
+ REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
+ LEGAL_NEW_RESOURCE(stuff->cid, client);
+
+ res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
+ stuff->mask, stuff->maskChar,
+ stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
+ stuff->backRed, stuff->backGreen, stuff->backBlue,
+ &pCursor, client, stuff->cid);
+ if (res != Success)
+ return res;
+ if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor))
+ return client->noClientException;
+ return BadAlloc;
+}
+
+
+int
+ProcFreeCursor (ClientPtr client)
+{
+ CursorPtr pCursor;
+ int rc;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ rc = dixLookupResourceByType((pointer *)&pCursor, stuff->id, RT_CURSOR, client,
+ DixDestroyAccess);
+ if (rc == Success)
+ {
+ FreeResource(stuff->id, RT_NONE);
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->id;
+ return (rc == BadValue) ? BadCursor : rc;
+ }
+}
+
+int
+ProcQueryBestSize (ClientPtr client)
+{
+ xQueryBestSizeReply reply;
+ DrawablePtr pDraw;
+ ScreenPtr pScreen;
+ int rc;
+ REQUEST(xQueryBestSizeReq);
+ REQUEST_SIZE_MATCH(xQueryBestSizeReq);
+
+ if ((stuff->class != CursorShape) &&
+ (stuff->class != TileShape) &&
+ (stuff->class != StippleShape))
+ {
+ client->errorValue = stuff->class;
+ return(BadValue);
+ }
+
+ rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
+ DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
+ return (BadMatch);
+ pScreen = pDraw->pScreen;
+ rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ (* pScreen->QueryBestSize)(stuff->class, &stuff->width,
+ &stuff->height, pScreen);
+ memset(&reply, 0, sizeof(xQueryBestSizeReply));
+ reply.type = X_Reply;
+ reply.length = 0;
+ reply.sequenceNumber = client->sequence;
+ reply.width = stuff->width;
+ reply.height = stuff->height;
+ WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
+ return (client->noClientException);
+}
+
+
+int
+ProcSetScreenSaver (ClientPtr client)
+{
+ int rc, i, blankingOption, exposureOption;
+ REQUEST(xSetScreenSaverReq);
+ REQUEST_SIZE_MATCH(xSetScreenSaverReq);
+
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
+ DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ }
+
+ blankingOption = stuff->preferBlank;
+ if ((blankingOption != DontPreferBlanking) &&
+ (blankingOption != PreferBlanking) &&
+ (blankingOption != DefaultBlanking))
+ {
+ client->errorValue = blankingOption;
+ return BadValue;
+ }
+ exposureOption = stuff->allowExpose;
+ if ((exposureOption != DontAllowExposures) &&
+ (exposureOption != AllowExposures) &&
+ (exposureOption != DefaultExposures))
+ {
+ client->errorValue = exposureOption;
+ return BadValue;
+ }
+ if (stuff->timeout < -1)
+ {
+ client->errorValue = stuff->timeout;
+ return BadValue;
+ }
+ if (stuff->interval < -1)
+ {
+ client->errorValue = stuff->interval;
+ return BadValue;
+ }
+
+ if (blankingOption == DefaultBlanking)
+ ScreenSaverBlanking = defaultScreenSaverBlanking;
+ else
+ ScreenSaverBlanking = blankingOption;
+ if (exposureOption == DefaultExposures)
+ ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+ else
+ ScreenSaverAllowExposures = exposureOption;
+
+ if (stuff->timeout >= 0)
+ ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
+ else
+ ScreenSaverTime = defaultScreenSaverTime;
+ if (stuff->interval >= 0)
+ ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
+ else
+ ScreenSaverInterval = defaultScreenSaverInterval;
+
+ SetScreenSaverTimer();
+ return (client->noClientException);
+}
+
+int
+ProcGetScreenSaver(ClientPtr client)
+{
+ xGetScreenSaverReply rep;
+ int rc, i;
+ REQUEST_SIZE_MATCH(xReq);
+
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
+ DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ }
+
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.timeout = ScreenSaverTime / MILLI_PER_SECOND;
+ rep.interval = ScreenSaverInterval / MILLI_PER_SECOND;
+ rep.preferBlanking = ScreenSaverBlanking;
+ rep.allowExposures = ScreenSaverAllowExposures;
+ WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
+ return (client->noClientException);
+}
+
+int
+ProcChangeHosts(ClientPtr client)
+{
+ REQUEST(xChangeHostsReq);
+ int result;
+
+ REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
+
+ if(stuff->mode == HostInsert)
+ result = AddHost(client, (int)stuff->hostFamily,
+ stuff->hostLength, (pointer)&stuff[1]);
+ else if (stuff->mode == HostDelete)
+ result = RemoveHost(client, (int)stuff->hostFamily,
+ stuff->hostLength, (pointer)&stuff[1]);
+ else
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ if (!result)
+ result = client->noClientException;
+ return (result);
+}
+
+int
+ProcListHosts(ClientPtr client)
+{
+ xListHostsReply reply;
+ int len, nHosts, result;
+ pointer pdata;
+ /* REQUEST(xListHostsReq); */
+
+ REQUEST_SIZE_MATCH(xListHostsReq);
+
+ /* untrusted clients can't list hosts */
+ result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess);
+ if (result != Success)
+ return result;
+
+ result = GetHosts(&pdata, &nHosts, &len, &reply.enabled);
+ if (result != Success)
+ return(result);
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.nHosts = nHosts;
+ reply.length = bytes_to_int32(len);
+ WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
+ if (nHosts)
+ {
+ client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
+ WriteSwappedDataToClient(client, len, pdata);
+ }
+ xfree(pdata);
+ return (client->noClientException);
+}
+
+int
+ProcChangeAccessControl(ClientPtr client)
+{
+ int result;
+ REQUEST(xSetAccessControlReq);
+
+ REQUEST_SIZE_MATCH(xSetAccessControlReq);
+ if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess))
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ result = ChangeAccessControl(client, stuff->mode == EnableAccess);
+ if (!result)
+ result = client->noClientException;
+ return (result);
+}
+
+/*********************
+ * CloseDownRetainedResources
+ *
+ * Find all clients that are gone and have terminated in RetainTemporary
+ * and destroy their resources.
+ *********************/
+
+static void
+CloseDownRetainedResources(void)
+{
+ int i;
+ ClientPtr client;
+
+ for (i=1; i<currentMaxClients; i++)
+ {
+ client = clients[i];
+ if (client && (client->closeDownMode == RetainTemporary)
+ && (client->clientGone))
+ CloseDownClient(client);
+ }
+}
+
+int
+ProcKillClient(ClientPtr client)
+{
+ REQUEST(xResourceReq);
+ ClientPtr killclient;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ if (stuff->id == AllTemporary)
+ {
+ CloseDownRetainedResources();
+ return (client->noClientException);
+ }
+
+ rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess);
+ if (rc == Success) {
+ CloseDownClient(killclient);
+ /* if an LBX proxy gets killed, isItTimeToYield will be set */
+ if (isItTimeToYield || (client == killclient))
+ {
+ /* force yield and return Success, so that Dispatch()
+ * doesn't try to touch client
+ */
+ isItTimeToYield = TRUE;
+ return (Success);
+ }
+ return (client->noClientException);
+ }
+ else
+ return rc;
+}
+
+int
+ProcSetFontPath(ClientPtr client)
+{
+ unsigned char *ptr;
+ unsigned long nbytes, total;
+ long nfonts;
+ int n, result;
+ int error;
+ REQUEST(xSetFontPathReq);
+
+ REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
+
+ nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
+ total = nbytes;
+ ptr = (unsigned char *)&stuff[1];
+ nfonts = stuff->nFonts;
+ while (--nfonts >= 0)
+ {
+ if ((total == 0) || (total < (n = (*ptr + 1))))
+ return(BadLength);
+ total -= n;
+ ptr += n;
+ }
+ if (total >= 4)
+ return(BadLength);
+ result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1],
+ &error);
+ if (!result)
+ {
+ result = client->noClientException;
+ client->errorValue = error;
+ }
+ return (result);
+}
+
+int
+ProcGetFontPath(ClientPtr client)
+{
+ xGetFontPathReply reply;
+ int rc, stringLens, numpaths;
+ unsigned char *bufferStart;
+ /* REQUEST (xReq); */
+
+ REQUEST_SIZE_MATCH(xReq);
+ rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart);
+ if (rc != Success)
+ return rc;
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = bytes_to_int32(stringLens + numpaths);
+ reply.nPaths = numpaths;
+
+ WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
+ if (stringLens || numpaths)
+ (void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart);
+ return(client->noClientException);
+}
+
+int
+ProcChangeCloseDownMode(ClientPtr client)
+{
+ int rc;
+ REQUEST(xSetCloseDownModeReq);
+ REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
+
+ rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess);
+ if (rc != Success)
+ return rc;
+
+ if ((stuff->mode == AllTemporary) ||
+ (stuff->mode == RetainPermanent) ||
+ (stuff->mode == RetainTemporary))
+ {
+ client->closeDownMode = stuff->mode;
+ return (client->noClientException);
+ }
+ else
+ {
+ client->errorValue = stuff->mode;
+ return (BadValue);
+ }
+}
+
+int ProcForceScreenSaver(ClientPtr client)
+{
+ int rc;
+ REQUEST(xForceScreenSaverReq);
+
+ REQUEST_SIZE_MATCH(xForceScreenSaverReq);
+
+ if ((stuff->mode != ScreenSaverReset) &&
+ (stuff->mode != ScreenSaverActive))
+ {
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int)stuff->mode);
+ if (rc != Success)
+ return rc;
+ return client->noClientException;
+}
+
+int ProcNoOperation(ClientPtr client)
+{
+ REQUEST_AT_LEAST_SIZE(xReq);
+
+ /* noop -- don't do anything */
+ return(client->noClientException);
+}
+
+void
+InitProcVectors(void)
+{
+ int i;
+ for (i = 0; i<256; i++)
+ {
+ if(!ProcVector[i])
+ {
+ ProcVector[i] = SwappedProcVector[i] = ProcBadRequest;
+ ReplySwapVector[i] = ReplyNotSwappd;
+ }
+ }
+ for(i = LASTEvent; i < 128; i++)
+ {
+ EventSwapVector[i] = NotImplemented;
+ }
+
+}
+
+/**********************
+ * CloseDownClient
+ *
+ * Client can either mark his resources destroy or retain. If retained and
+ * then killed again, the client is really destroyed.
+ *********************/
+
+char dispatchExceptionAtReset = DE_RESET;
+
+void
+CloseDownClient(ClientPtr client)
+{
+ Bool really_close_down = client->clientGone ||
+ client->closeDownMode == DestroyAll;
+
+ if (!client->clientGone)
+ {
+ /* ungrab server if grabbing client dies */
+ if (grabState != GrabNone && grabClient == client)
+ {
+ UngrabServer(client);
+ }
+ BITCLEAR(grabWaiters, client->index);
+ DeleteClientFromAnySelections(client);
+ ReleaseActiveGrabs(client);
+ DeleteClientFontStuff(client);
+ if (!really_close_down)
+ {
+ /* This frees resources that should never be retained
+ * no matter what the close down mode is. Actually we
+ * could do this unconditionally, but it's probably
+ * better not to traverse all the client's resources
+ * twice (once here, once a few lines down in
+ * FreeClientResources) in the common case of
+ * really_close_down == TRUE.
+ */
+ FreeClientNeverRetainResources(client);
+ client->clientState = ClientStateRetained;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ }
+ client->clientGone = TRUE; /* so events aren't sent to client */
+ if (ClientIsAsleep(client))
+ ClientSignal (client);
+ ProcessWorkQueueZombies();
+ CloseDownConnection(client);
+
+ /* If the client made it to the Running stage, nClients has
+ * been incremented on its behalf, so we need to decrement it
+ * now. If it hasn't gotten to Running, nClients has *not*
+ * been incremented, so *don't* decrement it.
+ */
+ if (client->clientState != ClientStateInitial &&
+ client->clientState != ClientStateAuthenticating )
+ {
+ --nClients;
+ }
+ }
+
+ if (really_close_down)
+ {
+ if (client->clientState == ClientStateRunning && nClients == 0)
+ dispatchException |= dispatchExceptionAtReset;
+
+ client->clientState = ClientStateGone;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ FreeClientResources(client);
+#ifdef XSERVER_DTRACE
+ XSERVER_CLIENT_DISCONNECT(client->index);
+#endif
+ if (client->index < nextFreeClientID)
+ nextFreeClientID = client->index;
+ clients[client->index] = NullClient;
+ SmartLastClient = NullClient;
+ dixFreePrivates(client->devPrivates);
+ xfree(client);
+
+ while (!clients[currentMaxClients-1])
+ currentMaxClients--;
+ }
+}
+
+static void
+KillAllClients(void)
+{
+ int i;
+ for (i=1; i<currentMaxClients; i++)
+ if (clients[i]) {
+ /* Make sure Retained clients are released. */
+ clients[i]->closeDownMode = DestroyAll;
+ CloseDownClient(clients[i]);
+ }
+}
+
+void InitClient(ClientPtr client, int i, pointer ospriv)
+{
+ memset(client, 0, sizeof(*client));
+ client->index = i;
+ client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
+ client->closeDownMode = i ? DestroyAll : RetainPermanent;
+ client->requestVector = InitialVector;
+ client->osPrivate = ospriv;
+ QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
+ client->smart_start_tick = SmartScheduleTime;
+ client->smart_stop_tick = SmartScheduleTime;
+ client->smart_check_tick = SmartScheduleTime;
+}
+
+/************************
+ * int NextAvailableClient(ospriv)
+ *
+ * OS dependent portion can't assign client id's because of CloseDownModes.
+ * Returns NULL if there are no free clients.
+ *************************/
+
+ClientPtr NextAvailableClient(pointer ospriv)
+{
+ int i;
+ ClientPtr client;
+ xReq data;
+
+ i = nextFreeClientID;
+ if (i == MAXCLIENTS)
+ return (ClientPtr)NULL;
+ clients[i] = client = xalloc(sizeof(ClientRec));
+ if (!client)
+ return (ClientPtr)NULL;
+ InitClient(client, i, ospriv);
+ if (!InitClientResources(client))
+ {
+ xfree(client);
+ return (ClientPtr)NULL;
+ }
+ data.reqType = 1;
+ data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix);
+ if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
+ {
+ FreeClientResources(client);
+ xfree(client);
+ return (ClientPtr)NULL;
+ }
+ if (i == currentMaxClients)
+ currentMaxClients++;
+ while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID])
+ nextFreeClientID++;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = (xConnSetupPrefix *)NULL;
+ clientinfo.setup = (xConnSetup *) NULL;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ return(client);
+}
+
+int
+ProcInitialConnection(ClientPtr client)
+{
+ REQUEST(xReq);
+ xConnClientPrefix *prefix;
+ int whichbyte = 1;
+
+ prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+ if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B'))
+ return (client->noClientException = -1);
+ if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) ||
+ (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l')))
+ {
+ client->swapped = TRUE;
+ SwapConnClientPrefix(prefix);
+ }
+ stuff->reqType = 2;
+ stuff->length += bytes_to_int32(prefix->nbytesAuthProto) +
+ bytes_to_int32(prefix->nbytesAuthString);
+ if (client->swapped)
+ {
+ swaps(&stuff->length, whichbyte);
+ }
+ ResetCurrentRequest(client);
+ return (client->noClientException);
+}
+
+static int
+SendConnSetup(ClientPtr client, char *reason)
+{
+ xWindowRoot *root;
+ int i;
+ int numScreens;
+ char* lConnectionInfo;
+ xConnSetupPrefix* lconnSetupPrefix;
+
+ if (reason)
+ {
+ xConnSetupPrefix csp;
+
+ csp.success = xFalse;
+ csp.lengthReason = strlen(reason);
+ csp.length = bytes_to_int32(csp.lengthReason);
+ csp.majorVersion = X_PROTOCOL;
+ csp.minorVersion = X_PROTOCOL_REVISION;
+ if (client->swapped)
+ WriteSConnSetupPrefix(client, &csp);
+ else
+ (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp);
+ (void)WriteToClient(client, (int)csp.lengthReason, reason);
+ return (client->noClientException = -1);
+ }
+
+ numScreens = screenInfo.numScreens;
+ lConnectionInfo = ConnectionInfo;
+ lconnSetupPrefix = &connSetupPrefix;
+
+ /* We're about to start speaking X protocol back to the client by
+ * sending the connection setup info. This means the authorization
+ * step is complete, and we can count the client as an
+ * authorized one.
+ */
+ nClients++;
+
+ client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
+ client->sequence = 0;
+ ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask;
+ ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
+#ifdef MATCH_CLIENT_ENDIAN
+ ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client);
+ ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client);
+#endif
+ /* fill in the "currentInputMask" */
+ root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart);
+#ifdef PANORAMIX
+ if (noPanoramiXExtension)
+ numScreens = screenInfo.numScreens;
+ else
+ numScreens = ((xConnSetup *)ConnectionInfo)->numRoots;
+#endif
+
+ for (i=0; i<numScreens; i++)
+ {
+ unsigned int j;
+ xDepth *pDepth;
+
+ root->currentInputMask = WindowTable[i]->eventMask |
+ wOtherEventMasks (WindowTable[i]);
+ pDepth = (xDepth *)(root + 1);
+ for (j = 0; j < root->nDepths; j++)
+ {
+ pDepth = (xDepth *)(((char *)(pDepth + 1)) +
+ pDepth->nVisuals * sizeof(xVisualType));
+ }
+ root = (xWindowRoot *)pDepth;
+ }
+
+ if (client->swapped)
+ {
+ WriteSConnSetupPrefix(client, lconnSetupPrefix);
+ WriteSConnectionInfo(client,
+ (unsigned long)(lconnSetupPrefix->length << 2),
+ lConnectionInfo);
+ }
+ else
+ {
+ (void)WriteToClient(client, sizeof(xConnSetupPrefix),
+ (char *) lconnSetupPrefix);
+ (void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2),
+ lConnectionInfo);
+ }
+ client->clientState = ClientStateRunning;
+ if (ClientStateCallback)
+ {
+ NewClientInfoRec clientinfo;
+
+ clientinfo.client = client;
+ clientinfo.prefix = lconnSetupPrefix;
+ clientinfo.setup = (xConnSetup *)lConnectionInfo;
+ CallCallbacks((&ClientStateCallback), (pointer)&clientinfo);
+ }
+ return (client->noClientException);
+}
+
+int
+ProcEstablishConnection(ClientPtr client)
+{
+ char *reason, *auth_proto, *auth_string;
+ xConnClientPrefix *prefix;
+ REQUEST(xReq);
+
+ prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
+ auth_proto = (char *)prefix + sz_xConnClientPrefix;
+ auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto);
+ if ((prefix->majorVersion != X_PROTOCOL) ||
+ (prefix->minorVersion != X_PROTOCOL_REVISION))
+ reason = "Protocol version mismatch";
+ else
+ reason = ClientAuthorized(client,
+ (unsigned short)prefix->nbytesAuthProto,
+ auth_proto,
+ (unsigned short)prefix->nbytesAuthString,
+ auth_string);
+ /*
+ * If Kerberos is being used for this client, the clientState
+ * will be set to ClientStateAuthenticating at this point.
+ * More messages need to be exchanged among the X server, Kerberos
+ * server, and client to figure out if everyone is authorized.
+ * So we don't want to send the connection setup info yet, since
+ * the auth step isn't really done.
+ */
+ if (client->clientState == ClientStateCheckingSecurity)
+ client->clientState = ClientStateCheckedSecurity;
+ else if (client->clientState != ClientStateAuthenticating)
+ return(SendConnSetup(client, reason));
+ return(client->noClientException);
+}
+
+void
+SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
+ XID resId, int errorCode)
+{
+ xError rep;
+
+ memset(&rep, 0, sizeof(xError));
+ rep.type = X_Error;
+ rep.sequenceNumber = client->sequence;
+ rep.errorCode = errorCode;
+ rep.majorCode = majorCode;
+ rep.minorCode = minorCode;
+ rep.resourceID = resId;
+
+ WriteEventsToClient (client, 1, (xEvent *)&rep);
+}
+
+void
+MarkClientException(ClientPtr client)
+{
+ client->noClientException = -1;
+}
+
+/*
+ * This array encodes the answer to the question "what is the log base 2
+ * of the number of pixels that fit in a scanline pad unit?"
+ * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
+ */
+static int answer[6][4] = {
+ /* pad pad pad pad*/
+ /* 8 16 32 64 */
+
+ { 3, 4, 5 , 6 }, /* 1 bit per pixel */
+ { 1, 2, 3 , 4 }, /* 4 bits per pixel */
+ { 0, 1, 2 , 3 }, /* 8 bits per pixel */
+ { ~0, 0, 1 , 2 }, /* 16 bits per pixel */
+ { ~0, ~0, 0 , 1 }, /* 24 bits per pixel */
+ { ~0, ~0, 0 , 1 } /* 32 bits per pixel */
+};
+
+/*
+ * This array gives the answer to the question "what is the first index for
+ * the answer array above given the number of bits per pixel?"
+ * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
+ */
+static int indexForBitsPerPixel[ 33 ] = {
+ ~0, 0, ~0, ~0, /* 1 bit per pixel */
+ 1, ~0, ~0, ~0, /* 4 bits per pixel */
+ 2, ~0, ~0, ~0, /* 8 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 3, ~0, ~0, ~0, /* 16 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 4, ~0, ~0, ~0, /* 24 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 5 /* 32 bits per pixel */
+};
+
+/*
+ * This array gives the bytesperPixel value for cases where the number
+ * of bits per pixel is a multiple of 8 but not a power of 2.
+ */
+static int answerBytesPerPixel[ 33 ] = {
+ ~0, 0, ~0, ~0, /* 1 bit per pixel */
+ 0, ~0, ~0, ~0, /* 4 bits per pixel */
+ 0, ~0, ~0, ~0, /* 8 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 0, ~0, ~0, ~0, /* 16 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 3, ~0, ~0, ~0, /* 24 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 0 /* 32 bits per pixel */
+};
+
+/*
+ * This array gives the answer to the question "what is the second index for
+ * the answer array above given the number of bits per scanline pad unit?"
+ * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
+ */
+static int indexForScanlinePad[ 65 ] = {
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */
+ ~0, ~0, ~0, ~0,
+ 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ 3 /* 64 bits per scanline pad unit */
+};
+
+/*
+ grow the array of screenRecs if necessary.
+ call the device-supplied initialization procedure
+with its screen number, a pointer to its ScreenRec, argc, and argv.
+ return the number of successfully installed screens.
+
+*/
+
+int
+AddScreen(
+ Bool (* pfnInit)(
+ int /*index*/,
+ ScreenPtr /*pScreen*/,
+ int /*argc*/,
+ char ** /*argv*/
+ ),
+ int argc,
+ char **argv)
+{
+
+ int i;
+ int scanlinepad, format, depth, bitsPerPixel, j, k;
+ ScreenPtr pScreen;
+
+ i = screenInfo.numScreens;
+ if (i == MAXSCREENS)
+ return -1;
+
+ pScreen = (ScreenPtr) xcalloc(1, sizeof(ScreenRec));
+ if (!pScreen)
+ return -1;
+
+ pScreen->devPrivates = NULL;
+ pScreen->myNum = i;
+ pScreen->totalPixmapSize = BitmapBytePad(sizeof(PixmapRec)*8);
+ pScreen->ClipNotify = 0; /* for R4 ddx compatibility */
+ pScreen->CreateScreenResources = 0;
+
+ /*
+ * This loop gets run once for every Screen that gets added,
+ * but thats ok. If the ddx layer initializes the formats
+ * one at a time calling AddScreen() after each, then each
+ * iteration will make it a little more accurate. Worst case
+ * we do this loop N * numPixmapFormats where N is # of screens.
+ * Anyway, this must be called after InitOutput and before the
+ * screen init routine is called.
+ */
+ for (format=0; format<screenInfo.numPixmapFormats; format++)
+ {
+ depth = screenInfo.formats[format].depth;
+ bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
+ scanlinepad = screenInfo.formats[format].scanlinePad;
+ j = indexForBitsPerPixel[ bitsPerPixel ];
+ k = indexForScanlinePad[ scanlinepad ];
+ PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k];
+ PixmapWidthPaddingInfo[ depth ].padRoundUp =
+ (scanlinepad/bitsPerPixel) - 1;
+ j = indexForBitsPerPixel[ 8 ]; /* bits per byte */
+ PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k];
+ PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel;
+ if (answerBytesPerPixel[bitsPerPixel])
+ {
+ PixmapWidthPaddingInfo[ depth ].notPower2 = 1;
+ PixmapWidthPaddingInfo[ depth ].bytesPerPixel =
+ answerBytesPerPixel[bitsPerPixel];
+ }
+ else
+ {
+ PixmapWidthPaddingInfo[ depth ].notPower2 = 0;
+ }
+ }
+
+ /* This is where screen specific stuff gets initialized. Load the
+ screen structure, call the hardware, whatever.
+ This is also where the default colormap should be allocated and
+ also pixel values for blackPixel, whitePixel, and the cursor
+ Note that InitScreen is NOT allowed to modify argc, argv, or
+ any of the strings pointed to by argv. They may be passed to
+ multiple screens.
+ */
+ pScreen->rgf = ~0L; /* there are no scratch GCs yet*/
+ WindowTable[i] = NullWindow;
+ screenInfo.screens[i] = pScreen;
+ screenInfo.numScreens++;
+ if (!(*pfnInit)(i, pScreen, argc, argv))
+ {
+ dixFreePrivates(pScreen->devPrivates);
+ xfree(pScreen);
+ screenInfo.numScreens--;
+ return -1;
+ }
+ return i;
+}
diff --git a/xorg-server/dix/dixfonts.c b/xorg-server/dix/dixfonts.c index 329318d5d..77c166ee5 100644 --- a/xorg-server/dix/dixfonts.c +++ b/xorg-server/dix/dixfonts.c @@ -1,2102 +1,2104 @@ -/************************************************************************ -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. - -************************************************************************/ -/* The panoramix components contained the following notice */ -/* -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 <dix-config.h> -#endif - -#include <X11/X.h> -#include <X11/Xmd.h> -#include <X11/Xproto.h> -#include "scrnintstr.h" -#include "resource.h" -#include "dixstruct.h" -#include "cursorstr.h" -#include "misc.h" -#include "opaque.h" -#include "dixfontstr.h" -#include "closestr.h" -#include "dixfont.h" -#include "xace.h" - -#ifdef DEBUG -#include <stdio.h> -#endif - -#ifdef XF86BIGFONT -#define _XF86BIGFONT_SERVER_ -#include <X11/extensions/xf86bigfont.h> -#endif - -#define QUERYCHARINFO(pci, pr) *(pr) = (pci)->metrics - -extern pointer fosNaturalParams; -extern FontPtr defaultFont; - -static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0; -static int num_fpes = 0; -static FPEFunctions *fpe_functions = (FPEFunctions *) 0; -static int num_fpe_types = 0; - -static unsigned char *font_path_string; - -static int num_slept_fpes = 0; -static int size_slept_fpes = 0; -static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0; -static FontPatternCachePtr patternCache; - -static int -FontToXError(int err) -{ - switch (err) { - case Successful: - return Success; - case AllocError: - return BadAlloc; - case BadFontName: - return BadName; - case BadFontPath: - case BadFontFormat: /* is there something better? */ - case BadCharRange: - return BadValue; - default: - return err; - } -} - -static int -LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size, - unsigned char *data) -{ - if (fpe_functions[pfont->fpe->type].load_glyphs) - return (*fpe_functions[pfont->fpe->type].load_glyphs) - (client, pfont, 0, nchars, item_size, data); - else - return Successful; -} - -/* - * adding RT_FONT prevents conflict with default cursor font - */ -Bool -SetDefaultFont(char *defaultfontname) -{ - int err; - FontPtr pf; - XID fid; - - fid = FakeClientID(0); - err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync, - (unsigned) strlen(defaultfontname), defaultfontname); - if (err != Success) - return FALSE; - err = dixLookupResourceByType((pointer *)&pf, fid, RT_FONT, serverClient, - DixReadAccess); - if (err != Success) - return FALSE; - defaultFont = pf; - return TRUE; -} - -/* - * note that the font wakeup queue is not refcounted. this is because - * an fpe needs to be added when it's inited, and removed when it's finally - * freed, in order to handle any data that isn't requested, like FS events. - * - * since the only thing that should call these routines is the renderer's - * init_fpe() and free_fpe(), there shouldn't be any problem in using - * freed data. - */ -void -QueueFontWakeup(FontPathElementPtr fpe) -{ - int i; - FontPathElementPtr *new; - - for (i = 0; i < num_slept_fpes; i++) { - if (slept_fpes[i] == fpe) { - return; - } - } - if (num_slept_fpes == size_slept_fpes) { - new = (FontPathElementPtr *) - xrealloc(slept_fpes, - sizeof(FontPathElementPtr) * (size_slept_fpes + 4)); - if (!new) - return; - slept_fpes = new; - size_slept_fpes += 4; - } - slept_fpes[num_slept_fpes] = fpe; - num_slept_fpes++; -} - -void -RemoveFontWakeup(FontPathElementPtr fpe) -{ - int i, - j; - - for (i = 0; i < num_slept_fpes; i++) { - if (slept_fpes[i] == fpe) { - for (j = i; j < num_slept_fpes; j++) { - slept_fpes[j] = slept_fpes[j + 1]; - } - num_slept_fpes--; - return; - } - } -} - -void -FontWakeup(pointer data, int count, pointer LastSelectMask) -{ - int i; - FontPathElementPtr fpe; - - if (count < 0) - return; - /* wake up any fpe's that may be waiting for information */ - for (i = 0; i < num_slept_fpes; i++) { - fpe = slept_fpes[i]; - (void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask); - } -} - -/* XXX -- these two funcs may want to be broken into macros */ -static void -UseFPE(FontPathElementPtr fpe) -{ - fpe->refcount++; -} - -static void -FreeFPE (FontPathElementPtr fpe) -{ - fpe->refcount--; - if (fpe->refcount == 0) { - (*fpe_functions[fpe->type].free_fpe) (fpe); - xfree(fpe->name); - xfree(fpe); - } -} - -static Bool -doOpenFont(ClientPtr client, OFclosurePtr c) -{ - FontPtr pfont = NullFont; - FontPathElementPtr fpe = NULL; - ScreenPtr pScr; - int err = Successful; - int i; - char *alias, - *newname; - int newlen; - int aliascount = 20; - /* - * Decide at runtime what FontFormat to use. - */ - Mask FontFormat = - - ((screenInfo.imageByteOrder == LSBFirst) ? - BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) | - - ((screenInfo.bitmapBitOrder == LSBFirst) ? - BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) | - - BitmapFormatImageRectMin | - -#if GLYPHPADBYTES == 1 - BitmapFormatScanlinePad8 | -#endif - -#if GLYPHPADBYTES == 2 - BitmapFormatScanlinePad16 | -#endif - -#if GLYPHPADBYTES == 4 - BitmapFormatScanlinePad32 | -#endif - -#if GLYPHPADBYTES == 8 - BitmapFormatScanlinePad64 | -#endif - - BitmapFormatScanlineUnit8; - - if (client->clientGone) - { - if (c->current_fpe < c->num_fpes) - { - fpe = c->fpe_list[c->current_fpe]; - (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); - } - err = Successful; - goto bail; - } - while (c->current_fpe < c->num_fpes) { - fpe = c->fpe_list[c->current_fpe]; - err = (*fpe_functions[fpe->type].open_font) - ((pointer) client, fpe, c->flags, - c->fontname, c->fnamelen, FontFormat, - BitmapFormatMaskByte | - BitmapFormatMaskBit | - BitmapFormatMaskImageRectangle | - BitmapFormatMaskScanLinePad | - BitmapFormatMaskScanLineUnit, - c->fontid, &pfont, &alias, - c->non_cachable_font && c->non_cachable_font->fpe == fpe ? - c->non_cachable_font : - (FontPtr)0); - - if (err == FontNameAlias && alias) { - newlen = strlen(alias); - newname = (char *) xrealloc(c->fontname, newlen); - if (!newname) { - err = AllocError; - break; - } - memmove(newname, alias, newlen); - c->fontname = newname; - c->fnamelen = newlen; - c->current_fpe = 0; - if (--aliascount <= 0) { - /* We've tried resolving this alias 20 times, we're - * probably stuck in an infinite loop of aliases pointing - * to each other - time to take emergency exit! - */ - err = BadImplementation; - break; - } - continue; - } - if (err == BadFontName) { - c->current_fpe++; - continue; - } - if (err == Suspended) { - if (!c->slept) { - c->slept = TRUE; - ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c); - } - return TRUE; - } - break; - } - - if (err != Successful) - goto bail; - if (!pfont) { - err = BadFontName; - goto bail; - } - /* check values for firstCol, lastCol, firstRow, and lastRow */ - if (pfont->info.firstCol > pfont->info.lastCol || - pfont->info.firstRow > pfont->info.lastRow || - pfont->info.lastCol - pfont->info.firstCol > 255) { - err = AllocError; - goto bail; - } - if (!pfont->fpe) - pfont->fpe = fpe; - pfont->refcnt++; - if (pfont->refcnt == 1) { - UseFPE(pfont->fpe); - for (i = 0; i < screenInfo.numScreens; i++) { - pScr = screenInfo.screens[i]; - if (pScr->RealizeFont) - { - if (!(*pScr->RealizeFont) (pScr, pfont)) - { - CloseFont (pfont, (Font) 0); - err = AllocError; - goto bail; - } - } - } - } - if (!AddResource(c->fontid, RT_FONT, (pointer) pfont)) { - err = AllocError; - goto bail; - } - if (patternCache && pfont != c->non_cachable_font) - CacheFontPattern(patternCache, c->origFontName, c->origFontNameLen, - pfont); -bail: - if (err != Successful && c->client != serverClient) { - SendErrorToClient(c->client, X_OpenFont, 0, - c->fontid, FontToXError(err)); - } - if (c->slept) - ClientWakeup(c->client); - for (i = 0; i < c->num_fpes; i++) { - FreeFPE(c->fpe_list[i]); - } - xfree(c->fpe_list); - xfree(c->fontname); - xfree(c); - return TRUE; -} - -int -OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontname) -{ - OFclosurePtr c; - int i; - FontPtr cached = (FontPtr)0; - -#ifdef FONTDEBUG - char *f; - f = xalloc(lenfname + 1); - memmove(f, pfontname, lenfname); - f[lenfname] = '\0'; - ErrorF("[dix] OpenFont: fontname is \"%s\"\n", f); - xfree(f); -#endif - if (!lenfname || lenfname > XLFDMAXFONTNAMELEN) - return BadName; - if (patternCache) - { - - /* - ** Check name cache. If we find a cached version of this font that - ** is cachable, immediately satisfy the request with it. If we find - ** a cached version of this font that is non-cachable, we do not - ** satisfy the request with it. Instead, we pass the FontPtr to the - ** FPE's open_font code (the fontfile FPE in turn passes the - ** information to the rasterizer; the fserve FPE ignores it). - ** - ** Presumably, the font is marked non-cachable because the FPE has - ** put some licensing restrictions on it. If the FPE, using - ** whatever logic it relies on, determines that it is willing to - ** share this existing font with the client, then it has the option - ** to return the FontPtr we passed it as the newly-opened font. - ** This allows the FPE to exercise its licensing logic without - ** having to create another instance of a font that already exists. - */ - - cached = FindCachedFontPattern(patternCache, pfontname, lenfname); - if (cached && cached->info.cachable) - { - if (!AddResource(fid, RT_FONT, (pointer) cached)) - return BadAlloc; - cached->refcnt++; - return Success; - } - } - c = xalloc(sizeof(OFclosureRec)); - if (!c) - return BadAlloc; - c->fontname = xalloc(lenfname); - c->origFontName = pfontname; - c->origFontNameLen = lenfname; - if (!c->fontname) { - xfree(c); - return BadAlloc; - } - /* - * copy the current FPE list, so that if it gets changed by another client - * while we're blocking, the request still appears atomic - */ - c->fpe_list = xalloc(sizeof(FontPathElementPtr) * num_fpes); - if (!c->fpe_list) { - xfree(c->fontname); - xfree(c); - return BadAlloc; - } - memmove(c->fontname, pfontname, lenfname); - for (i = 0; i < num_fpes; i++) { - c->fpe_list[i] = font_path_elements[i]; - UseFPE(c->fpe_list[i]); - } - c->client = client; - c->fontid = fid; - c->current_fpe = 0; - c->num_fpes = num_fpes; - c->fnamelen = lenfname; - c->slept = FALSE; - c->flags = flags; - c->non_cachable_font = cached; - - (void) doOpenFont(client, c); - return Success; -} - -/** - * Decrement font's ref count, and free storage if ref count equals zero - * - * \param value must conform to DeleteType - */ -int -CloseFont(pointer value, XID fid) -{ - int nscr; - ScreenPtr pscr; - FontPathElementPtr fpe; - FontPtr pfont = (FontPtr)value; - - if (pfont == NullFont) - return (Success); - if (--pfont->refcnt == 0) { - if (patternCache) - RemoveCachedFontPattern (patternCache, pfont); - /* - * since the last reference is gone, ask each screen to free any - * storage it may have allocated locally for it. - */ - for (nscr = 0; nscr < screenInfo.numScreens; nscr++) { - pscr = screenInfo.screens[nscr]; - if (pscr->UnrealizeFont) - (*pscr->UnrealizeFont) (pscr, pfont); - } - if (pfont == defaultFont) - defaultFont = NULL; -#ifdef XF86BIGFONT - XF86BigfontFreeFontShm(pfont); -#endif - fpe = pfont->fpe; - (*fpe_functions[fpe->type].close_font) (fpe, pfont); - FreeFPE(fpe); - } - return (Success); -} - - -/***====================================================================***/ - -/** - * Sets up pReply as the correct QueryFontReply for pFont with the first - * nProtoCCIStructs char infos. - * - * \param pReply caller must allocate this storage - */ -void -QueryFont(FontPtr pFont, xQueryFontReply *pReply, int nProtoCCIStructs) -{ - FontPropPtr pFP; - int r, - c, - i; - xFontProp *prFP; - xCharInfo *prCI; - xCharInfo *charInfos[256]; - unsigned char chars[512]; - int ninfos; - unsigned long ncols; - unsigned long count; - - /* pr->length set in dispatch */ - pReply->minCharOrByte2 = pFont->info.firstCol; - pReply->defaultChar = pFont->info.defaultCh; - pReply->maxCharOrByte2 = pFont->info.lastCol; - pReply->drawDirection = pFont->info.drawDirection; - pReply->allCharsExist = pFont->info.allExist; - pReply->minByte1 = pFont->info.firstRow; - pReply->maxByte1 = pFont->info.lastRow; - pReply->fontAscent = pFont->info.fontAscent; - pReply->fontDescent = pFont->info.fontDescent; - - pReply->minBounds = pFont->info.ink_minbounds; - pReply->maxBounds = pFont->info.ink_maxbounds; - - pReply->nFontProps = pFont->info.nprops; - pReply->nCharInfos = nProtoCCIStructs; - - for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]); - i < pFont->info.nprops; - i++, pFP++, prFP++) { - prFP->name = pFP->name; - prFP->value = pFP->value; - } - - ninfos = 0; - ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1); - prCI = (xCharInfo *) (prFP); - for (r = pFont->info.firstRow; - ninfos < nProtoCCIStructs && r <= (int)pFont->info.lastRow; - r++) { - i = 0; - for (c = pFont->info.firstCol; c <= (int)pFont->info.lastCol; c++) { - chars[i++] = r; - chars[i++] = c; - } - (*pFont->get_metrics) (pFont, ncols, chars, - TwoD16Bit, &count, charInfos); - i = 0; - for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) { - *prCI = *charInfos[i]; - prCI++; - ninfos++; - } - } - return; -} - -static Bool -doListFontsAndAliases(ClientPtr client, LFclosurePtr c) -{ - FontPathElementPtr fpe; - int err = Successful; - FontNamesPtr names = NULL; - char *name, *resolved=NULL; - int namelen, resolvedlen; - int nnames; - int stringLens; - int i; - xListFontsReply reply; - char *bufptr; - char *bufferStart; - int aliascount = 0; - - if (client->clientGone) - { - if (c->current.current_fpe < c->num_fpes) - { - fpe = c->fpe_list[c->current.current_fpe]; - (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); - } - err = Successful; - goto bail; - } - - if (!c->current.patlen) - goto finish; - - while (c->current.current_fpe < c->num_fpes) { - fpe = c->fpe_list[c->current.current_fpe]; - err = Successful; - - if (!fpe_functions[fpe->type].start_list_fonts_and_aliases) - { - /* This FPE doesn't support/require list_fonts_and_aliases */ - - err = (*fpe_functions[fpe->type].list_fonts) - ((pointer) c->client, fpe, c->current.pattern, - c->current.patlen, c->current.max_names - c->names->nnames, - c->names); - - if (err == Suspended) { - if (!c->slept) { - c->slept = TRUE; - ClientSleep(client, - (ClientSleepProcPtr)doListFontsAndAliases, - (pointer) c); - } - return TRUE; - } - - err = BadFontName; - } - else - { - /* Start of list_fonts_and_aliases functionality. Modeled - after list_fonts_with_info in that it resolves aliases, - except that the information collected from FPEs is just - names, not font info. Each list_next_font_or_alias() - returns either a name into name/namelen or an alias into - name/namelen and its target name into resolved/resolvedlen. - The code at this level then resolves the alias by polling - the FPEs. */ - - if (!c->current.list_started) { - err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases) - ((pointer) c->client, fpe, c->current.pattern, - c->current.patlen, c->current.max_names - c->names->nnames, - &c->current.private); - if (err == Suspended) { - if (!c->slept) { - ClientSleep(client, - (ClientSleepProcPtr)doListFontsAndAliases, - (pointer) c); - c->slept = TRUE; - } - return TRUE; - } - if (err == Successful) - c->current.list_started = TRUE; - } - if (err == Successful) { - char *tmpname; - name = 0; - err = (*fpe_functions[fpe->type].list_next_font_or_alias) - ((pointer) c->client, fpe, &name, &namelen, &tmpname, - &resolvedlen, c->current.private); - if (err == Suspended) { - if (!c->slept) { - ClientSleep(client, - (ClientSleepProcPtr)doListFontsAndAliases, - (pointer) c); - c->slept = TRUE; - } - return TRUE; - } - if (err == FontNameAlias) { - if (resolved) xfree(resolved); - resolved = xalloc(resolvedlen + 1); - if (resolved) - memmove(resolved, tmpname, resolvedlen + 1); - } - } - - if (err == Successful) - { - if (c->haveSaved) - { - if (c->savedName) - (void)AddFontNamesName(c->names, c->savedName, - c->savedNameLen); - } - else - (void)AddFontNamesName(c->names, name, namelen); - } - - /* - * When we get an alias back, save our state and reset back to - * the start of the FPE looking for the specified name. As - * soon as a real font is found for the alias, pop back to the - * old state - */ - else if (err == FontNameAlias) { - char tmp_pattern[XLFDMAXFONTNAMELEN]; - /* - * when an alias recurses, we need to give - * the last FPE a chance to clean up; so we call - * it again, and assume that the error returned - * is BadFontName, indicating the alias resolution - * is complete. - */ - memmove(tmp_pattern, resolved, resolvedlen); - if (c->haveSaved) - { - char *tmpname; - int tmpnamelen; - - tmpname = 0; - (void) (*fpe_functions[fpe->type].list_next_font_or_alias) - ((pointer) c->client, fpe, &tmpname, &tmpnamelen, - &tmpname, &tmpnamelen, c->current.private); - if (--aliascount <= 0) - { - err = BadFontName; - goto ContBadFontName; - } - } - else - { - c->saved = c->current; - c->haveSaved = TRUE; - if (c->savedName) - xfree(c->savedName); - c->savedName = xalloc(namelen + 1); - if (c->savedName) - memmove(c->savedName, name, namelen + 1); - c->savedNameLen = namelen; - aliascount = 20; - } - memmove(c->current.pattern, tmp_pattern, resolvedlen); - c->current.patlen = resolvedlen; - c->current.max_names = c->names->nnames + 1; - c->current.current_fpe = -1; - c->current.private = 0; - err = BadFontName; - } - } - /* - * At the end of this FPE, step to the next. If we've finished - * processing an alias, pop state back. If we've collected enough - * font names, quit. - */ - if (err == BadFontName) { - ContBadFontName: ; - c->current.list_started = FALSE; - c->current.current_fpe++; - err = Successful; - if (c->haveSaved) - { - if (c->names->nnames == c->current.max_names || - c->current.current_fpe == c->num_fpes) { - c->haveSaved = FALSE; - c->current = c->saved; - /* Give the saved namelist a chance to clean itself up */ - continue; - } - } - if (c->names->nnames == c->current.max_names) - break; - } - } - - /* - * send the reply - */ - if (err != Successful) { - SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err)); - goto bail; - } - -finish: - - names = c->names; - nnames = names->nnames; - client = c->client; - stringLens = 0; - for (i = 0; i < nnames; i++) - stringLens += (names->length[i] <= 255) ? names->length[i] : 0; - - memset(&reply, 0, sizeof(xListFontsReply)); - reply.type = X_Reply; - reply.length = bytes_to_int32(stringLens + nnames); - reply.nFonts = nnames; - reply.sequenceNumber = client->sequence; - - bufptr = bufferStart = xalloc(reply.length << 2); - - if (!bufptr && reply.length) { - SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc); - goto bail; - } - /* - * since WriteToClient long word aligns things, copy to temp buffer and - * write all at once - */ - for (i = 0; i < nnames; i++) { - if (names->length[i] > 255) - reply.nFonts--; - else - { - *bufptr++ = names->length[i]; - memmove( bufptr, names->names[i], names->length[i]); - bufptr += names->length[i]; - } - } - nnames = reply.nFonts; - reply.length = bytes_to_int32(stringLens + nnames); - client->pSwapReplyFunc = ReplySwapVector[X_ListFonts]; - WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply); - (void) WriteToClient(client, stringLens + nnames, bufferStart); - xfree(bufferStart); - -bail: - if (c->slept) - ClientWakeup(client); - for (i = 0; i < c->num_fpes; i++) - FreeFPE(c->fpe_list[i]); - xfree(c->fpe_list); - if (c->savedName) xfree(c->savedName); - FreeFontNames(names); - xfree(c); - if (resolved) xfree(resolved); - return TRUE; -} - -int -ListFonts(ClientPtr client, unsigned char *pattern, unsigned length, - unsigned max_names) -{ - int i; - LFclosurePtr c; - - /* - * The right error to return here would be BadName, however the - * specification does not allow for a Name error on this request. - * Perhaps a better solution would be to return a nil list, i.e. - * a list containing zero fontnames. - */ - if (length > XLFDMAXFONTNAMELEN) - return BadAlloc; - - i = XaceHook(XACE_SERVER_ACCESS, client, DixGetAttrAccess); - if (i != Success) - return i; - - if (!(c = xalloc(sizeof *c))) - return BadAlloc; - c->fpe_list = xalloc(sizeof(FontPathElementPtr) * num_fpes); - if (!c->fpe_list) { - xfree(c); - return BadAlloc; - } - c->names = MakeFontNamesRecord(max_names < 100 ? max_names : 100); - if (!c->names) - { - xfree(c->fpe_list); - xfree(c); - return BadAlloc; - } - memmove( c->current.pattern, pattern, length); - for (i = 0; i < num_fpes; i++) { - c->fpe_list[i] = font_path_elements[i]; - UseFPE(c->fpe_list[i]); - } - c->client = client; - c->num_fpes = num_fpes; - c->current.patlen = length; - c->current.current_fpe = 0; - c->current.max_names = max_names; - c->current.list_started = FALSE; - c->current.private = 0; - c->haveSaved = FALSE; - c->slept = FALSE; - c->savedName = 0; - doListFontsAndAliases(client, c); - return Success; -} - -int -doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c) -{ - FontPathElementPtr fpe; - int err = Successful; - char *name; - int namelen; - int numFonts; - FontInfoRec fontInfo, - *pFontInfo; - xListFontsWithInfoReply *reply; - int length; - xFontProp *pFP; - int i; - int aliascount = 0; - xListFontsWithInfoReply finalReply; - - if (client->clientGone) - { - if (c->current.current_fpe < c->num_fpes) - { - fpe = c->fpe_list[c->current.current_fpe]; - (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); - } - err = Successful; - goto bail; - } - client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo]; - if (!c->current.patlen) - goto finish; - while (c->current.current_fpe < c->num_fpes) - { - fpe = c->fpe_list[c->current.current_fpe]; - err = Successful; - if (!c->current.list_started) - { - err = (*fpe_functions[fpe->type].start_list_fonts_with_info) - (client, fpe, c->current.pattern, c->current.patlen, - c->current.max_names, &c->current.private); - if (err == Suspended) - { - if (!c->slept) - { - ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c); - c->slept = TRUE; - } - return TRUE; - } - if (err == Successful) - c->current.list_started = TRUE; - } - if (err == Successful) - { - name = 0; - pFontInfo = &fontInfo; - err = (*fpe_functions[fpe->type].list_next_font_with_info) - (client, fpe, &name, &namelen, &pFontInfo, - &numFonts, c->current.private); - if (err == Suspended) - { - if (!c->slept) - { - ClientSleep(client, - (ClientSleepProcPtr)doListFontsWithInfo, - c); - c->slept = TRUE; - } - return TRUE; - } - } - /* - * When we get an alias back, save our state and reset back to the - * start of the FPE looking for the specified name. As soon as a real - * font is found for the alias, pop back to the old state - */ - if (err == FontNameAlias) - { - /* - * when an alias recurses, we need to give - * the last FPE a chance to clean up; so we call - * it again, and assume that the error returned - * is BadFontName, indicating the alias resolution - * is complete. - */ - if (c->haveSaved) - { - char *tmpname; - int tmpnamelen; - FontInfoPtr tmpFontInfo; - - tmpname = 0; - tmpFontInfo = &fontInfo; - (void) (*fpe_functions[fpe->type].list_next_font_with_info) - (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo, - &numFonts, c->current.private); - if (--aliascount <= 0) - { - err = BadFontName; - goto ContBadFontName; - } - } - else - { - c->saved = c->current; - c->haveSaved = TRUE; - c->savedNumFonts = numFonts; - if (c->savedName) - xfree(c->savedName); - c->savedName = xalloc(namelen + 1); - if (c->savedName) - memmove(c->savedName, name, namelen + 1); - aliascount = 20; - } - memmove(c->current.pattern, name, namelen); - c->current.patlen = namelen; - c->current.max_names = 1; - c->current.current_fpe = 0; - c->current.private = 0; - c->current.list_started = FALSE; - } - /* - * At the end of this FPE, step to the next. If we've finished - * processing an alias, pop state back. If we've sent enough font - * names, quit. Always wait for BadFontName to let the FPE - * have a chance to clean up. - */ - else if (err == BadFontName) - { - ContBadFontName: ; - c->current.list_started = FALSE; - c->current.current_fpe++; - err = Successful; - if (c->haveSaved) - { - if (c->current.max_names == 0 || - c->current.current_fpe == c->num_fpes) - { - c->haveSaved = FALSE; - c->saved.max_names -= (1 - c->current.max_names); - c->current = c->saved; - } - } - else if (c->current.max_names == 0) - break; - } - else if (err == Successful) - { - length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp); - reply = c->reply; - if (c->length < length) - { - reply = (xListFontsWithInfoReply *) xrealloc(c->reply, length); - if (!reply) - { - err = AllocError; - break; - } - memset((char*)reply + c->length, 0, length - c->length); - c->reply = reply; - c->length = length; - } - if (c->haveSaved) - { - numFonts = c->savedNumFonts; - name = c->savedName; - namelen = strlen(name); - } - reply->type = X_Reply; - reply->length = bytes_to_int32(sizeof *reply - sizeof(xGenericReply) + - pFontInfo->nprops * sizeof(xFontProp) + - namelen); - reply->sequenceNumber = client->sequence; - reply->nameLength = namelen; - reply->minBounds = pFontInfo->ink_minbounds; - reply->maxBounds = pFontInfo->ink_maxbounds; - reply->minCharOrByte2 = pFontInfo->firstCol; - reply->maxCharOrByte2 = pFontInfo->lastCol; - reply->defaultChar = pFontInfo->defaultCh; - reply->nFontProps = pFontInfo->nprops; - reply->drawDirection = pFontInfo->drawDirection; - reply->minByte1 = pFontInfo->firstRow; - reply->maxByte1 = pFontInfo->lastRow; - reply->allCharsExist = pFontInfo->allExist; - reply->fontAscent = pFontInfo->fontAscent; - reply->fontDescent = pFontInfo->fontDescent; - reply->nReplies = numFonts; - pFP = (xFontProp *) (reply + 1); - for (i = 0; i < pFontInfo->nprops; i++) - { - pFP->name = pFontInfo->props[i].name; - pFP->value = pFontInfo->props[i].value; - pFP++; - } - WriteSwappedDataToClient(client, length, reply); - (void) WriteToClient(client, namelen, name); - if (pFontInfo == &fontInfo) - { - xfree(fontInfo.props); - xfree(fontInfo.isStringProp); - } - --c->current.max_names; - } - } -finish: - length = sizeof(xListFontsWithInfoReply); - bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply)); - finalReply.type = X_Reply; - finalReply.sequenceNumber = client->sequence; - finalReply.length = bytes_to_int32(sizeof(xListFontsWithInfoReply) - - sizeof(xGenericReply)); - WriteSwappedDataToClient(client, length, &finalReply); -bail: - if (c->slept) - ClientWakeup(client); - for (i = 0; i < c->num_fpes; i++) - FreeFPE(c->fpe_list[i]); - xfree(c->reply); - xfree(c->fpe_list); - if (c->savedName) xfree(c->savedName); - xfree(c); - return TRUE; -} - -int -StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern, - int max_names) -{ - int i; - LFWIclosurePtr c; - - /* - * The right error to return here would be BadName, however the - * specification does not allow for a Name error on this request. - * Perhaps a better solution would be to return a nil list, i.e. - * a list containing zero fontnames. - */ - if (length > XLFDMAXFONTNAMELEN) - return BadAlloc; - - i = XaceHook(XACE_SERVER_ACCESS, client, DixGetAttrAccess); - if (i != Success) - return i; - - if (!(c = xalloc(sizeof *c))) - goto badAlloc; - c->fpe_list = xalloc(sizeof(FontPathElementPtr) * num_fpes); - if (!c->fpe_list) - { - xfree(c); - goto badAlloc; - } - memmove(c->current.pattern, pattern, length); - for (i = 0; i < num_fpes; i++) - { - c->fpe_list[i] = font_path_elements[i]; - UseFPE(c->fpe_list[i]); - } - c->client = client; - c->num_fpes = num_fpes; - c->reply = 0; - c->length = 0; - c->current.patlen = length; - c->current.current_fpe = 0; - c->current.max_names = max_names; - c->current.list_started = FALSE; - c->current.private = 0; - c->savedNumFonts = 0; - c->haveSaved = FALSE; - c->slept = FALSE; - c->savedName = 0; - doListFontsWithInfo(client, c); - return Success; -badAlloc: - return BadAlloc; -} - -#define TextEltHeader 2 -#define FontShiftSize 5 -static XID clearGC[] = { CT_NONE }; -#define clearGCmask (GCClipMask) - -int -doPolyText(ClientPtr client, PTclosurePtr c) -{ - FontPtr pFont = c->pGC->font, oldpFont; - Font fid, oldfid; - int err = Success, lgerr; /* err is in X error, not font error, space */ - enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state = NEVER_SLEPT; - FontPathElementPtr fpe; - GC *origGC = NULL; - - if (client->clientGone) - { - fpe = c->pGC->font->fpe; - (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); - - if (c->slept) - { - /* Client has died, but we cannot bail out right now. We - need to clean up after the work we did when going to - sleep. Setting the drawable pointer to 0 makes this - happen without any attempts to render or perform other - unnecessary activities. */ - c->pDraw = (DrawablePtr)0; - } - else - { - err = Success; - goto bail; - } - } - - /* Make sure our drawable hasn't disappeared while we slept. */ - if (c->slept && c->pDraw) - { - DrawablePtr pDraw; - dixLookupDrawable(&pDraw, c->did, client, 0, DixWriteAccess); - if (c->pDraw != pDraw) { - /* Our drawable has disappeared. Treat like client died... ask - the FPE code to clean up after client and avoid further - rendering while we clean up after ourself. */ - fpe = c->pGC->font->fpe; - (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); - c->pDraw = (DrawablePtr)0; - } - } - - client_state = c->slept ? SLEEPING : NEVER_SLEPT; - - while (c->endReq - c->pElt > TextEltHeader) - { - if (*c->pElt == FontChange) - { - if (c->endReq - c->pElt < FontShiftSize) - { - err = BadLength; - goto bail; - } - - oldpFont = pFont; - oldfid = fid; - - fid = ((Font)*(c->pElt+4)) /* big-endian */ - | ((Font)*(c->pElt+3)) << 8 - | ((Font)*(c->pElt+2)) << 16 - | ((Font)*(c->pElt+1)) << 24; - err = dixLookupResourceByType((pointer *)&pFont, fid, RT_FONT, - client, DixReadAccess); - if (err != Success) - { - err = (err == BadValue) ? BadFont : err; - /* restore pFont and fid for step 4 (described below) */ - pFont = oldpFont; - fid = oldfid; - - /* If we're in START_SLEEP mode, the following step - shortens the request... in the unlikely event that - the fid somehow becomes valid before we come through - again to actually execute the polytext, which would - then mess up our refcounting scheme badly. */ - c->err = err; - c->endReq = c->pElt; - - goto bail; - } - - /* Step 3 (described below) on our new font */ - if (client_state == START_SLEEP) - pFont->refcnt++; - else - { - if (pFont != c->pGC->font && c->pDraw) - { - ChangeGC( c->pGC, GCFont, &fid); - ValidateGC(c->pDraw, c->pGC); - if (c->reqType == X_PolyText8) - c->polyText = (PolyTextPtr) c->pGC->ops->PolyText8; - else - c->polyText = (PolyTextPtr) c->pGC->ops->PolyText16; - } - - /* Undo the refcnt++ we performed when going to sleep */ - if (client_state == SLEEPING) - (void)CloseFont(c->pGC->font, (Font)0); - } - c->pElt += FontShiftSize; - } - else /* print a string */ - { - unsigned char *pNextElt; - pNextElt = c->pElt + TextEltHeader + (*c->pElt)*c->itemSize; - if ( pNextElt > c->endReq) - { - err = BadLength; - goto bail; - } - if (client_state == START_SLEEP) - { - c->pElt = pNextElt; - continue; - } - if (c->pDraw) - { - lgerr = LoadGlyphs(client, c->pGC->font, *c->pElt, c->itemSize, - c->pElt + TextEltHeader); - } - else lgerr = Successful; - - if (lgerr == Suspended) - { - if (!c->slept) { - int len; - GC *pGC; - PTclosurePtr new_closure; - - /* We're putting the client to sleep. We need to do a few things - to ensure successful and atomic-appearing execution of the - remainder of the request. First, copy the remainder of the - request into a safe malloc'd area. Second, create a scratch GC - to use for the remainder of the request. Third, mark all fonts - referenced in the remainder of the request to prevent their - deallocation. Fourth, make the original GC look like the - request has completed... set its font to the final font value - from this request. These GC manipulations are for the unlikely - (but possible) event that some other client is using the GC. - Steps 3 and 4 are performed by running this procedure through - the remainder of the request in a special no-render mode - indicated by client_state = START_SLEEP. */ - - /* Step 1 */ - /* Allocate a malloc'd closure structure to replace - the local one we were passed */ - new_closure = xalloc(sizeof(PTclosureRec)); - if (!new_closure) - { - err = BadAlloc; - goto bail; - } - *new_closure = *c; - c = new_closure; - - len = c->endReq - c->pElt; - c->data = xalloc(len); - if (!c->data) - { - xfree(c); - err = BadAlloc; - goto bail; - } - memmove(c->data, c->pElt, len); - c->pElt = c->data; - c->endReq = c->pElt + len; - - /* Step 2 */ - - pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen); - if (!pGC) - { - xfree(c->data); - xfree(c); - err = BadAlloc; - goto bail; - } - if ((err = CopyGC(c->pGC, pGC, GCFunction | - GCPlaneMask | GCForeground | - GCBackground | GCFillStyle | - GCTile | GCStipple | - GCTileStipXOrigin | - GCTileStipYOrigin | GCFont | - GCSubwindowMode | GCClipXOrigin | - GCClipYOrigin | GCClipMask)) != - Success) - { - FreeScratchGC(pGC); - xfree(c->data); - xfree(c); - err = BadAlloc; - goto bail; - } - origGC = c->pGC; - c->pGC = pGC; - ValidateGC(c->pDraw, c->pGC); - - c->slept = TRUE; - ClientSleep(client, - (ClientSleepProcPtr)doPolyText, - (pointer) c); - - /* Set up to perform steps 3 and 4 */ - client_state = START_SLEEP; - continue; /* on to steps 3 and 4 */ - } - return TRUE; - } - else if (lgerr != Successful) - { - err = FontToXError(lgerr); - goto bail; - } - if (c->pDraw) - { - c->xorg += *((INT8 *)(c->pElt + 1)); /* must be signed */ - c->xorg = (* c->polyText)(c->pDraw, c->pGC, c->xorg, c->yorg, - *c->pElt, c->pElt + TextEltHeader); - } - c->pElt = pNextElt; - } - } - -bail: - - if (client_state == START_SLEEP) - { - /* Step 4 */ - if (pFont != origGC->font) - { - ChangeGC(origGC, GCFont, &fid); - ValidateGC(c->pDraw, origGC); - } - - /* restore pElt pointer for execution of remainder of the request */ - c->pElt = c->data; - return TRUE; - } - - if (c->err != Success) err = c->err; - if (err != Success && c->client != serverClient) { -#ifdef PANORAMIX - if (noPanoramiXExtension || !c->pGC->pScreen->myNum) -#endif - SendErrorToClient(c->client, c->reqType, 0, 0, err); - } - if (c->slept) - { - ClientWakeup(c->client); - ChangeGC(c->pGC, clearGCmask, clearGC); - - /* Unreference the font from the scratch GC */ - CloseFont(c->pGC->font, (Font)0); - c->pGC->font = NullFont; - - FreeScratchGC(c->pGC); - xfree(c->data); - xfree(c); - } - return TRUE; -} - -int -PolyText(ClientPtr client, DrawablePtr pDraw, GC *pGC, unsigned char *pElt, - unsigned char *endReq, int xorg, int yorg, int reqType, XID did) -{ - PTclosureRec local_closure; - - local_closure.pElt = pElt; - local_closure.endReq = endReq; - local_closure.client = client; - local_closure.pDraw = pDraw; - local_closure.xorg = xorg; - local_closure.yorg = yorg; - if ((local_closure.reqType = reqType) == X_PolyText8) - { - local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText8; - local_closure.itemSize = 1; - } - else - { - local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText16; - local_closure.itemSize = 2; - } - local_closure.pGC = pGC; - local_closure.did = did; - local_closure.err = Success; - local_closure.slept = FALSE; - - (void) doPolyText(client, &local_closure); - return Success; -} - - -#undef TextEltHeader -#undef FontShiftSize - -int -doImageText(ClientPtr client, ITclosurePtr c) -{ - int err = Success, lgerr; /* err is in X error, not font error, space */ - FontPathElementPtr fpe; - - if (client->clientGone) - { - fpe = c->pGC->font->fpe; - (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); - err = Success; - goto bail; - } - - /* Make sure our drawable hasn't disappeared while we slept. */ - if (c->slept && c->pDraw) - { - DrawablePtr pDraw; - dixLookupDrawable(&pDraw, c->did, client, 0, DixWriteAccess); - if (c->pDraw != pDraw) { - /* Our drawable has disappeared. Treat like client died... ask - the FPE code to clean up after client. */ - fpe = c->pGC->font->fpe; - (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); - err = Success; - goto bail; - } - } - - lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data); - if (lgerr == Suspended) - { - if (!c->slept) { - GC *pGC; - unsigned char *data; - ITclosurePtr new_closure; - - /* We're putting the client to sleep. We need to - save some state. Similar problem to that handled - in doPolyText, but much simpler because the - request structure is much simpler. */ - - new_closure = xalloc(sizeof(ITclosureRec)); - if (!new_closure) - { - err = BadAlloc; - goto bail; - } - *new_closure = *c; - c = new_closure; - - data = xalloc(c->nChars * c->itemSize); - if (!data) - { - xfree(c); - err = BadAlloc; - goto bail; - } - memmove(data, c->data, c->nChars * c->itemSize); - c->data = data; - - pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen); - if (!pGC) - { - xfree(c->data); - xfree(c); - err = BadAlloc; - goto bail; - } - if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask | - GCForeground | GCBackground | GCFillStyle | - GCTile | GCStipple | GCTileStipXOrigin | - GCTileStipYOrigin | GCFont | - GCSubwindowMode | GCClipXOrigin | - GCClipYOrigin | GCClipMask)) != Success) - { - FreeScratchGC(pGC); - xfree(c->data); - xfree(c); - err = BadAlloc; - goto bail; - } - c->pGC = pGC; - ValidateGC(c->pDraw, c->pGC); - - c->slept = TRUE; - ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c); - } - return TRUE; - } - else if (lgerr != Successful) - { - err = FontToXError(lgerr); - goto bail; - } - if (c->pDraw) - { - (* c->imageText)(c->pDraw, c->pGC, c->xorg, c->yorg, - c->nChars, c->data); - } - -bail: - - if (err != Success && c->client != serverClient) { - SendErrorToClient(c->client, c->reqType, 0, 0, err); - } - if (c->slept) - { - ClientWakeup(c->client); - ChangeGC(c->pGC, clearGCmask, clearGC); - - /* Unreference the font from the scratch GC */ - CloseFont(c->pGC->font, (Font)0); - c->pGC->font = NullFont; - - FreeScratchGC(c->pGC); - xfree(c->data); - xfree(c); - } - return TRUE; -} - -int -ImageText(ClientPtr client, DrawablePtr pDraw, GC *pGC, int nChars, - unsigned char *data, int xorg, int yorg, int reqType, XID did) -{ - ITclosureRec local_closure; - - local_closure.client = client; - local_closure.pDraw = pDraw; - local_closure.pGC = pGC; - local_closure.nChars = nChars; - local_closure.data = data; - local_closure.xorg = xorg; - local_closure.yorg = yorg; - if ((local_closure.reqType = reqType) == X_ImageText8) - { - local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText8; - local_closure.itemSize = 1; - } - else - { - local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText16; - local_closure.itemSize = 2; - } - local_closure.did = did; - local_closure.slept = FALSE; - - (void) doImageText(client, &local_closure); - return Success; -} - - -/* does the necessary magic to figure out the fpe type */ -static int -DetermineFPEType(char *pathname) -{ - int i; - - for (i = 0; i < num_fpe_types; i++) { - if ((*fpe_functions[i].name_check) (pathname)) - return i; - } - return -1; -} - - -static void -FreeFontPath(FontPathElementPtr *list, int n, Bool force) -{ - int i; - - for (i = 0; i < n; i++) { - if (force) { - /* Sanity check that all refcounts will be 0 by the time - we get to the end of the list. */ - int found = 1; /* the first reference is us */ - int j; - for (j = i+1; j < n; j++) { - if (list[j] == list[i]) - found++; - } - if (list[i]->refcount != found) { - list[i]->refcount = found; /* ensure it will get freed */ - } - } - FreeFPE(list[i]); - } - xfree(list); -} - -static FontPathElementPtr -find_existing_fpe(FontPathElementPtr *list, int num, unsigned char *name, int len) -{ - FontPathElementPtr fpe; - int i; - - for (i = 0; i < num; i++) { - fpe = list[i]; - if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0) - return fpe; - } - return (FontPathElementPtr) 0; -} - - -static int -SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist) -{ - int i, err = 0; - int valid_paths = 0; - unsigned int len; - unsigned char *cp = paths; - FontPathElementPtr fpe = NULL, *fplist; - - fplist = xalloc(sizeof(FontPathElementPtr) * npaths); - if (!fplist) { - *bad = 0; - return BadAlloc; - } - for (i = 0; i < num_fpe_types; i++) { - if (fpe_functions[i].set_path_hook) - (*fpe_functions[i].set_path_hook) (); - } - for (i = 0; i < npaths; i++) - { - len = (unsigned int) (*cp++); - - if (len == 0) - { - if (persist) - ErrorF("[dix] Removing empty element from the valid list of fontpaths\n"); - err = BadValue; - } - else - { - /* if it's already in our active list, just reset it */ - /* - * note that this can miss FPE's in limbo -- may be worth catching - * them, though it'd muck up refcounting - */ - fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len); - if (fpe) - { - err = (*fpe_functions[fpe->type].reset_fpe) (fpe); - if (err == Successful) - { - UseFPE(fpe);/* since it'll be decref'd later when freed - * from the old list */ - } - else - fpe = 0; - } - /* if error or can't do it, act like it's a new one */ - if (!fpe) - { - fpe = xalloc(sizeof(FontPathElementRec)); - if (!fpe) - { - err = BadAlloc; - goto bail; - } - fpe->name = xalloc(len + 1); - if (!fpe->name) - { - xfree(fpe); - err = BadAlloc; - goto bail; - } - fpe->refcount = 1; - - strncpy(fpe->name, (char *) cp, (int) len); - fpe->name[len] = '\0'; - fpe->name_length = len; - fpe->type = DetermineFPEType(fpe->name); - if (fpe->type == -1) - err = BadValue; - else - err = (*fpe_functions[fpe->type].init_fpe) (fpe); - if (err != Successful) - { - if (persist) - { - ErrorF("[dix] Could not init font path element %s, removing from list!\n", - fpe->name); - } - xfree (fpe->name); - xfree (fpe); - } - } - } - if (err != Successful) - { - if (!persist) - goto bail; - } - else - { - fplist[valid_paths++] = fpe; - } - cp += len; - } - - FreeFontPath(font_path_elements, num_fpes, FALSE); - font_path_elements = fplist; - if (patternCache) - EmptyFontPatternCache(patternCache); - num_fpes = valid_paths; - - return Success; -bail: - *bad = i; - while (--valid_paths >= 0) - FreeFPE(fplist[valid_paths]); - xfree(fplist); - return FontToXError(err); -} - -/* XXX -- do we need to pass error down to each renderer? */ -int -SetFontPath(ClientPtr client, int npaths, unsigned char *paths, int *error) -{ - int err = XaceHook(XACE_SERVER_ACCESS, client, DixManageAccess); - if (err != Success) - return err; - - if (npaths == 0) { - if (SetDefaultFontPath(defaultFontPath) != Success) - return BadValue; - } else { - err = SetFontPathElements(npaths, paths, error, FALSE); - } - return err; -} - -int -SetDefaultFontPath(char *path) -{ - char *temp_path, - *start, - *end; - unsigned char *cp, - *pp, - *nump, - *newpath; - int num = 1, - len, - err, - size = 0, - bad; - - /* ensure temp_path contains "built-ins" */ - start = path; - while (1) { - start = strstr(start, "built-ins"); - if (start == NULL) - break; - end = start + strlen("built-ins"); - if ((start == path || start[-1] == ',') && (!*end || *end == ',')) - break; - start = end; - } - if (!start) { - temp_path = Xprintf("%s%sbuilt-ins", path, *path ? "," : ""); - } else { - temp_path = Xstrdup(path); - } - if (!temp_path) - return BadAlloc; - - /* get enough for string, plus values -- use up commas */ - len = strlen(temp_path) + 1; - nump = cp = newpath = xalloc(len); - if (!newpath) - return BadAlloc; - pp = (unsigned char *) temp_path; - cp++; - while (*pp) { - if (*pp == ',') { - *nump = (unsigned char) size; - nump = cp++; - pp++; - num++; - size = 0; - } else { - *cp++ = *pp++; - size++; - } - } - *nump = (unsigned char) size; - - err = SetFontPathElements(num, newpath, &bad, TRUE); - - xfree(newpath); - xfree(temp_path); - - return err; -} - -int -GetFontPath(ClientPtr client, int *count, int *length, unsigned char **result) -{ - int i; - unsigned char *c; - int len; - FontPathElementPtr fpe; - - i = XaceHook(XACE_SERVER_ACCESS, client, DixGetAttrAccess); - if (i != Success) - return i; - - len = 0; - for (i = 0; i < num_fpes; i++) { - fpe = font_path_elements[i]; - len += fpe->name_length + 1; - } - font_path_string = (unsigned char *) xrealloc(font_path_string, len); - if (!font_path_string) - return BadAlloc; - - c = font_path_string; - *length = 0; - for (i = 0; i < num_fpes; i++) { - fpe = font_path_elements[i]; - *c = fpe->name_length; - *length += *c++; - memmove(c, fpe->name, fpe->name_length); - c += fpe->name_length; - } - *count = num_fpes; - *result = font_path_string; - return Success; -} - -void -DeleteClientFontStuff(ClientPtr client) -{ - int i; - FontPathElementPtr fpe; - - for (i = 0; i < num_fpes; i++) - { - fpe = font_path_elements[i]; - if (fpe_functions[fpe->type].client_died) - (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe); - } -} - -void -InitFonts (void) -{ - patternCache = MakeFontPatternCache(); - - BuiltinRegisterFpeFunctions(); - FontFileRegisterFpeFunctions(); - fs_register_fpe_functions(); -} - -int -GetDefaultPointSize (void) -{ - return 120; -} - - -FontResolutionPtr -GetClientResolutions (int *num) -{ - static struct _FontResolution res; - ScreenPtr pScreen; - - pScreen = screenInfo.screens[0]; - res.x_resolution = (pScreen->width * 25.4) / pScreen->mmWidth; - /* - * XXX - we'll want this as long as bitmap instances are prevalent - so that we can match them from scalable fonts - */ - if (res.x_resolution < 88) - res.x_resolution = 75; - else - res.x_resolution = 100; - res.y_resolution = (pScreen->height * 25.4) / pScreen->mmHeight; - if (res.y_resolution < 88) - res.y_resolution = 75; - else - res.y_resolution = 100; - res.point_size = 120; - *num = 1; - return &res; -} - -/* - * returns the type index of the new fpe - * - * should be called (only once!) by each type of fpe when initialized - */ - -int -RegisterFPEFunctions(NameCheckFunc name_func, - InitFpeFunc init_func, - FreeFpeFunc free_func, - ResetFpeFunc reset_func, - OpenFontFunc open_func, - CloseFontFunc close_func, - ListFontsFunc list_func, - StartLfwiFunc start_lfwi_func, - NextLfwiFunc next_lfwi_func, - WakeupFpeFunc wakeup_func, - ClientDiedFunc client_died, - LoadGlyphsFunc load_glyphs, - StartLaFunc start_list_alias_func, - NextLaFunc next_list_alias_func, - SetPathFunc set_path_func) -{ - FPEFunctions *new; - - /* grow the list */ - new = (FPEFunctions *) xrealloc(fpe_functions, - (num_fpe_types + 1) * sizeof(FPEFunctions)); - if (!new) - return -1; - fpe_functions = new; - - fpe_functions[num_fpe_types].name_check = name_func; - fpe_functions[num_fpe_types].open_font = open_func; - fpe_functions[num_fpe_types].close_font = close_func; - fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func; - fpe_functions[num_fpe_types].list_fonts = list_func; - fpe_functions[num_fpe_types].start_list_fonts_with_info = - start_lfwi_func; - fpe_functions[num_fpe_types].list_next_font_with_info = - next_lfwi_func; - fpe_functions[num_fpe_types].init_fpe = init_func; - fpe_functions[num_fpe_types].free_fpe = free_func; - fpe_functions[num_fpe_types].reset_fpe = reset_func; - fpe_functions[num_fpe_types].client_died = client_died; - fpe_functions[num_fpe_types].load_glyphs = load_glyphs; - fpe_functions[num_fpe_types].start_list_fonts_and_aliases = - start_list_alias_func; - fpe_functions[num_fpe_types].list_next_font_or_alias = - next_list_alias_func; - fpe_functions[num_fpe_types].set_path_hook = set_path_func; - - return num_fpe_types++; -} - -void -FreeFonts(void) -{ - if (patternCache) { - FreeFontPatternCache(patternCache); - patternCache = 0; - } - FreeFontPath(font_path_elements, num_fpes, TRUE); - font_path_elements = 0; - num_fpes = 0; - xfree(fpe_functions); - num_fpe_types = 0; - fpe_functions = (FPEFunctions *) 0; -} - -/* convenience functions for FS interface */ - -FontPtr -find_old_font(XID id) -{ - pointer pFont; - dixLookupResourceByType(&pFont, id, RT_NONE, serverClient, DixReadAccess); - return (FontPtr)pFont; -} - -Font -GetNewFontClientID(void) -{ - return FakeClientID(0); -} - -int -StoreFontClientFont(FontPtr pfont, Font id) -{ - return AddResource(id, RT_NONE, (pointer) pfont); -} - -void -DeleteFontClientID(Font id) -{ - FreeResource(id, RT_NONE); -} - -int -client_auth_generation(ClientPtr client) -{ - return 0; -} - -static int fs_handlers_installed = 0; -static unsigned int last_server_gen; - -int -init_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler) -{ - /* if server has reset, make sure the b&w handlers are reinstalled */ - if (last_server_gen < serverGeneration) { - last_server_gen = serverGeneration; - fs_handlers_installed = 0; - } - if (fs_handlers_installed == 0) { - if (!RegisterBlockAndWakeupHandlers(block_handler, - FontWakeup, (pointer) 0)) - return AllocError; - fs_handlers_installed++; - } - QueueFontWakeup(fpe); - return Successful; -} - -void -remove_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler, Bool all) -{ - if (all) { - /* remove the handlers if no one else is using them */ - if (--fs_handlers_installed == 0) { - RemoveBlockAndWakeupHandlers(block_handler, FontWakeup, - (pointer) 0); - } - } - RemoveFontWakeup(fpe); -} +/************************************************************************
+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.
+
+************************************************************************/
+/* The panoramix components contained the following notice */
+/*
+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 <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "misc.h"
+#include "opaque.h"
+#include "dixfontstr.h"
+#include "closestr.h"
+#include "dixfont.h"
+#include "xace.h"
+
+#ifdef DEBUG
+#include <stdio.h>
+#endif
+
+#ifdef XF86BIGFONT
+#define _XF86BIGFONT_SERVER_
+#include <X11/extensions/xf86bigfont.h>
+#endif
+
+#define QUERYCHARINFO(pci, pr) *(pr) = (pci)->metrics
+
+extern pointer fosNaturalParams;
+extern FontPtr defaultFont;
+
+static FontPathElementPtr *font_path_elements = (FontPathElementPtr *) 0;
+static int num_fpes = 0;
+static FPEFunctions *fpe_functions = (FPEFunctions *) 0;
+static int num_fpe_types = 0;
+
+static unsigned char *font_path_string;
+
+static int num_slept_fpes = 0;
+static int size_slept_fpes = 0;
+static FontPathElementPtr *slept_fpes = (FontPathElementPtr *) 0;
+static FontPatternCachePtr patternCache;
+
+static int
+FontToXError(int err)
+{
+ switch (err) {
+ case Successful:
+ return Success;
+ case AllocError:
+ return BadAlloc;
+ case BadFontName:
+ return BadName;
+ case BadFontPath:
+ case BadFontFormat: /* is there something better? */
+ case BadCharRange:
+ return BadValue;
+ default:
+ return err;
+ }
+}
+
+static int
+LoadGlyphs(ClientPtr client, FontPtr pfont, unsigned nchars, int item_size,
+ unsigned char *data)
+{
+ if (fpe_functions[pfont->fpe->type].load_glyphs)
+ return (*fpe_functions[pfont->fpe->type].load_glyphs)
+ (client, pfont, 0, nchars, item_size, data);
+ else
+ return Successful;
+}
+
+/*
+ * adding RT_FONT prevents conflict with default cursor font
+ */
+Bool
+SetDefaultFont(char *defaultfontname)
+{
+ int err;
+ FontPtr pf;
+ XID fid;
+ static FontPtr last_pf;
+
+ fid = FakeClientID(0);
+ err = OpenFont(serverClient, fid, FontLoadAll | FontOpenSync,
+ (unsigned) strlen(defaultfontname), defaultfontname);
+ if (err != Success)
+ return FALSE;
+ err = dixLookupResourceByType((pointer *)&pf, fid, RT_FONT, serverClient,
+ DixReadAccess);
+ if (err == Success) last_pf = pf;
+ if (last_pf == (FontPtr) NULL)
+ return FALSE;
+ defaultFont = last_pf;
+ return TRUE;
+}
+
+/*
+ * note that the font wakeup queue is not refcounted. this is because
+ * an fpe needs to be added when it's inited, and removed when it's finally
+ * freed, in order to handle any data that isn't requested, like FS events.
+ *
+ * since the only thing that should call these routines is the renderer's
+ * init_fpe() and free_fpe(), there shouldn't be any problem in using
+ * freed data.
+ */
+void
+QueueFontWakeup(FontPathElementPtr fpe)
+{
+ int i;
+ FontPathElementPtr *new;
+
+ for (i = 0; i < num_slept_fpes; i++) {
+ if (slept_fpes[i] == fpe) {
+ return;
+ }
+ }
+ if (num_slept_fpes == size_slept_fpes) {
+ new = (FontPathElementPtr *)
+ xrealloc(slept_fpes,
+ sizeof(FontPathElementPtr) * (size_slept_fpes + 4));
+ if (!new)
+ return;
+ slept_fpes = new;
+ size_slept_fpes += 4;
+ }
+ slept_fpes[num_slept_fpes] = fpe;
+ num_slept_fpes++;
+}
+
+void
+RemoveFontWakeup(FontPathElementPtr fpe)
+{
+ int i,
+ j;
+
+ for (i = 0; i < num_slept_fpes; i++) {
+ if (slept_fpes[i] == fpe) {
+ for (j = i; j < num_slept_fpes; j++) {
+ slept_fpes[j] = slept_fpes[j + 1];
+ }
+ num_slept_fpes--;
+ return;
+ }
+ }
+}
+
+void
+FontWakeup(pointer data, int count, pointer LastSelectMask)
+{
+ int i;
+ FontPathElementPtr fpe;
+
+ if (count < 0)
+ return;
+ /* wake up any fpe's that may be waiting for information */
+ for (i = 0; i < num_slept_fpes; i++) {
+ fpe = slept_fpes[i];
+ (void) (*fpe_functions[fpe->type].wakeup_fpe) (fpe, LastSelectMask);
+ }
+}
+
+/* XXX -- these two funcs may want to be broken into macros */
+static void
+UseFPE(FontPathElementPtr fpe)
+{
+ fpe->refcount++;
+}
+
+static void
+FreeFPE (FontPathElementPtr fpe)
+{
+ fpe->refcount--;
+ if (fpe->refcount == 0) {
+ (*fpe_functions[fpe->type].free_fpe) (fpe);
+ xfree(fpe->name);
+ xfree(fpe);
+ }
+}
+
+static Bool
+doOpenFont(ClientPtr client, OFclosurePtr c)
+{
+ FontPtr pfont = NullFont;
+ FontPathElementPtr fpe = NULL;
+ ScreenPtr pScr;
+ int err = Successful;
+ int i;
+ char *alias,
+ *newname;
+ int newlen;
+ int aliascount = 20;
+ /*
+ * Decide at runtime what FontFormat to use.
+ */
+ Mask FontFormat =
+
+ ((screenInfo.imageByteOrder == LSBFirst) ?
+ BitmapFormatByteOrderLSB : BitmapFormatByteOrderMSB) |
+
+ ((screenInfo.bitmapBitOrder == LSBFirst) ?
+ BitmapFormatBitOrderLSB : BitmapFormatBitOrderMSB) |
+
+ BitmapFormatImageRectMin |
+
+#if GLYPHPADBYTES == 1
+ BitmapFormatScanlinePad8 |
+#endif
+
+#if GLYPHPADBYTES == 2
+ BitmapFormatScanlinePad16 |
+#endif
+
+#if GLYPHPADBYTES == 4
+ BitmapFormatScanlinePad32 |
+#endif
+
+#if GLYPHPADBYTES == 8
+ BitmapFormatScanlinePad64 |
+#endif
+
+ BitmapFormatScanlineUnit8;
+
+ if (client->clientGone)
+ {
+ if (c->current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+ while (c->current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current_fpe];
+ err = (*fpe_functions[fpe->type].open_font)
+ ((pointer) client, fpe, c->flags,
+ c->fontname, c->fnamelen, FontFormat,
+ BitmapFormatMaskByte |
+ BitmapFormatMaskBit |
+ BitmapFormatMaskImageRectangle |
+ BitmapFormatMaskScanLinePad |
+ BitmapFormatMaskScanLineUnit,
+ c->fontid, &pfont, &alias,
+ c->non_cachable_font && c->non_cachable_font->fpe == fpe ?
+ c->non_cachable_font :
+ (FontPtr)0);
+
+ if (err == FontNameAlias && alias) {
+ newlen = strlen(alias);
+ newname = (char *) xrealloc(c->fontname, newlen);
+ if (!newname) {
+ err = AllocError;
+ break;
+ }
+ memmove(newname, alias, newlen);
+ c->fontname = newname;
+ c->fnamelen = newlen;
+ c->current_fpe = 0;
+ if (--aliascount <= 0) {
+ /* We've tried resolving this alias 20 times, we're
+ * probably stuck in an infinite loop of aliases pointing
+ * to each other - time to take emergency exit!
+ */
+ err = BadImplementation;
+ break;
+ }
+ continue;
+ }
+ if (err == BadFontName) {
+ c->current_fpe++;
+ continue;
+ }
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client, (ClientSleepProcPtr)doOpenFont, (pointer) c);
+ }
+ return TRUE;
+ }
+ break;
+ }
+
+ if (err != Successful)
+ goto bail;
+ if (!pfont) {
+ err = BadFontName;
+ goto bail;
+ }
+ /* check values for firstCol, lastCol, firstRow, and lastRow */
+ if (pfont->info.firstCol > pfont->info.lastCol ||
+ pfont->info.firstRow > pfont->info.lastRow ||
+ pfont->info.lastCol - pfont->info.firstCol > 255) {
+ err = AllocError;
+ goto bail;
+ }
+ if (!pfont->fpe)
+ pfont->fpe = fpe;
+ pfont->refcnt++;
+ if (pfont->refcnt == 1) {
+ UseFPE(pfont->fpe);
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ pScr = screenInfo.screens[i];
+ if (pScr->RealizeFont)
+ {
+ if (!(*pScr->RealizeFont) (pScr, pfont))
+ {
+ CloseFont (pfont, (Font) 0);
+ err = AllocError;
+ goto bail;
+ }
+ }
+ }
+ }
+ if (!AddResource(c->fontid, RT_FONT, (pointer) pfont)) {
+ err = AllocError;
+ goto bail;
+ }
+ if (patternCache && pfont != c->non_cachable_font)
+ CacheFontPattern(patternCache, c->origFontName, c->origFontNameLen,
+ pfont);
+bail:
+ if (err != Successful && c->client != serverClient) {
+ SendErrorToClient(c->client, X_OpenFont, 0,
+ c->fontid, FontToXError(err));
+ }
+ if (c->slept)
+ ClientWakeup(c->client);
+ for (i = 0; i < c->num_fpes; i++) {
+ FreeFPE(c->fpe_list[i]);
+ }
+ xfree(c->fpe_list);
+ xfree(c->fontname);
+ xfree(c);
+ return TRUE;
+}
+
+int
+OpenFont(ClientPtr client, XID fid, Mask flags, unsigned lenfname, char *pfontname)
+{
+ OFclosurePtr c;
+ int i;
+ FontPtr cached = (FontPtr)0;
+
+#ifdef FONTDEBUG
+ char *f;
+ f = xalloc(lenfname + 1);
+ memmove(f, pfontname, lenfname);
+ f[lenfname] = '\0';
+ ErrorF("[dix] OpenFont: fontname is \"%s\"\n", f);
+ xfree(f);
+#endif
+ if (!lenfname || lenfname > XLFDMAXFONTNAMELEN)
+ return BadName;
+ if (patternCache)
+ {
+
+ /*
+ ** Check name cache. If we find a cached version of this font that
+ ** is cachable, immediately satisfy the request with it. If we find
+ ** a cached version of this font that is non-cachable, we do not
+ ** satisfy the request with it. Instead, we pass the FontPtr to the
+ ** FPE's open_font code (the fontfile FPE in turn passes the
+ ** information to the rasterizer; the fserve FPE ignores it).
+ **
+ ** Presumably, the font is marked non-cachable because the FPE has
+ ** put some licensing restrictions on it. If the FPE, using
+ ** whatever logic it relies on, determines that it is willing to
+ ** share this existing font with the client, then it has the option
+ ** to return the FontPtr we passed it as the newly-opened font.
+ ** This allows the FPE to exercise its licensing logic without
+ ** having to create another instance of a font that already exists.
+ */
+
+ cached = FindCachedFontPattern(patternCache, pfontname, lenfname);
+ if (cached && cached->info.cachable)
+ {
+ if (!AddResource(fid, RT_FONT, (pointer) cached))
+ return BadAlloc;
+ cached->refcnt++;
+ return Success;
+ }
+ }
+ c = xalloc(sizeof(OFclosureRec));
+ if (!c)
+ return BadAlloc;
+ c->fontname = xalloc(lenfname);
+ c->origFontName = pfontname;
+ c->origFontNameLen = lenfname;
+ if (!c->fontname) {
+ xfree(c);
+ return BadAlloc;
+ }
+ /*
+ * copy the current FPE list, so that if it gets changed by another client
+ * while we're blocking, the request still appears atomic
+ */
+ c->fpe_list = xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ xfree(c->fontname);
+ xfree(c);
+ return BadAlloc;
+ }
+ memmove(c->fontname, pfontname, lenfname);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->fontid = fid;
+ c->current_fpe = 0;
+ c->num_fpes = num_fpes;
+ c->fnamelen = lenfname;
+ c->slept = FALSE;
+ c->flags = flags;
+ c->non_cachable_font = cached;
+
+ (void) doOpenFont(client, c);
+ return Success;
+}
+
+/**
+ * Decrement font's ref count, and free storage if ref count equals zero
+ *
+ * \param value must conform to DeleteType
+ */
+int
+CloseFont(pointer value, XID fid)
+{
+ int nscr;
+ ScreenPtr pscr;
+ FontPathElementPtr fpe;
+ FontPtr pfont = (FontPtr)value;
+
+ if (pfont == NullFont)
+ return (Success);
+ if (--pfont->refcnt == 0) {
+ if (patternCache)
+ RemoveCachedFontPattern (patternCache, pfont);
+ /*
+ * since the last reference is gone, ask each screen to free any
+ * storage it may have allocated locally for it.
+ */
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++) {
+ pscr = screenInfo.screens[nscr];
+ if (pscr->UnrealizeFont)
+ (*pscr->UnrealizeFont) (pscr, pfont);
+ }
+ if (pfont == defaultFont)
+ defaultFont = NULL;
+#ifdef XF86BIGFONT
+ XF86BigfontFreeFontShm(pfont);
+#endif
+ fpe = pfont->fpe;
+ (*fpe_functions[fpe->type].close_font) (fpe, pfont);
+ FreeFPE(fpe);
+ }
+ return (Success);
+}
+
+
+/***====================================================================***/
+
+/**
+ * Sets up pReply as the correct QueryFontReply for pFont with the first
+ * nProtoCCIStructs char infos.
+ *
+ * \param pReply caller must allocate this storage
+ */
+void
+QueryFont(FontPtr pFont, xQueryFontReply *pReply, int nProtoCCIStructs)
+{
+ FontPropPtr pFP;
+ int r,
+ c,
+ i;
+ xFontProp *prFP;
+ xCharInfo *prCI;
+ xCharInfo *charInfos[256];
+ unsigned char chars[512];
+ int ninfos;
+ unsigned long ncols;
+ unsigned long count;
+
+ /* pr->length set in dispatch */
+ pReply->minCharOrByte2 = pFont->info.firstCol;
+ pReply->defaultChar = pFont->info.defaultCh;
+ pReply->maxCharOrByte2 = pFont->info.lastCol;
+ pReply->drawDirection = pFont->info.drawDirection;
+ pReply->allCharsExist = pFont->info.allExist;
+ pReply->minByte1 = pFont->info.firstRow;
+ pReply->maxByte1 = pFont->info.lastRow;
+ pReply->fontAscent = pFont->info.fontAscent;
+ pReply->fontDescent = pFont->info.fontDescent;
+
+ pReply->minBounds = pFont->info.ink_minbounds;
+ pReply->maxBounds = pFont->info.ink_maxbounds;
+
+ pReply->nFontProps = pFont->info.nprops;
+ pReply->nCharInfos = nProtoCCIStructs;
+
+ for (i = 0, pFP = pFont->info.props, prFP = (xFontProp *) (&pReply[1]);
+ i < pFont->info.nprops;
+ i++, pFP++, prFP++) {
+ prFP->name = pFP->name;
+ prFP->value = pFP->value;
+ }
+
+ ninfos = 0;
+ ncols = (unsigned long) (pFont->info.lastCol - pFont->info.firstCol + 1);
+ prCI = (xCharInfo *) (prFP);
+ for (r = pFont->info.firstRow;
+ ninfos < nProtoCCIStructs && r <= (int)pFont->info.lastRow;
+ r++) {
+ i = 0;
+ for (c = pFont->info.firstCol; c <= (int)pFont->info.lastCol; c++) {
+ chars[i++] = r;
+ chars[i++] = c;
+ }
+ (*pFont->get_metrics) (pFont, ncols, chars,
+ TwoD16Bit, &count, charInfos);
+ i = 0;
+ for (i = 0; i < (int) count && ninfos < nProtoCCIStructs; i++) {
+ *prCI = *charInfos[i];
+ prCI++;
+ ninfos++;
+ }
+ }
+ return;
+}
+
+static Bool
+doListFontsAndAliases(ClientPtr client, LFclosurePtr c)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ FontNamesPtr names = NULL;
+ char *name, *resolved=NULL;
+ int namelen, resolvedlen;
+ int nnames;
+ int stringLens;
+ int i;
+ xListFontsReply reply;
+ char *bufptr;
+ char *bufferStart;
+ int aliascount = 0;
+
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+
+ if (!c->current.patlen)
+ goto finish;
+
+ while (c->current.current_fpe < c->num_fpes) {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+
+ if (!fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ {
+ /* This FPE doesn't support/require list_fonts_and_aliases */
+
+ err = (*fpe_functions[fpe->type].list_fonts)
+ ((pointer) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ c->names);
+
+ if (err == Suspended) {
+ if (!c->slept) {
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+ }
+ return TRUE;
+ }
+
+ err = BadFontName;
+ }
+ else
+ {
+ /* Start of list_fonts_and_aliases functionality. Modeled
+ after list_fonts_with_info in that it resolves aliases,
+ except that the information collected from FPEs is just
+ names, not font info. Each list_next_font_or_alias()
+ returns either a name into name/namelen or an alias into
+ name/namelen and its target name into resolved/resolvedlen.
+ The code at this level then resolves the alias by polling
+ the FPEs. */
+
+ if (!c->current.list_started) {
+ err = (*fpe_functions[fpe->type].start_list_fonts_and_aliases)
+ ((pointer) c->client, fpe, c->current.pattern,
+ c->current.patlen, c->current.max_names - c->names->nnames,
+ &c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful) {
+ char *tmpname;
+ name = 0;
+ err = (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) c->client, fpe, &name, &namelen, &tmpname,
+ &resolvedlen, c->current.private);
+ if (err == Suspended) {
+ if (!c->slept) {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsAndAliases,
+ (pointer) c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == FontNameAlias) {
+ if (resolved) xfree(resolved);
+ resolved = xalloc(resolvedlen + 1);
+ if (resolved)
+ memmove(resolved, tmpname, resolvedlen + 1);
+ }
+ }
+
+ if (err == Successful)
+ {
+ if (c->haveSaved)
+ {
+ if (c->savedName)
+ (void)AddFontNamesName(c->names, c->savedName,
+ c->savedNameLen);
+ }
+ else
+ (void)AddFontNamesName(c->names, name, namelen);
+ }
+
+ /*
+ * When we get an alias back, save our state and reset back to
+ * the start of the FPE looking for the specified name. As
+ * soon as a real font is found for the alias, pop back to the
+ * old state
+ */
+ else if (err == FontNameAlias) {
+ char tmp_pattern[XLFDMAXFONTNAMELEN];
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ memmove(tmp_pattern, resolved, resolvedlen);
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+
+ tmpname = 0;
+ (void) (*fpe_functions[fpe->type].list_next_font_or_alias)
+ ((pointer) c->client, fpe, &tmpname, &tmpnamelen,
+ &tmpname, &tmpnamelen, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ if (c->savedName)
+ xfree(c->savedName);
+ c->savedName = xalloc(namelen + 1);
+ if (c->savedName)
+ memmove(c->savedName, name, namelen + 1);
+ c->savedNameLen = namelen;
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, tmp_pattern, resolvedlen);
+ c->current.patlen = resolvedlen;
+ c->current.max_names = c->names->nnames + 1;
+ c->current.current_fpe = -1;
+ c->current.private = 0;
+ err = BadFontName;
+ }
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've collected enough
+ * font names, quit.
+ */
+ if (err == BadFontName) {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->names->nnames == c->current.max_names ||
+ c->current.current_fpe == c->num_fpes) {
+ c->haveSaved = FALSE;
+ c->current = c->saved;
+ /* Give the saved namelist a chance to clean itself up */
+ continue;
+ }
+ }
+ if (c->names->nnames == c->current.max_names)
+ break;
+ }
+ }
+
+ /*
+ * send the reply
+ */
+ if (err != Successful) {
+ SendErrorToClient(client, X_ListFonts, 0, 0, FontToXError(err));
+ goto bail;
+ }
+
+finish:
+
+ names = c->names;
+ nnames = names->nnames;
+ client = c->client;
+ stringLens = 0;
+ for (i = 0; i < nnames; i++)
+ stringLens += (names->length[i] <= 255) ? names->length[i] : 0;
+
+ memset(&reply, 0, sizeof(xListFontsReply));
+ reply.type = X_Reply;
+ reply.length = bytes_to_int32(stringLens + nnames);
+ reply.nFonts = nnames;
+ reply.sequenceNumber = client->sequence;
+
+ bufptr = bufferStart = xalloc(reply.length << 2);
+
+ if (!bufptr && reply.length) {
+ SendErrorToClient(client, X_ListFonts, 0, 0, BadAlloc);
+ goto bail;
+ }
+ /*
+ * since WriteToClient long word aligns things, copy to temp buffer and
+ * write all at once
+ */
+ for (i = 0; i < nnames; i++) {
+ if (names->length[i] > 255)
+ reply.nFonts--;
+ else
+ {
+ *bufptr++ = names->length[i];
+ memmove( bufptr, names->names[i], names->length[i]);
+ bufptr += names->length[i];
+ }
+ }
+ nnames = reply.nFonts;
+ reply.length = bytes_to_int32(stringLens + nnames);
+ client->pSwapReplyFunc = ReplySwapVector[X_ListFonts];
+ WriteSwappedDataToClient(client, sizeof(xListFontsReply), &reply);
+ (void) WriteToClient(client, stringLens + nnames, bufferStart);
+ xfree(bufferStart);
+
+bail:
+ if (c->slept)
+ ClientWakeup(client);
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->fpe_list);
+ if (c->savedName) xfree(c->savedName);
+ FreeFontNames(names);
+ xfree(c);
+ if (resolved) xfree(resolved);
+ return TRUE;
+}
+
+int
+ListFonts(ClientPtr client, unsigned char *pattern, unsigned length,
+ unsigned max_names)
+{
+ int i;
+ LFclosurePtr c;
+
+ /*
+ * The right error to return here would be BadName, however the
+ * specification does not allow for a Name error on this request.
+ * Perhaps a better solution would be to return a nil list, i.e.
+ * a list containing zero fontnames.
+ */
+ if (length > XLFDMAXFONTNAMELEN)
+ return BadAlloc;
+
+ i = XaceHook(XACE_SERVER_ACCESS, client, DixGetAttrAccess);
+ if (i != Success)
+ return i;
+
+ if (!(c = xalloc(sizeof *c)))
+ return BadAlloc;
+ c->fpe_list = xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list) {
+ xfree(c);
+ return BadAlloc;
+ }
+ c->names = MakeFontNamesRecord(max_names < 100 ? max_names : 100);
+ if (!c->names)
+ {
+ xfree(c->fpe_list);
+ xfree(c);
+ return BadAlloc;
+ }
+ memmove( c->current.pattern, pattern, length);
+ for (i = 0; i < num_fpes; i++) {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->current.patlen = length;
+ c->current.current_fpe = 0;
+ c->current.max_names = max_names;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+ doListFontsAndAliases(client, c);
+ return Success;
+}
+
+int
+doListFontsWithInfo(ClientPtr client, LFWIclosurePtr c)
+{
+ FontPathElementPtr fpe;
+ int err = Successful;
+ char *name;
+ int namelen;
+ int numFonts;
+ FontInfoRec fontInfo,
+ *pFontInfo;
+ xListFontsWithInfoReply *reply;
+ int length;
+ xFontProp *pFP;
+ int i;
+ int aliascount = 0;
+ xListFontsWithInfoReply finalReply;
+
+ if (client->clientGone)
+ {
+ if (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+ err = Successful;
+ goto bail;
+ }
+ client->pSwapReplyFunc = ReplySwapVector[X_ListFontsWithInfo];
+ if (!c->current.patlen)
+ goto finish;
+ while (c->current.current_fpe < c->num_fpes)
+ {
+ fpe = c->fpe_list[c->current.current_fpe];
+ err = Successful;
+ if (!c->current.list_started)
+ {
+ err = (*fpe_functions[fpe->type].start_list_fonts_with_info)
+ (client, fpe, c->current.pattern, c->current.patlen,
+ c->current.max_names, &c->current.private);
+ if (err == Suspended)
+ {
+ if (!c->slept)
+ {
+ ClientSleep(client, (ClientSleepProcPtr)doListFontsWithInfo, c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ if (err == Successful)
+ c->current.list_started = TRUE;
+ }
+ if (err == Successful)
+ {
+ name = 0;
+ pFontInfo = &fontInfo;
+ err = (*fpe_functions[fpe->type].list_next_font_with_info)
+ (client, fpe, &name, &namelen, &pFontInfo,
+ &numFonts, c->current.private);
+ if (err == Suspended)
+ {
+ if (!c->slept)
+ {
+ ClientSleep(client,
+ (ClientSleepProcPtr)doListFontsWithInfo,
+ c);
+ c->slept = TRUE;
+ }
+ return TRUE;
+ }
+ }
+ /*
+ * When we get an alias back, save our state and reset back to the
+ * start of the FPE looking for the specified name. As soon as a real
+ * font is found for the alias, pop back to the old state
+ */
+ if (err == FontNameAlias)
+ {
+ /*
+ * when an alias recurses, we need to give
+ * the last FPE a chance to clean up; so we call
+ * it again, and assume that the error returned
+ * is BadFontName, indicating the alias resolution
+ * is complete.
+ */
+ if (c->haveSaved)
+ {
+ char *tmpname;
+ int tmpnamelen;
+ FontInfoPtr tmpFontInfo;
+
+ tmpname = 0;
+ tmpFontInfo = &fontInfo;
+ (void) (*fpe_functions[fpe->type].list_next_font_with_info)
+ (client, fpe, &tmpname, &tmpnamelen, &tmpFontInfo,
+ &numFonts, c->current.private);
+ if (--aliascount <= 0)
+ {
+ err = BadFontName;
+ goto ContBadFontName;
+ }
+ }
+ else
+ {
+ c->saved = c->current;
+ c->haveSaved = TRUE;
+ c->savedNumFonts = numFonts;
+ if (c->savedName)
+ xfree(c->savedName);
+ c->savedName = xalloc(namelen + 1);
+ if (c->savedName)
+ memmove(c->savedName, name, namelen + 1);
+ aliascount = 20;
+ }
+ memmove(c->current.pattern, name, namelen);
+ c->current.patlen = namelen;
+ c->current.max_names = 1;
+ c->current.current_fpe = 0;
+ c->current.private = 0;
+ c->current.list_started = FALSE;
+ }
+ /*
+ * At the end of this FPE, step to the next. If we've finished
+ * processing an alias, pop state back. If we've sent enough font
+ * names, quit. Always wait for BadFontName to let the FPE
+ * have a chance to clean up.
+ */
+ else if (err == BadFontName)
+ {
+ ContBadFontName: ;
+ c->current.list_started = FALSE;
+ c->current.current_fpe++;
+ err = Successful;
+ if (c->haveSaved)
+ {
+ if (c->current.max_names == 0 ||
+ c->current.current_fpe == c->num_fpes)
+ {
+ c->haveSaved = FALSE;
+ c->saved.max_names -= (1 - c->current.max_names);
+ c->current = c->saved;
+ }
+ }
+ else if (c->current.max_names == 0)
+ break;
+ }
+ else if (err == Successful)
+ {
+ length = sizeof(*reply) + pFontInfo->nprops * sizeof(xFontProp);
+ reply = c->reply;
+ if (c->length < length)
+ {
+ reply = (xListFontsWithInfoReply *) xrealloc(c->reply, length);
+ if (!reply)
+ {
+ err = AllocError;
+ break;
+ }
+ memset((char*)reply + c->length, 0, length - c->length);
+ c->reply = reply;
+ c->length = length;
+ }
+ if (c->haveSaved)
+ {
+ numFonts = c->savedNumFonts;
+ name = c->savedName;
+ namelen = strlen(name);
+ }
+ reply->type = X_Reply;
+ reply->length = bytes_to_int32(sizeof *reply - sizeof(xGenericReply) +
+ pFontInfo->nprops * sizeof(xFontProp) +
+ namelen);
+ reply->sequenceNumber = client->sequence;
+ reply->nameLength = namelen;
+ reply->minBounds = pFontInfo->ink_minbounds;
+ reply->maxBounds = pFontInfo->ink_maxbounds;
+ reply->minCharOrByte2 = pFontInfo->firstCol;
+ reply->maxCharOrByte2 = pFontInfo->lastCol;
+ reply->defaultChar = pFontInfo->defaultCh;
+ reply->nFontProps = pFontInfo->nprops;
+ reply->drawDirection = pFontInfo->drawDirection;
+ reply->minByte1 = pFontInfo->firstRow;
+ reply->maxByte1 = pFontInfo->lastRow;
+ reply->allCharsExist = pFontInfo->allExist;
+ reply->fontAscent = pFontInfo->fontAscent;
+ reply->fontDescent = pFontInfo->fontDescent;
+ reply->nReplies = numFonts;
+ pFP = (xFontProp *) (reply + 1);
+ for (i = 0; i < pFontInfo->nprops; i++)
+ {
+ pFP->name = pFontInfo->props[i].name;
+ pFP->value = pFontInfo->props[i].value;
+ pFP++;
+ }
+ WriteSwappedDataToClient(client, length, reply);
+ (void) WriteToClient(client, namelen, name);
+ if (pFontInfo == &fontInfo)
+ {
+ xfree(fontInfo.props);
+ xfree(fontInfo.isStringProp);
+ }
+ --c->current.max_names;
+ }
+ }
+finish:
+ length = sizeof(xListFontsWithInfoReply);
+ bzero((char *) &finalReply, sizeof(xListFontsWithInfoReply));
+ finalReply.type = X_Reply;
+ finalReply.sequenceNumber = client->sequence;
+ finalReply.length = bytes_to_int32(sizeof(xListFontsWithInfoReply)
+ - sizeof(xGenericReply));
+ WriteSwappedDataToClient(client, length, &finalReply);
+bail:
+ if (c->slept)
+ ClientWakeup(client);
+ for (i = 0; i < c->num_fpes; i++)
+ FreeFPE(c->fpe_list[i]);
+ xfree(c->reply);
+ xfree(c->fpe_list);
+ if (c->savedName) xfree(c->savedName);
+ xfree(c);
+ return TRUE;
+}
+
+int
+StartListFontsWithInfo(ClientPtr client, int length, unsigned char *pattern,
+ int max_names)
+{
+ int i;
+ LFWIclosurePtr c;
+
+ /*
+ * The right error to return here would be BadName, however the
+ * specification does not allow for a Name error on this request.
+ * Perhaps a better solution would be to return a nil list, i.e.
+ * a list containing zero fontnames.
+ */
+ if (length > XLFDMAXFONTNAMELEN)
+ return BadAlloc;
+
+ i = XaceHook(XACE_SERVER_ACCESS, client, DixGetAttrAccess);
+ if (i != Success)
+ return i;
+
+ if (!(c = xalloc(sizeof *c)))
+ goto badAlloc;
+ c->fpe_list = xalloc(sizeof(FontPathElementPtr) * num_fpes);
+ if (!c->fpe_list)
+ {
+ xfree(c);
+ goto badAlloc;
+ }
+ memmove(c->current.pattern, pattern, length);
+ for (i = 0; i < num_fpes; i++)
+ {
+ c->fpe_list[i] = font_path_elements[i];
+ UseFPE(c->fpe_list[i]);
+ }
+ c->client = client;
+ c->num_fpes = num_fpes;
+ c->reply = 0;
+ c->length = 0;
+ c->current.patlen = length;
+ c->current.current_fpe = 0;
+ c->current.max_names = max_names;
+ c->current.list_started = FALSE;
+ c->current.private = 0;
+ c->savedNumFonts = 0;
+ c->haveSaved = FALSE;
+ c->slept = FALSE;
+ c->savedName = 0;
+ doListFontsWithInfo(client, c);
+ return Success;
+badAlloc:
+ return BadAlloc;
+}
+
+#define TextEltHeader 2
+#define FontShiftSize 5
+static XID clearGC[] = { CT_NONE };
+#define clearGCmask (GCClipMask)
+
+int
+doPolyText(ClientPtr client, PTclosurePtr c)
+{
+ FontPtr pFont = c->pGC->font, oldpFont;
+ Font fid, oldfid;
+ int err = Success, lgerr; /* err is in X error, not font error, space */
+ enum { NEVER_SLEPT, START_SLEEP, SLEEPING } client_state = NEVER_SLEPT;
+ FontPathElementPtr fpe;
+ GC *origGC = NULL;
+
+ if (client->clientGone)
+ {
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+
+ if (c->slept)
+ {
+ /* Client has died, but we cannot bail out right now. We
+ need to clean up after the work we did when going to
+ sleep. Setting the drawable pointer to 0 makes this
+ happen without any attempts to render or perform other
+ unnecessary activities. */
+ c->pDraw = (DrawablePtr)0;
+ }
+ else
+ {
+ err = Success;
+ goto bail;
+ }
+ }
+
+ /* Make sure our drawable hasn't disappeared while we slept. */
+ if (c->slept && c->pDraw)
+ {
+ DrawablePtr pDraw;
+ dixLookupDrawable(&pDraw, c->did, client, 0, DixWriteAccess);
+ if (c->pDraw != pDraw) {
+ /* Our drawable has disappeared. Treat like client died... ask
+ the FPE code to clean up after client and avoid further
+ rendering while we clean up after ourself. */
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ c->pDraw = (DrawablePtr)0;
+ }
+ }
+
+ client_state = c->slept ? SLEEPING : NEVER_SLEPT;
+
+ while (c->endReq - c->pElt > TextEltHeader)
+ {
+ if (*c->pElt == FontChange)
+ {
+ if (c->endReq - c->pElt < FontShiftSize)
+ {
+ err = BadLength;
+ goto bail;
+ }
+
+ oldpFont = pFont;
+ oldfid = fid;
+
+ fid = ((Font)*(c->pElt+4)) /* big-endian */
+ | ((Font)*(c->pElt+3)) << 8
+ | ((Font)*(c->pElt+2)) << 16
+ | ((Font)*(c->pElt+1)) << 24;
+ err = dixLookupResourceByType((pointer *)&pFont, fid, RT_FONT,
+ client, DixReadAccess);
+ if (err != Success)
+ {
+ err = (err == BadValue) ? BadFont : err;
+ /* restore pFont and fid for step 4 (described below) */
+ pFont = oldpFont;
+ fid = oldfid;
+
+ /* If we're in START_SLEEP mode, the following step
+ shortens the request... in the unlikely event that
+ the fid somehow becomes valid before we come through
+ again to actually execute the polytext, which would
+ then mess up our refcounting scheme badly. */
+ c->err = err;
+ c->endReq = c->pElt;
+
+ goto bail;
+ }
+
+ /* Step 3 (described below) on our new font */
+ if (client_state == START_SLEEP)
+ pFont->refcnt++;
+ else
+ {
+ if (pFont != c->pGC->font && c->pDraw)
+ {
+ ChangeGC( c->pGC, GCFont, &fid);
+ ValidateGC(c->pDraw, c->pGC);
+ if (c->reqType == X_PolyText8)
+ c->polyText = (PolyTextPtr) c->pGC->ops->PolyText8;
+ else
+ c->polyText = (PolyTextPtr) c->pGC->ops->PolyText16;
+ }
+
+ /* Undo the refcnt++ we performed when going to sleep */
+ if (client_state == SLEEPING)
+ (void)CloseFont(c->pGC->font, (Font)0);
+ }
+ c->pElt += FontShiftSize;
+ }
+ else /* print a string */
+ {
+ unsigned char *pNextElt;
+ pNextElt = c->pElt + TextEltHeader + (*c->pElt)*c->itemSize;
+ if ( pNextElt > c->endReq)
+ {
+ err = BadLength;
+ goto bail;
+ }
+ if (client_state == START_SLEEP)
+ {
+ c->pElt = pNextElt;
+ continue;
+ }
+ if (c->pDraw)
+ {
+ lgerr = LoadGlyphs(client, c->pGC->font, *c->pElt, c->itemSize,
+ c->pElt + TextEltHeader);
+ }
+ else lgerr = Successful;
+
+ if (lgerr == Suspended)
+ {
+ if (!c->slept) {
+ int len;
+ GC *pGC;
+ PTclosurePtr new_closure;
+
+ /* We're putting the client to sleep. We need to do a few things
+ to ensure successful and atomic-appearing execution of the
+ remainder of the request. First, copy the remainder of the
+ request into a safe malloc'd area. Second, create a scratch GC
+ to use for the remainder of the request. Third, mark all fonts
+ referenced in the remainder of the request to prevent their
+ deallocation. Fourth, make the original GC look like the
+ request has completed... set its font to the final font value
+ from this request. These GC manipulations are for the unlikely
+ (but possible) event that some other client is using the GC.
+ Steps 3 and 4 are performed by running this procedure through
+ the remainder of the request in a special no-render mode
+ indicated by client_state = START_SLEEP. */
+
+ /* Step 1 */
+ /* Allocate a malloc'd closure structure to replace
+ the local one we were passed */
+ new_closure = xalloc(sizeof(PTclosureRec));
+ if (!new_closure)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ *new_closure = *c;
+ c = new_closure;
+
+ len = c->endReq - c->pElt;
+ c->data = xalloc(len);
+ if (!c->data)
+ {
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ memmove(c->data, c->pElt, len);
+ c->pElt = c->data;
+ c->endReq = c->pElt + len;
+
+ /* Step 2 */
+
+ pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+ if (!pGC)
+ {
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ if ((err = CopyGC(c->pGC, pGC, GCFunction |
+ GCPlaneMask | GCForeground |
+ GCBackground | GCFillStyle |
+ GCTile | GCStipple |
+ GCTileStipXOrigin |
+ GCTileStipYOrigin | GCFont |
+ GCSubwindowMode | GCClipXOrigin |
+ GCClipYOrigin | GCClipMask)) !=
+ Success)
+ {
+ FreeScratchGC(pGC);
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ origGC = c->pGC;
+ c->pGC = pGC;
+ ValidateGC(c->pDraw, c->pGC);
+
+ c->slept = TRUE;
+ ClientSleep(client,
+ (ClientSleepProcPtr)doPolyText,
+ (pointer) c);
+
+ /* Set up to perform steps 3 and 4 */
+ client_state = START_SLEEP;
+ continue; /* on to steps 3 and 4 */
+ }
+ return TRUE;
+ }
+ else if (lgerr != Successful)
+ {
+ err = FontToXError(lgerr);
+ goto bail;
+ }
+ if (c->pDraw)
+ {
+ c->xorg += *((INT8 *)(c->pElt + 1)); /* must be signed */
+ c->xorg = (* c->polyText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+ *c->pElt, c->pElt + TextEltHeader);
+ }
+ c->pElt = pNextElt;
+ }
+ }
+
+bail:
+
+ if (client_state == START_SLEEP)
+ {
+ /* Step 4 */
+ if (pFont != origGC->font)
+ {
+ ChangeGC(origGC, GCFont, &fid);
+ ValidateGC(c->pDraw, origGC);
+ }
+
+ /* restore pElt pointer for execution of remainder of the request */
+ c->pElt = c->data;
+ return TRUE;
+ }
+
+ if (c->err != Success) err = c->err;
+ if (err != Success && c->client != serverClient) {
+#ifdef PANORAMIX
+ if (noPanoramiXExtension || !c->pGC->pScreen->myNum)
+#endif
+ SendErrorToClient(c->client, c->reqType, 0, 0, err);
+ }
+ if (c->slept)
+ {
+ ClientWakeup(c->client);
+ ChangeGC(c->pGC, clearGCmask, clearGC);
+
+ /* Unreference the font from the scratch GC */
+ CloseFont(c->pGC->font, (Font)0);
+ c->pGC->font = NullFont;
+
+ FreeScratchGC(c->pGC);
+ xfree(c->data);
+ xfree(c);
+ }
+ return TRUE;
+}
+
+int
+PolyText(ClientPtr client, DrawablePtr pDraw, GC *pGC, unsigned char *pElt,
+ unsigned char *endReq, int xorg, int yorg, int reqType, XID did)
+{
+ PTclosureRec local_closure;
+
+ local_closure.pElt = pElt;
+ local_closure.endReq = endReq;
+ local_closure.client = client;
+ local_closure.pDraw = pDraw;
+ local_closure.xorg = xorg;
+ local_closure.yorg = yorg;
+ if ((local_closure.reqType = reqType) == X_PolyText8)
+ {
+ local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText8;
+ local_closure.itemSize = 1;
+ }
+ else
+ {
+ local_closure.polyText = (PolyTextPtr) pGC->ops->PolyText16;
+ local_closure.itemSize = 2;
+ }
+ local_closure.pGC = pGC;
+ local_closure.did = did;
+ local_closure.err = Success;
+ local_closure.slept = FALSE;
+
+ (void) doPolyText(client, &local_closure);
+ return Success;
+}
+
+
+#undef TextEltHeader
+#undef FontShiftSize
+
+int
+doImageText(ClientPtr client, ITclosurePtr c)
+{
+ int err = Success, lgerr; /* err is in X error, not font error, space */
+ FontPathElementPtr fpe;
+
+ if (client->clientGone)
+ {
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ err = Success;
+ goto bail;
+ }
+
+ /* Make sure our drawable hasn't disappeared while we slept. */
+ if (c->slept && c->pDraw)
+ {
+ DrawablePtr pDraw;
+ dixLookupDrawable(&pDraw, c->did, client, 0, DixWriteAccess);
+ if (c->pDraw != pDraw) {
+ /* Our drawable has disappeared. Treat like client died... ask
+ the FPE code to clean up after client. */
+ fpe = c->pGC->font->fpe;
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ err = Success;
+ goto bail;
+ }
+ }
+
+ lgerr = LoadGlyphs(client, c->pGC->font, c->nChars, c->itemSize, c->data);
+ if (lgerr == Suspended)
+ {
+ if (!c->slept) {
+ GC *pGC;
+ unsigned char *data;
+ ITclosurePtr new_closure;
+
+ /* We're putting the client to sleep. We need to
+ save some state. Similar problem to that handled
+ in doPolyText, but much simpler because the
+ request structure is much simpler. */
+
+ new_closure = xalloc(sizeof(ITclosureRec));
+ if (!new_closure)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ *new_closure = *c;
+ c = new_closure;
+
+ data = xalloc(c->nChars * c->itemSize);
+ if (!data)
+ {
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ memmove(data, c->data, c->nChars * c->itemSize);
+ c->data = data;
+
+ pGC = GetScratchGC(c->pGC->depth, c->pGC->pScreen);
+ if (!pGC)
+ {
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ if ((err = CopyGC(c->pGC, pGC, GCFunction | GCPlaneMask |
+ GCForeground | GCBackground | GCFillStyle |
+ GCTile | GCStipple | GCTileStipXOrigin |
+ GCTileStipYOrigin | GCFont |
+ GCSubwindowMode | GCClipXOrigin |
+ GCClipYOrigin | GCClipMask)) != Success)
+ {
+ FreeScratchGC(pGC);
+ xfree(c->data);
+ xfree(c);
+ err = BadAlloc;
+ goto bail;
+ }
+ c->pGC = pGC;
+ ValidateGC(c->pDraw, c->pGC);
+
+ c->slept = TRUE;
+ ClientSleep(client, (ClientSleepProcPtr)doImageText, (pointer) c);
+ }
+ return TRUE;
+ }
+ else if (lgerr != Successful)
+ {
+ err = FontToXError(lgerr);
+ goto bail;
+ }
+ if (c->pDraw)
+ {
+ (* c->imageText)(c->pDraw, c->pGC, c->xorg, c->yorg,
+ c->nChars, c->data);
+ }
+
+bail:
+
+ if (err != Success && c->client != serverClient) {
+ SendErrorToClient(c->client, c->reqType, 0, 0, err);
+ }
+ if (c->slept)
+ {
+ ClientWakeup(c->client);
+ ChangeGC(c->pGC, clearGCmask, clearGC);
+
+ /* Unreference the font from the scratch GC */
+ CloseFont(c->pGC->font, (Font)0);
+ c->pGC->font = NullFont;
+
+ FreeScratchGC(c->pGC);
+ xfree(c->data);
+ xfree(c);
+ }
+ return TRUE;
+}
+
+int
+ImageText(ClientPtr client, DrawablePtr pDraw, GC *pGC, int nChars,
+ unsigned char *data, int xorg, int yorg, int reqType, XID did)
+{
+ ITclosureRec local_closure;
+
+ local_closure.client = client;
+ local_closure.pDraw = pDraw;
+ local_closure.pGC = pGC;
+ local_closure.nChars = nChars;
+ local_closure.data = data;
+ local_closure.xorg = xorg;
+ local_closure.yorg = yorg;
+ if ((local_closure.reqType = reqType) == X_ImageText8)
+ {
+ local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText8;
+ local_closure.itemSize = 1;
+ }
+ else
+ {
+ local_closure.imageText = (ImageTextPtr) pGC->ops->ImageText16;
+ local_closure.itemSize = 2;
+ }
+ local_closure.did = did;
+ local_closure.slept = FALSE;
+
+ (void) doImageText(client, &local_closure);
+ return Success;
+}
+
+
+/* does the necessary magic to figure out the fpe type */
+static int
+DetermineFPEType(char *pathname)
+{
+ int i;
+
+ for (i = 0; i < num_fpe_types; i++) {
+ if ((*fpe_functions[i].name_check) (pathname))
+ return i;
+ }
+ return -1;
+}
+
+
+static void
+FreeFontPath(FontPathElementPtr *list, int n, Bool force)
+{
+ int i;
+
+ for (i = 0; i < n; i++) {
+ if (force) {
+ /* Sanity check that all refcounts will be 0 by the time
+ we get to the end of the list. */
+ int found = 1; /* the first reference is us */
+ int j;
+ for (j = i+1; j < n; j++) {
+ if (list[j] == list[i])
+ found++;
+ }
+ if (list[i]->refcount != found) {
+ list[i]->refcount = found; /* ensure it will get freed */
+ }
+ }
+ FreeFPE(list[i]);
+ }
+ xfree(list);
+}
+
+static FontPathElementPtr
+find_existing_fpe(FontPathElementPtr *list, int num, unsigned char *name, int len)
+{
+ FontPathElementPtr fpe;
+ int i;
+
+ for (i = 0; i < num; i++) {
+ fpe = list[i];
+ if (fpe->name_length == len && memcmp(name, fpe->name, len) == 0)
+ return fpe;
+ }
+ return (FontPathElementPtr) 0;
+}
+
+
+static int
+SetFontPathElements(int npaths, unsigned char *paths, int *bad, Bool persist)
+{
+ int i, err = 0;
+ int valid_paths = 0;
+ unsigned int len;
+ unsigned char *cp = paths;
+ FontPathElementPtr fpe = NULL, *fplist;
+
+ fplist = xalloc(sizeof(FontPathElementPtr) * npaths);
+ if (!fplist) {
+ *bad = 0;
+ return BadAlloc;
+ }
+ for (i = 0; i < num_fpe_types; i++) {
+ if (fpe_functions[i].set_path_hook)
+ (*fpe_functions[i].set_path_hook) ();
+ }
+ for (i = 0; i < npaths; i++)
+ {
+ len = (unsigned int) (*cp++);
+
+ if (len == 0)
+ {
+ if (persist)
+ ErrorF("[dix] Removing empty element from the valid list of fontpaths\n");
+ err = BadValue;
+ }
+ else
+ {
+ /* if it's already in our active list, just reset it */
+ /*
+ * note that this can miss FPE's in limbo -- may be worth catching
+ * them, though it'd muck up refcounting
+ */
+ fpe = find_existing_fpe(font_path_elements, num_fpes, cp, len);
+ if (fpe)
+ {
+ err = (*fpe_functions[fpe->type].reset_fpe) (fpe);
+ if (err == Successful)
+ {
+ UseFPE(fpe);/* since it'll be decref'd later when freed
+ * from the old list */
+ }
+ else
+ fpe = 0;
+ }
+ /* if error or can't do it, act like it's a new one */
+ if (!fpe)
+ {
+ fpe = xalloc(sizeof(FontPathElementRec));
+ if (!fpe)
+ {
+ err = BadAlloc;
+ goto bail;
+ }
+ fpe->name = xalloc(len + 1);
+ if (!fpe->name)
+ {
+ xfree(fpe);
+ err = BadAlloc;
+ goto bail;
+ }
+ fpe->refcount = 1;
+
+ strncpy(fpe->name, (char *) cp, (int) len);
+ fpe->name[len] = '\0';
+ fpe->name_length = len;
+ fpe->type = DetermineFPEType(fpe->name);
+ if (fpe->type == -1)
+ err = BadValue;
+ else
+ err = (*fpe_functions[fpe->type].init_fpe) (fpe);
+ if (err != Successful)
+ {
+ if (persist)
+ {
+ ErrorF("[dix] Could not init font path element %s, removing from list!\n",
+ fpe->name);
+ }
+ xfree (fpe->name);
+ xfree (fpe);
+ }
+ }
+ }
+ if (err != Successful)
+ {
+ if (!persist)
+ goto bail;
+ }
+ else
+ {
+ fplist[valid_paths++] = fpe;
+ }
+ cp += len;
+ }
+
+ FreeFontPath(font_path_elements, num_fpes, FALSE);
+ font_path_elements = fplist;
+ if (patternCache)
+ EmptyFontPatternCache(patternCache);
+ num_fpes = valid_paths;
+
+ return Success;
+bail:
+ *bad = i;
+ while (--valid_paths >= 0)
+ FreeFPE(fplist[valid_paths]);
+ xfree(fplist);
+ return FontToXError(err);
+}
+
+/* XXX -- do we need to pass error down to each renderer? */
+int
+SetFontPath(ClientPtr client, int npaths, unsigned char *paths, int *error)
+{
+ int err = XaceHook(XACE_SERVER_ACCESS, client, DixManageAccess);
+ if (err != Success)
+ return err;
+
+ if (npaths == 0) {
+ if (SetDefaultFontPath(defaultFontPath) != Success)
+ return BadValue;
+ } else {
+ err = SetFontPathElements(npaths, paths, error, FALSE);
+ }
+ return err;
+}
+
+int
+SetDefaultFontPath(char *path)
+{
+ char *temp_path,
+ *start,
+ *end;
+ unsigned char *cp,
+ *pp,
+ *nump,
+ *newpath;
+ int num = 1,
+ len,
+ err,
+ size = 0,
+ bad;
+
+ /* ensure temp_path contains "built-ins" */
+ start = path;
+ while (1) {
+ start = strstr(start, "built-ins");
+ if (start == NULL)
+ break;
+ end = start + strlen("built-ins");
+ if ((start == path || start[-1] == ',') && (!*end || *end == ','))
+ break;
+ start = end;
+ }
+ if (!start) {
+ temp_path = Xprintf("%s%sbuilt-ins", path, *path ? "," : "");
+ } else {
+ temp_path = Xstrdup(path);
+ }
+ if (!temp_path)
+ return BadAlloc;
+
+ /* get enough for string, plus values -- use up commas */
+ len = strlen(temp_path) + 1;
+ nump = cp = newpath = xalloc(len);
+ if (!newpath)
+ return BadAlloc;
+ pp = (unsigned char *) temp_path;
+ cp++;
+ while (*pp) {
+ if (*pp == ',') {
+ *nump = (unsigned char) size;
+ nump = cp++;
+ pp++;
+ num++;
+ size = 0;
+ } else {
+ *cp++ = *pp++;
+ size++;
+ }
+ }
+ *nump = (unsigned char) size;
+
+ err = SetFontPathElements(num, newpath, &bad, TRUE);
+
+ xfree(newpath);
+ xfree(temp_path);
+
+ return err;
+}
+
+int
+GetFontPath(ClientPtr client, int *count, int *length, unsigned char **result)
+{
+ int i;
+ unsigned char *c;
+ int len;
+ FontPathElementPtr fpe;
+
+ i = XaceHook(XACE_SERVER_ACCESS, client, DixGetAttrAccess);
+ if (i != Success)
+ return i;
+
+ len = 0;
+ for (i = 0; i < num_fpes; i++) {
+ fpe = font_path_elements[i];
+ len += fpe->name_length + 1;
+ }
+ font_path_string = (unsigned char *) xrealloc(font_path_string, len);
+ if (!font_path_string)
+ return BadAlloc;
+
+ c = font_path_string;
+ *length = 0;
+ for (i = 0; i < num_fpes; i++) {
+ fpe = font_path_elements[i];
+ *c = fpe->name_length;
+ *length += *c++;
+ memmove(c, fpe->name, fpe->name_length);
+ c += fpe->name_length;
+ }
+ *count = num_fpes;
+ *result = font_path_string;
+ return Success;
+}
+
+void
+DeleteClientFontStuff(ClientPtr client)
+{
+ int i;
+ FontPathElementPtr fpe;
+
+ for (i = 0; i < num_fpes; i++)
+ {
+ fpe = font_path_elements[i];
+ if (fpe_functions[fpe->type].client_died)
+ (*fpe_functions[fpe->type].client_died) ((pointer) client, fpe);
+ }
+}
+
+void
+InitFonts (void)
+{
+ patternCache = MakeFontPatternCache();
+
+ BuiltinRegisterFpeFunctions();
+ FontFileRegisterFpeFunctions();
+ fs_register_fpe_functions();
+}
+
+int
+GetDefaultPointSize (void)
+{
+ return 120;
+}
+
+
+FontResolutionPtr
+GetClientResolutions (int *num)
+{
+ static struct _FontResolution res;
+ ScreenPtr pScreen;
+
+ pScreen = screenInfo.screens[0];
+ res.x_resolution = (pScreen->width * 25.4) / pScreen->mmWidth;
+ /*
+ * XXX - we'll want this as long as bitmap instances are prevalent
+ so that we can match them from scalable fonts
+ */
+ if (res.x_resolution < 88)
+ res.x_resolution = 75;
+ else
+ res.x_resolution = 100;
+ res.y_resolution = (pScreen->height * 25.4) / pScreen->mmHeight;
+ if (res.y_resolution < 88)
+ res.y_resolution = 75;
+ else
+ res.y_resolution = 100;
+ res.point_size = 120;
+ *num = 1;
+ return &res;
+}
+
+/*
+ * returns the type index of the new fpe
+ *
+ * should be called (only once!) by each type of fpe when initialized
+ */
+
+int
+RegisterFPEFunctions(NameCheckFunc name_func,
+ InitFpeFunc init_func,
+ FreeFpeFunc free_func,
+ ResetFpeFunc reset_func,
+ OpenFontFunc open_func,
+ CloseFontFunc close_func,
+ ListFontsFunc list_func,
+ StartLfwiFunc start_lfwi_func,
+ NextLfwiFunc next_lfwi_func,
+ WakeupFpeFunc wakeup_func,
+ ClientDiedFunc client_died,
+ LoadGlyphsFunc load_glyphs,
+ StartLaFunc start_list_alias_func,
+ NextLaFunc next_list_alias_func,
+ SetPathFunc set_path_func)
+{
+ FPEFunctions *new;
+
+ /* grow the list */
+ new = (FPEFunctions *) xrealloc(fpe_functions,
+ (num_fpe_types + 1) * sizeof(FPEFunctions));
+ if (!new)
+ return -1;
+ fpe_functions = new;
+
+ fpe_functions[num_fpe_types].name_check = name_func;
+ fpe_functions[num_fpe_types].open_font = open_func;
+ fpe_functions[num_fpe_types].close_font = close_func;
+ fpe_functions[num_fpe_types].wakeup_fpe = wakeup_func;
+ fpe_functions[num_fpe_types].list_fonts = list_func;
+ fpe_functions[num_fpe_types].start_list_fonts_with_info =
+ start_lfwi_func;
+ fpe_functions[num_fpe_types].list_next_font_with_info =
+ next_lfwi_func;
+ fpe_functions[num_fpe_types].init_fpe = init_func;
+ fpe_functions[num_fpe_types].free_fpe = free_func;
+ fpe_functions[num_fpe_types].reset_fpe = reset_func;
+ fpe_functions[num_fpe_types].client_died = client_died;
+ fpe_functions[num_fpe_types].load_glyphs = load_glyphs;
+ fpe_functions[num_fpe_types].start_list_fonts_and_aliases =
+ start_list_alias_func;
+ fpe_functions[num_fpe_types].list_next_font_or_alias =
+ next_list_alias_func;
+ fpe_functions[num_fpe_types].set_path_hook = set_path_func;
+
+ return num_fpe_types++;
+}
+
+void
+FreeFonts(void)
+{
+ if (patternCache) {
+ FreeFontPatternCache(patternCache);
+ patternCache = 0;
+ }
+ FreeFontPath(font_path_elements, num_fpes, TRUE);
+ font_path_elements = 0;
+ num_fpes = 0;
+ xfree(fpe_functions);
+ num_fpe_types = 0;
+ fpe_functions = (FPEFunctions *) 0;
+}
+
+/* convenience functions for FS interface */
+
+FontPtr
+find_old_font(XID id)
+{
+ pointer pFont;
+ dixLookupResourceByType(&pFont, id, RT_NONE, serverClient, DixReadAccess);
+ return (FontPtr)pFont;
+}
+
+Font
+GetNewFontClientID(void)
+{
+ return FakeClientID(0);
+}
+
+int
+StoreFontClientFont(FontPtr pfont, Font id)
+{
+ return AddResource(id, RT_NONE, (pointer) pfont);
+}
+
+void
+DeleteFontClientID(Font id)
+{
+ FreeResource(id, RT_NONE);
+}
+
+int
+client_auth_generation(ClientPtr client)
+{
+ return 0;
+}
+
+static int fs_handlers_installed = 0;
+static unsigned int last_server_gen;
+
+int
+init_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler)
+{
+ /* if server has reset, make sure the b&w handlers are reinstalled */
+ if (last_server_gen < serverGeneration) {
+ last_server_gen = serverGeneration;
+ fs_handlers_installed = 0;
+ }
+ if (fs_handlers_installed == 0) {
+ if (!RegisterBlockAndWakeupHandlers(block_handler,
+ FontWakeup, (pointer) 0))
+ return AllocError;
+ fs_handlers_installed++;
+ }
+ QueueFontWakeup(fpe);
+ return Successful;
+}
+
+void
+remove_fs_handlers(FontPathElementPtr fpe, BlockHandlerProcPtr block_handler, Bool all)
+{
+ if (all) {
+ /* remove the handlers if no one else is using them */
+ if (--fs_handlers_installed == 0) {
+ RemoveBlockAndWakeupHandlers(block_handler, FontWakeup,
+ (pointer) 0);
+ }
+ }
+ RemoveFontWakeup(fpe);
+}
diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c index b5c88802c..781cc98e4 100644 --- a/xorg-server/dix/events.c +++ b/xorg-server/dix/events.c @@ -1,5916 +1,5919 @@ -/************************************************************ - -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. - -********************************************************/ - -/* The panoramix components contained the following notice */ -/***************************************************************** - -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. - -******************************************************************/ - -/* - * Copyright © 2003-2005 Sun Microsystems, 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 (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. - */ - -/** @file events.c - * This file handles event delivery and a big part of the server-side protocol - * handling (the parts for input devices). - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <X11/X.h> -#include "misc.h" -#include "resource.h" -#include <X11/Xproto.h> -#include "windowstr.h" -#include "inputstr.h" -#include "scrnintstr.h" -#include "cursorstr.h" - -#include "dixstruct.h" -#ifdef PANORAMIX -#include "panoramiX.h" -#include "panoramiXsrv.h" -#endif -#include "globals.h" - -#include <X11/extensions/XKBproto.h> -#include "xkbsrv.h" -#include "xace.h" - -#ifdef XSERVER_DTRACE -#include <sys/types.h> -typedef const char *string; -#include "Xserver-dtrace.h" -#endif - -#include <X11/extensions/XIproto.h> -#include <X11/extensions/XI2proto.h> -#include <X11/extensions/XI.h> -#include <X11/extensions/XI2.h> -#include "exglobals.h" -#include "exevents.h" -#include "exglobals.h" -#include "extnsionst.h" - -#include "dixevents.h" -#include "dixgrabs.h" -#include "dispatch.h" - -#include <X11/extensions/ge.h> -#include "geext.h" -#include "geint.h" - -#include "eventstr.h" -#include "enterleave.h" -#include "eventconvert.h" - -/* Extension events type numbering starts at EXTENSION_EVENT_BASE. */ -#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */ -#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask ) -#define AllButtonsMask ( \ - Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) -#define MotionMask ( \ - PointerMotionMask | Button1MotionMask | \ - Button2MotionMask | Button3MotionMask | Button4MotionMask | \ - Button5MotionMask | ButtonMotionMask ) -#define PropagateMask ( \ - KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \ - MotionMask ) -#define PointerGrabMask ( \ - ButtonPressMask | ButtonReleaseMask | \ - EnterWindowMask | LeaveWindowMask | \ - PointerMotionHintMask | KeymapStateMask | \ - MotionMask ) -#define AllModifiersMask ( \ - ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \ - Mod3Mask | Mod4Mask | Mod5Mask ) -#define LastEventMask OwnerGrabButtonMask -#define AllEventMasks (LastEventMask|(LastEventMask-1)) - - -#define CORE_EVENT(event) \ - (!((event)->u.u.type & EXTENSION_EVENT_BASE) && \ - (event)->u.u.type != GenericEvent) -#define XI2_EVENT(event) \ - (((event)->u.u.type == GenericEvent) && \ - ((xGenericEvent*)(event))->extension == IReqCode) - -/** - * Used to indicate a implicit passive grab created by a ButtonPress event. - * See DeliverEventsToWindow(). - */ -#define ImplicitGrabMask (1 << 7) - -#define WID(w) ((w) ? ((w)->drawable.id) : 0) - -#define XE_KBPTR (xE->u.keyButtonPointer) - - -#define rClient(obj) (clients[CLIENT_ID((obj)->resource)]) - -CallbackListPtr EventCallback; -CallbackListPtr DeviceEventCallback; - -#define DNPMCOUNT 8 - -Mask DontPropagateMasks[DNPMCOUNT]; -static int DontPropagateRefCnts[DNPMCOUNT]; - -static void CheckVirtualMotion( DeviceIntPtr pDev, QdEventPtr qe, WindowPtr pWin); -static void CheckPhysLimits(DeviceIntPtr pDev, - CursorPtr cursor, - Bool generateEvents, - Bool confineToScreen, - ScreenPtr pScreen); -static Bool CheckPassiveGrabsOnWindow(WindowPtr pWin, - DeviceIntPtr device, - DeviceEvent *event, - BOOL checkCore); - -/** Key repeat hack. Do not use but in TryClientEvents */ -extern BOOL EventIsKeyRepeat(xEvent *event); - -/** - * Main input device struct. - * inputInfo.pointer - * is the core pointer. Referred to as "virtual core pointer", "VCP", - * "core pointer" or inputInfo.pointer. The VCP is the first master - * pointer device and cannot be deleted. - * - * inputInfo.keyboard - * is the core keyboard ("virtual core keyboard", "VCK", "core keyboard"). - * See inputInfo.pointer. - * - * inputInfo.devices - * linked list containing all devices including VCP and VCK. - * - * inputInfo.off_devices - * Devices that have not been initialized and are thus turned off. - * - * inputInfo.numDevices - * Total number of devices. - * - * inputInfo.all_devices - * Virtual device used for XIAllDevices passive grabs. This device is - * not part of the inputInfo.devices list and mostly unset except for - * the deviceid. It exists because passivegrabs need a valid device - * reference. - * - * inputInfo.all_master_devices - * Virtual device used for XIAllMasterDevices passive grabs. This device - * is not part of the inputInfo.devices list and mostly unset except for - * the deviceid. It exists because passivegrabs need a valid device - * reference. - */ -InputInfo inputInfo; - -/** - * syncEvents is the global structure for queued events. - * - * Devices can be frozen through GrabModeSync pointer grabs. If this is the - * case, events from these devices are added to "pending" instead of being - * processed normally. When the device is unfrozen, events in "pending" are - * replayed and processed as if they would come from the device directly. - */ -static struct { - QdEventPtr pending, /**< list of queued events */ - *pendtail; /**< last event in list */ - /** The device to replay events for. Only set in AllowEvents(), in which - * case it is set to the device specified in the request. */ - DeviceIntPtr replayDev; /* kludgy rock to put flag for */ - - /** - * The window the events are supposed to be replayed on. - * This window may be set to the grab's window (but only when - * Replay{Pointer|Keyboard} is given in the XAllowEvents() - * request. */ - WindowPtr replayWin; /* ComputeFreezes */ - /** - * Flag to indicate whether we're in the process of - * replaying events. Only set in ComputeFreezes(). */ - Bool playingEvents; - TimeStamp time; -} syncEvents; - -/** - * The root window the given device is currently on. - */ -#define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0] - -static xEvent* swapEvent = NULL; -static int swapEventLen = 0; - -void -NotImplemented(xEvent *from, xEvent *to) -{ - FatalError("Not implemented"); -} - -/** - * Convert the given event type from an XI event to a core event. - * @param[in] The XI 1.x event type. - * @return The matching core event type or 0 if there is none. - */ -int -XItoCoreType(int xitype) -{ - int coretype = 0; - if (xitype == DeviceMotionNotify) - coretype = MotionNotify; - else if (xitype == DeviceButtonPress) - coretype = ButtonPress; - else if (xitype == DeviceButtonRelease) - coretype = ButtonRelease; - else if (xitype == DeviceKeyPress) - coretype = KeyPress; - else if (xitype == DeviceKeyRelease) - coretype = KeyRelease; - - return coretype; -} - -/** - * @return true if the device owns a cursor, false if device shares a cursor - * sprite with another device. - */ -Bool -DevHasCursor(DeviceIntPtr pDev) -{ - return pDev->spriteInfo->spriteOwner; -} - -/* - * @return true if a device is a pointer, check is the same as used by XI to - * fill the 'use' field. - */ -Bool -IsPointerDevice(DeviceIntPtr dev) -{ - return (dev->type == MASTER_POINTER) || - (dev->valuator && dev->button) || - (dev->valuator && !dev->key); -} - -/* - * @return true if a device is a keyboard, check is the same as used by XI to - * fill the 'use' field. - * - * Some pointer devices have keys as well (e.g. multimedia keys). Try to not - * count them as keyboard devices. - */ -Bool -IsKeyboardDevice(DeviceIntPtr dev) -{ - return (dev->type == MASTER_KEYBOARD) || - ((dev->key && dev->kbdfeed) && !IsPointerDevice(dev)); -} - -Bool -IsMaster(DeviceIntPtr dev) -{ - return (dev->type == MASTER_POINTER || dev->type == MASTER_KEYBOARD); -} - -static WindowPtr XYToWindow( - DeviceIntPtr pDev, - int x, - int y -); - -/** - * Max event opcode. - */ -extern int lastEvent; - -extern int DeviceMotionNotify; - -#define CantBeFiltered NoEventMask -/** - * Event masks for each event type. - * - * One set of filters for each device, but only the first layer - * is initialized. The rest is memcpy'd in InitEvents. - * - * Filters are used whether a given event may be delivered to a client, - * usually in the form of if (window-event-mask & filter); then deliver event. - * - * One notable filter is for PointerMotion/DevicePointerMotion events. Each - * time a button is pressed, the filter is modified to also contain the - * matching ButtonXMotion mask. - */ -static Mask filters[MAXDEVICES][128] = { -{ - NoSuchEvent, /* 0 */ - NoSuchEvent, /* 1 */ - KeyPressMask, /* KeyPress */ - KeyReleaseMask, /* KeyRelease */ - ButtonPressMask, /* ButtonPress */ - ButtonReleaseMask, /* ButtonRelease */ - PointerMotionMask, /* MotionNotify (initial state) */ - EnterWindowMask, /* EnterNotify */ - LeaveWindowMask, /* LeaveNotify */ - FocusChangeMask, /* FocusIn */ - FocusChangeMask, /* FocusOut */ - KeymapStateMask, /* KeymapNotify */ - ExposureMask, /* Expose */ - CantBeFiltered, /* GraphicsExpose */ - CantBeFiltered, /* NoExpose */ - VisibilityChangeMask, /* VisibilityNotify */ - SubstructureNotifyMask, /* CreateNotify */ - StructureAndSubMask, /* DestroyNotify */ - StructureAndSubMask, /* UnmapNotify */ - StructureAndSubMask, /* MapNotify */ - SubstructureRedirectMask, /* MapRequest */ - StructureAndSubMask, /* ReparentNotify */ - StructureAndSubMask, /* ConfigureNotify */ - SubstructureRedirectMask, /* ConfigureRequest */ - StructureAndSubMask, /* GravityNotify */ - ResizeRedirectMask, /* ResizeRequest */ - StructureAndSubMask, /* CirculateNotify */ - SubstructureRedirectMask, /* CirculateRequest */ - PropertyChangeMask, /* PropertyNotify */ - CantBeFiltered, /* SelectionClear */ - CantBeFiltered, /* SelectionRequest */ - CantBeFiltered, /* SelectionNotify */ - ColormapChangeMask, /* ColormapNotify */ - CantBeFiltered, /* ClientMessage */ - CantBeFiltered /* MappingNotify */ -}}; - -/** - * For the given event, return the matching event filter. This filter may then - * be AND'ed with the selected event mask. - * - * For XI2 events, the returned filter is simply the byte containing the event - * mask we're interested in. E.g. for a mask of (1 << 13), this would be - * byte[1]. - * - * @param[in] dev The device the event belongs to, may be NULL. - * @param[in] event The event to get the filter for. Only the type of the - * event matters, or the extension + evtype for GenericEvents. - * @return The filter mask for the given event. - * - * @see GetEventMask - */ -Mask -GetEventFilter(DeviceIntPtr dev, xEvent *event) -{ - if (event->u.u.type != GenericEvent) - return filters[dev ? dev->id : 0][event->u.u.type]; - else if (XI2_EVENT(event)) - return (1 << (((xXIDeviceEvent*)event)->evtype % 8)); - ErrorF("[dix] Unknown device type %d. No filter\n", event->u.u.type); - return 0; -} - -/** - * Return the windows complete XI2 mask for the given XI2 event type. - */ -Mask -GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev) -{ - OtherInputMasks *inputMasks = wOtherInputMasks(win); - int filter; - int evtype; - - if (!inputMasks || !XI2_EVENT(ev)) - return 0; - - evtype = ((xGenericEvent*)ev)->evtype; - filter = GetEventFilter(dev, ev); - - return ((inputMasks->xi2mask[dev->id][evtype/8] & filter) || - inputMasks->xi2mask[XIAllDevices][evtype/8] || - (inputMasks->xi2mask[XIAllMasterDevices][evtype/8] && IsMaster(dev))); -} - -static Mask -GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other) -{ - /* XI2 filters are only ever 8 bit, so let's return a 8 bit mask */ - if (XI2_EVENT(event)) - { - int byte = ((xGenericEvent*)event)->evtype / 8; - return (other->xi2mask[dev->id][byte] | - other->xi2mask[XIAllDevices][byte] | - (IsMaster(dev)? other->xi2mask[XIAllMasterDevices][byte] : 0)); - } else if (CORE_EVENT(event)) - return other->mask[XIAllDevices]; - else - return other->mask[dev->id]; -} - - -static CARD8 criticalEvents[32] = -{ - 0x7c, 0x30, 0x40 /* key, button, expose, and configure events */ -}; - -static void -SyntheticMotion(DeviceIntPtr dev, int x, int y) { - int screenno = 0; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) - screenno = dev->spriteInfo->sprite->screen->myNum; -#endif - PostSyntheticMotion(dev, x, y, screenno, - (syncEvents.playingEvents) ? syncEvents.time.milliseconds : currentTime.milliseconds); - -} - -#ifdef PANORAMIX -static void PostNewCursor(DeviceIntPtr pDev); - -static Bool -XineramaSetCursorPosition( - DeviceIntPtr pDev, - int x, - int y, - Bool generateEvent -){ - ScreenPtr pScreen; - BoxRec box; - int i; - SpritePtr pSprite = pDev->spriteInfo->sprite; - - /* x,y are in Screen 0 coordinates. We need to decide what Screen - to send the message too and what the coordinates relative to - that screen are. */ - - pScreen = pSprite->screen; - x += panoramiXdataPtr[0].x; - y += panoramiXdataPtr[0].y; - - if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum], - x, y, &box)) - { - FOR_NSCREENS(i) - { - if(i == pScreen->myNum) - continue; - if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box)) - { - pScreen = screenInfo.screens[i]; - break; - } - } - } - - pSprite->screen = pScreen; - pSprite->hotPhys.x = x - panoramiXdataPtr[0].x; - pSprite->hotPhys.y = y - panoramiXdataPtr[0].y; - x -= panoramiXdataPtr[pScreen->myNum].x; - y -= panoramiXdataPtr[pScreen->myNum].y; - - return (*pScreen->SetCursorPosition)(pDev, pScreen, x, y, generateEvent); -} - - -static void -XineramaConstrainCursor(DeviceIntPtr pDev) -{ - SpritePtr pSprite = pDev->spriteInfo->sprite; - ScreenPtr pScreen; - BoxRec newBox; - - pScreen = pSprite->screen; - newBox = pSprite->physLimits; - - /* Translate the constraining box to the screen - the sprite is actually on */ - newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x; - newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x; - newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y; - newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y; - - (* pScreen->ConstrainCursor)(pDev, pScreen, &newBox); -} - - -static Bool -XineramaSetWindowPntrs(DeviceIntPtr pDev, WindowPtr pWin) -{ - SpritePtr pSprite = pDev->spriteInfo->sprite; - - if(pWin == WindowTable[0]) { - memcpy(pSprite->windows, WindowTable, - PanoramiXNumScreens*sizeof(WindowPtr)); - } else { - PanoramiXRes *win; - int rc, i; - - rc = dixLookupResourceByType((pointer *)&win, pWin->drawable.id, - XRT_WINDOW, serverClient, DixReadAccess); - if (rc != Success) - return FALSE; - - for(i = 0; i < PanoramiXNumScreens; i++) { - rc = dixLookupWindow(pSprite->windows + i, win->info[i].id, - serverClient, DixReadAccess); - if (rc != Success) /* window is being unmapped */ - return FALSE; - } - } - return TRUE; -} - -static void -XineramaConfineCursorToWindow(DeviceIntPtr pDev, - WindowPtr pWin, - Bool generateEvents) -{ - SpritePtr pSprite = pDev->spriteInfo->sprite; - - int x, y, off_x, off_y, i; - - if(!XineramaSetWindowPntrs(pDev, pWin)) - return; - - i = PanoramiXNumScreens - 1; - - REGION_COPY(pSprite->screen, &pSprite->Reg1, - &pSprite->windows[i]->borderSize); - off_x = panoramiXdataPtr[i].x; - off_y = panoramiXdataPtr[i].y; - - while(i--) { - x = off_x - panoramiXdataPtr[i].x; - y = off_y - panoramiXdataPtr[i].y; - - if(x || y) - REGION_TRANSLATE(pSprite->screen, &pSprite->Reg1, x, y); - - REGION_UNION(pSprite->screen, &pSprite->Reg1, &pSprite->Reg1, - &pSprite->windows[i]->borderSize); - - off_x = panoramiXdataPtr[i].x; - off_y = panoramiXdataPtr[i].y; - } - - pSprite->hotLimits = *REGION_EXTENTS(pSprite->screen, &pSprite->Reg1); - - if(REGION_NUM_RECTS(&pSprite->Reg1) > 1) - pSprite->hotShape = &pSprite->Reg1; - else - pSprite->hotShape = NullRegion; - - pSprite->confined = FALSE; - pSprite->confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin; - - CheckPhysLimits(pDev, pSprite->current, generateEvents, FALSE, NULL); -} - -#endif /* PANORAMIX */ - -/** - * Modifies the filter for the given protocol event type to the given masks. - * - * There's only two callers: UpdateDeviceState() and XI's SetMaskForExtEvent(). - * The latter initialises masks for the matching XI events, it's a once-off - * setting. - * UDS however changes the mask for MotionNotify and DeviceMotionNotify each - * time a button is pressed to include the matching ButtonXMotion mask in the - * filter. - * - * @param[in] deviceid The device to modify the filter for. - * @param[in] mask The new filter mask. - * @param[in] event Protocol event type. - */ -void -SetMaskForEvent(int deviceid, Mask mask, int event) -{ - if (deviceid < 0 || deviceid >= MAXDEVICES) - FatalError("SetMaskForEvent: bogus device id"); - filters[deviceid][event] = mask; -} - -void -SetCriticalEvent(int event) -{ - if (event >= 128) - FatalError("SetCriticalEvent: bogus event number"); - criticalEvents[event >> 3] |= 1 << (event & 7); -} - -void -ConfineToShape(DeviceIntPtr pDev, RegionPtr shape, int *px, int *py) -{ - BoxRec box; - int x = *px, y = *py; - int incx = 1, incy = 1; - SpritePtr pSprite; - - pSprite = pDev->spriteInfo->sprite; - if (POINT_IN_REGION(pSprite->hot.pScreen, shape, x, y, &box)) - return; - box = *REGION_EXTENTS(pSprite->hot.pScreen, shape); - /* this is rather crude */ - do { - x += incx; - if (x >= box.x2) - { - incx = -1; - x = *px - 1; - } - else if (x < box.x1) - { - incx = 1; - x = *px; - y += incy; - if (y >= box.y2) - { - incy = -1; - y = *py - 1; - } - else if (y < box.y1) - return; /* should never get here! */ - } - } while (!POINT_IN_REGION(pSprite->hot.pScreen, shape, x, y, &box)); - *px = x; - *py = y; -} - -static void -CheckPhysLimits( - DeviceIntPtr pDev, - CursorPtr cursor, - Bool generateEvents, - Bool confineToScreen, /* unused if PanoramiX on */ - ScreenPtr pScreen) /* unused if PanoramiX on */ -{ - HotSpot new; - SpritePtr pSprite = pDev->spriteInfo->sprite; - - if (!cursor) - return; - new = pSprite->hotPhys; -#ifdef PANORAMIX - if (!noPanoramiXExtension) - /* I don't care what the DDX has to say about it */ - pSprite->physLimits = pSprite->hotLimits; - else -#endif - { - if (pScreen) - new.pScreen = pScreen; - else - pScreen = new.pScreen; - (*pScreen->CursorLimits) (pDev, pScreen, cursor, &pSprite->hotLimits, - &pSprite->physLimits); - pSprite->confined = confineToScreen; - (* pScreen->ConstrainCursor)(pDev, pScreen, &pSprite->physLimits); - } - - /* constrain the pointer to those limits */ - if (new.x < pSprite->physLimits.x1) - new.x = pSprite->physLimits.x1; - else - if (new.x >= pSprite->physLimits.x2) - new.x = pSprite->physLimits.x2 - 1; - if (new.y < pSprite->physLimits.y1) - new.y = pSprite->physLimits.y1; - else - if (new.y >= pSprite->physLimits.y2) - new.y = pSprite->physLimits.y2 - 1; - if (pSprite->hotShape) - ConfineToShape(pDev, pSprite->hotShape, &new.x, &new.y); - if ((pScreen != pSprite->hotPhys.pScreen) || - (new.x != pSprite->hotPhys.x) || (new.y != pSprite->hotPhys.y)) - { -#ifdef PANORAMIX - if (!noPanoramiXExtension) - XineramaSetCursorPosition (pDev, new.x, new.y, generateEvents); - else -#endif - { - if (pScreen != pSprite->hotPhys.pScreen) - pSprite->hotPhys = new; - (*pScreen->SetCursorPosition) - (pDev, pScreen, new.x, new.y, generateEvents); - } - if (!generateEvents) - SyntheticMotion(pDev, new.x, new.y); - } - -#ifdef PANORAMIX - /* Tell DDX what the limits are */ - if (!noPanoramiXExtension) - XineramaConstrainCursor(pDev); -#endif -} - -static void -CheckVirtualMotion( - DeviceIntPtr pDev, - QdEventPtr qe, - WindowPtr pWin) -{ - SpritePtr pSprite = pDev->spriteInfo->sprite; - RegionPtr reg = NULL; - DeviceEvent *ev = NULL; - - if (qe) - { - ev = &qe->event->device_event; - switch(ev->type) - { - case ET_Motion: - case ET_ButtonPress: - case ET_ButtonRelease: - case ET_KeyPress: - case ET_KeyRelease: - case ET_ProximityIn: - case ET_ProximityOut: - pSprite->hot.pScreen = qe->pScreen; - pSprite->hot.x = ev->root_x; - pSprite->hot.y = ev->root_y; - pWin = pDev->deviceGrab.grab ? pDev->deviceGrab.grab->confineTo : NullWindow; - break; - default: - break; - } - } - if (pWin) - { - BoxRec lims; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - int x, y, off_x, off_y, i; - - if(!XineramaSetWindowPntrs(pDev, pWin)) - return; - - i = PanoramiXNumScreens - 1; - - REGION_COPY(pSprite->screen, &pSprite->Reg2, - &pSprite->windows[i]->borderSize); - off_x = panoramiXdataPtr[i].x; - off_y = panoramiXdataPtr[i].y; - - while(i--) { - x = off_x - panoramiXdataPtr[i].x; - y = off_y - panoramiXdataPtr[i].y; - - if(x || y) - REGION_TRANSLATE(pSprite->screen, &pSprite->Reg2, x, y); - - REGION_UNION(pSprite->screen, &pSprite->Reg2, &pSprite->Reg2, - &pSprite->windows[i]->borderSize); - - off_x = panoramiXdataPtr[i].x; - off_y = panoramiXdataPtr[i].y; - } - } else -#endif - { - if (pSprite->hot.pScreen != pWin->drawable.pScreen) - { - pSprite->hot.pScreen = pWin->drawable.pScreen; - pSprite->hot.x = pSprite->hot.y = 0; - } - } - - lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize); - if (pSprite->hot.x < lims.x1) - pSprite->hot.x = lims.x1; - else if (pSprite->hot.x >= lims.x2) - pSprite->hot.x = lims.x2 - 1; - if (pSprite->hot.y < lims.y1) - pSprite->hot.y = lims.y1; - else if (pSprite->hot.y >= lims.y2) - pSprite->hot.y = lims.y2 - 1; - -#ifdef PANORAMIX - if (!noPanoramiXExtension) - { - if (REGION_NUM_RECTS(&pSprite->Reg2) > 1) - reg = &pSprite->Reg2; - - } else -#endif - { - if (wBoundingShape(pWin)) - reg = &pWin->borderSize; - } - - if (reg) - ConfineToShape(pDev, reg, &pSprite->hot.x, &pSprite->hot.y); - - if (qe && ev) - { - qe->pScreen = pSprite->hot.pScreen; - ev->root_x = pSprite->hot.x; - ev->root_y = pSprite->hot.y; - } - } -#ifdef PANORAMIX - if (noPanoramiXExtension) /* No typo. Only set the root win if disabled */ -#endif - RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum]; -} - -static void -ConfineCursorToWindow(DeviceIntPtr pDev, WindowPtr pWin, Bool generateEvents, Bool confineToScreen) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - SpritePtr pSprite = pDev->spriteInfo->sprite; - - if (syncEvents.playingEvents) - { - CheckVirtualMotion(pDev, (QdEventPtr)NULL, pWin); - SyntheticMotion(pDev, pSprite->hot.x, pSprite->hot.y); - } - else - { -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - XineramaConfineCursorToWindow(pDev, pWin, generateEvents); - return; - } -#endif - pSprite->hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize); - pSprite->hotShape = wBoundingShape(pWin) ? &pWin->borderSize - : NullRegion; - CheckPhysLimits(pDev, pSprite->current, generateEvents, - confineToScreen, pScreen); - } -} - -Bool -PointerConfinedToScreen(DeviceIntPtr pDev) -{ - return pDev->spriteInfo->sprite->confined; -} - -/** - * Update the sprite cursor to the given cursor. - * - * ChangeToCursor() will display the new cursor and free the old cursor (if - * applicable). If the provided cursor is already the updated cursor, nothing - * happens. - */ -static void -ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor) -{ - SpritePtr pSprite = pDev->spriteInfo->sprite; - ScreenPtr pScreen; - - if (cursor != pSprite->current) - { - if ((pSprite->current->bits->xhot != cursor->bits->xhot) || - (pSprite->current->bits->yhot != cursor->bits->yhot)) - CheckPhysLimits(pDev, cursor, FALSE, pSprite->confined, - (ScreenPtr)NULL); -#ifdef PANORAMIX - /* XXX: is this really necessary?? (whot) */ - if (!noPanoramiXExtension) - pScreen = pSprite->screen; - else -#endif - pScreen = pSprite->hotPhys.pScreen; - - (*pScreen->DisplayCursor)(pDev, pScreen, cursor); - FreeCursor(pSprite->current, (Cursor)0); - pSprite->current = cursor; - pSprite->current->refcnt++; - } -} - -/** - * @returns true if b is a descendent of a - */ -Bool -IsParent(WindowPtr a, WindowPtr b) -{ - for (b = b->parent; b; b = b->parent) - if (b == a) return TRUE; - return FALSE; -} - -/** - * Update the cursor displayed on the screen. - * - * Called whenever a cursor may have changed shape or position. - */ -static void -PostNewCursor(DeviceIntPtr pDev) -{ - WindowPtr win; - GrabPtr grab = pDev->deviceGrab.grab; - SpritePtr pSprite = pDev->spriteInfo->sprite; - CursorPtr pCursor; - - if (syncEvents.playingEvents) - return; - if (grab) - { - if (grab->cursor) - { - ChangeToCursor(pDev, grab->cursor); - return; - } - if (IsParent(grab->window, pSprite->win)) - win = pSprite->win; - else - win = grab->window; - } - else - win = pSprite->win; - for (; win; win = win->parent) - { - if (win->optional) - { - pCursor = WindowGetDeviceCursor(win, pDev); - if (!pCursor && win->optional->cursor != NullCursor) - pCursor = win->optional->cursor; - if (pCursor) - { - ChangeToCursor(pDev, pCursor); - return; - } - } - } -} - - -/** - * @param dev device which you want to know its current root window - * @return root window where dev's sprite is located - */ -WindowPtr -GetCurrentRootWindow(DeviceIntPtr dev) -{ - return RootWindow(dev); -} - -/** - * @return window underneath the cursor sprite. - */ -WindowPtr -GetSpriteWindow(DeviceIntPtr pDev) -{ - return pDev->spriteInfo->sprite->win; -} - -/** - * @return current sprite cursor. - */ -CursorPtr -GetSpriteCursor(DeviceIntPtr pDev) -{ - return pDev->spriteInfo->sprite->current; -} - -/** - * Set x/y current sprite position in screen coordinates. - */ -void -GetSpritePosition(DeviceIntPtr pDev, int *px, int *py) -{ - SpritePtr pSprite = pDev->spriteInfo->sprite; - *px = pSprite->hotPhys.x; - *py = pSprite->hotPhys.y; -} - -#ifdef PANORAMIX -int -XineramaGetCursorScreen(DeviceIntPtr pDev) -{ - if(!noPanoramiXExtension) { - return pDev->spriteInfo->sprite->screen->myNum; - } else { - return 0; - } -} -#endif /* PANORAMIX */ - -#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */ - -static void -MonthChangedOrBadTime(InternalEvent *ev) -{ - /* If the ddx/OS is careless about not processing timestamped events from - * different sources in sorted order, then it's possible for time to go - * backwards when it should not. Here we ensure a decent time. - */ - if ((currentTime.milliseconds - ev->any.time) > TIMESLOP) - currentTime.months++; - else - ev->any.time = currentTime.milliseconds; -} - -static void -NoticeTime(InternalEvent *ev) -{ - if (ev->any.time < currentTime.milliseconds) - MonthChangedOrBadTime(ev); - currentTime.milliseconds = ev->any.time; - lastDeviceEventTime = currentTime; -} - -void -NoticeEventTime(InternalEvent *ev) -{ - if (!syncEvents.playingEvents) - NoticeTime(ev); -} - -/************************************************************************** - * The following procedures deal with synchronous events * - **************************************************************************/ - -/** - * EnqueueEvent is a device's processInputProc if a device is frozen. - * Instead of delivering the events to the client, the event is tacked onto a - * linked list for later delivery. - */ -void -EnqueueEvent(InternalEvent *ev, DeviceIntPtr device) -{ - QdEventPtr tail = *syncEvents.pendtail; - QdEventPtr qe; - SpritePtr pSprite = device->spriteInfo->sprite; - int eventlen; - DeviceEvent *event = &ev->device_event; - - NoticeTime((InternalEvent*)event); - - /* Fix for key repeating bug. */ - if (device->key != NULL && device->key->xkbInfo != NULL && - event->type == ET_KeyRelease) - AccessXCancelRepeatKey(device->key->xkbInfo, event->detail.key); - - if (DeviceEventCallback) - { - DeviceEventInfoRec eventinfo; - xEvent *xi_events = NULL; - int count; - - /* The RECORD spec says that the root window field of motion events - * must be valid. At this point, it hasn't been filled in yet, so - * we do it here. The long expression below is necessary to get - * the current root window; the apparently reasonable alternative - * GetCurrentRootWindow()->drawable.id doesn't give you the right - * answer on the first motion event after a screen change because - * the data that GetCurrentRootWindow relies on hasn't been - * updated yet. - */ - - if (ev->any.type == ET_Motion) - ev->device_event.root = - WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id; - - EventToXI(ev, &xi_events, &count); - - eventinfo.events = (xEventPtr)xi_events; - eventinfo.count = count; - CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); - xfree(xi_events); - - if (IsMaster(device)) - { - xEvent core; - EventToCore(ev, &core); - eventinfo.events = (xEventPtr)&core; - eventinfo.count = 1; - CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo); - } - - } - - if (event->type == ET_Motion) - { -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - event->root_x += panoramiXdataPtr[pSprite->screen->myNum].x - - panoramiXdataPtr[0].x; - event->root_y += panoramiXdataPtr[pSprite->screen->myNum].y - - panoramiXdataPtr[0].y; - } -#endif - pSprite->hotPhys.x = event->root_x; - pSprite->hotPhys.y = event->root_y; - /* do motion compression, but not if from different devices */ - if (tail && - (tail->event->any.type == ET_Motion) && - (tail->device == device) && - (tail->pScreen == pSprite->hotPhys.pScreen)) - { - DeviceEvent *tailev = &tail->event->device_event; - tailev->root_x = pSprite->hotPhys.x; - tailev->root_y = pSprite->hotPhys.y; - tailev->time = event->time; - tail->months = currentTime.months; - return; - } - } - - eventlen = event->length; - - qe = xalloc(sizeof(QdEventRec) + eventlen); - if (!qe) - return; - qe->next = (QdEventPtr)NULL; - qe->device = device; - qe->pScreen = pSprite->hotPhys.pScreen; - qe->months = currentTime.months; - qe->event = (InternalEvent *)(qe + 1); - memcpy(qe->event, event, eventlen); - if (tail) - syncEvents.pendtail = &tail->next; - *syncEvents.pendtail = qe; -} - -/** - * Run through the list of events queued up in syncEvents. - * For each event do: - * If the device for this event is not frozen anymore, take it and process it - * as usually. - * After that, check if there's any devices in the list that are not frozen. - * If there is none, we're done. If there is at least one device that is not - * frozen, then re-run from the beginning of the event queue. - */ -static void -PlayReleasedEvents(void) -{ - QdEventPtr *prev, qe; - DeviceIntPtr dev; - DeviceIntPtr pDev; - - prev = &syncEvents.pending; - while ( (qe = *prev) ) - { - if (!qe->device->deviceGrab.sync.frozen) - { - *prev = qe->next; - pDev = qe->device; - if (*syncEvents.pendtail == *prev) - syncEvents.pendtail = prev; - if (qe->event->any.type == ET_Motion) - CheckVirtualMotion(pDev, qe, NullWindow); - syncEvents.time.months = qe->months; - syncEvents.time.milliseconds = qe->event->any.time; -#ifdef PANORAMIX - /* Translate back to the sprite screen since processInputProc - will translate from sprite screen to screen 0 upon reentry - to the DIX layer */ - if(!noPanoramiXExtension) { - DeviceEvent *ev = &qe->event->device_event; - switch(ev->type) - { - case ET_Motion: - case ET_ButtonPress: - case ET_ButtonRelease: - case ET_KeyPress: - case ET_KeyRelease: - case ET_ProximityIn: - case ET_ProximityOut: - ev->root_x += panoramiXdataPtr[0].x - - panoramiXdataPtr[pDev->spriteInfo->sprite->screen->myNum].x; - ev->root_y += panoramiXdataPtr[0].y - - panoramiXdataPtr[pDev->spriteInfo->sprite->screen->myNum].y; - break; - default: - break; - } - - } -#endif - (*qe->device->public.processInputProc)(qe->event, qe->device); - xfree(qe); - for (dev = inputInfo.devices; dev && dev->deviceGrab.sync.frozen; dev = dev->next) - ; - if (!dev) - break; - /* Playing the event may have unfrozen another device. */ - /* So to play it safe, restart at the head of the queue */ - prev = &syncEvents.pending; - } - else - prev = &qe->next; - } -} - -/** - * Freeze or thaw the given devices. The device's processing proc is - * switched to either the real processing proc (in case of thawing) or an - * enqueuing processing proc (usually EnqueueEvent()). - * - * @param dev The device to freeze/thaw - * @param frozen True to freeze or false to thaw. - */ -static void -FreezeThaw(DeviceIntPtr dev, Bool frozen) -{ - dev->deviceGrab.sync.frozen = frozen; - if (frozen) - dev->public.processInputProc = dev->public.enqueueInputProc; - else - dev->public.processInputProc = dev->public.realInputProc; -} - -/** - * Unfreeze devices and replay all events to the respective clients. - * - * ComputeFreezes takes the first event in the device's frozen event queue. It - * runs up the sprite tree (spriteTrace) and searches for the window to replay - * the events from. If it is found, it checks for passive grabs one down from - * the window or delivers the events. - */ -static void -ComputeFreezes(void) -{ - DeviceIntPtr replayDev = syncEvents.replayDev; - int i; - WindowPtr w; - GrabPtr grab; - DeviceIntPtr dev; - - for (dev = inputInfo.devices; dev; dev = dev->next) - FreezeThaw(dev, dev->deviceGrab.sync.other || - (dev->deviceGrab.sync.state >= FROZEN)); - if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending)) - return; - syncEvents.playingEvents = TRUE; - if (replayDev) - { - DeviceEvent* event = replayDev->deviceGrab.sync.event; - - syncEvents.replayDev = (DeviceIntPtr)NULL; - - w = XYToWindow(replayDev, event->root_x, event->root_y); - for (i = 0; i < replayDev->spriteInfo->sprite->spriteTraceGood; i++) - { - if (syncEvents.replayWin == - replayDev->spriteInfo->sprite->spriteTrace[i]) - { - if (!CheckDeviceGrabs(replayDev, event, i+1)) { - if (replayDev->focus && !IsPointerEvent((InternalEvent*)event)) - DeliverFocusedEvent(replayDev, (InternalEvent*)event, w); - else - DeliverDeviceEvents(w, (InternalEvent*)event, NullGrab, - NullWindow, replayDev); - } - goto playmore; - } - } - /* must not still be in the same stack */ - if (replayDev->focus && !IsPointerEvent((InternalEvent*)event)) - DeliverFocusedEvent(replayDev, (InternalEvent*)event, w); - else - DeliverDeviceEvents(w, (InternalEvent*)event, NullGrab, - NullWindow, replayDev); - } -playmore: - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (!dev->deviceGrab.sync.frozen) - { - PlayReleasedEvents(); - break; - } - } - syncEvents.playingEvents = FALSE; - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (DevHasCursor(dev)) - { - /* the following may have been skipped during replay, - so do it now */ - if ((grab = dev->deviceGrab.grab) && grab->confineTo) - { - if (grab->confineTo->drawable.pScreen != - dev->spriteInfo->sprite->hotPhys.pScreen) - dev->spriteInfo->sprite->hotPhys.x = - dev->spriteInfo->sprite->hotPhys.y = 0; - ConfineCursorToWindow(dev, grab->confineTo, TRUE, TRUE); - } - else - ConfineCursorToWindow(dev, - WindowTable[dev->spriteInfo->sprite->hotPhys.pScreen->myNum], - TRUE, FALSE); - PostNewCursor(dev); - } - } -} - -#ifdef RANDR -void -ScreenRestructured (ScreenPtr pScreen) -{ - GrabPtr grab; - DeviceIntPtr pDev; - - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) - { - if (!DevHasCursor(pDev)) - continue; - - /* GrabDevice doesn't have a confineTo field, so we don't need to - * worry about it. */ - if ((grab = pDev->deviceGrab.grab) && grab->confineTo) - { - if (grab->confineTo->drawable.pScreen - != pDev->spriteInfo->sprite->hotPhys.pScreen) - pDev->spriteInfo->sprite->hotPhys.x = pDev->spriteInfo->sprite->hotPhys.y = 0; - ConfineCursorToWindow(pDev, grab->confineTo, TRUE, TRUE); - } - else - ConfineCursorToWindow(pDev, - WindowTable[pDev->spriteInfo->sprite->hotPhys.pScreen->myNum], - TRUE, FALSE); - } -} -#endif - -static void -CheckGrabForSyncs(DeviceIntPtr thisDev, Bool thisMode, Bool otherMode) -{ - GrabPtr grab = thisDev->deviceGrab.grab; - DeviceIntPtr dev; - - if (thisMode == GrabModeSync) - thisDev->deviceGrab.sync.state = FROZEN_NO_EVENT; - else - { /* free both if same client owns both */ - thisDev->deviceGrab.sync.state = THAWED; - if (thisDev->deviceGrab.sync.other && - (CLIENT_BITS(thisDev->deviceGrab.sync.other->resource) == - CLIENT_BITS(grab->resource))) - thisDev->deviceGrab.sync.other = NullGrab; - } - - /* - XXX: Direct slave grab won't freeze the paired master device. - The correct thing to do would be to freeze all SDs attached to the - paired master device. - */ - if (IsMaster(thisDev)) - { - dev = GetPairedDevice(thisDev); - if (otherMode == GrabModeSync) - dev->deviceGrab.sync.other = grab; - else - { /* free both if same client owns both */ - if (dev->deviceGrab.sync.other && - (CLIENT_BITS(dev->deviceGrab.sync.other->resource) == - CLIENT_BITS(grab->resource))) - dev->deviceGrab.sync.other = NullGrab; - } - } - ComputeFreezes(); -} - -/* Only ever used if a grab is called on an attached slave device. */ -static int GrabPrivateKeyIndex; -static DevPrivateKey GrabPrivateKey = &GrabPrivateKeyIndex; - -/** - * Save the device's master device in the devPrivates. This needs to be done - * if a client directly grabs a slave device that is attached to a master. For - * the duration of the grab, the device is detached, ungrabbing re-attaches it - * though. - * - * We store the ID of the master device only in case the master disappears - * while the device has a grab. - */ -static void -DetachFromMaster(DeviceIntPtr dev) -{ - intptr_t id; - if (!dev->u.master) - return; - - id = dev->u.master->id; - - dixSetPrivate(&dev->devPrivates, GrabPrivateKey, (void *)id); - AttachDevice(NULL, dev, NULL); -} - -static void -ReattachToOldMaster(DeviceIntPtr dev) -{ - int id; - void *p; - DeviceIntPtr master = NULL; - - if (IsMaster(dev)) - return; - - - p = dixLookupPrivate(&dev->devPrivates, GrabPrivateKey); - id = (intptr_t) p; /* silence gcc warnings */ - dixLookupDevice(&master, id, serverClient, DixUseAccess); - - if (master) - { - AttachDevice(serverClient, dev, master); - dixSetPrivate(&dev->devPrivates, GrabPrivateKey, NULL); - } -} - -/** - * Activate a pointer grab on the given device. A pointer grab will cause all - * core pointer events of this device to be delivered to the grabbing client only. - * No other device will send core events to the grab client while the grab is - * on, but core events will be sent to other clients. - * Can cause the cursor to change if a grab cursor is set. - * - * Note that parameter autoGrab may be (True & ImplicitGrabMask) if the grab - * is an implicit grab caused by a ButtonPress event. - * - * @param mouse The device to grab. - * @param grab The grab structure, needs to be setup. - * @param autoGrab True if the grab was caused by a button down event and not - * explicitely by a client. - */ -void -ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab, - TimeStamp time, Bool autoGrab) -{ - GrabInfoPtr grabinfo = &mouse->deviceGrab; - WindowPtr oldWin = (grabinfo->grab) ? - grabinfo->grab->window - : mouse->spriteInfo->sprite->win; - Bool isPassive = autoGrab & ~ImplicitGrabMask; - - /* slave devices need to float for the duration of the grab. */ - if (grab->grabtype == GRABTYPE_XI2 && - !(autoGrab & ImplicitGrabMask) && !IsMaster(mouse)) - DetachFromMaster(mouse); - - if (grab->confineTo) - { - if (grab->confineTo->drawable.pScreen - != mouse->spriteInfo->sprite->hotPhys.pScreen) - mouse->spriteInfo->sprite->hotPhys.x = - mouse->spriteInfo->sprite->hotPhys.y = 0; - ConfineCursorToWindow(mouse, grab->confineTo, FALSE, TRUE); - } - DoEnterLeaveEvents(mouse, mouse->id, oldWin, grab->window, NotifyGrab); - mouse->valuator->motionHintWindow = NullWindow; - if (syncEvents.playingEvents) - grabinfo->grabTime = syncEvents.time; - else - grabinfo->grabTime = time; - if (grab->cursor) - grab->cursor->refcnt++; - grabinfo->activeGrab = *grab; - grabinfo->grab = &grabinfo->activeGrab; - grabinfo->fromPassiveGrab = isPassive; - grabinfo->implicitGrab = autoGrab & ImplicitGrabMask; - PostNewCursor(mouse); - CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode); -} - -/** - * Delete grab on given device, update the sprite. - * - * Extension devices are set up for ActivateKeyboardGrab(). - */ -void -DeactivatePointerGrab(DeviceIntPtr mouse) -{ - GrabPtr grab = mouse->deviceGrab.grab; - DeviceIntPtr dev; - Bool wasImplicit = (mouse->deviceGrab.fromPassiveGrab && - mouse->deviceGrab.implicitGrab); - - mouse->valuator->motionHintWindow = NullWindow; - mouse->deviceGrab.grab = NullGrab; - mouse->deviceGrab.sync.state = NOT_GRABBED; - mouse->deviceGrab.fromPassiveGrab = FALSE; - - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (dev->deviceGrab.sync.other == grab) - dev->deviceGrab.sync.other = NullGrab; - } - DoEnterLeaveEvents(mouse, mouse->id, grab->window, - mouse->spriteInfo->sprite->win, NotifyUngrab); - if (grab->confineTo) - ConfineCursorToWindow(mouse, RootWindow(mouse), FALSE, FALSE); - PostNewCursor(mouse); - if (grab->cursor) - FreeCursor(grab->cursor, (Cursor)0); - - if (!wasImplicit && grab->grabtype == GRABTYPE_XI2) - ReattachToOldMaster(mouse); - - ComputeFreezes(); -} - -/** - * Activate a keyboard grab on the given device. - * - * Extension devices have ActivateKeyboardGrab() set as their grabbing proc. - */ -void -ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive) -{ - GrabInfoPtr grabinfo = &keybd->deviceGrab; - WindowPtr oldWin; - - /* slave devices need to float for the duration of the grab. */ - if (grab->grabtype == GRABTYPE_XI2 && - !(passive & ImplicitGrabMask) && - !IsMaster(keybd)) - DetachFromMaster(keybd); - - if (grabinfo->grab) - oldWin = grabinfo->grab->window; - else if (keybd->focus) - oldWin = keybd->focus->win; - else - oldWin = keybd->spriteInfo->sprite->win; - if (oldWin == FollowKeyboardWin) - oldWin = keybd->focus->win; - if (keybd->valuator) - keybd->valuator->motionHintWindow = NullWindow; - DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab); - if (syncEvents.playingEvents) - grabinfo->grabTime = syncEvents.time; - else - grabinfo->grabTime = time; - grabinfo->activeGrab = *grab; - grabinfo->grab = &grabinfo->activeGrab; - grabinfo->fromPassiveGrab = passive; - grabinfo->implicitGrab = passive & ImplicitGrabMask; - CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode); -} - -/** - * Delete keyboard grab for the given device. - */ -void -DeactivateKeyboardGrab(DeviceIntPtr keybd) -{ - GrabPtr grab = keybd->deviceGrab.grab; - DeviceIntPtr dev; - WindowPtr focusWin = keybd->focus ? keybd->focus->win - : keybd->spriteInfo->sprite->win; - Bool wasImplicit = (keybd->deviceGrab.fromPassiveGrab && - keybd->deviceGrab.implicitGrab); - - if (focusWin == FollowKeyboardWin) - focusWin = inputInfo.keyboard->focus->win; - if (keybd->valuator) - keybd->valuator->motionHintWindow = NullWindow; - keybd->deviceGrab.grab = NullGrab; - keybd->deviceGrab.sync.state = NOT_GRABBED; - keybd->deviceGrab.fromPassiveGrab = FALSE; - - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (dev->deviceGrab.sync.other == grab) - dev->deviceGrab.sync.other = NullGrab; - } - DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab); - - if (!wasImplicit && grab->grabtype == GRABTYPE_XI2) - ReattachToOldMaster(keybd); - - ComputeFreezes(); -} - -void -AllowSome(ClientPtr client, - TimeStamp time, - DeviceIntPtr thisDev, - int newState) -{ - Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced; - TimeStamp grabTime; - DeviceIntPtr dev; - GrabInfoPtr devgrabinfo, - grabinfo = &thisDev->deviceGrab; - - thisGrabbed = grabinfo->grab && SameClient(grabinfo->grab, client); - thisSynced = FALSE; - otherGrabbed = FALSE; - othersFrozen = FALSE; - grabTime = grabinfo->grabTime; - for (dev = inputInfo.devices; dev; dev = dev->next) - { - devgrabinfo = &dev->deviceGrab; - - if (dev == thisDev) - continue; - if (devgrabinfo->grab && SameClient(devgrabinfo->grab, client)) - { - if (!(thisGrabbed || otherGrabbed) || - (CompareTimeStamps(devgrabinfo->grabTime, grabTime) == LATER)) - grabTime = devgrabinfo->grabTime; - otherGrabbed = TRUE; - if (grabinfo->sync.other == devgrabinfo->grab) - thisSynced = TRUE; - if (devgrabinfo->sync.state >= FROZEN) - othersFrozen = TRUE; - } - } - if (!((thisGrabbed && grabinfo->sync.state >= FROZEN) || thisSynced)) - return; - if ((CompareTimeStamps(time, currentTime) == LATER) || - (CompareTimeStamps(time, grabTime) == EARLIER)) - return; - switch (newState) - { - case THAWED: /* Async */ - if (thisGrabbed) - grabinfo->sync.state = THAWED; - if (thisSynced) - grabinfo->sync.other = NullGrab; - ComputeFreezes(); - break; - case FREEZE_NEXT_EVENT: /* Sync */ - if (thisGrabbed) - { - grabinfo->sync.state = FREEZE_NEXT_EVENT; - if (thisSynced) - grabinfo->sync.other = NullGrab; - ComputeFreezes(); - } - break; - case THAWED_BOTH: /* AsyncBoth */ - if (othersFrozen) - { - for (dev = inputInfo.devices; dev; dev = dev->next) - { - devgrabinfo = &dev->deviceGrab; - if (devgrabinfo->grab - && SameClient(devgrabinfo->grab, client)) - devgrabinfo->sync.state = THAWED; - if (devgrabinfo->sync.other && - SameClient(devgrabinfo->sync.other, client)) - devgrabinfo->sync.other = NullGrab; - } - ComputeFreezes(); - } - break; - case FREEZE_BOTH_NEXT_EVENT: /* SyncBoth */ - if (othersFrozen) - { - for (dev = inputInfo.devices; dev; dev = dev->next) - { - devgrabinfo = &dev->deviceGrab; - if (devgrabinfo->grab - && SameClient(devgrabinfo->grab, client)) - devgrabinfo->sync.state = FREEZE_BOTH_NEXT_EVENT; - if (devgrabinfo->sync.other - && SameClient(devgrabinfo->sync.other, client)) - devgrabinfo->sync.other = NullGrab; - } - ComputeFreezes(); - } - break; - case NOT_GRABBED: /* Replay */ - if (thisGrabbed && grabinfo->sync.state == FROZEN_WITH_EVENT) - { - if (thisSynced) - grabinfo->sync.other = NullGrab; - syncEvents.replayDev = thisDev; - syncEvents.replayWin = grabinfo->grab->window; - (*grabinfo->DeactivateGrab)(thisDev); - syncEvents.replayDev = (DeviceIntPtr)NULL; - } - break; - case THAW_OTHERS: /* AsyncOthers */ - if (othersFrozen) - { - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (dev == thisDev) - continue; - devgrabinfo = &dev->deviceGrab; - if (devgrabinfo->grab - && SameClient(devgrabinfo->grab, client)) - devgrabinfo->sync.state = THAWED; - if (devgrabinfo->sync.other - && SameClient(devgrabinfo->sync.other, client)) - devgrabinfo->sync.other = NullGrab; - } - ComputeFreezes(); - } - break; - } -} - -/** - * Server-side protocol handling for AllowEvents request. - * - * Release some events from a frozen device. - */ -int -ProcAllowEvents(ClientPtr client) -{ - TimeStamp time; - DeviceIntPtr mouse = NULL; - DeviceIntPtr keybd = NULL; - REQUEST(xAllowEventsReq); - - REQUEST_SIZE_MATCH(xAllowEventsReq); - time = ClientTimeToServerTime(stuff->time); - - mouse = PickPointer(client); - keybd = PickKeyboard(client); - - switch (stuff->mode) - { - case ReplayPointer: - AllowSome(client, time, mouse, NOT_GRABBED); - break; - case SyncPointer: - AllowSome(client, time, mouse, FREEZE_NEXT_EVENT); - break; - case AsyncPointer: - AllowSome(client, time, mouse, THAWED); - break; - case ReplayKeyboard: - AllowSome(client, time, keybd, NOT_GRABBED); - break; - case SyncKeyboard: - AllowSome(client, time, keybd, FREEZE_NEXT_EVENT); - break; - case AsyncKeyboard: - AllowSome(client, time, keybd, THAWED); - break; - case SyncBoth: - AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT); - break; - case AsyncBoth: - AllowSome(client, time, keybd, THAWED_BOTH); - break; - default: - client->errorValue = stuff->mode; - return BadValue; - } - return Success; -} - -/** - * Deactivate grabs from any device that has been grabbed by the client. - */ -void -ReleaseActiveGrabs(ClientPtr client) -{ - DeviceIntPtr dev; - Bool done; - - /* XXX CloseDownClient should remove passive grabs before - * releasing active grabs. - */ - do { - done = TRUE; - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (dev->deviceGrab.grab && SameClient(dev->deviceGrab.grab, client)) - { - (*dev->deviceGrab.DeactivateGrab)(dev); - done = FALSE; - } - } - } while (!done); -} - -/************************************************************************** - * The following procedures deal with delivering events * - **************************************************************************/ - -/** - * Deliver the given events to the given client. - * - * More than one event may be delivered at a time. This is the case with - * DeviceMotionNotifies which may be followed by DeviceValuator events. - * - * TryClientEvents() is the last station before actually writing the events to - * the socket. Anything that is not filtered here, will get delivered to the - * client. - * An event is only delivered if - * - mask and filter match up. - * - no other client has a grab on the device that caused the event. - * - * - * @param client The target client to deliver to. - * @param dev The device the event came from. May be NULL. - * @param pEvents The events to be delivered. - * @param count Number of elements in pEvents. - * @param mask Event mask as set by the window. - * @param filter Mask based on event type. - * @param grab Possible grab on the device that caused the event. - * - * @return 1 if event was delivered, 0 if not or -1 if grab was not set by the - * client. - */ -int -TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents, - int count, Mask mask, Mask filter, GrabPtr grab) -{ - int i; - int type; - -#ifdef DEBUG_EVENTS - ErrorF("[dix] Event([%d, %d], mask=0x%lx), client=%d%s", - pEvents->u.u.type, pEvents->u.u.detail, mask, - client ? client->index : -1, - (client && client->clientGone) ? " (gone)" : ""); -#endif - - if (!client || client == serverClient || client->clientGone) { -#ifdef DEBUG_EVENTS - ErrorF(" not delivered to fake/dead client\n"); -#endif - return 0; - } - - if (filter != CantBeFiltered && !(mask & filter)) - { - #ifdef DEBUG_EVENTS - ErrorF(" filtered\n"); - #endif - return 0; - } - - if (grab && !SameClient(grab, client)) - { -#ifdef DEBUG_EVENTS - ErrorF(" not delivered due to grab\n"); -#endif - return -1; /* don't send, but notify caller */ - } - - type = pEvents->u.u.type; - if (type == MotionNotify) - { - if (mask & PointerMotionHintMask) - { - if (WID(dev->valuator->motionHintWindow) == - pEvents->u.keyButtonPointer.event) - { -#ifdef DEBUG_EVENTS - ErrorF("[dix] \n"); - ErrorF("[dix] motionHintWindow == keyButtonPointer.event\n"); -#endif - return 1; /* don't send, but pretend we did */ - } - pEvents->u.u.detail = NotifyHint; - } - else - { - pEvents->u.u.detail = NotifyNormal; - } - } - else if (type == DeviceMotionNotify) - { - if (MaybeSendDeviceMotionNotifyHint((deviceKeyButtonPointer*)pEvents, - mask) != 0) - return 1; - } else if (type == KeyPress) - { - if (EventIsKeyRepeat(pEvents)) - { - if (!_XkbWantsDetectableAutoRepeat(client)) - { - xEvent release = *pEvents; - release.u.u.type = KeyRelease; - release.u.u.sequenceNumber = client->sequence; - WriteEventsToClient(client, 1, &release); -#ifdef DEBUG_EVENTS - ErrorF(" (plus fake core release for repeat)"); -#endif - } else - { -#ifdef DEBUG_EVENTS - ErrorF(" (detectable autorepeat for core)"); -#endif - } - } - - } else if (type == DeviceKeyPress) - { - if (EventIsKeyRepeat(pEvents)) - { - if (!_XkbWantsDetectableAutoRepeat(client)) - { - deviceKeyButtonPointer release = *(deviceKeyButtonPointer *)pEvents; - release.type = DeviceKeyRelease; - release.sequenceNumber = client->sequence; -#ifdef DEBUG_EVENTS - ErrorF(" (plus fake xi1 release for repeat)"); -#endif - WriteEventsToClient(client, 1, (xEvent *) &release); - } - else { -#ifdef DEBUG_EVENTS - ErrorF(" (detectable autorepeat for core)"); -#endif - } - } - } - - type &= 0177; - if (type != KeymapNotify) - { - /* all extension events must have a sequence number */ - for (i = 0; i < count; i++) - pEvents[i].u.u.sequenceNumber = client->sequence; - } - - if (BitIsOn(criticalEvents, type)) - { - if (client->smart_priority < SMART_MAX_PRIORITY) - client->smart_priority++; - SetCriticalOutputPending(); - } - - WriteEventsToClient(client, count, pEvents); -#ifdef DEBUG_EVENTS - ErrorF("[dix] delivered\n"); -#endif - return 1; -} - -/** - * Deliver events to a window. At this point, we do not yet know if the event - * actually needs to be delivered. May activate a grab if the event is a - * button press. - * - * Core events are always delivered to the window owner. If the filter is - * something other than CantBeFiltered, the event is also delivered to other - * clients with the matching mask on the window. - * - * More than one event may be delivered at a time. This is the case with - * DeviceMotionNotifies which may be followed by DeviceValuator events. - * - * @param pWin The window that would get the event. - * @param pEvents The events to be delivered. - * @param count Number of elements in pEvents. - * @param filter Mask based on event type. - * @param grab Possible grab on the device that caused the event. - * - * @return Number of events delivered to various clients. - */ -int -DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent - *pEvents, int count, Mask filter, GrabPtr grab) -{ - int deliveries = 0, nondeliveries = 0; - int attempt; - InputClients *other; - ClientPtr client = NullClient; - Mask deliveryMask = 0; /* If a grab occurs due to a button press, then - this mask is the mask of the grab. */ - int type = pEvents->u.u.type; - - - /* Deliver to window owner */ - if ((filter == CantBeFiltered) || CORE_EVENT(pEvents)) - { - /* if nobody ever wants to see this event, skip some work */ - if (filter != CantBeFiltered && - !((wOtherEventMasks(pWin)|pWin->eventMask) & filter)) - return 0; - - if (IsInterferingGrab(wClient(pWin), pDev, pEvents)) - return 0; - - if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count)) - /* do nothing */; - else if ( (attempt = TryClientEvents(wClient(pWin), pDev, pEvents, - count, pWin->eventMask, - filter, grab)) ) - { - if (attempt > 0) - { - deliveries++; - client = wClient(pWin); - deliveryMask = pWin->eventMask; - } else - nondeliveries--; - } - } - - /* CantBeFiltered means only window owner gets the event */ - if (filter != CantBeFiltered) - { - if (CORE_EVENT(pEvents)) - other = (InputClients *)wOtherClients(pWin); - else if (XI2_EVENT(pEvents)) - { - OtherInputMasks *inputMasks = wOtherInputMasks(pWin); - /* Has any client selected for the event? */ - if (!GetWindowXI2Mask(pDev, pWin, pEvents)) - return 0; - other = inputMasks->inputClients; - } else { - OtherInputMasks *inputMasks = wOtherInputMasks(pWin); - /* Has any client selected for the event? */ - if (!inputMasks || - !(inputMasks->inputEvents[pDev->id] & filter)) - return 0; - - other = inputMasks->inputClients; - } - - for (; other; other = other->next) - { - Mask mask; - if (IsInterferingGrab(rClient(other), pDev, pEvents)) - continue; - - mask = GetEventMask(pDev, pEvents, other); - - if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin, - pEvents, count)) - /* do nothing */; - else if ( (attempt = TryClientEvents(rClient(other), pDev, - pEvents, count, - mask, filter, grab)) ) - { - if (attempt > 0) - { - deliveries++; - client = rClient(other); - deliveryMask = mask; - } else - nondeliveries--; - } - } - } - /* - * Note that since core events are delivered first, an implicit grab may - * be activated on a core grab, stopping the XI events. - */ - if ((type == DeviceButtonPress || type == ButtonPress || - ((XI2_EVENT(pEvents) && ((xGenericEvent*)pEvents)->evtype == XI_ButtonPress))) - && deliveries - && (!grab)) - { - GrabRec tempGrab; - OtherInputMasks *inputMasks; - - memset(&tempGrab, 0, sizeof(GrabRec)); - tempGrab.next = NULL; - tempGrab.device = pDev; - tempGrab.resource = client->clientAsMask; - tempGrab.window = pWin; - tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE; - tempGrab.eventMask = deliveryMask; - tempGrab.keyboardMode = GrabModeAsync; - tempGrab.pointerMode = GrabModeAsync; - tempGrab.confineTo = NullWindow; - tempGrab.cursor = NullCursor; - tempGrab.type = type; - if (type == ButtonPress) - tempGrab.grabtype = GRABTYPE_CORE; - else if (type == DeviceButtonPress) - tempGrab.grabtype = GRABTYPE_XI; - else - { - tempGrab.type = ((xGenericEvent*)pEvents)->evtype; - tempGrab.grabtype = GRABTYPE_XI2; - } - - /* get the XI and XI2 device mask */ - inputMasks = wOtherInputMasks(pWin); - tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[pDev->id]: 0; - - if (inputMasks) - memcpy(tempGrab.xi2mask, inputMasks->xi2mask, - sizeof(tempGrab.xi2mask)); - - (*pDev->deviceGrab.ActivateGrab)(pDev, &tempGrab, - currentTime, TRUE | ImplicitGrabMask); - } - else if ((type == MotionNotify) && deliveries) - pDev->valuator->motionHintWindow = pWin; - else - { - if ((type == DeviceMotionNotify || type == DeviceButtonPress) && - deliveries) - CheckDeviceGrabAndHintWindow (pWin, type, - (deviceKeyButtonPointer*) pEvents, - grab, client, deliveryMask); - } - if (deliveries) - return deliveries; - return nondeliveries; -} - -/* If the event goes to dontClient, don't send it and return 0. if - send works, return 1 or if send didn't work, return 2. - Only works for core events. -*/ - -#ifdef PANORAMIX -static int -XineramaTryClientEventsResult( - ClientPtr client, - GrabPtr grab, - Mask mask, - Mask filter -){ - if ((client) && (client != serverClient) && (!client->clientGone) && - ((filter == CantBeFiltered) || (mask & filter))) - { - if (grab && !SameClient(grab, client)) return -1; - else return 1; - } - return 0; -} -#endif - -/** - * Try to deliver events to the interested parties. - * - * @param pWin The window that would get the event. - * @param pEvents The events to be delivered. - * @param count Number of elements in pEvents. - * @param filter Mask based on event type. - * @param dontClient Don't deliver to the dontClient. - */ -int -MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents, - int count, Mask filter, ClientPtr dontClient) -{ - OtherClients *other; - - - if (pWin->eventMask & filter) - { - if (wClient(pWin) == dontClient) - return 0; -#ifdef PANORAMIX - if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) - return XineramaTryClientEventsResult( - wClient(pWin), NullGrab, pWin->eventMask, filter); -#endif - if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count)) - return 1; /* don't send, but pretend we did */ - return TryClientEvents(wClient(pWin), NULL, pEvents, count, - pWin->eventMask, filter, NullGrab); - } - for (other = wOtherClients(pWin); other; other = other->next) - { - if (other->mask & filter) - { - if (SameClient(other, dontClient)) - return 0; -#ifdef PANORAMIX - if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) - return XineramaTryClientEventsResult( - rClient(other), NullGrab, other->mask, filter); -#endif - if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin, pEvents, - count)) - return 1; /* don't send, but pretend we did */ - return TryClientEvents(rClient(other), NULL, pEvents, count, - other->mask, filter, NullGrab); - } - } - return 2; -} - -static Window FindChildForEvent(DeviceIntPtr dev, WindowPtr event) -{ - SpritePtr pSprite = dev->spriteInfo->sprite; - WindowPtr w = pSprite->spriteTrace[pSprite->spriteTraceGood-1]; - Window child = None; - - /* If the search ends up past the root should the child field be - set to none or should the value in the argument be passed - through. It probably doesn't matter since everyone calls - this function with child == None anyway. */ - while (w) - { - /* If the source window is same as event window, child should be - none. Don't bother going all all the way back to the root. */ - - if (w == event) - { - child = None; - break; - } - - if (w->parent == event) - { - child = w->drawable.id; - break; - } - w = w->parent; - } - return child; -} - -/** - * Adjust event fields to comply with the window properties. - * - * @param xE Event to be modified in place - * @param pWin The window to get the information from. - * @param child Child window setting for event (if applicable) - * @param calcChild If True, calculate the child window. - */ -void -FixUpEventFromWindow( - DeviceIntPtr pDev, - xEvent *xE, - WindowPtr pWin, - Window child, - Bool calcChild) -{ - SpritePtr pSprite = pDev->spriteInfo->sprite; - - if (calcChild) - child = FindChildForEvent(pDev, pWin); - - if (XI2_EVENT(xE)) - { - xXIDeviceEvent* event = (xXIDeviceEvent*)xE; - - if (event->evtype == XI_RawKeyPress || - event->evtype == XI_RawKeyRelease || - event->evtype == XI_RawButtonPress || - event->evtype == XI_RawButtonRelease || - event->evtype == XI_RawMotion || - event->evtype == XI_DeviceChanged || - event->evtype == XI_HierarchyChanged || - event->evtype == XI_PropertyEvent) - return; - - event->root = RootWindow(pDev)->drawable.id; - event->event = pWin->drawable.id; - if (pSprite->hot.pScreen == pWin->drawable.pScreen) - { - event->event_x = event->root_x - FP1616(pWin->drawable.x, 0); - event->event_y = event->root_y - FP1616(pWin->drawable.y, 0); - event->child = child; - } else - { - event->event_x = 0; - event->event_y = 0; - event->child = None; - } - - if (event->evtype == XI_Enter || event->evtype == XI_Leave || - event->evtype == XI_FocusIn || event->evtype == XI_FocusOut) - ((xXIEnterEvent*)event)->same_screen = - (pSprite->hot.pScreen == pWin->drawable.pScreen); - - } else - { - XE_KBPTR.root = RootWindow(pDev)->drawable.id; - XE_KBPTR.event = pWin->drawable.id; - if (pSprite->hot.pScreen == pWin->drawable.pScreen) - { - XE_KBPTR.sameScreen = xTrue; - XE_KBPTR.child = child; - XE_KBPTR.eventX = - XE_KBPTR.rootX - pWin->drawable.x; - XE_KBPTR.eventY = - XE_KBPTR.rootY - pWin->drawable.y; - } - else - { - XE_KBPTR.sameScreen = xFalse; - XE_KBPTR.child = None; - XE_KBPTR.eventX = 0; - XE_KBPTR.eventY = 0; - } - } -} - -/** - * Return masks for EventIsDeliverable. - * @defgroup EventIsDeliverable return flags - * @{ - */ -#define XI_MASK (1 << 0) /**< XI mask set on window */ -#define CORE_MASK (1 << 1) /**< Core mask set on window */ -#define DONT_PROPAGATE_MASK (1 << 2) /**< DontPropagate mask set on window */ -#define XI2_MASK (1 << 3) /**< XI2 mask set on window */ -/* @} */ - -/** - * Check if a given event is deliverable at all on a given window. - * - * This function only checks if any client wants it, not for a specific - * client. - * - * @param[in] dev The device this event is being sent for. - * @param[in] event The event that is to be sent. - * @param[in] win The current event window. - * - * @return Bitmask of ::XI2_MASK, ::XI_MASK, ::CORE_MASK, and - * ::DONT_PROPAGATE_MASK. - */ -static int -EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win) -{ - int rc = 0; - int filter = 0; - int type; - OtherInputMasks *inputMasks = wOtherInputMasks(win); - xEvent ev; - - /* XXX: this makes me gag */ - type = GetXI2Type(event); - ev.u.u.type = GenericEvent; /* GetEventFilter only cares about type and evtype*/ - ((xGenericEvent*)&ev)->extension = IReqCode; - ((xGenericEvent*)&ev)->evtype = type; - filter = GetEventFilter(dev, &ev); - if (type && inputMasks && - ((inputMasks->xi2mask[XIAllDevices][type/8] & filter) || - ((inputMasks->xi2mask[XIAllMasterDevices][type/8] & filter) && IsMaster(dev)) || - (inputMasks->xi2mask[dev->id][type/8] & filter))) - rc |= XI2_MASK; - - type = GetXIType(event); - ev.u.u.type = type; - filter = GetEventFilter(dev, &ev); - - /* Check for XI mask */ - if (type && inputMasks && - (inputMasks->deliverableEvents[dev->id] & filter) && - (inputMasks->inputEvents[dev->id] & filter)) - rc |= XI_MASK; - - /* Check for XI DontPropagate mask */ - if (type && inputMasks && - (inputMasks->dontPropagateMask[dev->id] & filter)) - rc |= DONT_PROPAGATE_MASK; - - /* Check for core mask */ - type = GetCoreType(event); - if (type && (win->deliverableEvents & filter) && - ((wOtherEventMasks(win) | win->eventMask) & filter)) - rc |= CORE_MASK; - - /* Check for core DontPropagate mask */ - if (type && (filter & wDontPropagateMask(win))) - rc |= DONT_PROPAGATE_MASK; - - return rc; -} - -/** - * Deliver events caused by input devices. - * - * For events from a non-grabbed, non-focus device, DeliverDeviceEvents is - * called directly from the processInputProc. - * For grabbed devices, DeliverGrabbedEvent is called first, and _may_ call - * DeliverDeviceEvents. - * For focused events, DeliverFocusedEvent is called first, and _may_ call - * DeliverDeviceEvents. - * - * @param pWin Window to deliver event to. - * @param event The events to deliver, not yet in wire format. - * @param grab Possible grab on a device. - * @param stopAt Don't recurse up to the root window. - * @param dev The device that is responsible for the event. - * - * @see DeliverGrabbedEvent - * @see DeliverFocusedEvent - */ -int -DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab, - WindowPtr stopAt, DeviceIntPtr dev) -{ - Window child = None; - Mask filter; - int deliveries = 0; - xEvent core; - xEvent *xE = NULL; - int rc, mask, count = 0; - - CHECKEVENT(event); - - while (pWin) - { - if ((mask = EventIsDeliverable(dev, event, pWin))) - { - /* XI2 events first */ - if (mask & XI2_MASK) - { - xEvent *xi2 = NULL; - rc = EventToXI2(event, &xi2); - if (rc == Success) - { - /* XXX: XACE */ - filter = GetEventFilter(dev, xi2); - FixUpEventFromWindow(dev, xi2, pWin, child, FALSE); - deliveries = DeliverEventsToWindow(dev, pWin, xi2, 1, - filter, grab); - xfree(xi2); - if (deliveries > 0) - goto unwind; - } else if (rc != BadMatch) - ErrorF("[dix] %s: XI2 conversion failed in DDE (%d).\n", - dev->name, rc); - } - - /* XI events */ - if (mask & XI_MASK) - { - rc = EventToXI(event, &xE, &count); - if (rc == Success && - XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count) == Success) - { - filter = GetEventFilter(dev, xE); - FixUpEventFromWindow(dev, xE, pWin, child, FALSE); - deliveries = DeliverEventsToWindow(dev, pWin, xE, count, - filter, grab); - if (deliveries > 0) - goto unwind; - } - } - - /* Core event */ - if ((mask & CORE_MASK) && IsMaster(dev) && dev->coreEvents) - { - rc = EventToCore(event, &core); - if (rc == Success && - XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, &core, 1) == Success) - { - filter = GetEventFilter(dev, &core); - FixUpEventFromWindow(dev, &core, pWin, child, FALSE); - deliveries = DeliverEventsToWindow(dev, pWin, &core, 1, - filter, grab); - if (deliveries > 0) - goto unwind; - } - } - - if ((deliveries < 0) || (pWin == stopAt) || - (mask & DONT_PROPAGATE_MASK)) - { - deliveries = 0; - goto unwind; - } - } - - child = pWin->drawable.id; - pWin = pWin->parent; - } - -unwind: - xfree(xE); - return deliveries; -} - -#undef XI_MASK -#undef CORE_MASK -#undef DONT_PROPAGATE_MASK - -/** - * Deliver event to a window and it's immediate parent. Used for most window - * events (CreateNotify, ConfigureNotify, etc.). Not useful for events that - * propagate up the tree or extension events - * - * In case of a ReparentNotify event, the event will be delivered to the - * otherParent as well. - * - * @param pWin Window to deliver events to. - * @param xE Events to deliver. - * @param count number of events in xE. - * @param otherParent Used for ReparentNotify events. - */ -int -DeliverEvents(WindowPtr pWin, xEvent *xE, int count, - WindowPtr otherParent) -{ - Mask filter; - int deliveries; - DeviceIntRec dummy; - -#ifdef PANORAMIX - if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) - return count; -#endif - - if (!count) - return 0; - - dummy.id = XIAllDevices; - filter = GetEventFilter(&dummy, xE); - if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify)) - xE->u.destroyNotify.event = pWin->drawable.id; - if (filter != StructureAndSubMask) - return DeliverEventsToWindow(&dummy, pWin, xE, count, filter, NullGrab); - deliveries = DeliverEventsToWindow(&dummy, pWin, xE, count, - StructureNotifyMask, NullGrab); - if (pWin->parent) - { - xE->u.destroyNotify.event = pWin->parent->drawable.id; - deliveries += DeliverEventsToWindow(&dummy, pWin->parent, xE, count, - SubstructureNotifyMask, NullGrab); - if (xE->u.u.type == ReparentNotify) - { - xE->u.destroyNotify.event = otherParent->drawable.id; - deliveries += DeliverEventsToWindow(&dummy, - otherParent, xE, count, SubstructureNotifyMask, - NullGrab); - } - } - return deliveries; -} - - -static Bool -PointInBorderSize(WindowPtr pWin, int x, int y) -{ - BoxRec box; - SpritePtr pSprite = inputInfo.pointer->spriteInfo->sprite; - - if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box)) - return TRUE; - -#ifdef PANORAMIX - if(!noPanoramiXExtension && - XineramaSetWindowPntrs(inputInfo.pointer, pWin)) { - int i; - - for(i = 1; i < PanoramiXNumScreens; i++) { - if(POINT_IN_REGION(pSprite->screen, - &pSprite->windows[i]->borderSize, - x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x, - y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y, - &box)) - return TRUE; - } - } -#endif - return FALSE; -} - -/** - * Traversed from the root window to the window at the position x/y. While - * traversing, it sets up the traversal history in the spriteTrace array. - * After completing, the spriteTrace history is set in the following way: - * spriteTrace[0] ... root window - * spriteTrace[1] ... top level window that encloses x/y - * ... - * spriteTrace[spriteTraceGood - 1] ... window at x/y - * - * @returns the window at the given coordinates. - */ -static WindowPtr -XYToWindow(DeviceIntPtr pDev, int x, int y) -{ - WindowPtr pWin; - BoxRec box; - SpritePtr pSprite; - - pSprite = pDev->spriteInfo->sprite; - pSprite->spriteTraceGood = 1; /* root window still there */ - pWin = RootWindow(pDev)->firstChild; - while (pWin) - { - if ((pWin->mapped) && - (x >= pWin->drawable.x - wBorderWidth (pWin)) && - (x < pWin->drawable.x + (int)pWin->drawable.width + - wBorderWidth(pWin)) && - (y >= pWin->drawable.y - wBorderWidth (pWin)) && - (y < pWin->drawable.y + (int)pWin->drawable.height + - wBorderWidth (pWin)) - /* When a window is shaped, a further check - * is made to see if the point is inside - * borderSize - */ - && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y)) - && (!wInputShape(pWin) || - POINT_IN_REGION(pWin->drawable.pScreen, - wInputShape(pWin), - x - pWin->drawable.x, - y - pWin->drawable.y, &box)) -#ifdef ROOTLESS - /* In rootless mode windows may be offscreen, even when - * they're in X's stack. (E.g. if the native window system - * implements some form of virtual desktop system). - */ - && !pWin->rootlessUnhittable -#endif - ) - { - if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize) - { - pSprite->spriteTraceSize += 10; - pSprite->spriteTrace = xrealloc(pSprite->spriteTrace, - pSprite->spriteTraceSize*sizeof(WindowPtr)); - } - pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin; - pWin = pWin->firstChild; - } - else - pWin = pWin->nextSib; - } - return pSprite->spriteTrace[pSprite->spriteTraceGood-1]; -} - -/** - * Ungrab a currently FocusIn grabbed device and grab the device on the - * given window. If the win given is the NoneWin, the device is ungrabbed if - * applicable and FALSE is returned. - * - * @returns TRUE if the device has been grabbed, or FALSE otherwise. - */ -BOOL -ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) -{ - BOOL rc = FALSE; - DeviceEvent event; - - if (dev->deviceGrab.grab && - dev->deviceGrab.fromPassiveGrab && - dev->deviceGrab.grab->type == XI_Enter) - { - if (dev->deviceGrab.grab->window == win || - IsParent(dev->deviceGrab.grab->window, win)) - return FALSE; - DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab); - (*dev->deviceGrab.DeactivateGrab)(dev); - } - - if (win == NoneWin || win == PointerRootWin) - return FALSE; - - memset(&event, 0, sizeof(DeviceEvent)); - event.header = ET_Internal; - event.type = ET_FocusIn; - event.length = sizeof(DeviceEvent); - event.time = GetTimeInMillis(); - event.deviceid = dev->id; - event.sourceid = dev->id; - event.detail.button = 0; - rc = CheckPassiveGrabsOnWindow(win, dev, &event, FALSE); - if (rc) - DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab); - return rc; -} - -/** - * Ungrab a currently Enter grabbed device and grab the device for the given - * window. - * - * @returns TRUE if the device has been grabbed, or FALSE otherwise. - */ -static BOOL -ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win) -{ - BOOL rc = FALSE; - DeviceEvent event; - - if (dev->deviceGrab.grab && - dev->deviceGrab.fromPassiveGrab && - dev->deviceGrab.grab->type == XI_Enter) - { - if (dev->deviceGrab.grab->window == win || - IsParent(dev->deviceGrab.grab->window, win)) - return FALSE; - DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab); - (*dev->deviceGrab.DeactivateGrab)(dev); - } - - memset(&event, 0, sizeof(DeviceEvent)); - event.header = ET_Internal; - event.type = ET_Enter; - event.length = sizeof(DeviceEvent); - event.time = GetTimeInMillis(); - event.deviceid = dev->id; - event.sourceid = dev->id; - event.detail.button = 0; - rc = CheckPassiveGrabsOnWindow(win, dev, &event, FALSE); - if (rc) - DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab); - - return rc; -} - -/** - * Update the sprite coordinates based on the event. Update the cursor - * position, then update the event with the new coordinates that may have been - * changed. If the window underneath the sprite has changed, change to new - * cursor and send enter/leave events. - * - * CheckMotion() will not do anything and return FALSE if the event is not a - * pointer event. - * - * @return TRUE if the sprite has moved or FALSE otherwise. - */ -Bool -CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev) -{ - WindowPtr prevSpriteWin, newSpriteWin; - SpritePtr pSprite = pDev->spriteInfo->sprite; - - CHECKEVENT(ev); - - prevSpriteWin = pSprite->win; - - if (ev && !syncEvents.playingEvents) - { - /* GetPointerEvents() guarantees that pointer events have the correct - rootX/Y set already. */ - switch (ev->type) - { - case ET_ButtonPress: - case ET_ButtonRelease: - case ET_Motion: - break; - default: - /* all other events return FALSE */ - return FALSE; - } - - -#ifdef PANORAMIX - if (!noPanoramiXExtension) - { - /* Motion events entering DIX get translated to Screen 0 - coordinates. Replayed events have already been - translated since they've entered DIX before */ - ev->root_x += panoramiXdataPtr[pSprite->screen->myNum].x - - panoramiXdataPtr[0].x; - ev->root_y += panoramiXdataPtr[pSprite->screen->myNum].y - - panoramiXdataPtr[0].y; - } else -#endif - { - if (pSprite->hot.pScreen != pSprite->hotPhys.pScreen) - { - pSprite->hot.pScreen = pSprite->hotPhys.pScreen; - RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum]; - } - } - - pSprite->hot.x = ev->root_x; - pSprite->hot.y = ev->root_y; - if (pSprite->hot.x < pSprite->physLimits.x1) - pSprite->hot.x = pSprite->physLimits.x1; - else if (pSprite->hot.x >= pSprite->physLimits.x2) - pSprite->hot.x = pSprite->physLimits.x2 - 1; - if (pSprite->hot.y < pSprite->physLimits.y1) - pSprite->hot.y = pSprite->physLimits.y1; - else if (pSprite->hot.y >= pSprite->physLimits.y2) - pSprite->hot.y = pSprite->physLimits.y2 - 1; - if (pSprite->hotShape) - ConfineToShape(pDev, pSprite->hotShape, &pSprite->hot.x, &pSprite->hot.y); - pSprite->hotPhys = pSprite->hot; - - if ((pSprite->hotPhys.x != ev->root_x) || - (pSprite->hotPhys.y != ev->root_y)) - { -#ifdef PANORAMIX - if (!noPanoramiXExtension) - { - XineramaSetCursorPosition( - pDev, pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE); - } else -#endif - { - (*pSprite->hotPhys.pScreen->SetCursorPosition)( - pDev, pSprite->hotPhys.pScreen, - pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE); - } - } - - ev->root_x = pSprite->hot.x; - ev->root_y = pSprite->hot.y; - } - - newSpriteWin = XYToWindow(pDev, pSprite->hot.x, pSprite->hot.y); - - if (newSpriteWin != prevSpriteWin) - { - int sourceid; - if (!ev) { - UpdateCurrentTimeIf(); - sourceid = pDev->id; /* when from WindowsRestructured */ - } else - sourceid = ev->sourceid; - - if (prevSpriteWin != NullWindow) { - if (!ActivateEnterGrab(pDev, prevSpriteWin, newSpriteWin)) - DoEnterLeaveEvents(pDev, sourceid, prevSpriteWin, - newSpriteWin, NotifyNormal); - } - /* set pSprite->win after ActivateEnterGrab, otherwise - sprite window == grab_window and no enter/leave events are - sent. */ - pSprite->win = newSpriteWin; - PostNewCursor(pDev); - return FALSE; - } - return TRUE; -} - -/** - * Windows have restructured, we need to update the sprite position and the - * sprite's cursor. - */ -void -WindowsRestructured(void) -{ - DeviceIntPtr pDev = inputInfo.devices; - while(pDev) - { - if (IsMaster(pDev) || !pDev->u.master) - CheckMotion(NULL, pDev); - pDev = pDev->next; - } -} - -#ifdef PANORAMIX -/* This was added to support reconfiguration under Xdmx. The problem is - * that if the 0th screen (i.e., WindowTable[0]) is moved to an origin - * other than 0,0, the information in the private sprite structure must - * be updated accordingly, or XYToWindow (and other routines) will not - * compute correctly. */ -void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff) -{ - GrabPtr grab; - DeviceIntPtr pDev; - SpritePtr pSprite; - - if (noPanoramiXExtension) return; - - pDev = inputInfo.devices; - while(pDev) - { - if (DevHasCursor(pDev)) - { - pSprite = pDev->spriteInfo->sprite; - pSprite->hot.x -= xoff; - pSprite->hot.y -= yoff; - - pSprite->hotPhys.x -= xoff; - pSprite->hotPhys.y -= yoff; - - pSprite->hotLimits.x1 -= xoff; - pSprite->hotLimits.y1 -= yoff; - pSprite->hotLimits.x2 -= xoff; - pSprite->hotLimits.y2 -= yoff; - - if (REGION_NOTEMPTY(pSprite->screen, &pSprite->Reg1)) - REGION_TRANSLATE(pSprite->screen, &pSprite->Reg1, xoff, yoff); - if (REGION_NOTEMPTY(pSprite->screen, &pSprite->Reg2)) - REGION_TRANSLATE(pSprite->screen, &pSprite->Reg2, xoff, yoff); - - /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */ - if ((grab = pDev->deviceGrab.grab) && grab->confineTo) { - if (grab->confineTo->drawable.pScreen - != pSprite->hotPhys.pScreen) - pSprite->hotPhys.x = pSprite->hotPhys.y = 0; - ConfineCursorToWindow(pDev, grab->confineTo, TRUE, TRUE); - } else - ConfineCursorToWindow( - pDev, - WindowTable[pSprite->hotPhys.pScreen->myNum], - TRUE, FALSE); - - } - pDev = pDev->next; - } -} -#endif - -/** - * Initialize a sprite for the given device and set it to some sane values. If - * the device already has a sprite alloc'd, don't realloc but just reset to - * default values. - * If a window is supplied, the sprite will be initialized with the window's - * cursor and positioned in the center of the window's screen. The root window - * is a good choice to pass in here. - * - * It's a good idea to call it only for pointer devices, unless you have a - * really talented keyboard. - * - * @param pDev The device to initialize. - * @param pWin The window where to generate the sprite in. - * - */ -void -InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin) -{ - SpritePtr pSprite; - ScreenPtr pScreen; - - if (!pDev->spriteInfo->sprite) - { - DeviceIntPtr it; - - pDev->spriteInfo->sprite = (SpritePtr)xcalloc(1, sizeof(SpriteRec)); - if (!pDev->spriteInfo->sprite) - FatalError("InitializeSprite: failed to allocate sprite struct"); - - /* We may have paired another device with this device before our - * device had a actual sprite. We need to check for this and reset the - * sprite field for all paired devices. - * - * The VCK is always paired with the VCP before the VCP has a sprite. - */ - for (it = inputInfo.devices; it; it = it->next) - { - if (it->spriteInfo->paired == pDev) - it->spriteInfo->sprite = pDev->spriteInfo->sprite; - } - if (inputInfo.keyboard->spriteInfo->paired == pDev) - inputInfo.keyboard->spriteInfo->sprite = pDev->spriteInfo->sprite; - } - - pSprite = pDev->spriteInfo->sprite; - pDev->spriteInfo->spriteOwner = TRUE; - - pScreen = (pWin) ? pWin->drawable.pScreen : (ScreenPtr)NULL; - pSprite->hot.pScreen = pScreen; - pSprite->hotPhys.pScreen = pScreen; - if (pScreen) - { - pSprite->hotPhys.x = pScreen->width / 2; - pSprite->hotPhys.y = pScreen->height / 2; - pSprite->hotLimits.x2 = pScreen->width; - pSprite->hotLimits.y2 = pScreen->height; - } - - pSprite->hot = pSprite->hotPhys; - pSprite->win = pWin; - - if (pWin) - { - pSprite->current = wCursor(pWin); - pSprite->current->refcnt++; - pSprite->spriteTrace = (WindowPtr *)xcalloc(1, 32*sizeof(WindowPtr)); - if (!pSprite->spriteTrace) - FatalError("Failed to allocate spriteTrace"); - pSprite->spriteTraceSize = 32; - - RootWindow(pDev) = pWin; - pSprite->spriteTraceGood = 1; - - pSprite->pEnqueueScreen = pScreen; - pSprite->pDequeueScreen = pSprite->pEnqueueScreen; - - } else { - pSprite->current = NullCursor; - pSprite->spriteTrace = NULL; - pSprite->spriteTraceSize = 0; - pSprite->spriteTraceGood = 0; - pSprite->pEnqueueScreen = screenInfo.screens[0]; - pSprite->pDequeueScreen = pSprite->pEnqueueScreen; - } - - if (pScreen) - { - (*pScreen->RealizeCursor) ( pDev, pScreen, pSprite->current); - (*pScreen->CursorLimits) ( pDev, pScreen, pSprite->current, - &pSprite->hotLimits, &pSprite->physLimits); - pSprite->confined = FALSE; - - (*pScreen->ConstrainCursor) (pDev, pScreen, - &pSprite->physLimits); - (*pScreen->SetCursorPosition) (pDev, pScreen, pSprite->hot.x, - pSprite->hot.y, - FALSE); - (*pScreen->DisplayCursor) (pDev, pScreen, pSprite->current); - } -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - pSprite->hotLimits.x1 = -panoramiXdataPtr[0].x; - pSprite->hotLimits.y1 = -panoramiXdataPtr[0].y; - pSprite->hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x; - pSprite->hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y; - pSprite->physLimits = pSprite->hotLimits; - pSprite->confineWin = NullWindow; - pSprite->hotShape = NullRegion; - pSprite->screen = pScreen; - /* gotta UNINIT these someplace */ - REGION_NULL(pScreen, &pSprite->Reg1); - REGION_NULL(pScreen, &pSprite->Reg2); - } -#endif -} - -/** - * Update the mouse sprite info when the server switches from a pScreen to another. - * Otherwise, the pScreen of the mouse sprite is never updated when we switch - * from a pScreen to another. Never updating the pScreen of the mouse sprite - * implies that windows that are in pScreen whose pScreen->myNum >0 will never - * get pointer events. This is because in CheckMotion(), sprite.hotPhys.pScreen - * always points to the first pScreen it has been set by - * DefineInitialRootWindow(). - * - * Calling this function is useful for use cases where the server - * has more than one pScreen. - * This function is similar to DefineInitialRootWindow() but it does not - * reset the mouse pointer position. - * @param win must be the new pScreen we are switching to. - */ -void -UpdateSpriteForScreen(DeviceIntPtr pDev, ScreenPtr pScreen) -{ - SpritePtr pSprite = NULL; - WindowPtr win = NULL; - if (!pScreen) - return ; - - if (!pDev->spriteInfo->sprite) - return; - - pSprite = pDev->spriteInfo->sprite; - - win = WindowTable[pScreen->myNum]; - - pSprite->hotPhys.pScreen = pScreen; - pSprite->hot = pSprite->hotPhys; - pSprite->hotLimits.x2 = pScreen->width; - pSprite->hotLimits.y2 = pScreen->height; - pSprite->win = win; - pSprite->current = wCursor (win); - pSprite->current->refcnt++; - pSprite->spriteTraceGood = 1; - pSprite->spriteTrace[0] = win; - (*pScreen->CursorLimits) (pDev, - pScreen, - pSprite->current, - &pSprite->hotLimits, - &pSprite->physLimits); - pSprite->confined = FALSE; - (*pScreen->ConstrainCursor) (pDev, pScreen, &pSprite->physLimits); - (*pScreen->DisplayCursor) (pDev, pScreen, pSprite->current); - -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - pSprite->hotLimits.x1 = -panoramiXdataPtr[0].x; - pSprite->hotLimits.y1 = -panoramiXdataPtr[0].y; - pSprite->hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x; - pSprite->hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y; - pSprite->physLimits = pSprite->hotLimits; - pSprite->screen = pScreen; - } -#endif -} - -/* - * This does not take any shortcuts, and even ignores its argument, since - * it does not happen very often, and one has to walk up the tree since - * this might be a newly instantiated cursor for an intermediate window - * between the one the pointer is in and the one that the last cursor was - * instantiated from. - */ -void -WindowHasNewCursor(WindowPtr pWin) -{ - DeviceIntPtr pDev; - - for(pDev = inputInfo.devices; pDev; pDev = pDev->next) - if (DevHasCursor(pDev)) - PostNewCursor(pDev); -} - -void -NewCurrentScreen(DeviceIntPtr pDev, ScreenPtr newScreen, int x, int y) -{ - SpritePtr pSprite = pDev->spriteInfo->sprite; - - pSprite->hotPhys.x = x; - pSprite->hotPhys.y = y; -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - pSprite->hotPhys.x += panoramiXdataPtr[newScreen->myNum].x - - panoramiXdataPtr[0].x; - pSprite->hotPhys.y += panoramiXdataPtr[newScreen->myNum].y - - panoramiXdataPtr[0].y; - if (newScreen != pSprite->screen) { - pSprite->screen = newScreen; - /* Make sure we tell the DDX to update its copy of the screen */ - if(pSprite->confineWin) - XineramaConfineCursorToWindow(pDev, - pSprite->confineWin, TRUE); - else - XineramaConfineCursorToWindow(pDev, WindowTable[0], TRUE); - /* if the pointer wasn't confined, the DDX won't get - told of the pointer warp so we reposition it here */ - if(!syncEvents.playingEvents) - (*pSprite->screen->SetCursorPosition)( - pDev, - pSprite->screen, - pSprite->hotPhys.x + panoramiXdataPtr[0].x - - panoramiXdataPtr[pSprite->screen->myNum].x, - pSprite->hotPhys.y + panoramiXdataPtr[0].y - - panoramiXdataPtr[pSprite->screen->myNum].y, FALSE); - } - } else -#endif - if (newScreen != pSprite->hotPhys.pScreen) - ConfineCursorToWindow(pDev, WindowTable[newScreen->myNum], - TRUE, FALSE); -} - -#ifdef PANORAMIX - -static Bool -XineramaPointInWindowIsVisible( - WindowPtr pWin, - int x, - int y -) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - BoxRec box; - int i, xoff, yoff; - - if (!pWin->realized) return FALSE; - - if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box)) - return TRUE; - - if(!XineramaSetWindowPntrs(inputInfo.pointer, pWin)) return FALSE; - - xoff = x + panoramiXdataPtr[0].x; - yoff = y + panoramiXdataPtr[0].y; - - for(i = 1; i < PanoramiXNumScreens; i++) { - pWin = inputInfo.pointer->spriteInfo->sprite->windows[i]; - pScreen = pWin->drawable.pScreen; - x = xoff - panoramiXdataPtr[i].x; - y = yoff - panoramiXdataPtr[i].y; - - if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box) - && (!wInputShape(pWin) || - POINT_IN_REGION(pWin->drawable.pScreen, - wInputShape(pWin), - x - pWin->drawable.x, - y - pWin->drawable.y, &box))) - return TRUE; - - } - - return FALSE; -} - -static int -XineramaWarpPointer(ClientPtr client) -{ - WindowPtr dest = NULL; - int x, y, rc; - SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite; - - REQUEST(xWarpPointerReq); - - - if (stuff->dstWid != None) { - rc = dixLookupWindow(&dest, stuff->dstWid, client, DixReadAccess); - if (rc != Success) - return rc; - } - x = pSprite->hotPhys.x; - y = pSprite->hotPhys.y; - - if (stuff->srcWid != None) - { - int winX, winY; - XID winID = stuff->srcWid; - WindowPtr source; - - rc = dixLookupWindow(&source, winID, client, DixReadAccess); - if (rc != Success) - return rc; - - winX = source->drawable.x; - winY = source->drawable.y; - if(source == WindowTable[0]) { - winX -= panoramiXdataPtr[0].x; - winY -= panoramiXdataPtr[0].y; - } - if (x < winX + stuff->srcX || - y < winY + stuff->srcY || - (stuff->srcWidth != 0 && - winX + stuff->srcX + (int)stuff->srcWidth < x) || - (stuff->srcHeight != 0 && - winY + stuff->srcY + (int)stuff->srcHeight < y) || - !XineramaPointInWindowIsVisible(source, x, y)) - return Success; - } - if (dest) { - x = dest->drawable.x; - y = dest->drawable.y; - if(dest == WindowTable[0]) { - x -= panoramiXdataPtr[0].x; - y -= panoramiXdataPtr[0].y; - } - } - - x += stuff->dstX; - y += stuff->dstY; - - if (x < pSprite->physLimits.x1) - x = pSprite->physLimits.x1; - else if (x >= pSprite->physLimits.x2) - x = pSprite->physLimits.x2 - 1; - if (y < pSprite->physLimits.y1) - y = pSprite->physLimits.y1; - else if (y >= pSprite->physLimits.y2) - y = pSprite->physLimits.y2 - 1; - if (pSprite->hotShape) - ConfineToShape(PickPointer(client), pSprite->hotShape, &x, &y); - - XineramaSetCursorPosition(PickPointer(client), x, y, TRUE); - - return Success; -} - -#endif - - -/** - * Server-side protocol handling for WarpPointer request. - * Warps the cursor position to the coordinates given in the request. - */ -int -ProcWarpPointer(ClientPtr client) -{ - WindowPtr dest = NULL; - int x, y, rc; - ScreenPtr newScreen; - DeviceIntPtr dev, tmp; - SpritePtr pSprite; - - REQUEST(xWarpPointerReq); - REQUEST_SIZE_MATCH(xWarpPointerReq); - - dev = PickPointer(client); - - for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { - if ((tmp == dev) || (!IsMaster(tmp) && tmp->u.master == dev)) { - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixWriteAccess); - if (rc != Success) - return rc; - } - } - - if (dev->u.lastSlave) - dev = dev->u.lastSlave; - pSprite = dev->spriteInfo->sprite; - -#ifdef PANORAMIX - if(!noPanoramiXExtension) - return XineramaWarpPointer(client); -#endif - - if (stuff->dstWid != None) { - rc = dixLookupWindow(&dest, stuff->dstWid, client, DixGetAttrAccess); - if (rc != Success) - return rc; - } - x = pSprite->hotPhys.x; - y = pSprite->hotPhys.y; - - if (stuff->srcWid != None) - { - int winX, winY; - XID winID = stuff->srcWid; - WindowPtr source; - - rc = dixLookupWindow(&source, winID, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - winX = source->drawable.x; - winY = source->drawable.y; - if (source->drawable.pScreen != pSprite->hotPhys.pScreen || - x < winX + stuff->srcX || - y < winY + stuff->srcY || - (stuff->srcWidth != 0 && - winX + stuff->srcX + (int)stuff->srcWidth < x) || - (stuff->srcHeight != 0 && - winY + stuff->srcY + (int)stuff->srcHeight < y) || - !PointInWindowIsVisible(source, x, y)) - return Success; - } - if (dest) - { - x = dest->drawable.x; - y = dest->drawable.y; - newScreen = dest->drawable.pScreen; - } else - newScreen = pSprite->hotPhys.pScreen; - - x += stuff->dstX; - y += stuff->dstY; - - if (x < 0) - x = 0; - else if (x >= newScreen->width) - x = newScreen->width - 1; - if (y < 0) - y = 0; - else if (y >= newScreen->height) - y = newScreen->height - 1; - - if (newScreen == pSprite->hotPhys.pScreen) - { - if (x < pSprite->physLimits.x1) - x = pSprite->physLimits.x1; - else if (x >= pSprite->physLimits.x2) - x = pSprite->physLimits.x2 - 1; - if (y < pSprite->physLimits.y1) - y = pSprite->physLimits.y1; - else if (y >= pSprite->physLimits.y2) - y = pSprite->physLimits.y2 - 1; - if (pSprite->hotShape) - ConfineToShape(dev, pSprite->hotShape, &x, &y); - (*newScreen->SetCursorPosition)(dev, newScreen, x, y, TRUE); - } - else if (!PointerConfinedToScreen(dev)) - { - NewCurrentScreen(dev, newScreen, x, y); - } - return Success; -} - -static Bool -BorderSizeNotEmpty(DeviceIntPtr pDev, WindowPtr pWin) -{ - if(REGION_NOTEMPTY(pDev->spriteInfo->sprite->hotPhys.pScreen, &pWin->borderSize)) - return TRUE; - -#ifdef PANORAMIX - if(!noPanoramiXExtension && XineramaSetWindowPntrs(pDev, pWin)) { - int i; - - for(i = 1; i < PanoramiXNumScreens; i++) { - if(REGION_NOTEMPTY(pDev->spriteInfo->sprite->screen, - &pDev->spriteInfo->sprite->windows[i]->borderSize)) - return TRUE; - } - } -#endif - return FALSE; -} - -/** - * "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a - * passive grab set on the window to be activated. - * If a passive grab is activated, the event will be delivered to the client. - * - * @param pWin The window that may be subject to a passive grab. - * @param device Device that caused the event. - * @param event The current device event. - * @param checkCore Check for core grabs too. - */ - -static Bool -CheckPassiveGrabsOnWindow( - WindowPtr pWin, - DeviceIntPtr device, - DeviceEvent *event, - BOOL checkCore) -{ - GrabPtr grab = wPassiveGrabs(pWin); - GrabRec tempGrab; - GrabInfoPtr grabinfo; -#define CORE_MATCH 0x1 -#define XI_MATCH 0x2 -#define XI2_MATCH 0x4 - int match = 0; - - if (device->deviceGrab.grab) - return FALSE; - - if (!grab) - return FALSE; - /* Fill out the grab details, but leave the type for later before - * comparing */ - tempGrab.window = pWin; - tempGrab.device = device; - tempGrab.detail.exact = event->detail.key; - tempGrab.detail.pMask = NULL; - tempGrab.modifiersDetail.pMask = NULL; - tempGrab.next = NULL; - for (; grab; grab = grab->next) - { - DeviceIntPtr gdev; - XkbSrvInfoPtr xkbi = NULL; - Mask mask = 0; - - gdev= grab->modifierDevice; - if (grab->grabtype == GRABTYPE_CORE) - { - if (IsPointerDevice(device)) - gdev = GetPairedDevice(device); - else - gdev = device; - } else if (grab->grabtype == GRABTYPE_XI2) - { - /* if the device is an attached slave device, gdev must be the - * attached master keyboard. Since the slave may have been - * reattached after the grab, the modifier device may not be the - * same. */ - if (!IsMaster(grab->device) && device->u.master) - gdev = GetMaster(device, MASTER_KEYBOARD); - } - - - if (gdev && gdev->key) - xkbi= gdev->key->xkbInfo; - tempGrab.modifierDevice = grab->modifierDevice; - tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0; - - /* Check for XI2 and XI grabs first */ - tempGrab.type = GetXI2Type((InternalEvent*)event); - tempGrab.grabtype = GRABTYPE_XI2; - if (GrabMatchesSecond(&tempGrab, grab, FALSE)) - match = XI2_MATCH; - - tempGrab.detail.exact = event->detail.key; - if (!match) - { - tempGrab.type = GetXIType((InternalEvent*)event); - tempGrab.grabtype = GRABTYPE_XI; - if (GrabMatchesSecond(&tempGrab, grab, FALSE)) - match = XI_MATCH; - } - - /* Check for a core grab (ignore the device when comparing) */ - if (!match && checkCore) - { - tempGrab.grabtype = GRABTYPE_CORE; - if ((tempGrab.type = GetCoreType((InternalEvent*)event)) && - (GrabMatchesSecond(&tempGrab, grab, TRUE))) - match = CORE_MATCH; - } - - if (match && (!grab->confineTo || - (grab->confineTo->realized && - BorderSizeNotEmpty(device, grab->confineTo)))) - { - int rc, count = 0; - xEvent *xE = NULL; - xEvent core; - - event->corestate &= 0x1f00; - event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00); - grabinfo = &device->deviceGrab; - /* In some cases a passive core grab may exist, but the client - * already has a core grab on some other device. In this case we - * must not get the grab, otherwise we may never ungrab the - * device. - */ - - if (grab->grabtype == GRABTYPE_CORE) - { - DeviceIntPtr other; - BOOL interfering = FALSE; - - /* A passive grab may have been created for a different device - than it is assigned to at this point in time. - Update the grab's device and modifier device to reflect the - current state. - Since XGrabDeviceButton requires to specify the - modifierDevice explicitly, we don't override this choice. - */ - if (tempGrab.type < GenericEvent) - { - grab->device = device; - grab->modifierDevice = GetPairedDevice(device); - } - - for (other = inputInfo.devices; other; other = other->next) - { - GrabPtr othergrab = other->deviceGrab.grab; - if (othergrab && othergrab->grabtype == GRABTYPE_CORE && - SameClient(grab, rClient(othergrab)) && - ((IsPointerDevice(grab->device) && - IsPointerDevice(othergrab->device)) || - (IsKeyboardDevice(grab->device) && - IsKeyboardDevice(othergrab->device)))) - { - interfering = TRUE; - break; - } - } - if (interfering) - continue; - } - - - if (match & CORE_MATCH) - { - rc = EventToCore((InternalEvent*)event, &core); - if (rc != Success) - { - if (rc != BadMatch) - ErrorF("[dix] %s: core conversion failed in CPGFW " - "(%d, %d).\n", device->name, event->type, rc); - continue; - } - xE = &core; - count = 1; - mask = grab->eventMask; - } else if (match & XI2_MATCH) - { - rc = EventToXI2((InternalEvent*)event, &xE); - if (rc != Success) - { - if (rc != BadMatch) - ErrorF("[dix] %s: XI2 conversion failed in CPGFW " - "(%d, %d).\n", device->name, event->type, rc); - continue; - } - count = 1; - - /* FIXME: EventToXI2 returns NULL for enter events, so - * dereferencing the event is bad. Internal event types are - * aligned with core events, so the else clause is valid. - * long-term we should use internal events for enter/focus - * as well */ - if (xE) - mask = grab->xi2mask[device->id][((xGenericEvent*)xE)->evtype/8]; - else if (event->type == XI_Enter || event->type == XI_FocusIn) - mask = grab->xi2mask[device->id][event->type/8]; - } else - { - rc = EventToXI((InternalEvent*)event, &xE, &count); - if (rc != Success) - { - if (rc != BadMatch) - ErrorF("[dix] %s: XI conversion failed in CPGFW " - "(%d, %d).\n", device->name, event->type, rc); - continue; - } - mask = grab->eventMask; - } - - (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE); - - if (xE) - { - FixUpEventFromWindow(device, xE, grab->window, None, TRUE); - - TryClientEvents(rClient(grab), device, xE, count, mask, - GetEventFilter(device, xE), grab); - } - - if (grabinfo->sync.state == FROZEN_NO_EVENT) - { - if (!grabinfo->sync.event) - grabinfo->sync.event = xcalloc(1, sizeof(InternalEvent)); - *grabinfo->sync.event = *event; - grabinfo->sync.state = FROZEN_WITH_EVENT; - } - - if (match & (XI_MATCH | XI2_MATCH)) - xfree(xE); /* on core match xE == &core */ - return TRUE; - } - } - return FALSE; -#undef CORE_MATCH -#undef XI_MATCH -#undef XI2_MATCH -} - -/** - * CheckDeviceGrabs handles both keyboard and pointer events that may cause - * a passive grab to be activated. - * - * If the event is a keyboard event, the ancestors of the focus window are - * traced down and tried to see if they have any passive grabs to be - * activated. If the focus window itself is reached and it's descendants - * contain the pointer, the ancestors of the window that the pointer is in - * are then traced down starting at the focus window, otherwise no grabs are - * activated. - * If the event is a pointer event, the ancestors of the window that the - * pointer is in are traced down starting at the root until CheckPassiveGrabs - * causes a passive grab to activate or all the windows are - * tried. PRH - * - * If a grab is activated, the event has been sent to the client already! - * - * The event we pass in must always be an XI event. From this, we then emulate - * the core event and then check for grabs. - * - * @param device The device that caused the event. - * @param xE The event to handle (Device{Button|Key}Press). - * @param count Number of events in list. - * @return TRUE if a grab has been activated or false otherwise. -*/ - -Bool -CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, int checkFirst) -{ - int i; - WindowPtr pWin = NULL; - FocusClassPtr focus = IsPointerEvent((InternalEvent*)event) ? NULL : device->focus; - BOOL sendCore = (IsMaster(device) && device->coreEvents); - - if (event->type != ET_ButtonPress && - event->type != ET_KeyPress) - return FALSE; - - if (event->type == ET_ButtonPress - && (device->button->buttonsDown != 1)) - return FALSE; - - i = checkFirst; - - if (focus) - { - for (; i < focus->traceGood; i++) - { - pWin = focus->trace[i]; - if (pWin->optional && - CheckPassiveGrabsOnWindow(pWin, device, event, sendCore)) - return TRUE; - } - - if ((focus->win == NoneWin) || - (i >= device->spriteInfo->sprite->spriteTraceGood) || - ((i > checkFirst) && - (pWin != device->spriteInfo->sprite->spriteTrace[i-1]))) - return FALSE; - } - - for (; i < device->spriteInfo->sprite->spriteTraceGood; i++) - { - pWin = device->spriteInfo->sprite->spriteTrace[i]; - if (pWin->optional && - CheckPassiveGrabsOnWindow(pWin, device, event, sendCore)) - return TRUE; - } - - return FALSE; -} - -/** - * Called for keyboard events to deliver event to whatever client owns the - * focus. - * - * The event is delivered to the keyboard's focus window, the root window or - * to the window owning the input focus. - * - * @param keybd The keyboard originating the event. - * @param event The event, not yet in wire format. - * @param window Window underneath the sprite. - */ -void -DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window) -{ - DeviceIntPtr ptr; - WindowPtr focus = keybd->focus->win; - BOOL sendCore = (IsMaster(keybd) && keybd->coreEvents); - xEvent core; - xEvent *xE = NULL, *xi2 = NULL; - int count, rc; - int deliveries = 0; - - if (focus == FollowKeyboardWin) - focus = inputInfo.keyboard->focus->win; - if (!focus) - return; - if (focus == PointerRootWin) - { - DeliverDeviceEvents(window, event, NullGrab, NullWindow, keybd); - return; - } - if ((focus == window) || IsParent(focus, window)) - { - if (DeliverDeviceEvents(window, event, NullGrab, focus, keybd)) - return; - } - - /* just deliver it to the focus window */ - ptr = GetPairedDevice(keybd); - - - rc = EventToXI2(event, &xi2); - if (rc == Success) - { - /* XXX: XACE */ - int filter = GetEventFilter(keybd, xi2); - FixUpEventFromWindow(ptr, xi2, focus, None, FALSE); - deliveries = DeliverEventsToWindow(keybd, focus, xi2, 1, - filter, NullGrab); - if (deliveries > 0) - goto unwind; - } else if (rc != BadMatch) - ErrorF("[dix] %s: XI2 conversion failed in DFE (%d, %d). Skipping delivery.\n", - keybd->name, event->any.type, rc); - - rc = EventToXI(event, &xE, &count); - if (rc == Success && - XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count) == Success) - { - FixUpEventFromWindow(ptr, xE, focus, None, FALSE); - deliveries = DeliverEventsToWindow(keybd, focus, xE, count, - GetEventFilter(keybd, xE), - NullGrab); - - if (deliveries > 0) - goto unwind; - } else if (rc != BadMatch) - ErrorF("[dix] %s: XI conversion failed in DFE (%d, %d). Skipping delivery.\n", - keybd->name, event->any.type, rc); - - if (sendCore) - { - rc = EventToCore(event, &core); - if (rc == Success && - XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, &core, 1) == Success) - { - FixUpEventFromWindow(keybd, &core, focus, None, FALSE); - deliveries = DeliverEventsToWindow(keybd, focus, &core, 1, - GetEventFilter(keybd, &core), - NullGrab); - } - } - -unwind: - if (xE) - xfree(xE); - if (xi2) - xfree(xi2); - return; -} - -/** - * Deliver an event from a device that is currently grabbed. Uses - * DeliverDeviceEvents() for further delivery if a ownerEvents is set on the - * grab. If not, TryClientEvents() is used. - * - * @param deactivateGrab True if the device's grab should be deactivated. - */ -void -DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev, - Bool deactivateGrab) -{ - GrabPtr grab; - GrabInfoPtr grabinfo; - int deliveries = 0; - DeviceIntPtr dev; - SpritePtr pSprite = thisDev->spriteInfo->sprite; - BOOL sendCore = FALSE; - int rc, count = 0; - xEvent *xi = NULL; - xEvent *xi2 = NULL; - - grabinfo = &thisDev->deviceGrab; - grab = grabinfo->grab; - - if (grab->ownerEvents) - { - WindowPtr focus; - - /* Hack: Some pointer device have a focus class. So we need to check - * for the type of event, to see if we really want to deliver it to - * the focus window. For pointer events, the answer is no. - */ - if (IsPointerEvent(event)) - focus = PointerRootWin; - else if (thisDev->focus) - { - focus = thisDev->focus->win; - if (focus == FollowKeyboardWin) - focus = inputInfo.keyboard->focus->win; - } - else - focus = PointerRootWin; - if (focus == PointerRootWin) - deliveries = DeliverDeviceEvents(pSprite->win, event, grab, - NullWindow, thisDev); - else if (focus && (focus == pSprite->win || - IsParent(focus, pSprite->win))) - deliveries = DeliverDeviceEvents(pSprite->win, event, grab, focus, - thisDev); - else if (focus) - deliveries = DeliverDeviceEvents(focus, event, grab, focus, - thisDev); - } - if (!deliveries) - { - Mask mask; - - /* XXX: In theory, we could pass the internal events through to - * everything and only convert just before hitting the wire. We can't - * do that yet, so DGE is the last stop for internal events. From here - * onwards, we deal with core/XI events. - */ - - mask = grab->eventMask; - - sendCore = (IsMaster(thisDev) && thisDev->coreEvents); - /* try core event */ - if (sendCore && grab->grabtype == GRABTYPE_CORE) - { - xEvent core; - - rc = EventToCore(event, &core); - if (rc == Success) - { - FixUpEventFromWindow(thisDev, &core, grab->window, - None, TRUE); - if (XaceHook(XACE_SEND_ACCESS, 0, thisDev, - grab->window, &core, 1) || - XaceHook(XACE_RECEIVE_ACCESS, rClient(grab), - grab->window, &core, 1)) - deliveries = 1; /* don't send, but pretend we did */ - else if (!IsInterferingGrab(rClient(grab), thisDev, &core)) - { - deliveries = TryClientEvents(rClient(grab), thisDev, - &core, 1, mask, - GetEventFilter(thisDev, &core), - grab); - } - } else if (rc != BadMatch) - ErrorF("[dix] DeliverGrabbedEvent. Core conversion failed.\n"); - } - - if (!deliveries) - { - rc = EventToXI2(event, &xi2); - if (rc == Success) - { - int evtype = ((xGenericEvent*)xi2)->evtype; - mask = grab->xi2mask[XIAllDevices][evtype/8] | - grab->xi2mask[XIAllMasterDevices][evtype/8] | - grab->xi2mask[thisDev->id][evtype/8]; - /* try XI2 event */ - FixUpEventFromWindow(thisDev, xi2, grab->window, None, TRUE); - /* XXX: XACE */ - deliveries = TryClientEvents(rClient(grab), thisDev, xi2, 1, mask, - GetEventFilter(thisDev, xi2), grab); - } else if (rc != BadMatch) - ErrorF("[dix] %s: XI2 conversion failed in DGE (%d, %d). Skipping delivery.\n", - thisDev->name, event->any.type, rc); - } - - if (!deliveries) - { - rc = EventToXI(event, &xi, &count); - if (rc == Success) - { - /* try XI event */ - if (grabinfo->fromPassiveGrab && - grabinfo->implicitGrab) - mask = grab->deviceMask; - else - mask = grab->eventMask; - - FixUpEventFromWindow(thisDev, xi, grab->window, - None, TRUE); - - if (XaceHook(XACE_SEND_ACCESS, 0, thisDev, - grab->window, xi, count) || - XaceHook(XACE_RECEIVE_ACCESS, rClient(grab), - grab->window, xi, count)) - deliveries = 1; /* don't send, but pretend we did */ - else - { - deliveries = - TryClientEvents(rClient(grab), thisDev, - xi, count, - mask, - GetEventFilter(thisDev, xi), - grab); - } - } else if (rc != BadMatch) - ErrorF("[dix] %s: XI conversion failed in DGE (%d, %d). Skipping delivery.\n", - thisDev->name, event->any.type, rc); - } - - if (deliveries && (event->any.type == ET_Motion)) - thisDev->valuator->motionHintWindow = grab->window; - } - if (deliveries && !deactivateGrab && event->any.type != ET_Motion) - { - switch (grabinfo->sync.state) - { - case FREEZE_BOTH_NEXT_EVENT: - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (dev == thisDev) - continue; - FreezeThaw(dev, TRUE); - if ((dev->deviceGrab.sync.state == FREEZE_BOTH_NEXT_EVENT) && - (CLIENT_BITS(grab->resource) == - CLIENT_BITS(dev->deviceGrab.sync.other->resource))) - dev->deviceGrab.sync.state = FROZEN_NO_EVENT; - else - dev->deviceGrab.sync.other = grab; - } - /* fall through */ - case FREEZE_NEXT_EVENT: - grabinfo->sync.state = FROZEN_WITH_EVENT; - FreezeThaw(thisDev, TRUE); - if (!grabinfo->sync.event) - grabinfo->sync.event = xcalloc(1, sizeof(InternalEvent)); - *grabinfo->sync.event = event->device_event; - break; - } - } - - if (xi) - xfree(xi); - if (xi2) - xfree(xi2); -} - -/* This function is used to set the key pressed or key released state - - this is only used when the pressing of keys does not cause - the device's processInputProc to be called, as in for example Mouse Keys. -*/ -void -FixKeyState (DeviceEvent *event, DeviceIntPtr keybd) -{ - int key, bit; - BYTE *kptr; - KeyClassPtr keyc = keybd->key; - - key = event->detail.key; - kptr = &keyc->down[key >> 3]; - bit = 1 << (key & 7); - - if (event->type == ET_KeyPress) { - DebugF("FixKeyState: Key %d %s\n",key, - ((event->type == ET_KeyPress) ? "down" : "up")); - } - - if (event->type == ET_KeyPress) - *kptr |= bit; - else if (event->type == ET_KeyRelease) - *kptr &= ~bit; - else - FatalError("Impossible keyboard event"); -} - -#define AtMostOneClient \ - (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask) -#define ManagerMask \ - (SubstructureRedirectMask | ResizeRedirectMask) - -/** - * Recalculate which events may be deliverable for the given window. - * Recalculated mask is used for quicker determination which events may be - * delivered to a window. - * - * The otherEventMasks on a WindowOptional is the combination of all event - * masks set by all clients on the window. - * deliverableEventMask is the combination of the eventMask and the - * otherEventMask plus the events that may be propagated to the parent. - * - * Traverses to siblings and parents of the window. - */ -void -RecalculateDeliverableEvents(WindowPtr pWin) -{ - OtherClients *others; - WindowPtr pChild; - - pChild = pWin; - while (1) - { - if (pChild->optional) - { - pChild->optional->otherEventMasks = 0; - for (others = wOtherClients(pChild); others; others = others->next) - { - pChild->optional->otherEventMasks |= others->mask; - } - } - pChild->deliverableEvents = pChild->eventMask| - wOtherEventMasks(pChild); - if (pChild->parent) - pChild->deliverableEvents |= - (pChild->parent->deliverableEvents & - ~wDontPropagateMask(pChild) & PropagateMask); - if (pChild->firstChild) - { - pChild = pChild->firstChild; - continue; - } - while (!pChild->nextSib && (pChild != pWin)) - pChild = pChild->parent; - if (pChild == pWin) - break; - pChild = pChild->nextSib; - } -} - -/** - * - * \param value must conform to DeleteType - */ -int -OtherClientGone(pointer value, XID id) -{ - OtherClientsPtr other, prev; - WindowPtr pWin = (WindowPtr)value; - - prev = 0; - for (other = wOtherClients(pWin); other; other = other->next) - { - if (other->resource == id) - { - if (prev) - prev->next = other->next; - else - { - if (!(pWin->optional->otherClients = other->next)) - CheckWindowOptionalNeed (pWin); - } - xfree(other); - RecalculateDeliverableEvents(pWin); - return(Success); - } - prev = other; - } - FatalError("client not on event list"); - /*NOTREACHED*/ - return -1; /* make compiler happy */ -} - -int -EventSelectForWindow(WindowPtr pWin, ClientPtr client, Mask mask) -{ - Mask check; - OtherClients * others; - DeviceIntPtr dev; - int rc; - - if (mask & ~AllEventMasks) - { - client->errorValue = mask; - return BadValue; - } - check = (mask & ManagerMask); - if (check) { - rc = XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id, - RT_WINDOW, pWin, RT_NONE, NULL, DixManageAccess); - if (rc != Success) - return rc; - } - check = (mask & AtMostOneClient); - if (check & (pWin->eventMask|wOtherEventMasks(pWin))) - { /* It is illegal for two different - clients to select on any of the - events for AtMostOneClient. However, - it is OK, for some client to - continue selecting on one of those - events. */ - if ((wClient(pWin) != client) && (check & pWin->eventMask)) - return BadAccess; - for (others = wOtherClients (pWin); others; others = others->next) - { - if (!SameClient(others, client) && (check & others->mask)) - return BadAccess; - } - } - if (wClient (pWin) == client) - { - check = pWin->eventMask; - pWin->eventMask = mask; - } - else - { - for (others = wOtherClients (pWin); others; others = others->next) - { - if (SameClient(others, client)) - { - check = others->mask; - if (mask == 0) - { - FreeResource(others->resource, RT_NONE); - return Success; - } - else - others->mask = mask; - goto maskSet; - } - } - check = 0; - if (!pWin->optional && !MakeWindowOptional (pWin)) - return BadAlloc; - others = xalloc(sizeof(OtherClients)); - if (!others) - return BadAlloc; - others->mask = mask; - others->resource = FakeClientID(client->index); - others->next = pWin->optional->otherClients; - pWin->optional->otherClients = others; - if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin)) - return BadAlloc; - } -maskSet: - if ((mask & PointerMotionHintMask) && !(check & PointerMotionHintMask)) - { - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (dev->valuator && dev->valuator->motionHintWindow == pWin) - dev->valuator->motionHintWindow = NullWindow; - } - } - RecalculateDeliverableEvents(pWin); - return Success; -} - -int -EventSuppressForWindow(WindowPtr pWin, ClientPtr client, - Mask mask, Bool *checkOptional) -{ - int i, free; - - if (mask & ~PropagateMask) - { - client->errorValue = mask; - return BadValue; - } - if (pWin->dontPropagate) - DontPropagateRefCnts[pWin->dontPropagate]--; - if (!mask) - i = 0; - else - { - for (i = DNPMCOUNT, free = 0; --i > 0; ) - { - if (!DontPropagateRefCnts[i]) - free = i; - else if (mask == DontPropagateMasks[i]) - break; - } - if (!i && free) - { - i = free; - DontPropagateMasks[i] = mask; - } - } - if (i || !mask) - { - pWin->dontPropagate = i; - if (i) - DontPropagateRefCnts[i]++; - if (pWin->optional) - { - pWin->optional->dontPropagateMask = mask; - *checkOptional = TRUE; - } - } - else - { - if (!pWin->optional && !MakeWindowOptional (pWin)) - { - if (pWin->dontPropagate) - DontPropagateRefCnts[pWin->dontPropagate]++; - return BadAlloc; - } - pWin->dontPropagate = 0; - pWin->optional->dontPropagateMask = mask; - } - RecalculateDeliverableEvents(pWin); - return Success; -} - -/** - * Assembles an EnterNotify or LeaveNotify and sends it event to the client. - * Uses the paired keyboard to get some additional information. - */ -void -CoreEnterLeaveEvent( - DeviceIntPtr mouse, - int type, - int mode, - int detail, - WindowPtr pWin, - Window child) -{ - xEvent event; - WindowPtr focus; - DeviceIntPtr keybd; - GrabPtr grab = mouse->deviceGrab.grab; - Mask mask; - - keybd = GetPairedDevice(mouse); - - if ((pWin == mouse->valuator->motionHintWindow) && - (detail != NotifyInferior)) - mouse->valuator->motionHintWindow = NullWindow; - if (grab) - { - mask = (pWin == grab->window) ? grab->eventMask : 0; - if (grab->ownerEvents) - mask |= EventMaskForClient(pWin, rClient(grab)); - } - else - { - mask = pWin->eventMask | wOtherEventMasks(pWin); - } - - memset(&event, 0, sizeof(xEvent)); - event.u.u.type = type; - event.u.u.detail = detail; - event.u.enterLeave.time = currentTime.milliseconds; - event.u.enterLeave.rootX = mouse->spriteInfo->sprite->hot.x; - event.u.enterLeave.rootY = mouse->spriteInfo->sprite->hot.y; - /* Counts on the same initial structure of crossing & button events! */ - FixUpEventFromWindow(mouse, &event, pWin, None, FALSE); - /* Enter/Leave events always set child */ - event.u.enterLeave.child = child; - event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ? - ELFlagSameScreen : 0; - event.u.enterLeave.state = mouse->button ? (mouse->button->state & 0x1f00) : 0; - if (keybd) - event.u.enterLeave.state |= - XkbGrabStateFromRec(&keybd->key->xkbInfo->state); - event.u.enterLeave.mode = mode; - focus = (keybd) ? keybd->focus->win : None; - if ((focus != NoneWin) && - ((pWin == focus) || (focus == PointerRootWin) || - IsParent(focus, pWin))) - event.u.enterLeave.flags |= ELFlagFocus; - - if ((mask & GetEventFilter(mouse, &event))) - { - if (grab) - TryClientEvents(rClient(grab), mouse, &event, 1, mask, - GetEventFilter(mouse, &event), grab); - else - DeliverEventsToWindow(mouse, pWin, &event, 1, - GetEventFilter(mouse, &event), - NullGrab); - } - - if ((type == EnterNotify) && (mask & KeymapStateMask)) - { - xKeymapEvent ke; - ClientPtr client = grab ? rClient(grab) : wClient(pWin); - if (XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess)) - bzero((char *)&ke.map[0], 31); - else - memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31); - - ke.type = KeymapNotify; - if (grab) - TryClientEvents(rClient(grab), keybd, (xEvent *)&ke, 1, - mask, KeymapStateMask, grab); - else - DeliverEventsToWindow(mouse, pWin, (xEvent *)&ke, 1, - KeymapStateMask, NullGrab); - } -} - -void -DeviceEnterLeaveEvent( - DeviceIntPtr mouse, - int sourceid, - int type, - int mode, - int detail, - WindowPtr pWin, - Window child) -{ - GrabPtr grab = mouse->deviceGrab.grab; - xXIEnterEvent *event; - int filter; - int btlen, len, i; - DeviceIntPtr kbd; - - if ((mode == XINotifyPassiveGrab && type == XI_Leave) || - (mode == XINotifyPassiveUngrab && type == XI_Enter)) - return; - - btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0; - btlen = bytes_to_int32(btlen); - len = sizeof(xXIEnterEvent) + btlen * 4; - - event = xcalloc(1, len); - event->type = GenericEvent; - event->extension = IReqCode; - event->evtype = type; - event->length = (len - sizeof(xEvent))/4; - event->buttons_len = btlen; - event->detail = detail; - event->time = currentTime.milliseconds; - event->deviceid = mouse->id; - event->sourceid = sourceid; - event->mode = mode; - event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0); - event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0); - - for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) - if (BitIsOn(mouse->button->down, i)) - SetBit(&event[1], i); - - kbd = (IsMaster(mouse) || mouse->u.master) ? GetPairedDevice(mouse) : NULL; - if (kbd && kbd->key) - { - event->mods.base_mods = kbd->key->xkbInfo->state.base_mods; - event->mods.latched_mods = kbd->key->xkbInfo->state.latched_mods; - event->mods.locked_mods = kbd->key->xkbInfo->state.locked_mods; - - event->group.base_group = kbd->key->xkbInfo->state.base_group; - event->group.latched_group = kbd->key->xkbInfo->state.latched_group; - event->group.locked_group = kbd->key->xkbInfo->state.locked_group; - } - - FixUpEventFromWindow(mouse, (xEvent*)event, pWin, None, FALSE); - - filter = GetEventFilter(mouse, (xEvent*)event); - - if (grab) - { - Mask mask; - mask = grab->xi2mask[XIAllDevices][type/8] | - grab->xi2mask[XIAllMasterDevices][type/8] | - grab->xi2mask[mouse->id][type/8]; - TryClientEvents(rClient(grab), mouse, (xEvent*)event, 1, mask, - filter, grab); - } else { - if (!GetWindowXI2Mask(mouse, pWin, (xEvent*)event)) - goto out; - DeliverEventsToWindow(mouse, pWin, (xEvent*)event, 1, filter, - NullGrab); - } - -out: - xfree(event); -} - -void -CoreFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin) -{ - xEvent event; - - memset(&event, 0, sizeof(xEvent)); - event.u.focus.mode = mode; - event.u.u.type = type; - event.u.u.detail = detail; - event.u.focus.window = pWin->drawable.id; - - DeliverEventsToWindow(dev, pWin, &event, 1, - GetEventFilter(dev, &event), NullGrab); - if ((type == FocusIn) && - ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask)) - { - xKeymapEvent ke; - ClientPtr client = wClient(pWin); - if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess)) - bzero((char *)&ke.map[0], 31); - else - memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31); - - ke.type = KeymapNotify; - DeliverEventsToWindow(dev, pWin, (xEvent *)&ke, 1, - KeymapStateMask, NullGrab); - } -} - -/** - * Set the input focus to the given window. Subsequent keyboard events will be - * delivered to the given window. - * - * Usually called from ProcSetInputFocus as result of a client request. If so, - * the device is the inputInfo.keyboard. - * If called from ProcXSetInputFocus as result of a client xinput request, the - * device is set to the device specified by the client. - * - * @param client Client that requested input focus change. - * @param dev Focus device. - * @param focusID The window to obtain the focus. Can be PointerRoot or None. - * @param revertTo Specifies where the focus reverts to when window becomes - * unviewable. - * @param ctime Specifies the time. - * @param followOK True if pointer is allowed to follow the keyboard. - */ -int -SetInputFocus( - ClientPtr client, - DeviceIntPtr dev, - Window focusID, - CARD8 revertTo, - Time ctime, - Bool followOK) -{ - FocusClassPtr focus; - WindowPtr focusWin; - int mode, rc; - TimeStamp time; - DeviceIntPtr keybd; /* used for FollowKeyboard or FollowKeyboardWin */ - - - UpdateCurrentTime(); - if ((revertTo != RevertToParent) && - (revertTo != RevertToPointerRoot) && - (revertTo != RevertToNone) && - ((revertTo != RevertToFollowKeyboard) || !followOK)) - { - client->errorValue = revertTo; - return BadValue; - } - time = ClientTimeToServerTime(ctime); - - if (IsKeyboardDevice(dev)) - keybd = dev; - else - keybd = GetPairedDevice(dev); - - if ((focusID == None) || (focusID == PointerRoot)) - focusWin = (WindowPtr)(long)focusID; - else if ((focusID == FollowKeyboard) && followOK) - { - focusWin = keybd->focus->win; - } - else { - rc = dixLookupWindow(&focusWin, focusID, client, DixSetAttrAccess); - if (rc != Success) - return rc; - /* It is a match error to try to set the input focus to an - unviewable window. */ - if(!focusWin->realized) - return(BadMatch); - } - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixSetFocusAccess); - if (rc != Success) - return Success; - - focus = dev->focus; - if ((CompareTimeStamps(time, currentTime) == LATER) || - (CompareTimeStamps(time, focus->time) == EARLIER)) - return Success; - mode = (dev->deviceGrab.grab) ? NotifyWhileGrabbed : NotifyNormal; - if (focus->win == FollowKeyboardWin) - { - if (!ActivateFocusInGrab(dev, keybd->focus->win, focusWin)) - DoFocusEvents(dev, keybd->focus->win, focusWin, mode); - } else - { - if (!ActivateFocusInGrab(dev, focus->win, focusWin)) - DoFocusEvents(dev, focus->win, focusWin, mode); - } - focus->time = time; - focus->revert = revertTo; - if (focusID == FollowKeyboard) - focus->win = FollowKeyboardWin; - else - focus->win = focusWin; - if ((focusWin == NoneWin) || (focusWin == PointerRootWin)) - focus->traceGood = 0; - else - { - int depth = 0; - WindowPtr pWin; - - for (pWin = focusWin; pWin; pWin = pWin->parent) depth++; - if (depth > focus->traceSize) - { - focus->traceSize = depth+1; - focus->trace = xrealloc(focus->trace, - focus->traceSize * sizeof(WindowPtr)); - } - focus->traceGood = depth; - for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--) - focus->trace[depth] = pWin; - } - return Success; -} - -/** - * Server-side protocol handling for SetInputFocus request. - * - * Sets the input focus for the virtual core keyboard. - */ -int -ProcSetInputFocus(ClientPtr client) -{ - DeviceIntPtr kbd = PickKeyboard(client); - REQUEST(xSetInputFocusReq); - - REQUEST_SIZE_MATCH(xSetInputFocusReq); - - return SetInputFocus(client, kbd, stuff->focus, - stuff->revertTo, stuff->time, FALSE); -} - -/** - * Server-side protocol handling for GetInputFocus request. - * - * Sends the current input focus for the client's keyboard back to the - * client. - */ -int -ProcGetInputFocus(ClientPtr client) -{ - DeviceIntPtr kbd = PickKeyboard(client); - xGetInputFocusReply rep; - FocusClassPtr focus = kbd->focus; - int rc; - /* REQUEST(xReq); */ - REQUEST_SIZE_MATCH(xReq); - - rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetFocusAccess); - if (rc != Success) - return rc; - - memset(&rep, 0, sizeof(xGetInputFocusReply)); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - if (focus->win == NoneWin) - rep.focus = None; - else if (focus->win == PointerRootWin) - rep.focus = PointerRoot; - else rep.focus = focus->win->drawable.id; - rep.revertTo = focus->revert; - WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep); - return Success; -} - -/** - * Server-side protocol handling for GrabPointer request. - * - * Sets an active grab on the client's ClientPointer and returns success - * status to client. - */ -int -ProcGrabPointer(ClientPtr client) -{ - xGrabPointerReply rep; - DeviceIntPtr device = PickPointer(client); - GrabPtr grab; - GrabMask mask; - WindowPtr confineTo; - CursorPtr oldCursor; - REQUEST(xGrabPointerReq); - TimeStamp time; - int rc; - - REQUEST_SIZE_MATCH(xGrabPointerReq); - UpdateCurrentTime(); - - if (stuff->eventMask & ~PointerGrabMask) - { - client->errorValue = stuff->eventMask; - return BadValue; - } - - if (stuff->confineTo == None) - confineTo = NullWindow; - else - { - rc = dixLookupWindow(&confineTo, stuff->confineTo, client, - DixSetAttrAccess); - if (rc != Success) - return rc; - } - - memset(&rep, 0, sizeof(xGrabPointerReply)); - oldCursor = NullCursor; - grab = device->deviceGrab.grab; - - if (grab) - { - if (grab->confineTo && !confineTo) - ConfineCursorToWindow(device, RootWindow(device), FALSE, FALSE); - oldCursor = grab->cursor; - } - - mask.core = stuff->eventMask; - - rc = GrabDevice(client, device, stuff->pointerMode, stuff->keyboardMode, - stuff->grabWindow, stuff->ownerEvents, stuff->time, - &mask, GRABTYPE_CORE, stuff->cursor, - stuff->confineTo, &rep.status); - if (rc != Success) - return rc; - - if (oldCursor && rep.status == GrabSuccess) - FreeCursor (oldCursor, (Cursor)0); - - time = ClientTimeToServerTime(stuff->time); - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep); - return Success; -} - -/** - * Server-side protocol handling for ChangeActivePointerGrab request. - * - * Changes properties of the grab hold by the client. If the client does not - * hold an active grab on the device, nothing happens. - */ -int -ProcChangeActivePointerGrab(ClientPtr client) -{ - DeviceIntPtr device; - GrabPtr grab; - CursorPtr newCursor, oldCursor; - REQUEST(xChangeActivePointerGrabReq); - TimeStamp time; - - REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq); - if (stuff->eventMask & ~PointerGrabMask) - { - client->errorValue = stuff->eventMask; - return BadValue; - } - if (stuff->cursor == None) - newCursor = NullCursor; - else - { - int rc = dixLookupResourceByType((pointer *)&newCursor, stuff->cursor, - RT_CURSOR, client, DixUseAccess); - if (rc != Success) - { - client->errorValue = stuff->cursor; - return (rc == BadValue) ? BadCursor : rc; - } - } - - device = PickPointer(client); - grab = device->deviceGrab.grab; - - if (!grab) - return Success; - if (!SameClient(grab, client)) - return Success; - time = ClientTimeToServerTime(stuff->time); - if ((CompareTimeStamps(time, currentTime) == LATER) || - (CompareTimeStamps(time, device->deviceGrab.grabTime) == EARLIER)) - return Success; - oldCursor = grab->cursor; - grab->cursor = newCursor; - if (newCursor) - newCursor->refcnt++; - PostNewCursor(device); - if (oldCursor) - FreeCursor(oldCursor, (Cursor)0); - grab->eventMask = stuff->eventMask; - return Success; -} - -/** - * Server-side protocol handling for UngrabPointer request. - * - * Deletes a pointer grab on a device the client has grabbed. - */ -int -ProcUngrabPointer(ClientPtr client) -{ - DeviceIntPtr device = PickPointer(client); - GrabPtr grab; - TimeStamp time; - REQUEST(xResourceReq); - - REQUEST_SIZE_MATCH(xResourceReq); - UpdateCurrentTime(); - grab = device->deviceGrab.grab; - - time = ClientTimeToServerTime(stuff->id); - if ((CompareTimeStamps(time, currentTime) != LATER) && - (CompareTimeStamps(time, device->deviceGrab.grabTime) != EARLIER) && - (grab) && SameClient(grab, client)) - (*device->deviceGrab.DeactivateGrab)(device); - return Success; -} - -/** - * Sets a grab on the given device. - * - * Called from ProcGrabKeyboard to work on the client's keyboard. - * Called from ProcXGrabDevice to work on the device specified by the client. - * - * The parameters this_mode and other_mode represent the keyboard_mode and - * pointer_mode parameters of XGrabKeyboard(). - * See man page for details on all the parameters - * - * @param client Client that owns the grab. - * @param dev The device to grab. - * @param this_mode GrabModeSync or GrabModeAsync - * @param other_mode GrabModeSync or GrabModeAsync - * @param status Return code to be returned to the caller. - * - * @returns Success or BadValue. - */ -int -GrabDevice(ClientPtr client, DeviceIntPtr dev, - unsigned pointer_mode, unsigned keyboard_mode, Window grabWindow, - unsigned ownerEvents, Time ctime, GrabMask *mask, - int grabtype, Cursor curs, Window confineToWin, CARD8 *status) -{ - WindowPtr pWin, confineTo; - GrabPtr grab; - TimeStamp time; - Mask access_mode = DixGrabAccess; - int rc; - GrabInfoPtr grabInfo = &dev->deviceGrab; - CursorPtr cursor; - - UpdateCurrentTime(); - if ((keyboard_mode != GrabModeSync) && (keyboard_mode != GrabModeAsync)) - { - client->errorValue = keyboard_mode; - return BadValue; - } - if ((pointer_mode != GrabModeSync) && (pointer_mode != GrabModeAsync)) - { - client->errorValue = pointer_mode; - return BadValue; - } - if ((ownerEvents != xFalse) && (ownerEvents != xTrue)) - { - client->errorValue = ownerEvents; - return BadValue; - } - - rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess); - if (rc != Success) - return rc; - - if (confineToWin == None) - confineTo = NullWindow; - else - { - rc = dixLookupWindow(&confineTo, confineToWin, client, - DixSetAttrAccess); - if (rc != Success) - return rc; - } - - if (curs == None) - cursor = NullCursor; - else - { - rc = dixLookupResourceByType((pointer *)&cursor, curs, RT_CURSOR, - client, DixUseAccess); - if (rc != Success) - { - client->errorValue = curs; - return (rc == BadValue) ? BadCursor : rc; - } - access_mode |= DixForceAccess; - } - - if (keyboard_mode == GrabModeSync || pointer_mode == GrabModeSync) - access_mode |= DixFreezeAccess; - rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode); - if (rc != Success) - return rc; - - time = ClientTimeToServerTime(ctime); - grab = grabInfo->grab; - if (grab && grab->grabtype != grabtype) - *status = AlreadyGrabbed; - if (grab && !SameClient(grab, client)) - *status = AlreadyGrabbed; - else if ((!pWin->realized) || - (confineTo && - !(confineTo->realized - && BorderSizeNotEmpty(dev, confineTo)))) - *status = GrabNotViewable; - else if ((CompareTimeStamps(time, currentTime) == LATER) || - (CompareTimeStamps(time, grabInfo->grabTime) == EARLIER)) - *status = GrabInvalidTime; - else if (grabInfo->sync.frozen && - grabInfo->sync.other && !SameClient(grabInfo->sync.other, client)) - *status = GrabFrozen; - else - { - GrabRec tempGrab; - - /* Otherwise segfaults happen on grabbed MPX devices */ - memset(&tempGrab, 0, sizeof(GrabRec)); - - tempGrab.next = NULL; - tempGrab.window = pWin; - tempGrab.resource = client->clientAsMask; - tempGrab.ownerEvents = ownerEvents; - tempGrab.keyboardMode = keyboard_mode; - tempGrab.pointerMode = pointer_mode; - if (grabtype == GRABTYPE_CORE) - tempGrab.eventMask = mask->core; - else if (grabtype == GRABTYPE_XI) - tempGrab.eventMask = mask->xi; - else - memcpy(tempGrab.xi2mask, mask->xi2mask, sizeof(tempGrab.xi2mask)); - tempGrab.device = dev; - tempGrab.cursor = cursor; - tempGrab.confineTo = confineTo; - tempGrab.grabtype = grabtype; - (*grabInfo->ActivateGrab)(dev, &tempGrab, time, FALSE); - *status = GrabSuccess; - } - return Success; -} - -/** - * Server-side protocol handling for GrabKeyboard request. - * - * Grabs the client's keyboard and returns success status to client. - */ -int -ProcGrabKeyboard(ClientPtr client) -{ - xGrabKeyboardReply rep; - REQUEST(xGrabKeyboardReq); - int result; - DeviceIntPtr keyboard = PickKeyboard(client); - GrabMask mask; - - REQUEST_SIZE_MATCH(xGrabKeyboardReq); - - memset(&rep, 0, sizeof(xGrabKeyboardReply)); - mask.core = KeyPressMask | KeyReleaseMask; - - result = GrabDevice(client, keyboard, stuff->pointerMode, - stuff->keyboardMode, stuff->grabWindow, stuff->ownerEvents, - stuff->time, &mask, GRABTYPE_CORE, None, None, - &rep.status); - - if (result != Success) - return result; - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep); - return Success; -} - -/** - * Server-side protocol handling for UngrabKeyboard request. - * - * Deletes a possible grab on the client's keyboard. - */ -int -ProcUngrabKeyboard(ClientPtr client) -{ - DeviceIntPtr device = PickKeyboard(client); - GrabPtr grab; - TimeStamp time; - REQUEST(xResourceReq); - - REQUEST_SIZE_MATCH(xResourceReq); - UpdateCurrentTime(); - - grab = device->deviceGrab.grab; - - time = ClientTimeToServerTime(stuff->id); - if ((CompareTimeStamps(time, currentTime) != LATER) && - (CompareTimeStamps(time, device->deviceGrab.grabTime) != EARLIER) && - (grab) && SameClient(grab, client) && grab->grabtype == GRABTYPE_CORE) - (*device->deviceGrab.DeactivateGrab)(device); - return Success; -} - -/** - * Server-side protocol handling for QueryPointer request. - * - * Returns the current state and position of the client's ClientPointer to the - * client. - */ -int -ProcQueryPointer(ClientPtr client) -{ - xQueryPointerReply rep; - WindowPtr pWin, t; - DeviceIntPtr mouse = PickPointer(client); - DeviceIntPtr keyboard; - SpritePtr pSprite; - int rc; - REQUEST(xResourceReq); - REQUEST_SIZE_MATCH(xResourceReq); - - rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); - if (rc != Success) - return rc; - rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess); - if (rc != Success && rc != BadAccess) - return rc; - - keyboard = GetPairedDevice(mouse); - - pSprite = mouse->spriteInfo->sprite; - if (mouse->valuator->motionHintWindow) - MaybeStopHint(mouse, client); - memset(&rep, 0, sizeof(xQueryPointerReply)); - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.mask = mouse->button ? (mouse->button->state) : 0; - rep.mask |= XkbStateFieldFromRec(&keyboard->key->xkbInfo->state); - rep.length = 0; - rep.root = (RootWindow(mouse))->drawable.id; - rep.rootX = pSprite->hot.x; - rep.rootY = pSprite->hot.y; - rep.child = None; - if (pSprite->hot.pScreen == pWin->drawable.pScreen) - { - rep.sameScreen = xTrue; - rep.winX = pSprite->hot.x - pWin->drawable.x; - rep.winY = pSprite->hot.y - pWin->drawable.y; - for (t = pSprite->win; t; t = t->parent) - if (t->parent == pWin) - { - rep.child = t->drawable.id; - break; - } - } - else - { - rep.sameScreen = xFalse; - rep.winX = 0; - rep.winY = 0; - } - -#ifdef PANORAMIX - if(!noPanoramiXExtension) { - rep.rootX += panoramiXdataPtr[0].x; - rep.rootY += panoramiXdataPtr[0].y; - if(stuff->id == rep.root) { - rep.winX += panoramiXdataPtr[0].x; - rep.winY += panoramiXdataPtr[0].y; - } - } -#endif - - if (rc == BadAccess) { - rep.mask = 0; - rep.child = None; - rep.rootX = 0; - rep.rootY = 0; - rep.winX = 0; - rep.winY = 0; - } - - WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep); - - return(Success); -} - -/** - * Initializes the device list and the DIX sprite to sane values. Allocates - * trace memory used for quick window traversal. - */ -void -InitEvents(void) -{ - int i; - - inputInfo.numDevices = 0; - inputInfo.devices = (DeviceIntPtr)NULL; - inputInfo.off_devices = (DeviceIntPtr)NULL; - inputInfo.keyboard = (DeviceIntPtr)NULL; - inputInfo.pointer = (DeviceIntPtr)NULL; - /* The mask for pointer motion events may have changed in the last server - * generation. See comment above definition of filters. */ - filters[0][PointerMotionMask] = MotionNotify; - for (i = 1; i < MAXDEVICES; i++) - { - memcpy(&filters[i], filters[0], sizeof(filters[0])); - } - - syncEvents.replayDev = (DeviceIntPtr)NULL; - syncEvents.replayWin = NullWindow; - while (syncEvents.pending) - { - QdEventPtr next = syncEvents.pending->next; - xfree(syncEvents.pending); - syncEvents.pending = next; - } - syncEvents.pendtail = &syncEvents.pending; - syncEvents.playingEvents = FALSE; - syncEvents.time.months = 0; - syncEvents.time.milliseconds = 0; /* hardly matters */ - currentTime.months = 0; - currentTime.milliseconds = GetTimeInMillis(); - lastDeviceEventTime = currentTime; - for (i = 0; i < DNPMCOUNT; i++) - { - DontPropagateMasks[i] = 0; - DontPropagateRefCnts[i] = 0; - } - - InputEventListLen = GetMaximumEventsNum(); - InputEventList = InitEventList(InputEventListLen); - if (!InputEventList) - FatalError("[dix] Failed to allocate input event list.\n"); -} - -void -CloseDownEvents(void) -{ - FreeEventList(InputEventList, InputEventListLen); - InputEventListLen = 0; - InputEventList = NULL; -} - -/** - * Server-side protocol handling for SendEvent request. - * - * Locates the window to send the event to and forwards the event. - */ -int -ProcSendEvent(ClientPtr client) -{ - WindowPtr pWin; - WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ - DeviceIntPtr dev = PickPointer(client); - DeviceIntPtr keybd = GetPairedDevice(dev); - SpritePtr pSprite = dev->spriteInfo->sprite; - REQUEST(xSendEventReq); - - REQUEST_SIZE_MATCH(xSendEventReq); - - /* The client's event type must be a core event type or one defined by an - extension. */ - - if ( ! ((stuff->event.u.u.type > X_Reply && - stuff->event.u.u.type < LASTEvent) || - (stuff->event.u.u.type >= EXTENSION_EVENT_BASE && - stuff->event.u.u.type < (unsigned)lastEvent))) - { - client->errorValue = stuff->event.u.u.type; - return BadValue; - } - if (stuff->event.u.u.type == ClientMessage && - stuff->event.u.u.detail != 8 && - stuff->event.u.u.detail != 16 && - stuff->event.u.u.detail != 32) - { - client->errorValue = stuff->event.u.u.detail; - return BadValue; - } - if (stuff->eventMask & ~AllEventMasks) - { - client->errorValue = stuff->eventMask; - return BadValue; - } - - if (stuff->destination == PointerWindow) - pWin = pSprite->win; - else if (stuff->destination == InputFocus) - { - WindowPtr inputFocus = (keybd) ? keybd->focus->win : NoneWin; - - if (inputFocus == NoneWin) - return Success; - - /* If the input focus is PointerRootWin, send the event to where - the pointer is if possible, then perhaps propogate up to root. */ - if (inputFocus == PointerRootWin) - inputFocus = pSprite->spriteTrace[0]; /* Root window! */ - - if (IsParent(inputFocus, pSprite->win)) - { - effectiveFocus = inputFocus; - pWin = pSprite->win; - } - else - effectiveFocus = pWin = inputFocus; - } - else - dixLookupWindow(&pWin, stuff->destination, client, DixSendAccess); - - if (!pWin) - return BadWindow; - if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue)) - { - client->errorValue = stuff->propagate; - return BadValue; - } - stuff->event.u.u.type |= 0x80; - if (stuff->propagate) - { - for (;pWin; pWin = pWin->parent) - { - if (XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, - &stuff->event, 1)) - return Success; - if (DeliverEventsToWindow(dev, pWin, - &stuff->event, 1, stuff->eventMask, NullGrab)) - return Success; - if (pWin == effectiveFocus) - return Success; - stuff->eventMask &= ~wDontPropagateMask(pWin); - if (!stuff->eventMask) - break; - } - } - else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, &stuff->event, 1)) - DeliverEventsToWindow(dev, pWin, &stuff->event, - 1, stuff->eventMask, NullGrab); - return Success; -} - -/** - * Server-side protocol handling for UngrabKey request. - * - * Deletes a passive grab for the given key. Works on the - * client's keyboard. - */ -int -ProcUngrabKey(ClientPtr client) -{ - REQUEST(xUngrabKeyReq); - WindowPtr pWin; - GrabRec tempGrab; - DeviceIntPtr keybd = PickKeyboard(client); - int rc; - - REQUEST_SIZE_MATCH(xUngrabKeyReq); - rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixGetAttrAccess); - if (rc != Success) - return rc; - - if (((stuff->key > keybd->key->xkbInfo->desc->max_key_code) || - (stuff->key < keybd->key->xkbInfo->desc->min_key_code)) - && (stuff->key != AnyKey)) - { - client->errorValue = stuff->key; - return BadValue; - } - if ((stuff->modifiers != AnyModifier) && - (stuff->modifiers & ~AllModifiersMask)) - { - client->errorValue = stuff->modifiers; - return BadValue; - } - tempGrab.resource = client->clientAsMask; - tempGrab.device = keybd; - tempGrab.window = pWin; - tempGrab.modifiersDetail.exact = stuff->modifiers; - tempGrab.modifiersDetail.pMask = NULL; - tempGrab.modifierDevice = GetPairedDevice(keybd); - tempGrab.type = KeyPress; - tempGrab.grabtype = GRABTYPE_CORE; - tempGrab.detail.exact = stuff->key; - tempGrab.detail.pMask = NULL; - tempGrab.next = NULL; - - if (!DeletePassiveGrabFromList(&tempGrab)) - return(BadAlloc); - return(Success); -} - -/** - * Server-side protocol handling for GrabKey request. - * - * Creates a grab for the client's keyboard and adds it to the list of passive - * grabs. - */ -int -ProcGrabKey(ClientPtr client) -{ - WindowPtr pWin; - REQUEST(xGrabKeyReq); - GrabPtr grab; - DeviceIntPtr keybd = PickKeyboard(client); - int rc; - GrabParameters param; - GrabMask mask; - - REQUEST_SIZE_MATCH(xGrabKeyReq); - - memset(¶m, 0, sizeof(param)); - param.grabtype = GRABTYPE_CORE; - param.ownerEvents = stuff->ownerEvents; - param.this_device_mode = stuff->keyboardMode; - param.other_devices_mode = stuff->pointerMode; - param.modifiers = stuff->modifiers; - - rc = CheckGrabValues(client, ¶m); - if (rc != Success) - return rc; - - if (((stuff->key > keybd->key->xkbInfo->desc->max_key_code) || - (stuff->key < keybd->key->xkbInfo->desc->min_key_code)) - && (stuff->key != AnyKey)) - { - client->errorValue = stuff->key; - return BadValue; - } - rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixSetAttrAccess); - if (rc != Success) - return rc; - - - mask.core = (KeyPressMask | KeyReleaseMask); - - grab = CreateGrab(client->index, keybd, keybd, pWin, GRABTYPE_CORE, &mask, - ¶m, KeyPress, stuff->key, NullWindow, NullCursor); - if (!grab) - return BadAlloc; - return AddPassiveGrabToList(client, grab); -} - - -/** - * Server-side protocol handling for GrabButton request. - * - * Creates a grab for the client's ClientPointer and adds it as a passive grab - * to the list. - */ -int -ProcGrabButton(ClientPtr client) -{ - WindowPtr pWin, confineTo; - REQUEST(xGrabButtonReq); - CursorPtr cursor; - GrabPtr grab; - DeviceIntPtr ptr, modifierDevice; - Mask access_mode = DixGrabAccess; - GrabMask mask; - GrabParameters param; - int rc; - - REQUEST_SIZE_MATCH(xGrabButtonReq); - if ((stuff->pointerMode != GrabModeSync) && - (stuff->pointerMode != GrabModeAsync)) - { - client->errorValue = stuff->pointerMode; - return BadValue; - } - if ((stuff->keyboardMode != GrabModeSync) && - (stuff->keyboardMode != GrabModeAsync)) - { - client->errorValue = stuff->keyboardMode; - return BadValue; - } - if ((stuff->modifiers != AnyModifier) && - (stuff->modifiers & ~AllModifiersMask)) - { - client->errorValue = stuff->modifiers; - return BadValue; - } - if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue)) - { - client->errorValue = stuff->ownerEvents; - return BadValue; - } - if (stuff->eventMask & ~PointerGrabMask) - { - client->errorValue = stuff->eventMask; - return BadValue; - } - rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixSetAttrAccess); - if (rc != Success) - return rc; - if (stuff->confineTo == None) - confineTo = NullWindow; - else { - rc = dixLookupWindow(&confineTo, stuff->confineTo, client, - DixSetAttrAccess); - if (rc != Success) - return rc; - } - if (stuff->cursor == None) - cursor = NullCursor; - else - { - rc = dixLookupResourceByType((pointer *)&cursor, stuff->cursor, RT_CURSOR, - client, DixUseAccess); - if (rc != Success) - if (!cursor) - { - client->errorValue = stuff->cursor; - return (rc == BadValue) ? BadCursor : rc; - } - access_mode |= DixForceAccess; - } - - ptr = PickPointer(client); - modifierDevice = GetPairedDevice(ptr); - if (stuff->pointerMode == GrabModeSync || - stuff->keyboardMode == GrabModeSync) - access_mode |= DixFreezeAccess; - rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, access_mode); - if (rc != Success) - return rc; - - memset(¶m, 0, sizeof(param)); - param.grabtype = GRABTYPE_CORE; - param.ownerEvents = stuff->ownerEvents; - param.this_device_mode = stuff->keyboardMode; - param.other_devices_mode = stuff->pointerMode; - param.modifiers = stuff->modifiers; - - mask.core = stuff->eventMask; - - grab = CreateGrab(client->index, ptr, modifierDevice, pWin, - GRABTYPE_CORE, &mask, ¶m, ButtonPress, - stuff->button, confineTo, cursor); - if (!grab) - return BadAlloc; - return AddPassiveGrabToList(client, grab); -} - -/** - * Server-side protocol handling for UngrabButton request. - * - * Deletes a passive grab on the client's ClientPointer from the list. - */ -int -ProcUngrabButton(ClientPtr client) -{ - REQUEST(xUngrabButtonReq); - WindowPtr pWin; - GrabRec tempGrab; - int rc; - DeviceIntPtr ptr; - - REQUEST_SIZE_MATCH(xUngrabButtonReq); - if ((stuff->modifiers != AnyModifier) && - (stuff->modifiers & ~AllModifiersMask)) - { - client->errorValue = stuff->modifiers; - return BadValue; - } - rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixReadAccess); - if (rc != Success) - return rc; - - ptr = PickPointer(client); - - tempGrab.resource = client->clientAsMask; - tempGrab.device = ptr; - tempGrab.window = pWin; - tempGrab.modifiersDetail.exact = stuff->modifiers; - tempGrab.modifiersDetail.pMask = NULL; - tempGrab.modifierDevice = GetPairedDevice(ptr); - tempGrab.type = ButtonPress; - tempGrab.detail.exact = stuff->button; - tempGrab.grabtype = GRABTYPE_CORE; - tempGrab.detail.pMask = NULL; - tempGrab.next = NULL; - - if (!DeletePassiveGrabFromList(&tempGrab)) - return(BadAlloc); - return(Success); -} - -/** - * Deactivate any grab that may be on the window, remove the focus. - * Delete any XInput extension events from the window too. Does not change the - * window mask. Use just before the window is deleted. - * - * If freeResources is set, passive grabs on the window are deleted. - * - * @param pWin The window to delete events from. - * @param freeResources True if resources associated with the window should be - * deleted. - */ -void -DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources) -{ - WindowPtr parent; - DeviceIntPtr mouse = inputInfo.pointer; - DeviceIntPtr keybd = inputInfo.keyboard; - FocusClassPtr focus; - OtherClientsPtr oc; - GrabPtr passive; - GrabPtr grab; - - - /* Deactivate any grabs performed on this window, before making any - input focus changes. */ - grab = mouse->deviceGrab.grab; - if (grab && - ((grab->window == pWin) || (grab->confineTo == pWin))) - (*mouse->deviceGrab.DeactivateGrab)(mouse); - - - /* Deactivating a keyboard grab should cause focus events. */ - grab = keybd->deviceGrab.grab; - if (grab && (grab->window == pWin)) - (*keybd->deviceGrab.DeactivateGrab)(keybd); - - /* And now the real devices */ - for (mouse = inputInfo.devices; mouse; mouse = mouse->next) - { - grab = mouse->deviceGrab.grab; - if (grab && ((grab->window == pWin) || (grab->confineTo == pWin))) - (*mouse->deviceGrab.DeactivateGrab)(mouse); - } - - - for (keybd = inputInfo.devices; keybd; keybd = keybd->next) - { - if (IsKeyboardDevice(keybd)) - { - focus = keybd->focus; - - /* If the focus window is a root window (ie. has no parent) then don't - delete the focus from it. */ - - if ((pWin == focus->win) && (pWin->parent != NullWindow)) - { - int focusEventMode = NotifyNormal; - - /* If a grab is in progress, then alter the mode of focus events. */ - - if (keybd->deviceGrab.grab) - focusEventMode = NotifyWhileGrabbed; - - switch (focus->revert) - { - case RevertToNone: - DoFocusEvents(keybd, pWin, NoneWin, focusEventMode); - focus->win = NoneWin; - focus->traceGood = 0; - break; - case RevertToParent: - parent = pWin; - do - { - parent = parent->parent; - focus->traceGood--; - } while (!parent->realized - /* This would be a good protocol change -- windows being reparented - during SaveSet processing would cause the focus to revert to the - nearest enclosing window which will survive the death of the exiting - client, instead of ending up reverting to a dying window and thence - to None - */ -#ifdef NOTDEF - || wClient(parent)->clientGone -#endif - ); - if (!ActivateFocusInGrab(keybd, pWin, parent)) - DoFocusEvents(keybd, pWin, parent, focusEventMode); - focus->win = parent; - focus->revert = RevertToNone; - break; - case RevertToPointerRoot: - if (!ActivateFocusInGrab(keybd, pWin, PointerRootWin)) - DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode); - focus->win = PointerRootWin; - focus->traceGood = 0; - break; - } - } - } - - if (IsPointerDevice(keybd)) - { - if (keybd->valuator->motionHintWindow == pWin) - keybd->valuator->motionHintWindow = NullWindow; - } - } - - if (freeResources) - { - if (pWin->dontPropagate) - DontPropagateRefCnts[pWin->dontPropagate]--; - while ( (oc = wOtherClients(pWin)) ) - FreeResource(oc->resource, RT_NONE); - while ( (passive = wPassiveGrabs(pWin)) ) - FreeResource(passive->resource, RT_NONE); - } - - DeleteWindowFromAnyExtEvents(pWin, freeResources); -} - -/** - * Call this whenever some window at or below pWin has changed geometry. If - * there is a grab on the window, the cursor will be re-confined into the - * window. - */ -void -CheckCursorConfinement(WindowPtr pWin) -{ - GrabPtr grab; - WindowPtr confineTo; - DeviceIntPtr pDev; - -#ifdef PANORAMIX - if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return; -#endif - - for (pDev = inputInfo.devices; pDev; pDev = pDev->next) - { - if (DevHasCursor(pDev)) - { - grab = pDev->deviceGrab.grab; - if (grab && (confineTo = grab->confineTo)) - { - if (!BorderSizeNotEmpty(pDev, confineTo)) - (*pDev->deviceGrab.DeactivateGrab)(pDev); - else if ((pWin == confineTo) || IsParent(pWin, confineTo)) - ConfineCursorToWindow(pDev, confineTo, TRUE, TRUE); - } - } - } -} - -Mask -EventMaskForClient(WindowPtr pWin, ClientPtr client) -{ - OtherClientsPtr other; - - if (wClient (pWin) == client) - return pWin->eventMask; - for (other = wOtherClients(pWin); other; other = other->next) - { - if (SameClient(other, client)) - return other->mask; - } - return 0; -} - -/** - * Server-side protocol handling for RecolorCursor request. - */ -int -ProcRecolorCursor(ClientPtr client) -{ - CursorPtr pCursor; - int rc, nscr; - ScreenPtr pscr; - Bool displayed; - SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite; - REQUEST(xRecolorCursorReq); - - REQUEST_SIZE_MATCH(xRecolorCursorReq); - rc = dixLookupResourceByType((pointer *)&pCursor, stuff->cursor, RT_CURSOR, - client, DixWriteAccess); - if (rc != Success) - { - client->errorValue = stuff->cursor; - return (rc == BadValue) ? BadCursor : rc; - } - - pCursor->foreRed = stuff->foreRed; - pCursor->foreGreen = stuff->foreGreen; - pCursor->foreBlue = stuff->foreBlue; - - pCursor->backRed = stuff->backRed; - pCursor->backGreen = stuff->backGreen; - pCursor->backBlue = stuff->backBlue; - - for (nscr = 0; nscr < screenInfo.numScreens; nscr++) - { - pscr = screenInfo.screens[nscr]; -#ifdef PANORAMIX - if(!noPanoramiXExtension) - displayed = (pscr == pSprite->screen); - else -#endif - displayed = (pscr == pSprite->hotPhys.pScreen); - ( *pscr->RecolorCursor)(PickPointer(client), pscr, pCursor, - (pCursor == pSprite->current) && displayed); - } - return (Success); -} - -/** - * Write the given events to a client, swapping the byte order if necessary. - * To swap the byte ordering, a callback is called that has to be set up for - * the given event type. - * - * In the case of DeviceMotionNotify trailed by DeviceValuators, the events - * can be more than one. Usually it's just one event. - * - * Do not modify the event structure passed in. See comment below. - * - * @param pClient Client to send events to. - * @param count Number of events. - * @param events The event list. - */ -void -WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) -{ -#ifdef PANORAMIX - xEvent eventCopy; -#endif - xEvent *eventTo, *eventFrom; - int i, - eventlength = sizeof(xEvent); - - /* Let XKB rewrite the state, as it depends on client preferences. */ - XkbFilterEvents(pClient, count, events); - -#ifdef PANORAMIX - if(!noPanoramiXExtension && - (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y)) - { - switch(events->u.u.type) { - case MotionNotify: - case ButtonPress: - case ButtonRelease: - case KeyPress: - case KeyRelease: - case EnterNotify: - case LeaveNotify: - /* - When multiple clients want the same event DeliverEventsToWindow - passes the same event structure multiple times so we can't - modify the one passed to us - */ - count = 1; /* should always be 1 */ - memcpy(&eventCopy, events, sizeof(xEvent)); - eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x; - eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y; - if(eventCopy.u.keyButtonPointer.event == - eventCopy.u.keyButtonPointer.root) - { - eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x; - eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y; - } - events = &eventCopy; - break; - default: break; - } - } -#endif - - if (EventCallback) - { - EventInfoRec eventinfo; - eventinfo.client = pClient; - eventinfo.events = events; - eventinfo.count = count; - CallCallbacks(&EventCallback, (pointer)&eventinfo); - } -#ifdef XSERVER_DTRACE - if (XSERVER_SEND_EVENT_ENABLED()) { - for (i = 0; i < count; i++) - { - XSERVER_SEND_EVENT(pClient->index, events[i].u.u.type, &events[i]); - } - } -#endif - /* Just a safety check to make sure we only have one GenericEvent, it just - * makes things easier for me right now. (whot) */ - for (i = 1; i < count; i++) - { - if (events[i].u.u.type == GenericEvent) - { - ErrorF("[dix] TryClientEvents: Only one GenericEvent at a time.\n"); - return; - } - } - - if (events->u.u.type == GenericEvent) - { - eventlength += ((xGenericEvent*)events)->length * 4; - } - - if(pClient->swapped) - { - if (eventlength > swapEventLen) - { - swapEventLen = eventlength; - swapEvent = Xrealloc(swapEvent, swapEventLen); - if (!swapEvent) - { - FatalError("WriteEventsToClient: Out of memory.\n"); - return; - } - } - - for(i = 0; i < count; i++) - { - eventFrom = &events[i]; - eventTo = swapEvent; - - /* Remember to strip off the leading bit of type in case - this event was sent with "SendEvent." */ - (*EventSwapVector[eventFrom->u.u.type & 0177]) - (eventFrom, eventTo); - - WriteToClient(pClient, eventlength, (char *)eventTo); - } - } - else - { - /* only one GenericEvent, remember? that means either count is 1 and - * eventlength is arbitrary or eventlength is 32 and count doesn't - * matter. And we're all set. Woohoo. */ - WriteToClient(pClient, count * eventlength, (char *) events); - } -} - -/* - * Set the client pointer for the given client. - * - * A client can have exactly one ClientPointer. Each time a - * request/reply/event is processed and the choice of devices is ambiguous - * (e.g. QueryPointer request), the server will pick the ClientPointer (see - * PickPointer()). - * If a keyboard is needed, the first keyboard paired with the CP is used. - */ -int -SetClientPointer(ClientPtr client, DeviceIntPtr device) -{ - int rc = XaceHook(XACE_DEVICE_ACCESS, client, device, DixUseAccess); - if (rc != Success) - return rc; - - if (!IsMaster(device)) - { - ErrorF("[dix] Need master device for ClientPointer. This is a bug.\n"); - return BadDevice; - } else if (!device->spriteInfo->spriteOwner) - { - ErrorF("[dix] Device %d does not have a sprite. " - "Cannot be ClientPointer\n", device->id); - return BadDevice; - } - client->clientPtr = device; - return Success; -} - -/* PickPointer will pick an appropriate pointer for the given client. - * - * An "appropriate device" is (in order of priority): - * 1) A device the given client has a core grab on. - * 2) A device set as ClientPointer for the given client. - * 3) The first master device. - */ -DeviceIntPtr -PickPointer(ClientPtr client) -{ - DeviceIntPtr it = inputInfo.devices; - - /* First, check if the client currently has a grab on a device. Even - * keyboards count. */ - for(it = inputInfo.devices; it; it = it->next) - { - GrabPtr grab = it->deviceGrab.grab; - if (grab && grab->grabtype == GRABTYPE_CORE && SameClient(grab, client)) - { - it = GetMaster(it, MASTER_POINTER); - return it; /* Always return a core grabbed device */ - } - } - - if (!client->clientPtr) - { - DeviceIntPtr it = inputInfo.devices; - while (it) - { - if (IsMaster(it) && it->spriteInfo->spriteOwner) - { - client->clientPtr = it; - break; - } - it = it->next; - } - } - return client->clientPtr; -} - -/* PickKeyboard will pick an appropriate keyboard for the given client by - * searching the list of devices for the keyboard device that is paired with - * the client's pointer. - */ -DeviceIntPtr -PickKeyboard(ClientPtr client) -{ - DeviceIntPtr ptr = PickPointer(client); - DeviceIntPtr kbd = GetMaster(ptr, MASTER_KEYBOARD); - - if (!kbd) - { - ErrorF("[dix] ClientPointer not paired with a keyboard. This " - "is a bug.\n"); - } - - return kbd; -} - -/* A client that has one or more core grabs does not get core events from - * devices it does not have a grab on. Legacy applications behave bad - * otherwise because they are not used to it and the events interfere. - * Only applies for core events. - * - * Return true if a core event from the device would interfere and should not - * be delivered. - */ -Bool -IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent* event) -{ - DeviceIntPtr it = inputInfo.devices; - - switch(event->u.u.type) - { - case KeyPress: - case KeyRelease: - case ButtonPress: - case ButtonRelease: - case MotionNotify: - case EnterNotify: - case LeaveNotify: - break; - default: - return FALSE; - } - - if (dev->deviceGrab.grab && SameClient(dev->deviceGrab.grab, client)) - return FALSE; - - while(it) - { - if (it != dev) - { - if (it->deviceGrab.grab && SameClient(it->deviceGrab.grab, client) - && !it->deviceGrab.fromPassiveGrab) - { - if ((IsPointerDevice(it) && IsPointerDevice(dev)) || - (IsKeyboardDevice(it) && IsKeyboardDevice(dev))) - return TRUE; - } - } - it = it->next; - } - - return FALSE; -} - +/************************************************************
+
+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.
+
+********************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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.
+
+******************************************************************/
+
+/*
+ * Copyright © 2003-2005 Sun Microsystems, 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 (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.
+ */
+
+/** @file events.c
+ * This file handles event delivery and a big part of the server-side protocol
+ * handling (the parts for input devices).
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include "misc.h"
+#include "resource.h"
+#include <X11/Xproto.h>
+#include "windowstr.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+
+#include "dixstruct.h"
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+#include "globals.h"
+
+#include <X11/extensions/XKBproto.h>
+#include "xkbsrv.h"
+#include "xace.h"
+
+#ifdef XSERVER_DTRACE
+#include <sys/types.h>
+typedef const char *string;
+#include "Xserver-dtrace.h"
+#endif
+
+#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XI2.h>
+#include "exglobals.h"
+#include "exevents.h"
+#include "exglobals.h"
+#include "extnsionst.h"
+
+#include "dixevents.h"
+#include "dixgrabs.h"
+#include "dispatch.h"
+
+#include <X11/extensions/ge.h>
+#include "geext.h"
+#include "geint.h"
+
+#include "eventstr.h"
+#include "enterleave.h"
+#include "eventconvert.h"
+
+/* Extension events type numbering starts at EXTENSION_EVENT_BASE. */
+#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
+#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
+#define AllButtonsMask ( \
+ Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
+#define MotionMask ( \
+ PointerMotionMask | Button1MotionMask | \
+ Button2MotionMask | Button3MotionMask | Button4MotionMask | \
+ Button5MotionMask | ButtonMotionMask )
+#define PropagateMask ( \
+ KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
+ MotionMask )
+#define PointerGrabMask ( \
+ ButtonPressMask | ButtonReleaseMask | \
+ EnterWindowMask | LeaveWindowMask | \
+ PointerMotionHintMask | KeymapStateMask | \
+ MotionMask )
+#define AllModifiersMask ( \
+ ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
+ Mod3Mask | Mod4Mask | Mod5Mask )
+#define LastEventMask OwnerGrabButtonMask
+#define AllEventMasks (LastEventMask|(LastEventMask-1))
+
+
+#define CORE_EVENT(event) \
+ (!((event)->u.u.type & EXTENSION_EVENT_BASE) && \
+ (event)->u.u.type != GenericEvent)
+#define XI2_EVENT(event) \
+ (((event)->u.u.type == GenericEvent) && \
+ ((xGenericEvent*)(event))->extension == IReqCode)
+
+/**
+ * Used to indicate a implicit passive grab created by a ButtonPress event.
+ * See DeliverEventsToWindow().
+ */
+#define ImplicitGrabMask (1 << 7)
+
+#define WID(w) ((w) ? ((w)->drawable.id) : 0)
+
+#define XE_KBPTR (xE->u.keyButtonPointer)
+
+
+#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
+
+CallbackListPtr EventCallback;
+CallbackListPtr DeviceEventCallback;
+
+#define DNPMCOUNT 8
+
+Mask DontPropagateMasks[DNPMCOUNT];
+static int DontPropagateRefCnts[DNPMCOUNT];
+
+static void CheckVirtualMotion( DeviceIntPtr pDev, QdEventPtr qe, WindowPtr pWin);
+static void CheckPhysLimits(DeviceIntPtr pDev,
+ CursorPtr cursor,
+ Bool generateEvents,
+ Bool confineToScreen,
+ ScreenPtr pScreen);
+static Bool CheckPassiveGrabsOnWindow(WindowPtr pWin,
+ DeviceIntPtr device,
+ DeviceEvent *event,
+ BOOL checkCore);
+
+/** Key repeat hack. Do not use but in TryClientEvents */
+extern BOOL EventIsKeyRepeat(xEvent *event);
+
+/**
+ * Main input device struct.
+ * inputInfo.pointer
+ * is the core pointer. Referred to as "virtual core pointer", "VCP",
+ * "core pointer" or inputInfo.pointer. The VCP is the first master
+ * pointer device and cannot be deleted.
+ *
+ * inputInfo.keyboard
+ * is the core keyboard ("virtual core keyboard", "VCK", "core keyboard").
+ * See inputInfo.pointer.
+ *
+ * inputInfo.devices
+ * linked list containing all devices including VCP and VCK.
+ *
+ * inputInfo.off_devices
+ * Devices that have not been initialized and are thus turned off.
+ *
+ * inputInfo.numDevices
+ * Total number of devices.
+ *
+ * inputInfo.all_devices
+ * Virtual device used for XIAllDevices passive grabs. This device is
+ * not part of the inputInfo.devices list and mostly unset except for
+ * the deviceid. It exists because passivegrabs need a valid device
+ * reference.
+ *
+ * inputInfo.all_master_devices
+ * Virtual device used for XIAllMasterDevices passive grabs. This device
+ * is not part of the inputInfo.devices list and mostly unset except for
+ * the deviceid. It exists because passivegrabs need a valid device
+ * reference.
+ */
+InputInfo inputInfo;
+
+/**
+ * syncEvents is the global structure for queued events.
+ *
+ * Devices can be frozen through GrabModeSync pointer grabs. If this is the
+ * case, events from these devices are added to "pending" instead of being
+ * processed normally. When the device is unfrozen, events in "pending" are
+ * replayed and processed as if they would come from the device directly.
+ */
+static struct {
+ QdEventPtr pending, /**< list of queued events */
+ *pendtail; /**< last event in list */
+ /** The device to replay events for. Only set in AllowEvents(), in which
+ * case it is set to the device specified in the request. */
+ DeviceIntPtr replayDev; /* kludgy rock to put flag for */
+
+ /**
+ * The window the events are supposed to be replayed on.
+ * This window may be set to the grab's window (but only when
+ * Replay{Pointer|Keyboard} is given in the XAllowEvents()
+ * request. */
+ WindowPtr replayWin; /* ComputeFreezes */
+ /**
+ * Flag to indicate whether we're in the process of
+ * replaying events. Only set in ComputeFreezes(). */
+ Bool playingEvents;
+ TimeStamp time;
+} syncEvents;
+
+/**
+ * The root window the given device is currently on.
+ */
+#define RootWindow(dev) dev->spriteInfo->sprite->spriteTrace[0]
+
+static xEvent* swapEvent = NULL;
+static int swapEventLen = 0;
+
+void
+NotImplemented(xEvent *from, xEvent *to)
+{
+ FatalError("Not implemented");
+}
+
+/**
+ * Convert the given event type from an XI event to a core event.
+ * @param[in] The XI 1.x event type.
+ * @return The matching core event type or 0 if there is none.
+ */
+int
+XItoCoreType(int xitype)
+{
+ int coretype = 0;
+ if (xitype == DeviceMotionNotify)
+ coretype = MotionNotify;
+ else if (xitype == DeviceButtonPress)
+ coretype = ButtonPress;
+ else if (xitype == DeviceButtonRelease)
+ coretype = ButtonRelease;
+ else if (xitype == DeviceKeyPress)
+ coretype = KeyPress;
+ else if (xitype == DeviceKeyRelease)
+ coretype = KeyRelease;
+
+ return coretype;
+}
+
+/**
+ * @return true if the device owns a cursor, false if device shares a cursor
+ * sprite with another device.
+ */
+Bool
+DevHasCursor(DeviceIntPtr pDev)
+{
+ return pDev->spriteInfo->spriteOwner;
+}
+
+/*
+ * @return true if a device is a pointer, check is the same as used by XI to
+ * fill the 'use' field.
+ */
+Bool
+IsPointerDevice(DeviceIntPtr dev)
+{
+ return (dev->type == MASTER_POINTER) ||
+ (dev->valuator && dev->button) ||
+ (dev->valuator && !dev->key);
+}
+
+/*
+ * @return true if a device is a keyboard, check is the same as used by XI to
+ * fill the 'use' field.
+ *
+ * Some pointer devices have keys as well (e.g. multimedia keys). Try to not
+ * count them as keyboard devices.
+ */
+Bool
+IsKeyboardDevice(DeviceIntPtr dev)
+{
+ return (dev->type == MASTER_KEYBOARD) ||
+ ((dev->key && dev->kbdfeed) && !IsPointerDevice(dev));
+}
+
+Bool
+IsMaster(DeviceIntPtr dev)
+{
+ return (dev->type == MASTER_POINTER || dev->type == MASTER_KEYBOARD);
+}
+
+static WindowPtr XYToWindow(
+ DeviceIntPtr pDev,
+ int x,
+ int y
+);
+
+/**
+ * Max event opcode.
+ */
+extern int lastEvent;
+
+extern int DeviceMotionNotify;
+
+#define CantBeFiltered NoEventMask
+/**
+ * Event masks for each event type.
+ *
+ * One set of filters for each device, but only the first layer
+ * is initialized. The rest is memcpy'd in InitEvents.
+ *
+ * Filters are used whether a given event may be delivered to a client,
+ * usually in the form of if (window-event-mask & filter); then deliver event.
+ *
+ * One notable filter is for PointerMotion/DevicePointerMotion events. Each
+ * time a button is pressed, the filter is modified to also contain the
+ * matching ButtonXMotion mask.
+ */
+static Mask filters[MAXDEVICES][128] = {
+{
+ NoSuchEvent, /* 0 */
+ NoSuchEvent, /* 1 */
+ KeyPressMask, /* KeyPress */
+ KeyReleaseMask, /* KeyRelease */
+ ButtonPressMask, /* ButtonPress */
+ ButtonReleaseMask, /* ButtonRelease */
+ PointerMotionMask, /* MotionNotify (initial state) */
+ EnterWindowMask, /* EnterNotify */
+ LeaveWindowMask, /* LeaveNotify */
+ FocusChangeMask, /* FocusIn */
+ FocusChangeMask, /* FocusOut */
+ KeymapStateMask, /* KeymapNotify */
+ ExposureMask, /* Expose */
+ CantBeFiltered, /* GraphicsExpose */
+ CantBeFiltered, /* NoExpose */
+ VisibilityChangeMask, /* VisibilityNotify */
+ SubstructureNotifyMask, /* CreateNotify */
+ StructureAndSubMask, /* DestroyNotify */
+ StructureAndSubMask, /* UnmapNotify */
+ StructureAndSubMask, /* MapNotify */
+ SubstructureRedirectMask, /* MapRequest */
+ StructureAndSubMask, /* ReparentNotify */
+ StructureAndSubMask, /* ConfigureNotify */
+ SubstructureRedirectMask, /* ConfigureRequest */
+ StructureAndSubMask, /* GravityNotify */
+ ResizeRedirectMask, /* ResizeRequest */
+ StructureAndSubMask, /* CirculateNotify */
+ SubstructureRedirectMask, /* CirculateRequest */
+ PropertyChangeMask, /* PropertyNotify */
+ CantBeFiltered, /* SelectionClear */
+ CantBeFiltered, /* SelectionRequest */
+ CantBeFiltered, /* SelectionNotify */
+ ColormapChangeMask, /* ColormapNotify */
+ CantBeFiltered, /* ClientMessage */
+ CantBeFiltered /* MappingNotify */
+}};
+
+/**
+ * For the given event, return the matching event filter. This filter may then
+ * be AND'ed with the selected event mask.
+ *
+ * For XI2 events, the returned filter is simply the byte containing the event
+ * mask we're interested in. E.g. for a mask of (1 << 13), this would be
+ * byte[1].
+ *
+ * @param[in] dev The device the event belongs to, may be NULL.
+ * @param[in] event The event to get the filter for. Only the type of the
+ * event matters, or the extension + evtype for GenericEvents.
+ * @return The filter mask for the given event.
+ *
+ * @see GetEventMask
+ */
+Mask
+GetEventFilter(DeviceIntPtr dev, xEvent *event)
+{
+ if (event->u.u.type != GenericEvent)
+ return filters[dev ? dev->id : 0][event->u.u.type];
+ else if (XI2_EVENT(event))
+ return (1 << (((xXIDeviceEvent*)event)->evtype % 8));
+ ErrorF("[dix] Unknown device type %d. No filter\n", event->u.u.type);
+ return 0;
+}
+
+/**
+ * Return the windows complete XI2 mask for the given XI2 event type.
+ */
+Mask
+GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
+{
+ OtherInputMasks *inputMasks = wOtherInputMasks(win);
+ int filter;
+ int evtype;
+
+ if (!inputMasks || !XI2_EVENT(ev))
+ return 0;
+
+ evtype = ((xGenericEvent*)ev)->evtype;
+ filter = GetEventFilter(dev, ev);
+
+ return ((inputMasks->xi2mask[dev->id][evtype/8] & filter) ||
+ inputMasks->xi2mask[XIAllDevices][evtype/8] ||
+ (inputMasks->xi2mask[XIAllMasterDevices][evtype/8] && IsMaster(dev)));
+}
+
+static Mask
+GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other)
+{
+ /* XI2 filters are only ever 8 bit, so let's return a 8 bit mask */
+ if (XI2_EVENT(event))
+ {
+ int byte = ((xGenericEvent*)event)->evtype / 8;
+ return (other->xi2mask[dev->id][byte] |
+ other->xi2mask[XIAllDevices][byte] |
+ (IsMaster(dev)? other->xi2mask[XIAllMasterDevices][byte] : 0));
+ } else if (CORE_EVENT(event))
+ return other->mask[XIAllDevices];
+ else
+ return other->mask[dev->id];
+}
+
+
+static CARD8 criticalEvents[32] =
+{
+ 0x7c, 0x30, 0x40 /* key, button, expose, and configure events */
+};
+
+static void
+SyntheticMotion(DeviceIntPtr dev, int x, int y) {
+ int screenno = 0;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ screenno = dev->spriteInfo->sprite->screen->myNum;
+#endif
+ PostSyntheticMotion(dev, x, y, screenno,
+ (syncEvents.playingEvents) ? syncEvents.time.milliseconds : currentTime.milliseconds);
+
+}
+
+#ifdef PANORAMIX
+static void PostNewCursor(DeviceIntPtr pDev);
+
+static Bool
+XineramaSetCursorPosition(
+ DeviceIntPtr pDev,
+ int x,
+ int y,
+ Bool generateEvent
+){
+ ScreenPtr pScreen;
+ BoxRec box;
+ int i;
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
+ /* x,y are in Screen 0 coordinates. We need to decide what Screen
+ to send the message too and what the coordinates relative to
+ that screen are. */
+
+ pScreen = pSprite->screen;
+ x += panoramiXdataPtr[0].x;
+ y += panoramiXdataPtr[0].y;
+
+ if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
+ x, y, &box))
+ {
+ FOR_NSCREENS(i)
+ {
+ if(i == pScreen->myNum)
+ continue;
+ if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box))
+ {
+ pScreen = screenInfo.screens[i];
+ break;
+ }
+ }
+ }
+
+ pSprite->screen = pScreen;
+ pSprite->hotPhys.x = x - panoramiXdataPtr[0].x;
+ pSprite->hotPhys.y = y - panoramiXdataPtr[0].y;
+ x -= panoramiXdataPtr[pScreen->myNum].x;
+ y -= panoramiXdataPtr[pScreen->myNum].y;
+
+ return (*pScreen->SetCursorPosition)(pDev, pScreen, x, y, generateEvent);
+}
+
+
+static void
+XineramaConstrainCursor(DeviceIntPtr pDev)
+{
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+ ScreenPtr pScreen;
+ BoxRec newBox;
+
+ pScreen = pSprite->screen;
+ newBox = pSprite->physLimits;
+
+ /* Translate the constraining box to the screen
+ the sprite is actually on */
+ newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+ newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
+ newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+ newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
+
+ (* pScreen->ConstrainCursor)(pDev, pScreen, &newBox);
+}
+
+
+static Bool
+XineramaSetWindowPntrs(DeviceIntPtr pDev, WindowPtr pWin)
+{
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
+ if(pWin == WindowTable[0]) {
+ memcpy(pSprite->windows, WindowTable,
+ PanoramiXNumScreens*sizeof(WindowPtr));
+ } else {
+ PanoramiXRes *win;
+ int rc, i;
+
+ rc = dixLookupResourceByType((pointer *)&win, pWin->drawable.id,
+ XRT_WINDOW, serverClient, DixReadAccess);
+ if (rc != Success)
+ return FALSE;
+
+ for(i = 0; i < PanoramiXNumScreens; i++) {
+ rc = dixLookupWindow(pSprite->windows + i, win->info[i].id,
+ serverClient, DixReadAccess);
+ if (rc != Success) /* window is being unmapped */
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static void
+XineramaConfineCursorToWindow(DeviceIntPtr pDev,
+ WindowPtr pWin,
+ Bool generateEvents)
+{
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
+ int x, y, off_x, off_y, i;
+
+ if(!XineramaSetWindowPntrs(pDev, pWin))
+ return;
+
+ i = PanoramiXNumScreens - 1;
+
+ REGION_COPY(pSprite->screen, &pSprite->Reg1,
+ &pSprite->windows[i]->borderSize);
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+
+ while(i--) {
+ x = off_x - panoramiXdataPtr[i].x;
+ y = off_y - panoramiXdataPtr[i].y;
+
+ if(x || y)
+ REGION_TRANSLATE(pSprite->screen, &pSprite->Reg1, x, y);
+
+ REGION_UNION(pSprite->screen, &pSprite->Reg1, &pSprite->Reg1,
+ &pSprite->windows[i]->borderSize);
+
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+ }
+
+ pSprite->hotLimits = *REGION_EXTENTS(pSprite->screen, &pSprite->Reg1);
+
+ if(REGION_NUM_RECTS(&pSprite->Reg1) > 1)
+ pSprite->hotShape = &pSprite->Reg1;
+ else
+ pSprite->hotShape = NullRegion;
+
+ pSprite->confined = FALSE;
+ pSprite->confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
+
+ CheckPhysLimits(pDev, pSprite->current, generateEvents, FALSE, NULL);
+}
+
+#endif /* PANORAMIX */
+
+/**
+ * Modifies the filter for the given protocol event type to the given masks.
+ *
+ * There's only two callers: UpdateDeviceState() and XI's SetMaskForExtEvent().
+ * The latter initialises masks for the matching XI events, it's a once-off
+ * setting.
+ * UDS however changes the mask for MotionNotify and DeviceMotionNotify each
+ * time a button is pressed to include the matching ButtonXMotion mask in the
+ * filter.
+ *
+ * @param[in] deviceid The device to modify the filter for.
+ * @param[in] mask The new filter mask.
+ * @param[in] event Protocol event type.
+ */
+void
+SetMaskForEvent(int deviceid, Mask mask, int event)
+{
+ if (deviceid < 0 || deviceid >= MAXDEVICES)
+ FatalError("SetMaskForEvent: bogus device id");
+ filters[deviceid][event] = mask;
+}
+
+void
+SetCriticalEvent(int event)
+{
+ if (event >= 128)
+ FatalError("SetCriticalEvent: bogus event number");
+ criticalEvents[event >> 3] |= 1 << (event & 7);
+}
+
+void
+ConfineToShape(DeviceIntPtr pDev, RegionPtr shape, int *px, int *py)
+{
+ BoxRec box;
+ int x = *px, y = *py;
+ int incx = 1, incy = 1;
+ SpritePtr pSprite;
+
+ pSprite = pDev->spriteInfo->sprite;
+ if (POINT_IN_REGION(pSprite->hot.pScreen, shape, x, y, &box))
+ return;
+ box = *REGION_EXTENTS(pSprite->hot.pScreen, shape);
+ /* this is rather crude */
+ do {
+ x += incx;
+ if (x >= box.x2)
+ {
+ incx = -1;
+ x = *px - 1;
+ }
+ else if (x < box.x1)
+ {
+ incx = 1;
+ x = *px;
+ y += incy;
+ if (y >= box.y2)
+ {
+ incy = -1;
+ y = *py - 1;
+ }
+ else if (y < box.y1)
+ return; /* should never get here! */
+ }
+ } while (!POINT_IN_REGION(pSprite->hot.pScreen, shape, x, y, &box));
+ *px = x;
+ *py = y;
+}
+
+static void
+CheckPhysLimits(
+ DeviceIntPtr pDev,
+ CursorPtr cursor,
+ Bool generateEvents,
+ Bool confineToScreen, /* unused if PanoramiX on */
+ ScreenPtr pScreen) /* unused if PanoramiX on */
+{
+ HotSpot new;
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
+ if (!cursor)
+ return;
+ new = pSprite->hotPhys;
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ /* I don't care what the DDX has to say about it */
+ pSprite->physLimits = pSprite->hotLimits;
+ else
+#endif
+ {
+ if (pScreen)
+ new.pScreen = pScreen;
+ else
+ pScreen = new.pScreen;
+ (*pScreen->CursorLimits) (pDev, pScreen, cursor, &pSprite->hotLimits,
+ &pSprite->physLimits);
+ pSprite->confined = confineToScreen;
+ (* pScreen->ConstrainCursor)(pDev, pScreen, &pSprite->physLimits);
+ }
+
+ /* constrain the pointer to those limits */
+ if (new.x < pSprite->physLimits.x1)
+ new.x = pSprite->physLimits.x1;
+ else
+ if (new.x >= pSprite->physLimits.x2)
+ new.x = pSprite->physLimits.x2 - 1;
+ if (new.y < pSprite->physLimits.y1)
+ new.y = pSprite->physLimits.y1;
+ else
+ if (new.y >= pSprite->physLimits.y2)
+ new.y = pSprite->physLimits.y2 - 1;
+ if (pSprite->hotShape)
+ ConfineToShape(pDev, pSprite->hotShape, &new.x, &new.y);
+ if ((pScreen != pSprite->hotPhys.pScreen) ||
+ (new.x != pSprite->hotPhys.x) || (new.y != pSprite->hotPhys.y))
+ {
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ {
+ if (pScreen && ((new.x != pSprite->hotPhys.x) || (new.y != pSprite->hotPhys.y)))
+ XineramaSetCursorPosition (pDev, new.x, new.y, generateEvents);
+ }
+ else
+#endif
+ {
+ if (pScreen != pSprite->hotPhys.pScreen)
+ pSprite->hotPhys = new;
+ (*pScreen->SetCursorPosition)
+ (pDev, pScreen, new.x, new.y, generateEvents);
+ }
+ if (!generateEvents)
+ SyntheticMotion(pDev, new.x, new.y);
+ }
+
+#ifdef PANORAMIX
+ /* Tell DDX what the limits are */
+ if (!noPanoramiXExtension)
+ XineramaConstrainCursor(pDev);
+#endif
+}
+
+static void
+CheckVirtualMotion(
+ DeviceIntPtr pDev,
+ QdEventPtr qe,
+ WindowPtr pWin)
+{
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+ RegionPtr reg = NULL;
+ DeviceEvent *ev = NULL;
+
+ if (qe)
+ {
+ ev = &qe->event->device_event;
+ switch(ev->type)
+ {
+ case ET_Motion:
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_KeyPress:
+ case ET_KeyRelease:
+ case ET_ProximityIn:
+ case ET_ProximityOut:
+ pSprite->hot.pScreen = qe->pScreen;
+ pSprite->hot.x = ev->root_x;
+ pSprite->hot.y = ev->root_y;
+ pWin = pDev->deviceGrab.grab ? pDev->deviceGrab.grab->confineTo : NullWindow;
+ break;
+ default:
+ break;
+ }
+ }
+ if (pWin)
+ {
+ BoxRec lims;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ int x, y, off_x, off_y, i;
+
+ if(!XineramaSetWindowPntrs(pDev, pWin))
+ return;
+
+ i = PanoramiXNumScreens - 1;
+
+ REGION_COPY(pSprite->screen, &pSprite->Reg2,
+ &pSprite->windows[i]->borderSize);
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+
+ while(i--) {
+ x = off_x - panoramiXdataPtr[i].x;
+ y = off_y - panoramiXdataPtr[i].y;
+
+ if(x || y)
+ REGION_TRANSLATE(pSprite->screen, &pSprite->Reg2, x, y);
+
+ REGION_UNION(pSprite->screen, &pSprite->Reg2, &pSprite->Reg2,
+ &pSprite->windows[i]->borderSize);
+
+ off_x = panoramiXdataPtr[i].x;
+ off_y = panoramiXdataPtr[i].y;
+ }
+ } else
+#endif
+ {
+ if (pSprite->hot.pScreen != pWin->drawable.pScreen)
+ {
+ pSprite->hot.pScreen = pWin->drawable.pScreen;
+ pSprite->hot.x = pSprite->hot.y = 0;
+ }
+ }
+
+ lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize);
+ if (pSprite->hot.x < lims.x1)
+ pSprite->hot.x = lims.x1;
+ else if (pSprite->hot.x >= lims.x2)
+ pSprite->hot.x = lims.x2 - 1;
+ if (pSprite->hot.y < lims.y1)
+ pSprite->hot.y = lims.y1;
+ else if (pSprite->hot.y >= lims.y2)
+ pSprite->hot.y = lims.y2 - 1;
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ {
+ if (REGION_NUM_RECTS(&pSprite->Reg2) > 1)
+ reg = &pSprite->Reg2;
+
+ } else
+#endif
+ {
+ if (wBoundingShape(pWin))
+ reg = &pWin->borderSize;
+ }
+
+ if (reg)
+ ConfineToShape(pDev, reg, &pSprite->hot.x, &pSprite->hot.y);
+
+ if (qe && ev)
+ {
+ qe->pScreen = pSprite->hot.pScreen;
+ ev->root_x = pSprite->hot.x;
+ ev->root_y = pSprite->hot.y;
+ }
+ }
+#ifdef PANORAMIX
+ if (noPanoramiXExtension) /* No typo. Only set the root win if disabled */
+#endif
+ RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum];
+}
+
+static void
+ConfineCursorToWindow(DeviceIntPtr pDev, WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
+ if (syncEvents.playingEvents)
+ {
+ CheckVirtualMotion(pDev, (QdEventPtr)NULL, pWin);
+ SyntheticMotion(pDev, pSprite->hot.x, pSprite->hot.y);
+ }
+ else
+ {
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ XineramaConfineCursorToWindow(pDev, pWin, generateEvents);
+ return;
+ }
+#endif
+ pSprite->hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
+ pSprite->hotShape = wBoundingShape(pWin) ? &pWin->borderSize
+ : NullRegion;
+ CheckPhysLimits(pDev, pSprite->current, generateEvents,
+ confineToScreen, pScreen);
+ }
+}
+
+Bool
+PointerConfinedToScreen(DeviceIntPtr pDev)
+{
+ return pDev->spriteInfo->sprite->confined;
+}
+
+/**
+ * Update the sprite cursor to the given cursor.
+ *
+ * ChangeToCursor() will display the new cursor and free the old cursor (if
+ * applicable). If the provided cursor is already the updated cursor, nothing
+ * happens.
+ */
+static void
+ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor)
+{
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+ ScreenPtr pScreen;
+
+ if (cursor != pSprite->current)
+ {
+ if ((pSprite->current->bits->xhot != cursor->bits->xhot) ||
+ (pSprite->current->bits->yhot != cursor->bits->yhot))
+ CheckPhysLimits(pDev, cursor, FALSE, pSprite->confined,
+ (ScreenPtr)NULL);
+#ifdef PANORAMIX
+ /* XXX: is this really necessary?? (whot) */
+ if (!noPanoramiXExtension)
+ pScreen = pSprite->screen;
+ else
+#endif
+ pScreen = pSprite->hotPhys.pScreen;
+
+ (*pScreen->DisplayCursor)(pDev, pScreen, cursor);
+ FreeCursor(pSprite->current, (Cursor)0);
+ pSprite->current = cursor;
+ pSprite->current->refcnt++;
+ }
+}
+
+/**
+ * @returns true if b is a descendent of a
+ */
+Bool
+IsParent(WindowPtr a, WindowPtr b)
+{
+ for (b = b->parent; b; b = b->parent)
+ if (b == a) return TRUE;
+ return FALSE;
+}
+
+/**
+ * Update the cursor displayed on the screen.
+ *
+ * Called whenever a cursor may have changed shape or position.
+ */
+static void
+PostNewCursor(DeviceIntPtr pDev)
+{
+ WindowPtr win;
+ GrabPtr grab = pDev->deviceGrab.grab;
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+ CursorPtr pCursor;
+
+ if (syncEvents.playingEvents)
+ return;
+ if (grab)
+ {
+ if (grab->cursor)
+ {
+ ChangeToCursor(pDev, grab->cursor);
+ return;
+ }
+ if (IsParent(grab->window, pSprite->win))
+ win = pSprite->win;
+ else
+ win = grab->window;
+ }
+ else
+ win = pSprite->win;
+ for (; win; win = win->parent)
+ {
+ if (win->optional)
+ {
+ pCursor = WindowGetDeviceCursor(win, pDev);
+ if (!pCursor && win->optional->cursor != NullCursor)
+ pCursor = win->optional->cursor;
+ if (pCursor)
+ {
+ ChangeToCursor(pDev, pCursor);
+ return;
+ }
+ }
+ }
+}
+
+
+/**
+ * @param dev device which you want to know its current root window
+ * @return root window where dev's sprite is located
+ */
+WindowPtr
+GetCurrentRootWindow(DeviceIntPtr dev)
+{
+ return RootWindow(dev);
+}
+
+/**
+ * @return window underneath the cursor sprite.
+ */
+WindowPtr
+GetSpriteWindow(DeviceIntPtr pDev)
+{
+ return pDev->spriteInfo->sprite->win;
+}
+
+/**
+ * @return current sprite cursor.
+ */
+CursorPtr
+GetSpriteCursor(DeviceIntPtr pDev)
+{
+ return pDev->spriteInfo->sprite->current;
+}
+
+/**
+ * Set x/y current sprite position in screen coordinates.
+ */
+void
+GetSpritePosition(DeviceIntPtr pDev, int *px, int *py)
+{
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+ *px = pSprite->hotPhys.x;
+ *py = pSprite->hotPhys.y;
+}
+
+#ifdef PANORAMIX
+int
+XineramaGetCursorScreen(DeviceIntPtr pDev)
+{
+ if(!noPanoramiXExtension) {
+ return pDev->spriteInfo->sprite->screen->myNum;
+ } else {
+ return 0;
+ }
+}
+#endif /* PANORAMIX */
+
+#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
+
+static void
+MonthChangedOrBadTime(InternalEvent *ev)
+{
+ /* If the ddx/OS is careless about not processing timestamped events from
+ * different sources in sorted order, then it's possible for time to go
+ * backwards when it should not. Here we ensure a decent time.
+ */
+ if ((currentTime.milliseconds - ev->any.time) > TIMESLOP)
+ currentTime.months++;
+ else
+ ev->any.time = currentTime.milliseconds;
+}
+
+static void
+NoticeTime(InternalEvent *ev)
+{
+ if (ev->any.time < currentTime.milliseconds)
+ MonthChangedOrBadTime(ev);
+ currentTime.milliseconds = ev->any.time;
+ lastDeviceEventTime = currentTime;
+}
+
+void
+NoticeEventTime(InternalEvent *ev)
+{
+ if (!syncEvents.playingEvents)
+ NoticeTime(ev);
+}
+
+/**************************************************************************
+ * The following procedures deal with synchronous events *
+ **************************************************************************/
+
+/**
+ * EnqueueEvent is a device's processInputProc if a device is frozen.
+ * Instead of delivering the events to the client, the event is tacked onto a
+ * linked list for later delivery.
+ */
+void
+EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
+{
+ QdEventPtr tail = *syncEvents.pendtail;
+ QdEventPtr qe;
+ SpritePtr pSprite = device->spriteInfo->sprite;
+ int eventlen;
+ DeviceEvent *event = &ev->device_event;
+
+ NoticeTime((InternalEvent*)event);
+
+ /* Fix for key repeating bug. */
+ if (device->key != NULL && device->key->xkbInfo != NULL &&
+ event->type == ET_KeyRelease)
+ AccessXCancelRepeatKey(device->key->xkbInfo, event->detail.key);
+
+ if (DeviceEventCallback)
+ {
+ DeviceEventInfoRec eventinfo;
+ xEvent *xi_events = NULL;
+ int count;
+
+ /* The RECORD spec says that the root window field of motion events
+ * must be valid. At this point, it hasn't been filled in yet, so
+ * we do it here. The long expression below is necessary to get
+ * the current root window; the apparently reasonable alternative
+ * GetCurrentRootWindow()->drawable.id doesn't give you the right
+ * answer on the first motion event after a screen change because
+ * the data that GetCurrentRootWindow relies on hasn't been
+ * updated yet.
+ */
+
+ if (ev->any.type == ET_Motion)
+ ev->device_event.root =
+ WindowTable[pSprite->hotPhys.pScreen->myNum]->drawable.id;
+
+ EventToXI(ev, &xi_events, &count);
+
+ eventinfo.events = (xEventPtr)xi_events;
+ eventinfo.count = count;
+ CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo);
+ xfree(xi_events);
+
+ if (IsMaster(device))
+ {
+ xEvent core;
+ EventToCore(ev, &core);
+ eventinfo.events = (xEventPtr)&core;
+ eventinfo.count = 1;
+ CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo);
+ }
+
+ }
+
+ if (event->type == ET_Motion)
+ {
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ event->root_x += panoramiXdataPtr[pSprite->screen->myNum].x -
+ panoramiXdataPtr[0].x;
+ event->root_y += panoramiXdataPtr[pSprite->screen->myNum].y -
+ panoramiXdataPtr[0].y;
+ }
+#endif
+ pSprite->hotPhys.x = event->root_x;
+ pSprite->hotPhys.y = event->root_y;
+ /* do motion compression, but not if from different devices */
+ if (tail &&
+ (tail->event->any.type == ET_Motion) &&
+ (tail->device == device) &&
+ (tail->pScreen == pSprite->hotPhys.pScreen))
+ {
+ DeviceEvent *tailev = &tail->event->device_event;
+ tailev->root_x = pSprite->hotPhys.x;
+ tailev->root_y = pSprite->hotPhys.y;
+ tailev->time = event->time;
+ tail->months = currentTime.months;
+ return;
+ }
+ }
+
+ eventlen = event->length;
+
+ qe = xalloc(sizeof(QdEventRec) + eventlen);
+ if (!qe)
+ return;
+ qe->next = (QdEventPtr)NULL;
+ qe->device = device;
+ qe->pScreen = pSprite->hotPhys.pScreen;
+ qe->months = currentTime.months;
+ qe->event = (InternalEvent *)(qe + 1);
+ memcpy(qe->event, event, eventlen);
+ if (tail)
+ syncEvents.pendtail = &tail->next;
+ *syncEvents.pendtail = qe;
+}
+
+/**
+ * Run through the list of events queued up in syncEvents.
+ * For each event do:
+ * If the device for this event is not frozen anymore, take it and process it
+ * as usually.
+ * After that, check if there's any devices in the list that are not frozen.
+ * If there is none, we're done. If there is at least one device that is not
+ * frozen, then re-run from the beginning of the event queue.
+ */
+static void
+PlayReleasedEvents(void)
+{
+ QdEventPtr *prev, qe;
+ DeviceIntPtr dev;
+ DeviceIntPtr pDev;
+
+ prev = &syncEvents.pending;
+ while ( (qe = *prev) )
+ {
+ if (!qe->device->deviceGrab.sync.frozen)
+ {
+ *prev = qe->next;
+ pDev = qe->device;
+ if (*syncEvents.pendtail == *prev)
+ syncEvents.pendtail = prev;
+ if (qe->event->any.type == ET_Motion)
+ CheckVirtualMotion(pDev, qe, NullWindow);
+ syncEvents.time.months = qe->months;
+ syncEvents.time.milliseconds = qe->event->any.time;
+#ifdef PANORAMIX
+ /* Translate back to the sprite screen since processInputProc
+ will translate from sprite screen to screen 0 upon reentry
+ to the DIX layer */
+ if(!noPanoramiXExtension) {
+ DeviceEvent *ev = &qe->event->device_event;
+ switch(ev->type)
+ {
+ case ET_Motion:
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_KeyPress:
+ case ET_KeyRelease:
+ case ET_ProximityIn:
+ case ET_ProximityOut:
+ ev->root_x += panoramiXdataPtr[0].x -
+ panoramiXdataPtr[pDev->spriteInfo->sprite->screen->myNum].x;
+ ev->root_y += panoramiXdataPtr[0].y -
+ panoramiXdataPtr[pDev->spriteInfo->sprite->screen->myNum].y;
+ break;
+ default:
+ break;
+ }
+
+ }
+#endif
+ (*qe->device->public.processInputProc)(qe->event, qe->device);
+ xfree(qe);
+ for (dev = inputInfo.devices; dev && dev->deviceGrab.sync.frozen; dev = dev->next)
+ ;
+ if (!dev)
+ break;
+ /* Playing the event may have unfrozen another device. */
+ /* So to play it safe, restart at the head of the queue */
+ prev = &syncEvents.pending;
+ }
+ else
+ prev = &qe->next;
+ }
+}
+
+/**
+ * Freeze or thaw the given devices. The device's processing proc is
+ * switched to either the real processing proc (in case of thawing) or an
+ * enqueuing processing proc (usually EnqueueEvent()).
+ *
+ * @param dev The device to freeze/thaw
+ * @param frozen True to freeze or false to thaw.
+ */
+static void
+FreezeThaw(DeviceIntPtr dev, Bool frozen)
+{
+ dev->deviceGrab.sync.frozen = frozen;
+ if (frozen)
+ dev->public.processInputProc = dev->public.enqueueInputProc;
+ else
+ dev->public.processInputProc = dev->public.realInputProc;
+}
+
+/**
+ * Unfreeze devices and replay all events to the respective clients.
+ *
+ * ComputeFreezes takes the first event in the device's frozen event queue. It
+ * runs up the sprite tree (spriteTrace) and searches for the window to replay
+ * the events from. If it is found, it checks for passive grabs one down from
+ * the window or delivers the events.
+ */
+static void
+ComputeFreezes(void)
+{
+ DeviceIntPtr replayDev = syncEvents.replayDev;
+ int i;
+ WindowPtr w;
+ GrabPtr grab;
+ DeviceIntPtr dev;
+
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ FreezeThaw(dev, dev->deviceGrab.sync.other ||
+ (dev->deviceGrab.sync.state >= FROZEN));
+ if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
+ return;
+ syncEvents.playingEvents = TRUE;
+ if (replayDev)
+ {
+ DeviceEvent* event = replayDev->deviceGrab.sync.event;
+
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+
+ w = XYToWindow(replayDev, event->root_x, event->root_y);
+ for (i = 0; i < replayDev->spriteInfo->sprite->spriteTraceGood; i++)
+ {
+ if (syncEvents.replayWin ==
+ replayDev->spriteInfo->sprite->spriteTrace[i])
+ {
+ if (!CheckDeviceGrabs(replayDev, event, i+1)) {
+ if (replayDev->focus && !IsPointerEvent((InternalEvent*)event))
+ DeliverFocusedEvent(replayDev, (InternalEvent*)event, w);
+ else
+ DeliverDeviceEvents(w, (InternalEvent*)event, NullGrab,
+ NullWindow, replayDev);
+ }
+ goto playmore;
+ }
+ }
+ /* must not still be in the same stack */
+ if (replayDev->focus && !IsPointerEvent((InternalEvent*)event))
+ DeliverFocusedEvent(replayDev, (InternalEvent*)event, w);
+ else
+ DeliverDeviceEvents(w, (InternalEvent*)event, NullGrab,
+ NullWindow, replayDev);
+ }
+playmore:
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (!dev->deviceGrab.sync.frozen)
+ {
+ PlayReleasedEvents();
+ break;
+ }
+ }
+ syncEvents.playingEvents = FALSE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (DevHasCursor(dev))
+ {
+ /* the following may have been skipped during replay,
+ so do it now */
+ if ((grab = dev->deviceGrab.grab) && grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen !=
+ dev->spriteInfo->sprite->hotPhys.pScreen)
+ dev->spriteInfo->sprite->hotPhys.x =
+ dev->spriteInfo->sprite->hotPhys.y = 0;
+ ConfineCursorToWindow(dev, grab->confineTo, TRUE, TRUE);
+ }
+ else
+ ConfineCursorToWindow(dev,
+ WindowTable[dev->spriteInfo->sprite->hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+ PostNewCursor(dev);
+ }
+ }
+}
+
+#ifdef RANDR
+void
+ScreenRestructured (ScreenPtr pScreen)
+{
+ GrabPtr grab;
+ DeviceIntPtr pDev;
+
+ for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
+ {
+ if (!DevHasCursor(pDev))
+ continue;
+
+ /* GrabDevice doesn't have a confineTo field, so we don't need to
+ * worry about it. */
+ if ((grab = pDev->deviceGrab.grab) && grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen
+ != pDev->spriteInfo->sprite->hotPhys.pScreen)
+ pDev->spriteInfo->sprite->hotPhys.x = pDev->spriteInfo->sprite->hotPhys.y = 0;
+ ConfineCursorToWindow(pDev, grab->confineTo, TRUE, TRUE);
+ }
+ else
+ ConfineCursorToWindow(pDev,
+ WindowTable[pDev->spriteInfo->sprite->hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+ }
+}
+#endif
+
+static void
+CheckGrabForSyncs(DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
+{
+ GrabPtr grab = thisDev->deviceGrab.grab;
+ DeviceIntPtr dev;
+
+ if (thisMode == GrabModeSync)
+ thisDev->deviceGrab.sync.state = FROZEN_NO_EVENT;
+ else
+ { /* free both if same client owns both */
+ thisDev->deviceGrab.sync.state = THAWED;
+ if (thisDev->deviceGrab.sync.other &&
+ (CLIENT_BITS(thisDev->deviceGrab.sync.other->resource) ==
+ CLIENT_BITS(grab->resource)))
+ thisDev->deviceGrab.sync.other = NullGrab;
+ }
+
+ /*
+ XXX: Direct slave grab won't freeze the paired master device.
+ The correct thing to do would be to freeze all SDs attached to the
+ paired master device.
+ */
+ if (IsMaster(thisDev))
+ {
+ dev = GetPairedDevice(thisDev);
+ if (otherMode == GrabModeSync)
+ dev->deviceGrab.sync.other = grab;
+ else
+ { /* free both if same client owns both */
+ if (dev->deviceGrab.sync.other &&
+ (CLIENT_BITS(dev->deviceGrab.sync.other->resource) ==
+ CLIENT_BITS(grab->resource)))
+ dev->deviceGrab.sync.other = NullGrab;
+ }
+ }
+ ComputeFreezes();
+}
+
+/* Only ever used if a grab is called on an attached slave device. */
+static int GrabPrivateKeyIndex;
+static DevPrivateKey GrabPrivateKey = &GrabPrivateKeyIndex;
+
+/**
+ * Save the device's master device in the devPrivates. This needs to be done
+ * if a client directly grabs a slave device that is attached to a master. For
+ * the duration of the grab, the device is detached, ungrabbing re-attaches it
+ * though.
+ *
+ * We store the ID of the master device only in case the master disappears
+ * while the device has a grab.
+ */
+static void
+DetachFromMaster(DeviceIntPtr dev)
+{
+ intptr_t id;
+ if (!dev->u.master)
+ return;
+
+ id = dev->u.master->id;
+
+ dixSetPrivate(&dev->devPrivates, GrabPrivateKey, (void *)id);
+ AttachDevice(NULL, dev, NULL);
+}
+
+static void
+ReattachToOldMaster(DeviceIntPtr dev)
+{
+ int id;
+ void *p;
+ DeviceIntPtr master = NULL;
+
+ if (IsMaster(dev))
+ return;
+
+
+ p = dixLookupPrivate(&dev->devPrivates, GrabPrivateKey);
+ id = (intptr_t) p; /* silence gcc warnings */
+ dixLookupDevice(&master, id, serverClient, DixUseAccess);
+
+ if (master)
+ {
+ AttachDevice(serverClient, dev, master);
+ dixSetPrivate(&dev->devPrivates, GrabPrivateKey, NULL);
+ }
+}
+
+/**
+ * Activate a pointer grab on the given device. A pointer grab will cause all
+ * core pointer events of this device to be delivered to the grabbing client only.
+ * No other device will send core events to the grab client while the grab is
+ * on, but core events will be sent to other clients.
+ * Can cause the cursor to change if a grab cursor is set.
+ *
+ * Note that parameter autoGrab may be (True & ImplicitGrabMask) if the grab
+ * is an implicit grab caused by a ButtonPress event.
+ *
+ * @param mouse The device to grab.
+ * @param grab The grab structure, needs to be setup.
+ * @param autoGrab True if the grab was caused by a button down event and not
+ * explicitely by a client.
+ */
+void
+ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
+ TimeStamp time, Bool autoGrab)
+{
+ GrabInfoPtr grabinfo = &mouse->deviceGrab;
+ WindowPtr oldWin = (grabinfo->grab) ?
+ grabinfo->grab->window
+ : mouse->spriteInfo->sprite->win;
+ Bool isPassive = autoGrab & ~ImplicitGrabMask;
+
+ /* slave devices need to float for the duration of the grab. */
+ if (grab->grabtype == GRABTYPE_XI2 &&
+ !(autoGrab & ImplicitGrabMask) && !IsMaster(mouse))
+ DetachFromMaster(mouse);
+
+ if (grab->confineTo)
+ {
+ if (grab->confineTo->drawable.pScreen
+ != mouse->spriteInfo->sprite->hotPhys.pScreen)
+ mouse->spriteInfo->sprite->hotPhys.x =
+ mouse->spriteInfo->sprite->hotPhys.y = 0;
+ ConfineCursorToWindow(mouse, grab->confineTo, FALSE, TRUE);
+ }
+ DoEnterLeaveEvents(mouse, mouse->id, oldWin, grab->window, NotifyGrab);
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (syncEvents.playingEvents)
+ grabinfo->grabTime = syncEvents.time;
+ else
+ grabinfo->grabTime = time;
+ if (grab->cursor)
+ grab->cursor->refcnt++;
+ grabinfo->activeGrab = *grab;
+ grabinfo->grab = &grabinfo->activeGrab;
+ grabinfo->fromPassiveGrab = isPassive;
+ grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
+ PostNewCursor(mouse);
+ CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
+}
+
+/**
+ * Delete grab on given device, update the sprite.
+ *
+ * Extension devices are set up for ActivateKeyboardGrab().
+ */
+void
+DeactivatePointerGrab(DeviceIntPtr mouse)
+{
+ GrabPtr grab = mouse->deviceGrab.grab;
+ DeviceIntPtr dev;
+ Bool wasImplicit = (mouse->deviceGrab.fromPassiveGrab &&
+ mouse->deviceGrab.implicitGrab);
+
+ mouse->valuator->motionHintWindow = NullWindow;
+ mouse->deviceGrab.grab = NullGrab;
+ mouse->deviceGrab.sync.state = NOT_GRABBED;
+ mouse->deviceGrab.fromPassiveGrab = FALSE;
+
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->deviceGrab.sync.other == grab)
+ dev->deviceGrab.sync.other = NullGrab;
+ }
+ DoEnterLeaveEvents(mouse, mouse->id, grab->window,
+ mouse->spriteInfo->sprite->win, NotifyUngrab);
+ if (grab->confineTo)
+ ConfineCursorToWindow(mouse, RootWindow(mouse), FALSE, FALSE);
+ PostNewCursor(mouse);
+ if (grab->cursor)
+ FreeCursor(grab->cursor, (Cursor)0);
+
+ if (!wasImplicit && grab->grabtype == GRABTYPE_XI2)
+ ReattachToOldMaster(mouse);
+
+ ComputeFreezes();
+}
+
+/**
+ * Activate a keyboard grab on the given device.
+ *
+ * Extension devices have ActivateKeyboardGrab() set as their grabbing proc.
+ */
+void
+ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool passive)
+{
+ GrabInfoPtr grabinfo = &keybd->deviceGrab;
+ WindowPtr oldWin;
+
+ /* slave devices need to float for the duration of the grab. */
+ if (grab->grabtype == GRABTYPE_XI2 &&
+ !(passive & ImplicitGrabMask) &&
+ !IsMaster(keybd))
+ DetachFromMaster(keybd);
+
+ if (grabinfo->grab)
+ oldWin = grabinfo->grab->window;
+ else if (keybd->focus)
+ oldWin = keybd->focus->win;
+ else
+ oldWin = keybd->spriteInfo->sprite->win;
+ if (oldWin == FollowKeyboardWin)
+ oldWin = keybd->focus->win;
+ if (keybd->valuator)
+ keybd->valuator->motionHintWindow = NullWindow;
+ DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
+ if (syncEvents.playingEvents)
+ grabinfo->grabTime = syncEvents.time;
+ else
+ grabinfo->grabTime = time;
+ grabinfo->activeGrab = *grab;
+ grabinfo->grab = &grabinfo->activeGrab;
+ grabinfo->fromPassiveGrab = passive;
+ grabinfo->implicitGrab = passive & ImplicitGrabMask;
+ CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
+}
+
+/**
+ * Delete keyboard grab for the given device.
+ */
+void
+DeactivateKeyboardGrab(DeviceIntPtr keybd)
+{
+ GrabPtr grab = keybd->deviceGrab.grab;
+ DeviceIntPtr dev;
+ WindowPtr focusWin = keybd->focus ? keybd->focus->win
+ : keybd->spriteInfo->sprite->win;
+ Bool wasImplicit = (keybd->deviceGrab.fromPassiveGrab &&
+ keybd->deviceGrab.implicitGrab);
+
+ if (focusWin == FollowKeyboardWin)
+ focusWin = inputInfo.keyboard->focus->win;
+ if (keybd->valuator)
+ keybd->valuator->motionHintWindow = NullWindow;
+ keybd->deviceGrab.grab = NullGrab;
+ keybd->deviceGrab.sync.state = NOT_GRABBED;
+ keybd->deviceGrab.fromPassiveGrab = FALSE;
+
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->deviceGrab.sync.other == grab)
+ dev->deviceGrab.sync.other = NullGrab;
+ }
+ DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
+
+ if (!wasImplicit && grab->grabtype == GRABTYPE_XI2)
+ ReattachToOldMaster(keybd);
+
+ ComputeFreezes();
+}
+
+void
+AllowSome(ClientPtr client,
+ TimeStamp time,
+ DeviceIntPtr thisDev,
+ int newState)
+{
+ Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
+ TimeStamp grabTime;
+ DeviceIntPtr dev;
+ GrabInfoPtr devgrabinfo,
+ grabinfo = &thisDev->deviceGrab;
+
+ thisGrabbed = grabinfo->grab && SameClient(grabinfo->grab, client);
+ thisSynced = FALSE;
+ otherGrabbed = FALSE;
+ othersFrozen = FALSE;
+ grabTime = grabinfo->grabTime;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ devgrabinfo = &dev->deviceGrab;
+
+ if (dev == thisDev)
+ continue;
+ if (devgrabinfo->grab && SameClient(devgrabinfo->grab, client))
+ {
+ if (!(thisGrabbed || otherGrabbed) ||
+ (CompareTimeStamps(devgrabinfo->grabTime, grabTime) == LATER))
+ grabTime = devgrabinfo->grabTime;
+ otherGrabbed = TRUE;
+ if (grabinfo->sync.other == devgrabinfo->grab)
+ thisSynced = TRUE;
+ if (devgrabinfo->sync.state >= FROZEN)
+ othersFrozen = TRUE;
+ }
+ }
+ if (!((thisGrabbed && grabinfo->sync.state >= FROZEN) || thisSynced))
+ return;
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, grabTime) == EARLIER))
+ return;
+ switch (newState)
+ {
+ case THAWED: /* Async */
+ if (thisGrabbed)
+ grabinfo->sync.state = THAWED;
+ if (thisSynced)
+ grabinfo->sync.other = NullGrab;
+ ComputeFreezes();
+ break;
+ case FREEZE_NEXT_EVENT: /* Sync */
+ if (thisGrabbed)
+ {
+ grabinfo->sync.state = FREEZE_NEXT_EVENT;
+ if (thisSynced)
+ grabinfo->sync.other = NullGrab;
+ ComputeFreezes();
+ }
+ break;
+ case THAWED_BOTH: /* AsyncBoth */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ devgrabinfo = &dev->deviceGrab;
+ if (devgrabinfo->grab
+ && SameClient(devgrabinfo->grab, client))
+ devgrabinfo->sync.state = THAWED;
+ if (devgrabinfo->sync.other &&
+ SameClient(devgrabinfo->sync.other, client))
+ devgrabinfo->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ case FREEZE_BOTH_NEXT_EVENT: /* SyncBoth */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ devgrabinfo = &dev->deviceGrab;
+ if (devgrabinfo->grab
+ && SameClient(devgrabinfo->grab, client))
+ devgrabinfo->sync.state = FREEZE_BOTH_NEXT_EVENT;
+ if (devgrabinfo->sync.other
+ && SameClient(devgrabinfo->sync.other, client))
+ devgrabinfo->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ case NOT_GRABBED: /* Replay */
+ if (thisGrabbed && grabinfo->sync.state == FROZEN_WITH_EVENT)
+ {
+ if (thisSynced)
+ grabinfo->sync.other = NullGrab;
+ syncEvents.replayDev = thisDev;
+ syncEvents.replayWin = grabinfo->grab->window;
+ (*grabinfo->DeactivateGrab)(thisDev);
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+ }
+ break;
+ case THAW_OTHERS: /* AsyncOthers */
+ if (othersFrozen)
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ devgrabinfo = &dev->deviceGrab;
+ if (devgrabinfo->grab
+ && SameClient(devgrabinfo->grab, client))
+ devgrabinfo->sync.state = THAWED;
+ if (devgrabinfo->sync.other
+ && SameClient(devgrabinfo->sync.other, client))
+ devgrabinfo->sync.other = NullGrab;
+ }
+ ComputeFreezes();
+ }
+ break;
+ }
+}
+
+/**
+ * Server-side protocol handling for AllowEvents request.
+ *
+ * Release some events from a frozen device.
+ */
+int
+ProcAllowEvents(ClientPtr client)
+{
+ TimeStamp time;
+ DeviceIntPtr mouse = NULL;
+ DeviceIntPtr keybd = NULL;
+ REQUEST(xAllowEventsReq);
+
+ REQUEST_SIZE_MATCH(xAllowEventsReq);
+ time = ClientTimeToServerTime(stuff->time);
+
+ mouse = PickPointer(client);
+ keybd = PickKeyboard(client);
+
+ switch (stuff->mode)
+ {
+ case ReplayPointer:
+ AllowSome(client, time, mouse, NOT_GRABBED);
+ break;
+ case SyncPointer:
+ AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
+ break;
+ case AsyncPointer:
+ AllowSome(client, time, mouse, THAWED);
+ break;
+ case ReplayKeyboard:
+ AllowSome(client, time, keybd, NOT_GRABBED);
+ break;
+ case SyncKeyboard:
+ AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
+ break;
+ case AsyncKeyboard:
+ AllowSome(client, time, keybd, THAWED);
+ break;
+ case SyncBoth:
+ AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
+ break;
+ case AsyncBoth:
+ AllowSome(client, time, keybd, THAWED_BOTH);
+ break;
+ default:
+ client->errorValue = stuff->mode;
+ return BadValue;
+ }
+ return Success;
+}
+
+/**
+ * Deactivate grabs from any device that has been grabbed by the client.
+ */
+void
+ReleaseActiveGrabs(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ Bool done;
+
+ /* XXX CloseDownClient should remove passive grabs before
+ * releasing active grabs.
+ */
+ do {
+ done = TRUE;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->deviceGrab.grab && SameClient(dev->deviceGrab.grab, client))
+ {
+ (*dev->deviceGrab.DeactivateGrab)(dev);
+ done = FALSE;
+ }
+ }
+ } while (!done);
+}
+
+/**************************************************************************
+ * The following procedures deal with delivering events *
+ **************************************************************************/
+
+/**
+ * Deliver the given events to the given client.
+ *
+ * More than one event may be delivered at a time. This is the case with
+ * DeviceMotionNotifies which may be followed by DeviceValuator events.
+ *
+ * TryClientEvents() is the last station before actually writing the events to
+ * the socket. Anything that is not filtered here, will get delivered to the
+ * client.
+ * An event is only delivered if
+ * - mask and filter match up.
+ * - no other client has a grab on the device that caused the event.
+ *
+ *
+ * @param client The target client to deliver to.
+ * @param dev The device the event came from. May be NULL.
+ * @param pEvents The events to be delivered.
+ * @param count Number of elements in pEvents.
+ * @param mask Event mask as set by the window.
+ * @param filter Mask based on event type.
+ * @param grab Possible grab on the device that caused the event.
+ *
+ * @return 1 if event was delivered, 0 if not or -1 if grab was not set by the
+ * client.
+ */
+int
+TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents,
+ int count, Mask mask, Mask filter, GrabPtr grab)
+{
+ int i;
+ int type;
+
+#ifdef DEBUG_EVENTS
+ ErrorF("[dix] Event([%d, %d], mask=0x%lx), client=%d%s",
+ pEvents->u.u.type, pEvents->u.u.detail, mask,
+ client ? client->index : -1,
+ (client && client->clientGone) ? " (gone)" : "");
+#endif
+
+ if (!client || client == serverClient || client->clientGone) {
+#ifdef DEBUG_EVENTS
+ ErrorF(" not delivered to fake/dead client\n");
+#endif
+ return 0;
+ }
+
+ if (filter != CantBeFiltered && !(mask & filter))
+ {
+ #ifdef DEBUG_EVENTS
+ ErrorF(" filtered\n");
+ #endif
+ return 0;
+ }
+
+ if (grab && !SameClient(grab, client))
+ {
+#ifdef DEBUG_EVENTS
+ ErrorF(" not delivered due to grab\n");
+#endif
+ return -1; /* don't send, but notify caller */
+ }
+
+ type = pEvents->u.u.type;
+ if (type == MotionNotify)
+ {
+ if (mask & PointerMotionHintMask)
+ {
+ if (WID(dev->valuator->motionHintWindow) ==
+ pEvents->u.keyButtonPointer.event)
+ {
+#ifdef DEBUG_EVENTS
+ ErrorF("[dix] \n");
+ ErrorF("[dix] motionHintWindow == keyButtonPointer.event\n");
+#endif
+ return 1; /* don't send, but pretend we did */
+ }
+ pEvents->u.u.detail = NotifyHint;
+ }
+ else
+ {
+ pEvents->u.u.detail = NotifyNormal;
+ }
+ }
+ else if (type == DeviceMotionNotify)
+ {
+ if (MaybeSendDeviceMotionNotifyHint((deviceKeyButtonPointer*)pEvents,
+ mask) != 0)
+ return 1;
+ } else if (type == KeyPress)
+ {
+ if (EventIsKeyRepeat(pEvents))
+ {
+ if (!_XkbWantsDetectableAutoRepeat(client))
+ {
+ xEvent release = *pEvents;
+ release.u.u.type = KeyRelease;
+ release.u.u.sequenceNumber = client->sequence;
+ WriteEventsToClient(client, 1, &release);
+#ifdef DEBUG_EVENTS
+ ErrorF(" (plus fake core release for repeat)");
+#endif
+ } else
+ {
+#ifdef DEBUG_EVENTS
+ ErrorF(" (detectable autorepeat for core)");
+#endif
+ }
+ }
+
+ } else if (type == DeviceKeyPress)
+ {
+ if (EventIsKeyRepeat(pEvents))
+ {
+ if (!_XkbWantsDetectableAutoRepeat(client))
+ {
+ deviceKeyButtonPointer release = *(deviceKeyButtonPointer *)pEvents;
+ release.type = DeviceKeyRelease;
+ release.sequenceNumber = client->sequence;
+#ifdef DEBUG_EVENTS
+ ErrorF(" (plus fake xi1 release for repeat)");
+#endif
+ WriteEventsToClient(client, 1, (xEvent *) &release);
+ }
+ else {
+#ifdef DEBUG_EVENTS
+ ErrorF(" (detectable autorepeat for core)");
+#endif
+ }
+ }
+ }
+
+ type &= 0177;
+ if (type != KeymapNotify)
+ {
+ /* all extension events must have a sequence number */
+ for (i = 0; i < count; i++)
+ pEvents[i].u.u.sequenceNumber = client->sequence;
+ }
+
+ if (BitIsOn(criticalEvents, type))
+ {
+ if (client->smart_priority < SMART_MAX_PRIORITY)
+ client->smart_priority++;
+ SetCriticalOutputPending();
+ }
+
+ WriteEventsToClient(client, count, pEvents);
+#ifdef DEBUG_EVENTS
+ ErrorF("[dix] delivered\n");
+#endif
+ return 1;
+}
+
+/**
+ * Deliver events to a window. At this point, we do not yet know if the event
+ * actually needs to be delivered. May activate a grab if the event is a
+ * button press.
+ *
+ * Core events are always delivered to the window owner. If the filter is
+ * something other than CantBeFiltered, the event is also delivered to other
+ * clients with the matching mask on the window.
+ *
+ * More than one event may be delivered at a time. This is the case with
+ * DeviceMotionNotifies which may be followed by DeviceValuator events.
+ *
+ * @param pWin The window that would get the event.
+ * @param pEvents The events to be delivered.
+ * @param count Number of elements in pEvents.
+ * @param filter Mask based on event type.
+ * @param grab Possible grab on the device that caused the event.
+ *
+ * @return Number of events delivered to various clients.
+ */
+int
+DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
+ *pEvents, int count, Mask filter, GrabPtr grab)
+{
+ int deliveries = 0, nondeliveries = 0;
+ int attempt;
+ InputClients *other;
+ ClientPtr client = NullClient;
+ Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
+ this mask is the mask of the grab. */
+ int type = pEvents->u.u.type;
+
+
+ /* Deliver to window owner */
+ if ((filter == CantBeFiltered) || CORE_EVENT(pEvents))
+ {
+ /* if nobody ever wants to see this event, skip some work */
+ if (filter != CantBeFiltered &&
+ !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
+ return 0;
+
+ if (IsInterferingGrab(wClient(pWin), pDev, pEvents))
+ return 0;
+
+ if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count))
+ /* do nothing */;
+ else if ( (attempt = TryClientEvents(wClient(pWin), pDev, pEvents,
+ count, pWin->eventMask,
+ filter, grab)) )
+ {
+ if (attempt > 0)
+ {
+ deliveries++;
+ client = wClient(pWin);
+ deliveryMask = pWin->eventMask;
+ } else
+ nondeliveries--;
+ }
+ }
+
+ /* CantBeFiltered means only window owner gets the event */
+ if (filter != CantBeFiltered)
+ {
+ if (CORE_EVENT(pEvents))
+ other = (InputClients *)wOtherClients(pWin);
+ else if (XI2_EVENT(pEvents))
+ {
+ OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
+ /* Has any client selected for the event? */
+ if (!GetWindowXI2Mask(pDev, pWin, pEvents))
+ return 0;
+ other = inputMasks->inputClients;
+ } else {
+ OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
+ /* Has any client selected for the event? */
+ if (!inputMasks ||
+ !(inputMasks->inputEvents[pDev->id] & filter))
+ return 0;
+
+ other = inputMasks->inputClients;
+ }
+
+ for (; other; other = other->next)
+ {
+ Mask mask;
+ if (IsInterferingGrab(rClient(other), pDev, pEvents))
+ continue;
+
+ mask = GetEventMask(pDev, pEvents, other);
+
+ if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin,
+ pEvents, count))
+ /* do nothing */;
+ else if ( (attempt = TryClientEvents(rClient(other), pDev,
+ pEvents, count,
+ mask, filter, grab)) )
+ {
+ if (attempt > 0)
+ {
+ deliveries++;
+ client = rClient(other);
+ deliveryMask = mask;
+ } else
+ nondeliveries--;
+ }
+ }
+ }
+ /*
+ * Note that since core events are delivered first, an implicit grab may
+ * be activated on a core grab, stopping the XI events.
+ */
+ if ((type == DeviceButtonPress || type == ButtonPress ||
+ ((XI2_EVENT(pEvents) && ((xGenericEvent*)pEvents)->evtype == XI_ButtonPress)))
+ && deliveries
+ && (!grab))
+ {
+ GrabRec tempGrab;
+ OtherInputMasks *inputMasks;
+
+ memset(&tempGrab, 0, sizeof(GrabRec));
+ tempGrab.next = NULL;
+ tempGrab.device = pDev;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.window = pWin;
+ tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
+ tempGrab.eventMask = deliveryMask;
+ tempGrab.keyboardMode = GrabModeAsync;
+ tempGrab.pointerMode = GrabModeAsync;
+ tempGrab.confineTo = NullWindow;
+ tempGrab.cursor = NullCursor;
+ tempGrab.type = type;
+ if (type == ButtonPress)
+ tempGrab.grabtype = GRABTYPE_CORE;
+ else if (type == DeviceButtonPress)
+ tempGrab.grabtype = GRABTYPE_XI;
+ else
+ {
+ tempGrab.type = ((xGenericEvent*)pEvents)->evtype;
+ tempGrab.grabtype = GRABTYPE_XI2;
+ }
+
+ /* get the XI and XI2 device mask */
+ inputMasks = wOtherInputMasks(pWin);
+ tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[pDev->id]: 0;
+
+ if (inputMasks)
+ memcpy(tempGrab.xi2mask, inputMasks->xi2mask,
+ sizeof(tempGrab.xi2mask));
+
+ (*pDev->deviceGrab.ActivateGrab)(pDev, &tempGrab,
+ currentTime, TRUE | ImplicitGrabMask);
+ }
+ else if ((type == MotionNotify) && deliveries)
+ pDev->valuator->motionHintWindow = pWin;
+ else
+ {
+ if ((type == DeviceMotionNotify || type == DeviceButtonPress) &&
+ deliveries)
+ CheckDeviceGrabAndHintWindow (pWin, type,
+ (deviceKeyButtonPointer*) pEvents,
+ grab, client, deliveryMask);
+ }
+ if (deliveries)
+ return deliveries;
+ return nondeliveries;
+}
+
+/* If the event goes to dontClient, don't send it and return 0. if
+ send works, return 1 or if send didn't work, return 2.
+ Only works for core events.
+*/
+
+#ifdef PANORAMIX
+static int
+XineramaTryClientEventsResult(
+ ClientPtr client,
+ GrabPtr grab,
+ Mask mask,
+ Mask filter
+){
+ if ((client) && (client != serverClient) && (!client->clientGone) &&
+ ((filter == CantBeFiltered) || (mask & filter)))
+ {
+ if (grab && !SameClient(grab, client)) return -1;
+ else return 1;
+ }
+ return 0;
+}
+#endif
+
+/**
+ * Try to deliver events to the interested parties.
+ *
+ * @param pWin The window that would get the event.
+ * @param pEvents The events to be delivered.
+ * @param count Number of elements in pEvents.
+ * @param filter Mask based on event type.
+ * @param dontClient Don't deliver to the dontClient.
+ */
+int
+MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents,
+ int count, Mask filter, ClientPtr dontClient)
+{
+ OtherClients *other;
+
+
+ if (pWin->eventMask & filter)
+ {
+ if (wClient(pWin) == dontClient)
+ return 0;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return XineramaTryClientEventsResult(
+ wClient(pWin), NullGrab, pWin->eventMask, filter);
+#endif
+ if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count))
+ return 1; /* don't send, but pretend we did */
+ return TryClientEvents(wClient(pWin), NULL, pEvents, count,
+ pWin->eventMask, filter, NullGrab);
+ }
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (other->mask & filter)
+ {
+ if (SameClient(other, dontClient))
+ return 0;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return XineramaTryClientEventsResult(
+ rClient(other), NullGrab, other->mask, filter);
+#endif
+ if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin, pEvents,
+ count))
+ return 1; /* don't send, but pretend we did */
+ return TryClientEvents(rClient(other), NULL, pEvents, count,
+ other->mask, filter, NullGrab);
+ }
+ }
+ return 2;
+}
+
+static Window FindChildForEvent(DeviceIntPtr dev, WindowPtr event)
+{
+ SpritePtr pSprite = dev->spriteInfo->sprite;
+ WindowPtr w = pSprite->spriteTrace[pSprite->spriteTraceGood-1];
+ Window child = None;
+
+ /* If the search ends up past the root should the child field be
+ set to none or should the value in the argument be passed
+ through. It probably doesn't matter since everyone calls
+ this function with child == None anyway. */
+ while (w)
+ {
+ /* If the source window is same as event window, child should be
+ none. Don't bother going all all the way back to the root. */
+
+ if (w == event)
+ {
+ child = None;
+ break;
+ }
+
+ if (w->parent == event)
+ {
+ child = w->drawable.id;
+ break;
+ }
+ w = w->parent;
+ }
+ return child;
+}
+
+/**
+ * Adjust event fields to comply with the window properties.
+ *
+ * @param xE Event to be modified in place
+ * @param pWin The window to get the information from.
+ * @param child Child window setting for event (if applicable)
+ * @param calcChild If True, calculate the child window.
+ */
+void
+FixUpEventFromWindow(
+ DeviceIntPtr pDev,
+ xEvent *xE,
+ WindowPtr pWin,
+ Window child,
+ Bool calcChild)
+{
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
+ if (calcChild)
+ child = FindChildForEvent(pDev, pWin);
+
+ if (XI2_EVENT(xE))
+ {
+ xXIDeviceEvent* event = (xXIDeviceEvent*)xE;
+
+ if (event->evtype == XI_RawKeyPress ||
+ event->evtype == XI_RawKeyRelease ||
+ event->evtype == XI_RawButtonPress ||
+ event->evtype == XI_RawButtonRelease ||
+ event->evtype == XI_RawMotion ||
+ event->evtype == XI_DeviceChanged ||
+ event->evtype == XI_HierarchyChanged ||
+ event->evtype == XI_PropertyEvent)
+ return;
+
+ event->root = RootWindow(pDev)->drawable.id;
+ event->event = pWin->drawable.id;
+ if (pSprite->hot.pScreen == pWin->drawable.pScreen)
+ {
+ event->event_x = event->root_x - FP1616(pWin->drawable.x, 0);
+ event->event_y = event->root_y - FP1616(pWin->drawable.y, 0);
+ event->child = child;
+ } else
+ {
+ event->event_x = 0;
+ event->event_y = 0;
+ event->child = None;
+ }
+
+ if (event->evtype == XI_Enter || event->evtype == XI_Leave ||
+ event->evtype == XI_FocusIn || event->evtype == XI_FocusOut)
+ ((xXIEnterEvent*)event)->same_screen =
+ (pSprite->hot.pScreen == pWin->drawable.pScreen);
+
+ } else
+ {
+ XE_KBPTR.root = RootWindow(pDev)->drawable.id;
+ XE_KBPTR.event = pWin->drawable.id;
+ if (pSprite->hot.pScreen == pWin->drawable.pScreen)
+ {
+ XE_KBPTR.sameScreen = xTrue;
+ XE_KBPTR.child = child;
+ XE_KBPTR.eventX =
+ XE_KBPTR.rootX - pWin->drawable.x;
+ XE_KBPTR.eventY =
+ XE_KBPTR.rootY - pWin->drawable.y;
+ }
+ else
+ {
+ XE_KBPTR.sameScreen = xFalse;
+ XE_KBPTR.child = None;
+ XE_KBPTR.eventX = 0;
+ XE_KBPTR.eventY = 0;
+ }
+ }
+}
+
+/**
+ * Return masks for EventIsDeliverable.
+ * @defgroup EventIsDeliverable return flags
+ * @{
+ */
+#define XI_MASK (1 << 0) /**< XI mask set on window */
+#define CORE_MASK (1 << 1) /**< Core mask set on window */
+#define DONT_PROPAGATE_MASK (1 << 2) /**< DontPropagate mask set on window */
+#define XI2_MASK (1 << 3) /**< XI2 mask set on window */
+/* @} */
+
+/**
+ * Check if a given event is deliverable at all on a given window.
+ *
+ * This function only checks if any client wants it, not for a specific
+ * client.
+ *
+ * @param[in] dev The device this event is being sent for.
+ * @param[in] event The event that is to be sent.
+ * @param[in] win The current event window.
+ *
+ * @return Bitmask of ::XI2_MASK, ::XI_MASK, ::CORE_MASK, and
+ * ::DONT_PROPAGATE_MASK.
+ */
+static int
+EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win)
+{
+ int rc = 0;
+ int filter = 0;
+ int type;
+ OtherInputMasks *inputMasks = wOtherInputMasks(win);
+ xEvent ev;
+
+ /* XXX: this makes me gag */
+ type = GetXI2Type(event);
+ ev.u.u.type = GenericEvent; /* GetEventFilter only cares about type and evtype*/
+ ((xGenericEvent*)&ev)->extension = IReqCode;
+ ((xGenericEvent*)&ev)->evtype = type;
+ filter = GetEventFilter(dev, &ev);
+ if (type && inputMasks &&
+ ((inputMasks->xi2mask[XIAllDevices][type/8] & filter) ||
+ ((inputMasks->xi2mask[XIAllMasterDevices][type/8] & filter) && IsMaster(dev)) ||
+ (inputMasks->xi2mask[dev->id][type/8] & filter)))
+ rc |= XI2_MASK;
+
+ type = GetXIType(event);
+ ev.u.u.type = type;
+ filter = GetEventFilter(dev, &ev);
+
+ /* Check for XI mask */
+ if (type && inputMasks &&
+ (inputMasks->deliverableEvents[dev->id] & filter) &&
+ (inputMasks->inputEvents[dev->id] & filter))
+ rc |= XI_MASK;
+
+ /* Check for XI DontPropagate mask */
+ if (type && inputMasks &&
+ (inputMasks->dontPropagateMask[dev->id] & filter))
+ rc |= DONT_PROPAGATE_MASK;
+
+ /* Check for core mask */
+ type = GetCoreType(event);
+ if (type && (win->deliverableEvents & filter) &&
+ ((wOtherEventMasks(win) | win->eventMask) & filter))
+ rc |= CORE_MASK;
+
+ /* Check for core DontPropagate mask */
+ if (type && (filter & wDontPropagateMask(win)))
+ rc |= DONT_PROPAGATE_MASK;
+
+ return rc;
+}
+
+/**
+ * Deliver events caused by input devices.
+ *
+ * For events from a non-grabbed, non-focus device, DeliverDeviceEvents is
+ * called directly from the processInputProc.
+ * For grabbed devices, DeliverGrabbedEvent is called first, and _may_ call
+ * DeliverDeviceEvents.
+ * For focused events, DeliverFocusedEvent is called first, and _may_ call
+ * DeliverDeviceEvents.
+ *
+ * @param pWin Window to deliver event to.
+ * @param event The events to deliver, not yet in wire format.
+ * @param grab Possible grab on a device.
+ * @param stopAt Don't recurse up to the root window.
+ * @param dev The device that is responsible for the event.
+ *
+ * @see DeliverGrabbedEvent
+ * @see DeliverFocusedEvent
+ */
+int
+DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
+ WindowPtr stopAt, DeviceIntPtr dev)
+{
+ Window child = None;
+ Mask filter;
+ int deliveries = 0;
+ xEvent core;
+ xEvent *xE = NULL;
+ int rc, mask, count = 0;
+
+ CHECKEVENT(event);
+
+ while (pWin)
+ {
+ if ((mask = EventIsDeliverable(dev, event, pWin)))
+ {
+ /* XI2 events first */
+ if (mask & XI2_MASK)
+ {
+ xEvent *xi2 = NULL;
+ rc = EventToXI2(event, &xi2);
+ if (rc == Success)
+ {
+ /* XXX: XACE */
+ filter = GetEventFilter(dev, xi2);
+ FixUpEventFromWindow(dev, xi2, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(dev, pWin, xi2, 1,
+ filter, grab);
+ xfree(xi2);
+ if (deliveries > 0)
+ goto unwind;
+ } else if (rc != BadMatch)
+ ErrorF("[dix] %s: XI2 conversion failed in DDE (%d).\n",
+ dev->name, rc);
+ }
+
+ /* XI events */
+ if (mask & XI_MASK)
+ {
+ rc = EventToXI(event, &xE, &count);
+ if (rc == Success &&
+ XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count) == Success)
+ {
+ filter = GetEventFilter(dev, xE);
+ FixUpEventFromWindow(dev, xE, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
+ filter, grab);
+ if (deliveries > 0)
+ goto unwind;
+ }
+ }
+
+ /* Core event */
+ if ((mask & CORE_MASK) && IsMaster(dev) && dev->coreEvents)
+ {
+ rc = EventToCore(event, &core);
+ if (rc == Success &&
+ XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, &core, 1) == Success)
+ {
+ filter = GetEventFilter(dev, &core);
+ FixUpEventFromWindow(dev, &core, pWin, child, FALSE);
+ deliveries = DeliverEventsToWindow(dev, pWin, &core, 1,
+ filter, grab);
+ if (deliveries > 0)
+ goto unwind;
+ }
+ }
+
+ if ((deliveries < 0) || (pWin == stopAt) ||
+ (mask & DONT_PROPAGATE_MASK))
+ {
+ deliveries = 0;
+ goto unwind;
+ }
+ }
+
+ child = pWin->drawable.id;
+ pWin = pWin->parent;
+ }
+
+unwind:
+ xfree(xE);
+ return deliveries;
+}
+
+#undef XI_MASK
+#undef CORE_MASK
+#undef DONT_PROPAGATE_MASK
+
+/**
+ * Deliver event to a window and it's immediate parent. Used for most window
+ * events (CreateNotify, ConfigureNotify, etc.). Not useful for events that
+ * propagate up the tree or extension events
+ *
+ * In case of a ReparentNotify event, the event will be delivered to the
+ * otherParent as well.
+ *
+ * @param pWin Window to deliver events to.
+ * @param xE Events to deliver.
+ * @param count number of events in xE.
+ * @param otherParent Used for ReparentNotify events.
+ */
+int
+DeliverEvents(WindowPtr pWin, xEvent *xE, int count,
+ WindowPtr otherParent)
+{
+ Mask filter;
+ int deliveries;
+ DeviceIntRec dummy;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
+ return count;
+#endif
+
+ if (!count)
+ return 0;
+
+ dummy.id = XIAllDevices;
+ filter = GetEventFilter(&dummy, xE);
+ if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
+ xE->u.destroyNotify.event = pWin->drawable.id;
+ if (filter != StructureAndSubMask)
+ return DeliverEventsToWindow(&dummy, pWin, xE, count, filter, NullGrab);
+ deliveries = DeliverEventsToWindow(&dummy, pWin, xE, count,
+ StructureNotifyMask, NullGrab);
+ if (pWin->parent)
+ {
+ xE->u.destroyNotify.event = pWin->parent->drawable.id;
+ deliveries += DeliverEventsToWindow(&dummy, pWin->parent, xE, count,
+ SubstructureNotifyMask, NullGrab);
+ if (xE->u.u.type == ReparentNotify)
+ {
+ xE->u.destroyNotify.event = otherParent->drawable.id;
+ deliveries += DeliverEventsToWindow(&dummy,
+ otherParent, xE, count, SubstructureNotifyMask,
+ NullGrab);
+ }
+ }
+ return deliveries;
+}
+
+
+static Bool
+PointInBorderSize(WindowPtr pWin, int x, int y)
+{
+ BoxRec box;
+ SpritePtr pSprite = inputInfo.pointer->spriteInfo->sprite;
+
+ if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box))
+ return TRUE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension &&
+ XineramaSetWindowPntrs(inputInfo.pointer, pWin)) {
+ int i;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ if(POINT_IN_REGION(pSprite->screen,
+ &pSprite->windows[i]->borderSize,
+ x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x,
+ y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y,
+ &box))
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+/**
+ * Traversed from the root window to the window at the position x/y. While
+ * traversing, it sets up the traversal history in the spriteTrace array.
+ * After completing, the spriteTrace history is set in the following way:
+ * spriteTrace[0] ... root window
+ * spriteTrace[1] ... top level window that encloses x/y
+ * ...
+ * spriteTrace[spriteTraceGood - 1] ... window at x/y
+ *
+ * @returns the window at the given coordinates.
+ */
+static WindowPtr
+XYToWindow(DeviceIntPtr pDev, int x, int y)
+{
+ WindowPtr pWin;
+ BoxRec box;
+ SpritePtr pSprite;
+
+ pSprite = pDev->spriteInfo->sprite;
+ pSprite->spriteTraceGood = 1; /* root window still there */
+ pWin = RootWindow(pDev)->firstChild;
+ while (pWin)
+ {
+ if ((pWin->mapped) &&
+ (x >= pWin->drawable.x - wBorderWidth (pWin)) &&
+ (x < pWin->drawable.x + (int)pWin->drawable.width +
+ wBorderWidth(pWin)) &&
+ (y >= pWin->drawable.y - wBorderWidth (pWin)) &&
+ (y < pWin->drawable.y + (int)pWin->drawable.height +
+ wBorderWidth (pWin))
+ /* When a window is shaped, a further check
+ * is made to see if the point is inside
+ * borderSize
+ */
+ && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box))
+#ifdef ROOTLESS
+ /* In rootless mode windows may be offscreen, even when
+ * they're in X's stack. (E.g. if the native window system
+ * implements some form of virtual desktop system).
+ */
+ && !pWin->rootlessUnhittable
+#endif
+ )
+ {
+ if (pSprite->spriteTraceGood >= pSprite->spriteTraceSize)
+ {
+ pSprite->spriteTraceSize += 10;
+ pSprite->spriteTrace = xrealloc(pSprite->spriteTrace,
+ pSprite->spriteTraceSize*sizeof(WindowPtr));
+ }
+ pSprite->spriteTrace[pSprite->spriteTraceGood++] = pWin;
+ pWin = pWin->firstChild;
+ }
+ else
+ pWin = pWin->nextSib;
+ }
+ return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
+}
+
+/**
+ * Ungrab a currently FocusIn grabbed device and grab the device on the
+ * given window. If the win given is the NoneWin, the device is ungrabbed if
+ * applicable and FALSE is returned.
+ *
+ * @returns TRUE if the device has been grabbed, or FALSE otherwise.
+ */
+BOOL
+ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
+{
+ BOOL rc = FALSE;
+ DeviceEvent event;
+
+ if (dev->deviceGrab.grab &&
+ dev->deviceGrab.fromPassiveGrab &&
+ dev->deviceGrab.grab->type == XI_Enter)
+ {
+ if (dev->deviceGrab.grab->window == win ||
+ IsParent(dev->deviceGrab.grab->window, win))
+ return FALSE;
+ DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab);
+ (*dev->deviceGrab.DeactivateGrab)(dev);
+ }
+
+ if (win == NoneWin || win == PointerRootWin)
+ return FALSE;
+
+ memset(&event, 0, sizeof(DeviceEvent));
+ event.header = ET_Internal;
+ event.type = ET_FocusIn;
+ event.length = sizeof(DeviceEvent);
+ event.time = GetTimeInMillis();
+ event.deviceid = dev->id;
+ event.sourceid = dev->id;
+ event.detail.button = 0;
+ rc = CheckPassiveGrabsOnWindow(win, dev, &event, FALSE);
+ if (rc)
+ DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab);
+ return rc;
+}
+
+/**
+ * Ungrab a currently Enter grabbed device and grab the device for the given
+ * window.
+ *
+ * @returns TRUE if the device has been grabbed, or FALSE otherwise.
+ */
+static BOOL
+ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
+{
+ BOOL rc = FALSE;
+ DeviceEvent event;
+
+ if (dev->deviceGrab.grab &&
+ dev->deviceGrab.fromPassiveGrab &&
+ dev->deviceGrab.grab->type == XI_Enter)
+ {
+ if (dev->deviceGrab.grab->window == win ||
+ IsParent(dev->deviceGrab.grab->window, win))
+ return FALSE;
+ DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab);
+ (*dev->deviceGrab.DeactivateGrab)(dev);
+ }
+
+ memset(&event, 0, sizeof(DeviceEvent));
+ event.header = ET_Internal;
+ event.type = ET_Enter;
+ event.length = sizeof(DeviceEvent);
+ event.time = GetTimeInMillis();
+ event.deviceid = dev->id;
+ event.sourceid = dev->id;
+ event.detail.button = 0;
+ rc = CheckPassiveGrabsOnWindow(win, dev, &event, FALSE);
+ if (rc)
+ DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab);
+
+ return rc;
+}
+
+/**
+ * Update the sprite coordinates based on the event. Update the cursor
+ * position, then update the event with the new coordinates that may have been
+ * changed. If the window underneath the sprite has changed, change to new
+ * cursor and send enter/leave events.
+ *
+ * CheckMotion() will not do anything and return FALSE if the event is not a
+ * pointer event.
+ *
+ * @return TRUE if the sprite has moved or FALSE otherwise.
+ */
+Bool
+CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
+{
+ WindowPtr prevSpriteWin, newSpriteWin;
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
+ CHECKEVENT(ev);
+
+ prevSpriteWin = pSprite->win;
+
+ if (ev && !syncEvents.playingEvents)
+ {
+ /* GetPointerEvents() guarantees that pointer events have the correct
+ rootX/Y set already. */
+ switch (ev->type)
+ {
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_Motion:
+ break;
+ default:
+ /* all other events return FALSE */
+ return FALSE;
+ }
+
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ {
+ /* Motion events entering DIX get translated to Screen 0
+ coordinates. Replayed events have already been
+ translated since they've entered DIX before */
+ ev->root_x += panoramiXdataPtr[pSprite->screen->myNum].x -
+ panoramiXdataPtr[0].x;
+ ev->root_y += panoramiXdataPtr[pSprite->screen->myNum].y -
+ panoramiXdataPtr[0].y;
+ } else
+#endif
+ {
+ if (pSprite->hot.pScreen != pSprite->hotPhys.pScreen)
+ {
+ pSprite->hot.pScreen = pSprite->hotPhys.pScreen;
+ RootWindow(pDev) = WindowTable[pSprite->hot.pScreen->myNum];
+ }
+ }
+
+ pSprite->hot.x = ev->root_x;
+ pSprite->hot.y = ev->root_y;
+ if (pSprite->hot.x < pSprite->physLimits.x1)
+ pSprite->hot.x = pSprite->physLimits.x1;
+ else if (pSprite->hot.x >= pSprite->physLimits.x2)
+ pSprite->hot.x = pSprite->physLimits.x2 - 1;
+ if (pSprite->hot.y < pSprite->physLimits.y1)
+ pSprite->hot.y = pSprite->physLimits.y1;
+ else if (pSprite->hot.y >= pSprite->physLimits.y2)
+ pSprite->hot.y = pSprite->physLimits.y2 - 1;
+ if (pSprite->hotShape)
+ ConfineToShape(pDev, pSprite->hotShape, &pSprite->hot.x, &pSprite->hot.y);
+ pSprite->hotPhys = pSprite->hot;
+
+ if ((pSprite->hotPhys.x != ev->root_x) ||
+ (pSprite->hotPhys.y != ev->root_y))
+ {
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension)
+ {
+ XineramaSetCursorPosition(
+ pDev, pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE);
+ } else
+#endif
+ {
+ (*pSprite->hotPhys.pScreen->SetCursorPosition)(
+ pDev, pSprite->hotPhys.pScreen,
+ pSprite->hotPhys.x, pSprite->hotPhys.y, FALSE);
+ }
+ }
+
+ ev->root_x = pSprite->hot.x;
+ ev->root_y = pSprite->hot.y;
+ }
+
+ newSpriteWin = XYToWindow(pDev, pSprite->hot.x, pSprite->hot.y);
+
+ if (newSpriteWin != prevSpriteWin)
+ {
+ int sourceid;
+ if (!ev) {
+ UpdateCurrentTimeIf();
+ sourceid = pDev->id; /* when from WindowsRestructured */
+ } else
+ sourceid = ev->sourceid;
+
+ if (prevSpriteWin != NullWindow) {
+ if (!ActivateEnterGrab(pDev, prevSpriteWin, newSpriteWin))
+ DoEnterLeaveEvents(pDev, sourceid, prevSpriteWin,
+ newSpriteWin, NotifyNormal);
+ }
+ /* set pSprite->win after ActivateEnterGrab, otherwise
+ sprite window == grab_window and no enter/leave events are
+ sent. */
+ pSprite->win = newSpriteWin;
+ PostNewCursor(pDev);
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/**
+ * Windows have restructured, we need to update the sprite position and the
+ * sprite's cursor.
+ */
+void
+WindowsRestructured(void)
+{
+ DeviceIntPtr pDev = inputInfo.devices;
+ while(pDev)
+ {
+ if (IsMaster(pDev) || !pDev->u.master)
+ CheckMotion(NULL, pDev);
+ pDev = pDev->next;
+ }
+}
+
+#ifdef PANORAMIX
+/* This was added to support reconfiguration under Xdmx. The problem is
+ * that if the 0th screen (i.e., WindowTable[0]) is moved to an origin
+ * other than 0,0, the information in the private sprite structure must
+ * be updated accordingly, or XYToWindow (and other routines) will not
+ * compute correctly. */
+void ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
+{
+ GrabPtr grab;
+ DeviceIntPtr pDev;
+ SpritePtr pSprite;
+
+ if (noPanoramiXExtension) return;
+
+ pDev = inputInfo.devices;
+ while(pDev)
+ {
+ if (DevHasCursor(pDev))
+ {
+ pSprite = pDev->spriteInfo->sprite;
+ pSprite->hot.x -= xoff;
+ pSprite->hot.y -= yoff;
+
+ pSprite->hotPhys.x -= xoff;
+ pSprite->hotPhys.y -= yoff;
+
+ pSprite->hotLimits.x1 -= xoff;
+ pSprite->hotLimits.y1 -= yoff;
+ pSprite->hotLimits.x2 -= xoff;
+ pSprite->hotLimits.y2 -= yoff;
+
+ if (REGION_NOTEMPTY(pSprite->screen, &pSprite->Reg1))
+ REGION_TRANSLATE(pSprite->screen, &pSprite->Reg1, xoff, yoff);
+ if (REGION_NOTEMPTY(pSprite->screen, &pSprite->Reg2))
+ REGION_TRANSLATE(pSprite->screen, &pSprite->Reg2, xoff, yoff);
+
+ /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */
+ if ((grab = pDev->deviceGrab.grab) && grab->confineTo) {
+ if (grab->confineTo->drawable.pScreen
+ != pSprite->hotPhys.pScreen)
+ pSprite->hotPhys.x = pSprite->hotPhys.y = 0;
+ ConfineCursorToWindow(pDev, grab->confineTo, TRUE, TRUE);
+ } else
+ ConfineCursorToWindow(
+ pDev,
+ WindowTable[pSprite->hotPhys.pScreen->myNum],
+ TRUE, FALSE);
+
+ }
+ pDev = pDev->next;
+ }
+}
+#endif
+
+/**
+ * Initialize a sprite for the given device and set it to some sane values. If
+ * the device already has a sprite alloc'd, don't realloc but just reset to
+ * default values.
+ * If a window is supplied, the sprite will be initialized with the window's
+ * cursor and positioned in the center of the window's screen. The root window
+ * is a good choice to pass in here.
+ *
+ * It's a good idea to call it only for pointer devices, unless you have a
+ * really talented keyboard.
+ *
+ * @param pDev The device to initialize.
+ * @param pWin The window where to generate the sprite in.
+ *
+ */
+void
+InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin)
+{
+ SpritePtr pSprite;
+ ScreenPtr pScreen;
+
+ if (!pDev->spriteInfo->sprite)
+ {
+ DeviceIntPtr it;
+
+ pDev->spriteInfo->sprite = (SpritePtr)xcalloc(1, sizeof(SpriteRec));
+ if (!pDev->spriteInfo->sprite)
+ FatalError("InitializeSprite: failed to allocate sprite struct");
+
+ /* We may have paired another device with this device before our
+ * device had a actual sprite. We need to check for this and reset the
+ * sprite field for all paired devices.
+ *
+ * The VCK is always paired with the VCP before the VCP has a sprite.
+ */
+ for (it = inputInfo.devices; it; it = it->next)
+ {
+ if (it->spriteInfo->paired == pDev)
+ it->spriteInfo->sprite = pDev->spriteInfo->sprite;
+ }
+ if (inputInfo.keyboard->spriteInfo->paired == pDev)
+ inputInfo.keyboard->spriteInfo->sprite = pDev->spriteInfo->sprite;
+ }
+
+ pSprite = pDev->spriteInfo->sprite;
+ pDev->spriteInfo->spriteOwner = TRUE;
+
+ pScreen = (pWin) ? pWin->drawable.pScreen : (ScreenPtr)NULL;
+ pSprite->hot.pScreen = pScreen;
+ pSprite->hotPhys.pScreen = pScreen;
+ if (pScreen)
+ {
+ pSprite->hotPhys.x = pScreen->width / 2;
+ pSprite->hotPhys.y = pScreen->height / 2;
+ pSprite->hotLimits.x2 = pScreen->width;
+ pSprite->hotLimits.y2 = pScreen->height;
+ }
+
+ pSprite->hot = pSprite->hotPhys;
+ pSprite->win = pWin;
+
+ if (pWin)
+ {
+ pSprite->current = wCursor(pWin);
+ pSprite->current->refcnt++;
+ pSprite->spriteTrace = (WindowPtr *)xcalloc(1, 32*sizeof(WindowPtr));
+ if (!pSprite->spriteTrace)
+ FatalError("Failed to allocate spriteTrace");
+ pSprite->spriteTraceSize = 32;
+
+ RootWindow(pDev) = pWin;
+ pSprite->spriteTraceGood = 1;
+
+ pSprite->pEnqueueScreen = pScreen;
+ pSprite->pDequeueScreen = pSprite->pEnqueueScreen;
+
+ } else {
+ pSprite->current = NullCursor;
+ pSprite->spriteTrace = NULL;
+ pSprite->spriteTraceSize = 0;
+ pSprite->spriteTraceGood = 0;
+ pSprite->pEnqueueScreen = screenInfo.screens[0];
+ pSprite->pDequeueScreen = pSprite->pEnqueueScreen;
+ }
+
+ if (pScreen)
+ {
+ (*pScreen->RealizeCursor) ( pDev, pScreen, pSprite->current);
+ (*pScreen->CursorLimits) ( pDev, pScreen, pSprite->current,
+ &pSprite->hotLimits, &pSprite->physLimits);
+ pSprite->confined = FALSE;
+
+ (*pScreen->ConstrainCursor) (pDev, pScreen,
+ &pSprite->physLimits);
+ (*pScreen->SetCursorPosition) (pDev, pScreen, pSprite->hot.x,
+ pSprite->hot.y,
+ FALSE);
+ (*pScreen->DisplayCursor) (pDev, pScreen, pSprite->current);
+ }
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ pSprite->hotLimits.x1 = -panoramiXdataPtr[0].x;
+ pSprite->hotLimits.y1 = -panoramiXdataPtr[0].y;
+ pSprite->hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x;
+ pSprite->hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+ pSprite->physLimits = pSprite->hotLimits;
+ pSprite->confineWin = NullWindow;
+ pSprite->hotShape = NullRegion;
+ pSprite->screen = pScreen;
+ /* gotta UNINIT these someplace */
+ REGION_NULL(pScreen, &pSprite->Reg1);
+ REGION_NULL(pScreen, &pSprite->Reg2);
+ }
+#endif
+}
+
+/**
+ * Update the mouse sprite info when the server switches from a pScreen to another.
+ * Otherwise, the pScreen of the mouse sprite is never updated when we switch
+ * from a pScreen to another. Never updating the pScreen of the mouse sprite
+ * implies that windows that are in pScreen whose pScreen->myNum >0 will never
+ * get pointer events. This is because in CheckMotion(), sprite.hotPhys.pScreen
+ * always points to the first pScreen it has been set by
+ * DefineInitialRootWindow().
+ *
+ * Calling this function is useful for use cases where the server
+ * has more than one pScreen.
+ * This function is similar to DefineInitialRootWindow() but it does not
+ * reset the mouse pointer position.
+ * @param win must be the new pScreen we are switching to.
+ */
+void
+UpdateSpriteForScreen(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+ SpritePtr pSprite = NULL;
+ WindowPtr win = NULL;
+ if (!pScreen)
+ return ;
+
+ if (!pDev->spriteInfo->sprite)
+ return;
+
+ pSprite = pDev->spriteInfo->sprite;
+
+ win = WindowTable[pScreen->myNum];
+
+ pSprite->hotPhys.pScreen = pScreen;
+ pSprite->hot = pSprite->hotPhys;
+ pSprite->hotLimits.x2 = pScreen->width;
+ pSprite->hotLimits.y2 = pScreen->height;
+ pSprite->win = win;
+ pSprite->current = wCursor (win);
+ pSprite->current->refcnt++;
+ pSprite->spriteTraceGood = 1;
+ pSprite->spriteTrace[0] = win;
+ (*pScreen->CursorLimits) (pDev,
+ pScreen,
+ pSprite->current,
+ &pSprite->hotLimits,
+ &pSprite->physLimits);
+ pSprite->confined = FALSE;
+ (*pScreen->ConstrainCursor) (pDev, pScreen, &pSprite->physLimits);
+ (*pScreen->DisplayCursor) (pDev, pScreen, pSprite->current);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ pSprite->hotLimits.x1 = -panoramiXdataPtr[0].x;
+ pSprite->hotLimits.y1 = -panoramiXdataPtr[0].y;
+ pSprite->hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x;
+ pSprite->hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
+ pSprite->physLimits = pSprite->hotLimits;
+ pSprite->screen = pScreen;
+ }
+#endif
+}
+
+/*
+ * This does not take any shortcuts, and even ignores its argument, since
+ * it does not happen very often, and one has to walk up the tree since
+ * this might be a newly instantiated cursor for an intermediate window
+ * between the one the pointer is in and the one that the last cursor was
+ * instantiated from.
+ */
+void
+WindowHasNewCursor(WindowPtr pWin)
+{
+ DeviceIntPtr pDev;
+
+ for(pDev = inputInfo.devices; pDev; pDev = pDev->next)
+ if (DevHasCursor(pDev))
+ PostNewCursor(pDev);
+}
+
+void
+NewCurrentScreen(DeviceIntPtr pDev, ScreenPtr newScreen, int x, int y)
+{
+ SpritePtr pSprite = pDev->spriteInfo->sprite;
+
+ pSprite->hotPhys.x = x;
+ pSprite->hotPhys.y = y;
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ pSprite->hotPhys.x += panoramiXdataPtr[newScreen->myNum].x -
+ panoramiXdataPtr[0].x;
+ pSprite->hotPhys.y += panoramiXdataPtr[newScreen->myNum].y -
+ panoramiXdataPtr[0].y;
+ if (newScreen != pSprite->screen) {
+ pSprite->screen = newScreen;
+ /* Make sure we tell the DDX to update its copy of the screen */
+ if(pSprite->confineWin)
+ XineramaConfineCursorToWindow(pDev,
+ pSprite->confineWin, TRUE);
+ else
+ XineramaConfineCursorToWindow(pDev, WindowTable[0], TRUE);
+ /* if the pointer wasn't confined, the DDX won't get
+ told of the pointer warp so we reposition it here */
+ if(!syncEvents.playingEvents)
+ (*pSprite->screen->SetCursorPosition)(
+ pDev,
+ pSprite->screen,
+ pSprite->hotPhys.x + panoramiXdataPtr[0].x -
+ panoramiXdataPtr[pSprite->screen->myNum].x,
+ pSprite->hotPhys.y + panoramiXdataPtr[0].y -
+ panoramiXdataPtr[pSprite->screen->myNum].y, FALSE);
+ }
+ } else
+#endif
+ if (newScreen != pSprite->hotPhys.pScreen)
+ ConfineCursorToWindow(pDev, WindowTable[newScreen->myNum],
+ TRUE, FALSE);
+}
+
+#ifdef PANORAMIX
+
+static Bool
+XineramaPointInWindowIsVisible(
+ WindowPtr pWin,
+ int x,
+ int y
+)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ BoxRec box;
+ int i, xoff, yoff;
+
+ if (!pWin->realized) return FALSE;
+
+ if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
+ return TRUE;
+
+ if(!XineramaSetWindowPntrs(inputInfo.pointer, pWin)) return FALSE;
+
+ xoff = x + panoramiXdataPtr[0].x;
+ yoff = y + panoramiXdataPtr[0].y;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ pWin = inputInfo.pointer->spriteInfo->sprite->windows[i];
+ pScreen = pWin->drawable.pScreen;
+ x = xoff - panoramiXdataPtr[i].x;
+ y = yoff - panoramiXdataPtr[i].y;
+
+ if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box)
+ && (!wInputShape(pWin) ||
+ POINT_IN_REGION(pWin->drawable.pScreen,
+ wInputShape(pWin),
+ x - pWin->drawable.x,
+ y - pWin->drawable.y, &box)))
+ return TRUE;
+
+ }
+
+ return FALSE;
+}
+
+static int
+XineramaWarpPointer(ClientPtr client)
+{
+ WindowPtr dest = NULL;
+ int x, y, rc;
+ SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite;
+
+ REQUEST(xWarpPointerReq);
+
+
+ if (stuff->dstWid != None) {
+ rc = dixLookupWindow(&dest, stuff->dstWid, client, DixReadAccess);
+ if (rc != Success)
+ return rc;
+ }
+ x = pSprite->hotPhys.x;
+ y = pSprite->hotPhys.y;
+
+ if (stuff->srcWid != None)
+ {
+ int winX, winY;
+ XID winID = stuff->srcWid;
+ WindowPtr source;
+
+ rc = dixLookupWindow(&source, winID, client, DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ winX = source->drawable.x;
+ winY = source->drawable.y;
+ if(source == WindowTable[0]) {
+ winX -= panoramiXdataPtr[0].x;
+ winY -= panoramiXdataPtr[0].y;
+ }
+ if (x < winX + stuff->srcX ||
+ y < winY + stuff->srcY ||
+ (stuff->srcWidth != 0 &&
+ winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+ (stuff->srcHeight != 0 &&
+ winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+ !XineramaPointInWindowIsVisible(source, x, y))
+ return Success;
+ }
+ if (dest) {
+ x = dest->drawable.x;
+ y = dest->drawable.y;
+ if(dest == WindowTable[0]) {
+ x -= panoramiXdataPtr[0].x;
+ y -= panoramiXdataPtr[0].y;
+ }
+ }
+
+ x += stuff->dstX;
+ y += stuff->dstY;
+
+ if (x < pSprite->physLimits.x1)
+ x = pSprite->physLimits.x1;
+ else if (x >= pSprite->physLimits.x2)
+ x = pSprite->physLimits.x2 - 1;
+ if (y < pSprite->physLimits.y1)
+ y = pSprite->physLimits.y1;
+ else if (y >= pSprite->physLimits.y2)
+ y = pSprite->physLimits.y2 - 1;
+ if (pSprite->hotShape)
+ ConfineToShape(PickPointer(client), pSprite->hotShape, &x, &y);
+
+ XineramaSetCursorPosition(PickPointer(client), x, y, TRUE);
+
+ return Success;
+}
+
+#endif
+
+
+/**
+ * Server-side protocol handling for WarpPointer request.
+ * Warps the cursor position to the coordinates given in the request.
+ */
+int
+ProcWarpPointer(ClientPtr client)
+{
+ WindowPtr dest = NULL;
+ int x, y, rc;
+ ScreenPtr newScreen;
+ DeviceIntPtr dev, tmp;
+ SpritePtr pSprite;
+
+ REQUEST(xWarpPointerReq);
+ REQUEST_SIZE_MATCH(xWarpPointerReq);
+
+ dev = PickPointer(client);
+
+ for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
+ if ((tmp == dev) || (!IsMaster(tmp) && tmp->u.master == dev)) {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixWriteAccess);
+ if (rc != Success)
+ return rc;
+ }
+ }
+
+ if (dev->u.lastSlave)
+ dev = dev->u.lastSlave;
+ pSprite = dev->spriteInfo->sprite;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ return XineramaWarpPointer(client);
+#endif
+
+ if (stuff->dstWid != None) {
+ rc = dixLookupWindow(&dest, stuff->dstWid, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ }
+ x = pSprite->hotPhys.x;
+ y = pSprite->hotPhys.y;
+
+ if (stuff->srcWid != None)
+ {
+ int winX, winY;
+ XID winID = stuff->srcWid;
+ WindowPtr source;
+
+ rc = dixLookupWindow(&source, winID, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ winX = source->drawable.x;
+ winY = source->drawable.y;
+ if (source->drawable.pScreen != pSprite->hotPhys.pScreen ||
+ x < winX + stuff->srcX ||
+ y < winY + stuff->srcY ||
+ (stuff->srcWidth != 0 &&
+ winX + stuff->srcX + (int)stuff->srcWidth < x) ||
+ (stuff->srcHeight != 0 &&
+ winY + stuff->srcY + (int)stuff->srcHeight < y) ||
+ !PointInWindowIsVisible(source, x, y))
+ return Success;
+ }
+ if (dest)
+ {
+ x = dest->drawable.x;
+ y = dest->drawable.y;
+ newScreen = dest->drawable.pScreen;
+ } else
+ newScreen = pSprite->hotPhys.pScreen;
+
+ x += stuff->dstX;
+ y += stuff->dstY;
+
+ if (x < 0)
+ x = 0;
+ else if (x >= newScreen->width)
+ x = newScreen->width - 1;
+ if (y < 0)
+ y = 0;
+ else if (y >= newScreen->height)
+ y = newScreen->height - 1;
+
+ if (newScreen == pSprite->hotPhys.pScreen)
+ {
+ if (x < pSprite->physLimits.x1)
+ x = pSprite->physLimits.x1;
+ else if (x >= pSprite->physLimits.x2)
+ x = pSprite->physLimits.x2 - 1;
+ if (y < pSprite->physLimits.y1)
+ y = pSprite->physLimits.y1;
+ else if (y >= pSprite->physLimits.y2)
+ y = pSprite->physLimits.y2 - 1;
+ if (pSprite->hotShape)
+ ConfineToShape(dev, pSprite->hotShape, &x, &y);
+ (*newScreen->SetCursorPosition)(dev, newScreen, x, y, TRUE);
+ }
+ else if (!PointerConfinedToScreen(dev))
+ {
+ NewCurrentScreen(dev, newScreen, x, y);
+ }
+ return Success;
+}
+
+static Bool
+BorderSizeNotEmpty(DeviceIntPtr pDev, WindowPtr pWin)
+{
+ if(REGION_NOTEMPTY(pDev->spriteInfo->sprite->hotPhys.pScreen, &pWin->borderSize))
+ return TRUE;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && XineramaSetWindowPntrs(pDev, pWin)) {
+ int i;
+
+ for(i = 1; i < PanoramiXNumScreens; i++) {
+ if(REGION_NOTEMPTY(pDev->spriteInfo->sprite->screen,
+ &pDev->spriteInfo->sprite->windows[i]->borderSize))
+ return TRUE;
+ }
+ }
+#endif
+ return FALSE;
+}
+
+/**
+ * "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
+ * passive grab set on the window to be activated.
+ * If a passive grab is activated, the event will be delivered to the client.
+ *
+ * @param pWin The window that may be subject to a passive grab.
+ * @param device Device that caused the event.
+ * @param event The current device event.
+ * @param checkCore Check for core grabs too.
+ */
+
+static Bool
+CheckPassiveGrabsOnWindow(
+ WindowPtr pWin,
+ DeviceIntPtr device,
+ DeviceEvent *event,
+ BOOL checkCore)
+{
+ GrabPtr grab = wPassiveGrabs(pWin);
+ GrabRec tempGrab;
+ GrabInfoPtr grabinfo;
+#define CORE_MATCH 0x1
+#define XI_MATCH 0x2
+#define XI2_MATCH 0x4
+ int match = 0;
+
+ if (device->deviceGrab.grab)
+ return FALSE;
+
+ if (!grab)
+ return FALSE;
+ /* Fill out the grab details, but leave the type for later before
+ * comparing */
+ tempGrab.window = pWin;
+ tempGrab.device = device;
+ tempGrab.detail.exact = event->detail.key;
+ tempGrab.detail.pMask = NULL;
+ tempGrab.modifiersDetail.pMask = NULL;
+ tempGrab.next = NULL;
+ for (; grab; grab = grab->next)
+ {
+ DeviceIntPtr gdev;
+ XkbSrvInfoPtr xkbi = NULL;
+ Mask mask = 0;
+
+ gdev= grab->modifierDevice;
+ if (grab->grabtype == GRABTYPE_CORE)
+ {
+ if (IsPointerDevice(device))
+ gdev = GetPairedDevice(device);
+ else
+ gdev = device;
+ } else if (grab->grabtype == GRABTYPE_XI2)
+ {
+ /* if the device is an attached slave device, gdev must be the
+ * attached master keyboard. Since the slave may have been
+ * reattached after the grab, the modifier device may not be the
+ * same. */
+ if (!IsMaster(grab->device) && device->u.master)
+ gdev = GetMaster(device, MASTER_KEYBOARD);
+ }
+
+
+ if (gdev && gdev->key)
+ xkbi= gdev->key->xkbInfo;
+ tempGrab.modifierDevice = grab->modifierDevice;
+ tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
+
+ /* Check for XI2 and XI grabs first */
+ tempGrab.type = GetXI2Type((InternalEvent*)event);
+ tempGrab.grabtype = GRABTYPE_XI2;
+ if (GrabMatchesSecond(&tempGrab, grab, FALSE))
+ match = XI2_MATCH;
+
+ tempGrab.detail.exact = event->detail.key;
+ if (!match)
+ {
+ tempGrab.type = GetXIType((InternalEvent*)event);
+ tempGrab.grabtype = GRABTYPE_XI;
+ if (GrabMatchesSecond(&tempGrab, grab, FALSE))
+ match = XI_MATCH;
+ }
+
+ /* Check for a core grab (ignore the device when comparing) */
+ if (!match && checkCore)
+ {
+ tempGrab.grabtype = GRABTYPE_CORE;
+ if ((tempGrab.type = GetCoreType((InternalEvent*)event)) &&
+ (GrabMatchesSecond(&tempGrab, grab, TRUE)))
+ match = CORE_MATCH;
+ }
+
+ if (match && (!grab->confineTo ||
+ (grab->confineTo->realized &&
+ BorderSizeNotEmpty(device, grab->confineTo))))
+ {
+ int rc, count = 0;
+ xEvent *xE = NULL;
+ xEvent core;
+
+ event->corestate &= 0x1f00;
+ event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00);
+ grabinfo = &device->deviceGrab;
+ /* In some cases a passive core grab may exist, but the client
+ * already has a core grab on some other device. In this case we
+ * must not get the grab, otherwise we may never ungrab the
+ * device.
+ */
+
+ if (grab->grabtype == GRABTYPE_CORE)
+ {
+ DeviceIntPtr other;
+ BOOL interfering = FALSE;
+
+ /* A passive grab may have been created for a different device
+ than it is assigned to at this point in time.
+ Update the grab's device and modifier device to reflect the
+ current state.
+ Since XGrabDeviceButton requires to specify the
+ modifierDevice explicitly, we don't override this choice.
+ */
+ if (tempGrab.type < GenericEvent)
+ {
+ grab->device = device;
+ grab->modifierDevice = GetPairedDevice(device);
+ }
+
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ GrabPtr othergrab = other->deviceGrab.grab;
+ if (othergrab && othergrab->grabtype == GRABTYPE_CORE &&
+ SameClient(grab, rClient(othergrab)) &&
+ ((IsPointerDevice(grab->device) &&
+ IsPointerDevice(othergrab->device)) ||
+ (IsKeyboardDevice(grab->device) &&
+ IsKeyboardDevice(othergrab->device))))
+ {
+ interfering = TRUE;
+ break;
+ }
+ }
+ if (interfering)
+ continue;
+ }
+
+
+ if (match & CORE_MATCH)
+ {
+ rc = EventToCore((InternalEvent*)event, &core);
+ if (rc != Success)
+ {
+ if (rc != BadMatch)
+ ErrorF("[dix] %s: core conversion failed in CPGFW "
+ "(%d, %d).\n", device->name, event->type, rc);
+ continue;
+ }
+ xE = &core;
+ count = 1;
+ mask = grab->eventMask;
+ } else if (match & XI2_MATCH)
+ {
+ rc = EventToXI2((InternalEvent*)event, &xE);
+ if (rc != Success)
+ {
+ if (rc != BadMatch)
+ ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
+ "(%d, %d).\n", device->name, event->type, rc);
+ continue;
+ }
+ count = 1;
+
+ /* FIXME: EventToXI2 returns NULL for enter events, so
+ * dereferencing the event is bad. Internal event types are
+ * aligned with core events, so the else clause is valid.
+ * long-term we should use internal events for enter/focus
+ * as well */
+ if (xE)
+ mask = grab->xi2mask[device->id][((xGenericEvent*)xE)->evtype/8];
+ else if (event->type == XI_Enter || event->type == XI_FocusIn)
+ mask = grab->xi2mask[device->id][event->type/8];
+ } else
+ {
+ rc = EventToXI((InternalEvent*)event, &xE, &count);
+ if (rc != Success)
+ {
+ if (rc != BadMatch)
+ ErrorF("[dix] %s: XI conversion failed in CPGFW "
+ "(%d, %d).\n", device->name, event->type, rc);
+ continue;
+ }
+ mask = grab->eventMask;
+ }
+
+ (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
+
+ if (xE)
+ {
+ FixUpEventFromWindow(device, xE, grab->window, None, TRUE);
+
+ TryClientEvents(rClient(grab), device, xE, count, mask,
+ GetEventFilter(device, xE), grab);
+ }
+
+ if (grabinfo->sync.state == FROZEN_NO_EVENT)
+ {
+ if (!grabinfo->sync.event)
+ grabinfo->sync.event = xcalloc(1, sizeof(InternalEvent));
+ *grabinfo->sync.event = *event;
+ grabinfo->sync.state = FROZEN_WITH_EVENT;
+ }
+
+ if (match & (XI_MATCH | XI2_MATCH))
+ xfree(xE); /* on core match xE == &core */
+ return TRUE;
+ }
+ }
+ return FALSE;
+#undef CORE_MATCH
+#undef XI_MATCH
+#undef XI2_MATCH
+}
+
+/**
+ * CheckDeviceGrabs handles both keyboard and pointer events that may cause
+ * a passive grab to be activated.
+ *
+ * If the event is a keyboard event, the ancestors of the focus window are
+ * traced down and tried to see if they have any passive grabs to be
+ * activated. If the focus window itself is reached and it's descendants
+ * contain the pointer, the ancestors of the window that the pointer is in
+ * are then traced down starting at the focus window, otherwise no grabs are
+ * activated.
+ * If the event is a pointer event, the ancestors of the window that the
+ * pointer is in are traced down starting at the root until CheckPassiveGrabs
+ * causes a passive grab to activate or all the windows are
+ * tried. PRH
+ *
+ * If a grab is activated, the event has been sent to the client already!
+ *
+ * The event we pass in must always be an XI event. From this, we then emulate
+ * the core event and then check for grabs.
+ *
+ * @param device The device that caused the event.
+ * @param xE The event to handle (Device{Button|Key}Press).
+ * @param count Number of events in list.
+ * @return TRUE if a grab has been activated or false otherwise.
+*/
+
+Bool
+CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, int checkFirst)
+{
+ int i;
+ WindowPtr pWin = NULL;
+ FocusClassPtr focus = IsPointerEvent((InternalEvent*)event) ? NULL : device->focus;
+ BOOL sendCore = (IsMaster(device) && device->coreEvents);
+
+ if (event->type != ET_ButtonPress &&
+ event->type != ET_KeyPress)
+ return FALSE;
+
+ if (event->type == ET_ButtonPress
+ && (device->button->buttonsDown != 1))
+ return FALSE;
+
+ i = checkFirst;
+
+ if (focus)
+ {
+ for (; i < focus->traceGood; i++)
+ {
+ pWin = focus->trace[i];
+ if (pWin->optional &&
+ CheckPassiveGrabsOnWindow(pWin, device, event, sendCore))
+ return TRUE;
+ }
+
+ if ((focus->win == NoneWin) ||
+ (i >= device->spriteInfo->sprite->spriteTraceGood) ||
+ ((i > checkFirst) &&
+ (pWin != device->spriteInfo->sprite->spriteTrace[i-1])))
+ return FALSE;
+ }
+
+ for (; i < device->spriteInfo->sprite->spriteTraceGood; i++)
+ {
+ pWin = device->spriteInfo->sprite->spriteTrace[i];
+ if (pWin->optional &&
+ CheckPassiveGrabsOnWindow(pWin, device, event, sendCore))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * Called for keyboard events to deliver event to whatever client owns the
+ * focus.
+ *
+ * The event is delivered to the keyboard's focus window, the root window or
+ * to the window owning the input focus.
+ *
+ * @param keybd The keyboard originating the event.
+ * @param event The event, not yet in wire format.
+ * @param window Window underneath the sprite.
+ */
+void
+DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
+{
+ DeviceIntPtr ptr;
+ WindowPtr focus = keybd->focus->win;
+ BOOL sendCore = (IsMaster(keybd) && keybd->coreEvents);
+ xEvent core;
+ xEvent *xE = NULL, *xi2 = NULL;
+ int count, rc;
+ int deliveries = 0;
+
+ if (focus == FollowKeyboardWin)
+ focus = inputInfo.keyboard->focus->win;
+ if (!focus)
+ return;
+ if (focus == PointerRootWin)
+ {
+ DeliverDeviceEvents(window, event, NullGrab, NullWindow, keybd);
+ return;
+ }
+ if ((focus == window) || IsParent(focus, window))
+ {
+ if (DeliverDeviceEvents(window, event, NullGrab, focus, keybd))
+ return;
+ }
+
+ /* just deliver it to the focus window */
+ ptr = GetPairedDevice(keybd);
+
+
+ rc = EventToXI2(event, &xi2);
+ if (rc == Success)
+ {
+ /* XXX: XACE */
+ int filter = GetEventFilter(keybd, xi2);
+ FixUpEventFromWindow(ptr, xi2, focus, None, FALSE);
+ deliveries = DeliverEventsToWindow(keybd, focus, xi2, 1,
+ filter, NullGrab);
+ if (deliveries > 0)
+ goto unwind;
+ } else if (rc != BadMatch)
+ ErrorF("[dix] %s: XI2 conversion failed in DFE (%d, %d). Skipping delivery.\n",
+ keybd->name, event->any.type, rc);
+
+ rc = EventToXI(event, &xE, &count);
+ if (rc == Success &&
+ XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count) == Success)
+ {
+ FixUpEventFromWindow(ptr, xE, focus, None, FALSE);
+ deliveries = DeliverEventsToWindow(keybd, focus, xE, count,
+ GetEventFilter(keybd, xE),
+ NullGrab);
+
+ if (deliveries > 0)
+ goto unwind;
+ } else if (rc != BadMatch)
+ ErrorF("[dix] %s: XI conversion failed in DFE (%d, %d). Skipping delivery.\n",
+ keybd->name, event->any.type, rc);
+
+ if (sendCore)
+ {
+ rc = EventToCore(event, &core);
+ if (rc == Success &&
+ XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, &core, 1) == Success)
+ {
+ FixUpEventFromWindow(keybd, &core, focus, None, FALSE);
+ deliveries = DeliverEventsToWindow(keybd, focus, &core, 1,
+ GetEventFilter(keybd, &core),
+ NullGrab);
+ }
+ }
+
+unwind:
+ if (xE)
+ xfree(xE);
+ if (xi2)
+ xfree(xi2);
+ return;
+}
+
+/**
+ * Deliver an event from a device that is currently grabbed. Uses
+ * DeliverDeviceEvents() for further delivery if a ownerEvents is set on the
+ * grab. If not, TryClientEvents() is used.
+ *
+ * @param deactivateGrab True if the device's grab should be deactivated.
+ */
+void
+DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
+ Bool deactivateGrab)
+{
+ GrabPtr grab;
+ GrabInfoPtr grabinfo;
+ int deliveries = 0;
+ DeviceIntPtr dev;
+ SpritePtr pSprite = thisDev->spriteInfo->sprite;
+ BOOL sendCore = FALSE;
+ int rc, count = 0;
+ xEvent *xi = NULL;
+ xEvent *xi2 = NULL;
+
+ grabinfo = &thisDev->deviceGrab;
+ grab = grabinfo->grab;
+
+ if (grab->ownerEvents)
+ {
+ WindowPtr focus;
+
+ /* Hack: Some pointer device have a focus class. So we need to check
+ * for the type of event, to see if we really want to deliver it to
+ * the focus window. For pointer events, the answer is no.
+ */
+ if (IsPointerEvent(event))
+ focus = PointerRootWin;
+ else if (thisDev->focus)
+ {
+ focus = thisDev->focus->win;
+ if (focus == FollowKeyboardWin)
+ focus = inputInfo.keyboard->focus->win;
+ }
+ else
+ focus = PointerRootWin;
+ if (focus == PointerRootWin)
+ deliveries = DeliverDeviceEvents(pSprite->win, event, grab,
+ NullWindow, thisDev);
+ else if (focus && (focus == pSprite->win ||
+ IsParent(focus, pSprite->win)))
+ deliveries = DeliverDeviceEvents(pSprite->win, event, grab, focus,
+ thisDev);
+ else if (focus)
+ deliveries = DeliverDeviceEvents(focus, event, grab, focus,
+ thisDev);
+ }
+ if (!deliveries)
+ {
+ Mask mask;
+
+ /* XXX: In theory, we could pass the internal events through to
+ * everything and only convert just before hitting the wire. We can't
+ * do that yet, so DGE is the last stop for internal events. From here
+ * onwards, we deal with core/XI events.
+ */
+
+ mask = grab->eventMask;
+
+ sendCore = (IsMaster(thisDev) && thisDev->coreEvents);
+ /* try core event */
+ if (sendCore && grab->grabtype == GRABTYPE_CORE)
+ {
+ xEvent core;
+
+ rc = EventToCore(event, &core);
+ if (rc == Success)
+ {
+ FixUpEventFromWindow(thisDev, &core, grab->window,
+ None, TRUE);
+ if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
+ grab->window, &core, 1) ||
+ XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
+ grab->window, &core, 1))
+ deliveries = 1; /* don't send, but pretend we did */
+ else if (!IsInterferingGrab(rClient(grab), thisDev, &core))
+ {
+ deliveries = TryClientEvents(rClient(grab), thisDev,
+ &core, 1, mask,
+ GetEventFilter(thisDev, &core),
+ grab);
+ }
+ } else if (rc != BadMatch)
+ ErrorF("[dix] DeliverGrabbedEvent. Core conversion failed.\n");
+ }
+
+ if (!deliveries)
+ {
+ rc = EventToXI2(event, &xi2);
+ if (rc == Success)
+ {
+ int evtype = ((xGenericEvent*)xi2)->evtype;
+ mask = grab->xi2mask[XIAllDevices][evtype/8] |
+ grab->xi2mask[XIAllMasterDevices][evtype/8] |
+ grab->xi2mask[thisDev->id][evtype/8];
+ /* try XI2 event */
+ FixUpEventFromWindow(thisDev, xi2, grab->window, None, TRUE);
+ /* XXX: XACE */
+ deliveries = TryClientEvents(rClient(grab), thisDev, xi2, 1, mask,
+ GetEventFilter(thisDev, xi2), grab);
+ } else if (rc != BadMatch)
+ ErrorF("[dix] %s: XI2 conversion failed in DGE (%d, %d). Skipping delivery.\n",
+ thisDev->name, event->any.type, rc);
+ }
+
+ if (!deliveries)
+ {
+ rc = EventToXI(event, &xi, &count);
+ if (rc == Success)
+ {
+ /* try XI event */
+ if (grabinfo->fromPassiveGrab &&
+ grabinfo->implicitGrab)
+ mask = grab->deviceMask;
+ else
+ mask = grab->eventMask;
+
+ FixUpEventFromWindow(thisDev, xi, grab->window,
+ None, TRUE);
+
+ if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
+ grab->window, xi, count) ||
+ XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
+ grab->window, xi, count))
+ deliveries = 1; /* don't send, but pretend we did */
+ else
+ {
+ deliveries =
+ TryClientEvents(rClient(grab), thisDev,
+ xi, count,
+ mask,
+ GetEventFilter(thisDev, xi),
+ grab);
+ }
+ } else if (rc != BadMatch)
+ ErrorF("[dix] %s: XI conversion failed in DGE (%d, %d). Skipping delivery.\n",
+ thisDev->name, event->any.type, rc);
+ }
+
+ if (deliveries && (event->any.type == ET_Motion))
+ thisDev->valuator->motionHintWindow = grab->window;
+ }
+ if (deliveries && !deactivateGrab && event->any.type != ET_Motion)
+ {
+ switch (grabinfo->sync.state)
+ {
+ case FREEZE_BOTH_NEXT_EVENT:
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev == thisDev)
+ continue;
+ FreezeThaw(dev, TRUE);
+ if ((dev->deviceGrab.sync.state == FREEZE_BOTH_NEXT_EVENT) &&
+ (CLIENT_BITS(grab->resource) ==
+ CLIENT_BITS(dev->deviceGrab.sync.other->resource)))
+ dev->deviceGrab.sync.state = FROZEN_NO_EVENT;
+ else
+ dev->deviceGrab.sync.other = grab;
+ }
+ /* fall through */
+ case FREEZE_NEXT_EVENT:
+ grabinfo->sync.state = FROZEN_WITH_EVENT;
+ FreezeThaw(thisDev, TRUE);
+ if (!grabinfo->sync.event)
+ grabinfo->sync.event = xcalloc(1, sizeof(InternalEvent));
+ *grabinfo->sync.event = event->device_event;
+ break;
+ }
+ }
+
+ if (xi)
+ xfree(xi);
+ if (xi2)
+ xfree(xi2);
+}
+
+/* This function is used to set the key pressed or key released state -
+ this is only used when the pressing of keys does not cause
+ the device's processInputProc to be called, as in for example Mouse Keys.
+*/
+void
+FixKeyState (DeviceEvent *event, DeviceIntPtr keybd)
+{
+ int key, bit;
+ BYTE *kptr;
+ KeyClassPtr keyc = keybd->key;
+
+ key = event->detail.key;
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+
+ if (event->type == ET_KeyPress) {
+ DebugF("FixKeyState: Key %d %s\n",key,
+ ((event->type == ET_KeyPress) ? "down" : "up"));
+ }
+
+ if (event->type == ET_KeyPress)
+ *kptr |= bit;
+ else if (event->type == ET_KeyRelease)
+ *kptr &= ~bit;
+ else
+ FatalError("Impossible keyboard event");
+}
+
+#define AtMostOneClient \
+ (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
+#define ManagerMask \
+ (SubstructureRedirectMask | ResizeRedirectMask)
+
+/**
+ * Recalculate which events may be deliverable for the given window.
+ * Recalculated mask is used for quicker determination which events may be
+ * delivered to a window.
+ *
+ * The otherEventMasks on a WindowOptional is the combination of all event
+ * masks set by all clients on the window.
+ * deliverableEventMask is the combination of the eventMask and the
+ * otherEventMask plus the events that may be propagated to the parent.
+ *
+ * Traverses to siblings and parents of the window.
+ */
+void
+RecalculateDeliverableEvents(WindowPtr pWin)
+{
+ OtherClients *others;
+ WindowPtr pChild;
+
+ pChild = pWin;
+ while (1)
+ {
+ if (pChild->optional)
+ {
+ pChild->optional->otherEventMasks = 0;
+ for (others = wOtherClients(pChild); others; others = others->next)
+ {
+ pChild->optional->otherEventMasks |= others->mask;
+ }
+ }
+ pChild->deliverableEvents = pChild->eventMask|
+ wOtherEventMasks(pChild);
+ if (pChild->parent)
+ pChild->deliverableEvents |=
+ (pChild->parent->deliverableEvents &
+ ~wDontPropagateMask(pChild) & PropagateMask);
+ if (pChild->firstChild)
+ {
+ pChild = pChild->firstChild;
+ continue;
+ }
+ while (!pChild->nextSib && (pChild != pWin))
+ pChild = pChild->parent;
+ if (pChild == pWin)
+ break;
+ pChild = pChild->nextSib;
+ }
+}
+
+/**
+ *
+ * \param value must conform to DeleteType
+ */
+int
+OtherClientGone(pointer value, XID id)
+{
+ OtherClientsPtr other, prev;
+ WindowPtr pWin = (WindowPtr)value;
+
+ prev = 0;
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (other->resource == id)
+ {
+ if (prev)
+ prev->next = other->next;
+ else
+ {
+ if (!(pWin->optional->otherClients = other->next))
+ CheckWindowOptionalNeed (pWin);
+ }
+ xfree(other);
+ RecalculateDeliverableEvents(pWin);
+ return(Success);
+ }
+ prev = other;
+ }
+ FatalError("client not on event list");
+ /*NOTREACHED*/
+ return -1; /* make compiler happy */
+}
+
+int
+EventSelectForWindow(WindowPtr pWin, ClientPtr client, Mask mask)
+{
+ Mask check;
+ OtherClients * others;
+ DeviceIntPtr dev;
+ int rc;
+
+ if (mask & ~AllEventMasks)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ check = (mask & ManagerMask);
+ if (check) {
+ rc = XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id,
+ RT_WINDOW, pWin, RT_NONE, NULL, DixManageAccess);
+ if (rc != Success)
+ return rc;
+ }
+ check = (mask & AtMostOneClient);
+ if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
+ { /* It is illegal for two different
+ clients to select on any of the
+ events for AtMostOneClient. However,
+ it is OK, for some client to
+ continue selecting on one of those
+ events. */
+ if ((wClient(pWin) != client) && (check & pWin->eventMask))
+ return BadAccess;
+ for (others = wOtherClients (pWin); others; others = others->next)
+ {
+ if (!SameClient(others, client) && (check & others->mask))
+ return BadAccess;
+ }
+ }
+ if (wClient (pWin) == client)
+ {
+ check = pWin->eventMask;
+ pWin->eventMask = mask;
+ }
+ else
+ {
+ for (others = wOtherClients (pWin); others; others = others->next)
+ {
+ if (SameClient(others, client))
+ {
+ check = others->mask;
+ if (mask == 0)
+ {
+ FreeResource(others->resource, RT_NONE);
+ return Success;
+ }
+ else
+ others->mask = mask;
+ goto maskSet;
+ }
+ }
+ check = 0;
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ return BadAlloc;
+ others = xalloc(sizeof(OtherClients));
+ if (!others)
+ return BadAlloc;
+ others->mask = mask;
+ others->resource = FakeClientID(client->index);
+ others->next = pWin->optional->otherClients;
+ pWin->optional->otherClients = others;
+ if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin))
+ return BadAlloc;
+ }
+maskSet:
+ if ((mask & PointerMotionHintMask) && !(check & PointerMotionHintMask))
+ {
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (dev->valuator && dev->valuator->motionHintWindow == pWin)
+ dev->valuator->motionHintWindow = NullWindow;
+ }
+ }
+ RecalculateDeliverableEvents(pWin);
+ return Success;
+}
+
+int
+EventSuppressForWindow(WindowPtr pWin, ClientPtr client,
+ Mask mask, Bool *checkOptional)
+{
+ int i, free;
+
+ if (mask & ~PropagateMask)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]--;
+ if (!mask)
+ i = 0;
+ else
+ {
+ for (i = DNPMCOUNT, free = 0; --i > 0; )
+ {
+ if (!DontPropagateRefCnts[i])
+ free = i;
+ else if (mask == DontPropagateMasks[i])
+ break;
+ }
+ if (!i && free)
+ {
+ i = free;
+ DontPropagateMasks[i] = mask;
+ }
+ }
+ if (i || !mask)
+ {
+ pWin->dontPropagate = i;
+ if (i)
+ DontPropagateRefCnts[i]++;
+ if (pWin->optional)
+ {
+ pWin->optional->dontPropagateMask = mask;
+ *checkOptional = TRUE;
+ }
+ }
+ else
+ {
+ if (!pWin->optional && !MakeWindowOptional (pWin))
+ {
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]++;
+ return BadAlloc;
+ }
+ pWin->dontPropagate = 0;
+ pWin->optional->dontPropagateMask = mask;
+ }
+ RecalculateDeliverableEvents(pWin);
+ return Success;
+}
+
+/**
+ * Assembles an EnterNotify or LeaveNotify and sends it event to the client.
+ * Uses the paired keyboard to get some additional information.
+ */
+void
+CoreEnterLeaveEvent(
+ DeviceIntPtr mouse,
+ int type,
+ int mode,
+ int detail,
+ WindowPtr pWin,
+ Window child)
+{
+ xEvent event;
+ WindowPtr focus;
+ DeviceIntPtr keybd;
+ GrabPtr grab = mouse->deviceGrab.grab;
+ Mask mask;
+
+ keybd = GetPairedDevice(mouse);
+
+ if ((pWin == mouse->valuator->motionHintWindow) &&
+ (detail != NotifyInferior))
+ mouse->valuator->motionHintWindow = NullWindow;
+ if (grab)
+ {
+ mask = (pWin == grab->window) ? grab->eventMask : 0;
+ if (grab->ownerEvents)
+ mask |= EventMaskForClient(pWin, rClient(grab));
+ }
+ else
+ {
+ mask = pWin->eventMask | wOtherEventMasks(pWin);
+ }
+
+ memset(&event, 0, sizeof(xEvent));
+ event.u.u.type = type;
+ event.u.u.detail = detail;
+ event.u.enterLeave.time = currentTime.milliseconds;
+ event.u.enterLeave.rootX = mouse->spriteInfo->sprite->hot.x;
+ event.u.enterLeave.rootY = mouse->spriteInfo->sprite->hot.y;
+ /* Counts on the same initial structure of crossing & button events! */
+ FixUpEventFromWindow(mouse, &event, pWin, None, FALSE);
+ /* Enter/Leave events always set child */
+ event.u.enterLeave.child = child;
+ event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
+ ELFlagSameScreen : 0;
+ event.u.enterLeave.state = mouse->button ? (mouse->button->state & 0x1f00) : 0;
+ if (keybd)
+ event.u.enterLeave.state |=
+ XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
+ event.u.enterLeave.mode = mode;
+ focus = (keybd) ? keybd->focus->win : None;
+ if ((focus != NoneWin) &&
+ ((pWin == focus) || (focus == PointerRootWin) ||
+ IsParent(focus, pWin)))
+ event.u.enterLeave.flags |= ELFlagFocus;
+
+ if ((mask & GetEventFilter(mouse, &event)))
+ {
+ if (grab)
+ TryClientEvents(rClient(grab), mouse, &event, 1, mask,
+ GetEventFilter(mouse, &event), grab);
+ else
+ DeliverEventsToWindow(mouse, pWin, &event, 1,
+ GetEventFilter(mouse, &event),
+ NullGrab);
+ }
+
+ if ((type == EnterNotify) && (mask & KeymapStateMask))
+ {
+ xKeymapEvent ke;
+ ClientPtr client = grab ? rClient(grab) : wClient(pWin);
+ if (XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess))
+ bzero((char *)&ke.map[0], 31);
+ else
+ memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
+
+ ke.type = KeymapNotify;
+ if (grab)
+ TryClientEvents(rClient(grab), keybd, (xEvent *)&ke, 1,
+ mask, KeymapStateMask, grab);
+ else
+ DeliverEventsToWindow(mouse, pWin, (xEvent *)&ke, 1,
+ KeymapStateMask, NullGrab);
+ }
+}
+
+void
+DeviceEnterLeaveEvent(
+ DeviceIntPtr mouse,
+ int sourceid,
+ int type,
+ int mode,
+ int detail,
+ WindowPtr pWin,
+ Window child)
+{
+ GrabPtr grab = mouse->deviceGrab.grab;
+ xXIEnterEvent *event;
+ int filter;
+ int btlen, len, i;
+ DeviceIntPtr kbd;
+
+ if ((mode == XINotifyPassiveGrab && type == XI_Leave) ||
+ (mode == XINotifyPassiveUngrab && type == XI_Enter))
+ return;
+
+ btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0;
+ btlen = bytes_to_int32(btlen);
+ len = sizeof(xXIEnterEvent) + btlen * 4;
+
+ event = xcalloc(1, len);
+ event->type = GenericEvent;
+ event->extension = IReqCode;
+ event->evtype = type;
+ event->length = (len - sizeof(xEvent))/4;
+ event->buttons_len = btlen;
+ event->detail = detail;
+ event->time = currentTime.milliseconds;
+ event->deviceid = mouse->id;
+ event->sourceid = sourceid;
+ event->mode = mode;
+ event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0);
+ event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0);
+
+ for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
+ if (BitIsOn(mouse->button->down, i))
+ SetBit(&event[1], i);
+
+ kbd = (IsMaster(mouse) || mouse->u.master) ? GetPairedDevice(mouse) : NULL;
+ if (kbd && kbd->key)
+ {
+ event->mods.base_mods = kbd->key->xkbInfo->state.base_mods;
+ event->mods.latched_mods = kbd->key->xkbInfo->state.latched_mods;
+ event->mods.locked_mods = kbd->key->xkbInfo->state.locked_mods;
+
+ event->group.base_group = kbd->key->xkbInfo->state.base_group;
+ event->group.latched_group = kbd->key->xkbInfo->state.latched_group;
+ event->group.locked_group = kbd->key->xkbInfo->state.locked_group;
+ }
+
+ FixUpEventFromWindow(mouse, (xEvent*)event, pWin, None, FALSE);
+
+ filter = GetEventFilter(mouse, (xEvent*)event);
+
+ if (grab)
+ {
+ Mask mask;
+ mask = grab->xi2mask[XIAllDevices][type/8] |
+ grab->xi2mask[XIAllMasterDevices][type/8] |
+ grab->xi2mask[mouse->id][type/8];
+ TryClientEvents(rClient(grab), mouse, (xEvent*)event, 1, mask,
+ filter, grab);
+ } else {
+ if (!GetWindowXI2Mask(mouse, pWin, (xEvent*)event))
+ goto out;
+ DeliverEventsToWindow(mouse, pWin, (xEvent*)event, 1, filter,
+ NullGrab);
+ }
+
+out:
+ xfree(event);
+}
+
+void
+CoreFocusEvent(DeviceIntPtr dev, int type, int mode, int detail, WindowPtr pWin)
+{
+ xEvent event;
+
+ memset(&event, 0, sizeof(xEvent));
+ event.u.focus.mode = mode;
+ event.u.u.type = type;
+ event.u.u.detail = detail;
+ event.u.focus.window = pWin->drawable.id;
+
+ DeliverEventsToWindow(dev, pWin, &event, 1,
+ GetEventFilter(dev, &event), NullGrab);
+ if ((type == FocusIn) &&
+ ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
+ {
+ xKeymapEvent ke;
+ ClientPtr client = wClient(pWin);
+ if (XaceHook(XACE_DEVICE_ACCESS, client, dev, DixReadAccess))
+ bzero((char *)&ke.map[0], 31);
+ else
+ memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
+
+ ke.type = KeymapNotify;
+ DeliverEventsToWindow(dev, pWin, (xEvent *)&ke, 1,
+ KeymapStateMask, NullGrab);
+ }
+}
+
+/**
+ * Set the input focus to the given window. Subsequent keyboard events will be
+ * delivered to the given window.
+ *
+ * Usually called from ProcSetInputFocus as result of a client request. If so,
+ * the device is the inputInfo.keyboard.
+ * If called from ProcXSetInputFocus as result of a client xinput request, the
+ * device is set to the device specified by the client.
+ *
+ * @param client Client that requested input focus change.
+ * @param dev Focus device.
+ * @param focusID The window to obtain the focus. Can be PointerRoot or None.
+ * @param revertTo Specifies where the focus reverts to when window becomes
+ * unviewable.
+ * @param ctime Specifies the time.
+ * @param followOK True if pointer is allowed to follow the keyboard.
+ */
+int
+SetInputFocus(
+ ClientPtr client,
+ DeviceIntPtr dev,
+ Window focusID,
+ CARD8 revertTo,
+ Time ctime,
+ Bool followOK)
+{
+ FocusClassPtr focus;
+ WindowPtr focusWin;
+ int mode, rc;
+ TimeStamp time;
+ DeviceIntPtr keybd; /* used for FollowKeyboard or FollowKeyboardWin */
+
+
+ UpdateCurrentTime();
+ if ((revertTo != RevertToParent) &&
+ (revertTo != RevertToPointerRoot) &&
+ (revertTo != RevertToNone) &&
+ ((revertTo != RevertToFollowKeyboard) || !followOK))
+ {
+ client->errorValue = revertTo;
+ return BadValue;
+ }
+ time = ClientTimeToServerTime(ctime);
+
+ if (IsKeyboardDevice(dev))
+ keybd = dev;
+ else
+ keybd = GetPairedDevice(dev);
+
+ if ((focusID == None) || (focusID == PointerRoot))
+ focusWin = (WindowPtr)(long)focusID;
+ else if ((focusID == FollowKeyboard) && followOK)
+ {
+ focusWin = keybd->focus->win;
+ }
+ else {
+ rc = dixLookupWindow(&focusWin, focusID, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ /* It is a match error to try to set the input focus to an
+ unviewable window. */
+ if(!focusWin->realized)
+ return(BadMatch);
+ }
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixSetFocusAccess);
+ if (rc != Success)
+ return Success;
+
+ focus = dev->focus;
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, focus->time) == EARLIER))
+ return Success;
+ mode = (dev->deviceGrab.grab) ? NotifyWhileGrabbed : NotifyNormal;
+ if (focus->win == FollowKeyboardWin)
+ {
+ if (!ActivateFocusInGrab(dev, keybd->focus->win, focusWin))
+ DoFocusEvents(dev, keybd->focus->win, focusWin, mode);
+ } else
+ {
+ if (!ActivateFocusInGrab(dev, focus->win, focusWin))
+ DoFocusEvents(dev, focus->win, focusWin, mode);
+ }
+ focus->time = time;
+ focus->revert = revertTo;
+ if (focusID == FollowKeyboard)
+ focus->win = FollowKeyboardWin;
+ else
+ focus->win = focusWin;
+ if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
+ focus->traceGood = 0;
+ else
+ {
+ int depth = 0;
+ WindowPtr pWin;
+
+ for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
+ if (depth > focus->traceSize)
+ {
+ focus->traceSize = depth+1;
+ focus->trace = xrealloc(focus->trace,
+ focus->traceSize * sizeof(WindowPtr));
+ }
+ focus->traceGood = depth;
+ for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--)
+ focus->trace[depth] = pWin;
+ }
+ return Success;
+}
+
+/**
+ * Server-side protocol handling for SetInputFocus request.
+ *
+ * Sets the input focus for the virtual core keyboard.
+ */
+int
+ProcSetInputFocus(ClientPtr client)
+{
+ DeviceIntPtr kbd = PickKeyboard(client);
+ REQUEST(xSetInputFocusReq);
+
+ REQUEST_SIZE_MATCH(xSetInputFocusReq);
+
+ return SetInputFocus(client, kbd, stuff->focus,
+ stuff->revertTo, stuff->time, FALSE);
+}
+
+/**
+ * Server-side protocol handling for GetInputFocus request.
+ *
+ * Sends the current input focus for the client's keyboard back to the
+ * client.
+ */
+int
+ProcGetInputFocus(ClientPtr client)
+{
+ DeviceIntPtr kbd = PickKeyboard(client);
+ xGetInputFocusReply rep;
+ FocusClassPtr focus = kbd->focus;
+ int rc;
+ /* REQUEST(xReq); */
+ REQUEST_SIZE_MATCH(xReq);
+
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetFocusAccess);
+ if (rc != Success)
+ return rc;
+
+ memset(&rep, 0, sizeof(xGetInputFocusReply));
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (focus->win == NoneWin)
+ rep.focus = None;
+ else if (focus->win == PointerRootWin)
+ rep.focus = PointerRoot;
+ else rep.focus = focus->win->drawable.id;
+ rep.revertTo = focus->revert;
+ WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
+ return Success;
+}
+
+/**
+ * Server-side protocol handling for GrabPointer request.
+ *
+ * Sets an active grab on the client's ClientPointer and returns success
+ * status to client.
+ */
+int
+ProcGrabPointer(ClientPtr client)
+{
+ xGrabPointerReply rep;
+ DeviceIntPtr device = PickPointer(client);
+ GrabPtr grab;
+ GrabMask mask;
+ WindowPtr confineTo;
+ CursorPtr oldCursor;
+ REQUEST(xGrabPointerReq);
+ TimeStamp time;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xGrabPointerReq);
+ UpdateCurrentTime();
+
+ if (stuff->eventMask & ~PointerGrabMask)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+
+ if (stuff->confineTo == None)
+ confineTo = NullWindow;
+ else
+ {
+ rc = dixLookupWindow(&confineTo, stuff->confineTo, client,
+ DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ }
+
+ memset(&rep, 0, sizeof(xGrabPointerReply));
+ oldCursor = NullCursor;
+ grab = device->deviceGrab.grab;
+
+ if (grab)
+ {
+ if (grab->confineTo && !confineTo)
+ ConfineCursorToWindow(device, RootWindow(device), FALSE, FALSE);
+ oldCursor = grab->cursor;
+ }
+
+ mask.core = stuff->eventMask;
+
+ rc = GrabDevice(client, device, stuff->pointerMode, stuff->keyboardMode,
+ stuff->grabWindow, stuff->ownerEvents, stuff->time,
+ &mask, GRABTYPE_CORE, stuff->cursor,
+ stuff->confineTo, &rep.status);
+ if (rc != Success)
+ return rc;
+
+ if (oldCursor && rep.status == GrabSuccess)
+ FreeCursor (oldCursor, (Cursor)0);
+
+ time = ClientTimeToServerTime(stuff->time);
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
+ return Success;
+}
+
+/**
+ * Server-side protocol handling for ChangeActivePointerGrab request.
+ *
+ * Changes properties of the grab hold by the client. If the client does not
+ * hold an active grab on the device, nothing happens.
+ */
+int
+ProcChangeActivePointerGrab(ClientPtr client)
+{
+ DeviceIntPtr device;
+ GrabPtr grab;
+ CursorPtr newCursor, oldCursor;
+ REQUEST(xChangeActivePointerGrabReq);
+ TimeStamp time;
+
+ REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
+ if (stuff->eventMask & ~PointerGrabMask)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ if (stuff->cursor == None)
+ newCursor = NullCursor;
+ else
+ {
+ int rc = dixLookupResourceByType((pointer *)&newCursor, stuff->cursor,
+ RT_CURSOR, client, DixUseAccess);
+ if (rc != Success)
+ {
+ client->errorValue = stuff->cursor;
+ return (rc == BadValue) ? BadCursor : rc;
+ }
+ }
+
+ device = PickPointer(client);
+ grab = device->deviceGrab.grab;
+
+ if (!grab)
+ return Success;
+ if (!SameClient(grab, client))
+ return Success;
+ time = ClientTimeToServerTime(stuff->time);
+ if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, device->deviceGrab.grabTime) == EARLIER))
+ return Success;
+ oldCursor = grab->cursor;
+ grab->cursor = newCursor;
+ if (newCursor)
+ newCursor->refcnt++;
+ PostNewCursor(device);
+ if (oldCursor)
+ FreeCursor(oldCursor, (Cursor)0);
+ grab->eventMask = stuff->eventMask;
+ return Success;
+}
+
+/**
+ * Server-side protocol handling for UngrabPointer request.
+ *
+ * Deletes a pointer grab on a device the client has grabbed.
+ */
+int
+ProcUngrabPointer(ClientPtr client)
+{
+ DeviceIntPtr device = PickPointer(client);
+ GrabPtr grab;
+ TimeStamp time;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ UpdateCurrentTime();
+ grab = device->deviceGrab.grab;
+
+ time = ClientTimeToServerTime(stuff->id);
+ if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ (CompareTimeStamps(time, device->deviceGrab.grabTime) != EARLIER) &&
+ (grab) && SameClient(grab, client))
+ (*device->deviceGrab.DeactivateGrab)(device);
+ return Success;
+}
+
+/**
+ * Sets a grab on the given device.
+ *
+ * Called from ProcGrabKeyboard to work on the client's keyboard.
+ * Called from ProcXGrabDevice to work on the device specified by the client.
+ *
+ * The parameters this_mode and other_mode represent the keyboard_mode and
+ * pointer_mode parameters of XGrabKeyboard().
+ * See man page for details on all the parameters
+ *
+ * @param client Client that owns the grab.
+ * @param dev The device to grab.
+ * @param this_mode GrabModeSync or GrabModeAsync
+ * @param other_mode GrabModeSync or GrabModeAsync
+ * @param status Return code to be returned to the caller.
+ *
+ * @returns Success or BadValue.
+ */
+int
+GrabDevice(ClientPtr client, DeviceIntPtr dev,
+ unsigned pointer_mode, unsigned keyboard_mode, Window grabWindow,
+ unsigned ownerEvents, Time ctime, GrabMask *mask,
+ int grabtype, Cursor curs, Window confineToWin, CARD8 *status)
+{
+ WindowPtr pWin, confineTo;
+ GrabPtr grab;
+ TimeStamp time;
+ Mask access_mode = DixGrabAccess;
+ int rc;
+ GrabInfoPtr grabInfo = &dev->deviceGrab;
+ CursorPtr cursor;
+
+ UpdateCurrentTime();
+ if ((keyboard_mode != GrabModeSync) && (keyboard_mode != GrabModeAsync))
+ {
+ client->errorValue = keyboard_mode;
+ return BadValue;
+ }
+ if ((pointer_mode != GrabModeSync) && (pointer_mode != GrabModeAsync))
+ {
+ client->errorValue = pointer_mode;
+ return BadValue;
+ }
+ if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
+ {
+ client->errorValue = ownerEvents;
+ return BadValue;
+ }
+
+ rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ if (confineToWin == None)
+ confineTo = NullWindow;
+ else
+ {
+ rc = dixLookupWindow(&confineTo, confineToWin, client,
+ DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ }
+
+ if (curs == None)
+ cursor = NullCursor;
+ else
+ {
+ rc = dixLookupResourceByType((pointer *)&cursor, curs, RT_CURSOR,
+ client, DixUseAccess);
+ if (rc != Success)
+ {
+ client->errorValue = curs;
+ return (rc == BadValue) ? BadCursor : rc;
+ }
+ access_mode |= DixForceAccess;
+ }
+
+ if (keyboard_mode == GrabModeSync || pointer_mode == GrabModeSync)
+ access_mode |= DixFreezeAccess;
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
+ if (rc != Success)
+ return rc;
+
+ time = ClientTimeToServerTime(ctime);
+ grab = grabInfo->grab;
+ if (grab && grab->grabtype != grabtype)
+ *status = AlreadyGrabbed;
+ if (grab && !SameClient(grab, client))
+ *status = AlreadyGrabbed;
+ else if ((!pWin->realized) ||
+ (confineTo &&
+ !(confineTo->realized
+ && BorderSizeNotEmpty(dev, confineTo))))
+ *status = GrabNotViewable;
+ else if ((CompareTimeStamps(time, currentTime) == LATER) ||
+ (CompareTimeStamps(time, grabInfo->grabTime) == EARLIER))
+ *status = GrabInvalidTime;
+ else if (grabInfo->sync.frozen &&
+ grabInfo->sync.other && !SameClient(grabInfo->sync.other, client))
+ *status = GrabFrozen;
+ else
+ {
+ GrabRec tempGrab;
+
+ /* Otherwise segfaults happen on grabbed MPX devices */
+ memset(&tempGrab, 0, sizeof(GrabRec));
+
+ tempGrab.next = NULL;
+ tempGrab.window = pWin;
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.ownerEvents = ownerEvents;
+ tempGrab.keyboardMode = keyboard_mode;
+ tempGrab.pointerMode = pointer_mode;
+ if (grabtype == GRABTYPE_CORE)
+ tempGrab.eventMask = mask->core;
+ else if (grabtype == GRABTYPE_XI)
+ tempGrab.eventMask = mask->xi;
+ else
+ memcpy(tempGrab.xi2mask, mask->xi2mask, sizeof(tempGrab.xi2mask));
+ tempGrab.device = dev;
+ tempGrab.cursor = cursor;
+ tempGrab.confineTo = confineTo;
+ tempGrab.grabtype = grabtype;
+ (*grabInfo->ActivateGrab)(dev, &tempGrab, time, FALSE);
+ *status = GrabSuccess;
+ }
+ return Success;
+}
+
+/**
+ * Server-side protocol handling for GrabKeyboard request.
+ *
+ * Grabs the client's keyboard and returns success status to client.
+ */
+int
+ProcGrabKeyboard(ClientPtr client)
+{
+ xGrabKeyboardReply rep;
+ REQUEST(xGrabKeyboardReq);
+ int result;
+ DeviceIntPtr keyboard = PickKeyboard(client);
+ GrabMask mask;
+
+ REQUEST_SIZE_MATCH(xGrabKeyboardReq);
+
+ memset(&rep, 0, sizeof(xGrabKeyboardReply));
+ mask.core = KeyPressMask | KeyReleaseMask;
+
+ result = GrabDevice(client, keyboard, stuff->pointerMode,
+ stuff->keyboardMode, stuff->grabWindow, stuff->ownerEvents,
+ stuff->time, &mask, GRABTYPE_CORE, None, None,
+ &rep.status);
+
+ if (result != Success)
+ return result;
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
+ return Success;
+}
+
+/**
+ * Server-side protocol handling for UngrabKeyboard request.
+ *
+ * Deletes a possible grab on the client's keyboard.
+ */
+int
+ProcUngrabKeyboard(ClientPtr client)
+{
+ DeviceIntPtr device = PickKeyboard(client);
+ GrabPtr grab;
+ TimeStamp time;
+ REQUEST(xResourceReq);
+
+ REQUEST_SIZE_MATCH(xResourceReq);
+ UpdateCurrentTime();
+
+ grab = device->deviceGrab.grab;
+
+ time = ClientTimeToServerTime(stuff->id);
+ if ((CompareTimeStamps(time, currentTime) != LATER) &&
+ (CompareTimeStamps(time, device->deviceGrab.grabTime) != EARLIER) &&
+ (grab) && SameClient(grab, client) && grab->grabtype == GRABTYPE_CORE)
+ (*device->deviceGrab.DeactivateGrab)(device);
+ return Success;
+}
+
+/**
+ * Server-side protocol handling for QueryPointer request.
+ *
+ * Returns the current state and position of the client's ClientPointer to the
+ * client.
+ */
+int
+ProcQueryPointer(ClientPtr client)
+{
+ xQueryPointerReply rep;
+ WindowPtr pWin, t;
+ DeviceIntPtr mouse = PickPointer(client);
+ DeviceIntPtr keyboard;
+ SpritePtr pSprite;
+ int rc;
+ REQUEST(xResourceReq);
+ REQUEST_SIZE_MATCH(xResourceReq);
+
+ rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess);
+ if (rc != Success && rc != BadAccess)
+ return rc;
+
+ keyboard = GetPairedDevice(mouse);
+
+ pSprite = mouse->spriteInfo->sprite;
+ if (mouse->valuator->motionHintWindow)
+ MaybeStopHint(mouse, client);
+ memset(&rep, 0, sizeof(xQueryPointerReply));
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.mask = mouse->button ? (mouse->button->state) : 0;
+ rep.mask |= XkbStateFieldFromRec(&keyboard->key->xkbInfo->state);
+ rep.length = 0;
+ rep.root = (RootWindow(mouse))->drawable.id;
+ rep.rootX = pSprite->hot.x;
+ rep.rootY = pSprite->hot.y;
+ rep.child = None;
+ if (pSprite->hot.pScreen == pWin->drawable.pScreen)
+ {
+ rep.sameScreen = xTrue;
+ rep.winX = pSprite->hot.x - pWin->drawable.x;
+ rep.winY = pSprite->hot.y - pWin->drawable.y;
+ for (t = pSprite->win; t; t = t->parent)
+ if (t->parent == pWin)
+ {
+ rep.child = t->drawable.id;
+ break;
+ }
+ }
+ else
+ {
+ rep.sameScreen = xFalse;
+ rep.winX = 0;
+ rep.winY = 0;
+ }
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension) {
+ rep.rootX += panoramiXdataPtr[0].x;
+ rep.rootY += panoramiXdataPtr[0].y;
+ if(stuff->id == rep.root) {
+ rep.winX += panoramiXdataPtr[0].x;
+ rep.winY += panoramiXdataPtr[0].y;
+ }
+ }
+#endif
+
+ if (rc == BadAccess) {
+ rep.mask = 0;
+ rep.child = None;
+ rep.rootX = 0;
+ rep.rootY = 0;
+ rep.winX = 0;
+ rep.winY = 0;
+ }
+
+ WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
+
+ return(Success);
+}
+
+/**
+ * Initializes the device list and the DIX sprite to sane values. Allocates
+ * trace memory used for quick window traversal.
+ */
+void
+InitEvents(void)
+{
+ int i;
+
+ inputInfo.numDevices = 0;
+ inputInfo.devices = (DeviceIntPtr)NULL;
+ inputInfo.off_devices = (DeviceIntPtr)NULL;
+ inputInfo.keyboard = (DeviceIntPtr)NULL;
+ inputInfo.pointer = (DeviceIntPtr)NULL;
+ /* The mask for pointer motion events may have changed in the last server
+ * generation. See comment above definition of filters. */
+ filters[0][PointerMotionMask] = MotionNotify;
+ for (i = 1; i < MAXDEVICES; i++)
+ {
+ memcpy(&filters[i], filters[0], sizeof(filters[0]));
+ }
+
+ syncEvents.replayDev = (DeviceIntPtr)NULL;
+ syncEvents.replayWin = NullWindow;
+ while (syncEvents.pending)
+ {
+ QdEventPtr next = syncEvents.pending->next;
+ xfree(syncEvents.pending);
+ syncEvents.pending = next;
+ }
+ syncEvents.pendtail = &syncEvents.pending;
+ syncEvents.playingEvents = FALSE;
+ syncEvents.time.months = 0;
+ syncEvents.time.milliseconds = 0; /* hardly matters */
+ currentTime.months = 0;
+ currentTime.milliseconds = GetTimeInMillis();
+ lastDeviceEventTime = currentTime;
+ for (i = 0; i < DNPMCOUNT; i++)
+ {
+ DontPropagateMasks[i] = 0;
+ DontPropagateRefCnts[i] = 0;
+ }
+
+ InputEventListLen = GetMaximumEventsNum();
+ InputEventList = InitEventList(InputEventListLen);
+ if (!InputEventList)
+ FatalError("[dix] Failed to allocate input event list.\n");
+}
+
+void
+CloseDownEvents(void)
+{
+ FreeEventList(InputEventList, InputEventListLen);
+ InputEventListLen = 0;
+ InputEventList = NULL;
+}
+
+/**
+ * Server-side protocol handling for SendEvent request.
+ *
+ * Locates the window to send the event to and forwards the event.
+ */
+int
+ProcSendEvent(ClientPtr client)
+{
+ WindowPtr pWin;
+ WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
+ DeviceIntPtr dev = PickPointer(client);
+ DeviceIntPtr keybd = GetPairedDevice(dev);
+ SpritePtr pSprite = dev->spriteInfo->sprite;
+ REQUEST(xSendEventReq);
+
+ REQUEST_SIZE_MATCH(xSendEventReq);
+
+ /* The client's event type must be a core event type or one defined by an
+ extension. */
+
+ if ( ! ((stuff->event.u.u.type > X_Reply &&
+ stuff->event.u.u.type < LASTEvent) ||
+ (stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
+ stuff->event.u.u.type < (unsigned)lastEvent)))
+ {
+ client->errorValue = stuff->event.u.u.type;
+ return BadValue;
+ }
+ if (stuff->event.u.u.type == ClientMessage &&
+ stuff->event.u.u.detail != 8 &&
+ stuff->event.u.u.detail != 16 &&
+ stuff->event.u.u.detail != 32)
+ {
+ client->errorValue = stuff->event.u.u.detail;
+ return BadValue;
+ }
+ if (stuff->eventMask & ~AllEventMasks)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+
+ if (stuff->destination == PointerWindow)
+ pWin = pSprite->win;
+ else if (stuff->destination == InputFocus)
+ {
+ WindowPtr inputFocus = (keybd) ? keybd->focus->win : NoneWin;
+
+ if (inputFocus == NoneWin)
+ return Success;
+
+ /* If the input focus is PointerRootWin, send the event to where
+ the pointer is if possible, then perhaps propogate up to root. */
+ if (inputFocus == PointerRootWin)
+ inputFocus = pSprite->spriteTrace[0]; /* Root window! */
+
+ if (IsParent(inputFocus, pSprite->win))
+ {
+ effectiveFocus = inputFocus;
+ pWin = pSprite->win;
+ }
+ else
+ effectiveFocus = pWin = inputFocus;
+ }
+ else
+ dixLookupWindow(&pWin, stuff->destination, client, DixSendAccess);
+
+ if (!pWin)
+ return BadWindow;
+ if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
+ {
+ client->errorValue = stuff->propagate;
+ return BadValue;
+ }
+ stuff->event.u.u.type |= 0x80;
+ if (stuff->propagate)
+ {
+ for (;pWin; pWin = pWin->parent)
+ {
+ if (XaceHook(XACE_SEND_ACCESS, client, NULL, pWin,
+ &stuff->event, 1))
+ return Success;
+ if (DeliverEventsToWindow(dev, pWin,
+ &stuff->event, 1, stuff->eventMask, NullGrab))
+ return Success;
+ if (pWin == effectiveFocus)
+ return Success;
+ stuff->eventMask &= ~wDontPropagateMask(pWin);
+ if (!stuff->eventMask)
+ break;
+ }
+ }
+ else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, &stuff->event, 1))
+ DeliverEventsToWindow(dev, pWin, &stuff->event,
+ 1, stuff->eventMask, NullGrab);
+ return Success;
+}
+
+/**
+ * Server-side protocol handling for UngrabKey request.
+ *
+ * Deletes a passive grab for the given key. Works on the
+ * client's keyboard.
+ */
+int
+ProcUngrabKey(ClientPtr client)
+{
+ REQUEST(xUngrabKeyReq);
+ WindowPtr pWin;
+ GrabRec tempGrab;
+ DeviceIntPtr keybd = PickKeyboard(client);
+ int rc;
+
+ REQUEST_SIZE_MATCH(xUngrabKeyReq);
+ rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+ if (((stuff->key > keybd->key->xkbInfo->desc->max_key_code) ||
+ (stuff->key < keybd->key->xkbInfo->desc->min_key_code))
+ && (stuff->key != AnyKey))
+ {
+ client->errorValue = stuff->key;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.device = keybd;
+ tempGrab.window = pWin;
+ tempGrab.modifiersDetail.exact = stuff->modifiers;
+ tempGrab.modifiersDetail.pMask = NULL;
+ tempGrab.modifierDevice = GetPairedDevice(keybd);
+ tempGrab.type = KeyPress;
+ tempGrab.grabtype = GRABTYPE_CORE;
+ tempGrab.detail.exact = stuff->key;
+ tempGrab.detail.pMask = NULL;
+ tempGrab.next = NULL;
+
+ if (!DeletePassiveGrabFromList(&tempGrab))
+ return(BadAlloc);
+ return(Success);
+}
+
+/**
+ * Server-side protocol handling for GrabKey request.
+ *
+ * Creates a grab for the client's keyboard and adds it to the list of passive
+ * grabs.
+ */
+int
+ProcGrabKey(ClientPtr client)
+{
+ WindowPtr pWin;
+ REQUEST(xGrabKeyReq);
+ GrabPtr grab;
+ DeviceIntPtr keybd = PickKeyboard(client);
+ int rc;
+ GrabParameters param;
+ GrabMask mask;
+
+ REQUEST_SIZE_MATCH(xGrabKeyReq);
+
+ memset(¶m, 0, sizeof(param));
+ param.grabtype = GRABTYPE_CORE;
+ param.ownerEvents = stuff->ownerEvents;
+ param.this_device_mode = stuff->keyboardMode;
+ param.other_devices_mode = stuff->pointerMode;
+ param.modifiers = stuff->modifiers;
+
+ rc = CheckGrabValues(client, ¶m);
+ if (rc != Success)
+ return rc;
+
+ if (((stuff->key > keybd->key->xkbInfo->desc->max_key_code) ||
+ (stuff->key < keybd->key->xkbInfo->desc->min_key_code))
+ && (stuff->key != AnyKey))
+ {
+ client->errorValue = stuff->key;
+ return BadValue;
+ }
+ rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+
+
+ mask.core = (KeyPressMask | KeyReleaseMask);
+
+ grab = CreateGrab(client->index, keybd, keybd, pWin, GRABTYPE_CORE, &mask,
+ ¶m, KeyPress, stuff->key, NullWindow, NullCursor);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(client, grab);
+}
+
+
+/**
+ * Server-side protocol handling for GrabButton request.
+ *
+ * Creates a grab for the client's ClientPointer and adds it as a passive grab
+ * to the list.
+ */
+int
+ProcGrabButton(ClientPtr client)
+{
+ WindowPtr pWin, confineTo;
+ REQUEST(xGrabButtonReq);
+ CursorPtr cursor;
+ GrabPtr grab;
+ DeviceIntPtr ptr, modifierDevice;
+ Mask access_mode = DixGrabAccess;
+ GrabMask mask;
+ GrabParameters param;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xGrabButtonReq);
+ if ((stuff->pointerMode != GrabModeSync) &&
+ (stuff->pointerMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->pointerMode;
+ return BadValue;
+ }
+ if ((stuff->keyboardMode != GrabModeSync) &&
+ (stuff->keyboardMode != GrabModeAsync))
+ {
+ client->errorValue = stuff->keyboardMode;
+ return BadValue;
+ }
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
+ {
+ client->errorValue = stuff->ownerEvents;
+ return BadValue;
+ }
+ if (stuff->eventMask & ~PointerGrabMask)
+ {
+ client->errorValue = stuff->eventMask;
+ return BadValue;
+ }
+ rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ if (stuff->confineTo == None)
+ confineTo = NullWindow;
+ else {
+ rc = dixLookupWindow(&confineTo, stuff->confineTo, client,
+ DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ }
+ if (stuff->cursor == None)
+ cursor = NullCursor;
+ else
+ {
+ rc = dixLookupResourceByType((pointer *)&cursor, stuff->cursor, RT_CURSOR,
+ client, DixUseAccess);
+ if (rc != Success)
+ if (!cursor)
+ {
+ client->errorValue = stuff->cursor;
+ return (rc == BadValue) ? BadCursor : rc;
+ }
+ access_mode |= DixForceAccess;
+ }
+
+ ptr = PickPointer(client);
+ modifierDevice = GetPairedDevice(ptr);
+ if (stuff->pointerMode == GrabModeSync ||
+ stuff->keyboardMode == GrabModeSync)
+ access_mode |= DixFreezeAccess;
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, access_mode);
+ if (rc != Success)
+ return rc;
+
+ memset(¶m, 0, sizeof(param));
+ param.grabtype = GRABTYPE_CORE;
+ param.ownerEvents = stuff->ownerEvents;
+ param.this_device_mode = stuff->keyboardMode;
+ param.other_devices_mode = stuff->pointerMode;
+ param.modifiers = stuff->modifiers;
+
+ mask.core = stuff->eventMask;
+
+ grab = CreateGrab(client->index, ptr, modifierDevice, pWin,
+ GRABTYPE_CORE, &mask, ¶m, ButtonPress,
+ stuff->button, confineTo, cursor);
+ if (!grab)
+ return BadAlloc;
+ return AddPassiveGrabToList(client, grab);
+}
+
+/**
+ * Server-side protocol handling for UngrabButton request.
+ *
+ * Deletes a passive grab on the client's ClientPointer from the list.
+ */
+int
+ProcUngrabButton(ClientPtr client)
+{
+ REQUEST(xUngrabButtonReq);
+ WindowPtr pWin;
+ GrabRec tempGrab;
+ int rc;
+ DeviceIntPtr ptr;
+
+ REQUEST_SIZE_MATCH(xUngrabButtonReq);
+ if ((stuff->modifiers != AnyModifier) &&
+ (stuff->modifiers & ~AllModifiersMask))
+ {
+ client->errorValue = stuff->modifiers;
+ return BadValue;
+ }
+ rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ ptr = PickPointer(client);
+
+ tempGrab.resource = client->clientAsMask;
+ tempGrab.device = ptr;
+ tempGrab.window = pWin;
+ tempGrab.modifiersDetail.exact = stuff->modifiers;
+ tempGrab.modifiersDetail.pMask = NULL;
+ tempGrab.modifierDevice = GetPairedDevice(ptr);
+ tempGrab.type = ButtonPress;
+ tempGrab.detail.exact = stuff->button;
+ tempGrab.grabtype = GRABTYPE_CORE;
+ tempGrab.detail.pMask = NULL;
+ tempGrab.next = NULL;
+
+ if (!DeletePassiveGrabFromList(&tempGrab))
+ return(BadAlloc);
+ return(Success);
+}
+
+/**
+ * Deactivate any grab that may be on the window, remove the focus.
+ * Delete any XInput extension events from the window too. Does not change the
+ * window mask. Use just before the window is deleted.
+ *
+ * If freeResources is set, passive grabs on the window are deleted.
+ *
+ * @param pWin The window to delete events from.
+ * @param freeResources True if resources associated with the window should be
+ * deleted.
+ */
+void
+DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
+{
+ WindowPtr parent;
+ DeviceIntPtr mouse = inputInfo.pointer;
+ DeviceIntPtr keybd = inputInfo.keyboard;
+ FocusClassPtr focus;
+ OtherClientsPtr oc;
+ GrabPtr passive;
+ GrabPtr grab;
+
+
+ /* Deactivate any grabs performed on this window, before making any
+ input focus changes. */
+ grab = mouse->deviceGrab.grab;
+ if (grab &&
+ ((grab->window == pWin) || (grab->confineTo == pWin)))
+ (*mouse->deviceGrab.DeactivateGrab)(mouse);
+
+
+ /* Deactivating a keyboard grab should cause focus events. */
+ grab = keybd->deviceGrab.grab;
+ if (grab && (grab->window == pWin))
+ (*keybd->deviceGrab.DeactivateGrab)(keybd);
+
+ /* And now the real devices */
+ for (mouse = inputInfo.devices; mouse; mouse = mouse->next)
+ {
+ grab = mouse->deviceGrab.grab;
+ if (grab && ((grab->window == pWin) || (grab->confineTo == pWin)))
+ (*mouse->deviceGrab.DeactivateGrab)(mouse);
+ }
+
+
+ for (keybd = inputInfo.devices; keybd; keybd = keybd->next)
+ {
+ if (IsKeyboardDevice(keybd))
+ {
+ focus = keybd->focus;
+
+ /* If the focus window is a root window (ie. has no parent) then don't
+ delete the focus from it. */
+
+ if ((pWin == focus->win) && (pWin->parent != NullWindow))
+ {
+ int focusEventMode = NotifyNormal;
+
+ /* If a grab is in progress, then alter the mode of focus events. */
+
+ if (keybd->deviceGrab.grab)
+ focusEventMode = NotifyWhileGrabbed;
+
+ switch (focus->revert)
+ {
+ case RevertToNone:
+ DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
+ focus->win = NoneWin;
+ focus->traceGood = 0;
+ break;
+ case RevertToParent:
+ parent = pWin;
+ do
+ {
+ parent = parent->parent;
+ focus->traceGood--;
+ } while (!parent->realized
+ /* This would be a good protocol change -- windows being reparented
+ during SaveSet processing would cause the focus to revert to the
+ nearest enclosing window which will survive the death of the exiting
+ client, instead of ending up reverting to a dying window and thence
+ to None
+ */
+#ifdef NOTDEF
+ || wClient(parent)->clientGone
+#endif
+ );
+ if (!ActivateFocusInGrab(keybd, pWin, parent))
+ DoFocusEvents(keybd, pWin, parent, focusEventMode);
+ focus->win = parent;
+ focus->revert = RevertToNone;
+ break;
+ case RevertToPointerRoot:
+ if (!ActivateFocusInGrab(keybd, pWin, PointerRootWin))
+ DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
+ focus->win = PointerRootWin;
+ focus->traceGood = 0;
+ break;
+ }
+ }
+ }
+
+ if (IsPointerDevice(keybd))
+ {
+ if (keybd->valuator->motionHintWindow == pWin)
+ keybd->valuator->motionHintWindow = NullWindow;
+ }
+ }
+
+ if (freeResources)
+ {
+ if (pWin->dontPropagate)
+ DontPropagateRefCnts[pWin->dontPropagate]--;
+ while ( (oc = wOtherClients(pWin)) )
+ FreeResource(oc->resource, RT_NONE);
+ while ( (passive = wPassiveGrabs(pWin)) )
+ FreeResource(passive->resource, RT_NONE);
+ }
+
+ DeleteWindowFromAnyExtEvents(pWin, freeResources);
+}
+
+/**
+ * Call this whenever some window at or below pWin has changed geometry. If
+ * there is a grab on the window, the cursor will be re-confined into the
+ * window.
+ */
+void
+CheckCursorConfinement(WindowPtr pWin)
+{
+ GrabPtr grab;
+ WindowPtr confineTo;
+ DeviceIntPtr pDev;
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
+#endif
+
+ for (pDev = inputInfo.devices; pDev; pDev = pDev->next)
+ {
+ if (DevHasCursor(pDev))
+ {
+ grab = pDev->deviceGrab.grab;
+ if (grab && (confineTo = grab->confineTo))
+ {
+ if (!BorderSizeNotEmpty(pDev, confineTo))
+ (*pDev->deviceGrab.DeactivateGrab)(pDev);
+ else if ((pWin == confineTo) || IsParent(pWin, confineTo))
+ ConfineCursorToWindow(pDev, confineTo, TRUE, TRUE);
+ }
+ }
+ }
+}
+
+Mask
+EventMaskForClient(WindowPtr pWin, ClientPtr client)
+{
+ OtherClientsPtr other;
+
+ if (wClient (pWin) == client)
+ return pWin->eventMask;
+ for (other = wOtherClients(pWin); other; other = other->next)
+ {
+ if (SameClient(other, client))
+ return other->mask;
+ }
+ return 0;
+}
+
+/**
+ * Server-side protocol handling for RecolorCursor request.
+ */
+int
+ProcRecolorCursor(ClientPtr client)
+{
+ CursorPtr pCursor;
+ int rc, nscr;
+ ScreenPtr pscr;
+ Bool displayed;
+ SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite;
+ REQUEST(xRecolorCursorReq);
+
+ REQUEST_SIZE_MATCH(xRecolorCursorReq);
+ rc = dixLookupResourceByType((pointer *)&pCursor, stuff->cursor, RT_CURSOR,
+ client, DixWriteAccess);
+ if (rc != Success)
+ {
+ client->errorValue = stuff->cursor;
+ return (rc == BadValue) ? BadCursor : rc;
+ }
+
+ pCursor->foreRed = stuff->foreRed;
+ pCursor->foreGreen = stuff->foreGreen;
+ pCursor->foreBlue = stuff->foreBlue;
+
+ pCursor->backRed = stuff->backRed;
+ pCursor->backGreen = stuff->backGreen;
+ pCursor->backBlue = stuff->backBlue;
+
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+ {
+ pscr = screenInfo.screens[nscr];
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension)
+ displayed = (pscr == pSprite->screen);
+ else
+#endif
+ displayed = (pscr == pSprite->hotPhys.pScreen);
+ ( *pscr->RecolorCursor)(PickPointer(client), pscr, pCursor,
+ (pCursor == pSprite->current) && displayed);
+ }
+ return (Success);
+}
+
+/**
+ * Write the given events to a client, swapping the byte order if necessary.
+ * To swap the byte ordering, a callback is called that has to be set up for
+ * the given event type.
+ *
+ * In the case of DeviceMotionNotify trailed by DeviceValuators, the events
+ * can be more than one. Usually it's just one event.
+ *
+ * Do not modify the event structure passed in. See comment below.
+ *
+ * @param pClient Client to send events to.
+ * @param count Number of events.
+ * @param events The event list.
+ */
+void
+WriteEventsToClient(ClientPtr pClient, int count, xEvent *events)
+{
+#ifdef PANORAMIX
+ xEvent eventCopy;
+#endif
+ xEvent *eventTo, *eventFrom;
+ int i,
+ eventlength = sizeof(xEvent);
+
+ /* Let XKB rewrite the state, as it depends on client preferences. */
+ XkbFilterEvents(pClient, count, events);
+
+#ifdef PANORAMIX
+ if(!noPanoramiXExtension &&
+ (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y))
+ {
+ switch(events->u.u.type) {
+ case MotionNotify:
+ case ButtonPress:
+ case ButtonRelease:
+ case KeyPress:
+ case KeyRelease:
+ case EnterNotify:
+ case LeaveNotify:
+ /*
+ When multiple clients want the same event DeliverEventsToWindow
+ passes the same event structure multiple times so we can't
+ modify the one passed to us
+ */
+ count = 1; /* should always be 1 */
+ memcpy(&eventCopy, events, sizeof(xEvent));
+ eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x;
+ eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y;
+ if(eventCopy.u.keyButtonPointer.event ==
+ eventCopy.u.keyButtonPointer.root)
+ {
+ eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
+ eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
+ }
+ events = &eventCopy;
+ break;
+ default: break;
+ }
+ }
+#endif
+
+ if (EventCallback)
+ {
+ EventInfoRec eventinfo;
+ eventinfo.client = pClient;
+ eventinfo.events = events;
+ eventinfo.count = count;
+ CallCallbacks(&EventCallback, (pointer)&eventinfo);
+ }
+#ifdef XSERVER_DTRACE
+ if (XSERVER_SEND_EVENT_ENABLED()) {
+ for (i = 0; i < count; i++)
+ {
+ XSERVER_SEND_EVENT(pClient->index, events[i].u.u.type, &events[i]);
+ }
+ }
+#endif
+ /* Just a safety check to make sure we only have one GenericEvent, it just
+ * makes things easier for me right now. (whot) */
+ for (i = 1; i < count; i++)
+ {
+ if (events[i].u.u.type == GenericEvent)
+ {
+ ErrorF("[dix] TryClientEvents: Only one GenericEvent at a time.\n");
+ return;
+ }
+ }
+
+ if (events->u.u.type == GenericEvent)
+ {
+ eventlength += ((xGenericEvent*)events)->length * 4;
+ }
+
+ if(pClient->swapped)
+ {
+ if (eventlength > swapEventLen)
+ {
+ swapEventLen = eventlength;
+ swapEvent = Xrealloc(swapEvent, swapEventLen);
+ if (!swapEvent)
+ {
+ FatalError("WriteEventsToClient: Out of memory.\n");
+ return;
+ }
+ }
+
+ for(i = 0; i < count; i++)
+ {
+ eventFrom = &events[i];
+ eventTo = swapEvent;
+
+ /* Remember to strip off the leading bit of type in case
+ this event was sent with "SendEvent." */
+ (*EventSwapVector[eventFrom->u.u.type & 0177])
+ (eventFrom, eventTo);
+
+ WriteToClient(pClient, eventlength, (char *)eventTo);
+ }
+ }
+ else
+ {
+ /* only one GenericEvent, remember? that means either count is 1 and
+ * eventlength is arbitrary or eventlength is 32 and count doesn't
+ * matter. And we're all set. Woohoo. */
+ WriteToClient(pClient, count * eventlength, (char *) events);
+ }
+}
+
+/*
+ * Set the client pointer for the given client.
+ *
+ * A client can have exactly one ClientPointer. Each time a
+ * request/reply/event is processed and the choice of devices is ambiguous
+ * (e.g. QueryPointer request), the server will pick the ClientPointer (see
+ * PickPointer()).
+ * If a keyboard is needed, the first keyboard paired with the CP is used.
+ */
+int
+SetClientPointer(ClientPtr client, DeviceIntPtr device)
+{
+ int rc = XaceHook(XACE_DEVICE_ACCESS, client, device, DixUseAccess);
+ if (rc != Success)
+ return rc;
+
+ if (!IsMaster(device))
+ {
+ ErrorF("[dix] Need master device for ClientPointer. This is a bug.\n");
+ return BadDevice;
+ } else if (!device->spriteInfo->spriteOwner)
+ {
+ ErrorF("[dix] Device %d does not have a sprite. "
+ "Cannot be ClientPointer\n", device->id);
+ return BadDevice;
+ }
+ client->clientPtr = device;
+ return Success;
+}
+
+/* PickPointer will pick an appropriate pointer for the given client.
+ *
+ * An "appropriate device" is (in order of priority):
+ * 1) A device the given client has a core grab on.
+ * 2) A device set as ClientPointer for the given client.
+ * 3) The first master device.
+ */
+DeviceIntPtr
+PickPointer(ClientPtr client)
+{
+ DeviceIntPtr it = inputInfo.devices;
+
+ /* First, check if the client currently has a grab on a device. Even
+ * keyboards count. */
+ for(it = inputInfo.devices; it; it = it->next)
+ {
+ GrabPtr grab = it->deviceGrab.grab;
+ if (grab && grab->grabtype == GRABTYPE_CORE && SameClient(grab, client))
+ {
+ it = GetMaster(it, MASTER_POINTER);
+ return it; /* Always return a core grabbed device */
+ }
+ }
+
+ if (!client->clientPtr)
+ {
+ DeviceIntPtr it = inputInfo.devices;
+ while (it)
+ {
+ if (IsMaster(it) && it->spriteInfo->spriteOwner)
+ {
+ client->clientPtr = it;
+ break;
+ }
+ it = it->next;
+ }
+ }
+ return client->clientPtr;
+}
+
+/* PickKeyboard will pick an appropriate keyboard for the given client by
+ * searching the list of devices for the keyboard device that is paired with
+ * the client's pointer.
+ */
+DeviceIntPtr
+PickKeyboard(ClientPtr client)
+{
+ DeviceIntPtr ptr = PickPointer(client);
+ DeviceIntPtr kbd = GetMaster(ptr, MASTER_KEYBOARD);
+
+ if (!kbd)
+ {
+ ErrorF("[dix] ClientPointer not paired with a keyboard. This "
+ "is a bug.\n");
+ }
+
+ return kbd;
+}
+
+/* A client that has one or more core grabs does not get core events from
+ * devices it does not have a grab on. Legacy applications behave bad
+ * otherwise because they are not used to it and the events interfere.
+ * Only applies for core events.
+ *
+ * Return true if a core event from the device would interfere and should not
+ * be delivered.
+ */
+Bool
+IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent* event)
+{
+ DeviceIntPtr it = inputInfo.devices;
+
+ switch(event->u.u.type)
+ {
+ case KeyPress:
+ case KeyRelease:
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ case EnterNotify:
+ case LeaveNotify:
+ break;
+ default:
+ return FALSE;
+ }
+
+ if (dev->deviceGrab.grab && SameClient(dev->deviceGrab.grab, client))
+ return FALSE;
+
+ while(it)
+ {
+ if (it != dev)
+ {
+ if (it->deviceGrab.grab && SameClient(it->deviceGrab.grab, client)
+ && !it->deviceGrab.fromPassiveGrab)
+ {
+ if ((IsPointerDevice(it) && IsPointerDevice(dev)) ||
+ (IsKeyboardDevice(it) && IsKeyboardDevice(dev)))
+ return TRUE;
+ }
+ }
+ it = it->next;
+ }
+
+ return FALSE;
+}
+
diff --git a/xorg-server/dix/getevents.c b/xorg-server/dix/getevents.c index 82bb77b4b..8134c4d77 100644 --- a/xorg-server/dix/getevents.c +++ b/xorg-server/dix/getevents.c @@ -1,1207 +1,1215 @@ -/* - * Copyright © 2006 Nokia Corporation - * Copyright © 2006-2007 Daniel Stone - * Copyright © 2008 Red Hat, Inc. - * - * 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. - * - * Authors: Daniel Stone <daniel@fooishbar.org> - * Peter Hutterer <peter.hutterer@who-t.net> - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <X11/X.h> -#include <X11/keysym.h> -#include <X11/Xproto.h> - -#include "misc.h" -#include "resource.h" -#include "inputstr.h" -#include "scrnintstr.h" -#include "cursorstr.h" -#include "dixstruct.h" -#include "globals.h" -#include "dixevents.h" -#include "mipointer.h" -#include "eventstr.h" -#include "eventconvert.h" - -#include <X11/extensions/XKBproto.h> -#include "xkbsrv.h" - -#ifdef PANORAMIX -#include "panoramiX.h" -#include "panoramiXsrv.h" -#endif - -#include <X11/extensions/XI.h> -#include <X11/extensions/XIproto.h> -#include "exglobals.h" -#include "exevents.h" -#include "exglobals.h" -#include "extnsionst.h" -#include "listdev.h" /* for sizing up DeviceClassesChangedEvent */ - -/* Number of motion history events to store. */ -#define MOTION_HISTORY_SIZE 256 - -/* InputEventList is the container list for all input events generated by the - * DDX. The DDX is expected to call GetEventList() and then pass the list into - * Get{Pointer|Keyboard}Events. - */ -EventListPtr InputEventList = NULL; -int InputEventListLen = 0; - -int -GetEventList(EventListPtr* list) -{ - *list = InputEventList; - return InputEventListLen; -} - -/** - * Pick some arbitrary size for Xi motion history. - */ -int -GetMotionHistorySize(void) -{ - return MOTION_HISTORY_SIZE; -} - -void -set_key_down(DeviceIntPtr pDev, int key_code, int type) -{ - if (type == KEY_PROCESSED) - pDev->key->down[key_code >> 3] |= (1 << (key_code & 7)); - else - pDev->key->postdown[key_code >> 3] |= (1 << (key_code & 7)); -} - -void -set_key_up(DeviceIntPtr pDev, int key_code, int type) -{ - if (type == KEY_PROCESSED) - pDev->key->down[key_code >> 3] &= ~(1 << (key_code & 7)); - else - pDev->key->postdown[key_code >> 3] &= ~(1 << (key_code & 7)); -} - -Bool -key_is_down(DeviceIntPtr pDev, int key_code, int type) -{ - int ret = 0; - - if (type & KEY_PROCESSED) - ret |= !!(pDev->key->down[key_code >> 3] & (1 << (key_code & 7))); - else if (type & KEY_POSTED) - ret |= !!(pDev->key->postdown[key_code >> 3] & (1 << (key_code & 7))); - - return ret; -} - -static Bool -key_autorepeats(DeviceIntPtr pDev, int key_code) -{ - return !!(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] & - (1 << (key_code & 7))); -} - -static void -init_event(DeviceIntPtr dev, DeviceEvent* event, Time ms) -{ - memset(event, 0, sizeof(DeviceEvent)); - event->header = ET_Internal; - event->length = sizeof(DeviceEvent); - event->time = ms; - event->deviceid = dev->id; - event->sourceid = dev->id; -} - -static void -init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail) -{ - memset(event, 0, sizeof(RawDeviceEvent)); - event->header = ET_Internal; - event->length = sizeof(RawDeviceEvent); - event->type = ET_RawKeyPress - ET_KeyPress + type; - event->time = ms; - event->deviceid = dev->id; - event->sourceid = dev->id; - event->detail.button = detail; -} - -static void -set_raw_valuators(RawDeviceEvent *event, int first, int num, int *valuators, int32_t* data) -{ - int i; - for (i = first; i < first + num; i++) - SetBit(event->valuators.mask, i); - - memcpy(&data[first], valuators, num * sizeof(uint32_t)); -} - - -static void -set_valuators(DeviceIntPtr dev, DeviceEvent* event, int first_valuator, - int num_valuators, int *valuators) -{ - int i; - - for (i = first_valuator; i < first_valuator + num_valuators; i++) - { - SetBit(event->valuators.mask, i); - if (dev->valuator->mode == Absolute) - SetBit(event->valuators.mode, i); - event->valuators.data_frac[i] = - dev->last.remainder[i] * (1 << 16) * (1 << 16); - } - - memcpy(&event->valuators.data[first_valuator], - valuators, num_valuators * sizeof(uint32_t)); - -} - -void -CreateClassesChangedEvent(EventList* event, - DeviceIntPtr master, - DeviceIntPtr slave, - int type) -{ - int i; - DeviceChangedEvent *dce; - CARD32 ms = GetTimeInMillis(); - - dce = (DeviceChangedEvent*)event->event; - memset(dce, 0, sizeof(DeviceChangedEvent)); - dce->deviceid = slave->id; - dce->masterid = master->id; - dce->header = ET_Internal; - dce->length = sizeof(DeviceChangedEvent); - dce->type = ET_DeviceChanged; - dce->time = ms; - dce->flags = type; - dce->flags |= DEVCHANGE_SLAVE_SWITCH; - dce->sourceid = slave->id; - - if (slave->button) - { - dce->buttons.num_buttons = slave->button->numButtons; - for (i = 0; i < dce->buttons.num_buttons; i++) - dce->buttons.names[i] = slave->button->labels[i]; - } - if (slave->valuator) - { - dce->num_valuators = slave->valuator->numAxes; - for (i = 0; i < dce->num_valuators; i++) - { - dce->valuators[i].min = slave->valuator->axes[i].min_value; - dce->valuators[i].max = slave->valuator->axes[i].max_value; - dce->valuators[i].resolution = slave->valuator->axes[i].resolution; - /* This should, eventually, be a per-axis mode */ - dce->valuators[i].mode = slave->valuator->mode; - dce->valuators[i].name = slave->valuator->axes[i].label; - } - } - if (slave->key) - { - dce->keys.min_keycode = slave->key->xkbInfo->desc->min_key_code; - dce->keys.max_keycode = slave->key->xkbInfo->desc->max_key_code; - } -} - -/** - * Rescale the coord between the two axis ranges. - */ -static int -rescaleValuatorAxis(int coord, float remainder, float *remainder_return, AxisInfoPtr from, AxisInfoPtr to, - int defmax) -{ - int fmin = 0, tmin = 0, fmax = defmax, tmax = defmax, coord_return; - float value; - - if(from && from->min_value < from->max_value) { - fmin = from->min_value; - fmax = from->max_value; - } - if(to && to->min_value < to->max_value) { - tmin = to->min_value; - tmax = to->max_value; - } - - if(fmin == tmin && fmax == tmax) { - if (remainder_return) - *remainder_return = remainder; - return coord; - } - - if(fmax == fmin) { /* avoid division by 0 */ - if (remainder_return) - *remainder_return = 0.0; - return 0; - } - - value = (coord + remainder - fmin) * (tmax - tmin) / (fmax - fmin) + tmin; - coord_return = lroundf(value); - if (remainder_return) - *remainder_return = value - coord_return; - return coord_return; -} - -/** - * Update all coordinates when changing to a different SD - * to ensure that relative reporting will work as expected - * without loss of precision. - * - * pDev->last.valuators will be in absolute device coordinates after this - * function. - */ -static void -updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev) -{ - ScreenPtr scr = miPointerGetScreen(pDev); - int i; - DeviceIntPtr lastSlave; - - /* master->last.valuators[0]/[1] is in screen coords and the actual - * position of the pointer */ - pDev->last.valuators[0] = master->last.valuators[0]; - pDev->last.valuators[1] = master->last.valuators[1]; - - if (!pDev->valuator) - return; - - /* scale back to device coordinates */ - if(pDev->valuator->numAxes > 0) - pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0], pDev->last.remainder[0], - &pDev->last.remainder[0], NULL, pDev->valuator->axes + 0, scr->width); - if(pDev->valuator->numAxes > 1) - pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1], pDev->last.remainder[1], - &pDev->last.remainder[1], NULL, pDev->valuator->axes + 1, scr->height); - - /* calculate the other axis as well based on info from the old - * slave-device. If the old slave had less axes than this one, - * last.valuators is reset to 0. - */ - if ((lastSlave = master->last.slave) && lastSlave->valuator) { - for (i = 2; i < pDev->valuator->numAxes; i++) { - if (i >= lastSlave->valuator->numAxes) - pDev->last.valuators[i] = 0; - else - pDev->last.valuators[i] = - rescaleValuatorAxis(pDev->last.valuators[i], - pDev->last.remainder[i], - &pDev->last.remainder[i], - lastSlave->valuator->axes + i, - pDev->valuator->axes + i, 0); - } - } - -} - -/** - * Allocate the motion history buffer. - */ -void -AllocateMotionHistory(DeviceIntPtr pDev) -{ - int size; - if (pDev->valuator->motion) - xfree(pDev->valuator->motion); - - if (pDev->valuator->numMotionEvents < 1) - return; - - /* An MD must have a motion history size large enough to keep all - * potential valuators, plus the respective range of the valuators. - * 3 * INT32 for (min_val, max_val, curr_val)) - */ - if (IsMaster(pDev)) - size = sizeof(INT32) * 3 * MAX_VALUATORS; - else - size = sizeof(INT32) * pDev->valuator->numAxes; - - size += sizeof(Time); - - pDev->valuator->motion = xcalloc(pDev->valuator->numMotionEvents, size); - pDev->valuator->first_motion = 0; - pDev->valuator->last_motion = 0; - if (!pDev->valuator->motion) - ErrorF("[dix] %s: Failed to alloc motion history (%d bytes).\n", - pDev->name, size * pDev->valuator->numMotionEvents); -} - -/** - * Dump the motion history between start and stop into the supplied buffer. - * Only records the event for a given screen in theory, but in practice, we - * sort of ignore this. - * - * If core is set, we only generate x/y, in INT16, scaled to screen coords. - */ -int -GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start, - unsigned long stop, ScreenPtr pScreen, BOOL core) -{ - char *ibuff = NULL, *obuff; - int i = 0, ret = 0; - int j, coord; - Time current; - /* The size of a single motion event. */ - int size; - int dflt; - AxisInfo from, *to; /* for scaling */ - INT32 *ocbuf, *icbuf; /* pointer to coordinates for copying */ - INT16 *corebuf; - AxisInfo core_axis = {0}; - - if (!pDev->valuator || !pDev->valuator->numMotionEvents) - return 0; - - if (core && !pScreen) - return 0; - - if (IsMaster(pDev)) - size = (sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(Time); - else - size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time); - - *buff = xalloc(size * pDev->valuator->numMotionEvents); - if (!(*buff)) - return 0; - obuff = (char *)*buff; - - for (i = pDev->valuator->first_motion; - i != pDev->valuator->last_motion; - i = (i + 1) % pDev->valuator->numMotionEvents) { - /* We index the input buffer by which element we're accessing, which - * is not monotonic, and the output buffer by how many events we've - * written so far. */ - ibuff = (char *) pDev->valuator->motion + (i * size); - memcpy(¤t, ibuff, sizeof(Time)); - - if (current > stop) { - return ret; - } - else if (current >= start) { - if (core) - { - memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */ - - icbuf = (INT32*)(ibuff + sizeof(Time)); - corebuf = (INT16*)(obuff + sizeof(Time)); - - /* fetch x coordinate + range */ - memcpy(&from.min_value, icbuf++, sizeof(INT32)); - memcpy(&from.max_value, icbuf++, sizeof(INT32)); - memcpy(&coord, icbuf++, sizeof(INT32)); - - /* scale to screen coords */ - to = &core_axis; - to->max_value = pScreen->width; - coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->width); - - memcpy(corebuf, &coord, sizeof(INT16)); - corebuf++; - - /* fetch y coordinate + range */ - memcpy(&from.min_value, icbuf++, sizeof(INT32)); - memcpy(&from.max_value, icbuf++, sizeof(INT32)); - memcpy(&coord, icbuf++, sizeof(INT32)); - - to->max_value = pScreen->height; - coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->height); - memcpy(corebuf, &coord, sizeof(INT16)); - - } else if (IsMaster(pDev)) - { - memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */ - - ocbuf = (INT32*)(obuff + sizeof(Time)); - icbuf = (INT32*)(ibuff + sizeof(Time)); - for (j = 0; j < MAX_VALUATORS; j++) - { - if (j >= pDev->valuator->numAxes) - break; - - /* fetch min/max/coordinate */ - memcpy(&from.min_value, icbuf++, sizeof(INT32)); - memcpy(&from.max_value, icbuf++, sizeof(INT32)); - memcpy(&coord, icbuf++, sizeof(INT32)); - - to = (j < pDev->valuator->numAxes) ? &pDev->valuator->axes[j] : NULL; - - /* x/y scaled to screen if no range is present */ - if (j == 0 && (from.max_value < from.min_value)) - from.max_value = pScreen->width; - else if (j == 1 && (from.max_value < from.min_value)) - from.max_value = pScreen->height; - - if (j == 0 && (to->max_value < to->min_value)) - dflt = pScreen->width; - else if (j == 1 && (to->max_value < to->min_value)) - dflt = pScreen->height; - else - dflt = 0; - - /* scale from stored range into current range */ - coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, 0); - memcpy(ocbuf, &coord, sizeof(INT32)); - ocbuf++; - } - } else - memcpy(obuff, ibuff, size); - - /* don't advance by size here. size may be different to the - * actually written size if the MD has less valuators than MAX */ - if (core) - obuff += sizeof(INT32) + sizeof(Time); - else - obuff += (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time); - ret++; - } - } - - return ret; -} - - -/** - * Update the motion history for a specific device, with the list of - * valuators. - * - * Layout of the history buffer: - * for SDs: [time] [val0] [val1] ... [valn] - * for MDs: [time] [min_val0] [max_val0] [val0] [min_val1] ... [valn] - * - * For events that have some valuators unset (first_valuator > 0): - * min_val == max_val == val == 0. - */ -static void -updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator, - int num_valuators, int *valuators) -{ - char *buff = (char *) pDev->valuator->motion; - ValuatorClassPtr v; - int i; - - if (!pDev->valuator->numMotionEvents) - return; - - v = pDev->valuator; - if (IsMaster(pDev)) - { - buff += ((sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(CARD32)) * - v->last_motion; - - memcpy(buff, &ms, sizeof(Time)); - buff += sizeof(Time); - - memset(buff, 0, sizeof(INT32) * 3 * MAX_VALUATORS); - buff += 3 * sizeof(INT32) * first_valuator; - - for (i = first_valuator; i < first_valuator + num_valuators; i++) - { - if (i >= v->numAxes) - break; - memcpy(buff, &v->axes[i].min_value, sizeof(INT32)); - buff += sizeof(INT32); - memcpy(buff, &v->axes[i].max_value, sizeof(INT32)); - buff += sizeof(INT32); - memcpy(buff, &valuators[i - first_valuator], sizeof(INT32)); - buff += sizeof(INT32); - } - } else - { - - buff += ((sizeof(INT32) * pDev->valuator->numAxes) + sizeof(CARD32)) * - pDev->valuator->last_motion; - - memcpy(buff, &ms, sizeof(Time)); - buff += sizeof(Time); - - memset(buff, 0, sizeof(INT32) * pDev->valuator->numAxes); - buff += sizeof(INT32) * first_valuator; - - memcpy(buff, valuators, sizeof(INT32) * num_valuators); - } - - pDev->valuator->last_motion = (pDev->valuator->last_motion + 1) % - pDev->valuator->numMotionEvents; - /* If we're wrapping around, just keep the circular buffer going. */ - if (pDev->valuator->first_motion == pDev->valuator->last_motion) - pDev->valuator->first_motion = (pDev->valuator->first_motion + 1) % - pDev->valuator->numMotionEvents; - - return; -} - - -/** - * Returns the maximum number of events GetKeyboardEvents, - * GetKeyboardValuatorEvents, and GetPointerEvents will ever return. - * - * This MUST be absolutely constant, from init until exit. - */ -int -GetMaximumEventsNum(void) { - /* One raw event - * One device event - * One possible device changed event - */ - return 3; -} - - -/** - * Clip an axis to its bounds, which are declared in the call to - * InitValuatorAxisClassStruct. - */ -static void -clipAxis(DeviceIntPtr pDev, int axisNum, int *val) -{ - AxisInfoPtr axis; - - if (axisNum >= pDev->valuator->numAxes) - return; - - axis = pDev->valuator->axes + axisNum; - - /* If a value range is defined, clip. If not, do nothing */ - if (axis->max_value <= axis->min_value) - return; - - if (*val < axis->min_value) - *val = axis->min_value; - if (*val > axis->max_value) - *val = axis->max_value; -} - -/** - * Clip every axis in the list of valuators to its bounds. - */ -static void -clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators, - int *valuators) -{ - int i; - - for (i = 0; i < num_valuators; i++) - clipAxis(pDev, i + first_valuator, &(valuators[i])); -} - -/** - * Create the DCCE event (does not update the master's device state yet, this - * is done in the event processing). - * Pull in the coordinates from the MD if necessary. - * - * @param events Pointer to a pre-allocated event list. - * @param dev The slave device that generated an event. - * @param type Either DEVCHANGE_POINTER_EVENT and/or DEVCHANGE_KEYBOARD_EVENT - * @param num_events The current number of events, returns the number of - * events if a DCCE was generated. - * @return The updated @events pointer. - */ -static EventListPtr -updateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events) -{ - DeviceIntPtr master; - - master = GetMaster(dev, (type & DEVCHANGE_POINTER_EVENT) ? MASTER_POINTER : MASTER_KEYBOARD); - - if (master && master->last.slave != dev) - { - CreateClassesChangedEvent(events, master, dev, type); - if (IsPointerDevice(master)) - { - updateSlaveDeviceCoords(master, dev); - master->last.numValuators = dev->last.numValuators; - } - master->last.slave = dev; - (*num_events)++; - events++; - } - return events; -} - -/** - * Move the device's pointer to the position given in the valuators. - * - * @param dev The device which's pointer is to be moved. - * @param x Returns the x position of the pointer after the move. - * @param y Returns the y position of the pointer after the move. - * @param first The first valuator in @valuators - * @param num Total number of valuators in @valuators. - * @param valuators Valuator data for each axis between @first and - * @first+@num. - */ -static void -moveAbsolute(DeviceIntPtr dev, int *x, int *y, - int first, int num, int *valuators) -{ - int i; - - - if (num >= 1 && first == 0) - *x = *(valuators + 0); - else - *x = dev->last.valuators[0]; - - if (first <= 1 && num >= (2 - first)) - *y = *(valuators + 1 - first); - else - *y = dev->last.valuators[1]; - - clipAxis(dev, 0, x); - clipAxis(dev, 1, y); - - i = (first > 2) ? 0 : 2; - for (; i < num; i++) - { - dev->last.valuators[i + first] = valuators[i]; - clipAxis(dev, i, &dev->last.valuators[i + first]); - } -} - -/** - * Move the device's pointer by the values given in @valuators. - * - * @param dev The device which's pointer is to be moved. - * @param x Returns the x position of the pointer after the move. - * @param y Returns the y position of the pointer after the move. - * @param first The first valuator in @valuators - * @param num Total number of valuators in @valuators. - * @param valuators Valuator data for each axis between @first and - * @first+@num. - */ -static void -moveRelative(DeviceIntPtr dev, int *x, int *y, - int first, int num, int *valuators) -{ - int i; - - *x = dev->last.valuators[0]; - *y = dev->last.valuators[1]; - - if (num >= 1 && first == 0) - *x += *(valuators +0); - - if (first <= 1 && num >= (2 - first)) - *y += *(valuators + 1 - first); - - /* if attached, clip both x and y to the defined limits (usually - * co-ord space limit). If it is attached, we need x/y to go over the - * limits to be able to change screens. */ - if(dev->u.master) { - clipAxis(dev, 0, x); - clipAxis(dev, 1, y); - } - - /* calc other axes, clip, drop back into valuators */ - i = (first > 2) ? 0 : 2; - for (; i < num; i++) - { - dev->last.valuators[i + first] += valuators[i]; - clipAxis(dev, i, &dev->last.valuators[i + first]); - valuators[i] = dev->last.valuators[i + first]; - } -} - -/** - * Accelerate the data in valuators based on the device's acceleration scheme. - * - * @param dev The device which's pointer is to be moved. - * @param first The first valuator in @valuators - * @param num Total number of valuators in @valuators. - * @param valuators Valuator data for each axis between @first and - * @first+@num. - * @param ms Current time. - */ -static void -accelPointer(DeviceIntPtr dev, int first, int num, int *valuators, CARD32 ms) -{ - if (dev->valuator->accelScheme.AccelSchemeProc) - dev->valuator->accelScheme.AccelSchemeProc(dev, first, num, valuators, ms); -} - -/** - * If we have HW cursors, this actually moves the visible sprite. If not, we - * just do all the screen crossing, etc. - * - * We scale from device to screen coordinates here, call - * miPointerSetPosition() and then scale back into device coordinates (if - * needed). miPSP will change x/y if the screen was crossed. - * - * @param dev The device to be moved. - * @param x Pointer to current x-axis value, may be modified. - * @param y Pointer to current y-axis value, may be modified. - * @param x_frac Fractional part of current x-axis value, may be modified. - * @param y_frac Fractional part of current y-axis value, may be modified. - * @param scr Screen the device's sprite is currently on. - * @param screenx Screen x coordinate the sprite is on after the update. - * @param screeny Screen y coordinate the sprite is on after the update. - * @param screenx_frac Fractional part of screen x coordinate, as above. - * @param screeny_frac Fractional part of screen y coordinate, as above. - */ -static void -positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac, - ScreenPtr scr, int *screenx, int *screeny, float *screenx_frac, float *screeny_frac) -{ - int old_screenx, old_screeny; - - /* scale x&y to screen */ - if (dev->valuator->numAxes > 0) { - *screenx = rescaleValuatorAxis(*x, x_frac, screenx_frac, - dev->valuator->axes + 0, NULL, scr->width); - } else { - *screenx = dev->last.valuators[0]; - *screenx_frac = dev->last.remainder[0]; - } - - if (dev->valuator->numAxes > 1) { - *screeny = rescaleValuatorAxis(*y, y_frac, screeny_frac, - dev->valuator->axes + 1, NULL, scr->height); - } else { - *screeny = dev->last.valuators[1]; - *screeny_frac = dev->last.remainder[1]; - } - - /* Hit the left screen edge? */ - if (*screenx <= 0 && *screenx_frac < 0.0f) - { - *screenx_frac = 0.0f; - x_frac = 0.0f; - } - if (*screeny <= 0 && *screeny_frac < 0.0f) - { - *screeny_frac = 0.0f; - y_frac = 0.0f; - } - - - old_screenx = *screenx; - old_screeny = *screeny; - /* This takes care of crossing screens for us, as well as clipping - * to the current screen. */ - miPointerSetPosition(dev, screenx, screeny); - - if (dev->u.master) { - dev->u.master->last.valuators[0] = *screenx; - dev->u.master->last.valuators[1] = *screeny; - dev->u.master->last.remainder[0] = *screenx_frac; - dev->u.master->last.remainder[1] = *screeny_frac; - } - - /* Crossed screen? Scale back to device coordiantes */ - if(*screenx != old_screenx) - { - scr = miPointerGetScreen(dev); - *x = rescaleValuatorAxis(*screenx, *screenx_frac, &x_frac, NULL, - dev->valuator->axes + 0, scr->width); - } - if(*screeny != old_screeny) - { - scr = miPointerGetScreen(dev); - *y = rescaleValuatorAxis(*screeny, *screeny_frac, &y_frac, NULL, - dev->valuator->axes + 1, scr->height); - } - - /* dropy x/y (device coordinates) back into valuators for next event */ - dev->last.valuators[0] = *x; - dev->last.valuators[1] = *y; - dev->last.remainder[0] = x_frac; - dev->last.remainder[1] = y_frac; -} - -/** - * Update the motion history for the device and (if appropriate) for its - * master device. - * @param dev Slave device to update. - * @param first First valuator to append to history. - * @param num Total number of valuators to append to history. - * @param ms Current time - */ -static void -updateHistory(DeviceIntPtr dev, int first, int num, CARD32 ms) -{ - updateMotionHistory(dev, ms, first, num, &dev->last.valuators[first]); - if (dev->u.master) - { - DeviceIntPtr master = GetMaster(dev, MASTER_POINTER); - updateMotionHistory(master, ms, first, num, &dev->last.valuators[first]); - } -} - -/** - * Convenience wrapper around GetKeyboardValuatorEvents, that takes no - * valuators. - */ -int -GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code) { - return GetKeyboardValuatorEvents(events, pDev, type, key_code, 0, 0, NULL); -} - - -/** - * Returns a set of keyboard events for KeyPress/KeyRelease, optionally - * also with valuator events. Handles Xi and XKB. - * - * DOES NOT GENERATE CORE EVENTS! Core events are created when processing the - * event (ProcessOtherEvent). - * - * events is not NULL-terminated; the return value is the number of events. - * The DDX is responsible for allocating the event structure in the first - * place via GetMaximumEventsNum(), and for freeing it. - * - * This function does not change the core keymap to that of the device; - * that is done by SwitchCoreKeyboard, which is called from - * mieqProcessInputEvents. If replacing that function, take care to call - * SetCoreKeyboard before processInputProc, so keymaps are altered to suit. - */ -int -GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type, - int key_code, int first_valuator, - int num_valuators, int *valuators) { - int num_events = 0; - CARD32 ms = 0; - DeviceEvent *event; - RawDeviceEvent *raw; - - /* refuse events from disabled devices */ - if (!pDev->enabled) - return 0; - - if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed || - (type != KeyPress && type != KeyRelease) || - (key_code < 8 || key_code > 255)) - return 0; - - num_events = 1; - - events = updateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events); - - /* Handle core repeating, via press/release/press/release. */ - if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) { - /* If autorepeating is disabled either globally or just for that key, - * or we have a modifier, don't generate a repeat event. */ - if (!pDev->kbdfeed->ctrl.autoRepeat || - !key_autorepeats(pDev, key_code) || - pDev->key->xkbInfo->desc->map->modmap[key_code]) - return 0; - } - - ms = GetTimeInMillis(); - - raw = (RawDeviceEvent*)events->event; - events++; - num_events++; - - init_raw(pDev, raw, ms, type, key_code); - set_raw_valuators(raw, first_valuator, num_valuators, valuators, - raw->valuators.data_raw); - - if (num_valuators) - clipValuators(pDev, first_valuator, num_valuators, valuators); - - set_raw_valuators(raw, first_valuator, num_valuators, valuators, - raw->valuators.data); - - event = (DeviceEvent*) events->event; - init_event(pDev, event, ms); - event->detail.key = key_code; - - if (type == KeyPress) { - event->type = ET_KeyPress; - set_key_down(pDev, key_code, KEY_POSTED); - } - else if (type == KeyRelease) { - event->type = ET_KeyRelease; - set_key_up(pDev, key_code, KEY_POSTED); - } - - if (num_valuators) - clipValuators(pDev, first_valuator, num_valuators, valuators); - - set_valuators(pDev, event, first_valuator, num_valuators, valuators); - - return num_events; -} - -/** - * Initialize an event list and fill with 32 byte sized events. - * This event list is to be passed into GetPointerEvents() and - * GetKeyboardEvents(). - * - * @param num_events Number of elements in list. - */ -EventListPtr -InitEventList(int num_events) -{ - EventListPtr events; - int i; - - events = (EventListPtr)xcalloc(num_events, sizeof(EventList)); - if (!events) - return NULL; - - for (i = 0; i < num_events; i++) - { - events[i].evlen = sizeof(InternalEvent); - events[i].event = xcalloc(1, sizeof(InternalEvent)); - if (!events[i].event) - { - /* rollback */ - while(i--) - xfree(events[i].event); - xfree(events); - events = NULL; - break; - } - } - - return events; -} - -/** - * Free an event list. - * - * @param list The list to be freed. - * @param num_events Number of elements in list. - */ -void -FreeEventList(EventListPtr list, int num_events) -{ - if (!list) - return; - while(num_events--) - xfree(list[num_events].event); - xfree(list); -} - -/** - * Generate a series of xEvents (filled into the EventList) representing - * pointer motion, or button presses. Xi and XKB-aware. - * - * DOES NOT GENERATE CORE EVENTS! Core events are created when processing the - * event (ProcessOtherEvent). - * - * events is not NULL-terminated; the return value is the number of events. - * The DDX is responsible for allocating the event structure in the first - * place via InitEventList() and GetMaximumEventsNum(), and for freeing it. - * - * In the generated events rootX/Y will be in absolute screen coords and - * the valuator information in the absolute or relative device coords. - * - * last.valuators[x] of the device is always in absolute device coords. - * last.valuators[x] of the master device is in absolute screen coords. - * - * master->last.valuators[x] for x > 2 is undefined. - */ -int -GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons, - int flags, int first_valuator, int num_valuators, - int *valuators) { - int num_events = 1; - CARD32 ms; - DeviceEvent *event; - RawDeviceEvent *raw; - int x = 0, y = 0, /* device coords */ - cx, cy; /* only screen coordinates */ - float x_frac = 0.0, y_frac = 0.0, cx_frac, cy_frac; - ScreenPtr scr = miPointerGetScreen(pDev); - - /* refuse events from disabled devices */ - if (!pDev->enabled) - return 0; - - ms = GetTimeInMillis(); /* before pointer update to help precision */ - - if (!scr || !pDev->valuator || first_valuator < 0 || - ((num_valuators + first_valuator) > pDev->valuator->numAxes) || - (type != MotionNotify && type != ButtonPress && type != ButtonRelease) || - (type != MotionNotify && !pDev->button) || - ((type == ButtonPress || type == ButtonRelease) && !buttons) || - (type == MotionNotify && num_valuators <= 0)) - return 0; - - events = updateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); - - raw = (RawDeviceEvent*)events->event; - events++; - num_events++; - - init_raw(pDev, raw, ms, type, buttons); - set_raw_valuators(raw, first_valuator, num_valuators, valuators, - raw->valuators.data_raw); - - if (flags & POINTER_ABSOLUTE) - { - if (flags & POINTER_SCREEN) /* valuators are in screen coords */ - { - - if (num_valuators >= 1 && first_valuator == 0) - valuators[0] = rescaleValuatorAxis(valuators[0], 0.0, &x_frac, NULL, - pDev->valuator->axes + 0, - scr->width); - if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) - valuators[1 - first_valuator] = rescaleValuatorAxis(valuators[1 - first_valuator], 0.0, &y_frac, NULL, - pDev->valuator->axes + 1, - scr->height); - } - - moveAbsolute(pDev, &x, &y, first_valuator, num_valuators, valuators); - } else { - if (flags & POINTER_ACCELERATE) { - accelPointer(pDev, first_valuator, num_valuators, valuators, ms); - /* The pointer acceleration code modifies the fractional part - * in-place, so we need to extract this information first */ - x_frac = pDev->last.remainder[0]; - y_frac = pDev->last.remainder[1]; - } - moveRelative(pDev, &x, &y, first_valuator, num_valuators, valuators); - } - - set_raw_valuators(raw, first_valuator, num_valuators, valuators, - raw->valuators.data); - - positionSprite(pDev, &x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac); - updateHistory(pDev, first_valuator, num_valuators, ms); - - /* Update the valuators with the true value sent to the client*/ - if (num_valuators >= 1 && first_valuator == 0) - valuators[0] = x; - if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) - valuators[1 - first_valuator] = y; - - if (num_valuators) - clipValuators(pDev, first_valuator, num_valuators, valuators); - - event = (DeviceEvent*) events->event; - init_event(pDev, event, ms); - - if (type == MotionNotify) { - event->type = ET_Motion; - event->detail.button = 0; - } - else { - if (type == ButtonPress) { - event->type = ET_ButtonPress; - pDev->button->postdown[buttons >> 3] |= (1 << (buttons & 7)); - } - else if (type == ButtonRelease) { - event->type = ET_ButtonRelease; - pDev->button->postdown[buttons >> 3] &= ~(1 << (buttons & 7)); - } - event->detail.button = buttons; - } - - event->root_x = cx; /* root_x/y always in screen coords */ - event->root_y = cy; - event->root_x_frac = cx_frac; - event->root_y_frac = cy_frac; - - set_valuators(pDev, event, first_valuator, num_valuators, valuators); - - return num_events; -} - - -/** - * Post ProximityIn/ProximityOut events, accompanied by valuators. - * - * events is not NULL-terminated; the return value is the number of events. - * The DDX is responsible for allocating the event structure in the first - * place via GetMaximumEventsNum(), and for freeing it. - */ -int -GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, - int first_valuator, int num_valuators, int *valuators) -{ - int num_events = 1; - DeviceEvent *event; - - /* refuse events from disabled devices */ - if (!pDev->enabled) - return 0; - - /* Sanity checks. */ - if (type != ProximityIn && type != ProximityOut) - return 0; - if (!pDev->valuator) - return 0; - /* Do we need to send a DeviceValuator event? */ - if ((pDev->valuator->mode & 1) == Relative) - num_valuators = 0; - - /* You fail. */ - if (first_valuator < 0 || - (num_valuators + first_valuator) > pDev->valuator->numAxes) - return 0; - - events = updateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events); - - event = (DeviceEvent *) events->event; - init_event(pDev, event, GetTimeInMillis()); - event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut; - - if (num_valuators) - clipValuators(pDev, first_valuator, num_valuators, valuators); - - set_valuators(pDev, event, first_valuator, num_valuators, valuators); - - return num_events; -} - -/** - * Synthesize a single motion event for the core pointer. - * - * Used in cursor functions, e.g. when cursor confinement changes, and we need - * to shift the pointer to get it inside the new bounds. - */ -void -PostSyntheticMotion(DeviceIntPtr pDev, - int x, - int y, - int screen, - unsigned long time) -{ - DeviceEvent ev; - -#ifdef PANORAMIX - /* Translate back to the sprite screen since processInputProc - will translate from sprite screen to screen 0 upon reentry - to the DIX layer. */ - if (!noPanoramiXExtension) { - x += panoramiXdataPtr[0].x - panoramiXdataPtr[screen].x; - y += panoramiXdataPtr[0].y - panoramiXdataPtr[screen].y; - } -#endif - - memset(&ev, 0, sizeof(DeviceEvent)); - init_event(pDev, &ev, time); - ev.root_x = x; - ev.root_y = y; - ev.type = ET_Motion; - ev.time = time; - - /* FIXME: MD/SD considerations? */ - (*pDev->public.processInputProc)((InternalEvent*)&ev, pDev); -} +/*
+ * Copyright © 2006 Nokia Corporation
+ * Copyright © 2006-2007 Daniel Stone
+ * Copyright © 2008 Red Hat, Inc.
+ *
+ * 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.
+ *
+ * Authors: Daniel Stone <daniel@fooishbar.org>
+ * Peter Hutterer <peter.hutterer@who-t.net>
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/keysym.h>
+#include <X11/Xproto.h>
+
+#include "misc.h"
+#include "resource.h"
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+#include "dixstruct.h"
+#include "globals.h"
+#include "dixevents.h"
+#include "mipointer.h"
+#include "eventstr.h"
+#include "eventconvert.h"
+
+#include <X11/extensions/XKBproto.h>
+#include "xkbsrv.h"
+
+#ifdef PANORAMIX
+#include "panoramiX.h"
+#include "panoramiXsrv.h"
+#endif
+
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include "exglobals.h"
+#include "exevents.h"
+#include "exglobals.h"
+#include "extnsionst.h"
+#include "listdev.h" /* for sizing up DeviceClassesChangedEvent */
+
+#ifdef _MSC_VER
+float roundf(float f)
+{
+ return ((f<0.0f) ? ceil(f-.5) : floor (f+.5));
+}
+#define lroundf(val) ((int)roundf(val))
+#endif
+
+/* Number of motion history events to store. */
+#define MOTION_HISTORY_SIZE 256
+
+/* InputEventList is the container list for all input events generated by the
+ * DDX. The DDX is expected to call GetEventList() and then pass the list into
+ * Get{Pointer|Keyboard}Events.
+ */
+EventListPtr InputEventList = NULL;
+int InputEventListLen = 0;
+
+int
+GetEventList(EventListPtr* list)
+{
+ *list = InputEventList;
+ return InputEventListLen;
+}
+
+/**
+ * Pick some arbitrary size for Xi motion history.
+ */
+int
+GetMotionHistorySize(void)
+{
+ return MOTION_HISTORY_SIZE;
+}
+
+void
+set_key_down(DeviceIntPtr pDev, int key_code, int type)
+{
+ if (type == KEY_PROCESSED)
+ pDev->key->down[key_code >> 3] |= (1 << (key_code & 7));
+ else
+ pDev->key->postdown[key_code >> 3] |= (1 << (key_code & 7));
+}
+
+void
+set_key_up(DeviceIntPtr pDev, int key_code, int type)
+{
+ if (type == KEY_PROCESSED)
+ pDev->key->down[key_code >> 3] &= ~(1 << (key_code & 7));
+ else
+ pDev->key->postdown[key_code >> 3] &= ~(1 << (key_code & 7));
+}
+
+Bool
+key_is_down(DeviceIntPtr pDev, int key_code, int type)
+{
+ int ret = 0;
+
+ if (type & KEY_PROCESSED)
+ ret |= !!(pDev->key->down[key_code >> 3] & (1 << (key_code & 7)));
+ else if (type & KEY_POSTED)
+ ret |= !!(pDev->key->postdown[key_code >> 3] & (1 << (key_code & 7)));
+
+ return ret;
+}
+
+static Bool
+key_autorepeats(DeviceIntPtr pDev, int key_code)
+{
+ return !!(pDev->kbdfeed->ctrl.autoRepeats[key_code >> 3] &
+ (1 << (key_code & 7)));
+}
+
+static void
+init_event(DeviceIntPtr dev, DeviceEvent* event, Time ms)
+{
+ memset(event, 0, sizeof(DeviceEvent));
+ event->header = ET_Internal;
+ event->length = sizeof(DeviceEvent);
+ event->time = ms;
+ event->deviceid = dev->id;
+ event->sourceid = dev->id;
+}
+
+static void
+init_raw(DeviceIntPtr dev, RawDeviceEvent *event, Time ms, int type, int detail)
+{
+ memset(event, 0, sizeof(RawDeviceEvent));
+ event->header = ET_Internal;
+ event->length = sizeof(RawDeviceEvent);
+ event->type = ET_RawKeyPress - ET_KeyPress + type;
+ event->time = ms;
+ event->deviceid = dev->id;
+ event->sourceid = dev->id;
+ event->detail.button = detail;
+}
+
+static void
+set_raw_valuators(RawDeviceEvent *event, int first, int num, int *valuators, int32_t* data)
+{
+ int i;
+ for (i = first; i < first + num; i++)
+ SetBit(event->valuators.mask, i);
+
+ memcpy(&data[first], valuators, num * sizeof(uint32_t));
+}
+
+
+static void
+set_valuators(DeviceIntPtr dev, DeviceEvent* event, int first_valuator,
+ int num_valuators, int *valuators)
+{
+ int i;
+
+ for (i = first_valuator; i < first_valuator + num_valuators; i++)
+ {
+ SetBit(event->valuators.mask, i);
+ if (dev->valuator->mode == Absolute)
+ SetBit(event->valuators.mode, i);
+ event->valuators.data_frac[i] =
+ dev->last.remainder[i] * (1 << 16) * (1 << 16);
+ }
+
+ memcpy(&event->valuators.data[first_valuator],
+ valuators, num_valuators * sizeof(uint32_t));
+
+}
+
+void
+CreateClassesChangedEvent(EventList* event,
+ DeviceIntPtr master,
+ DeviceIntPtr slave,
+ int type)
+{
+ int i;
+ DeviceChangedEvent *dce;
+ CARD32 ms = GetTimeInMillis();
+
+ dce = (DeviceChangedEvent*)event->event;
+ memset(dce, 0, sizeof(DeviceChangedEvent));
+ dce->deviceid = slave->id;
+ dce->masterid = master->id;
+ dce->header = ET_Internal;
+ dce->length = sizeof(DeviceChangedEvent);
+ dce->type = ET_DeviceChanged;
+ dce->time = ms;
+ dce->flags = type;
+ dce->flags |= DEVCHANGE_SLAVE_SWITCH;
+ dce->sourceid = slave->id;
+
+ if (slave->button)
+ {
+ dce->buttons.num_buttons = slave->button->numButtons;
+ for (i = 0; i < dce->buttons.num_buttons; i++)
+ dce->buttons.names[i] = slave->button->labels[i];
+ }
+ if (slave->valuator)
+ {
+ dce->num_valuators = slave->valuator->numAxes;
+ for (i = 0; i < dce->num_valuators; i++)
+ {
+ dce->valuators[i].min = slave->valuator->axes[i].min_value;
+ dce->valuators[i].max = slave->valuator->axes[i].max_value;
+ dce->valuators[i].resolution = slave->valuator->axes[i].resolution;
+ /* This should, eventually, be a per-axis mode */
+ dce->valuators[i].mode = slave->valuator->mode;
+ dce->valuators[i].name = slave->valuator->axes[i].label;
+ }
+ }
+ if (slave->key)
+ {
+ dce->keys.min_keycode = slave->key->xkbInfo->desc->min_key_code;
+ dce->keys.max_keycode = slave->key->xkbInfo->desc->max_key_code;
+ }
+}
+
+/**
+ * Rescale the coord between the two axis ranges.
+ */
+static int
+rescaleValuatorAxis(int coord, float remainder, float *remainder_return, AxisInfoPtr from, AxisInfoPtr to,
+ int defmax)
+{
+ int fmin = 0, tmin = 0, fmax = defmax, tmax = defmax, coord_return;
+ float value;
+
+ if(from && from->min_value < from->max_value) {
+ fmin = from->min_value;
+ fmax = from->max_value;
+ }
+ if(to && to->min_value < to->max_value) {
+ tmin = to->min_value;
+ tmax = to->max_value;
+ }
+
+ if(fmin == tmin && fmax == tmax) {
+ if (remainder_return)
+ *remainder_return = remainder;
+ return coord;
+ }
+
+ if(fmax == fmin) { /* avoid division by 0 */
+ if (remainder_return)
+ *remainder_return = 0.0;
+ return 0;
+ }
+
+ value = (coord + remainder - fmin) * (tmax - tmin) / (fmax - fmin) + tmin;
+ coord_return = lroundf(value);
+ if (remainder_return)
+ *remainder_return = value - coord_return;
+ return coord_return;
+}
+
+/**
+ * Update all coordinates when changing to a different SD
+ * to ensure that relative reporting will work as expected
+ * without loss of precision.
+ *
+ * pDev->last.valuators will be in absolute device coordinates after this
+ * function.
+ */
+static void
+updateSlaveDeviceCoords(DeviceIntPtr master, DeviceIntPtr pDev)
+{
+ ScreenPtr scr = miPointerGetScreen(pDev);
+ int i;
+ DeviceIntPtr lastSlave;
+
+ /* master->last.valuators[0]/[1] is in screen coords and the actual
+ * position of the pointer */
+ pDev->last.valuators[0] = master->last.valuators[0];
+ pDev->last.valuators[1] = master->last.valuators[1];
+
+ if (!pDev->valuator)
+ return;
+
+ /* scale back to device coordinates */
+ if(pDev->valuator->numAxes > 0)
+ pDev->last.valuators[0] = rescaleValuatorAxis(pDev->last.valuators[0], pDev->last.remainder[0],
+ &pDev->last.remainder[0], NULL, pDev->valuator->axes + 0, scr->width);
+ if(pDev->valuator->numAxes > 1)
+ pDev->last.valuators[1] = rescaleValuatorAxis(pDev->last.valuators[1], pDev->last.remainder[1],
+ &pDev->last.remainder[1], NULL, pDev->valuator->axes + 1, scr->height);
+
+ /* calculate the other axis as well based on info from the old
+ * slave-device. If the old slave had less axes than this one,
+ * last.valuators is reset to 0.
+ */
+ if ((lastSlave = master->last.slave) && lastSlave->valuator) {
+ for (i = 2; i < pDev->valuator->numAxes; i++) {
+ if (i >= lastSlave->valuator->numAxes)
+ pDev->last.valuators[i] = 0;
+ else
+ pDev->last.valuators[i] =
+ rescaleValuatorAxis(pDev->last.valuators[i],
+ pDev->last.remainder[i],
+ &pDev->last.remainder[i],
+ lastSlave->valuator->axes + i,
+ pDev->valuator->axes + i, 0);
+ }
+ }
+
+}
+
+/**
+ * Allocate the motion history buffer.
+ */
+void
+AllocateMotionHistory(DeviceIntPtr pDev)
+{
+ int size;
+ if (pDev->valuator->motion)
+ xfree(pDev->valuator->motion);
+
+ if (pDev->valuator->numMotionEvents < 1)
+ return;
+
+ /* An MD must have a motion history size large enough to keep all
+ * potential valuators, plus the respective range of the valuators.
+ * 3 * INT32 for (min_val, max_val, curr_val))
+ */
+ if (IsMaster(pDev))
+ size = sizeof(INT32) * 3 * MAX_VALUATORS;
+ else
+ size = sizeof(INT32) * pDev->valuator->numAxes;
+
+ size += sizeof(Time);
+
+ pDev->valuator->motion = xcalloc(pDev->valuator->numMotionEvents, size);
+ pDev->valuator->first_motion = 0;
+ pDev->valuator->last_motion = 0;
+ if (!pDev->valuator->motion)
+ ErrorF("[dix] %s: Failed to alloc motion history (%d bytes).\n",
+ pDev->name, size * pDev->valuator->numMotionEvents);
+}
+
+/**
+ * Dump the motion history between start and stop into the supplied buffer.
+ * Only records the event for a given screen in theory, but in practice, we
+ * sort of ignore this.
+ *
+ * If core is set, we only generate x/y, in INT16, scaled to screen coords.
+ */
+int
+GetMotionHistory(DeviceIntPtr pDev, xTimecoord **buff, unsigned long start,
+ unsigned long stop, ScreenPtr pScreen, BOOL core)
+{
+ char *ibuff = NULL, *obuff;
+ int i = 0, ret = 0;
+ int j, coord;
+ Time current;
+ /* The size of a single motion event. */
+ int size;
+ int dflt;
+ AxisInfo from, *to; /* for scaling */
+ INT32 *ocbuf, *icbuf; /* pointer to coordinates for copying */
+ INT16 *corebuf;
+ AxisInfo core_axis = {0};
+
+ if (!pDev->valuator || !pDev->valuator->numMotionEvents)
+ return 0;
+
+ if (core && !pScreen)
+ return 0;
+
+ if (IsMaster(pDev))
+ size = (sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(Time);
+ else
+ size = (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
+
+ *buff = xalloc(size * pDev->valuator->numMotionEvents);
+ if (!(*buff))
+ return 0;
+ obuff = (char *)*buff;
+
+ for (i = pDev->valuator->first_motion;
+ i != pDev->valuator->last_motion;
+ i = (i + 1) % pDev->valuator->numMotionEvents) {
+ /* We index the input buffer by which element we're accessing, which
+ * is not monotonic, and the output buffer by how many events we've
+ * written so far. */
+ ibuff = (char *) pDev->valuator->motion + (i * size);
+ memcpy(¤t, ibuff, sizeof(Time));
+
+ if (current > stop) {
+ return ret;
+ }
+ else if (current >= start) {
+ if (core)
+ {
+ memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */
+
+ icbuf = (INT32*)(ibuff + sizeof(Time));
+ corebuf = (INT16*)(obuff + sizeof(Time));
+
+ /* fetch x coordinate + range */
+ memcpy(&from.min_value, icbuf++, sizeof(INT32));
+ memcpy(&from.max_value, icbuf++, sizeof(INT32));
+ memcpy(&coord, icbuf++, sizeof(INT32));
+
+ /* scale to screen coords */
+ to = &core_axis;
+ to->max_value = pScreen->width;
+ coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->width);
+
+ memcpy(corebuf, &coord, sizeof(INT16));
+ corebuf++;
+
+ /* fetch y coordinate + range */
+ memcpy(&from.min_value, icbuf++, sizeof(INT32));
+ memcpy(&from.max_value, icbuf++, sizeof(INT32));
+ memcpy(&coord, icbuf++, sizeof(INT32));
+
+ to->max_value = pScreen->height;
+ coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, pScreen->height);
+ memcpy(corebuf, &coord, sizeof(INT16));
+
+ } else if (IsMaster(pDev))
+ {
+ memcpy(obuff, ibuff, sizeof(Time)); /* copy timestamp */
+
+ ocbuf = (INT32*)(obuff + sizeof(Time));
+ icbuf = (INT32*)(ibuff + sizeof(Time));
+ for (j = 0; j < MAX_VALUATORS; j++)
+ {
+ if (j >= pDev->valuator->numAxes)
+ break;
+
+ /* fetch min/max/coordinate */
+ memcpy(&from.min_value, icbuf++, sizeof(INT32));
+ memcpy(&from.max_value, icbuf++, sizeof(INT32));
+ memcpy(&coord, icbuf++, sizeof(INT32));
+
+ to = (j < pDev->valuator->numAxes) ? &pDev->valuator->axes[j] : NULL;
+
+ /* x/y scaled to screen if no range is present */
+ if (j == 0 && (from.max_value < from.min_value))
+ from.max_value = pScreen->width;
+ else if (j == 1 && (from.max_value < from.min_value))
+ from.max_value = pScreen->height;
+
+ if (j == 0 && (to->max_value < to->min_value))
+ dflt = pScreen->width;
+ else if (j == 1 && (to->max_value < to->min_value))
+ dflt = pScreen->height;
+ else
+ dflt = 0;
+
+ /* scale from stored range into current range */
+ coord = rescaleValuatorAxis(coord, 0.0, NULL, &from, to, 0);
+ memcpy(ocbuf, &coord, sizeof(INT32));
+ ocbuf++;
+ }
+ } else
+ memcpy(obuff, ibuff, size);
+
+ /* don't advance by size here. size may be different to the
+ * actually written size if the MD has less valuators than MAX */
+ if (core)
+ obuff += sizeof(INT32) + sizeof(Time);
+ else
+ obuff += (sizeof(INT32) * pDev->valuator->numAxes) + sizeof(Time);
+ ret++;
+ }
+ }
+
+ return ret;
+}
+
+
+/**
+ * Update the motion history for a specific device, with the list of
+ * valuators.
+ *
+ * Layout of the history buffer:
+ * for SDs: [time] [val0] [val1] ... [valn]
+ * for MDs: [time] [min_val0] [max_val0] [val0] [min_val1] ... [valn]
+ *
+ * For events that have some valuators unset (first_valuator > 0):
+ * min_val == max_val == val == 0.
+ */
+static void
+updateMotionHistory(DeviceIntPtr pDev, CARD32 ms, int first_valuator,
+ int num_valuators, int *valuators)
+{
+ char *buff = (char *) pDev->valuator->motion;
+ ValuatorClassPtr v;
+ int i;
+
+ if (!pDev->valuator->numMotionEvents)
+ return;
+
+ v = pDev->valuator;
+ if (IsMaster(pDev))
+ {
+ buff += ((sizeof(INT32) * 3 * MAX_VALUATORS) + sizeof(CARD32)) *
+ v->last_motion;
+
+ memcpy(buff, &ms, sizeof(Time));
+ buff += sizeof(Time);
+
+ memset(buff, 0, sizeof(INT32) * 3 * MAX_VALUATORS);
+ buff += 3 * sizeof(INT32) * first_valuator;
+
+ for (i = first_valuator; i < first_valuator + num_valuators; i++)
+ {
+ if (i >= v->numAxes)
+ break;
+ memcpy(buff, &v->axes[i].min_value, sizeof(INT32));
+ buff += sizeof(INT32);
+ memcpy(buff, &v->axes[i].max_value, sizeof(INT32));
+ buff += sizeof(INT32);
+ memcpy(buff, &valuators[i - first_valuator], sizeof(INT32));
+ buff += sizeof(INT32);
+ }
+ } else
+ {
+
+ buff += ((sizeof(INT32) * pDev->valuator->numAxes) + sizeof(CARD32)) *
+ pDev->valuator->last_motion;
+
+ memcpy(buff, &ms, sizeof(Time));
+ buff += sizeof(Time);
+
+ memset(buff, 0, sizeof(INT32) * pDev->valuator->numAxes);
+ buff += sizeof(INT32) * first_valuator;
+
+ memcpy(buff, valuators, sizeof(INT32) * num_valuators);
+ }
+
+ pDev->valuator->last_motion = (pDev->valuator->last_motion + 1) %
+ pDev->valuator->numMotionEvents;
+ /* If we're wrapping around, just keep the circular buffer going. */
+ if (pDev->valuator->first_motion == pDev->valuator->last_motion)
+ pDev->valuator->first_motion = (pDev->valuator->first_motion + 1) %
+ pDev->valuator->numMotionEvents;
+
+ return;
+}
+
+
+/**
+ * Returns the maximum number of events GetKeyboardEvents,
+ * GetKeyboardValuatorEvents, and GetPointerEvents will ever return.
+ *
+ * This MUST be absolutely constant, from init until exit.
+ */
+int
+GetMaximumEventsNum(void) {
+ /* One raw event
+ * One device event
+ * One possible device changed event
+ */
+ return 3;
+}
+
+
+/**
+ * Clip an axis to its bounds, which are declared in the call to
+ * InitValuatorAxisClassStruct.
+ */
+static void
+clipAxis(DeviceIntPtr pDev, int axisNum, int *val)
+{
+ AxisInfoPtr axis;
+
+ if (axisNum >= pDev->valuator->numAxes)
+ return;
+
+ axis = pDev->valuator->axes + axisNum;
+
+ /* If a value range is defined, clip. If not, do nothing */
+ if (axis->max_value <= axis->min_value)
+ return;
+
+ if (*val < axis->min_value)
+ *val = axis->min_value;
+ if (*val > axis->max_value)
+ *val = axis->max_value;
+}
+
+/**
+ * Clip every axis in the list of valuators to its bounds.
+ */
+static void
+clipValuators(DeviceIntPtr pDev, int first_valuator, int num_valuators,
+ int *valuators)
+{
+ int i;
+
+ for (i = 0; i < num_valuators; i++)
+ clipAxis(pDev, i + first_valuator, &(valuators[i]));
+}
+
+/**
+ * Create the DCCE event (does not update the master's device state yet, this
+ * is done in the event processing).
+ * Pull in the coordinates from the MD if necessary.
+ *
+ * @param events Pointer to a pre-allocated event list.
+ * @param dev The slave device that generated an event.
+ * @param type Either DEVCHANGE_POINTER_EVENT and/or DEVCHANGE_KEYBOARD_EVENT
+ * @param num_events The current number of events, returns the number of
+ * events if a DCCE was generated.
+ * @return The updated @events pointer.
+ */
+static EventListPtr
+updateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events)
+{
+ DeviceIntPtr master;
+
+ master = GetMaster(dev, (type & DEVCHANGE_POINTER_EVENT) ? MASTER_POINTER : MASTER_KEYBOARD);
+
+ if (master && master->last.slave != dev)
+ {
+ CreateClassesChangedEvent(events, master, dev, type);
+ if (IsPointerDevice(master))
+ {
+ updateSlaveDeviceCoords(master, dev);
+ master->last.numValuators = dev->last.numValuators;
+ }
+ master->last.slave = dev;
+ (*num_events)++;
+ events++;
+ }
+ return events;
+}
+
+/**
+ * Move the device's pointer to the position given in the valuators.
+ *
+ * @param dev The device which's pointer is to be moved.
+ * @param x Returns the x position of the pointer after the move.
+ * @param y Returns the y position of the pointer after the move.
+ * @param first The first valuator in @valuators
+ * @param num Total number of valuators in @valuators.
+ * @param valuators Valuator data for each axis between @first and
+ * @first+@num.
+ */
+static void
+moveAbsolute(DeviceIntPtr dev, int *x, int *y,
+ int first, int num, int *valuators)
+{
+ int i;
+
+
+ if (num >= 1 && first == 0)
+ *x = *(valuators + 0);
+ else
+ *x = dev->last.valuators[0];
+
+ if (first <= 1 && num >= (2 - first))
+ *y = *(valuators + 1 - first);
+ else
+ *y = dev->last.valuators[1];
+
+ clipAxis(dev, 0, x);
+ clipAxis(dev, 1, y);
+
+ i = (first > 2) ? 0 : 2;
+ for (; i < num; i++)
+ {
+ dev->last.valuators[i + first] = valuators[i];
+ clipAxis(dev, i, &dev->last.valuators[i + first]);
+ }
+}
+
+/**
+ * Move the device's pointer by the values given in @valuators.
+ *
+ * @param dev The device which's pointer is to be moved.
+ * @param x Returns the x position of the pointer after the move.
+ * @param y Returns the y position of the pointer after the move.
+ * @param first The first valuator in @valuators
+ * @param num Total number of valuators in @valuators.
+ * @param valuators Valuator data for each axis between @first and
+ * @first+@num.
+ */
+static void
+moveRelative(DeviceIntPtr dev, int *x, int *y,
+ int first, int num, int *valuators)
+{
+ int i;
+
+ *x = dev->last.valuators[0];
+ *y = dev->last.valuators[1];
+
+ if (num >= 1 && first == 0)
+ *x += *(valuators +0);
+
+ if (first <= 1 && num >= (2 - first))
+ *y += *(valuators + 1 - first);
+
+ /* if attached, clip both x and y to the defined limits (usually
+ * co-ord space limit). If it is attached, we need x/y to go over the
+ * limits to be able to change screens. */
+ if(dev->u.master) {
+ clipAxis(dev, 0, x);
+ clipAxis(dev, 1, y);
+ }
+
+ /* calc other axes, clip, drop back into valuators */
+ i = (first > 2) ? 0 : 2;
+ for (; i < num; i++)
+ {
+ dev->last.valuators[i + first] += valuators[i];
+ clipAxis(dev, i, &dev->last.valuators[i + first]);
+ valuators[i] = dev->last.valuators[i + first];
+ }
+}
+
+/**
+ * Accelerate the data in valuators based on the device's acceleration scheme.
+ *
+ * @param dev The device which's pointer is to be moved.
+ * @param first The first valuator in @valuators
+ * @param num Total number of valuators in @valuators.
+ * @param valuators Valuator data for each axis between @first and
+ * @first+@num.
+ * @param ms Current time.
+ */
+static void
+accelPointer(DeviceIntPtr dev, int first, int num, int *valuators, CARD32 ms)
+{
+ if (dev->valuator->accelScheme.AccelSchemeProc)
+ dev->valuator->accelScheme.AccelSchemeProc(dev, first, num, valuators, ms);
+}
+
+/**
+ * If we have HW cursors, this actually moves the visible sprite. If not, we
+ * just do all the screen crossing, etc.
+ *
+ * We scale from device to screen coordinates here, call
+ * miPointerSetPosition() and then scale back into device coordinates (if
+ * needed). miPSP will change x/y if the screen was crossed.
+ *
+ * @param dev The device to be moved.
+ * @param x Pointer to current x-axis value, may be modified.
+ * @param y Pointer to current y-axis value, may be modified.
+ * @param x_frac Fractional part of current x-axis value, may be modified.
+ * @param y_frac Fractional part of current y-axis value, may be modified.
+ * @param scr Screen the device's sprite is currently on.
+ * @param screenx Screen x coordinate the sprite is on after the update.
+ * @param screeny Screen y coordinate the sprite is on after the update.
+ * @param screenx_frac Fractional part of screen x coordinate, as above.
+ * @param screeny_frac Fractional part of screen y coordinate, as above.
+ */
+static void
+positionSprite(DeviceIntPtr dev, int *x, int *y, float x_frac, float y_frac,
+ ScreenPtr scr, int *screenx, int *screeny, float *screenx_frac, float *screeny_frac)
+{
+ int old_screenx, old_screeny;
+
+ /* scale x&y to screen */
+ if (dev->valuator->numAxes > 0) {
+ *screenx = rescaleValuatorAxis(*x, x_frac, screenx_frac,
+ dev->valuator->axes + 0, NULL, scr->width);
+ } else {
+ *screenx = dev->last.valuators[0];
+ *screenx_frac = dev->last.remainder[0];
+ }
+
+ if (dev->valuator->numAxes > 1) {
+ *screeny = rescaleValuatorAxis(*y, y_frac, screeny_frac,
+ dev->valuator->axes + 1, NULL, scr->height);
+ } else {
+ *screeny = dev->last.valuators[1];
+ *screeny_frac = dev->last.remainder[1];
+ }
+
+ /* Hit the left screen edge? */
+ if (*screenx <= 0 && *screenx_frac < 0.0f)
+ {
+ *screenx_frac = 0.0f;
+ x_frac = 0.0f;
+ }
+ if (*screeny <= 0 && *screeny_frac < 0.0f)
+ {
+ *screeny_frac = 0.0f;
+ y_frac = 0.0f;
+ }
+
+
+ old_screenx = *screenx;
+ old_screeny = *screeny;
+ /* This takes care of crossing screens for us, as well as clipping
+ * to the current screen. */
+ miPointerSetPosition(dev, screenx, screeny);
+
+ if (dev->u.master) {
+ dev->u.master->last.valuators[0] = *screenx;
+ dev->u.master->last.valuators[1] = *screeny;
+ dev->u.master->last.remainder[0] = *screenx_frac;
+ dev->u.master->last.remainder[1] = *screeny_frac;
+ }
+
+ /* Crossed screen? Scale back to device coordiantes */
+ if(*screenx != old_screenx)
+ {
+ scr = miPointerGetScreen(dev);
+ *x = rescaleValuatorAxis(*screenx, *screenx_frac, &x_frac, NULL,
+ dev->valuator->axes + 0, scr->width);
+ }
+ if(*screeny != old_screeny)
+ {
+ scr = miPointerGetScreen(dev);
+ *y = rescaleValuatorAxis(*screeny, *screeny_frac, &y_frac, NULL,
+ dev->valuator->axes + 1, scr->height);
+ }
+
+ /* dropy x/y (device coordinates) back into valuators for next event */
+ dev->last.valuators[0] = *x;
+ dev->last.valuators[1] = *y;
+ dev->last.remainder[0] = x_frac;
+ dev->last.remainder[1] = y_frac;
+}
+
+/**
+ * Update the motion history for the device and (if appropriate) for its
+ * master device.
+ * @param dev Slave device to update.
+ * @param first First valuator to append to history.
+ * @param num Total number of valuators to append to history.
+ * @param ms Current time
+ */
+static void
+updateHistory(DeviceIntPtr dev, int first, int num, CARD32 ms)
+{
+ updateMotionHistory(dev, ms, first, num, &dev->last.valuators[first]);
+ if (dev->u.master)
+ {
+ DeviceIntPtr master = GetMaster(dev, MASTER_POINTER);
+ updateMotionHistory(master, ms, first, num, &dev->last.valuators[first]);
+ }
+}
+
+/**
+ * Convenience wrapper around GetKeyboardValuatorEvents, that takes no
+ * valuators.
+ */
+int
+GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type, int key_code) {
+ return GetKeyboardValuatorEvents(events, pDev, type, key_code, 0, 0, NULL);
+}
+
+
+/**
+ * Returns a set of keyboard events for KeyPress/KeyRelease, optionally
+ * also with valuator events. Handles Xi and XKB.
+ *
+ * DOES NOT GENERATE CORE EVENTS! Core events are created when processing the
+ * event (ProcessOtherEvent).
+ *
+ * events is not NULL-terminated; the return value is the number of events.
+ * The DDX is responsible for allocating the event structure in the first
+ * place via GetMaximumEventsNum(), and for freeing it.
+ *
+ * This function does not change the core keymap to that of the device;
+ * that is done by SwitchCoreKeyboard, which is called from
+ * mieqProcessInputEvents. If replacing that function, take care to call
+ * SetCoreKeyboard before processInputProc, so keymaps are altered to suit.
+ */
+int
+GetKeyboardValuatorEvents(EventList *events, DeviceIntPtr pDev, int type,
+ int key_code, int first_valuator,
+ int num_valuators, int *valuators) {
+ int num_events = 0;
+ CARD32 ms = 0;
+ DeviceEvent *event;
+ RawDeviceEvent *raw;
+
+ /* refuse events from disabled devices */
+ if (!pDev->enabled)
+ return 0;
+
+ if (!events ||!pDev->key || !pDev->focus || !pDev->kbdfeed ||
+ (type != KeyPress && type != KeyRelease) ||
+ (key_code < 8 || key_code > 255))
+ return 0;
+
+ num_events = 1;
+
+ events = updateFromMaster(events, pDev, DEVCHANGE_KEYBOARD_EVENT, &num_events);
+
+ /* Handle core repeating, via press/release/press/release. */
+ if (type == KeyPress && key_is_down(pDev, key_code, KEY_POSTED)) {
+ /* If autorepeating is disabled either globally or just for that key,
+ * or we have a modifier, don't generate a repeat event. */
+ if (!pDev->kbdfeed->ctrl.autoRepeat ||
+ !key_autorepeats(pDev, key_code) ||
+ pDev->key->xkbInfo->desc->map->modmap[key_code])
+ return 0;
+ }
+
+ ms = GetTimeInMillis();
+
+ raw = (RawDeviceEvent*)events->event;
+ events++;
+ num_events++;
+
+ init_raw(pDev, raw, ms, type, key_code);
+ set_raw_valuators(raw, first_valuator, num_valuators, valuators,
+ raw->valuators.data_raw);
+
+ if (num_valuators)
+ clipValuators(pDev, first_valuator, num_valuators, valuators);
+
+ set_raw_valuators(raw, first_valuator, num_valuators, valuators,
+ raw->valuators.data);
+
+ event = (DeviceEvent*) events->event;
+ init_event(pDev, event, ms);
+ event->detail.key = key_code;
+
+ if (type == KeyPress) {
+ event->type = ET_KeyPress;
+ set_key_down(pDev, key_code, KEY_POSTED);
+ }
+ else if (type == KeyRelease) {
+ event->type = ET_KeyRelease;
+ set_key_up(pDev, key_code, KEY_POSTED);
+ }
+
+ if (num_valuators)
+ clipValuators(pDev, first_valuator, num_valuators, valuators);
+
+ set_valuators(pDev, event, first_valuator, num_valuators, valuators);
+
+ return num_events;
+}
+
+/**
+ * Initialize an event list and fill with 32 byte sized events.
+ * This event list is to be passed into GetPointerEvents() and
+ * GetKeyboardEvents().
+ *
+ * @param num_events Number of elements in list.
+ */
+EventListPtr
+InitEventList(int num_events)
+{
+ EventListPtr events;
+ int i;
+
+ events = (EventListPtr)xcalloc(num_events, sizeof(EventList));
+ if (!events)
+ return NULL;
+
+ for (i = 0; i < num_events; i++)
+ {
+ events[i].evlen = sizeof(InternalEvent);
+ events[i].event = xcalloc(1, sizeof(InternalEvent));
+ if (!events[i].event)
+ {
+ /* rollback */
+ while(i--)
+ xfree(events[i].event);
+ xfree(events);
+ events = NULL;
+ break;
+ }
+ }
+
+ return events;
+}
+
+/**
+ * Free an event list.
+ *
+ * @param list The list to be freed.
+ * @param num_events Number of elements in list.
+ */
+void
+FreeEventList(EventListPtr list, int num_events)
+{
+ if (!list)
+ return;
+ while(num_events--)
+ xfree(list[num_events].event);
+ xfree(list);
+}
+
+/**
+ * Generate a series of xEvents (filled into the EventList) representing
+ * pointer motion, or button presses. Xi and XKB-aware.
+ *
+ * DOES NOT GENERATE CORE EVENTS! Core events are created when processing the
+ * event (ProcessOtherEvent).
+ *
+ * events is not NULL-terminated; the return value is the number of events.
+ * The DDX is responsible for allocating the event structure in the first
+ * place via InitEventList() and GetMaximumEventsNum(), and for freeing it.
+ *
+ * In the generated events rootX/Y will be in absolute screen coords and
+ * the valuator information in the absolute or relative device coords.
+ *
+ * last.valuators[x] of the device is always in absolute device coords.
+ * last.valuators[x] of the master device is in absolute screen coords.
+ *
+ * master->last.valuators[x] for x > 2 is undefined.
+ */
+int
+GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
+ int flags, int first_valuator, int num_valuators,
+ int *valuators) {
+ int num_events = 1;
+ CARD32 ms;
+ DeviceEvent *event;
+ RawDeviceEvent *raw;
+ int x = 0, y = 0, /* device coords */
+ cx, cy; /* only screen coordinates */
+ float x_frac = 0.0, y_frac = 0.0, cx_frac, cy_frac;
+ ScreenPtr scr = miPointerGetScreen(pDev);
+
+ /* refuse events from disabled devices */
+ if (!pDev->enabled)
+ return 0;
+
+ ms = GetTimeInMillis(); /* before pointer update to help precision */
+
+ if (!scr || !pDev->valuator || first_valuator < 0 ||
+ ((num_valuators + first_valuator) > pDev->valuator->numAxes) ||
+ (type != MotionNotify && type != ButtonPress && type != ButtonRelease) ||
+ (type != MotionNotify && !pDev->button) ||
+ ((type == ButtonPress || type == ButtonRelease) && !buttons) ||
+ (type == MotionNotify && num_valuators <= 0))
+ return 0;
+
+ events = updateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
+
+ raw = (RawDeviceEvent*)events->event;
+ events++;
+ num_events++;
+
+ init_raw(pDev, raw, ms, type, buttons);
+ set_raw_valuators(raw, first_valuator, num_valuators, valuators,
+ raw->valuators.data_raw);
+
+ if (flags & POINTER_ABSOLUTE)
+ {
+ if (flags & POINTER_SCREEN) /* valuators are in screen coords */
+ {
+
+ if (num_valuators >= 1 && first_valuator == 0)
+ valuators[0] = rescaleValuatorAxis(valuators[0], 0.0, &x_frac, NULL,
+ pDev->valuator->axes + 0,
+ scr->width);
+ if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
+ valuators[1 - first_valuator] = rescaleValuatorAxis(valuators[1 - first_valuator], 0.0, &y_frac, NULL,
+ pDev->valuator->axes + 1,
+ scr->height);
+ }
+
+ moveAbsolute(pDev, &x, &y, first_valuator, num_valuators, valuators);
+ } else {
+ if (flags & POINTER_ACCELERATE) {
+ accelPointer(pDev, first_valuator, num_valuators, valuators, ms);
+ /* The pointer acceleration code modifies the fractional part
+ * in-place, so we need to extract this information first */
+ x_frac = pDev->last.remainder[0];
+ y_frac = pDev->last.remainder[1];
+ }
+ moveRelative(pDev, &x, &y, first_valuator, num_valuators, valuators);
+ }
+
+ set_raw_valuators(raw, first_valuator, num_valuators, valuators,
+ raw->valuators.data);
+
+ positionSprite(pDev, &x, &y, x_frac, y_frac, scr, &cx, &cy, &cx_frac, &cy_frac);
+ updateHistory(pDev, first_valuator, num_valuators, ms);
+
+ /* Update the valuators with the true value sent to the client*/
+ if (num_valuators >= 1 && first_valuator == 0)
+ valuators[0] = x;
+ if (first_valuator <= 1 && num_valuators >= (2 - first_valuator))
+ valuators[1 - first_valuator] = y;
+
+ if (num_valuators)
+ clipValuators(pDev, first_valuator, num_valuators, valuators);
+
+ event = (DeviceEvent*) events->event;
+ init_event(pDev, event, ms);
+
+ if (type == MotionNotify) {
+ event->type = ET_Motion;
+ event->detail.button = 0;
+ }
+ else {
+ if (type == ButtonPress) {
+ event->type = ET_ButtonPress;
+ pDev->button->postdown[buttons >> 3] |= (1 << (buttons & 7));
+ }
+ else if (type == ButtonRelease) {
+ event->type = ET_ButtonRelease;
+ pDev->button->postdown[buttons >> 3] &= ~(1 << (buttons & 7));
+ }
+ event->detail.button = buttons;
+ }
+
+ event->root_x = cx; /* root_x/y always in screen coords */
+ event->root_y = cy;
+ event->root_x_frac = cx_frac;
+ event->root_y_frac = cy_frac;
+
+ set_valuators(pDev, event, first_valuator, num_valuators, valuators);
+
+ return num_events;
+}
+
+
+/**
+ * Post ProximityIn/ProximityOut events, accompanied by valuators.
+ *
+ * events is not NULL-terminated; the return value is the number of events.
+ * The DDX is responsible for allocating the event structure in the first
+ * place via GetMaximumEventsNum(), and for freeing it.
+ */
+int
+GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type,
+ int first_valuator, int num_valuators, int *valuators)
+{
+ int num_events = 1;
+ DeviceEvent *event;
+
+ /* refuse events from disabled devices */
+ if (!pDev->enabled)
+ return 0;
+
+ /* Sanity checks. */
+ if (type != ProximityIn && type != ProximityOut)
+ return 0;
+ if (!pDev->valuator)
+ return 0;
+ /* Do we need to send a DeviceValuator event? */
+ if ((pDev->valuator->mode & 1) == Relative)
+ num_valuators = 0;
+
+ /* You fail. */
+ if (first_valuator < 0 ||
+ (num_valuators + first_valuator) > pDev->valuator->numAxes)
+ return 0;
+
+ events = updateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
+
+ event = (DeviceEvent *) events->event;
+ init_event(pDev, event, GetTimeInMillis());
+ event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;
+
+ if (num_valuators)
+ clipValuators(pDev, first_valuator, num_valuators, valuators);
+
+ set_valuators(pDev, event, first_valuator, num_valuators, valuators);
+
+ return num_events;
+}
+
+/**
+ * Synthesize a single motion event for the core pointer.
+ *
+ * Used in cursor functions, e.g. when cursor confinement changes, and we need
+ * to shift the pointer to get it inside the new bounds.
+ */
+void
+PostSyntheticMotion(DeviceIntPtr pDev,
+ int x,
+ int y,
+ int screen,
+ unsigned long time)
+{
+ DeviceEvent ev;
+
+#ifdef PANORAMIX
+ /* Translate back to the sprite screen since processInputProc
+ will translate from sprite screen to screen 0 upon reentry
+ to the DIX layer. */
+ if (!noPanoramiXExtension) {
+ x += panoramiXdataPtr[0].x - panoramiXdataPtr[screen].x;
+ y += panoramiXdataPtr[0].y - panoramiXdataPtr[screen].y;
+ }
+#endif
+
+ memset(&ev, 0, sizeof(DeviceEvent));
+ init_event(pDev, &ev, time);
+ ev.root_x = x;
+ ev.root_y = y;
+ ev.type = ET_Motion;
+ ev.time = time;
+
+ /* FIXME: MD/SD considerations? */
+ (*pDev->public.processInputProc)((InternalEvent*)&ev, pDev);
+}
diff --git a/xorg-server/dix/main.c b/xorg-server/dix/main.c index f0235364f..54cd8a919 100644 --- a/xorg-server/dix/main.c +++ b/xorg-server/dix/main.c @@ -1,348 +1,392 @@ -/*********************************************************** - -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. - -******************************************************************/ - -/* The panoramix components contained the following notice */ -/***************************************************************** - -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 <dix-config.h> -#include <version-config.h> -#endif - -#include <X11/X.h> -#include <X11/Xos.h> /* for unistd.h */ -#include <X11/Xproto.h> -#include <pixman.h> -#include "scrnintstr.h" -#include "misc.h" -#include "os.h" -#include "windowstr.h" -#include "resource.h" -#include "dixstruct.h" -#include "gcstruct.h" -#include "extension.h" -#include "colormap.h" -#include "colormapst.h" -#include "cursorstr.h" -#include "selection.h" -#include <X11/fonts/font.h> -#include "opaque.h" -#include "servermd.h" -#include "hotplug.h" -#include "site.h" -#include "dixfont.h" -#include "extnsionst.h" -#include "privates.h" -#include "registry.h" -#ifdef PANORAMIX -#include "panoramiXsrv.h" -#else -#include "dixevents.h" /* InitEvents() */ -#include "dispatch.h" /* InitProcVectors() */ -#endif - -#ifdef DPMSExtension -#include <X11/extensions/dpmsconst.h> -#include "dpmsproc.h" -#endif - -extern void Dispatch(void); - -extern void InitProcVectors(void); - -#ifdef XQUARTZ -#include <pthread.h> - -BOOL serverInitComplete = FALSE; -pthread_mutex_t serverInitCompleteMutex = PTHREAD_MUTEX_INITIALIZER; -pthread_cond_t serverInitCompleteCond = PTHREAD_COND_INITIALIZER; - -int dix_main(int argc, char *argv[], char *envp[]); - -int dix_main(int argc, char *argv[], char *envp[]) -#else -int main(int argc, char *argv[], char *envp[]) -#endif -{ - int i; - HWEventQueueType alwaysCheckForInput[2]; - - display = "0"; - - InitRegions(); - - pixman_disable_out_of_bounds_workaround(); - - CheckUserParameters(argc, argv, envp); - - CheckUserAuthorization(); - - InitConnectionLimits(); - - ProcessCommandLine(argc, argv); - - alwaysCheckForInput[0] = 0; - alwaysCheckForInput[1] = 1; - while(1) - { - serverGeneration++; - ScreenSaverTime = defaultScreenSaverTime; - ScreenSaverInterval = defaultScreenSaverInterval; - ScreenSaverBlanking = defaultScreenSaverBlanking; - ScreenSaverAllowExposures = defaultScreenSaverAllowExposures; -#ifdef DPMSExtension - DPMSStandbyTime = DEFAULT_SCREEN_SAVER_TIME; - DPMSSuspendTime = DEFAULT_SCREEN_SAVER_TIME; - DPMSOffTime = DEFAULT_SCREEN_SAVER_TIME; - DPMSEnabled = TRUE; - DPMSPowerLevel = 0; -#endif - InitBlockAndWakeupHandlers(); - /* Perform any operating system dependent initializations you'd like */ - OsInit(); - if(serverGeneration == 1) - { - CreateWellKnownSockets(); - InitProcVectors(); - for (i=1; i<MAXCLIENTS; i++) - clients[i] = NullClient; - serverClient = xalloc(sizeof(ClientRec)); - if (!serverClient) - FatalError("couldn't create server client"); - InitClient(serverClient, 0, (pointer)NULL); - } - else - ResetWellKnownSockets (); - clients[0] = serverClient; - currentMaxClients = 1; - - if (!InitClientResources(serverClient)) /* for root resources */ - FatalError("couldn't init server resources"); - - SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]); - screenInfo.arraySize = MAXSCREENS; - screenInfo.numScreens = 0; - - InitAtoms(); - InitEvents(); - InitSelections(); - InitGlyphCaching(); - if (!dixResetPrivates()) - FatalError("couldn't init private data storage"); - dixResetRegistry(); - ResetFontPrivateIndex(); - InitCallbackManager(); - InitOutput(&screenInfo, argc, argv); - - if (screenInfo.numScreens < 1) - FatalError("no screens found"); - InitExtensions(argc, argv); - for (i = 0; i < screenInfo.numScreens; i++) - { - ScreenPtr pScreen = screenInfo.screens[i]; - if (!CreateScratchPixmapsForScreen(i)) - FatalError("failed to create scratch pixmaps"); - if (pScreen->CreateScreenResources && - !(*pScreen->CreateScreenResources)(pScreen)) - FatalError("failed to create screen resources"); - if (!CreateGCperDepth(i)) - FatalError("failed to create scratch GCs"); - if (!CreateDefaultStipple(i)) - FatalError("failed to create default stipple"); - if (!CreateRootWindow(pScreen)) - FatalError("failed to create root window"); - } - - InitFonts(); - if (SetDefaultFontPath(defaultFontPath) != Success) { - ErrorF("[dix] failed to set default font path '%s'", defaultFontPath); - } - if (!SetDefaultFont(defaultTextFont)) { - FatalError("could not open default font '%s'", defaultTextFont); - } - - if (!(rootCursor = CreateRootCursor(NULL, 0))) { - FatalError("could not open default cursor font '%s'", - defaultCursorFont); - } - -#ifdef DPMSExtension - /* check all screens, looking for DPMS Capabilities */ - DPMSCapableFlag = DPMSSupported(); - if (!DPMSCapableFlag) - DPMSEnabled = FALSE; -#endif - -#ifdef PANORAMIX - /* - * Consolidate window and colourmap information for each screen - */ - if (!noPanoramiXExtension) - PanoramiXConsolidate(); -#endif - - for (i = 0; i < screenInfo.numScreens; i++) - InitRootWindow(WindowTable[i]); - - InitCoreDevices(); - InitInput(argc, argv); - InitAndStartDevices(); - - dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset); - -#ifdef PANORAMIX - if (!noPanoramiXExtension) { - if (!PanoramiXCreateConnectionBlock()) { - FatalError("could not create connection block info"); - } - } else -#endif - { - if (!CreateConnectionBlock()) { - FatalError("could not create connection block info"); - } - } - -#ifdef XQUARTZ - /* Let the other threads know the server is done with its init */ - pthread_mutex_lock(&serverInitCompleteMutex); - serverInitComplete = TRUE; - pthread_cond_broadcast(&serverInitCompleteCond); - pthread_mutex_unlock(&serverInitCompleteMutex); -#endif - - NotifyParentProcess(); - - Dispatch(); - - UndisplayDevices(); - - /* Now free up whatever must be freed */ - if (screenIsSaved == SCREEN_SAVER_ON) - dixSaveScreens(serverClient, SCREEN_SAVER_OFF, ScreenSaverReset); - FreeScreenSaverTimer(); - CloseDownExtensions(); - -#ifdef PANORAMIX - { - Bool remember_it = noPanoramiXExtension; - noPanoramiXExtension = TRUE; - FreeAllResources(); - noPanoramiXExtension = remember_it; - } -#else - FreeAllResources(); -#endif - - CloseInput(); - - memset(WindowTable, 0, sizeof(WindowTable)); - CloseDownDevices(); - CloseDownEvents(); - - for (i = screenInfo.numScreens - 1; i >= 0; i--) - { - FreeScratchPixmapsForScreen(i); - FreeGCperDepth(i); - FreeDefaultStipple(i); - (* screenInfo.screens[i]->CloseScreen)(i, screenInfo.screens[i]); - dixFreePrivates(screenInfo.screens[i]->devPrivates); - xfree(screenInfo.screens[i]); - screenInfo.numScreens = i; - } - FreeFonts(); - - FreeAuditTimer(); - - dixFreePrivates(serverClient->devPrivates); - serverClient->devPrivates = NULL; - - if (dispatchException & DE_TERMINATE) - { - CloseWellKnownConnections(); - } - - OsCleanup((dispatchException & DE_TERMINATE) != 0); - - if (dispatchException & DE_TERMINATE) - { - ddxGiveUp(); - break; - } - - xfree(ConnectionInfo); - ConnectionInfo = NULL; - } - return(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.
+
+******************************************************************/
+
+/* The panoramix components contained the following notice */
+/*****************************************************************
+
+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 <dix-config.h>
+#include <version-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xos.h> /* for unistd.h */
+#include <X11/Xproto.h>
+#include <pixman.h>
+#include "scrnintstr.h"
+#include "misc.h"
+#include "os.h"
+#include "windowstr.h"
+#include "resource.h"
+#include "dixstruct.h"
+#include "gcstruct.h"
+#include "extension.h"
+#include "colormap.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "selection.h"
+#include <X11/fonts/font.h>
+#include "opaque.h"
+#include "servermd.h"
+#include "hotplug.h"
+#include "site.h"
+#include "dixfont.h"
+#include "extnsionst.h"
+#include "privates.h"
+#include "registry.h"
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#else
+#include "dixevents.h" /* InitEvents() */
+#include "dispatch.h" /* InitProcVectors() */
+#endif
+
+#ifdef DPMSExtension
+#include <X11/extensions/dpmsconst.h>
+#include "dpmsproc.h"
+#endif
+
+#ifdef _DEBUG
+#include <crtdbg.h>
+#endif
+
+extern void Dispatch(void);
+
+extern void InitProcVectors(void);
+
+#ifdef XQUARTZ
+#include <pthread.h>
+
+BOOL serverInitComplete = FALSE;
+pthread_mutex_t serverInitCompleteMutex = PTHREAD_MUTEX_INITIALIZER;
+pthread_cond_t serverInitCompleteCond = PTHREAD_COND_INITIALIZER;
+
+int dix_main(int argc, char *argv[], char *envp[]);
+
+int dix_main(int argc, char *argv[], char *envp[])
+#else
+int main(int argc, char *argv[], char *envp[])
+#endif
+{
+ int i;
+ HWEventQueueType alwaysCheckForInput[2];
+ #ifdef _DEBUG
+ //int TmpFlag=_CrtSetDbgFlag( _CRTDBG_REPORT_FLAG);
+
+ //TmpFlag|=_CRTDBG_ALLOC_MEM_DF;
+ //TmpFlag|=_CRTDBG_DELAY_FREE_MEM_DF;
+ //TmpFlag|=_CRTDBG_CHECK_ALWAYS_DF;
+ //TmpFlag|=_CRTDBG_CHECK_CRT_DF;
+ //TmpFlag|=_CRTDBG_LEAK_CHECK_DF;
+
+ //_CrtSetDbgFlag(TmpFlag);
+ #endif
+
+ ptw32_processInitialize();
+ display = "0";
+
+ #ifdef WIN32
+
+ if (InitWSA()<0)
+ {
+ printf("Error initialising WSA\n");
+ return -1;
+ }
+ /* In Win32 we have different threads call Xlib functions (depending
+ on the commandline options given).
+ XInitThreads has to be called before
+ any xlib function is called (aoccording to the man page) */
+ XInitThreads();
+ /* change the current directory to the directory where the vcxsrv.exe executable is installed.
+ This is needed because the font directories are relative to the current directory.
+ */
+ {
+ char ModuleFilename[MAX_PATH];
+ char *pSlash;
+ GetModuleFileName(NULL,ModuleFilename,sizeof(ModuleFilename));
+ pSlash=strrchr(ModuleFilename,'\\');
+ if (pSlash)
+ {
+ *pSlash='\0';
+ chdir(ModuleFilename);
+ }
+ }
+ #endif
+
+ InitRegions();
+
+ pixman_disable_out_of_bounds_workaround();
+
+ CheckUserParameters(argc, argv, envp);
+
+ CheckUserAuthorization();
+
+ InitConnectionLimits();
+
+ ProcessCommandLine(argc, argv);
+
+ alwaysCheckForInput[0] = 0;
+ alwaysCheckForInput[1] = 1;
+ while(1)
+ {
+ serverGeneration++;
+ ScreenSaverTime = defaultScreenSaverTime;
+ ScreenSaverInterval = defaultScreenSaverInterval;
+ ScreenSaverBlanking = defaultScreenSaverBlanking;
+ ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
+#ifdef DPMSExtension
+ DPMSStandbyTime = DEFAULT_SCREEN_SAVER_TIME;
+ DPMSSuspendTime = DEFAULT_SCREEN_SAVER_TIME;
+ DPMSOffTime = DEFAULT_SCREEN_SAVER_TIME;
+ DPMSEnabled = TRUE;
+ DPMSPowerLevel = 0;
+#endif
+ InitBlockAndWakeupHandlers();
+ /* Perform any operating system dependent initializations you'd like */
+ OsInit();
+ if(serverGeneration == 1)
+ {
+ CreateWellKnownSockets();
+ InitProcVectors();
+ for (i=1; i<MAXCLIENTS; i++)
+ clients[i] = NullClient;
+ serverClient = xalloc(sizeof(ClientRec));
+ if (!serverClient)
+ FatalError("couldn't create server client");
+ InitClient(serverClient, 0, (pointer)NULL);
+ }
+ else
+ ResetWellKnownSockets ();
+ clients[0] = serverClient;
+ currentMaxClients = 1;
+
+ if (!InitClientResources(serverClient)) /* for root resources */
+ FatalError("couldn't init server resources");
+
+ SetInputCheck(&alwaysCheckForInput[0], &alwaysCheckForInput[1]);
+ screenInfo.arraySize = MAXSCREENS;
+ screenInfo.numScreens = 0;
+
+ InitAtoms();
+ InitEvents();
+ InitSelections();
+ InitGlyphCaching();
+ if (!dixResetPrivates())
+ FatalError("couldn't init private data storage");
+ dixResetRegistry();
+ ResetFontPrivateIndex();
+ InitCallbackManager();
+ InitOutput(&screenInfo, argc, argv);
+
+ if (screenInfo.numScreens < 1)
+ FatalError("no screens found");
+ InitExtensions(argc, argv);
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ ScreenPtr pScreen = screenInfo.screens[i];
+ if (!CreateScratchPixmapsForScreen(i))
+ FatalError("failed to create scratch pixmaps");
+ if (pScreen->CreateScreenResources &&
+ !(*pScreen->CreateScreenResources)(pScreen))
+ FatalError("failed to create screen resources");
+ if (!CreateGCperDepth(i))
+ FatalError("failed to create scratch GCs");
+ if (!CreateDefaultStipple(i))
+ FatalError("failed to create default stipple");
+ if (!CreateRootWindow(pScreen))
+ FatalError("failed to create root window");
+ }
+
+ InitFonts();
+ if (SetDefaultFontPath(defaultFontPath) != Success) {
+ ErrorF("[dix] failed to set default font path '%s'", defaultFontPath);
+ }
+ if (!SetDefaultFont(defaultTextFont)) {
+ FatalError("could not open default font '%s'", defaultTextFont);
+ }
+
+ if (!(rootCursor = CreateRootCursor(NULL, 0))) {
+ FatalError("could not open default cursor font '%s'",
+ defaultCursorFont);
+ }
+
+#ifdef DPMSExtension
+ /* check all screens, looking for DPMS Capabilities */
+ DPMSCapableFlag = DPMSSupported();
+ if (!DPMSCapableFlag)
+ DPMSEnabled = FALSE;
+#endif
+
+#ifdef PANORAMIX
+ /*
+ * Consolidate window and colourmap information for each screen
+ */
+ if (!noPanoramiXExtension)
+ PanoramiXConsolidate();
+#endif
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ InitRootWindow(WindowTable[i]);
+
+ InitCoreDevices();
+ InitInput(argc, argv);
+ InitAndStartDevices();
+
+ dixSaveScreens(serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset);
+
+#ifdef PANORAMIX
+ if (!noPanoramiXExtension) {
+ if (!PanoramiXCreateConnectionBlock()) {
+ FatalError("could not create connection block info");
+ }
+ } else
+#endif
+ {
+ if (!CreateConnectionBlock()) {
+ FatalError("could not create connection block info");
+ }
+ }
+
+#ifdef XQUARTZ
+ /* Let the other threads know the server is done with its init */
+ pthread_mutex_lock(&serverInitCompleteMutex);
+ serverInitComplete = TRUE;
+ pthread_cond_broadcast(&serverInitCompleteCond);
+ pthread_mutex_unlock(&serverInitCompleteMutex);
+#endif
+
+ NotifyParentProcess();
+
+ Dispatch();
+
+ UndisplayDevices();
+
+ /* Now free up whatever must be freed */
+ if (screenIsSaved == SCREEN_SAVER_ON)
+ dixSaveScreens(serverClient, SCREEN_SAVER_OFF, ScreenSaverReset);
+ FreeScreenSaverTimer();
+ CloseDownExtensions();
+
+#ifdef PANORAMIX
+ {
+ Bool remember_it = noPanoramiXExtension;
+ noPanoramiXExtension = TRUE;
+ FreeAllResources();
+ noPanoramiXExtension = remember_it;
+ }
+#else
+ FreeAllResources();
+#endif
+
+ CloseInput();
+
+ memset(WindowTable, 0, sizeof(WindowTable));
+ CloseDownDevices();
+ CloseDownEvents();
+
+ for (i = screenInfo.numScreens - 1; i >= 0; i--)
+ {
+ FreeScratchPixmapsForScreen(i);
+ FreeGCperDepth(i);
+ FreeDefaultStipple(i);
+ (* screenInfo.screens[i]->CloseScreen)(i, screenInfo.screens[i]);
+ dixFreePrivates(screenInfo.screens[i]->devPrivates);
+ xfree(screenInfo.screens[i]);
+ screenInfo.numScreens = i;
+ }
+ FreeFonts();
+
+ FreeAuditTimer();
+
+ dixFreePrivates(serverClient->devPrivates);
+ serverClient->devPrivates = NULL;
+
+ if (dispatchException & DE_TERMINATE)
+ {
+ CloseWellKnownConnections();
+ }
+
+ OsCleanup((dispatchException & DE_TERMINATE) != 0);
+
+ if (dispatchException & DE_TERMINATE)
+ {
+ ddxGiveUp();
+ break;
+ }
+
+ xfree(ConnectionInfo);
+ ConnectionInfo = NULL;
+ }
+ return(0);
+}
+
diff --git a/xorg-server/dix/makefile b/xorg-server/dix/makefile new file mode 100644 index 000000000..01e98d638 --- /dev/null +++ b/xorg-server/dix/makefile @@ -0,0 +1,40 @@ +ifeq ($(DEBUG),1)
+DEFINES += FONTDEBUG XSERVER_DTRACE
+endif
+
+LIBRARY=libdix
+
+CSRCS=\
+ atom.c \
+ colormap.c \
+ cursor.c \
+ deprecated.c \
+ devices.c \
+ dispatch.c \
+ dixfonts.c \
+ dixutils.c \
+ enterleave.c \
+ events.c \
+ eventconvert.c \
+ extension.c \
+ ffs.c \
+ gc.c \
+ getevents.c \
+ globals.c \
+ glyphcurs.c \
+ grabs.c \
+ initatoms.c \
+ inpututils.c \
+ main.c \
+ pixmap.c \
+ privates.c \
+ property.c \
+ ptrveloc.c \
+ registry.c \
+ resource.c \
+ selection.c \
+ swaprep.c \
+ swapreq.c \
+ tables.c \
+ window.c
+
diff --git a/xorg-server/dix/ptrveloc.c b/xorg-server/dix/ptrveloc.c index c2f43784c..b9ece2159 100644 --- a/xorg-server/dix/ptrveloc.c +++ b/xorg-server/dix/ptrveloc.c @@ -1,1190 +1,1199 @@ -/* - * - * Copyright © 2006-2009 Simon Thum simon dot thum at gmx dot de - * - * 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 <dix-config.h> -#endif - -#include <math.h> -#include <ptrveloc.h> -#include <exevents.h> -#include <X11/Xatom.h> - -#include <xserver-properties.h> - -/***************************************************************************** - * Predictable pointer acceleration - * - * 2006-2009 by Simon Thum (simon [dot] thum [at] gmx de) - * - * Serves 3 complementary functions: - * 1) provide a sophisticated ballistic velocity estimate to improve - * the relation between velocity (of the device) and acceleration - * 2) make arbitrary acceleration profiles possible - * 3) decelerate by two means (constant and adaptive) if enabled - * - * Important concepts are the - * - * - Scheme - * which selects the basic algorithm - * (see devices.c/InitPointerAccelerationScheme) - * - Profile - * which returns an acceleration - * for a given velocity - * - * The profile can be selected by the user at runtime. - * The classic profile is intended to cleanly perform old-style - * function selection (threshold =/!= 0) - * - ****************************************************************************/ - -/* fwds */ -int -SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num); -static float -SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, float velocity, - float threshold, float acc); -static PointerAccelerationProfileFunc -GetAccelerationProfile(DeviceVelocityPtr vel, int profile_num); - -/*#define PTRACCEL_DEBUGGING*/ - -#ifdef PTRACCEL_DEBUGGING -#define DebugAccelF ErrorF -#else -#define DebugAccelF(...) /* */ -#endif - -/******************************** - * Init/Uninit - *******************************/ - -/* some int which is not a profile number */ -#define PROFILE_UNINITIALIZE (-100) - -/* number of properties for predictable acceleration */ -#define NPROPS_PREDICTABLE_ACCEL 4 - -/** - * Init struct so it should match the average case - */ -void -InitVelocityData(DeviceVelocityPtr vel) -{ - memset(vel, 0, sizeof(DeviceVelocityRec)); - - vel->corr_mul = 10.0; /* dots per 10 milisecond should be usable */ - vel->const_acceleration = 1.0; /* no acceleration/deceleration */ - vel->reset_time = 300; - vel->use_softening = 1; - vel->min_acceleration = 1.0; /* don't decelerate */ - vel->max_rel_diff = 0.2; - vel->max_diff = 1.0; - vel->initial_range = 2; - vel->average_accel = TRUE; - SetAccelerationProfile(vel, AccelProfileClassic); - InitTrackers(vel, 16); -} - - -/** - * Clean up - */ -void -FreeVelocityData(DeviceVelocityPtr vel){ - xfree(vel->tracker); - SetAccelerationProfile(vel, PROFILE_UNINITIALIZE); -} - - -/* - * dix uninit helper, called through scheme - */ -void -AccelerationDefaultCleanup(DeviceIntPtr dev) -{ - /*sanity check*/ - if( dev->valuator->accelScheme.AccelSchemeProc == acceleratePointerPredictable - && dev->valuator->accelScheme.accelData != NULL){ - dev->valuator->accelScheme.AccelSchemeProc = NULL; - FreeVelocityData(dev->valuator->accelScheme.accelData); - xfree(dev->valuator->accelScheme.accelData); - dev->valuator->accelScheme.accelData = NULL; - DeletePredictableAccelerationProperties(dev); - } -} - - -/************************* - * Input property support - ************************/ - -/** - * choose profile - */ -static int -AccelSetProfileProperty(DeviceIntPtr dev, Atom atom, - XIPropertyValuePtr val, BOOL checkOnly) -{ - DeviceVelocityPtr vel; - int profile, *ptr = &profile; - int rc; - int nelem = 1; - - if (atom != XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER)) - return Success; - - vel = GetDevicePredictableAccelData(dev); - if (!vel) - return BadValue; - rc = XIPropToInt(val, &nelem, &ptr); - - if(checkOnly) - { - if (rc) - return rc; - - if (GetAccelerationProfile(vel, profile) == NULL) - return BadValue; - } else - SetAccelerationProfile(vel, profile); - - return Success; -} - -static long -AccelInitProfileProperty(DeviceIntPtr dev, DeviceVelocityPtr vel) -{ - int profile = vel->statistics.profile_number; - Atom prop_profile_number = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER); - - XIChangeDeviceProperty(dev, prop_profile_number, XA_INTEGER, 32, - PropModeReplace, 1, &profile, FALSE); - XISetDevicePropertyDeletable(dev, prop_profile_number, FALSE); - return XIRegisterPropertyHandler(dev, AccelSetProfileProperty, NULL, NULL); -} - -/** - * constant deceleration - */ -static int -AccelSetDecelProperty(DeviceIntPtr dev, Atom atom, - XIPropertyValuePtr val, BOOL checkOnly) -{ - DeviceVelocityPtr vel; - float v, *ptr = &v; - int rc; - int nelem = 1; - - if (atom != XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION)) - return Success; - - vel = GetDevicePredictableAccelData(dev); - if (!vel) - return BadValue; - rc = XIPropToFloat(val, &nelem, &ptr); - - if(checkOnly) - { - if (rc) - return rc; - return (v >= 1.0f) ? Success : BadValue; - } - - if(v >= 1.0f) - vel->const_acceleration = 1/v; - - return Success; -} - -static long -AccelInitDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel) -{ - float fval = 1.0/vel->const_acceleration; - Atom prop_const_decel = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION); - XIChangeDeviceProperty(dev, prop_const_decel, - XIGetKnownProperty(XATOM_FLOAT), 32, - PropModeReplace, 1, &fval, FALSE); - XISetDevicePropertyDeletable(dev, prop_const_decel, FALSE); - return XIRegisterPropertyHandler(dev, AccelSetDecelProperty, NULL, NULL); -} - - -/** - * adaptive deceleration - */ -static int -AccelSetAdaptDecelProperty(DeviceIntPtr dev, Atom atom, - XIPropertyValuePtr val, BOOL checkOnly) -{ - DeviceVelocityPtr veloc; - float v, *ptr = &v; - int rc; - int nelem = 1; - - if (atom != XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION)) - return Success; - - veloc = GetDevicePredictableAccelData(dev); - if (!veloc) - return BadValue; - rc = XIPropToFloat(val, &nelem, &ptr); - - if(checkOnly) - { - if (rc) - return rc; - return (v >= 1.0f) ? Success : BadValue; - } - - if(v >= 1.0f) - veloc->min_acceleration = 1/v; - - return Success; -} - -static long -AccelInitAdaptDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel) -{ - float fval = 1.0/vel->min_acceleration; - Atom prop_adapt_decel = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION); - - XIChangeDeviceProperty(dev, prop_adapt_decel, XIGetKnownProperty(XATOM_FLOAT), 32, - PropModeReplace, 1, &fval, FALSE); - XISetDevicePropertyDeletable(dev, prop_adapt_decel, FALSE); - return XIRegisterPropertyHandler(dev, AccelSetAdaptDecelProperty, NULL, NULL); -} - - -/** - * velocity scaling - */ -static int -AccelSetScaleProperty(DeviceIntPtr dev, Atom atom, - XIPropertyValuePtr val, BOOL checkOnly) -{ - DeviceVelocityPtr vel; - float v, *ptr = &v; - int rc; - int nelem = 1; - - if (atom != XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING)) - return Success; - - vel = GetDevicePredictableAccelData(dev); - if (!vel) - return BadValue; - rc = XIPropToFloat(val, &nelem, &ptr); - - if (checkOnly) - { - if (rc) - return rc; - - return (v > 0) ? Success : BadValue; - } - - if(v > 0) - vel->corr_mul = v; - - return Success; -} - -static long -AccelInitScaleProperty(DeviceIntPtr dev, DeviceVelocityPtr vel) -{ - float fval = vel->corr_mul; - Atom prop_velo_scale = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING); - - XIChangeDeviceProperty(dev, prop_velo_scale, XIGetKnownProperty(XATOM_FLOAT), 32, - PropModeReplace, 1, &fval, FALSE); - XISetDevicePropertyDeletable(dev, prop_velo_scale, FALSE); - return XIRegisterPropertyHandler(dev, AccelSetScaleProperty, NULL, NULL); -} - -static int AccelPropHandlerPrivateKeyIndex; -DevPrivateKey AccelPropHandlerPrivateKey = &AccelPropHandlerPrivateKeyIndex; - -BOOL -InitializePredictableAccelerationProperties(DeviceIntPtr dev) -{ - DeviceVelocityPtr vel = GetDevicePredictableAccelData(dev); - long *prop_handlers; - - if(!vel) - return FALSE; - prop_handlers = xalloc(NPROPS_PREDICTABLE_ACCEL * sizeof(long)); - - prop_handlers[0] = AccelInitProfileProperty(dev, vel); - prop_handlers[1] = AccelInitDecelProperty(dev, vel); - prop_handlers[2] = AccelInitAdaptDecelProperty(dev, vel); - prop_handlers[3] = AccelInitScaleProperty(dev, vel); - - dixSetPrivate(&dev->devPrivates, AccelPropHandlerPrivateKey, - prop_handlers); - - return TRUE; -} - -BOOL -DeletePredictableAccelerationProperties(DeviceIntPtr dev) -{ - Atom prop; - long *prop_handlers; - int i; - - prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING); - XIDeleteDeviceProperty(dev, prop, FALSE); - prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION); - XIDeleteDeviceProperty(dev, prop, FALSE); - prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION); - XIDeleteDeviceProperty(dev, prop, FALSE); - prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER); - XIDeleteDeviceProperty(dev, prop, FALSE); - - prop_handlers = dixLookupPrivate(&dev->devPrivates, - AccelPropHandlerPrivateKey); - dixSetPrivate(&dev->devPrivates, AccelPropHandlerPrivateKey, NULL); - - for (i = 0; prop_handlers && i < NPROPS_PREDICTABLE_ACCEL; i++) - XIUnregisterPropertyHandler(dev, prop_handlers[i]); - xfree(prop_handlers); - - return TRUE; -} - -/********************* - * Tracking logic - ********************/ - -void -InitTrackers(DeviceVelocityPtr vel, int ntracker) -{ - if(ntracker < 1){ - ErrorF("(dix ptracc) invalid number of trackers\n"); - return; - } - xfree(vel->tracker); - vel->tracker = (MotionTrackerPtr)xalloc(ntracker * sizeof(MotionTracker)); - memset(vel->tracker, 0, ntracker * sizeof(MotionTracker)); - vel->num_tracker = ntracker; -} - -/** - * return a bit field of possible directions. - * 0 = N, 2 = E, 4 = S, 6 = W, in-between is as you guess. - * There's no reason against widening to more precise directions (<45 degrees), - * should it not perform well. All this is needed for is sort out non-linear - * motion, so precision isn't paramount. However, one should not flag direction - * too narrow, since it would then cut the linear segment to zero size way too - * often. - */ -static int -DoGetDirection(int dx, int dy){ - float r; - int i1, i2; - /* on insignificant mickeys, flag 135 degrees */ - if(abs(dx) < 2 && abs(dy < 2)){ - /* first check diagonal cases */ - if(dx > 0 && dy > 0) - return 4+8+16; - if(dx > 0 && dy < 0) - return 1+2+4; - if(dx < 0 && dy < 0) - return 1+128+64; - if(dx < 0 && dy > 0) - return 16+32+64; - /* check axis-aligned directions */ - if(dx > 0) - return 2+4+8; /*E*/ - if(dx < 0) - return 128+64+32; /*W*/ - if(dy > 0) - return 32+16+8; /*S*/ - if(dy < 0) - return 128+1+2; /*N*/ - return 255; /* shouldn't happen */ - } - /* else, compute angle and set appropriate flags */ -#ifdef _ISOC99_SOURCE - r = atan2f(dy, dx); -#else - r = atan2(dy, dx); -#endif - /* find direction. We avoid r to become negative, - * since C has no well-defined modulo for such cases. */ - r = (r+(M_PI*2.5))/(M_PI/4); - /* this intends to flag 2 directions (90 degrees), - * except on very well-aligned mickeys. */ - i1 = (int)(r+0.1) % 8; - i2 = (int)(r+0.9) % 8; - if(i1 < 0 || i1 > 7 || i2 < 0 || i2 > 7) - return 255; /* shouldn't happen */ - return 1 << i1 | 1 << i2; -} - -#define DIRECTION_CACHE_RANGE 5 -#define DIRECTION_CACHE_SIZE (DIRECTION_CACHE_RANGE*2+1) - -/* cache DoGetDirection(). */ -static int -GetDirection(int dx, int dy){ - static int cache[DIRECTION_CACHE_SIZE][DIRECTION_CACHE_SIZE]; - int i; - if (abs(dx) <= DIRECTION_CACHE_RANGE && - abs(dy) <= DIRECTION_CACHE_RANGE) { - /* cacheable */ - i = cache[DIRECTION_CACHE_RANGE+dx][DIRECTION_CACHE_RANGE+dy]; - if(i != 0){ - return i; - }else{ - i = DoGetDirection(dx, dy); - cache[DIRECTION_CACHE_RANGE+dx][DIRECTION_CACHE_RANGE+dy] = i; - return i; - } - }else{ - /* non-cacheable */ - return DoGetDirection(dx, dy); - } -} - -#undef DIRECTION_CACHE_RANGE -#undef DIRECTION_CACHE_SIZE - - -/* convert offset (age) to array index */ -#define TRACKER_INDEX(s, d) (((s)->num_tracker + (s)->cur_tracker - (d)) % (s)->num_tracker) - -static inline void -FeedTrackers(DeviceVelocityPtr vel, int dx, int dy, int cur_t) -{ - int n; - for(n = 0; n < vel->num_tracker; n++){ - vel->tracker[n].dx += dx; - vel->tracker[n].dy += dy; - } - n = (vel->cur_tracker + 1) % vel->num_tracker; - vel->tracker[n].dx = 0; - vel->tracker[n].dy = 0; - vel->tracker[n].time = cur_t; - vel->tracker[n].dir = GetDirection(dx, dy); - DebugAccelF("(dix prtacc) motion [dx: %i dy: %i dir:%i diff: %i]\n", - dx, dy, vel->tracker[n].dir, - cur_t - vel->tracker[vel->cur_tracker].time); - vel->cur_tracker = n; -} - -/** - * calc velocity for given tracker, with - * velocity scaling. - * This assumes linear motion. - */ -static float -CalcTracker(DeviceVelocityPtr vel, int offset, int cur_t){ - int index = TRACKER_INDEX(vel, offset); - float dist = sqrt( vel->tracker[index].dx * vel->tracker[index].dx - + vel->tracker[index].dy * vel->tracker[index].dy); - int dtime = cur_t - vel->tracker[index].time; - if(dtime > 0) - return (dist / dtime); - else - return 0;/* synonymous for NaN, since we're not C99 */ -} - -/* find the most plausible velocity. That is, the most distant - * (in time) tracker which isn't too old, beyond a linear partition, - * or simply too much off initial velocity. - * - * May return 0. - */ -static float -QueryTrackers(DeviceVelocityPtr vel, int cur_t){ - int n, offset, dir = 255, i = -1, age_ms; - /* initial velocity: a low-offset, valid velocity */ - float iveloc = 0, res = 0, tmp, vdiff; - float vfac = vel->corr_mul * vel->const_acceleration; /* premultiply */ - /* loop from current to older data */ - for(offset = 1; offset < vel->num_tracker; offset++){ - n = TRACKER_INDEX(vel, offset); - - age_ms = cur_t - vel->tracker[n].time; - - /* bail out if data is too old and protect from overrun */ - if (age_ms >= vel->reset_time || age_ms < 0) { - DebugAccelF("(dix prtacc) query: tracker too old\n"); - break; - } - - /* - * this heuristic avoids using the linear-motion velocity formula - * in CalcTracker() on motion that isn't exactly linear. So to get - * even more precision we could subdivide as a final step, so possible - * non-linearities are accounted for. - */ - dir &= vel->tracker[n].dir; - if(dir == 0){ - DebugAccelF("(dix prtacc) query: no longer linear\n"); - /* instead of breaking it we might also inspect the partition after, - * but actual improvement with this is probably rare. */ - break; - } - - tmp = CalcTracker(vel, offset, cur_t) * vfac; - - if ((iveloc == 0 || offset <= vel->initial_range) && tmp != 0) { - /* set initial velocity and result */ - res = iveloc = tmp; - i = offset; - } else if (iveloc != 0 && tmp != 0) { - vdiff = fabs(iveloc - tmp); - if (vdiff <= vel->max_diff || - vdiff/(iveloc + tmp) < vel->max_rel_diff) { - /* we're in range with the initial velocity, - * so this result is likely better - * (it contains more information). */ - res = tmp; - i = offset; - }else{ - /* we're not in range, quit - it won't get better. */ - DebugAccelF("(dix prtacc) query: tracker too different:" - " old %2.2f initial %2.2f diff: %2.2f\n", - tmp, iveloc, vdiff); - break; - } - } - } - if(offset == vel->num_tracker){ - DebugAccelF("(dix prtacc) query: last tracker in effect\n"); - i = vel->num_tracker-1; - } - if(i>=0){ - n = TRACKER_INDEX(vel, i); - DebugAccelF("(dix prtacc) result: offset %i [dx: %i dy: %i diff: %i]\n", - i, - vel->tracker[n].dx, - vel->tracker[n].dy, - cur_t - vel->tracker[n].time); - } - return res; -} - -#undef TRACKER_INDEX - -/** - * Perform velocity approximation based on 2D 'mickeys' (mouse motion delta). - * return true if non-visible state reset is suggested - */ -short -ProcessVelocityData2D( - DeviceVelocityPtr vel, - int dx, - int dy, - int time) -{ - float velocity; - - vel->last_velocity = vel->velocity; - - FeedTrackers(vel, dx, dy, time); - - velocity = QueryTrackers(vel, time); - - vel->velocity = velocity; - return velocity == 0; -} - -/** - * this flattens significant ( > 1) mickeys a little bit for more steady - * constant-velocity response - */ -static inline float -ApplySimpleSoftening(int od, int d) -{ - float res = d; - if (d <= 1 && d >= -1) - return res; - if (d > od) - res -= 0.5; - else if (d < od) - res += 0.5; - return res; -} - - -static void -ApplySofteningAndConstantDeceleration( - DeviceVelocityPtr vel, - int dx, - int dy, - float* fdx, - float* fdy, - short do_soften) -{ - if (do_soften && vel->use_softening) { - *fdx = ApplySimpleSoftening(vel->last_dx, dx); - *fdy = ApplySimpleSoftening(vel->last_dy, dy); - } else { - *fdx = dx; - *fdy = dy; - } - - *fdx *= vel->const_acceleration; - *fdy *= vel->const_acceleration; -} - -/* - * compute the acceleration for given velocity and enforce min_acceleartion - */ -float -BasicComputeAcceleration( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - float velocity, - float threshold, - float acc){ - - float result; - result = vel->Profile(dev, vel, velocity, threshold, acc); - - /* enforce min_acceleration */ - if (result < vel->min_acceleration) - result = vel->min_acceleration; - return result; -} - -/** - * Compute acceleration. Takes into account averaging, nv-reset, etc. - */ -static float -ComputeAcceleration( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - float threshold, - float acc){ - float res; - - if(vel->velocity <= 0){ - DebugAccelF("(dix ptracc) profile skipped\n"); - /* - * If we have no idea about device velocity, don't pretend it. - */ - return 1; - } - - if(vel->average_accel && vel->velocity != vel->last_velocity){ - /* use simpson's rule to average acceleration between - * current and previous velocity. - * Though being the more natural choice, it causes a minor delay - * in comparison, so it can be disabled. */ - res = BasicComputeAcceleration( - dev, vel, vel->velocity, threshold, acc); - res += BasicComputeAcceleration( - dev, vel, vel->last_velocity, threshold, acc); - res += 4.0f * BasicComputeAcceleration(dev, vel, - (vel->last_velocity + vel->velocity) / 2, - threshold, acc); - res /= 6.0f; - DebugAccelF("(dix ptracc) profile average [%.2f ... %.2f] is %.3f\n", - vel->velocity, vel->last_velocity, res); - return res; - }else{ - res = BasicComputeAcceleration(dev, vel, - vel->velocity, threshold, acc); - DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n", - vel->velocity, res); - return res; - } -} - - -/***************************************** - * Acceleration functions and profiles - ****************************************/ - -/** - * Polynomial function similar previous one, but with f(1) = 1 - */ -static float -PolynomialAccelerationProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - float velocity, - float ignored, - float acc) -{ - return pow(velocity, (acc - 1.0) * 0.5); -} - - -/** - * returns acceleration for velocity. - * This profile selects the two functions like the old scheme did - */ -static float -ClassicProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - float velocity, - float threshold, - float acc) -{ - if (threshold > 0) { - return SimpleSmoothProfile (dev, - vel, - velocity, - threshold, - acc); - } else { - return PolynomialAccelerationProfile (dev, - vel, - velocity, - 0, - acc); - } -} - - -/** - * Power profile - * This has a completely smooth transition curve, i.e. no jumps in the - * derivatives. - * - * This has the expense of overall response dependency on min-acceleration. - * In effect, min_acceleration mimics const_acceleration in this profile. - */ -static float -PowerProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - float velocity, - float threshold, - float acc) -{ - float vel_dist; - - acc = (acc-1.0) * 0.1f + 1.0; /* without this, acc of 2 is unuseable */ - - if (velocity <= threshold) - return vel->min_acceleration; - vel_dist = velocity - threshold; - return (pow(acc, vel_dist)) * vel->min_acceleration; -} - - -/** - * just a smooth function in [0..1] -> [0..1] - * - point symmetry at 0.5 - * - f'(0) = f'(1) = 0 - * - starts faster than a sinoid - * - smoothness C1 (Cinf if you dare to ignore endpoints) - */ -static inline float -CalcPenumbralGradient(float x){ - x *= 2.0f; - x -= 1.0f; - return 0.5f + (x * sqrt(1.0f - x*x) + asin(x))/M_PI; -} - - -/** - * acceleration function similar to classic accelerated/unaccelerated, - * but with smooth transition in between (and towards zero for adaptive dec.). - */ -static float -SimpleSmoothProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - float velocity, - float threshold, - float acc) -{ - if(velocity < 1.0f) - return CalcPenumbralGradient(0.5 + velocity*0.5) * 2.0f - 1.0f; - if(threshold < 1.0f) - threshold = 1.0f; - if (velocity <= threshold) - return 1; - velocity /= threshold; - if (velocity >= acc) - return acc; - else - return 1.0f + (CalcPenumbralGradient(velocity/acc) * (acc - 1.0f)); -} - - -/** - * This profile uses the first half of the penumbral gradient as a start - * and then scales linearly. - */ -static float -SmoothLinearProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - float velocity, - float threshold, - float acc) -{ - float res, nv; - - if(acc > 1.0f) - acc -= 1.0f; /*this is so acc = 1 is no acceleration */ - else - return 1.0f; - - nv = (velocity - threshold) * acc * 0.5f; - - if(nv < 0){ - res = 0; - }else if(nv < 2){ - res = CalcPenumbralGradient(nv*0.25f)*2.0f; - }else{ - nv -= 2.0f; - res = nv * 2.0f / M_PI /* steepness of gradient at 0.5 */ - + 1.0f; /* gradient crosses 2|1 */ - } - res += vel->min_acceleration; - return res; -} - - -/** - * From 0 to threshold, the response graduates smoothly from min_accel to - * acceleration. Beyond threshold it is exactly the specified acceleration. - */ -static float -SmoothLimitedProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - float velocity, - float threshold, - float acc) -{ - float res; - - if(velocity >= threshold || threshold == 0.0f) - return acc; - - velocity /= threshold; /* should be [0..1[ now */ - - res = CalcPenumbralGradient(velocity) * (acc - vel->min_acceleration); - - return vel->min_acceleration + res; -} - - -static float -LinearProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - float velocity, - float threshold, - float acc) -{ - return acc * velocity; -} - -static float -NoProfile( - DeviceIntPtr dev, - DeviceVelocityPtr vel, - float velocity, - float threshold, - float acc) -{ - return 1.0f; -} - -static PointerAccelerationProfileFunc -GetAccelerationProfile( - DeviceVelocityPtr vel, - int profile_num) -{ - switch(profile_num){ - case AccelProfileClassic: - return ClassicProfile; - case AccelProfileDeviceSpecific: - return vel->deviceSpecificProfile; - case AccelProfilePolynomial: - return PolynomialAccelerationProfile; - case AccelProfileSmoothLinear: - return SmoothLinearProfile; - case AccelProfileSimple: - return SimpleSmoothProfile; - case AccelProfilePower: - return PowerProfile; - case AccelProfileLinear: - return LinearProfile; - case AccelProfileSmoothLimited: - return SmoothLimitedProfile; - case AccelProfileNone: - return NoProfile; - default: - return NULL; - } -} - -/** - * Set the profile by number. - * Intended to make profiles exchangeable at runtime. - * If you created a profile, give it a number here and in the header to - * make it selectable. In case some profile-specific init is needed, here - * would be a good place, since FreeVelocityData() also calls this with - * PROFILE_UNINITIALIZE. - * - * returns FALSE if profile number is unavailable, TRUE otherwise. - */ -int -SetAccelerationProfile( - DeviceVelocityPtr vel, - int profile_num) -{ - PointerAccelerationProfileFunc profile; - profile = GetAccelerationProfile(vel, profile_num); - - if(profile == NULL && profile_num != PROFILE_UNINITIALIZE) - return FALSE; - - if(vel->profile_private != NULL){ - /* Here one could free old profile-private data */ - xfree(vel->profile_private); - vel->profile_private = NULL; - } - /* Here one could init profile-private data */ - vel->Profile = profile; - vel->statistics.profile_number = profile_num; - return TRUE; -} - -/********************************************** - * driver interaction - **********************************************/ - - -/** - * device-specific profile - * - * The device-specific profile is intended as a hook for a driver - * which may want to provide an own acceleration profile. - * It should not rely on profile-private data, instead - * it should do init/uninit in the driver (ie. with DEVICE_INIT and friends). - * Users may override or choose it. - */ -void -SetDeviceSpecificAccelerationProfile( - DeviceVelocityPtr vel, - PointerAccelerationProfileFunc profile) -{ - if(vel) - vel->deviceSpecificProfile = profile; -} - -/** - * Use this function to obtain a DeviceVelocityPtr for a device. Will return NULL if - * the predictable acceleration scheme is not in effect. - */ -DeviceVelocityPtr -GetDevicePredictableAccelData( - DeviceIntPtr dev) -{ - /*sanity check*/ - if(!dev){ - ErrorF("[dix] accel: DeviceIntPtr was NULL"); - return NULL; - } - if( dev->valuator && - dev->valuator->accelScheme.AccelSchemeProc == - acceleratePointerPredictable && - dev->valuator->accelScheme.accelData != NULL){ - - return (DeviceVelocityPtr)dev->valuator->accelScheme.accelData; - } - return NULL; -} - -/******************************** - * acceleration schemes - *******************************/ - -/** - * Modifies valuators in-place. - * This version employs a velocity approximation algorithm to - * enable fine-grained predictable acceleration profiles. - */ -void -acceleratePointerPredictable( - DeviceIntPtr dev, - int first_valuator, - int num_valuators, - int *valuators, - int evtime) -{ - float mult = 0.0; - int dx = 0, dy = 0; - int *px = NULL, *py = NULL; - DeviceVelocityPtr velocitydata = - (DeviceVelocityPtr) dev->valuator->accelScheme.accelData; - float fdx, fdy, tmp; /* no need to init */ - Bool soften = TRUE; - - if (!num_valuators || !valuators || !velocitydata) - return; - - if (velocitydata->statistics.profile_number == AccelProfileNone && - velocitydata->const_acceleration == 1.0f) { - return; /*we're inactive anyway, so skip the whole thing.*/ - } - - if (first_valuator == 0) { - dx = valuators[0]; - px = &valuators[0]; - } - if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) { - dy = valuators[1 - first_valuator]; - py = &valuators[1 - first_valuator]; - } - - if (dx || dy){ - /* reset non-visible state? */ - if (ProcessVelocityData2D(velocitydata, dx , dy, evtime)) { - soften = FALSE; - } - - if (dev->ptrfeed && dev->ptrfeed->ctrl.num) { - /* invoke acceleration profile to determine acceleration */ - mult = ComputeAcceleration (dev, velocitydata, - dev->ptrfeed->ctrl.threshold, - (float)dev->ptrfeed->ctrl.num / - (float)dev->ptrfeed->ctrl.den); - - if(mult != 1.0 || velocitydata->const_acceleration != 1.0) { - ApplySofteningAndConstantDeceleration( velocitydata, - dx, dy, - &fdx, &fdy, - (mult > 1.0) && soften); - - if (dx) { - tmp = mult * fdx + dev->last.remainder[0]; - /* Since it may not be apparent: lrintf() does not offer - * strong statements about rounding; however because we - * process each axis conditionally, there's no danger - * of a toggling remainder. Its lack of guarantees likely - * makes it faster on the average target. */ - *px = lrintf(tmp); - dev->last.remainder[0] = tmp - (float)*px; - } - if (dy) { - tmp = mult * fdy + dev->last.remainder[1]; - *py = lrintf(tmp); - dev->last.remainder[1] = tmp - (float)*py; - } - DebugAccelF("pos (%i | %i) remainders x: %.3f y: %.3f delta x:%.3f y:%.3f\n", - *px, *py, dev->last.remainder[0], dev->last.remainder[1], fdx, fdy); - } - } - } - /* remember last motion delta (for softening/slow movement treatment) */ - velocitydata->last_dx = dx; - velocitydata->last_dy = dy; -} - - - -/** - * Originally a part of xf86PostMotionEvent; modifies valuators - * in-place. Retained mostly for embedded scenarios. - */ -void -acceleratePointerLightweight( - DeviceIntPtr dev, - int first_valuator, - int num_valuators, - int *valuators, - int ignored) -{ - float mult = 0.0; - int dx = 0, dy = 0; - int *px = NULL, *py = NULL; - - if (!num_valuators || !valuators) - return; - - if (first_valuator == 0) { - dx = valuators[0]; - px = &valuators[0]; - } - if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) { - dy = valuators[1 - first_valuator]; - py = &valuators[1 - first_valuator]; - } - - if (!dx && !dy) - return; - - if (dev->ptrfeed && dev->ptrfeed->ctrl.num) { - /* modeled from xf86Events.c */ - if (dev->ptrfeed->ctrl.threshold) { - if ((abs(dx) + abs(dy)) >= dev->ptrfeed->ctrl.threshold) { - dev->last.remainder[0] = ((float)dx * - (float)(dev->ptrfeed->ctrl.num)) / - (float)(dev->ptrfeed->ctrl.den) + - dev->last.remainder[0]; - if (px) { - *px = (int)dev->last.remainder[0]; - dev->last.remainder[0] = dev->last.remainder[0] - - (float)(*px); - } - - dev->last.remainder[1] = ((float)dy * - (float)(dev->ptrfeed->ctrl.num)) / - (float)(dev->ptrfeed->ctrl.den) + - dev->last.remainder[1]; - if (py) { - *py = (int)dev->last.remainder[1]; - dev->last.remainder[1] = dev->last.remainder[1] - - (float)(*py); - } - } - } - else { - mult = pow((float)dx * (float)dx + (float)dy * (float)dy, - ((float)(dev->ptrfeed->ctrl.num) / - (float)(dev->ptrfeed->ctrl.den) - 1.0) / - 2.0) / 2.0; - if (dx) { - dev->last.remainder[0] = mult * (float)dx + - dev->last.remainder[0]; - *px = (int)dev->last.remainder[0]; - dev->last.remainder[0] = dev->last.remainder[0] - - (float)(*px); - } - if (dy) { - dev->last.remainder[1] = mult * (float)dy + - dev->last.remainder[1]; - *py = (int)dev->last.remainder[1]; - dev->last.remainder[1] = dev->last.remainder[1] - - (float)(*py); - } - } - } -} +/*
+ *
+ * Copyright © 2006-2009 Simon Thum simon dot thum at gmx dot de
+ *
+ * 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 <dix-config.h>
+#endif
+
+#ifdef _MSC_VER
+#define _USE_MATH_DEFINES
+#endif
+
+#include <math.h>
+#include <ptrveloc.h>
+#include <exevents.h>
+#include <X11/Xatom.h>
+
+#include <xserver-properties.h>
+
+/*****************************************************************************
+ * Predictable pointer acceleration
+ *
+ * 2006-2009 by Simon Thum (simon [dot] thum [at] gmx de)
+ *
+ * Serves 3 complementary functions:
+ * 1) provide a sophisticated ballistic velocity estimate to improve
+ * the relation between velocity (of the device) and acceleration
+ * 2) make arbitrary acceleration profiles possible
+ * 3) decelerate by two means (constant and adaptive) if enabled
+ *
+ * Important concepts are the
+ *
+ * - Scheme
+ * which selects the basic algorithm
+ * (see devices.c/InitPointerAccelerationScheme)
+ * - Profile
+ * which returns an acceleration
+ * for a given velocity
+ *
+ * The profile can be selected by the user at runtime.
+ * The classic profile is intended to cleanly perform old-style
+ * function selection (threshold =/!= 0)
+ *
+ ****************************************************************************/
+
+#ifdef _MSC_VER
+#define inline __inline
+#define lrintf(val) ((int)val)
+#endif
+
+/* fwds */
+int
+SetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
+static float
+SimpleSmoothProfile(DeviceIntPtr dev, DeviceVelocityPtr vel, float velocity,
+ float threshold, float acc);
+static PointerAccelerationProfileFunc
+GetAccelerationProfile(DeviceVelocityPtr vel, int profile_num);
+
+/*#define PTRACCEL_DEBUGGING*/
+
+#ifdef PTRACCEL_DEBUGGING
+#define DebugAccelF ErrorF
+#else
+#define DebugAccelF(...) /* */
+#endif
+
+/********************************
+ * Init/Uninit
+ *******************************/
+
+/* some int which is not a profile number */
+#define PROFILE_UNINITIALIZE (-100)
+
+/* number of properties for predictable acceleration */
+#define NPROPS_PREDICTABLE_ACCEL 4
+
+/**
+ * Init struct so it should match the average case
+ */
+void
+InitVelocityData(DeviceVelocityPtr vel)
+{
+ memset(vel, 0, sizeof(DeviceVelocityRec));
+
+ vel->corr_mul = 10.0; /* dots per 10 milisecond should be usable */
+ vel->const_acceleration = 1.0; /* no acceleration/deceleration */
+ vel->reset_time = 300;
+ vel->use_softening = 1;
+ vel->min_acceleration = 1.0; /* don't decelerate */
+ vel->max_rel_diff = 0.2;
+ vel->max_diff = 1.0;
+ vel->initial_range = 2;
+ vel->average_accel = TRUE;
+ SetAccelerationProfile(vel, AccelProfileClassic);
+ InitTrackers(vel, 16);
+}
+
+
+/**
+ * Clean up
+ */
+void
+FreeVelocityData(DeviceVelocityPtr vel){
+ xfree(vel->tracker);
+ SetAccelerationProfile(vel, PROFILE_UNINITIALIZE);
+}
+
+
+/*
+ * dix uninit helper, called through scheme
+ */
+void
+AccelerationDefaultCleanup(DeviceIntPtr dev)
+{
+ /*sanity check*/
+ if( dev->valuator->accelScheme.AccelSchemeProc == acceleratePointerPredictable
+ && dev->valuator->accelScheme.accelData != NULL){
+ dev->valuator->accelScheme.AccelSchemeProc = NULL;
+ FreeVelocityData(dev->valuator->accelScheme.accelData);
+ xfree(dev->valuator->accelScheme.accelData);
+ dev->valuator->accelScheme.accelData = NULL;
+ DeletePredictableAccelerationProperties(dev);
+ }
+}
+
+
+/*************************
+ * Input property support
+ ************************/
+
+/**
+ * choose profile
+ */
+static int
+AccelSetProfileProperty(DeviceIntPtr dev, Atom atom,
+ XIPropertyValuePtr val, BOOL checkOnly)
+{
+ DeviceVelocityPtr vel;
+ int profile, *ptr = &profile;
+ int rc;
+ int nelem = 1;
+
+ if (atom != XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER))
+ return Success;
+
+ vel = GetDevicePredictableAccelData(dev);
+ if (!vel)
+ return BadValue;
+ rc = XIPropToInt(val, &nelem, &ptr);
+
+ if(checkOnly)
+ {
+ if (rc)
+ return rc;
+
+ if (GetAccelerationProfile(vel, profile) == NULL)
+ return BadValue;
+ } else
+ SetAccelerationProfile(vel, profile);
+
+ return Success;
+}
+
+static long
+AccelInitProfileProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
+{
+ int profile = vel->statistics.profile_number;
+ Atom prop_profile_number = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
+
+ XIChangeDeviceProperty(dev, prop_profile_number, XA_INTEGER, 32,
+ PropModeReplace, 1, &profile, FALSE);
+ XISetDevicePropertyDeletable(dev, prop_profile_number, FALSE);
+ return XIRegisterPropertyHandler(dev, AccelSetProfileProperty, NULL, NULL);
+}
+
+/**
+ * constant deceleration
+ */
+static int
+AccelSetDecelProperty(DeviceIntPtr dev, Atom atom,
+ XIPropertyValuePtr val, BOOL checkOnly)
+{
+ DeviceVelocityPtr vel;
+ float v, *ptr = &v;
+ int rc;
+ int nelem = 1;
+
+ if (atom != XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION))
+ return Success;
+
+ vel = GetDevicePredictableAccelData(dev);
+ if (!vel)
+ return BadValue;
+ rc = XIPropToFloat(val, &nelem, &ptr);
+
+ if(checkOnly)
+ {
+ if (rc)
+ return rc;
+ return (v >= 1.0f) ? Success : BadValue;
+ }
+
+ if(v >= 1.0f)
+ vel->const_acceleration = 1/v;
+
+ return Success;
+}
+
+static long
+AccelInitDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
+{
+ float fval = 1.0/vel->const_acceleration;
+ Atom prop_const_decel = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
+ XIChangeDeviceProperty(dev, prop_const_decel,
+ XIGetKnownProperty(XATOM_FLOAT), 32,
+ PropModeReplace, 1, &fval, FALSE);
+ XISetDevicePropertyDeletable(dev, prop_const_decel, FALSE);
+ return XIRegisterPropertyHandler(dev, AccelSetDecelProperty, NULL, NULL);
+}
+
+
+/**
+ * adaptive deceleration
+ */
+static int
+AccelSetAdaptDecelProperty(DeviceIntPtr dev, Atom atom,
+ XIPropertyValuePtr val, BOOL checkOnly)
+{
+ DeviceVelocityPtr veloc;
+ float v, *ptr = &v;
+ int rc;
+ int nelem = 1;
+
+ if (atom != XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION))
+ return Success;
+
+ veloc = GetDevicePredictableAccelData(dev);
+ if (!veloc)
+ return BadValue;
+ rc = XIPropToFloat(val, &nelem, &ptr);
+
+ if(checkOnly)
+ {
+ if (rc)
+ return rc;
+ return (v >= 1.0f) ? Success : BadValue;
+ }
+
+ if(v >= 1.0f)
+ veloc->min_acceleration = 1/v;
+
+ return Success;
+}
+
+static long
+AccelInitAdaptDecelProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
+{
+ float fval = 1.0/vel->min_acceleration;
+ Atom prop_adapt_decel = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
+
+ XIChangeDeviceProperty(dev, prop_adapt_decel, XIGetKnownProperty(XATOM_FLOAT), 32,
+ PropModeReplace, 1, &fval, FALSE);
+ XISetDevicePropertyDeletable(dev, prop_adapt_decel, FALSE);
+ return XIRegisterPropertyHandler(dev, AccelSetAdaptDecelProperty, NULL, NULL);
+}
+
+
+/**
+ * velocity scaling
+ */
+static int
+AccelSetScaleProperty(DeviceIntPtr dev, Atom atom,
+ XIPropertyValuePtr val, BOOL checkOnly)
+{
+ DeviceVelocityPtr vel;
+ float v, *ptr = &v;
+ int rc;
+ int nelem = 1;
+
+ if (atom != XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING))
+ return Success;
+
+ vel = GetDevicePredictableAccelData(dev);
+ if (!vel)
+ return BadValue;
+ rc = XIPropToFloat(val, &nelem, &ptr);
+
+ if (checkOnly)
+ {
+ if (rc)
+ return rc;
+
+ return (v > 0) ? Success : BadValue;
+ }
+
+ if(v > 0)
+ vel->corr_mul = v;
+
+ return Success;
+}
+
+static long
+AccelInitScaleProperty(DeviceIntPtr dev, DeviceVelocityPtr vel)
+{
+ float fval = vel->corr_mul;
+ Atom prop_velo_scale = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
+
+ XIChangeDeviceProperty(dev, prop_velo_scale, XIGetKnownProperty(XATOM_FLOAT), 32,
+ PropModeReplace, 1, &fval, FALSE);
+ XISetDevicePropertyDeletable(dev, prop_velo_scale, FALSE);
+ return XIRegisterPropertyHandler(dev, AccelSetScaleProperty, NULL, NULL);
+}
+
+static int AccelPropHandlerPrivateKeyIndex;
+DevPrivateKey AccelPropHandlerPrivateKey = &AccelPropHandlerPrivateKeyIndex;
+
+BOOL
+InitializePredictableAccelerationProperties(DeviceIntPtr dev)
+{
+ DeviceVelocityPtr vel = GetDevicePredictableAccelData(dev);
+ long *prop_handlers;
+
+ if(!vel)
+ return FALSE;
+ prop_handlers = xalloc(NPROPS_PREDICTABLE_ACCEL * sizeof(long));
+
+ prop_handlers[0] = AccelInitProfileProperty(dev, vel);
+ prop_handlers[1] = AccelInitDecelProperty(dev, vel);
+ prop_handlers[2] = AccelInitAdaptDecelProperty(dev, vel);
+ prop_handlers[3] = AccelInitScaleProperty(dev, vel);
+
+ dixSetPrivate(&dev->devPrivates, AccelPropHandlerPrivateKey,
+ prop_handlers);
+
+ return TRUE;
+}
+
+BOOL
+DeletePredictableAccelerationProperties(DeviceIntPtr dev)
+{
+ Atom prop;
+ long *prop_handlers;
+ int i;
+
+ prop = XIGetKnownProperty(ACCEL_PROP_VELOCITY_SCALING);
+ XIDeleteDeviceProperty(dev, prop, FALSE);
+ prop = XIGetKnownProperty(ACCEL_PROP_ADAPTIVE_DECELERATION);
+ XIDeleteDeviceProperty(dev, prop, FALSE);
+ prop = XIGetKnownProperty(ACCEL_PROP_CONSTANT_DECELERATION);
+ XIDeleteDeviceProperty(dev, prop, FALSE);
+ prop = XIGetKnownProperty(ACCEL_PROP_PROFILE_NUMBER);
+ XIDeleteDeviceProperty(dev, prop, FALSE);
+
+ prop_handlers = dixLookupPrivate(&dev->devPrivates,
+ AccelPropHandlerPrivateKey);
+ dixSetPrivate(&dev->devPrivates, AccelPropHandlerPrivateKey, NULL);
+
+ for (i = 0; prop_handlers && i < NPROPS_PREDICTABLE_ACCEL; i++)
+ XIUnregisterPropertyHandler(dev, prop_handlers[i]);
+ xfree(prop_handlers);
+
+ return TRUE;
+}
+
+/*********************
+ * Tracking logic
+ ********************/
+
+void
+InitTrackers(DeviceVelocityPtr vel, int ntracker)
+{
+ if(ntracker < 1){
+ ErrorF("(dix ptracc) invalid number of trackers\n");
+ return;
+ }
+ xfree(vel->tracker);
+ vel->tracker = (MotionTrackerPtr)xalloc(ntracker * sizeof(MotionTracker));
+ memset(vel->tracker, 0, ntracker * sizeof(MotionTracker));
+ vel->num_tracker = ntracker;
+}
+
+/**
+ * return a bit field of possible directions.
+ * 0 = N, 2 = E, 4 = S, 6 = W, in-between is as you guess.
+ * There's no reason against widening to more precise directions (<45 degrees),
+ * should it not perform well. All this is needed for is sort out non-linear
+ * motion, so precision isn't paramount. However, one should not flag direction
+ * too narrow, since it would then cut the linear segment to zero size way too
+ * often.
+ */
+static int
+DoGetDirection(int dx, int dy){
+ float r;
+ int i1, i2;
+ /* on insignificant mickeys, flag 135 degrees */
+ if(abs(dx) < 2 && abs(dy < 2)){
+ /* first check diagonal cases */
+ if(dx > 0 && dy > 0)
+ return 4+8+16;
+ if(dx > 0 && dy < 0)
+ return 1+2+4;
+ if(dx < 0 && dy < 0)
+ return 1+128+64;
+ if(dx < 0 && dy > 0)
+ return 16+32+64;
+ /* check axis-aligned directions */
+ if(dx > 0)
+ return 2+4+8; /*E*/
+ if(dx < 0)
+ return 128+64+32; /*W*/
+ if(dy > 0)
+ return 32+16+8; /*S*/
+ if(dy < 0)
+ return 128+1+2; /*N*/
+ return 255; /* shouldn't happen */
+ }
+ /* else, compute angle and set appropriate flags */
+#ifdef _ISOC99_SOURCE
+ r = atan2f(dy, dx);
+#else
+ r = atan2(dy, dx);
+#endif
+ /* find direction. We avoid r to become negative,
+ * since C has no well-defined modulo for such cases. */
+ r = (r+(M_PI*2.5))/(M_PI/4);
+ /* this intends to flag 2 directions (90 degrees),
+ * except on very well-aligned mickeys. */
+ i1 = (int)(r+0.1) % 8;
+ i2 = (int)(r+0.9) % 8;
+ if(i1 < 0 || i1 > 7 || i2 < 0 || i2 > 7)
+ return 255; /* shouldn't happen */
+ return 1 << i1 | 1 << i2;
+}
+
+#define DIRECTION_CACHE_RANGE 5
+#define DIRECTION_CACHE_SIZE (DIRECTION_CACHE_RANGE*2+1)
+
+/* cache DoGetDirection(). */
+static int
+GetDirection(int dx, int dy){
+ static int cache[DIRECTION_CACHE_SIZE][DIRECTION_CACHE_SIZE];
+ int i;
+ if (abs(dx) <= DIRECTION_CACHE_RANGE &&
+ abs(dy) <= DIRECTION_CACHE_RANGE) {
+ /* cacheable */
+ i = cache[DIRECTION_CACHE_RANGE+dx][DIRECTION_CACHE_RANGE+dy];
+ if(i != 0){
+ return i;
+ }else{
+ i = DoGetDirection(dx, dy);
+ cache[DIRECTION_CACHE_RANGE+dx][DIRECTION_CACHE_RANGE+dy] = i;
+ return i;
+ }
+ }else{
+ /* non-cacheable */
+ return DoGetDirection(dx, dy);
+ }
+}
+
+#undef DIRECTION_CACHE_RANGE
+#undef DIRECTION_CACHE_SIZE
+
+
+/* convert offset (age) to array index */
+#define TRACKER_INDEX(s, d) (((s)->num_tracker + (s)->cur_tracker - (d)) % (s)->num_tracker)
+
+static inline void
+FeedTrackers(DeviceVelocityPtr vel, int dx, int dy, int cur_t)
+{
+ int n;
+ for(n = 0; n < vel->num_tracker; n++){
+ vel->tracker[n].dx += dx;
+ vel->tracker[n].dy += dy;
+ }
+ n = (vel->cur_tracker + 1) % vel->num_tracker;
+ vel->tracker[n].dx = 0;
+ vel->tracker[n].dy = 0;
+ vel->tracker[n].time = cur_t;
+ vel->tracker[n].dir = GetDirection(dx, dy);
+ DebugAccelF("(dix prtacc) motion [dx: %i dy: %i dir:%i diff: %i]\n",
+ dx, dy, vel->tracker[n].dir,
+ cur_t - vel->tracker[vel->cur_tracker].time);
+ vel->cur_tracker = n;
+}
+
+/**
+ * calc velocity for given tracker, with
+ * velocity scaling.
+ * This assumes linear motion.
+ */
+static float
+CalcTracker(DeviceVelocityPtr vel, int offset, int cur_t){
+ int index = TRACKER_INDEX(vel, offset);
+ float dist = sqrt( vel->tracker[index].dx * vel->tracker[index].dx
+ + vel->tracker[index].dy * vel->tracker[index].dy);
+ int dtime = cur_t - vel->tracker[index].time;
+ if(dtime > 0)
+ return (dist / dtime);
+ else
+ return 0;/* synonymous for NaN, since we're not C99 */
+}
+
+/* find the most plausible velocity. That is, the most distant
+ * (in time) tracker which isn't too old, beyond a linear partition,
+ * or simply too much off initial velocity.
+ *
+ * May return 0.
+ */
+static float
+QueryTrackers(DeviceVelocityPtr vel, int cur_t){
+ int n, offset, dir = 255, i = -1, age_ms;
+ /* initial velocity: a low-offset, valid velocity */
+ float iveloc = 0, res = 0, tmp, vdiff;
+ float vfac = vel->corr_mul * vel->const_acceleration; /* premultiply */
+ /* loop from current to older data */
+ for(offset = 1; offset < vel->num_tracker; offset++){
+ n = TRACKER_INDEX(vel, offset);
+
+ age_ms = cur_t - vel->tracker[n].time;
+
+ /* bail out if data is too old and protect from overrun */
+ if (age_ms >= vel->reset_time || age_ms < 0) {
+ DebugAccelF("(dix prtacc) query: tracker too old\n");
+ break;
+ }
+
+ /*
+ * this heuristic avoids using the linear-motion velocity formula
+ * in CalcTracker() on motion that isn't exactly linear. So to get
+ * even more precision we could subdivide as a final step, so possible
+ * non-linearities are accounted for.
+ */
+ dir &= vel->tracker[n].dir;
+ if(dir == 0){
+ DebugAccelF("(dix prtacc) query: no longer linear\n");
+ /* instead of breaking it we might also inspect the partition after,
+ * but actual improvement with this is probably rare. */
+ break;
+ }
+
+ tmp = CalcTracker(vel, offset, cur_t) * vfac;
+
+ if ((iveloc == 0 || offset <= vel->initial_range) && tmp != 0) {
+ /* set initial velocity and result */
+ res = iveloc = tmp;
+ i = offset;
+ } else if (iveloc != 0 && tmp != 0) {
+ vdiff = fabs(iveloc - tmp);
+ if (vdiff <= vel->max_diff ||
+ vdiff/(iveloc + tmp) < vel->max_rel_diff) {
+ /* we're in range with the initial velocity,
+ * so this result is likely better
+ * (it contains more information). */
+ res = tmp;
+ i = offset;
+ }else{
+ /* we're not in range, quit - it won't get better. */
+ DebugAccelF("(dix prtacc) query: tracker too different:"
+ " old %2.2f initial %2.2f diff: %2.2f\n",
+ tmp, iveloc, vdiff);
+ break;
+ }
+ }
+ }
+ if(offset == vel->num_tracker){
+ DebugAccelF("(dix prtacc) query: last tracker in effect\n");
+ i = vel->num_tracker-1;
+ }
+ if(i>=0){
+ n = TRACKER_INDEX(vel, i);
+ DebugAccelF("(dix prtacc) result: offset %i [dx: %i dy: %i diff: %i]\n",
+ i,
+ vel->tracker[n].dx,
+ vel->tracker[n].dy,
+ cur_t - vel->tracker[n].time);
+ }
+ return res;
+}
+
+#undef TRACKER_INDEX
+
+/**
+ * Perform velocity approximation based on 2D 'mickeys' (mouse motion delta).
+ * return true if non-visible state reset is suggested
+ */
+short
+ProcessVelocityData2D(
+ DeviceVelocityPtr vel,
+ int dx,
+ int dy,
+ int time)
+{
+ float velocity;
+
+ vel->last_velocity = vel->velocity;
+
+ FeedTrackers(vel, dx, dy, time);
+
+ velocity = QueryTrackers(vel, time);
+
+ vel->velocity = velocity;
+ return velocity == 0;
+}
+
+/**
+ * this flattens significant ( > 1) mickeys a little bit for more steady
+ * constant-velocity response
+ */
+static inline float
+ApplySimpleSoftening(int od, int d)
+{
+ float res = d;
+ if (d <= 1 && d >= -1)
+ return res;
+ if (d > od)
+ res -= 0.5;
+ else if (d < od)
+ res += 0.5;
+ return res;
+}
+
+
+static void
+ApplySofteningAndConstantDeceleration(
+ DeviceVelocityPtr vel,
+ int dx,
+ int dy,
+ float* fdx,
+ float* fdy,
+ short do_soften)
+{
+ if (do_soften && vel->use_softening) {
+ *fdx = ApplySimpleSoftening(vel->last_dx, dx);
+ *fdy = ApplySimpleSoftening(vel->last_dy, dy);
+ } else {
+ *fdx = dx;
+ *fdy = dy;
+ }
+
+ *fdx *= vel->const_acceleration;
+ *fdy *= vel->const_acceleration;
+}
+
+/*
+ * compute the acceleration for given velocity and enforce min_acceleartion
+ */
+float
+BasicComputeAcceleration(
+ DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ float velocity,
+ float threshold,
+ float acc){
+
+ float result;
+ result = vel->Profile(dev, vel, velocity, threshold, acc);
+
+ /* enforce min_acceleration */
+ if (result < vel->min_acceleration)
+ result = vel->min_acceleration;
+ return result;
+}
+
+/**
+ * Compute acceleration. Takes into account averaging, nv-reset, etc.
+ */
+static float
+ComputeAcceleration(
+ DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ float threshold,
+ float acc){
+ float res;
+
+ if(vel->velocity <= 0){
+ DebugAccelF("(dix ptracc) profile skipped\n");
+ /*
+ * If we have no idea about device velocity, don't pretend it.
+ */
+ return 1;
+ }
+
+ if(vel->average_accel && vel->velocity != vel->last_velocity){
+ /* use simpson's rule to average acceleration between
+ * current and previous velocity.
+ * Though being the more natural choice, it causes a minor delay
+ * in comparison, so it can be disabled. */
+ res = BasicComputeAcceleration(
+ dev, vel, vel->velocity, threshold, acc);
+ res += BasicComputeAcceleration(
+ dev, vel, vel->last_velocity, threshold, acc);
+ res += 4.0f * BasicComputeAcceleration(dev, vel,
+ (vel->last_velocity + vel->velocity) / 2,
+ threshold, acc);
+ res /= 6.0f;
+ DebugAccelF("(dix ptracc) profile average [%.2f ... %.2f] is %.3f\n",
+ vel->velocity, vel->last_velocity, res);
+ return res;
+ }else{
+ res = BasicComputeAcceleration(dev, vel,
+ vel->velocity, threshold, acc);
+ DebugAccelF("(dix ptracc) profile sample [%.2f] is %.3f\n",
+ vel->velocity, res);
+ return res;
+ }
+}
+
+
+/*****************************************
+ * Acceleration functions and profiles
+ ****************************************/
+
+/**
+ * Polynomial function similar previous one, but with f(1) = 1
+ */
+static float
+PolynomialAccelerationProfile(
+ DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ float velocity,
+ float ignored,
+ float acc)
+{
+ return pow(velocity, (acc - 1.0) * 0.5);
+}
+
+
+/**
+ * returns acceleration for velocity.
+ * This profile selects the two functions like the old scheme did
+ */
+static float
+ClassicProfile(
+ DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ float velocity,
+ float threshold,
+ float acc)
+{
+ if (threshold > 0) {
+ return SimpleSmoothProfile (dev,
+ vel,
+ velocity,
+ threshold,
+ acc);
+ } else {
+ return PolynomialAccelerationProfile (dev,
+ vel,
+ velocity,
+ 0,
+ acc);
+ }
+}
+
+
+/**
+ * Power profile
+ * This has a completely smooth transition curve, i.e. no jumps in the
+ * derivatives.
+ *
+ * This has the expense of overall response dependency on min-acceleration.
+ * In effect, min_acceleration mimics const_acceleration in this profile.
+ */
+static float
+PowerProfile(
+ DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ float velocity,
+ float threshold,
+ float acc)
+{
+ float vel_dist;
+
+ acc = (acc-1.0) * 0.1f + 1.0; /* without this, acc of 2 is unuseable */
+
+ if (velocity <= threshold)
+ return vel->min_acceleration;
+ vel_dist = velocity - threshold;
+ return (pow(acc, vel_dist)) * vel->min_acceleration;
+}
+
+
+/**
+ * just a smooth function in [0..1] -> [0..1]
+ * - point symmetry at 0.5
+ * - f'(0) = f'(1) = 0
+ * - starts faster than a sinoid
+ * - smoothness C1 (Cinf if you dare to ignore endpoints)
+ */
+static inline float
+CalcPenumbralGradient(float x){
+ x *= 2.0f;
+ x -= 1.0f;
+ return 0.5f + (x * sqrt(1.0f - x*x) + asin(x))/M_PI;
+}
+
+
+/**
+ * acceleration function similar to classic accelerated/unaccelerated,
+ * but with smooth transition in between (and towards zero for adaptive dec.).
+ */
+static float
+SimpleSmoothProfile(
+ DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ float velocity,
+ float threshold,
+ float acc)
+{
+ if(velocity < 1.0f)
+ return CalcPenumbralGradient(0.5 + velocity*0.5) * 2.0f - 1.0f;
+ if(threshold < 1.0f)
+ threshold = 1.0f;
+ if (velocity <= threshold)
+ return 1;
+ velocity /= threshold;
+ if (velocity >= acc)
+ return acc;
+ else
+ return 1.0f + (CalcPenumbralGradient(velocity/acc) * (acc - 1.0f));
+}
+
+
+/**
+ * This profile uses the first half of the penumbral gradient as a start
+ * and then scales linearly.
+ */
+static float
+SmoothLinearProfile(
+ DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ float velocity,
+ float threshold,
+ float acc)
+{
+ float res, nv;
+
+ if(acc > 1.0f)
+ acc -= 1.0f; /*this is so acc = 1 is no acceleration */
+ else
+ return 1.0f;
+
+ nv = (velocity - threshold) * acc * 0.5f;
+
+ if(nv < 0){
+ res = 0;
+ }else if(nv < 2){
+ res = CalcPenumbralGradient(nv*0.25f)*2.0f;
+ }else{
+ nv -= 2.0f;
+ res = nv * 2.0f / M_PI /* steepness of gradient at 0.5 */
+ + 1.0f; /* gradient crosses 2|1 */
+ }
+ res += vel->min_acceleration;
+ return res;
+}
+
+
+/**
+ * From 0 to threshold, the response graduates smoothly from min_accel to
+ * acceleration. Beyond threshold it is exactly the specified acceleration.
+ */
+static float
+SmoothLimitedProfile(
+ DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ float velocity,
+ float threshold,
+ float acc)
+{
+ float res;
+
+ if(velocity >= threshold || threshold == 0.0f)
+ return acc;
+
+ velocity /= threshold; /* should be [0..1[ now */
+
+ res = CalcPenumbralGradient(velocity) * (acc - vel->min_acceleration);
+
+ return vel->min_acceleration + res;
+}
+
+
+static float
+LinearProfile(
+ DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ float velocity,
+ float threshold,
+ float acc)
+{
+ return acc * velocity;
+}
+
+static float
+NoProfile(
+ DeviceIntPtr dev,
+ DeviceVelocityPtr vel,
+ float velocity,
+ float threshold,
+ float acc)
+{
+ return 1.0f;
+}
+
+static PointerAccelerationProfileFunc
+GetAccelerationProfile(
+ DeviceVelocityPtr vel,
+ int profile_num)
+{
+ switch(profile_num){
+ case AccelProfileClassic:
+ return ClassicProfile;
+ case AccelProfileDeviceSpecific:
+ return vel->deviceSpecificProfile;
+ case AccelProfilePolynomial:
+ return PolynomialAccelerationProfile;
+ case AccelProfileSmoothLinear:
+ return SmoothLinearProfile;
+ case AccelProfileSimple:
+ return SimpleSmoothProfile;
+ case AccelProfilePower:
+ return PowerProfile;
+ case AccelProfileLinear:
+ return LinearProfile;
+ case AccelProfileSmoothLimited:
+ return SmoothLimitedProfile;
+ case AccelProfileNone:
+ return NoProfile;
+ default:
+ return NULL;
+ }
+}
+
+/**
+ * Set the profile by number.
+ * Intended to make profiles exchangeable at runtime.
+ * If you created a profile, give it a number here and in the header to
+ * make it selectable. In case some profile-specific init is needed, here
+ * would be a good place, since FreeVelocityData() also calls this with
+ * PROFILE_UNINITIALIZE.
+ *
+ * returns FALSE if profile number is unavailable, TRUE otherwise.
+ */
+int
+SetAccelerationProfile(
+ DeviceVelocityPtr vel,
+ int profile_num)
+{
+ PointerAccelerationProfileFunc profile;
+ profile = GetAccelerationProfile(vel, profile_num);
+
+ if(profile == NULL && profile_num != PROFILE_UNINITIALIZE)
+ return FALSE;
+
+ if(vel->profile_private != NULL){
+ /* Here one could free old profile-private data */
+ xfree(vel->profile_private);
+ vel->profile_private = NULL;
+ }
+ /* Here one could init profile-private data */
+ vel->Profile = profile;
+ vel->statistics.profile_number = profile_num;
+ return TRUE;
+}
+
+/**********************************************
+ * driver interaction
+ **********************************************/
+
+
+/**
+ * device-specific profile
+ *
+ * The device-specific profile is intended as a hook for a driver
+ * which may want to provide an own acceleration profile.
+ * It should not rely on profile-private data, instead
+ * it should do init/uninit in the driver (ie. with DEVICE_INIT and friends).
+ * Users may override or choose it.
+ */
+void
+SetDeviceSpecificAccelerationProfile(
+ DeviceVelocityPtr vel,
+ PointerAccelerationProfileFunc profile)
+{
+ if(vel)
+ vel->deviceSpecificProfile = profile;
+}
+
+/**
+ * Use this function to obtain a DeviceVelocityPtr for a device. Will return NULL if
+ * the predictable acceleration scheme is not in effect.
+ */
+DeviceVelocityPtr
+GetDevicePredictableAccelData(
+ DeviceIntPtr dev)
+{
+ /*sanity check*/
+ if(!dev){
+ ErrorF("[dix] accel: DeviceIntPtr was NULL");
+ return NULL;
+ }
+ if( dev->valuator &&
+ dev->valuator->accelScheme.AccelSchemeProc ==
+ acceleratePointerPredictable &&
+ dev->valuator->accelScheme.accelData != NULL){
+
+ return (DeviceVelocityPtr)dev->valuator->accelScheme.accelData;
+ }
+ return NULL;
+}
+
+/********************************
+ * acceleration schemes
+ *******************************/
+
+/**
+ * Modifies valuators in-place.
+ * This version employs a velocity approximation algorithm to
+ * enable fine-grained predictable acceleration profiles.
+ */
+void
+acceleratePointerPredictable(
+ DeviceIntPtr dev,
+ int first_valuator,
+ int num_valuators,
+ int *valuators,
+ int evtime)
+{
+ float mult = 0.0;
+ int dx = 0, dy = 0;
+ int *px = NULL, *py = NULL;
+ DeviceVelocityPtr velocitydata =
+ (DeviceVelocityPtr) dev->valuator->accelScheme.accelData;
+ float fdx, fdy, tmp; /* no need to init */
+ Bool soften = TRUE;
+
+ if (!num_valuators || !valuators || !velocitydata)
+ return;
+
+ if (velocitydata->statistics.profile_number == AccelProfileNone &&
+ velocitydata->const_acceleration == 1.0f) {
+ return; /*we're inactive anyway, so skip the whole thing.*/
+ }
+
+ if (first_valuator == 0) {
+ dx = valuators[0];
+ px = &valuators[0];
+ }
+ if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) {
+ dy = valuators[1 - first_valuator];
+ py = &valuators[1 - first_valuator];
+ }
+
+ if (dx || dy){
+ /* reset non-visible state? */
+ if (ProcessVelocityData2D(velocitydata, dx , dy, evtime)) {
+ soften = FALSE;
+ }
+
+ if (dev->ptrfeed && dev->ptrfeed->ctrl.num) {
+ /* invoke acceleration profile to determine acceleration */
+ mult = ComputeAcceleration (dev, velocitydata,
+ dev->ptrfeed->ctrl.threshold,
+ (float)dev->ptrfeed->ctrl.num /
+ (float)dev->ptrfeed->ctrl.den);
+
+ if(mult != 1.0 || velocitydata->const_acceleration != 1.0) {
+ ApplySofteningAndConstantDeceleration( velocitydata,
+ dx, dy,
+ &fdx, &fdy,
+ (mult > 1.0) && soften);
+
+ if (dx) {
+ tmp = mult * fdx + dev->last.remainder[0];
+ /* Since it may not be apparent: lrintf() does not offer
+ * strong statements about rounding; however because we
+ * process each axis conditionally, there's no danger
+ * of a toggling remainder. Its lack of guarantees likely
+ * makes it faster on the average target. */
+ *px = lrintf(tmp);
+ dev->last.remainder[0] = tmp - (float)*px;
+ }
+ if (dy) {
+ tmp = mult * fdy + dev->last.remainder[1];
+ *py = lrintf(tmp);
+ dev->last.remainder[1] = tmp - (float)*py;
+ }
+ DebugAccelF("pos (%i | %i) remainders x: %.3f y: %.3f delta x:%.3f y:%.3f\n",
+ *px, *py, dev->last.remainder[0], dev->last.remainder[1], fdx, fdy);
+ }
+ }
+ }
+ /* remember last motion delta (for softening/slow movement treatment) */
+ velocitydata->last_dx = dx;
+ velocitydata->last_dy = dy;
+}
+
+
+
+/**
+ * Originally a part of xf86PostMotionEvent; modifies valuators
+ * in-place. Retained mostly for embedded scenarios.
+ */
+void
+acceleratePointerLightweight(
+ DeviceIntPtr dev,
+ int first_valuator,
+ int num_valuators,
+ int *valuators,
+ int ignored)
+{
+ float mult = 0.0;
+ int dx = 0, dy = 0;
+ int *px = NULL, *py = NULL;
+
+ if (!num_valuators || !valuators)
+ return;
+
+ if (first_valuator == 0) {
+ dx = valuators[0];
+ px = &valuators[0];
+ }
+ if (first_valuator <= 1 && num_valuators >= (2 - first_valuator)) {
+ dy = valuators[1 - first_valuator];
+ py = &valuators[1 - first_valuator];
+ }
+
+ if (!dx && !dy)
+ return;
+
+ if (dev->ptrfeed && dev->ptrfeed->ctrl.num) {
+ /* modeled from xf86Events.c */
+ if (dev->ptrfeed->ctrl.threshold) {
+ if ((abs(dx) + abs(dy)) >= dev->ptrfeed->ctrl.threshold) {
+ dev->last.remainder[0] = ((float)dx *
+ (float)(dev->ptrfeed->ctrl.num)) /
+ (float)(dev->ptrfeed->ctrl.den) +
+ dev->last.remainder[0];
+ if (px) {
+ *px = (int)dev->last.remainder[0];
+ dev->last.remainder[0] = dev->last.remainder[0] -
+ (float)(*px);
+ }
+
+ dev->last.remainder[1] = ((float)dy *
+ (float)(dev->ptrfeed->ctrl.num)) /
+ (float)(dev->ptrfeed->ctrl.den) +
+ dev->last.remainder[1];
+ if (py) {
+ *py = (int)dev->last.remainder[1];
+ dev->last.remainder[1] = dev->last.remainder[1] -
+ (float)(*py);
+ }
+ }
+ }
+ else {
+ mult = pow((float)dx * (float)dx + (float)dy * (float)dy,
+ ((float)(dev->ptrfeed->ctrl.num) /
+ (float)(dev->ptrfeed->ctrl.den) - 1.0) /
+ 2.0) / 2.0;
+ if (dx) {
+ dev->last.remainder[0] = mult * (float)dx +
+ dev->last.remainder[0];
+ *px = (int)dev->last.remainder[0];
+ dev->last.remainder[0] = dev->last.remainder[0] -
+ (float)(*px);
+ }
+ if (dy) {
+ dev->last.remainder[1] = mult * (float)dy +
+ dev->last.remainder[1];
+ *py = (int)dev->last.remainder[1];
+ dev->last.remainder[1] = dev->last.remainder[1] -
+ (float)(*py);
+ }
+ }
+ }
+}
diff --git a/xorg-server/dix/registry.c b/xorg-server/dix/registry.c index ec853b37f..9aa73d11d 100644 --- a/xorg-server/dix/registry.c +++ b/xorg-server/dix/registry.c @@ -25,6 +25,7 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <stdlib.h> #include <string.h> +#include <unistd.h> #include <X11/X.h> #include <X11/Xproto.h> #include "resource.h" diff --git a/xorg-server/exa/exa_accel.c b/xorg-server/exa/exa_accel.c index 4680c3709..00a97fdbf 100644 --- a/xorg-server/exa/exa_accel.c +++ b/xorg-server/exa/exa_accel.c @@ -1,1304 +1,1304 @@ -/* - * Copyright © 2001 Keith Packard - * - * Partly based on code that is Copyright © The XFree86 Project 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 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. - * - * Authors: - * Eric Anholt <eric@anholt.net> - * Michel Dänzer <michel@tungstengraphics.com> - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif -#include "exa_priv.h" -#include <X11/fonts/fontstruct.h> -#include "dixfontstr.h" -#include "exa.h" - -static void -exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n, - DDXPointPtr ppt, int *pwidth, int fSorted) -{ - ScreenPtr pScreen = pDrawable->pScreen; - ExaScreenPriv (pScreen); - RegionPtr pClip = fbGetCompositeClip(pGC); - PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable); - ExaPixmapPriv (pPixmap); - BoxPtr pextent, pbox; - int nbox; - int extentX1, extentX2, extentY1, extentY2; - int fullX1, fullX2, fullY1; - int partX1, partX2; - int off_x, off_y; - - if (pExaScr->fallback_counter || - pExaScr->swappedOut || - pGC->fillStyle != FillSolid || - pExaPixmap->accel_blocked) - { - ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted); - return; - } - - if (pExaScr->do_migration) { - ExaMigrationRec pixmaps[1]; - - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pPixmap; - pixmaps[0].pReg = NULL; - - exaDoMigration (pixmaps, 1, TRUE); - } - - if (!(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) || - !(*pExaScr->info->PrepareSolid) (pPixmap, - pGC->alu, - pGC->planemask, - pGC->fgPixel)) - { - ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted); - return; - } - - pextent = REGION_EXTENTS(pGC->pScreen, pClip); - extentX1 = pextent->x1; - extentY1 = pextent->y1; - extentX2 = pextent->x2; - extentY2 = pextent->y2; - while (n--) - { - fullX1 = ppt->x; - fullY1 = ppt->y; - fullX2 = fullX1 + (int) *pwidth; - ppt++; - pwidth++; - - if (fullY1 < extentY1 || extentY2 <= fullY1) - continue; - - if (fullX1 < extentX1) - fullX1 = extentX1; - - if (fullX2 > extentX2) - fullX2 = extentX2; - - if (fullX1 >= fullX2) - continue; - - nbox = REGION_NUM_RECTS (pClip); - if (nbox == 1) - { - (*pExaScr->info->Solid) (pPixmap, - fullX1 + off_x, fullY1 + off_y, - fullX2 + off_x, fullY1 + 1 + off_y); - } - else - { - pbox = REGION_RECTS(pClip); - while(nbox--) - { - if (pbox->y1 <= fullY1 && fullY1 < pbox->y2) - { - partX1 = pbox->x1; - if (partX1 < fullX1) - partX1 = fullX1; - partX2 = pbox->x2; - if (partX2 > fullX2) - partX2 = fullX2; - if (partX2 > partX1) { - (*pExaScr->info->Solid) (pPixmap, - partX1 + off_x, fullY1 + off_y, - partX2 + off_x, fullY1 + 1 + off_y); - } - } - pbox++; - } - } - } - (*pExaScr->info->DoneSolid) (pPixmap); - exaMarkSync(pScreen); -} - -static Bool -exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, - int w, int h, int format, char *bits, int src_stride) -{ - ExaScreenPriv (pDrawable->pScreen); - PixmapPtr pPix = exaGetDrawablePixmap (pDrawable); - ExaPixmapPriv(pPix); - RegionPtr pClip; - BoxPtr pbox; - int nbox; - int xoff, yoff; - int bpp = pDrawable->bitsPerPixel; - Bool ret = TRUE; - - if (pExaScr->fallback_counter || pExaPixmap->accel_blocked || !pExaScr->info->UploadToScreen) - return FALSE; - - /* If there's a system copy, we want to save the result there */ - if (pExaPixmap->pDamage) - return FALSE; - - /* Don't bother with under 8bpp, XYPixmaps. */ - if (format != ZPixmap || bpp < 8) - return FALSE; - - /* Only accelerate copies: no rop or planemask. */ - if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy) - return FALSE; - - if (pExaScr->swappedOut) - return FALSE; - - if (pExaScr->do_migration) { - ExaMigrationRec pixmaps[1]; - - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pPix; - pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage); - - exaDoMigration (pixmaps, 1, TRUE); - } - - pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); - - if (!pPix) - return FALSE; - - x += pDrawable->x; - y += pDrawable->y; - - pClip = fbGetCompositeClip(pGC); - for (nbox = REGION_NUM_RECTS(pClip), - pbox = REGION_RECTS(pClip); - nbox--; - pbox++) - { - int x1 = x; - int y1 = y; - int x2 = x + w; - int y2 = y + h; - char *src; - Bool ok; - - 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; - - src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8); - ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff, - x2 - x1, y2 - y1, src, src_stride); - /* We have to fall back completely, and ignore what has already been completed. - * Messing with the fb layer directly like we used to is completely unacceptable. - */ - if (!ok) { - ret = FALSE; - break; - } - } - - if (ret) - exaMarkSync(pDrawable->pScreen); - - return ret; -} - -static void -exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, - int w, int h, int leftPad, int format, char *bits) -{ - if (!exaDoPutImage(pDrawable, pGC, depth, x, y, w, h, format, bits, - PixmapBytePad(w, pDrawable->depth))) - ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, - bits); -} - -static Bool inline -exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, - GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy) -{ - ExaScreenPriv (pDstDrawable->pScreen); - PixmapPtr pSrcPixmap, pDstPixmap; - int src_off_x, src_off_y, dst_off_x, dst_off_y; - int dirsetup; - - /* Need to get both pixmaps to call the driver routines */ - pSrcPixmap = exaGetOffscreenPixmap (pSrcDrawable, &src_off_x, &src_off_y); - pDstPixmap = exaGetOffscreenPixmap (pDstDrawable, &dst_off_x, &dst_off_y); - if (!pSrcPixmap || !pDstPixmap) - return FALSE; - - /* - * Now the case of a chip that only supports xdir = ydir = 1 or - * xdir = ydir = -1, but we have xdir != ydir. - */ - dirsetup = 0; /* No direction set up yet. */ - for (; nbox; pbox++, nbox--) { - if (dx >= 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) { - /* Do a xdir = ydir = -1 blit instead. */ - if (dirsetup != -1) { - if (dirsetup != 0) - pExaScr->info->DoneCopy(pDstPixmap); - dirsetup = -1; - if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap, - pDstPixmap, - -1, -1, - pGC ? pGC->alu : GXcopy, - pGC ? pGC->planemask : - FB_ALLONES)) - return FALSE; - } - (*pExaScr->info->Copy)(pDstPixmap, - src_off_x + pbox->x1 + dx, - src_off_y + pbox->y1 + dy, - dst_off_x + pbox->x1, - dst_off_y + pbox->y1, - pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1); - } else if (dx < 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) { - /* Do a xdir = ydir = 1 blit instead. */ - if (dirsetup != 1) { - if (dirsetup != 0) - pExaScr->info->DoneCopy(pDstPixmap); - dirsetup = 1; - if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap, - pDstPixmap, - 1, 1, - pGC ? pGC->alu : GXcopy, - pGC ? pGC->planemask : - FB_ALLONES)) - return FALSE; - } - (*pExaScr->info->Copy)(pDstPixmap, - src_off_x + pbox->x1 + dx, - src_off_y + pbox->y1 + dy, - dst_off_x + pbox->x1, - dst_off_y + pbox->y1, - pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1); - } else if (dx >= 0) { - /* - * xdir = 1, ydir = -1. - * Perform line-by-line xdir = ydir = 1 blits, going up. - */ - int i; - if (dirsetup != 1) { - if (dirsetup != 0) - pExaScr->info->DoneCopy(pDstPixmap); - dirsetup = 1; - if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap, - pDstPixmap, - 1, 1, - pGC ? pGC->alu : GXcopy, - pGC ? pGC->planemask : - FB_ALLONES)) - return FALSE; - } - for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--) - (*pExaScr->info->Copy)(pDstPixmap, - src_off_x + pbox->x1 + dx, - src_off_y + pbox->y1 + dy + i, - dst_off_x + pbox->x1, - dst_off_y + pbox->y1 + i, - pbox->x2 - pbox->x1, 1); - } else { - /* - * xdir = -1, ydir = 1. - * Perform line-by-line xdir = ydir = -1 blits, going down. - */ - int i; - if (dirsetup != -1) { - if (dirsetup != 0) - pExaScr->info->DoneCopy(pDstPixmap); - dirsetup = -1; - if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap, - pDstPixmap, - -1, -1, - pGC ? pGC->alu : GXcopy, - pGC ? pGC->planemask : - FB_ALLONES)) - return FALSE; - } - for (i = 0; i < pbox->y2 - pbox->y1; i++) - (*pExaScr->info->Copy)(pDstPixmap, - src_off_x + pbox->x1 + dx, - src_off_y + pbox->y1 + dy + i, - dst_off_x + pbox->x1, - dst_off_y + pbox->y1 + i, - pbox->x2 - pbox->x1, 1); - } - } - if (dirsetup != 0) - pExaScr->info->DoneCopy(pDstPixmap); - exaMarkSync(pDstDrawable->pScreen); - return TRUE; -} - -Bool -exaHWCopyNtoN (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pbox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown) -{ - ExaScreenPriv (pDstDrawable->pScreen); - PixmapPtr pSrcPixmap, pDstPixmap; - ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap; - int src_off_x, src_off_y; - int dst_off_x, dst_off_y; - RegionPtr srcregion = NULL, dstregion = NULL; - xRectangle *rects; - Bool ret = TRUE; - - /* avoid doing copy operations if no boxes */ - if (nbox == 0) - return TRUE; - - pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable); - pDstPixmap = exaGetDrawablePixmap (pDstDrawable); - - exaGetDrawableDeltas (pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y); - exaGetDrawableDeltas (pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y); - - rects = xalloc(nbox * sizeof(xRectangle)); - - if (rects) { - int i; - int ordering; - - for (i = 0; i < nbox; i++) { - rects[i].x = pbox[i].x1 + dx + src_off_x; - rects[i].y = pbox[i].y1 + dy + src_off_y; - rects[i].width = pbox[i].x2 - pbox[i].x1; - rects[i].height = pbox[i].y2 - pbox[i].y1; - } - - /* This must match the miRegionCopy() logic for reversing rect order */ - if (nbox == 1 || (dx > 0 && dy > 0) || - (pDstDrawable != pSrcDrawable && - (pDstDrawable->type != DRAWABLE_WINDOW || - pSrcDrawable->type != DRAWABLE_WINDOW))) - ordering = CT_YXBANDED; - else - ordering = CT_UNSORTED; - - srcregion = RECTS_TO_REGION(pScreen, nbox, rects, ordering); - xfree(rects); - - if (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask, - pGC->fillStyle, pGC->alu, - pGC->clientClipType)) { - dstregion = REGION_CREATE(pScreen, NullBox, 0); - REGION_COPY(pScreen, dstregion, srcregion); - REGION_TRANSLATE(pScreen, dstregion, dst_off_x - dx - src_off_x, - dst_off_y - dy - src_off_y); - } - } - - - pSrcExaPixmap = ExaGetPixmapPriv (pSrcPixmap); - pDstExaPixmap = ExaGetPixmapPriv (pDstPixmap); - - /* Check whether the accelerator can use this pixmap. - * If the pitch of the pixmaps is out of range, there's nothing - * we can do but fall back to software rendering. - */ - if (pSrcExaPixmap->accel_blocked & EXA_RANGE_PITCH || - pDstExaPixmap->accel_blocked & EXA_RANGE_PITCH) - goto fallback; - - /* If the width or the height of either of the pixmaps - * is out of range, check whether the boxes are actually out of the - * addressable range as well. If they aren't, we can still do - * the copying in hardware. - */ - if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked) { - int i; - - for (i = 0; i < nbox; i++) { - /* src */ - if ((pbox[i].x2 + dx + src_off_x) >= pExaScr->info->maxX || - (pbox[i].y2 + dy + src_off_y) >= pExaScr->info->maxY) - goto fallback; - - /* dst */ - if ((pbox[i].x2 + dst_off_x) >= pExaScr->info->maxX || - (pbox[i].y2 + dst_off_y) >= pExaScr->info->maxY) - goto fallback; - } - } - - if (pExaScr->do_migration) { - ExaMigrationRec pixmaps[2]; - - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pDstPixmap; - pixmaps[0].pReg = dstregion; - pixmaps[1].as_dst = FALSE; - pixmaps[1].as_src = TRUE; - pixmaps[1].pPix = pSrcPixmap; - pixmaps[1].pReg = srcregion; - - exaDoMigration (pixmaps, 2, TRUE); - } - - /* Mixed directions must be handled specially if the card is lame */ - if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) && - reverse != upsidedown) { - if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, - dx, dy)) - goto out; - goto fallback; - } - - if (exaPixmapHasGpuCopy(pDstPixmap)) { - /* Normal blitting. */ - if (exaPixmapHasGpuCopy(pSrcPixmap)) { - if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1, - upsidedown ? -1 : 1, - pGC ? pGC->alu : GXcopy, - pGC ? pGC->planemask : FB_ALLONES)) { - goto fallback; - } - - while (nbox--) - { - (*pExaScr->info->Copy) (pDstPixmap, - pbox->x1 + dx + src_off_x, - pbox->y1 + dy + src_off_y, - pbox->x1 + dst_off_x, pbox->y1 + dst_off_y, - pbox->x2 - pbox->x1, pbox->y2 - pbox->y1); - pbox++; - } - - (*pExaScr->info->DoneCopy) (pDstPixmap); - exaMarkSync (pDstDrawable->pScreen); - /* UTS: mainly for SHM PutImage's secondary path. - * - * Only taking this path for directly accessible pixmaps. - */ - } else if (!pDstExaPixmap->pDamage) { - int bpp = pSrcDrawable->bitsPerPixel; - int src_stride = exaGetPixmapPitch(pSrcPixmap); - CARD8 *src = NULL; - - if (!pExaScr->info->UploadToScreen) - goto fallback; - - if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel) - goto fallback; - - if (pSrcDrawable->bitsPerPixel < 8) - goto fallback; - - if (pGC && !(pGC->alu == GXcopy && EXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask))) - goto fallback; - - while (nbox--) - { - src = pSrcExaPixmap->sys_ptr + (pbox->y1 + dy + src_off_y) * src_stride + (pbox->x1 + dx + src_off_x) * (bpp / 8); - if (!pExaScr->info->UploadToScreen(pDstPixmap, pbox->x1 + dst_off_x, - pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, - (char *) src, src_stride)) - goto fallback; - - pbox++; - } - } else - goto fallback; - } else - goto fallback; - - goto out; - -fallback: - ret = FALSE; - -out: - if (dstregion) { - REGION_UNINIT(pScreen, dstregion); - REGION_DESTROY(pScreen, dstregion); - } - if (srcregion) { - REGION_UNINIT(pScreen, srcregion); - REGION_DESTROY(pScreen, srcregion); - } - - return ret; -} - -void -exaCopyNtoN (DrawablePtr pSrcDrawable, - DrawablePtr pDstDrawable, - GCPtr pGC, - BoxPtr pbox, - int nbox, - int dx, - int dy, - Bool reverse, - Bool upsidedown, - Pixel bitplane, - void *closure) -{ - ExaScreenPriv(pDstDrawable->pScreen); - - if (pExaScr->fallback_counter || - (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW)) - return; - - if (exaHWCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown)) - return; - - /* This is a CopyWindow, it's cleaner to fallback at the original call. */ - if (pExaScr->fallback_flags & EXA_ACCEL_COPYWINDOW) { - pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW; - return; - } - - /* fallback */ - ExaCheckCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown, bitplane, closure); -} - -RegionPtr -exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC, - int srcx, int srcy, int width, int height, int dstx, int dsty) -{ - ExaScreenPriv (pDstDrawable->pScreen); - - if (pExaScr->fallback_counter || pExaScr->swappedOut) { - return ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC, - srcx, srcy, width, height, dstx, dsty); - } - - return miDoCopy (pSrcDrawable, pDstDrawable, pGC, - srcx, srcy, width, height, - dstx, dsty, exaCopyNtoN, 0, NULL); -} - -static void -exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr ppt) -{ - ExaScreenPriv (pDrawable->pScreen); - int i; - xRectangle *prect; - - /* If we can't reuse the current GC as is, don't bother accelerating the - * points. - */ - if (pExaScr->fallback_counter || pGC->fillStyle != FillSolid) { - ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt); - return; - } - - prect = xalloc(sizeof(xRectangle) * npt); - for (i = 0; i < npt; i++) { - prect[i].x = ppt[i].x; - prect[i].y = ppt[i].y; - if (i > 0 && mode == CoordModePrevious) { - prect[i].x += prect[i - 1].x; - prect[i].y += prect[i - 1].y; - } - prect[i].width = 1; - prect[i].height = 1; - } - pGC->ops->PolyFillRect(pDrawable, pGC, npt, prect); - xfree(prect); -} - -/** - * exaPolylines() checks if it can accelerate the lines as a group of - * horizontal or vertical lines (rectangles), and uses existing rectangle fill - * acceleration if so. - */ -static void -exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr ppt) -{ - ExaScreenPriv (pDrawable->pScreen); - xRectangle *prect; - int x1, x2, y1, y2; - int i; - - if (pExaScr->fallback_counter) { - ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt); - return; - } - - /* Don't try to do wide lines or non-solid fill style. */ - if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid || - pGC->fillStyle != FillSolid) { - ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt); - return; - } - - prect = xalloc(sizeof(xRectangle) * (npt - 1)); - x1 = ppt[0].x; - y1 = ppt[0].y; - /* If we have any non-horizontal/vertical, fall back. */ - for (i = 0; i < npt - 1; i++) { - if (mode == CoordModePrevious) { - x2 = x1 + ppt[i + 1].x; - y2 = y1 + ppt[i + 1].y; - } else { - x2 = ppt[i + 1].x; - y2 = ppt[i + 1].y; - } - - if (x1 != x2 && y1 != y2) { - xfree(prect); - ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt); - return; - } - - if (x1 < x2) { - prect[i].x = x1; - prect[i].width = x2 - x1 + 1; - } else { - prect[i].x = x2; - prect[i].width = x1 - x2 + 1; - } - if (y1 < y2) { - prect[i].y = y1; - prect[i].height = y2 - y1 + 1; - } else { - prect[i].y = y2; - prect[i].height = y1 - y2 + 1; - } - - x1 = x2; - y1 = y2; - } - pGC->ops->PolyFillRect(pDrawable, pGC, npt - 1, prect); - xfree(prect); -} - -/** - * exaPolySegment() checks if it can accelerate the lines as a group of - * horizontal or vertical lines (rectangles), and uses existing rectangle fill - * acceleration if so. - */ -static void -exaPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg, - xSegment *pSeg) -{ - ExaScreenPriv (pDrawable->pScreen); - xRectangle *prect; - int i; - - /* Don't try to do wide lines or non-solid fill style. */ - if (pExaScr->fallback_counter || pGC->lineWidth != 0 || - pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid) - { - ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg); - return; - } - - /* If we have any non-horizontal/vertical, fall back. */ - for (i = 0; i < nseg; i++) { - if (pSeg[i].x1 != pSeg[i].x2 && pSeg[i].y1 != pSeg[i].y2) { - ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg); - return; - } - } - - prect = xalloc(sizeof(xRectangle) * nseg); - for (i = 0; i < nseg; i++) { - if (pSeg[i].x1 < pSeg[i].x2) { - prect[i].x = pSeg[i].x1; - prect[i].width = pSeg[i].x2 - pSeg[i].x1 + 1; - } else { - prect[i].x = pSeg[i].x2; - prect[i].width = pSeg[i].x1 - pSeg[i].x2 + 1; - } - if (pSeg[i].y1 < pSeg[i].y2) { - prect[i].y = pSeg[i].y1; - prect[i].height = pSeg[i].y2 - pSeg[i].y1 + 1; - } else { - prect[i].y = pSeg[i].y2; - prect[i].height = pSeg[i].y1 - pSeg[i].y2 + 1; - } - - /* don't paint last pixel */ - if (pGC->capStyle == CapNotLast) { - if (prect[i].width == 1) - prect[i].height--; - else - prect[i].width--; - } - } - pGC->ops->PolyFillRect(pDrawable, pGC, nseg, prect); - xfree(prect); -} - -static Bool exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, - Pixel pixel, CARD32 planemask, CARD32 alu, - unsigned int clientClipType); - -static void -exaPolyFillRect(DrawablePtr pDrawable, - GCPtr pGC, - int nrect, - xRectangle *prect) -{ - ExaScreenPriv (pDrawable->pScreen); - RegionPtr pClip = fbGetCompositeClip(pGC); - PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); - ExaPixmapPriv (pPixmap); - register BoxPtr pbox; - BoxPtr pextent; - int extentX1, extentX2, extentY1, extentY2; - int fullX1, fullX2, fullY1, fullY2; - int partX1, partX2, partY1, partY2; - int xoff, yoff; - int xorg, yorg; - int n; - RegionPtr pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED); - - /* Compute intersection of rects and clip region */ - REGION_TRANSLATE(pScreen, pReg, pDrawable->x, pDrawable->y); - REGION_INTERSECT(pScreen, pReg, pClip, pReg); - - if (!REGION_NUM_RECTS(pReg)) { - goto out; - } - - exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); - - if (pExaScr->fallback_counter || pExaScr->swappedOut || - pExaPixmap->accel_blocked) - { - goto fallback; - } - - /* For ROPs where overlaps don't matter, convert rectangles to region and - * call exaFillRegion{Solid,Tiled}. - */ - if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) && - (nrect == 1 || pGC->alu == GXcopy || pGC->alu == GXclear || - pGC->alu == GXnoop || pGC->alu == GXcopyInverted || - pGC->alu == GXset)) { - if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) && - exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ? - pGC->fgPixel : pGC->tile.pixel, pGC->planemask, - pGC->alu, pGC->clientClipType)) || - (pGC->fillStyle == FillTiled && !pGC->tileIsPixel && - exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg, - pGC->planemask, pGC->alu, - pGC->clientClipType))) { - goto out; - } - } - - if (pGC->fillStyle != FillSolid && - !(pGC->tileIsPixel && pGC->fillStyle == FillTiled)) - { - goto fallback; - } - - if (pExaScr->do_migration) { - ExaMigrationRec pixmaps[1]; - - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pPixmap; - pixmaps[0].pReg = NULL; - - exaDoMigration (pixmaps, 1, TRUE); - } - - if (!exaPixmapHasGpuCopy (pPixmap) || - !(*pExaScr->info->PrepareSolid) (pPixmap, - pGC->alu, - pGC->planemask, - pGC->fgPixel)) - { -fallback: - ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect); - goto out; - } - - xorg = pDrawable->x; - yorg = pDrawable->y; - - pextent = REGION_EXTENTS(pGC->pScreen, pClip); - extentX1 = pextent->x1; - extentY1 = pextent->y1; - extentX2 = pextent->x2; - extentY2 = pextent->y2; - while (nrect--) - { - fullX1 = prect->x + xorg; - fullY1 = prect->y + yorg; - fullX2 = fullX1 + (int) prect->width; - fullY2 = fullY1 + (int) prect->height; - prect++; - - if (fullX1 < extentX1) - fullX1 = extentX1; - - if (fullY1 < extentY1) - fullY1 = extentY1; - - if (fullX2 > extentX2) - fullX2 = extentX2; - - if (fullY2 > extentY2) - fullY2 = extentY2; - - if ((fullX1 >= fullX2) || (fullY1 >= fullY2)) - continue; - n = REGION_NUM_RECTS (pClip); - if (n == 1) - { - (*pExaScr->info->Solid) (pPixmap, - fullX1 + xoff, fullY1 + yoff, - fullX2 + xoff, fullY2 + yoff); - } - else - { - pbox = REGION_RECTS(pClip); - /* - * clip the rectangle to each box in the clip region - * this is logically equivalent to calling Intersect(), - * but rectangles may overlap each other here. - */ - while(n--) - { - partX1 = pbox->x1; - if (partX1 < fullX1) - partX1 = fullX1; - partY1 = pbox->y1; - if (partY1 < fullY1) - partY1 = fullY1; - partX2 = pbox->x2; - if (partX2 > fullX2) - partX2 = fullX2; - partY2 = pbox->y2; - if (partY2 > fullY2) - partY2 = fullY2; - - pbox++; - - if (partX1 < partX2 && partY1 < partY2) { - (*pExaScr->info->Solid) (pPixmap, - partX1 + xoff, partY1 + yoff, - partX2 + xoff, partY2 + yoff); - } - } - } - } - (*pExaScr->info->DoneSolid) (pPixmap); - exaMarkSync(pDrawable->pScreen); - -out: - REGION_UNINIT(pScreen, pReg); - REGION_DESTROY(pScreen, pReg); -} - -const GCOps exaOps = { - exaFillSpans, - ExaCheckSetSpans, - exaPutImage, - exaCopyArea, - ExaCheckCopyPlane, - exaPolyPoint, - exaPolylines, - exaPolySegment, - miPolyRectangle, - ExaCheckPolyArc, - miFillPolygon, - exaPolyFillRect, - miPolyFillArc, - miPolyText8, - miPolyText16, - miImageText8, - miImageText16, - ExaCheckImageGlyphBlt, - ExaCheckPolyGlyphBlt, - ExaCheckPushPixels, -}; - -void -exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) -{ - RegionRec rgnDst; - int dx, dy; - PixmapPtr pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin); - ExaScreenPriv(pWin->drawable.pScreen); - - dx = ptOldOrg.x - pWin->drawable.x; - dy = ptOldOrg.y - pWin->drawable.y; - REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy); - - REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0); - - REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc); -#ifdef COMPOSITE - if (pPixmap->screen_x || pPixmap->screen_y) - REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst, - -pPixmap->screen_x, -pPixmap->screen_y); -#endif - - if (pExaScr->fallback_counter) { - pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW; - goto fallback; - } - - pExaScr->fallback_flags |= EXA_ACCEL_COPYWINDOW; - miCopyRegion (&pPixmap->drawable, &pPixmap->drawable, - NULL, - &rgnDst, dx, dy, exaCopyNtoN, 0, NULL); - pExaScr->fallback_flags &= ~EXA_ACCEL_COPYWINDOW; - -fallback: - REGION_UNINIT(pWin->drawable.pScreen, &rgnDst); - - if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) { - pExaScr->fallback_flags &= ~EXA_FALLBACK_COPYWINDOW; - REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, dx, dy); - ExaCheckCopyWindow(pWin, ptOldOrg, prgnSrc); - } -} - -static Bool -exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel, - CARD32 planemask, CARD32 alu, unsigned int clientClipType) -{ - ExaScreenPriv(pDrawable->pScreen); - PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable); - ExaPixmapPriv (pPixmap); - int xoff, yoff; - Bool ret = FALSE; - - exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); - REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); - - if (pExaScr->fallback_counter || pExaPixmap->accel_blocked) - goto out; - - if (pExaScr->do_migration) { - ExaMigrationRec pixmaps[1]; - - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pPixmap; - pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid, - alu, clientClipType) ? NULL : pRegion; - - exaDoMigration (pixmaps, 1, TRUE); - } - - if (exaPixmapHasGpuCopy (pPixmap) && - (*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel)) - { - int nbox; - BoxPtr pBox; - - nbox = REGION_NUM_RECTS (pRegion); - pBox = REGION_RECTS (pRegion); - - while (nbox--) - { - (*pExaScr->info->Solid) (pPixmap, pBox->x1, pBox->y1, pBox->x2, - pBox->y2); - pBox++; - } - (*pExaScr->info->DoneSolid) (pPixmap); - exaMarkSync(pDrawable->pScreen); - - if (pExaPixmap->pDamage && - pExaPixmap->sys_ptr && pDrawable->type == DRAWABLE_PIXMAP && - pDrawable->width == 1 && pDrawable->height == 1 && - pDrawable->bitsPerPixel != 24) { - ExaPixmapPriv(pPixmap); - RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage); - - switch (pDrawable->bitsPerPixel) { - case 32: - *(CARD32*)pExaPixmap->sys_ptr = pixel; - break; - case 16: - *(CARD16*)pExaPixmap->sys_ptr = pixel; - break; - case 8: - *(CARD8*)pExaPixmap->sys_ptr = pixel; - } - - REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys, - pRegion); - REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB, - pRegion); - REGION_SUBTRACT(pScreen, pending_damage, pending_damage, pRegion); - } - - ret = TRUE; - } - -out: - REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff); - - return ret; -} - -/* Try to do an accelerated tile of the pTile into pRegion of pDrawable. - * Based on fbFillRegionTiled(), fbTile(). - */ -Bool -exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile, - DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu, - unsigned int clientClipType) -{ - ExaScreenPriv(pDrawable->pScreen); - PixmapPtr pPixmap; - ExaPixmapPrivPtr pExaPixmap; - ExaPixmapPrivPtr pTileExaPixmap = ExaGetPixmapPriv(pTile); - int xoff, yoff; - int tileWidth, tileHeight; - int nbox = REGION_NUM_RECTS (pRegion); - BoxPtr pBox = REGION_RECTS (pRegion); - Bool ret = FALSE; - int i; - - tileWidth = pTile->drawable.width; - tileHeight = pTile->drawable.height; - - /* If we're filling with a solid color, grab it out and go to - * FillRegionSolid, saving numerous copies. - */ - if (tileWidth == 1 && tileHeight == 1) - return exaFillRegionSolid(pDrawable, pRegion, - exaGetPixmapFirstPixel (pTile), planemask, - alu, clientClipType); - - pPixmap = exaGetDrawablePixmap (pDrawable); - pExaPixmap = ExaGetPixmapPriv (pPixmap); - - if (pExaScr->fallback_counter || pExaPixmap->accel_blocked || - pTileExaPixmap->accel_blocked) - return FALSE; - - if (pExaScr->do_migration) { - ExaMigrationRec pixmaps[2]; - - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - pixmaps[0].pPix = pPixmap; - pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillTiled, - alu, clientClipType) ? NULL : pRegion; - pixmaps[1].as_dst = FALSE; - pixmaps[1].as_src = TRUE; - pixmaps[1].pPix = pTile; - pixmaps[1].pReg = NULL; - - exaDoMigration (pixmaps, 2, TRUE); - } - - pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); - - if (!pPixmap || !exaPixmapHasGpuCopy(pTile)) - return FALSE; - - if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask)) - { - if (xoff || yoff) - REGION_TRANSLATE(pScreen, pRegion, xoff, yoff); - - for (i = 0; i < nbox; i++) - { - int height = pBox[i].y2 - pBox[i].y1; - int dstY = pBox[i].y1; - int tileY; - - if (alu == GXcopy) - height = min(height, tileHeight); - - modulus(dstY - yoff - pDrawable->y - pPatOrg->y, tileHeight, tileY); - - while (height > 0) { - int width = pBox[i].x2 - pBox[i].x1; - int dstX = pBox[i].x1; - int tileX; - int h = tileHeight - tileY; - - if (alu == GXcopy) - width = min(width, tileWidth); - - if (h > height) - h = height; - height -= h; - - modulus(dstX - xoff - pDrawable->x - pPatOrg->x, tileWidth, - tileX); - - while (width > 0) { - int w = tileWidth - tileX; - if (w > width) - w = width; - width -= w; - - (*pExaScr->info->Copy) (pPixmap, tileX, tileY, dstX, dstY, - w, h); - dstX += w; - tileX = 0; - } - dstY += h; - tileY = 0; - } - } - (*pExaScr->info->DoneCopy) (pPixmap); - - /* With GXcopy, we only need to do the basic algorithm up to the tile - * size; then, we can just keep doubling the destination in each - * direction until it fills the box. This way, the number of copy - * operations is O(log(rx)) + O(log(ry)) instead of O(rx * ry), where - * rx/ry is the ratio between box and tile width/height. This can make - * a big difference if each driver copy incurs a significant constant - * overhead. - */ - if (alu != GXcopy) - ret = TRUE; - else { - Bool more_copy = FALSE; - - for (i = 0; i < nbox; i++) { - int dstX = pBox[i].x1 + tileWidth; - int dstY = pBox[i].y1 + tileHeight; - - if ((dstX < pBox[i].x2) || (dstY < pBox[i].y2)) { - more_copy = TRUE; - break; - } - } - - if (more_copy == FALSE) - ret = TRUE; - - if (more_copy && (*pExaScr->info->PrepareCopy) (pPixmap, pPixmap, - 1, 1, alu, planemask)) { - for (i = 0; i < nbox; i++) - { - int dstX = pBox[i].x1 + tileWidth; - int dstY = pBox[i].y1 + tileHeight; - int width = min(pBox[i].x2 - dstX, tileWidth); - int height = min(pBox[i].y2 - pBox[i].y1, tileHeight); - - while (dstX < pBox[i].x2) { - (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1, - dstX, pBox[i].y1, width, height); - dstX += width; - width = min(pBox[i].x2 - dstX, width * 2); - } - - width = pBox[i].x2 - pBox[i].x1; - height = min(pBox[i].y2 - dstY, tileHeight); - - while (dstY < pBox[i].y2) { - (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1, - pBox[i].x1, dstY, width, height); - dstY += height; - height = min(pBox[i].y2 - dstY, height * 2); - } - } - - (*pExaScr->info->DoneCopy) (pPixmap); - - ret = TRUE; - } - } - - exaMarkSync(pDrawable->pScreen); - - if (xoff || yoff) - REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff); - } - - return ret; -} - - -/** - * Accelerates GetImage for solid ZPixmap downloads from framebuffer memory. - * - * This is probably the only case we actually care about. The rest fall through - * to migration and fbGetImage, which hopefully will result in migration pushing - * the pixmap out of framebuffer. - */ -void -exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d) -{ - ExaScreenPriv (pDrawable->pScreen); - PixmapPtr pPix = exaGetDrawablePixmap (pDrawable); - ExaPixmapPriv(pPix); - int xoff, yoff; - Bool ok; - - if (pExaScr->fallback_counter || pExaScr->swappedOut) - goto fallback; - - /* If there's a system copy, we want to save the result there */ - if (pExaPixmap->pDamage) - goto fallback; - - pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff); - - if (pPix == NULL || pExaScr->info->DownloadFromScreen == NULL) - goto fallback; - - /* Only cover the ZPixmap, solid copy case. */ - if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask)) - goto fallback; - - /* Only try to handle the 8bpp and up cases, since we don't want to think - * about <8bpp. - */ - if (pDrawable->bitsPerPixel < 8) - goto fallback; - - ok = pExaScr->info->DownloadFromScreen(pPix, pDrawable->x + x + xoff, - pDrawable->y + y + yoff, w, h, d, - PixmapBytePad(w, pDrawable->depth)); - if (ok) { - exaWaitSync(pDrawable->pScreen); - return; - } - -fallback: - ExaCheckGetImage(pDrawable, x, y, w, h, format, planeMask, d); -} +/*
+ * Copyright © 2001 Keith Packard
+ *
+ * Partly based on code that is Copyright © The XFree86 Project 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 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.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ * Michel Dänzer <michel@tungstengraphics.com>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+#include "exa_priv.h"
+#include <X11/fonts/fontstruct.h>
+#include "dixfontstr.h"
+#include "exa.h"
+
+static void
+exaFillSpans(DrawablePtr pDrawable, GCPtr pGC, int n,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ ExaScreenPriv (pScreen);
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
+ ExaPixmapPriv (pPixmap);
+ BoxPtr pextent, pbox;
+ int nbox;
+ int extentX1, extentX2, extentY1, extentY2;
+ int fullX1, fullX2, fullY1;
+ int partX1, partX2;
+ int off_x, off_y;
+
+ if (pExaScr->fallback_counter ||
+ pExaScr->swappedOut ||
+ pGC->fillStyle != FillSolid ||
+ pExaPixmap->accel_blocked)
+ {
+ ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
+ return;
+ }
+
+ if (pExaScr->do_migration) {
+ ExaMigrationRec pixmaps[1];
+
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = pPixmap;
+ pixmaps[0].pReg = NULL;
+
+ exaDoMigration (pixmaps, 1, TRUE);
+ }
+
+ if (!(pPixmap = exaGetOffscreenPixmap (pDrawable, &off_x, &off_y)) ||
+ !(*pExaScr->info->PrepareSolid) (pPixmap,
+ pGC->alu,
+ pGC->planemask,
+ pGC->fgPixel))
+ {
+ ExaCheckFillSpans (pDrawable, pGC, n, ppt, pwidth, fSorted);
+ return;
+ }
+
+ pextent = REGION_EXTENTS(pGC->pScreen, pClip);
+ extentX1 = pextent->x1;
+ extentY1 = pextent->y1;
+ extentX2 = pextent->x2;
+ extentY2 = pextent->y2;
+ while (n--)
+ {
+ fullX1 = ppt->x;
+ fullY1 = ppt->y;
+ fullX2 = fullX1 + (int) *pwidth;
+ ppt++;
+ pwidth++;
+
+ if (fullY1 < extentY1 || extentY2 <= fullY1)
+ continue;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullX1 >= fullX2)
+ continue;
+
+ nbox = REGION_NUM_RECTS (pClip);
+ if (nbox == 1)
+ {
+ (*pExaScr->info->Solid) (pPixmap,
+ fullX1 + off_x, fullY1 + off_y,
+ fullX2 + off_x, fullY1 + 1 + off_y);
+ }
+ else
+ {
+ pbox = REGION_RECTS(pClip);
+ while(nbox--)
+ {
+ if (pbox->y1 <= fullY1 && fullY1 < pbox->y2)
+ {
+ partX1 = pbox->x1;
+ if (partX1 < fullX1)
+ partX1 = fullX1;
+ partX2 = pbox->x2;
+ if (partX2 > fullX2)
+ partX2 = fullX2;
+ if (partX2 > partX1) {
+ (*pExaScr->info->Solid) (pPixmap,
+ partX1 + off_x, fullY1 + off_y,
+ partX2 + off_x, fullY1 + 1 + off_y);
+ }
+ }
+ pbox++;
+ }
+ }
+ }
+ (*pExaScr->info->DoneSolid) (pPixmap);
+ exaMarkSync(pScreen);
+}
+
+static Bool
+exaDoPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int format, char *bits, int src_stride)
+{
+ ExaScreenPriv (pDrawable->pScreen);
+ PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
+ ExaPixmapPriv(pPix);
+ RegionPtr pClip;
+ BoxPtr pbox;
+ int nbox;
+ int xoff, yoff;
+ int bpp = pDrawable->bitsPerPixel;
+ Bool ret = TRUE;
+
+ if (pExaScr->fallback_counter || pExaPixmap->accel_blocked || !pExaScr->info->UploadToScreen)
+ return FALSE;
+
+ /* If there's a system copy, we want to save the result there */
+ if (pExaPixmap->pDamage)
+ return FALSE;
+
+ /* Don't bother with under 8bpp, XYPixmaps. */
+ if (format != ZPixmap || bpp < 8)
+ return FALSE;
+
+ /* Only accelerate copies: no rop or planemask. */
+ if (!EXA_PM_IS_SOLID(pDrawable, pGC->planemask) || pGC->alu != GXcopy)
+ return FALSE;
+
+ if (pExaScr->swappedOut)
+ return FALSE;
+
+ if (pExaScr->do_migration) {
+ ExaMigrationRec pixmaps[1];
+
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = pPix;
+ pixmaps[0].pReg = DamagePendingRegion(pExaPixmap->pDamage);
+
+ exaDoMigration (pixmaps, 1, TRUE);
+ }
+
+ pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
+
+ if (!pPix)
+ return FALSE;
+
+ x += pDrawable->x;
+ y += pDrawable->y;
+
+ pClip = fbGetCompositeClip(pGC);
+ for (nbox = REGION_NUM_RECTS(pClip),
+ pbox = REGION_RECTS(pClip);
+ nbox--;
+ pbox++)
+ {
+ int x1 = x;
+ int y1 = y;
+ int x2 = x + w;
+ int y2 = y + h;
+ char *src;
+ Bool ok;
+
+ 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;
+
+ src = bits + (y1 - y) * src_stride + (x1 - x) * (bpp / 8);
+ ok = pExaScr->info->UploadToScreen(pPix, x1 + xoff, y1 + yoff,
+ x2 - x1, y2 - y1, src, src_stride);
+ /* We have to fall back completely, and ignore what has already been completed.
+ * Messing with the fb layer directly like we used to is completely unacceptable.
+ */
+ if (!ok) {
+ ret = FALSE;
+ break;
+ }
+ }
+
+ if (ret)
+ exaMarkSync(pDrawable->pScreen);
+
+ return ret;
+}
+
+static void
+exaPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y,
+ int w, int h, int leftPad, int format, char *bits)
+{
+ if (!exaDoPutImage(pDrawable, pGC, depth, x, y, w, h, format, bits,
+ PixmapBytePad(w, pDrawable->depth)))
+ ExaCheckPutImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format,
+ bits);
+}
+
+static Bool __inline
+exaCopyNtoNTwoDir (DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable,
+ GCPtr pGC, BoxPtr pbox, int nbox, int dx, int dy)
+{
+ ExaScreenPriv (pDstDrawable->pScreen);
+ PixmapPtr pSrcPixmap, pDstPixmap;
+ int src_off_x, src_off_y, dst_off_x, dst_off_y;
+ int dirsetup;
+
+ /* Need to get both pixmaps to call the driver routines */
+ pSrcPixmap = exaGetOffscreenPixmap (pSrcDrawable, &src_off_x, &src_off_y);
+ pDstPixmap = exaGetOffscreenPixmap (pDstDrawable, &dst_off_x, &dst_off_y);
+ if (!pSrcPixmap || !pDstPixmap)
+ return FALSE;
+
+ /*
+ * Now the case of a chip that only supports xdir = ydir = 1 or
+ * xdir = ydir = -1, but we have xdir != ydir.
+ */
+ dirsetup = 0; /* No direction set up yet. */
+ for (; nbox; pbox++, nbox--) {
+ if (dx >= 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) {
+ /* Do a xdir = ydir = -1 blit instead. */
+ if (dirsetup != -1) {
+ if (dirsetup != 0)
+ pExaScr->info->DoneCopy(pDstPixmap);
+ dirsetup = -1;
+ if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
+ pDstPixmap,
+ -1, -1,
+ pGC ? pGC->alu : GXcopy,
+ pGC ? pGC->planemask :
+ FB_ALLONES))
+ return FALSE;
+ }
+ (*pExaScr->info->Copy)(pDstPixmap,
+ src_off_x + pbox->x1 + dx,
+ src_off_y + pbox->y1 + dy,
+ dst_off_x + pbox->x1,
+ dst_off_y + pbox->y1,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ } else if (dx < 0 && (src_off_y + pbox->y1 + dy) != pbox->y1) {
+ /* Do a xdir = ydir = 1 blit instead. */
+ if (dirsetup != 1) {
+ if (dirsetup != 0)
+ pExaScr->info->DoneCopy(pDstPixmap);
+ dirsetup = 1;
+ if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
+ pDstPixmap,
+ 1, 1,
+ pGC ? pGC->alu : GXcopy,
+ pGC ? pGC->planemask :
+ FB_ALLONES))
+ return FALSE;
+ }
+ (*pExaScr->info->Copy)(pDstPixmap,
+ src_off_x + pbox->x1 + dx,
+ src_off_y + pbox->y1 + dy,
+ dst_off_x + pbox->x1,
+ dst_off_y + pbox->y1,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ } else if (dx >= 0) {
+ /*
+ * xdir = 1, ydir = -1.
+ * Perform line-by-line xdir = ydir = 1 blits, going up.
+ */
+ int i;
+ if (dirsetup != 1) {
+ if (dirsetup != 0)
+ pExaScr->info->DoneCopy(pDstPixmap);
+ dirsetup = 1;
+ if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
+ pDstPixmap,
+ 1, 1,
+ pGC ? pGC->alu : GXcopy,
+ pGC ? pGC->planemask :
+ FB_ALLONES))
+ return FALSE;
+ }
+ for (i = pbox->y2 - pbox->y1 - 1; i >= 0; i--)
+ (*pExaScr->info->Copy)(pDstPixmap,
+ src_off_x + pbox->x1 + dx,
+ src_off_y + pbox->y1 + dy + i,
+ dst_off_x + pbox->x1,
+ dst_off_y + pbox->y1 + i,
+ pbox->x2 - pbox->x1, 1);
+ } else {
+ /*
+ * xdir = -1, ydir = 1.
+ * Perform line-by-line xdir = ydir = -1 blits, going down.
+ */
+ int i;
+ if (dirsetup != -1) {
+ if (dirsetup != 0)
+ pExaScr->info->DoneCopy(pDstPixmap);
+ dirsetup = -1;
+ if (!(*pExaScr->info->PrepareCopy)(pSrcPixmap,
+ pDstPixmap,
+ -1, -1,
+ pGC ? pGC->alu : GXcopy,
+ pGC ? pGC->planemask :
+ FB_ALLONES))
+ return FALSE;
+ }
+ for (i = 0; i < pbox->y2 - pbox->y1; i++)
+ (*pExaScr->info->Copy)(pDstPixmap,
+ src_off_x + pbox->x1 + dx,
+ src_off_y + pbox->y1 + dy + i,
+ dst_off_x + pbox->x1,
+ dst_off_y + pbox->y1 + i,
+ pbox->x2 - pbox->x1, 1);
+ }
+ }
+ if (dirsetup != 0)
+ pExaScr->info->DoneCopy(pDstPixmap);
+ exaMarkSync(pDstDrawable->pScreen);
+ return TRUE;
+}
+
+Bool
+exaHWCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown)
+{
+ ExaScreenPriv (pDstDrawable->pScreen);
+ PixmapPtr pSrcPixmap, pDstPixmap;
+ ExaPixmapPrivPtr pSrcExaPixmap, pDstExaPixmap;
+ int src_off_x, src_off_y;
+ int dst_off_x, dst_off_y;
+ RegionPtr srcregion = NULL, dstregion = NULL;
+ xRectangle *rects;
+ Bool ret = TRUE;
+
+ /* avoid doing copy operations if no boxes */
+ if (nbox == 0)
+ return TRUE;
+
+ pSrcPixmap = exaGetDrawablePixmap (pSrcDrawable);
+ pDstPixmap = exaGetDrawablePixmap (pDstDrawable);
+
+ exaGetDrawableDeltas (pSrcDrawable, pSrcPixmap, &src_off_x, &src_off_y);
+ exaGetDrawableDeltas (pDstDrawable, pDstPixmap, &dst_off_x, &dst_off_y);
+
+ rects = xalloc(nbox * sizeof(xRectangle));
+
+ if (rects) {
+ int i;
+ int ordering;
+
+ for (i = 0; i < nbox; i++) {
+ rects[i].x = pbox[i].x1 + dx + src_off_x;
+ rects[i].y = pbox[i].y1 + dy + src_off_y;
+ rects[i].width = pbox[i].x2 - pbox[i].x1;
+ rects[i].height = pbox[i].y2 - pbox[i].y1;
+ }
+
+ /* This must match the miRegionCopy() logic for reversing rect order */
+ if (nbox == 1 || (dx > 0 && dy > 0) ||
+ (pDstDrawable != pSrcDrawable &&
+ (pDstDrawable->type != DRAWABLE_WINDOW ||
+ pSrcDrawable->type != DRAWABLE_WINDOW)))
+ ordering = CT_YXBANDED;
+ else
+ ordering = CT_UNSORTED;
+
+ srcregion = RECTS_TO_REGION(pScreen, nbox, rects, ordering);
+ xfree(rects);
+
+ if (!pGC || !exaGCReadsDestination(pDstDrawable, pGC->planemask,
+ pGC->fillStyle, pGC->alu,
+ pGC->clientClipType)) {
+ dstregion = REGION_CREATE(pScreen, NullBox, 0);
+ REGION_COPY(pScreen, dstregion, srcregion);
+ REGION_TRANSLATE(pScreen, dstregion, dst_off_x - dx - src_off_x,
+ dst_off_y - dy - src_off_y);
+ }
+ }
+
+
+ pSrcExaPixmap = ExaGetPixmapPriv (pSrcPixmap);
+ pDstExaPixmap = ExaGetPixmapPriv (pDstPixmap);
+
+ /* Check whether the accelerator can use this pixmap.
+ * If the pitch of the pixmaps is out of range, there's nothing
+ * we can do but fall back to software rendering.
+ */
+ if (pSrcExaPixmap->accel_blocked & EXA_RANGE_PITCH ||
+ pDstExaPixmap->accel_blocked & EXA_RANGE_PITCH)
+ goto fallback;
+
+ /* If the width or the height of either of the pixmaps
+ * is out of range, check whether the boxes are actually out of the
+ * addressable range as well. If they aren't, we can still do
+ * the copying in hardware.
+ */
+ if (pSrcExaPixmap->accel_blocked || pDstExaPixmap->accel_blocked) {
+ int i;
+
+ for (i = 0; i < nbox; i++) {
+ /* src */
+ if ((pbox[i].x2 + dx + src_off_x) >= pExaScr->info->maxX ||
+ (pbox[i].y2 + dy + src_off_y) >= pExaScr->info->maxY)
+ goto fallback;
+
+ /* dst */
+ if ((pbox[i].x2 + dst_off_x) >= pExaScr->info->maxX ||
+ (pbox[i].y2 + dst_off_y) >= pExaScr->info->maxY)
+ goto fallback;
+ }
+ }
+
+ if (pExaScr->do_migration) {
+ ExaMigrationRec pixmaps[2];
+
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = pDstPixmap;
+ pixmaps[0].pReg = dstregion;
+ pixmaps[1].as_dst = FALSE;
+ pixmaps[1].as_src = TRUE;
+ pixmaps[1].pPix = pSrcPixmap;
+ pixmaps[1].pReg = srcregion;
+
+ exaDoMigration (pixmaps, 2, TRUE);
+ }
+
+ /* Mixed directions must be handled specially if the card is lame */
+ if ((pExaScr->info->flags & EXA_TWO_BITBLT_DIRECTIONS) &&
+ reverse != upsidedown) {
+ if (exaCopyNtoNTwoDir(pSrcDrawable, pDstDrawable, pGC, pbox, nbox,
+ dx, dy))
+ goto out;
+ goto fallback;
+ }
+
+ if (exaPixmapHasGpuCopy(pDstPixmap)) {
+ /* Normal blitting. */
+ if (exaPixmapHasGpuCopy(pSrcPixmap)) {
+ if (!(*pExaScr->info->PrepareCopy) (pSrcPixmap, pDstPixmap, reverse ? -1 : 1,
+ upsidedown ? -1 : 1,
+ pGC ? pGC->alu : GXcopy,
+ pGC ? pGC->planemask : FB_ALLONES)) {
+ goto fallback;
+ }
+
+ while (nbox--)
+ {
+ (*pExaScr->info->Copy) (pDstPixmap,
+ pbox->x1 + dx + src_off_x,
+ pbox->y1 + dy + src_off_y,
+ pbox->x1 + dst_off_x, pbox->y1 + dst_off_y,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1);
+ pbox++;
+ }
+
+ (*pExaScr->info->DoneCopy) (pDstPixmap);
+ exaMarkSync (pDstDrawable->pScreen);
+ /* UTS: mainly for SHM PutImage's secondary path.
+ *
+ * Only taking this path for directly accessible pixmaps.
+ */
+ } else if (!pDstExaPixmap->pDamage) {
+ int bpp = pSrcDrawable->bitsPerPixel;
+ int src_stride = exaGetPixmapPitch(pSrcPixmap);
+ CARD8 *src = NULL;
+
+ if (!pExaScr->info->UploadToScreen)
+ goto fallback;
+
+ if (pSrcDrawable->bitsPerPixel != pDstDrawable->bitsPerPixel)
+ goto fallback;
+
+ if (pSrcDrawable->bitsPerPixel < 8)
+ goto fallback;
+
+ if (pGC && !(pGC->alu == GXcopy && EXA_PM_IS_SOLID(pSrcDrawable, pGC->planemask)))
+ goto fallback;
+
+ while (nbox--)
+ {
+ src = pSrcExaPixmap->sys_ptr + (pbox->y1 + dy + src_off_y) * src_stride + (pbox->x1 + dx + src_off_x) * (bpp / 8);
+ if (!pExaScr->info->UploadToScreen(pDstPixmap, pbox->x1 + dst_off_x,
+ pbox->y1 + dst_off_y, pbox->x2 - pbox->x1, pbox->y2 - pbox->y1,
+ (char *) src, src_stride))
+ goto fallback;
+
+ pbox++;
+ }
+ } else
+ goto fallback;
+ } else
+ goto fallback;
+
+ goto out;
+
+fallback:
+ ret = FALSE;
+
+out:
+ if (dstregion) {
+ REGION_UNINIT(pScreen, dstregion);
+ REGION_DESTROY(pScreen, dstregion);
+ }
+ if (srcregion) {
+ REGION_UNINIT(pScreen, srcregion);
+ REGION_DESTROY(pScreen, srcregion);
+ }
+
+ return ret;
+}
+
+void
+exaCopyNtoN (DrawablePtr pSrcDrawable,
+ DrawablePtr pDstDrawable,
+ GCPtr pGC,
+ BoxPtr pbox,
+ int nbox,
+ int dx,
+ int dy,
+ Bool reverse,
+ Bool upsidedown,
+ Pixel bitplane,
+ void *closure)
+{
+ ExaScreenPriv(pDstDrawable->pScreen);
+
+ if (pExaScr->fallback_counter ||
+ (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW))
+ return;
+
+ if (exaHWCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown))
+ return;
+
+ /* This is a CopyWindow, it's cleaner to fallback at the original call. */
+ if (pExaScr->fallback_flags & EXA_ACCEL_COPYWINDOW) {
+ pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW;
+ return;
+ }
+
+ /* fallback */
+ ExaCheckCopyNtoN(pSrcDrawable, pDstDrawable, pGC, pbox, nbox, dx, dy, reverse, upsidedown, bitplane, closure);
+}
+
+RegionPtr
+exaCopyArea(DrawablePtr pSrcDrawable, DrawablePtr pDstDrawable, GCPtr pGC,
+ int srcx, int srcy, int width, int height, int dstx, int dsty)
+{
+ ExaScreenPriv (pDstDrawable->pScreen);
+
+ if (pExaScr->fallback_counter || pExaScr->swappedOut) {
+ return ExaCheckCopyArea(pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height, dstx, dsty);
+ }
+
+ return miDoCopy (pSrcDrawable, pDstDrawable, pGC,
+ srcx, srcy, width, height,
+ dstx, dsty, exaCopyNtoN, 0, NULL);
+}
+
+static void
+exaPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ DDXPointPtr ppt)
+{
+ ExaScreenPriv (pDrawable->pScreen);
+ int i;
+ xRectangle *prect;
+
+ /* If we can't reuse the current GC as is, don't bother accelerating the
+ * points.
+ */
+ if (pExaScr->fallback_counter || pGC->fillStyle != FillSolid) {
+ ExaCheckPolyPoint(pDrawable, pGC, mode, npt, ppt);
+ return;
+ }
+
+ prect = xalloc(sizeof(xRectangle) * npt);
+ for (i = 0; i < npt; i++) {
+ prect[i].x = ppt[i].x;
+ prect[i].y = ppt[i].y;
+ if (i > 0 && mode == CoordModePrevious) {
+ prect[i].x += prect[i - 1].x;
+ prect[i].y += prect[i - 1].y;
+ }
+ prect[i].width = 1;
+ prect[i].height = 1;
+ }
+ pGC->ops->PolyFillRect(pDrawable, pGC, npt, prect);
+ xfree(prect);
+}
+
+/**
+ * exaPolylines() checks if it can accelerate the lines as a group of
+ * horizontal or vertical lines (rectangles), and uses existing rectangle fill
+ * acceleration if so.
+ */
+static void
+exaPolylines(DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ DDXPointPtr ppt)
+{
+ ExaScreenPriv (pDrawable->pScreen);
+ xRectangle *prect;
+ int x1, x2, y1, y2;
+ int i;
+
+ if (pExaScr->fallback_counter) {
+ ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
+ return;
+ }
+
+ /* Don't try to do wide lines or non-solid fill style. */
+ if (pGC->lineWidth != 0 || pGC->lineStyle != LineSolid ||
+ pGC->fillStyle != FillSolid) {
+ ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
+ return;
+ }
+
+ prect = xalloc(sizeof(xRectangle) * (npt - 1));
+ x1 = ppt[0].x;
+ y1 = ppt[0].y;
+ /* If we have any non-horizontal/vertical, fall back. */
+ for (i = 0; i < npt - 1; i++) {
+ if (mode == CoordModePrevious) {
+ x2 = x1 + ppt[i + 1].x;
+ y2 = y1 + ppt[i + 1].y;
+ } else {
+ x2 = ppt[i + 1].x;
+ y2 = ppt[i + 1].y;
+ }
+
+ if (x1 != x2 && y1 != y2) {
+ xfree(prect);
+ ExaCheckPolylines(pDrawable, pGC, mode, npt, ppt);
+ return;
+ }
+
+ if (x1 < x2) {
+ prect[i].x = x1;
+ prect[i].width = x2 - x1 + 1;
+ } else {
+ prect[i].x = x2;
+ prect[i].width = x1 - x2 + 1;
+ }
+ if (y1 < y2) {
+ prect[i].y = y1;
+ prect[i].height = y2 - y1 + 1;
+ } else {
+ prect[i].y = y2;
+ prect[i].height = y1 - y2 + 1;
+ }
+
+ x1 = x2;
+ y1 = y2;
+ }
+ pGC->ops->PolyFillRect(pDrawable, pGC, npt - 1, prect);
+ xfree(prect);
+}
+
+/**
+ * exaPolySegment() checks if it can accelerate the lines as a group of
+ * horizontal or vertical lines (rectangles), and uses existing rectangle fill
+ * acceleration if so.
+ */
+static void
+exaPolySegment (DrawablePtr pDrawable, GCPtr pGC, int nseg,
+ xSegment *pSeg)
+{
+ ExaScreenPriv (pDrawable->pScreen);
+ xRectangle *prect;
+ int i;
+
+ /* Don't try to do wide lines or non-solid fill style. */
+ if (pExaScr->fallback_counter || pGC->lineWidth != 0 ||
+ pGC->lineStyle != LineSolid || pGC->fillStyle != FillSolid)
+ {
+ ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
+ return;
+ }
+
+ /* If we have any non-horizontal/vertical, fall back. */
+ for (i = 0; i < nseg; i++) {
+ if (pSeg[i].x1 != pSeg[i].x2 && pSeg[i].y1 != pSeg[i].y2) {
+ ExaCheckPolySegment(pDrawable, pGC, nseg, pSeg);
+ return;
+ }
+ }
+
+ prect = xalloc(sizeof(xRectangle) * nseg);
+ for (i = 0; i < nseg; i++) {
+ if (pSeg[i].x1 < pSeg[i].x2) {
+ prect[i].x = pSeg[i].x1;
+ prect[i].width = pSeg[i].x2 - pSeg[i].x1 + 1;
+ } else {
+ prect[i].x = pSeg[i].x2;
+ prect[i].width = pSeg[i].x1 - pSeg[i].x2 + 1;
+ }
+ if (pSeg[i].y1 < pSeg[i].y2) {
+ prect[i].y = pSeg[i].y1;
+ prect[i].height = pSeg[i].y2 - pSeg[i].y1 + 1;
+ } else {
+ prect[i].y = pSeg[i].y2;
+ prect[i].height = pSeg[i].y1 - pSeg[i].y2 + 1;
+ }
+
+ /* don't paint last pixel */
+ if (pGC->capStyle == CapNotLast) {
+ if (prect[i].width == 1)
+ prect[i].height--;
+ else
+ prect[i].width--;
+ }
+ }
+ pGC->ops->PolyFillRect(pDrawable, pGC, nseg, prect);
+ xfree(prect);
+}
+
+static Bool exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion,
+ Pixel pixel, CARD32 planemask, CARD32 alu,
+ unsigned int clientClipType);
+
+static void
+exaPolyFillRect(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nrect,
+ xRectangle *prect)
+{
+ ExaScreenPriv (pDrawable->pScreen);
+ RegionPtr pClip = fbGetCompositeClip(pGC);
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+ ExaPixmapPriv (pPixmap);
+ register BoxPtr pbox;
+ BoxPtr pextent;
+ int extentX1, extentX2, extentY1, extentY2;
+ int fullX1, fullX2, fullY1, fullY2;
+ int partX1, partX2, partY1, partY2;
+ int xoff, yoff;
+ int xorg, yorg;
+ int n;
+ RegionPtr pReg = RECTS_TO_REGION(pScreen, nrect, prect, CT_UNSORTED);
+
+ /* Compute intersection of rects and clip region */
+ REGION_TRANSLATE(pScreen, pReg, pDrawable->x, pDrawable->y);
+ REGION_INTERSECT(pScreen, pReg, pClip, pReg);
+
+ if (!REGION_NUM_RECTS(pReg)) {
+ goto out;
+ }
+
+ exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+
+ if (pExaScr->fallback_counter || pExaScr->swappedOut ||
+ pExaPixmap->accel_blocked)
+ {
+ goto fallback;
+ }
+
+ /* For ROPs where overlaps don't matter, convert rectangles to region and
+ * call exaFillRegion{Solid,Tiled}.
+ */
+ if ((pGC->fillStyle == FillSolid || pGC->fillStyle == FillTiled) &&
+ (nrect == 1 || pGC->alu == GXcopy || pGC->alu == GXclear ||
+ pGC->alu == GXnoop || pGC->alu == GXcopyInverted ||
+ pGC->alu == GXset)) {
+ if (((pGC->fillStyle == FillSolid || pGC->tileIsPixel) &&
+ exaFillRegionSolid(pDrawable, pReg, pGC->fillStyle == FillSolid ?
+ pGC->fgPixel : pGC->tile.pixel, pGC->planemask,
+ pGC->alu, pGC->clientClipType)) ||
+ (pGC->fillStyle == FillTiled && !pGC->tileIsPixel &&
+ exaFillRegionTiled(pDrawable, pReg, pGC->tile.pixmap, &pGC->patOrg,
+ pGC->planemask, pGC->alu,
+ pGC->clientClipType))) {
+ goto out;
+ }
+ }
+
+ if (pGC->fillStyle != FillSolid &&
+ !(pGC->tileIsPixel && pGC->fillStyle == FillTiled))
+ {
+ goto fallback;
+ }
+
+ if (pExaScr->do_migration) {
+ ExaMigrationRec pixmaps[1];
+
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = pPixmap;
+ pixmaps[0].pReg = NULL;
+
+ exaDoMigration (pixmaps, 1, TRUE);
+ }
+
+ if (!exaPixmapHasGpuCopy (pPixmap) ||
+ !(*pExaScr->info->PrepareSolid) (pPixmap,
+ pGC->alu,
+ pGC->planemask,
+ pGC->fgPixel))
+ {
+fallback:
+ ExaCheckPolyFillRect (pDrawable, pGC, nrect, prect);
+ goto out;
+ }
+
+ xorg = pDrawable->x;
+ yorg = pDrawable->y;
+
+ pextent = REGION_EXTENTS(pGC->pScreen, pClip);
+ extentX1 = pextent->x1;
+ extentY1 = pextent->y1;
+ extentX2 = pextent->x2;
+ extentY2 = pextent->y2;
+ while (nrect--)
+ {
+ fullX1 = prect->x + xorg;
+ fullY1 = prect->y + yorg;
+ fullX2 = fullX1 + (int) prect->width;
+ fullY2 = fullY1 + (int) prect->height;
+ prect++;
+
+ if (fullX1 < extentX1)
+ fullX1 = extentX1;
+
+ if (fullY1 < extentY1)
+ fullY1 = extentY1;
+
+ if (fullX2 > extentX2)
+ fullX2 = extentX2;
+
+ if (fullY2 > extentY2)
+ fullY2 = extentY2;
+
+ if ((fullX1 >= fullX2) || (fullY1 >= fullY2))
+ continue;
+ n = REGION_NUM_RECTS (pClip);
+ if (n == 1)
+ {
+ (*pExaScr->info->Solid) (pPixmap,
+ fullX1 + xoff, fullY1 + yoff,
+ fullX2 + xoff, fullY2 + yoff);
+ }
+ else
+ {
+ pbox = REGION_RECTS(pClip);
+ /*
+ * clip the rectangle to each box in the clip region
+ * this is logically equivalent to calling Intersect(),
+ * but rectangles may overlap each other here.
+ */
+ while(n--)
+ {
+ partX1 = pbox->x1;
+ if (partX1 < fullX1)
+ partX1 = fullX1;
+ partY1 = pbox->y1;
+ if (partY1 < fullY1)
+ partY1 = fullY1;
+ partX2 = pbox->x2;
+ if (partX2 > fullX2)
+ partX2 = fullX2;
+ partY2 = pbox->y2;
+ if (partY2 > fullY2)
+ partY2 = fullY2;
+
+ pbox++;
+
+ if (partX1 < partX2 && partY1 < partY2) {
+ (*pExaScr->info->Solid) (pPixmap,
+ partX1 + xoff, partY1 + yoff,
+ partX2 + xoff, partY2 + yoff);
+ }
+ }
+ }
+ }
+ (*pExaScr->info->DoneSolid) (pPixmap);
+ exaMarkSync(pDrawable->pScreen);
+
+out:
+ REGION_UNINIT(pScreen, pReg);
+ REGION_DESTROY(pScreen, pReg);
+}
+
+const GCOps exaOps = {
+ exaFillSpans,
+ ExaCheckSetSpans,
+ exaPutImage,
+ exaCopyArea,
+ ExaCheckCopyPlane,
+ exaPolyPoint,
+ exaPolylines,
+ exaPolySegment,
+ miPolyRectangle,
+ ExaCheckPolyArc,
+ miFillPolygon,
+ exaPolyFillRect,
+ miPolyFillArc,
+ miPolyText8,
+ miPolyText16,
+ miImageText8,
+ miImageText16,
+ ExaCheckImageGlyphBlt,
+ ExaCheckPolyGlyphBlt,
+ ExaCheckPushPixels,
+};
+
+void
+exaCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ RegionRec rgnDst;
+ int dx, dy;
+ PixmapPtr pPixmap = (*pWin->drawable.pScreen->GetWindowPixmap) (pWin);
+ ExaScreenPriv(pWin->drawable.pScreen);
+
+ dx = ptOldOrg.x - pWin->drawable.x;
+ dy = ptOldOrg.y - pWin->drawable.y;
+ REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, -dx, -dy);
+
+ REGION_INIT (pWin->drawable.pScreen, &rgnDst, NullBox, 0);
+
+ REGION_INTERSECT(pWin->drawable.pScreen, &rgnDst, &pWin->borderClip, prgnSrc);
+#ifdef COMPOSITE
+ if (pPixmap->screen_x || pPixmap->screen_y)
+ REGION_TRANSLATE (pWin->drawable.pScreen, &rgnDst,
+ -pPixmap->screen_x, -pPixmap->screen_y);
+#endif
+
+ if (pExaScr->fallback_counter) {
+ pExaScr->fallback_flags |= EXA_FALLBACK_COPYWINDOW;
+ goto fallback;
+ }
+
+ pExaScr->fallback_flags |= EXA_ACCEL_COPYWINDOW;
+ miCopyRegion (&pPixmap->drawable, &pPixmap->drawable,
+ NULL,
+ &rgnDst, dx, dy, exaCopyNtoN, 0, NULL);
+ pExaScr->fallback_flags &= ~EXA_ACCEL_COPYWINDOW;
+
+fallback:
+ REGION_UNINIT(pWin->drawable.pScreen, &rgnDst);
+
+ if (pExaScr->fallback_flags & EXA_FALLBACK_COPYWINDOW) {
+ pExaScr->fallback_flags &= ~EXA_FALLBACK_COPYWINDOW;
+ REGION_TRANSLATE(pWin->drawable.pScreen, prgnSrc, dx, dy);
+ ExaCheckCopyWindow(pWin, ptOldOrg, prgnSrc);
+ }
+}
+
+static Bool
+exaFillRegionSolid (DrawablePtr pDrawable, RegionPtr pRegion, Pixel pixel,
+ CARD32 planemask, CARD32 alu, unsigned int clientClipType)
+{
+ ExaScreenPriv(pDrawable->pScreen);
+ PixmapPtr pPixmap = exaGetDrawablePixmap (pDrawable);
+ ExaPixmapPriv (pPixmap);
+ int xoff, yoff;
+ Bool ret = FALSE;
+
+ exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+ REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
+
+ if (pExaScr->fallback_counter || pExaPixmap->accel_blocked)
+ goto out;
+
+ if (pExaScr->do_migration) {
+ ExaMigrationRec pixmaps[1];
+
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = pPixmap;
+ pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillSolid,
+ alu, clientClipType) ? NULL : pRegion;
+
+ exaDoMigration (pixmaps, 1, TRUE);
+ }
+
+ if (exaPixmapHasGpuCopy (pPixmap) &&
+ (*pExaScr->info->PrepareSolid) (pPixmap, alu, planemask, pixel))
+ {
+ int nbox;
+ BoxPtr pBox;
+
+ nbox = REGION_NUM_RECTS (pRegion);
+ pBox = REGION_RECTS (pRegion);
+
+ while (nbox--)
+ {
+ (*pExaScr->info->Solid) (pPixmap, pBox->x1, pBox->y1, pBox->x2,
+ pBox->y2);
+ pBox++;
+ }
+ (*pExaScr->info->DoneSolid) (pPixmap);
+ exaMarkSync(pDrawable->pScreen);
+
+ if (pExaPixmap->pDamage &&
+ pExaPixmap->sys_ptr && pDrawable->type == DRAWABLE_PIXMAP &&
+ pDrawable->width == 1 && pDrawable->height == 1 &&
+ pDrawable->bitsPerPixel != 24) {
+ ExaPixmapPriv(pPixmap);
+ RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
+
+ switch (pDrawable->bitsPerPixel) {
+ case 32:
+ *(CARD32*)pExaPixmap->sys_ptr = pixel;
+ break;
+ case 16:
+ *(CARD16*)pExaPixmap->sys_ptr = pixel;
+ break;
+ case 8:
+ *(CARD8*)pExaPixmap->sys_ptr = pixel;
+ }
+
+ REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
+ pRegion);
+ REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
+ pRegion);
+ REGION_SUBTRACT(pScreen, pending_damage, pending_damage, pRegion);
+ }
+
+ ret = TRUE;
+ }
+
+out:
+ REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
+
+ return ret;
+}
+
+/* Try to do an accelerated tile of the pTile into pRegion of pDrawable.
+ * Based on fbFillRegionTiled(), fbTile().
+ */
+Bool
+exaFillRegionTiled (DrawablePtr pDrawable, RegionPtr pRegion, PixmapPtr pTile,
+ DDXPointPtr pPatOrg, CARD32 planemask, CARD32 alu,
+ unsigned int clientClipType)
+{
+ ExaScreenPriv(pDrawable->pScreen);
+ PixmapPtr pPixmap;
+ ExaPixmapPrivPtr pExaPixmap;
+ ExaPixmapPrivPtr pTileExaPixmap = ExaGetPixmapPriv(pTile);
+ int xoff, yoff;
+ int tileWidth, tileHeight;
+ int nbox = REGION_NUM_RECTS (pRegion);
+ BoxPtr pBox = REGION_RECTS (pRegion);
+ Bool ret = FALSE;
+ int i;
+
+ tileWidth = pTile->drawable.width;
+ tileHeight = pTile->drawable.height;
+
+ /* If we're filling with a solid color, grab it out and go to
+ * FillRegionSolid, saving numerous copies.
+ */
+ if (tileWidth == 1 && tileHeight == 1)
+ return exaFillRegionSolid(pDrawable, pRegion,
+ exaGetPixmapFirstPixel (pTile), planemask,
+ alu, clientClipType);
+
+ pPixmap = exaGetDrawablePixmap (pDrawable);
+ pExaPixmap = ExaGetPixmapPriv (pPixmap);
+
+ if (pExaScr->fallback_counter || pExaPixmap->accel_blocked ||
+ pTileExaPixmap->accel_blocked)
+ return FALSE;
+
+ if (pExaScr->do_migration) {
+ ExaMigrationRec pixmaps[2];
+
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ pixmaps[0].pPix = pPixmap;
+ pixmaps[0].pReg = exaGCReadsDestination(pDrawable, planemask, FillTiled,
+ alu, clientClipType) ? NULL : pRegion;
+ pixmaps[1].as_dst = FALSE;
+ pixmaps[1].as_src = TRUE;
+ pixmaps[1].pPix = pTile;
+ pixmaps[1].pReg = NULL;
+
+ exaDoMigration (pixmaps, 2, TRUE);
+ }
+
+ pPixmap = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
+
+ if (!pPixmap || !exaPixmapHasGpuCopy(pTile))
+ return FALSE;
+
+ if ((*pExaScr->info->PrepareCopy) (pTile, pPixmap, 1, 1, alu, planemask))
+ {
+ if (xoff || yoff)
+ REGION_TRANSLATE(pScreen, pRegion, xoff, yoff);
+
+ for (i = 0; i < nbox; i++)
+ {
+ int height = pBox[i].y2 - pBox[i].y1;
+ int dstY = pBox[i].y1;
+ int tileY;
+
+ if (alu == GXcopy)
+ height = min(height, tileHeight);
+
+ modulus(dstY - yoff - pDrawable->y - pPatOrg->y, tileHeight, tileY);
+
+ while (height > 0) {
+ int width = pBox[i].x2 - pBox[i].x1;
+ int dstX = pBox[i].x1;
+ int tileX;
+ int h = tileHeight - tileY;
+
+ if (alu == GXcopy)
+ width = min(width, tileWidth);
+
+ if (h > height)
+ h = height;
+ height -= h;
+
+ modulus(dstX - xoff - pDrawable->x - pPatOrg->x, tileWidth,
+ tileX);
+
+ while (width > 0) {
+ int w = tileWidth - tileX;
+ if (w > width)
+ w = width;
+ width -= w;
+
+ (*pExaScr->info->Copy) (pPixmap, tileX, tileY, dstX, dstY,
+ w, h);
+ dstX += w;
+ tileX = 0;
+ }
+ dstY += h;
+ tileY = 0;
+ }
+ }
+ (*pExaScr->info->DoneCopy) (pPixmap);
+
+ /* With GXcopy, we only need to do the basic algorithm up to the tile
+ * size; then, we can just keep doubling the destination in each
+ * direction until it fills the box. This way, the number of copy
+ * operations is O(log(rx)) + O(log(ry)) instead of O(rx * ry), where
+ * rx/ry is the ratio between box and tile width/height. This can make
+ * a big difference if each driver copy incurs a significant constant
+ * overhead.
+ */
+ if (alu != GXcopy)
+ ret = TRUE;
+ else {
+ Bool more_copy = FALSE;
+
+ for (i = 0; i < nbox; i++) {
+ int dstX = pBox[i].x1 + tileWidth;
+ int dstY = pBox[i].y1 + tileHeight;
+
+ if ((dstX < pBox[i].x2) || (dstY < pBox[i].y2)) {
+ more_copy = TRUE;
+ break;
+ }
+ }
+
+ if (more_copy == FALSE)
+ ret = TRUE;
+
+ if (more_copy && (*pExaScr->info->PrepareCopy) (pPixmap, pPixmap,
+ 1, 1, alu, planemask)) {
+ for (i = 0; i < nbox; i++)
+ {
+ int dstX = pBox[i].x1 + tileWidth;
+ int dstY = pBox[i].y1 + tileHeight;
+ int width = min(pBox[i].x2 - dstX, tileWidth);
+ int height = min(pBox[i].y2 - pBox[i].y1, tileHeight);
+
+ while (dstX < pBox[i].x2) {
+ (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1,
+ dstX, pBox[i].y1, width, height);
+ dstX += width;
+ width = min(pBox[i].x2 - dstX, width * 2);
+ }
+
+ width = pBox[i].x2 - pBox[i].x1;
+ height = min(pBox[i].y2 - dstY, tileHeight);
+
+ while (dstY < pBox[i].y2) {
+ (*pExaScr->info->Copy) (pPixmap, pBox[i].x1, pBox[i].y1,
+ pBox[i].x1, dstY, width, height);
+ dstY += height;
+ height = min(pBox[i].y2 - dstY, height * 2);
+ }
+ }
+
+ (*pExaScr->info->DoneCopy) (pPixmap);
+
+ ret = TRUE;
+ }
+ }
+
+ exaMarkSync(pDrawable->pScreen);
+
+ if (xoff || yoff)
+ REGION_TRANSLATE(pScreen, pRegion, -xoff, -yoff);
+ }
+
+ return ret;
+}
+
+
+/**
+ * Accelerates GetImage for solid ZPixmap downloads from framebuffer memory.
+ *
+ * This is probably the only case we actually care about. The rest fall through
+ * to migration and fbGetImage, which hopefully will result in migration pushing
+ * the pixmap out of framebuffer.
+ */
+void
+exaGetImage (DrawablePtr pDrawable, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *d)
+{
+ ExaScreenPriv (pDrawable->pScreen);
+ PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
+ ExaPixmapPriv(pPix);
+ int xoff, yoff;
+ Bool ok;
+
+ if (pExaScr->fallback_counter || pExaScr->swappedOut)
+ goto fallback;
+
+ /* If there's a system copy, we want to save the result there */
+ if (pExaPixmap->pDamage)
+ goto fallback;
+
+ pPix = exaGetOffscreenPixmap (pDrawable, &xoff, &yoff);
+
+ if (pPix == NULL || pExaScr->info->DownloadFromScreen == NULL)
+ goto fallback;
+
+ /* Only cover the ZPixmap, solid copy case. */
+ if (format != ZPixmap || !EXA_PM_IS_SOLID(pDrawable, planeMask))
+ goto fallback;
+
+ /* Only try to handle the 8bpp and up cases, since we don't want to think
+ * about <8bpp.
+ */
+ if (pDrawable->bitsPerPixel < 8)
+ goto fallback;
+
+ ok = pExaScr->info->DownloadFromScreen(pPix, pDrawable->x + x + xoff,
+ pDrawable->y + y + yoff, w, h, d,
+ PixmapBytePad(w, pDrawable->depth));
+ if (ok) {
+ exaWaitSync(pDrawable->pScreen);
+ return;
+ }
+
+fallback:
+ ExaCheckGetImage(pDrawable, x, y, w, h, format, planeMask, d);
+}
diff --git a/xorg-server/exa/exa_migration_classic.c b/xorg-server/exa/exa_migration_classic.c index 871679ffc..9e1626c69 100644 --- a/xorg-server/exa/exa_migration_classic.c +++ b/xorg-server/exa/exa_migration_classic.c @@ -1,745 +1,745 @@ -/* - * Copyright © 2006 Intel Corporation - * - * 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. - * - * Authors: - * Eric Anholt <eric@anholt.net> - * Michel Dänzer <michel@tungstengraphics.com> - * - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <string.h> - -#include "exa_priv.h" -#include "exa.h" - -#if DEBUG_MIGRATE -#define DBG_MIGRATE(a) ErrorF a -#else -#define DBG_MIGRATE(a) -#endif - -/** - * The fallback path for UTS/DFS failing is to just memcpy. exaCopyDirtyToSys - * and exaCopyDirtyToFb both needed to do this loop. - */ -static void -exaMemcpyBox (PixmapPtr pPixmap, BoxPtr pbox, CARD8 *src, int src_pitch, - CARD8 *dst, int dst_pitch) - { - int i, cpp = pPixmap->drawable.bitsPerPixel / 8; - int bytes = (pbox->x2 - pbox->x1) * cpp; - - src += pbox->y1 * src_pitch + pbox->x1 * cpp; - dst += pbox->y1 * dst_pitch + pbox->x1 * cpp; - - for (i = pbox->y2 - pbox->y1; i; i--) { - memcpy (dst, src, bytes); - src += src_pitch; - dst += dst_pitch; - } -} - -/** - * Returns TRUE if the pixmap is dirty (has been modified in its current - * location compared to the other), or lacks a private for tracking - * dirtiness. - */ -static Bool -exaPixmapIsDirty (PixmapPtr pPix) -{ - ExaPixmapPriv (pPix); - - if (pExaPixmap == NULL) - EXA_FatalErrorDebugWithRet(("EXA bug: exaPixmapIsDirty was called on a non-exa pixmap.\n"), TRUE); - - if (!pExaPixmap->pDamage) - return FALSE; - - return REGION_NOTEMPTY (pScreen, DamageRegion(pExaPixmap->pDamage)) || - !REGION_EQUAL(pScreen, &pExaPixmap->validSys, &pExaPixmap->validFB); -} - -/** - * Returns TRUE if the pixmap is either pinned in FB, or has a sufficient score - * to be considered "should be in framebuffer". That's just anything that has - * had more acceleration than fallbacks, or has no score yet. - * - * Only valid if using a migration scheme that tracks score. - */ -static Bool -exaPixmapShouldBeInFB (PixmapPtr pPix) -{ - ExaPixmapPriv (pPix); - - if (exaPixmapIsPinned (pPix)) - return TRUE; - - return pExaPixmap->score >= 0; -} - -/** - * If the pixmap is currently dirty, this copies at least the dirty area from - * FB to system or vice versa. Both areas must be allocated. - */ -static void -exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc, - Bool (*transfer) (PixmapPtr pPix, int x, int y, int w, int h, - char *sys, int sys_pitch), int fallback_index, - void (*sync) (ScreenPtr pScreen)) -{ - PixmapPtr pPixmap = migrate->pPix; - ExaPixmapPriv (pPixmap); - RegionPtr damage = DamageRegion (pExaPixmap->pDamage); - RegionRec CopyReg; - Bool save_use_gpu_copy; - int save_pitch; - BoxPtr pBox; - int nbox; - Bool access_prepared = FALSE; - Bool need_sync = FALSE; - - /* Damaged bits are valid in current copy but invalid in other one */ - if (pExaPixmap->use_gpu_copy) { - REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB, - damage); - REGION_SUBTRACT(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys, - damage); - } else { - REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys, - damage); - REGION_SUBTRACT(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB, - damage); - } - - REGION_EMPTY(pScreen, damage); - - /* Copy bits valid in source but not in destination */ - REGION_NULL(pScreen, &CopyReg); - REGION_SUBTRACT(pScreen, &CopyReg, pValidSrc, pValidDst); - - if (migrate->as_dst) { - ExaScreenPriv (pPixmap->drawable.pScreen); - - /* XXX: The pending damage region will be marked as damaged after the - * operation, so it should serve as an upper bound for the region that - * needs to be synchronized for the operation. Unfortunately, this - * causes corruption in some cases, e.g. when starting compiz. See - * https://bugs.freedesktop.org/show_bug.cgi?id=12916 . - */ - if (pExaScr->optimize_migration) { - RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage); - -#if DEBUG_MIGRATE - if (REGION_NIL(pending_damage)) { - static Bool firsttime = TRUE; - - if (firsttime) { - ErrorF("%s: Pending damage region empty!\n", __func__); - firsttime = FALSE; - } - } -#endif - - /* Try to prevent destination valid region from growing too many - * rects by filling it up to the extents of the union of the - * destination valid region and the pending damage region. - */ - if (REGION_NUM_RECTS(pValidDst) > 10) { - BoxRec box; - BoxPtr pValidExt, pDamageExt; - RegionRec closure; - - pValidExt = REGION_EXTENTS(pScreen, pValidDst); - pDamageExt = REGION_EXTENTS(pScreen, pending_damage); - - box.x1 = min(pValidExt->x1, pDamageExt->x1); - box.y1 = min(pValidExt->y1, pDamageExt->y1); - box.x2 = max(pValidExt->x2, pDamageExt->x2); - box.y2 = max(pValidExt->y2, pDamageExt->y2); - - REGION_INIT(pScreen, &closure, &box, 0); - REGION_INTERSECT(pScreen, &CopyReg, &CopyReg, &closure); - } else - REGION_INTERSECT(pScreen, &CopyReg, &CopyReg, pending_damage); - } - - /* The caller may provide a region to be subtracted from the calculated - * dirty region. This is to avoid migration of bits that don't - * contribute to the result of the operation. - */ - if (migrate->pReg) - REGION_SUBTRACT(pScreen, &CopyReg, &CopyReg, migrate->pReg); - } else { - /* The caller may restrict the region to be migrated for source pixmaps - * to what's relevant for the operation. - */ - if (migrate->pReg) - REGION_INTERSECT(pScreen, &CopyReg, &CopyReg, migrate->pReg); - } - - pBox = REGION_RECTS(&CopyReg); - nbox = REGION_NUM_RECTS(&CopyReg); - - save_use_gpu_copy = pExaPixmap->use_gpu_copy; - save_pitch = pPixmap->devKind; - pExaPixmap->use_gpu_copy = TRUE; - pPixmap->devKind = pExaPixmap->fb_pitch; - - while (nbox--) { - pBox->x1 = max(pBox->x1, 0); - pBox->y1 = max(pBox->y1, 0); - pBox->x2 = min(pBox->x2, pPixmap->drawable.width); - pBox->y2 = min(pBox->y2, pPixmap->drawable.height); - - if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2) - continue; - - if (!transfer || !transfer (pPixmap, - pBox->x1, pBox->y1, - pBox->x2 - pBox->x1, - pBox->y2 - pBox->y1, - (char *) (pExaPixmap->sys_ptr - + pBox->y1 * pExaPixmap->sys_pitch - + pBox->x1 * pPixmap->drawable.bitsPerPixel / 8), - pExaPixmap->sys_pitch)) - { - if (!access_prepared) { - ExaDoPrepareAccess(pPixmap, fallback_index); - access_prepared = TRUE; - } - if (fallback_index == EXA_PREPARE_DEST) { - exaMemcpyBox (pPixmap, pBox, - pExaPixmap->sys_ptr, pExaPixmap->sys_pitch, - pPixmap->devPrivate.ptr, pPixmap->devKind); - } else { - exaMemcpyBox (pPixmap, pBox, - pPixmap->devPrivate.ptr, pPixmap->devKind, - pExaPixmap->sys_ptr, pExaPixmap->sys_pitch); - } - } else - need_sync = TRUE; - - pBox++; - } - - pExaPixmap->use_gpu_copy = save_use_gpu_copy; - pPixmap->devKind = save_pitch; - - /* Try to prevent source valid region from growing too many rects by - * removing parts of it which are also in the destination valid region. - * Removing anything beyond that would lead to data loss. - */ - if (REGION_NUM_RECTS(pValidSrc) > 20) - REGION_SUBTRACT(pScreen, pValidSrc, pValidSrc, pValidDst); - - /* The copied bits are now valid in destination */ - REGION_UNION(pScreen, pValidDst, pValidDst, &CopyReg); - - REGION_UNINIT(pScreen, &CopyReg); - - if (access_prepared) - exaFinishAccess(&pPixmap->drawable, fallback_index); - else if (need_sync && sync) - sync (pPixmap->drawable.pScreen); -} - -/** - * If the pixmap is currently dirty, this copies at least the dirty area from - * the framebuffer memory copy to the system memory copy. Both areas must be - * allocated. - */ -void -exaCopyDirtyToSys (ExaMigrationPtr migrate) -{ - PixmapPtr pPixmap = migrate->pPix; - ExaScreenPriv (pPixmap->drawable.pScreen); - ExaPixmapPriv (pPixmap); - - exaCopyDirty(migrate, &pExaPixmap->validSys, &pExaPixmap->validFB, - pExaScr->info->DownloadFromScreen, EXA_PREPARE_SRC, - exaWaitSync); -} - -/** - * If the pixmap is currently dirty, this copies at least the dirty area from - * the system memory copy to the framebuffer memory copy. Both areas must be - * allocated. - */ -void -exaCopyDirtyToFb (ExaMigrationPtr migrate) -{ - PixmapPtr pPixmap = migrate->pPix; - ExaScreenPriv (pPixmap->drawable.pScreen); - ExaPixmapPriv (pPixmap); - - exaCopyDirty(migrate, &pExaPixmap->validFB, &pExaPixmap->validSys, - pExaScr->info->UploadToScreen, EXA_PREPARE_DEST, NULL); -} - -/** - * Allocates a framebuffer copy of the pixmap if necessary, and then copies - * any necessary pixmap data into the framebuffer copy and points the pixmap at - * it. - * - * Note that when first allocated, a pixmap will have FALSE dirty flag. - * This is intentional because pixmap data starts out undefined. So if we move - * it in due to the first operation against it being accelerated, it will have - * undefined framebuffer contents that we didn't have to upload. If we do - * moveouts (and moveins) after the first movein, then we will only have to copy - * back and forth if the pixmap was written to after the last synchronization of - * the two copies. Then, at exaPixmapSave (when the framebuffer copy goes away) - * we mark the pixmap dirty, so that the next exaMoveInPixmap will actually move - * all the data, since it's almost surely all valid now. - */ -static void -exaDoMoveInPixmap (ExaMigrationPtr migrate) -{ - PixmapPtr pPixmap = migrate->pPix; - ScreenPtr pScreen = pPixmap->drawable.pScreen; - ExaScreenPriv (pScreen); - ExaPixmapPriv (pPixmap); - - /* If we're VT-switched away, no touching card memory allowed. */ - if (pExaScr->swappedOut) - return; - - /* If we're not allowed to move, then fail. */ - if (exaPixmapIsPinned(pPixmap)) - return; - - /* Don't migrate in pixmaps which are less than 8bpp. This avoids a lot of - * fragility in EXA, and <8bpp is probably not used enough any more to care - * (at least, not in acceleratd paths). - */ - if (pPixmap->drawable.bitsPerPixel < 8) - return; - - if (pExaPixmap->accel_blocked) - return; - - if (pExaPixmap->area == NULL) { - pExaPixmap->area = - exaOffscreenAlloc (pScreen, pExaPixmap->fb_size, - pExaScr->info->pixmapOffsetAlign, FALSE, - exaPixmapSave, (pointer) pPixmap); - if (pExaPixmap->area == NULL) - return; - - pExaPixmap->fb_ptr = (CARD8 *) pExaScr->info->memoryBase + - pExaPixmap->area->offset; - } - - exaCopyDirtyToFb (migrate); - - if (exaPixmapHasGpuCopy(pPixmap)) - return; - - DBG_MIGRATE (("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap, - (ExaGetPixmapPriv(pPixmap)->area ? - ExaGetPixmapPriv(pPixmap)->area->offset : 0), - pPixmap->drawable.width, - pPixmap->drawable.height, - exaPixmapIsDirty(pPixmap) ? 'd' : 'c')); - - pExaPixmap->use_gpu_copy = TRUE; - - pPixmap->devKind = pExaPixmap->fb_pitch; - pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; -} - -void -exaMoveInPixmap_classic (PixmapPtr pPixmap) -{ - static ExaMigrationRec migrate = { .as_dst = FALSE, .as_src = TRUE, - .pReg = NULL }; - - migrate.pPix = pPixmap; - exaDoMoveInPixmap (&migrate); -} - -/** - * Switches the current active location of the pixmap to system memory, copying - * updated data out if necessary. - */ -static void -exaDoMoveOutPixmap (ExaMigrationPtr migrate) -{ - PixmapPtr pPixmap = migrate->pPix; - ExaPixmapPriv (pPixmap); - - if (!pExaPixmap->area || exaPixmapIsPinned(pPixmap)) - return; - - exaCopyDirtyToSys (migrate); - - if (exaPixmapHasGpuCopy(pPixmap)) { - - DBG_MIGRATE (("<- %p (%p) (%dx%d) (%c)\n", pPixmap, - (void*)(ExaGetPixmapPriv(pPixmap)->area ? - ExaGetPixmapPriv(pPixmap)->area->offset : 0), - pPixmap->drawable.width, - pPixmap->drawable.height, - exaPixmapIsDirty(pPixmap) ? 'd' : 'c')); - - pExaPixmap->use_gpu_copy = FALSE; - - pPixmap->devKind = pExaPixmap->sys_pitch; - pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; - } -} - -void -exaMoveOutPixmap_classic (PixmapPtr pPixmap) -{ - static ExaMigrationRec migrate = { .as_dst = FALSE, .as_src = TRUE, - .pReg = NULL }; - - migrate.pPix = pPixmap; - exaDoMoveOutPixmap (&migrate); -} - - -/** - * Copies out important pixmap data and removes references to framebuffer area. - * Called when the memory manager decides it's time to kick the pixmap out of - * framebuffer entirely. - */ -void -exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area) -{ - PixmapPtr pPixmap = area->privData; - ExaPixmapPriv(pPixmap); - - exaMoveOutPixmap(pPixmap); - - pExaPixmap->fb_ptr = NULL; - pExaPixmap->area = NULL; - - /* Mark all FB bits as invalid, so all valid system bits get copied to FB - * next time */ - REGION_EMPTY(pPixmap->drawable.pScreen, &pExaPixmap->validFB); -} - -/** - * For the "greedy" migration scheme, pushes the pixmap toward being located in - * framebuffer memory. - */ -static void -exaMigrateTowardFb (ExaMigrationPtr migrate) -{ - PixmapPtr pPixmap = migrate->pPix; - ExaPixmapPriv (pPixmap); - - if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) { - DBG_MIGRATE(("UseScreen: not migrating pinned pixmap %p\n", - (pointer)pPixmap)); - return; - } - - DBG_MIGRATE(("UseScreen %p score %d\n", - (pointer)pPixmap, pExaPixmap->score)); - - if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) { - exaDoMoveInPixmap(migrate); - pExaPixmap->score = 0; - } - - if (pExaPixmap->score < EXA_PIXMAP_SCORE_MAX) - pExaPixmap->score++; - - if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN && - !exaPixmapHasGpuCopy(pPixmap)) - { - exaDoMoveInPixmap(migrate); - } - - if (exaPixmapHasGpuCopy(pPixmap)) { - exaCopyDirtyToFb (migrate); - ExaOffscreenMarkUsed (pPixmap); - } else - exaCopyDirtyToSys (migrate); -} - -/** - * For the "greedy" migration scheme, pushes the pixmap toward being located in - * system memory. - */ -static void -exaMigrateTowardSys (ExaMigrationPtr migrate) -{ - PixmapPtr pPixmap = migrate->pPix; - ExaPixmapPriv (pPixmap); - - DBG_MIGRATE(("UseMem: %p score %d\n", (pointer)pPixmap, pExaPixmap->score)); - - if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) - return; - - if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) - pExaPixmap->score = 0; - - if (pExaPixmap->score > EXA_PIXMAP_SCORE_MIN) - pExaPixmap->score--; - - if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area) - exaDoMoveOutPixmap(migrate); - - if (exaPixmapHasGpuCopy(pPixmap)) { - exaCopyDirtyToFb (migrate); - ExaOffscreenMarkUsed (pPixmap); - } else - exaCopyDirtyToSys (migrate); -} - -/** - * If the pixmap has both a framebuffer and system memory copy, this function - * asserts that both of them are the same. - */ -static Bool -exaAssertNotDirty (PixmapPtr pPixmap) -{ - ExaPixmapPriv (pPixmap); - CARD8 *dst, *src; - RegionRec ValidReg; - int dst_pitch, src_pitch, cpp, y, nbox, save_pitch; - BoxPtr pBox; - Bool ret = TRUE, save_use_gpu_copy; - - if (exaPixmapIsPinned(pPixmap) || pExaPixmap->area == NULL) - return ret; - - REGION_NULL(pScreen, &ValidReg); - REGION_INTERSECT(pScreen, &ValidReg, &pExaPixmap->validFB, - &pExaPixmap->validSys); - nbox = REGION_NUM_RECTS(&ValidReg); - - if (!nbox) - goto out; - - pBox = REGION_RECTS(&ValidReg); - - dst_pitch = pExaPixmap->sys_pitch; - src_pitch = pExaPixmap->fb_pitch; - cpp = pPixmap->drawable.bitsPerPixel / 8; - - save_use_gpu_copy = pExaPixmap->use_gpu_copy; - save_pitch = pPixmap->devKind; - pExaPixmap->use_gpu_copy = TRUE; - pPixmap->devKind = pExaPixmap->fb_pitch; - - if (!ExaDoPrepareAccess(pPixmap, EXA_PREPARE_SRC)) - goto skip; - - while (nbox--) { - int rowbytes; - - pBox->x1 = max(pBox->x1, 0); - pBox->y1 = max(pBox->y1, 0); - pBox->x2 = min(pBox->x2, pPixmap->drawable.width); - pBox->y2 = min(pBox->y2, pPixmap->drawable.height); - - if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2) - continue; - - rowbytes = (pBox->x2 - pBox->x1) * cpp; - src = (CARD8 *) pPixmap->devPrivate.ptr + pBox->y1 * src_pitch + pBox->x1 * cpp; - dst = pExaPixmap->sys_ptr + pBox->y1 * dst_pitch + pBox->x1 * cpp; - - for (y = pBox->y1; y < pBox->y2; - y++, src += src_pitch, dst += dst_pitch) { - if (memcmp(dst, src, rowbytes) != 0) { - ret = FALSE; - exaPixmapDirty(pPixmap, pBox->x1, pBox->y1, pBox->x2, - pBox->y2); - break; - } - } - } - -skip: - exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC); - - pExaPixmap->use_gpu_copy = save_use_gpu_copy; - pPixmap->devKind = save_pitch; - -out: - REGION_UNINIT(pScreen, &ValidReg); - return ret; -} - -/** - * Performs migration of the pixmaps according to the operation information - * provided in pixmaps and can_accel and the migration scheme chosen in the - * config file. - */ -void -exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel) -{ - ScreenPtr pScreen = pixmaps[0].pPix->drawable.pScreen; - ExaScreenPriv(pScreen); - int i, j; - - /* If this debugging flag is set, check each pixmap for whether it is marked - * as clean, and if so, actually check if that's the case. This should help - * catch issues with failing to mark a drawable as dirty. While it will - * catch them late (after the operation happened), it at least explains what - * went wrong, and instrumenting the code to find what operation happened - * to the pixmap last shouldn't be hard. - */ - if (pExaScr->checkDirtyCorrectness) { - for (i = 0; i < npixmaps; i++) { - if (!exaPixmapIsDirty (pixmaps[i].pPix) && - !exaAssertNotDirty (pixmaps[i].pPix)) - ErrorF("%s: Pixmap %d dirty but not marked as such!\n", __func__, i); - } - } - /* If anything is pinned in system memory, we won't be able to - * accelerate. - */ - for (i = 0; i < npixmaps; i++) { - if (exaPixmapIsPinned (pixmaps[i].pPix) && - !exaPixmapHasGpuCopy (pixmaps[i].pPix)) - { - EXA_FALLBACK(("Pixmap %p (%dx%d) pinned in sys\n", pixmaps[i].pPix, - pixmaps[i].pPix->drawable.width, - pixmaps[i].pPix->drawable.height)); - can_accel = FALSE; - break; - } - } - - if (pExaScr->migration == ExaMigrationSmart) { - /* If we've got something as a destination that we shouldn't cause to - * become newly dirtied, take the unaccelerated route. - */ - for (i = 0; i < npixmaps; i++) { - if (pixmaps[i].as_dst && !exaPixmapShouldBeInFB (pixmaps[i].pPix) && - !exaPixmapIsDirty (pixmaps[i].pPix)) - { - for (i = 0; i < npixmaps; i++) { - if (!exaPixmapIsDirty (pixmaps[i].pPix)) - exaDoMoveOutPixmap (pixmaps + i); - } - return; - } - } - - /* If we aren't going to accelerate, then we migrate everybody toward - * system memory, and kick out if it's free. - */ - if (!can_accel) { - for (i = 0; i < npixmaps; i++) { - exaMigrateTowardSys (pixmaps + i); - if (!exaPixmapIsDirty (pixmaps[i].pPix)) - exaDoMoveOutPixmap (pixmaps + i); - } - return; - } - - /* Finally, the acceleration path. Move them all in. */ - for (i = 0; i < npixmaps; i++) { - exaMigrateTowardFb(pixmaps + i); - exaDoMoveInPixmap(pixmaps + i); - } - } else if (pExaScr->migration == ExaMigrationGreedy) { - /* If we can't accelerate, either because the driver can't or because one of - * the pixmaps is pinned in system memory, then we migrate everybody toward - * system memory. - * - * We also migrate toward system if all pixmaps involved are currently in - * system memory -- this can mitigate thrashing when there are significantly - * more pixmaps active than would fit in memory. - * - * If not, then we migrate toward FB so that hopefully acceleration can - * happen. - */ - if (!can_accel) { - for (i = 0; i < npixmaps; i++) - exaMigrateTowardSys (pixmaps + i); - return; - } - - for (i = 0; i < npixmaps; i++) { - if (exaPixmapHasGpuCopy(pixmaps[i].pPix)) { - /* Found one in FB, so move all to FB. */ - for (j = 0; j < npixmaps; j++) - exaMigrateTowardFb(pixmaps + i); - return; - } - } - - /* Nobody's in FB, so move all away from FB. */ - for (i = 0; i < npixmaps; i++) - exaMigrateTowardSys(pixmaps + i); - } else if (pExaScr->migration == ExaMigrationAlways) { - /* Always move the pixmaps out if we can't accelerate. If we can - * accelerate, try to move them all in. If that fails, then move them - * back out. - */ - if (!can_accel) { - for (i = 0; i < npixmaps; i++) - exaDoMoveOutPixmap(pixmaps + i); - return; - } - - /* Now, try to move them all into FB */ - for (i = 0; i < npixmaps; i++) { - exaDoMoveInPixmap(pixmaps + i); - } - - /* If we couldn't fit everything in, abort */ - for (i = 0; i < npixmaps; i++) { - if (!exaPixmapHasGpuCopy(pixmaps[i].pPix)) { - return; - } - } - - /* Yay, everything has a gpu copy, mark memory as used */ - for (i = 0; i < npixmaps; i++) { - ExaOffscreenMarkUsed (pixmaps[i].pPix); - } - } -} - -void -exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg) -{ - ExaMigrationRec pixmaps[1]; - - if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) { - pixmaps[0].as_dst = TRUE; - pixmaps[0].as_src = FALSE; - } else { - pixmaps[0].as_dst = FALSE; - pixmaps[0].as_src = TRUE; - } - pixmaps[0].pPix = pPixmap; - pixmaps[0].pReg = pReg; - - exaDoMigration(pixmaps, 1, FALSE); - - (void)ExaDoPrepareAccess(pPixmap, index); -} +/*
+ * Copyright © 2006 Intel Corporation
+ *
+ * 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.
+ *
+ * Authors:
+ * Eric Anholt <eric@anholt.net>
+ * Michel Dänzer <michel@tungstengraphics.com>
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <string.h>
+
+#include "exa_priv.h"
+#include "exa.h"
+
+#if DEBUG_MIGRATE
+#define DBG_MIGRATE(a) ErrorF a
+#else
+#define DBG_MIGRATE(a)
+#endif
+
+/**
+ * The fallback path for UTS/DFS failing is to just memcpy. exaCopyDirtyToSys
+ * and exaCopyDirtyToFb both needed to do this loop.
+ */
+static void
+exaMemcpyBox (PixmapPtr pPixmap, BoxPtr pbox, CARD8 *src, int src_pitch,
+ CARD8 *dst, int dst_pitch)
+ {
+ int i, cpp = pPixmap->drawable.bitsPerPixel / 8;
+ int bytes = (pbox->x2 - pbox->x1) * cpp;
+
+ src += pbox->y1 * src_pitch + pbox->x1 * cpp;
+ dst += pbox->y1 * dst_pitch + pbox->x1 * cpp;
+
+ for (i = pbox->y2 - pbox->y1; i; i--) {
+ memcpy (dst, src, bytes);
+ src += src_pitch;
+ dst += dst_pitch;
+ }
+}
+
+/**
+ * Returns TRUE if the pixmap is dirty (has been modified in its current
+ * location compared to the other), or lacks a private for tracking
+ * dirtiness.
+ */
+static Bool
+exaPixmapIsDirty (PixmapPtr pPix)
+{
+ ExaPixmapPriv (pPix);
+
+ if (pExaPixmap == NULL)
+ EXA_FatalErrorDebugWithRet(("EXA bug: exaPixmapIsDirty was called on a non-exa pixmap.\n"), TRUE);
+
+ if (!pExaPixmap->pDamage)
+ return FALSE;
+
+ return REGION_NOTEMPTY (pScreen, DamageRegion(pExaPixmap->pDamage)) ||
+ !REGION_EQUAL(pScreen, &pExaPixmap->validSys, &pExaPixmap->validFB);
+}
+
+/**
+ * Returns TRUE if the pixmap is either pinned in FB, or has a sufficient score
+ * to be considered "should be in framebuffer". That's just anything that has
+ * had more acceleration than fallbacks, or has no score yet.
+ *
+ * Only valid if using a migration scheme that tracks score.
+ */
+static Bool
+exaPixmapShouldBeInFB (PixmapPtr pPix)
+{
+ ExaPixmapPriv (pPix);
+
+ if (exaPixmapIsPinned (pPix))
+ return TRUE;
+
+ return pExaPixmap->score >= 0;
+}
+
+/**
+ * If the pixmap is currently dirty, this copies at least the dirty area from
+ * FB to system or vice versa. Both areas must be allocated.
+ */
+static void
+exaCopyDirty(ExaMigrationPtr migrate, RegionPtr pValidDst, RegionPtr pValidSrc,
+ Bool (*transfer) (PixmapPtr pPix, int x, int y, int w, int h,
+ char *sys, int sys_pitch), int fallback_index,
+ void (*sync) (ScreenPtr pScreen))
+{
+ PixmapPtr pPixmap = migrate->pPix;
+ ExaPixmapPriv (pPixmap);
+ RegionPtr damage = DamageRegion (pExaPixmap->pDamage);
+ RegionRec CopyReg;
+ Bool save_use_gpu_copy;
+ int save_pitch;
+ BoxPtr pBox;
+ int nbox;
+ Bool access_prepared = FALSE;
+ Bool need_sync = FALSE;
+
+ /* Damaged bits are valid in current copy but invalid in other one */
+ if (pExaPixmap->use_gpu_copy) {
+ REGION_UNION(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
+ damage);
+ REGION_SUBTRACT(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
+ damage);
+ } else {
+ REGION_UNION(pScreen, &pExaPixmap->validSys, &pExaPixmap->validSys,
+ damage);
+ REGION_SUBTRACT(pScreen, &pExaPixmap->validFB, &pExaPixmap->validFB,
+ damage);
+ }
+
+ REGION_EMPTY(pScreen, damage);
+
+ /* Copy bits valid in source but not in destination */
+ REGION_NULL(pScreen, &CopyReg);
+ REGION_SUBTRACT(pScreen, &CopyReg, pValidSrc, pValidDst);
+
+ if (migrate->as_dst) {
+ ExaScreenPriv (pPixmap->drawable.pScreen);
+
+ /* XXX: The pending damage region will be marked as damaged after the
+ * operation, so it should serve as an upper bound for the region that
+ * needs to be synchronized for the operation. Unfortunately, this
+ * causes corruption in some cases, e.g. when starting compiz. See
+ * https://bugs.freedesktop.org/show_bug.cgi?id=12916 .
+ */
+ if (pExaScr->optimize_migration) {
+ RegionPtr pending_damage = DamagePendingRegion(pExaPixmap->pDamage);
+
+#if DEBUG_MIGRATE
+ if (REGION_NIL(pending_damage)) {
+ static Bool firsttime = TRUE;
+
+ if (firsttime) {
+ ErrorF("%s: Pending damage region empty!\n", __func__);
+ firsttime = FALSE;
+ }
+ }
+#endif
+
+ /* Try to prevent destination valid region from growing too many
+ * rects by filling it up to the extents of the union of the
+ * destination valid region and the pending damage region.
+ */
+ if (REGION_NUM_RECTS(pValidDst) > 10) {
+ BoxRec box;
+ BoxPtr pValidExt, pDamageExt;
+ RegionRec closure;
+
+ pValidExt = REGION_EXTENTS(pScreen, pValidDst);
+ pDamageExt = REGION_EXTENTS(pScreen, pending_damage);
+
+ box.x1 = min(pValidExt->x1, pDamageExt->x1);
+ box.y1 = min(pValidExt->y1, pDamageExt->y1);
+ box.x2 = max(pValidExt->x2, pDamageExt->x2);
+ box.y2 = max(pValidExt->y2, pDamageExt->y2);
+
+ REGION_INIT(pScreen, &closure, &box, 0);
+ REGION_INTERSECT(pScreen, &CopyReg, &CopyReg, &closure);
+ } else
+ REGION_INTERSECT(pScreen, &CopyReg, &CopyReg, pending_damage);
+ }
+
+ /* The caller may provide a region to be subtracted from the calculated
+ * dirty region. This is to avoid migration of bits that don't
+ * contribute to the result of the operation.
+ */
+ if (migrate->pReg)
+ REGION_SUBTRACT(pScreen, &CopyReg, &CopyReg, migrate->pReg);
+ } else {
+ /* The caller may restrict the region to be migrated for source pixmaps
+ * to what's relevant for the operation.
+ */
+ if (migrate->pReg)
+ REGION_INTERSECT(pScreen, &CopyReg, &CopyReg, migrate->pReg);
+ }
+
+ pBox = REGION_RECTS(&CopyReg);
+ nbox = REGION_NUM_RECTS(&CopyReg);
+
+ save_use_gpu_copy = pExaPixmap->use_gpu_copy;
+ save_pitch = pPixmap->devKind;
+ pExaPixmap->use_gpu_copy = TRUE;
+ pPixmap->devKind = pExaPixmap->fb_pitch;
+
+ while (nbox--) {
+ pBox->x1 = max(pBox->x1, 0);
+ pBox->y1 = max(pBox->y1, 0);
+ pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
+ pBox->y2 = min(pBox->y2, pPixmap->drawable.height);
+
+ if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
+ continue;
+
+ if (!transfer || !transfer (pPixmap,
+ pBox->x1, pBox->y1,
+ pBox->x2 - pBox->x1,
+ pBox->y2 - pBox->y1,
+ (char *) (pExaPixmap->sys_ptr
+ + pBox->y1 * pExaPixmap->sys_pitch
+ + pBox->x1 * pPixmap->drawable.bitsPerPixel / 8),
+ pExaPixmap->sys_pitch))
+ {
+ if (!access_prepared) {
+ ExaDoPrepareAccess(pPixmap, fallback_index);
+ access_prepared = TRUE;
+ }
+ if (fallback_index == EXA_PREPARE_DEST) {
+ exaMemcpyBox (pPixmap, pBox,
+ pExaPixmap->sys_ptr, pExaPixmap->sys_pitch,
+ pPixmap->devPrivate.ptr, pPixmap->devKind);
+ } else {
+ exaMemcpyBox (pPixmap, pBox,
+ pPixmap->devPrivate.ptr, pPixmap->devKind,
+ pExaPixmap->sys_ptr, pExaPixmap->sys_pitch);
+ }
+ } else
+ need_sync = TRUE;
+
+ pBox++;
+ }
+
+ pExaPixmap->use_gpu_copy = save_use_gpu_copy;
+ pPixmap->devKind = save_pitch;
+
+ /* Try to prevent source valid region from growing too many rects by
+ * removing parts of it which are also in the destination valid region.
+ * Removing anything beyond that would lead to data loss.
+ */
+ if (REGION_NUM_RECTS(pValidSrc) > 20)
+ REGION_SUBTRACT(pScreen, pValidSrc, pValidSrc, pValidDst);
+
+ /* The copied bits are now valid in destination */
+ REGION_UNION(pScreen, pValidDst, pValidDst, &CopyReg);
+
+ REGION_UNINIT(pScreen, &CopyReg);
+
+ if (access_prepared)
+ exaFinishAccess(&pPixmap->drawable, fallback_index);
+ else if (need_sync && sync)
+ sync (pPixmap->drawable.pScreen);
+}
+
+/**
+ * If the pixmap is currently dirty, this copies at least the dirty area from
+ * the framebuffer memory copy to the system memory copy. Both areas must be
+ * allocated.
+ */
+void
+exaCopyDirtyToSys (ExaMigrationPtr migrate)
+{
+ PixmapPtr pPixmap = migrate->pPix;
+ ExaScreenPriv (pPixmap->drawable.pScreen);
+ ExaPixmapPriv (pPixmap);
+
+ exaCopyDirty(migrate, &pExaPixmap->validSys, &pExaPixmap->validFB,
+ pExaScr->info->DownloadFromScreen, EXA_PREPARE_SRC,
+ exaWaitSync);
+}
+
+/**
+ * If the pixmap is currently dirty, this copies at least the dirty area from
+ * the system memory copy to the framebuffer memory copy. Both areas must be
+ * allocated.
+ */
+void
+exaCopyDirtyToFb (ExaMigrationPtr migrate)
+{
+ PixmapPtr pPixmap = migrate->pPix;
+ ExaScreenPriv (pPixmap->drawable.pScreen);
+ ExaPixmapPriv (pPixmap);
+
+ exaCopyDirty(migrate, &pExaPixmap->validFB, &pExaPixmap->validSys,
+ pExaScr->info->UploadToScreen, EXA_PREPARE_DEST, NULL);
+}
+
+/**
+ * Allocates a framebuffer copy of the pixmap if necessary, and then copies
+ * any necessary pixmap data into the framebuffer copy and points the pixmap at
+ * it.
+ *
+ * Note that when first allocated, a pixmap will have FALSE dirty flag.
+ * This is intentional because pixmap data starts out undefined. So if we move
+ * it in due to the first operation against it being accelerated, it will have
+ * undefined framebuffer contents that we didn't have to upload. If we do
+ * moveouts (and moveins) after the first movein, then we will only have to copy
+ * back and forth if the pixmap was written to after the last synchronization of
+ * the two copies. Then, at exaPixmapSave (when the framebuffer copy goes away)
+ * we mark the pixmap dirty, so that the next exaMoveInPixmap will actually move
+ * all the data, since it's almost surely all valid now.
+ */
+static void
+exaDoMoveInPixmap (ExaMigrationPtr migrate)
+{
+ PixmapPtr pPixmap = migrate->pPix;
+ ScreenPtr pScreen = pPixmap->drawable.pScreen;
+ ExaScreenPriv (pScreen);
+ ExaPixmapPriv (pPixmap);
+
+ /* If we're VT-switched away, no touching card memory allowed. */
+ if (pExaScr->swappedOut)
+ return;
+
+ /* If we're not allowed to move, then fail. */
+ if (exaPixmapIsPinned(pPixmap))
+ return;
+
+ /* Don't migrate in pixmaps which are less than 8bpp. This avoids a lot of
+ * fragility in EXA, and <8bpp is probably not used enough any more to care
+ * (at least, not in acceleratd paths).
+ */
+ if (pPixmap->drawable.bitsPerPixel < 8)
+ return;
+
+ if (pExaPixmap->accel_blocked)
+ return;
+
+ if (pExaPixmap->area == NULL) {
+ pExaPixmap->area =
+ exaOffscreenAlloc (pScreen, pExaPixmap->fb_size,
+ pExaScr->info->pixmapOffsetAlign, FALSE,
+ exaPixmapSave, (pointer) pPixmap);
+ if (pExaPixmap->area == NULL)
+ return;
+
+ pExaPixmap->fb_ptr = (CARD8 *) pExaScr->info->memoryBase +
+ pExaPixmap->area->offset;
+ }
+
+ exaCopyDirtyToFb (migrate);
+
+ if (exaPixmapHasGpuCopy(pPixmap))
+ return;
+
+ DBG_MIGRATE (("-> %p (0x%x) (%dx%d) (%c)\n", pPixmap,
+ (ExaGetPixmapPriv(pPixmap)->area ?
+ ExaGetPixmapPriv(pPixmap)->area->offset : 0),
+ pPixmap->drawable.width,
+ pPixmap->drawable.height,
+ exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
+
+ pExaPixmap->use_gpu_copy = TRUE;
+
+ pPixmap->devKind = pExaPixmap->fb_pitch;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+}
+
+void
+exaMoveInPixmap_classic (PixmapPtr pPixmap)
+{
+ static ExaMigrationRec migrate = { FALSE, TRUE,
+ NULL, NULL };
+
+ migrate.pPix = pPixmap;
+ exaDoMoveInPixmap (&migrate);
+}
+
+/**
+ * Switches the current active location of the pixmap to system memory, copying
+ * updated data out if necessary.
+ */
+static void
+exaDoMoveOutPixmap (ExaMigrationPtr migrate)
+{
+ PixmapPtr pPixmap = migrate->pPix;
+ ExaPixmapPriv (pPixmap);
+
+ if (!pExaPixmap->area || exaPixmapIsPinned(pPixmap))
+ return;
+
+ exaCopyDirtyToSys (migrate);
+
+ if (exaPixmapHasGpuCopy(pPixmap)) {
+
+ DBG_MIGRATE (("<- %p (%p) (%dx%d) (%c)\n", pPixmap,
+ (void*)(ExaGetPixmapPriv(pPixmap)->area ?
+ ExaGetPixmapPriv(pPixmap)->area->offset : 0),
+ pPixmap->drawable.width,
+ pPixmap->drawable.height,
+ exaPixmapIsDirty(pPixmap) ? 'd' : 'c'));
+
+ pExaPixmap->use_gpu_copy = FALSE;
+
+ pPixmap->devKind = pExaPixmap->sys_pitch;
+ pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
+ }
+}
+
+void
+exaMoveOutPixmap_classic (PixmapPtr pPixmap)
+{
+ static ExaMigrationRec migrate = { FALSE, TRUE,
+ NULL, NULL };
+
+ migrate.pPix = pPixmap;
+ exaDoMoveOutPixmap (&migrate);
+}
+
+
+/**
+ * Copies out important pixmap data and removes references to framebuffer area.
+ * Called when the memory manager decides it's time to kick the pixmap out of
+ * framebuffer entirely.
+ */
+void
+exaPixmapSave (ScreenPtr pScreen, ExaOffscreenArea *area)
+{
+ PixmapPtr pPixmap = area->privData;
+ ExaPixmapPriv(pPixmap);
+
+ exaMoveOutPixmap(pPixmap);
+
+ pExaPixmap->fb_ptr = NULL;
+ pExaPixmap->area = NULL;
+
+ /* Mark all FB bits as invalid, so all valid system bits get copied to FB
+ * next time */
+ REGION_EMPTY(pPixmap->drawable.pScreen, &pExaPixmap->validFB);
+}
+
+/**
+ * For the "greedy" migration scheme, pushes the pixmap toward being located in
+ * framebuffer memory.
+ */
+static void
+exaMigrateTowardFb (ExaMigrationPtr migrate)
+{
+ PixmapPtr pPixmap = migrate->pPix;
+ ExaPixmapPriv (pPixmap);
+
+ if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED) {
+ DBG_MIGRATE(("UseScreen: not migrating pinned pixmap %p\n",
+ (pointer)pPixmap));
+ return;
+ }
+
+ DBG_MIGRATE(("UseScreen %p score %d\n",
+ (pointer)pPixmap, pExaPixmap->score));
+
+ if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT) {
+ exaDoMoveInPixmap(migrate);
+ pExaPixmap->score = 0;
+ }
+
+ if (pExaPixmap->score < EXA_PIXMAP_SCORE_MAX)
+ pExaPixmap->score++;
+
+ if (pExaPixmap->score >= EXA_PIXMAP_SCORE_MOVE_IN &&
+ !exaPixmapHasGpuCopy(pPixmap))
+ {
+ exaDoMoveInPixmap(migrate);
+ }
+
+ if (exaPixmapHasGpuCopy(pPixmap)) {
+ exaCopyDirtyToFb (migrate);
+ ExaOffscreenMarkUsed (pPixmap);
+ } else
+ exaCopyDirtyToSys (migrate);
+}
+
+/**
+ * For the "greedy" migration scheme, pushes the pixmap toward being located in
+ * system memory.
+ */
+static void
+exaMigrateTowardSys (ExaMigrationPtr migrate)
+{
+ PixmapPtr pPixmap = migrate->pPix;
+ ExaPixmapPriv (pPixmap);
+
+ DBG_MIGRATE(("UseMem: %p score %d\n", (pointer)pPixmap, pExaPixmap->score));
+
+ if (pExaPixmap->score == EXA_PIXMAP_SCORE_PINNED)
+ return;
+
+ if (pExaPixmap->score == EXA_PIXMAP_SCORE_INIT)
+ pExaPixmap->score = 0;
+
+ if (pExaPixmap->score > EXA_PIXMAP_SCORE_MIN)
+ pExaPixmap->score--;
+
+ if (pExaPixmap->score <= EXA_PIXMAP_SCORE_MOVE_OUT && pExaPixmap->area)
+ exaDoMoveOutPixmap(migrate);
+
+ if (exaPixmapHasGpuCopy(pPixmap)) {
+ exaCopyDirtyToFb (migrate);
+ ExaOffscreenMarkUsed (pPixmap);
+ } else
+ exaCopyDirtyToSys (migrate);
+}
+
+/**
+ * If the pixmap has both a framebuffer and system memory copy, this function
+ * asserts that both of them are the same.
+ */
+static Bool
+exaAssertNotDirty (PixmapPtr pPixmap)
+{
+ ExaPixmapPriv (pPixmap);
+ CARD8 *dst, *src;
+ RegionRec ValidReg;
+ int dst_pitch, src_pitch, cpp, y, nbox, save_pitch;
+ BoxPtr pBox;
+ Bool ret = TRUE, save_use_gpu_copy;
+
+ if (exaPixmapIsPinned(pPixmap) || pExaPixmap->area == NULL)
+ return ret;
+
+ REGION_NULL(pScreen, &ValidReg);
+ REGION_INTERSECT(pScreen, &ValidReg, &pExaPixmap->validFB,
+ &pExaPixmap->validSys);
+ nbox = REGION_NUM_RECTS(&ValidReg);
+
+ if (!nbox)
+ goto out;
+
+ pBox = REGION_RECTS(&ValidReg);
+
+ dst_pitch = pExaPixmap->sys_pitch;
+ src_pitch = pExaPixmap->fb_pitch;
+ cpp = pPixmap->drawable.bitsPerPixel / 8;
+
+ save_use_gpu_copy = pExaPixmap->use_gpu_copy;
+ save_pitch = pPixmap->devKind;
+ pExaPixmap->use_gpu_copy = TRUE;
+ pPixmap->devKind = pExaPixmap->fb_pitch;
+
+ if (!ExaDoPrepareAccess(pPixmap, EXA_PREPARE_SRC))
+ goto skip;
+
+ while (nbox--) {
+ int rowbytes;
+
+ pBox->x1 = max(pBox->x1, 0);
+ pBox->y1 = max(pBox->y1, 0);
+ pBox->x2 = min(pBox->x2, pPixmap->drawable.width);
+ pBox->y2 = min(pBox->y2, pPixmap->drawable.height);
+
+ if (pBox->x1 >= pBox->x2 || pBox->y1 >= pBox->y2)
+ continue;
+
+ rowbytes = (pBox->x2 - pBox->x1) * cpp;
+ src = (CARD8 *) pPixmap->devPrivate.ptr + pBox->y1 * src_pitch + pBox->x1 * cpp;
+ dst = pExaPixmap->sys_ptr + pBox->y1 * dst_pitch + pBox->x1 * cpp;
+
+ for (y = pBox->y1; y < pBox->y2;
+ y++, src += src_pitch, dst += dst_pitch) {
+ if (memcmp(dst, src, rowbytes) != 0) {
+ ret = FALSE;
+ exaPixmapDirty(pPixmap, pBox->x1, pBox->y1, pBox->x2,
+ pBox->y2);
+ break;
+ }
+ }
+ }
+
+skip:
+ exaFinishAccess(&pPixmap->drawable, EXA_PREPARE_SRC);
+
+ pExaPixmap->use_gpu_copy = save_use_gpu_copy;
+ pPixmap->devKind = save_pitch;
+
+out:
+ REGION_UNINIT(pScreen, &ValidReg);
+ return ret;
+}
+
+/**
+ * Performs migration of the pixmaps according to the operation information
+ * provided in pixmaps and can_accel and the migration scheme chosen in the
+ * config file.
+ */
+void
+exaDoMigration_classic (ExaMigrationPtr pixmaps, int npixmaps, Bool can_accel)
+{
+ ScreenPtr pScreen = pixmaps[0].pPix->drawable.pScreen;
+ ExaScreenPriv(pScreen);
+ int i, j;
+
+ /* If this debugging flag is set, check each pixmap for whether it is marked
+ * as clean, and if so, actually check if that's the case. This should help
+ * catch issues with failing to mark a drawable as dirty. While it will
+ * catch them late (after the operation happened), it at least explains what
+ * went wrong, and instrumenting the code to find what operation happened
+ * to the pixmap last shouldn't be hard.
+ */
+ if (pExaScr->checkDirtyCorrectness) {
+ for (i = 0; i < npixmaps; i++) {
+ if (!exaPixmapIsDirty (pixmaps[i].pPix) &&
+ !exaAssertNotDirty (pixmaps[i].pPix))
+ ErrorF("%s: Pixmap %d dirty but not marked as such!\n", __FUNCTION__, i);
+ }
+ }
+ /* If anything is pinned in system memory, we won't be able to
+ * accelerate.
+ */
+ for (i = 0; i < npixmaps; i++) {
+ if (exaPixmapIsPinned (pixmaps[i].pPix) &&
+ !exaPixmapHasGpuCopy (pixmaps[i].pPix))
+ {
+ EXA_FALLBACK(("Pixmap %p (%dx%d) pinned in sys\n", pixmaps[i].pPix,
+ pixmaps[i].pPix->drawable.width,
+ pixmaps[i].pPix->drawable.height));
+ can_accel = FALSE;
+ break;
+ }
+ }
+
+ if (pExaScr->migration == ExaMigrationSmart) {
+ /* If we've got something as a destination that we shouldn't cause to
+ * become newly dirtied, take the unaccelerated route.
+ */
+ for (i = 0; i < npixmaps; i++) {
+ if (pixmaps[i].as_dst && !exaPixmapShouldBeInFB (pixmaps[i].pPix) &&
+ !exaPixmapIsDirty (pixmaps[i].pPix))
+ {
+ for (i = 0; i < npixmaps; i++) {
+ if (!exaPixmapIsDirty (pixmaps[i].pPix))
+ exaDoMoveOutPixmap (pixmaps + i);
+ }
+ return;
+ }
+ }
+
+ /* If we aren't going to accelerate, then we migrate everybody toward
+ * system memory, and kick out if it's free.
+ */
+ if (!can_accel) {
+ for (i = 0; i < npixmaps; i++) {
+ exaMigrateTowardSys (pixmaps + i);
+ if (!exaPixmapIsDirty (pixmaps[i].pPix))
+ exaDoMoveOutPixmap (pixmaps + i);
+ }
+ return;
+ }
+
+ /* Finally, the acceleration path. Move them all in. */
+ for (i = 0; i < npixmaps; i++) {
+ exaMigrateTowardFb(pixmaps + i);
+ exaDoMoveInPixmap(pixmaps + i);
+ }
+ } else if (pExaScr->migration == ExaMigrationGreedy) {
+ /* If we can't accelerate, either because the driver can't or because one of
+ * the pixmaps is pinned in system memory, then we migrate everybody toward
+ * system memory.
+ *
+ * We also migrate toward system if all pixmaps involved are currently in
+ * system memory -- this can mitigate thrashing when there are significantly
+ * more pixmaps active than would fit in memory.
+ *
+ * If not, then we migrate toward FB so that hopefully acceleration can
+ * happen.
+ */
+ if (!can_accel) {
+ for (i = 0; i < npixmaps; i++)
+ exaMigrateTowardSys (pixmaps + i);
+ return;
+ }
+
+ for (i = 0; i < npixmaps; i++) {
+ if (exaPixmapHasGpuCopy(pixmaps[i].pPix)) {
+ /* Found one in FB, so move all to FB. */
+ for (j = 0; j < npixmaps; j++)
+ exaMigrateTowardFb(pixmaps + i);
+ return;
+ }
+ }
+
+ /* Nobody's in FB, so move all away from FB. */
+ for (i = 0; i < npixmaps; i++)
+ exaMigrateTowardSys(pixmaps + i);
+ } else if (pExaScr->migration == ExaMigrationAlways) {
+ /* Always move the pixmaps out if we can't accelerate. If we can
+ * accelerate, try to move them all in. If that fails, then move them
+ * back out.
+ */
+ if (!can_accel) {
+ for (i = 0; i < npixmaps; i++)
+ exaDoMoveOutPixmap(pixmaps + i);
+ return;
+ }
+
+ /* Now, try to move them all into FB */
+ for (i = 0; i < npixmaps; i++) {
+ exaDoMoveInPixmap(pixmaps + i);
+ }
+
+ /* If we couldn't fit everything in, abort */
+ for (i = 0; i < npixmaps; i++) {
+ if (!exaPixmapHasGpuCopy(pixmaps[i].pPix)) {
+ return;
+ }
+ }
+
+ /* Yay, everything has a gpu copy, mark memory as used */
+ for (i = 0; i < npixmaps; i++) {
+ ExaOffscreenMarkUsed (pixmaps[i].pPix);
+ }
+ }
+}
+
+void
+exaPrepareAccessReg_classic(PixmapPtr pPixmap, int index, RegionPtr pReg)
+{
+ ExaMigrationRec pixmaps[1];
+
+ if (index == EXA_PREPARE_DEST || index == EXA_PREPARE_AUX_DEST) {
+ pixmaps[0].as_dst = TRUE;
+ pixmaps[0].as_src = FALSE;
+ } else {
+ pixmaps[0].as_dst = FALSE;
+ pixmaps[0].as_src = TRUE;
+ }
+ pixmaps[0].pPix = pPixmap;
+ pixmaps[0].pReg = pReg;
+
+ exaDoMigration(pixmaps, 1, FALSE);
+
+ (void)ExaDoPrepareAccess(pPixmap, index);
+}
diff --git a/xorg-server/exa/exa_unaccel.c b/xorg-server/exa/exa_unaccel.c index b4ead7ff2..adbee8413 100644 --- a/xorg-server/exa/exa_unaccel.c +++ b/xorg-server/exa/exa_unaccel.c @@ -1,748 +1,748 @@ -/* - * - * Copyright © 1999 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. - */ - -#include "exa_priv.h" - -#ifdef RENDER -#include "mipict.h" -#endif - -/* - * These functions wrap the low-level fb rendering functions and - * synchronize framebuffer/accelerated drawing by stalling until - * the accelerator is idle - */ - -/** - * Calls exaPrepareAccess with EXA_PREPARE_SRC for the tile, if that is the - * current fill style. - * - * Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are - * 1bpp and never in fb, so we don't worry about them. - * We should worry about them for completeness sake and going forward. - */ -void -exaPrepareAccessGC(GCPtr pGC) -{ - if (pGC->stipple) - exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK); - if (pGC->fillStyle == FillTiled) - exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC); -} - -/** - * Finishes access to the tile in the GC, if used. - */ -void -exaFinishAccessGC(GCPtr pGC) -{ - if (pGC->fillStyle == FillTiled) - exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC); - if (pGC->stipple) - exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK); -} - -#if DEBUG_TRACE_FALL -char -exaDrawableLocation(DrawablePtr pDrawable) -{ - return exaDrawableIsOffscreen(pDrawable) ? 's' : 'm'; -} -#endif /* DEBUG_TRACE_FALL */ - -void -ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans, - DDXPointPtr ppt, int *pwidth, int fSorted) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - exaPrepareAccessGC (pGC); - pGC->ops->FillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted); - exaFinishAccessGC (pGC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc, - DDXPointPtr ppt, int *pwidth, int nspans, int fSorted) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - pGC->ops->SetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth, - int x, int y, int w, int h, int leftPad, int format, - char *bits) -{ - PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); - ExaPixmapPriv(pPixmap); - - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage || - exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle, - pGC->alu, pGC->clientClipType)) - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - else - pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, - DamagePendingRegion(pExaPixmap->pDamage)); - pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - BoxPtr pbox, int nbox, int dx, int dy, Bool reverse, - Bool upsidedown, Pixel bitplane, void *closure) -{ - RegionRec reg; - int xoff, yoff; - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, - exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); - - if (pExaScr->prepare_access_reg) { - PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc); - - exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff); - REGION_INIT(pScreen, ®, pbox, nbox); - REGION_TRANSLATE(pScreen, ®, xoff + dx, yoff + dy); - pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, ®); - REGION_UNINIT(pScreen, ®); - } else - exaPrepareAccess (pSrc, EXA_PREPARE_SRC); - - if (pExaScr->prepare_access_reg && - !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle, - pGC->alu, pGC->clientClipType)) { - PixmapPtr pPixmap = exaGetDrawablePixmap(pDst); - - exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff); - REGION_INIT(pScreen, ®, pbox, nbox); - REGION_TRANSLATE(pScreen, ®, xoff, yoff); - pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, ®); - REGION_UNINIT(pScreen, ®); - } else - exaPrepareAccess (pDst, EXA_PREPARE_DEST); - - /* This will eventually call fbCopyNtoN, with some calculation overhead. */ - while (nbox--) { - pGC->ops->CopyArea (pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx, pbox->y1 - pSrc->y + dy, - pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, pbox->x1 - pDst->x, pbox->y1 - pDst->y); - pbox++; - } - exaFinishAccess (pSrc, EXA_PREPARE_SRC); - exaFinishAccess (pDst, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -static void -ExaFallbackPrepareReg(DrawablePtr pDrawable, - GCPtr pGC, - int x, int y, int width, int height, - int index, Bool checkReads) -{ - ScreenPtr pScreen = pDrawable->pScreen; - ExaScreenPriv(pScreen); - - if (pExaScr->prepare_access_reg && - !(checkReads && exaGCReadsDestination(pDrawable, - pGC->planemask, - pGC->fillStyle, - pGC->alu, - pGC->clientClipType))) { - BoxRec box; - RegionRec reg; - int xoff, yoff; - PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable); - - exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff); - box.x1 = pDrawable->x + x + xoff; - box.y1 = pDrawable->y + y + yoff; - box.x2 = box.x1 + width; - box.y2 = box.y1 + height; - - REGION_INIT(pScreen, ®, &box, 1); - pExaScr->prepare_access_reg(pPixmap, index, ®); - REGION_UNINIT(pScreen, ®); - } else - exaPrepareAccess(pDrawable, index); -} - - -RegionPtr -ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, int dstx, int dsty) -{ - RegionPtr ret; - - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, - exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); - ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h, - EXA_PREPARE_SRC, FALSE); - ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h, - EXA_PREPARE_DEST, TRUE); - ret = pGC->ops->CopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty); - exaFinishAccess (pSrc, EXA_PREPARE_SRC); - exaFinishAccess (pDst, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); - - return ret; -} - -RegionPtr -ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, - int srcx, int srcy, int w, int h, int dstx, int dsty, - unsigned long bitPlane) -{ - RegionPtr ret; - - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst, - exaDrawableLocation(pSrc), exaDrawableLocation(pDst))); - ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h, - EXA_PREPARE_SRC, FALSE); - ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h, - EXA_PREPARE_DEST, TRUE); - ret = pGC->ops->CopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty, - bitPlane); - exaFinishAccess (pSrc, EXA_PREPARE_SRC); - exaFinishAccess (pDst, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); - - return ret; -} - -void -ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt, - DDXPointPtr pptInit) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - pGC->ops->PolyPoint (pDrawable, pGC, mode, npt, pptInit); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC, - int mode, int npt, DDXPointPtr ppt) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n", - pDrawable, exaDrawableLocation(pDrawable), - pGC->lineWidth, mode, npt)); - - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - exaPrepareAccessGC (pGC); - pGC->ops->Polylines (pDrawable, pGC, mode, npt, ppt); - exaFinishAccessGC (pGC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC, - int nsegInit, xSegment *pSegInit) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable, - exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit)); - - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - exaPrepareAccessGC (pGC); - pGC->ops->PolySegment (pDrawable, pGC, nsegInit, pSegInit); - exaFinishAccessGC (pGC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC, - int narcs, xArc *pArcs) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - exaPrepareAccessGC (pGC); - pGC->ops->PolyArc (pDrawable, pGC, narcs, pArcs); - exaFinishAccessGC (pGC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC, - int nrect, xRectangle *prect) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - exaPrepareAccessGC (pGC); - pGC->ops->PolyFillRect (pDrawable, pGC, nrect, prect); - exaFinishAccessGC (pGC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, pointer pglyphBase) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c)\n", pDrawable, - exaDrawableLocation(pDrawable))); - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - exaPrepareAccessGC (pGC); - pGC->ops->ImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); - exaFinishAccessGC (pGC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC, - int x, int y, unsigned int nglyph, - CharInfoPtr *ppci, pointer pglyphBase) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable, - exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu)); - exaPrepareAccess (pDrawable, EXA_PREPARE_DEST); - exaPrepareAccessGC (pGC); - pGC->ops->PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase); - exaFinishAccessGC (pGC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap, - DrawablePtr pDrawable, - int w, int h, int x, int y) -{ - EXA_PRE_FALLBACK_GC(pGC); - EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable, - exaDrawableLocation(&pBitmap->drawable), - exaDrawableLocation(pDrawable))); - ExaFallbackPrepareReg(pDrawable, pGC, x, y, w, h, - EXA_PREPARE_DEST, TRUE); - ExaFallbackPrepareReg(&pBitmap->drawable, pGC, 0, 0, w, h, - EXA_PREPARE_SRC, FALSE); - exaPrepareAccessGC (pGC); - pGC->ops->PushPixels (pGC, pBitmap, pDrawable, w, h, x, y); - exaFinishAccessGC (pGC); - exaFinishAccess (&pBitmap->drawable, EXA_PREPARE_SRC); - exaFinishAccess (pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK_GC(pGC); -} - -void -ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc) -{ - DrawablePtr pDrawable = &pWin->drawable; - ScreenPtr pScreen = pDrawable->pScreen; - EXA_PRE_FALLBACK(pScreen); - EXA_FALLBACK(("from %p\n", pWin)); - - /* Only need the source bits, the destination region will be overwritten */ - if (pExaScr->prepare_access_reg) { - PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin); - int xoff, yoff; - - exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff); - REGION_TRANSLATE(pScreen, prgnSrc, xoff, yoff); - pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc); - REGION_TRANSLATE(pScreen, prgnSrc, -xoff, -yoff); - } else - exaPrepareAccess(pDrawable, EXA_PREPARE_SRC); - - swap(pExaScr, pScreen, CopyWindow); - pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc); - swap(pExaScr, pScreen, CopyWindow); - exaFinishAccess (pDrawable, EXA_PREPARE_SRC); - EXA_POST_FALLBACK(pScreen); -} - -void -ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h, - unsigned int format, unsigned long planeMask, char *d) -{ - ScreenPtr pScreen = pDrawable->pScreen; - EXA_PRE_FALLBACK(pScreen); - EXA_FALLBACK(("from %p (%c)\n", pDrawable, - exaDrawableLocation(pDrawable))); - - ExaFallbackPrepareReg(pDrawable, NULL, x, y, w, h, - EXA_PREPARE_SRC, FALSE); - swap(pExaScr, pScreen, GetImage); - pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d); - swap(pExaScr, pScreen, GetImage); - exaFinishAccess (pDrawable, EXA_PREPARE_SRC); - EXA_POST_FALLBACK(pScreen); -} - -void -ExaCheckGetSpans (DrawablePtr pDrawable, - int wMax, - DDXPointPtr ppt, - int *pwidth, - int nspans, - char *pdstStart) -{ - ScreenPtr pScreen = pDrawable->pScreen; - - EXA_PRE_FALLBACK(pScreen); - EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable))); - exaPrepareAccess (pDrawable, EXA_PREPARE_SRC); - swap(pExaScr, pScreen, GetSpans); - pScreen->GetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart); - swap(pExaScr, pScreen, GetSpans); - exaFinishAccess (pDrawable, EXA_PREPARE_SRC); - EXA_POST_FALLBACK(pScreen); -} - -static void -ExaSrcValidate(DrawablePtr pDrawable, - int x, - int y, - int width, - int height) -{ - ScreenPtr pScreen = pDrawable->pScreen; - ExaScreenPriv(pScreen); - PixmapPtr pPix = exaGetDrawablePixmap (pDrawable); - BoxRec box; - RegionRec reg; - RegionPtr dst; - int xoff, yoff; - - exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff); - - box.x1 = x + xoff; - box.y1 = y + yoff; - box.x2 = box.x1 + width; - box.y2 = box.y1 + height; - - dst = (pExaScr->srcPix == pPix) ? &pExaScr->srcReg : - &pExaScr->maskReg; - - REGION_INIT(pScreen, ®, &box, 1); - REGION_UNION(pScreen, dst, dst, ®); - REGION_UNINIT(pScreen, ®); - - swap(pExaScr, pScreen, SourceValidate); - pScreen->SourceValidate(pDrawable, x, y, width, height); - swap(pExaScr, pScreen, SourceValidate); -} - -static Bool -ExaPrepareCompositeReg(ScreenPtr pScreen, - CARD8 op, - PicturePtr pSrc, - PicturePtr pMask, - PicturePtr pDst, - INT16 xSrc, - INT16 ySrc, - INT16 xMask, - INT16 yMask, - INT16 xDst, - INT16 yDst, - CARD16 width, - CARD16 height) -{ - RegionRec region; - RegionPtr dstReg = NULL; - RegionPtr srcReg = NULL; - RegionPtr maskReg = NULL; - PixmapPtr pSrcPix = NULL; - PixmapPtr pMaskPix = NULL; - PixmapPtr pDstPix; - ExaScreenPriv(pScreen); - Bool ret; - - - REGION_NULL(pScreen, ®ion); - - if (pSrc->pDrawable) { - pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable); - REGION_NULL(pScreen, &pExaScr->srcReg); - srcReg = &pExaScr->srcReg; - pExaScr->srcPix = pSrcPix; - if (pSrc != pDst) - REGION_TRANSLATE(pScreen, pSrc->pCompositeClip, - -pSrc->pDrawable->x, - -pSrc->pDrawable->y); - } - - if (pMask && pMask->pDrawable) { - pMaskPix = exaGetDrawablePixmap(pMask->pDrawable); - REGION_NULL(pScreen, &pExaScr->maskReg); - maskReg = &pExaScr->maskReg; - if (pMask != pDst && pMask != pSrc) - REGION_TRANSLATE(pScreen, pMask->pCompositeClip, - -pMask->pDrawable->x, - -pMask->pDrawable->y); - } - - REGION_TRANSLATE(pScreen, pDst->pCompositeClip, - -pDst->pDrawable->x, - -pDst->pDrawable->y); - - pExaScr->SavedSourceValidate = ExaSrcValidate; - swap(pExaScr, pScreen, SourceValidate); - ret = miComputeCompositeRegion (®ion, pSrc, pMask, pDst, - xSrc, ySrc, xMask, yMask, - xDst, - yDst, - width, height); - swap(pExaScr, pScreen, SourceValidate); - - REGION_TRANSLATE(pScreen, pDst->pCompositeClip, - pDst->pDrawable->x, - pDst->pDrawable->y); - if (pSrc->pDrawable && pSrc != pDst) - REGION_TRANSLATE(pScreen, pSrc->pCompositeClip, - pSrc->pDrawable->x, - pSrc->pDrawable->y); - if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc) - REGION_TRANSLATE(pScreen, pMask->pCompositeClip, - pMask->pDrawable->x, - pMask->pDrawable->y); - - if (!ret) { - if (srcReg) - REGION_UNINIT(pScreen, srcReg); - if (maskReg) - REGION_UNINIT(pScreen, maskReg); - - return FALSE; - } - - /** - * Don't limit alphamaps readbacks for now until we've figured out how that - * should be done. - */ - - if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) - pExaScr->prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable), - EXA_PREPARE_AUX_SRC, - NULL); - if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) - pExaScr->prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable), - EXA_PREPARE_AUX_MASK, - NULL); - - if (pSrcPix) - pExaScr->prepare_access_reg(pSrcPix, - EXA_PREPARE_SRC, - srcReg); - - if (pMaskPix) - pExaScr->prepare_access_reg(pMaskPix, - EXA_PREPARE_MASK, - maskReg); - - if (srcReg) - REGION_UNINIT(pScreen, srcReg); - if (maskReg) - REGION_UNINIT(pScreen, maskReg); - - pDstPix = exaGetDrawablePixmap(pDst->pDrawable); - if (!exaOpReadsDestination(op)) { - int xoff; - int yoff; - - exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff); - REGION_TRANSLATE(pScreen, ®ion, pDst->pDrawable->x + xoff, - pDst->pDrawable->y + yoff); - dstReg = ®ion; - } - - if (pDst->alphaMap && pDst->alphaMap->pDrawable) - pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable), - EXA_PREPARE_AUX_DEST, - dstReg); - pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg); - - REGION_UNINIT(pScreen, ®ion); - return TRUE; -} - -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) -{ - ScreenPtr pScreen = pDst->pDrawable->pScreen; -#ifdef RENDER - PictureScreenPtr ps = GetPictureScreen(pScreen); -#endif /* RENDER */ - EXA_PRE_FALLBACK(pScreen); - - if (pExaScr->prepare_access_reg) { - if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc, - ySrc, xMask, yMask, xDst, yDst, width, - height)) - goto out_no_clip; - } else { - - /* We need to prepare access to any separate alpha maps first, - * in case the driver doesn't support EXA_PREPARE_AUX*, - * in which case EXA_PREPARE_SRC may be used for moving them out. - */ - - if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) - exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC); - if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) - exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK); - if (pDst->alphaMap && pDst->alphaMap->pDrawable) - exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST); - - exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST); - - EXA_FALLBACK(("from picts %p/%p to pict %p\n", - pSrc, pMask, pDst)); - - if (pSrc->pDrawable != NULL) - exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC); - if (pMask && pMask->pDrawable != NULL) - exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK); - } - -#ifdef RENDER - swap(pExaScr, ps, Composite); - ps->Composite (op, - pSrc, - pMask, - pDst, - xSrc, - ySrc, - xMask, - yMask, - xDst, - yDst, - width, - height); - swap(pExaScr, ps, Composite); -#endif /* RENDER */ - if (pMask && pMask->pDrawable != NULL) - exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK); - if (pSrc->pDrawable != NULL) - exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC); - exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST); - if (pDst->alphaMap && pDst->alphaMap->pDrawable) - exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST); - if (pSrc->alphaMap && pSrc->alphaMap->pDrawable) - exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC); - if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable) - exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK); - -out_no_clip: - EXA_POST_FALLBACK(pScreen); -} - -void -ExaCheckAddTraps (PicturePtr pPicture, - INT16 x_off, - INT16 y_off, - int ntrap, - xTrap *traps) -{ - ScreenPtr pScreen = pPicture->pDrawable->pScreen; -#ifdef RENDER - PictureScreenPtr ps = GetPictureScreen(pScreen); -#endif /* RENDER */ - EXA_PRE_FALLBACK(pScreen); - - EXA_FALLBACK(("to pict %p (%c)\n", - exaDrawableLocation(pPicture->pDrawable))); - exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST); -#ifdef RENDER - swap(pExaScr, ps, AddTraps); - ps->AddTraps (pPicture, x_off, y_off, ntrap, traps); - swap(pExaScr, ps, AddTraps); -#endif /* RENDER */ - exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST); - EXA_POST_FALLBACK(pScreen); -} - -/** - * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps - * that happen to be 1x1. Pixmap must be at least 8bpp. - */ -CARD32 -exaGetPixmapFirstPixel (PixmapPtr pPixmap) -{ - switch (pPixmap->drawable.bitsPerPixel) { - case 32: - { - CARD32 pixel; - - pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, - ZPixmap, ~0, (char*)&pixel); - return pixel; - } - case 16: - { - CARD16 pixel; - - pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, - ZPixmap, ~0, (char*)&pixel); - return pixel; - } - case 8: - { - CARD8 pixel; - - pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1, - ZPixmap, ~0, (char*)&pixel); - return pixel; - } - default: - FatalError("%s called for invalid bpp %d\n", __func__, - pPixmap->drawable.bitsPerPixel); - } -} +/*
+ *
+ * Copyright © 1999 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.
+ */
+
+#include "exa_priv.h"
+
+#ifdef RENDER
+#include "mipict.h"
+#endif
+
+/*
+ * These functions wrap the low-level fb rendering functions and
+ * synchronize framebuffer/accelerated drawing by stalling until
+ * the accelerator is idle
+ */
+
+/**
+ * Calls exaPrepareAccess with EXA_PREPARE_SRC for the tile, if that is the
+ * current fill style.
+ *
+ * Solid doesn't use an extra pixmap source, and Stippled/OpaqueStippled are
+ * 1bpp and never in fb, so we don't worry about them.
+ * We should worry about them for completeness sake and going forward.
+ */
+void
+exaPrepareAccessGC(GCPtr pGC)
+{
+ if (pGC->stipple)
+ exaPrepareAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
+ if (pGC->fillStyle == FillTiled)
+ exaPrepareAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
+}
+
+/**
+ * Finishes access to the tile in the GC, if used.
+ */
+void
+exaFinishAccessGC(GCPtr pGC)
+{
+ if (pGC->fillStyle == FillTiled)
+ exaFinishAccess(&pGC->tile.pixmap->drawable, EXA_PREPARE_SRC);
+ if (pGC->stipple)
+ exaFinishAccess(&pGC->stipple->drawable, EXA_PREPARE_MASK);
+}
+
+#if DEBUG_TRACE_FALL
+char
+exaDrawableLocation(DrawablePtr pDrawable)
+{
+ return exaDrawableIsOffscreen(pDrawable) ? 's' : 'm';
+}
+#endif /* DEBUG_TRACE_FALL */
+
+void
+ExaCheckFillSpans (DrawablePtr pDrawable, GCPtr pGC, int nspans,
+ DDXPointPtr ppt, int *pwidth, int fSorted)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->FillSpans (pDrawable, pGC, nspans, ppt, pwidth, fSorted);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckSetSpans (DrawablePtr pDrawable, GCPtr pGC, char *psrc,
+ DDXPointPtr ppt, int *pwidth, int nspans, int fSorted)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ pGC->ops->SetSpans (pDrawable, pGC, psrc, ppt, pwidth, nspans, fSorted);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPutImage (DrawablePtr pDrawable, GCPtr pGC, int depth,
+ int x, int y, int w, int h, int leftPad, int format,
+ char *bits)
+{
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+ ExaPixmapPriv(pPixmap);
+
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ if (!pExaScr->prepare_access_reg || !pExaPixmap->pDamage ||
+ exaGCReadsDestination(pDrawable, pGC->planemask, pGC->fillStyle,
+ pGC->alu, pGC->clientClipType))
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ else
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST,
+ DamagePendingRegion(pExaPixmap->pDamage));
+ pGC->ops->PutImage (pDrawable, pGC, depth, x, y, w, h, leftPad, format, bits);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckCopyNtoN (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ BoxPtr pbox, int nbox, int dx, int dy, Bool reverse,
+ Bool upsidedown, Pixel bitplane, void *closure)
+{
+ RegionRec reg;
+ int xoff, yoff;
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
+ exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
+
+ if (pExaScr->prepare_access_reg) {
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pSrc);
+
+ exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
+ REGION_INIT(pScreen, ®, pbox, nbox);
+ REGION_TRANSLATE(pScreen, ®, xoff + dx, yoff + dy);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, ®);
+ REGION_UNINIT(pScreen, ®);
+ } else
+ exaPrepareAccess (pSrc, EXA_PREPARE_SRC);
+
+ if (pExaScr->prepare_access_reg &&
+ !exaGCReadsDestination(pDst, pGC->planemask, pGC->fillStyle,
+ pGC->alu, pGC->clientClipType)) {
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDst);
+
+ exaGetDrawableDeltas(pSrc, pPixmap, &xoff, &yoff);
+ REGION_INIT(pScreen, ®, pbox, nbox);
+ REGION_TRANSLATE(pScreen, ®, xoff, yoff);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_DEST, ®);
+ REGION_UNINIT(pScreen, ®);
+ } else
+ exaPrepareAccess (pDst, EXA_PREPARE_DEST);
+
+ /* This will eventually call fbCopyNtoN, with some calculation overhead. */
+ while (nbox--) {
+ pGC->ops->CopyArea (pSrc, pDst, pGC, pbox->x1 - pSrc->x + dx, pbox->y1 - pSrc->y + dy,
+ pbox->x2 - pbox->x1, pbox->y2 - pbox->y1, pbox->x1 - pDst->x, pbox->y1 - pDst->y);
+ pbox++;
+ }
+ exaFinishAccess (pSrc, EXA_PREPARE_SRC);
+ exaFinishAccess (pDst, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+static void
+ExaFallbackPrepareReg(DrawablePtr pDrawable,
+ GCPtr pGC,
+ int x, int y, int width, int height,
+ int index, Bool checkReads)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ ExaScreenPriv(pScreen);
+
+ if (pExaScr->prepare_access_reg &&
+ !(checkReads && exaGCReadsDestination(pDrawable,
+ pGC->planemask,
+ pGC->fillStyle,
+ pGC->alu,
+ pGC->clientClipType))) {
+ BoxRec box;
+ RegionRec reg;
+ int xoff, yoff;
+ PixmapPtr pPixmap = exaGetDrawablePixmap(pDrawable);
+
+ exaGetDrawableDeltas(pDrawable, pPixmap, &xoff, &yoff);
+ box.x1 = pDrawable->x + x + xoff;
+ box.y1 = pDrawable->y + y + yoff;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+
+ REGION_INIT(pScreen, ®, &box, 1);
+ pExaScr->prepare_access_reg(pPixmap, index, ®);
+ REGION_UNINIT(pScreen, ®);
+ } else
+ exaPrepareAccess(pDrawable, index);
+}
+
+
+RegionPtr
+ExaCheckCopyArea (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty)
+{
+ RegionPtr ret;
+
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
+ exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
+ ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h,
+ EXA_PREPARE_SRC, FALSE);
+ ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h,
+ EXA_PREPARE_DEST, TRUE);
+ ret = pGC->ops->CopyArea (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty);
+ exaFinishAccess (pSrc, EXA_PREPARE_SRC);
+ exaFinishAccess (pDst, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+
+ return ret;
+}
+
+RegionPtr
+ExaCheckCopyPlane (DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC,
+ int srcx, int srcy, int w, int h, int dstx, int dsty,
+ unsigned long bitPlane)
+{
+ RegionPtr ret;
+
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("from %p to %p (%c,%c)\n", pSrc, pDst,
+ exaDrawableLocation(pSrc), exaDrawableLocation(pDst)));
+ ExaFallbackPrepareReg(pSrc, pGC, srcx, srcy, w, h,
+ EXA_PREPARE_SRC, FALSE);
+ ExaFallbackPrepareReg(pDst, pGC, dstx, dsty, w, h,
+ EXA_PREPARE_DEST, TRUE);
+ ret = pGC->ops->CopyPlane (pSrc, pDst, pGC, srcx, srcy, w, h, dstx, dsty,
+ bitPlane);
+ exaFinishAccess (pSrc, EXA_PREPARE_SRC);
+ exaFinishAccess (pDst, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+
+ return ret;
+}
+
+void
+ExaCheckPolyPoint (DrawablePtr pDrawable, GCPtr pGC, int mode, int npt,
+ DDXPointPtr pptInit)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ pGC->ops->PolyPoint (pDrawable, pGC, mode, npt, pptInit);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPolylines (DrawablePtr pDrawable, GCPtr pGC,
+ int mode, int npt, DDXPointPtr ppt)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c), width %d, mode %d, count %d\n",
+ pDrawable, exaDrawableLocation(pDrawable),
+ pGC->lineWidth, mode, npt));
+
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->Polylines (pDrawable, pGC, mode, npt, ppt);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPolySegment (DrawablePtr pDrawable, GCPtr pGC,
+ int nsegInit, xSegment *pSegInit)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c) width %d, count %d\n", pDrawable,
+ exaDrawableLocation(pDrawable), pGC->lineWidth, nsegInit));
+
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->PolySegment (pDrawable, pGC, nsegInit, pSegInit);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPolyArc (DrawablePtr pDrawable, GCPtr pGC,
+ int narcs, xArc *pArcs)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->PolyArc (pDrawable, pGC, narcs, pArcs);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPolyFillRect (DrawablePtr pDrawable, GCPtr pGC,
+ int nrect, xRectangle *prect)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->PolyFillRect (pDrawable, pGC, nrect, prect);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckImageGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c)\n", pDrawable,
+ exaDrawableLocation(pDrawable)));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->ImageGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPolyGlyphBlt (DrawablePtr pDrawable, GCPtr pGC,
+ int x, int y, unsigned int nglyph,
+ CharInfoPtr *ppci, pointer pglyphBase)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("to %p (%c), style %d alu %d\n", pDrawable,
+ exaDrawableLocation(pDrawable), pGC->fillStyle, pGC->alu));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_DEST);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->PolyGlyphBlt (pDrawable, pGC, x, y, nglyph, ppci, pglyphBase);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckPushPixels (GCPtr pGC, PixmapPtr pBitmap,
+ DrawablePtr pDrawable,
+ int w, int h, int x, int y)
+{
+ EXA_PRE_FALLBACK_GC(pGC);
+ EXA_FALLBACK(("from %p to %p (%c,%c)\n", pBitmap, pDrawable,
+ exaDrawableLocation(&pBitmap->drawable),
+ exaDrawableLocation(pDrawable)));
+ ExaFallbackPrepareReg(pDrawable, pGC, x, y, w, h,
+ EXA_PREPARE_DEST, TRUE);
+ ExaFallbackPrepareReg(&pBitmap->drawable, pGC, 0, 0, w, h,
+ EXA_PREPARE_SRC, FALSE);
+ exaPrepareAccessGC (pGC);
+ pGC->ops->PushPixels (pGC, pBitmap, pDrawable, w, h, x, y);
+ exaFinishAccessGC (pGC);
+ exaFinishAccess (&pBitmap->drawable, EXA_PREPARE_SRC);
+ exaFinishAccess (pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK_GC(pGC);
+}
+
+void
+ExaCheckCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ DrawablePtr pDrawable = &pWin->drawable;
+ ScreenPtr pScreen = pDrawable->pScreen;
+ EXA_PRE_FALLBACK(pScreen);
+ EXA_FALLBACK(("from %p\n", pWin));
+
+ /* Only need the source bits, the destination region will be overwritten */
+ if (pExaScr->prepare_access_reg) {
+ PixmapPtr pPixmap = pScreen->GetWindowPixmap(pWin);
+ int xoff, yoff;
+
+ exaGetDrawableDeltas(&pWin->drawable, pPixmap, &xoff, &yoff);
+ REGION_TRANSLATE(pScreen, prgnSrc, xoff, yoff);
+ pExaScr->prepare_access_reg(pPixmap, EXA_PREPARE_SRC, prgnSrc);
+ REGION_TRANSLATE(pScreen, prgnSrc, -xoff, -yoff);
+ } else
+ exaPrepareAccess(pDrawable, EXA_PREPARE_SRC);
+
+ swap(pExaScr, pScreen, CopyWindow);
+ pScreen->CopyWindow (pWin, ptOldOrg, prgnSrc);
+ swap(pExaScr, pScreen, CopyWindow);
+ exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+ EXA_POST_FALLBACK(pScreen);
+}
+
+void
+ExaCheckGetImage(DrawablePtr pDrawable, int x, int y, int w, int h,
+ unsigned int format, unsigned long planeMask, char *d)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ EXA_PRE_FALLBACK(pScreen);
+ EXA_FALLBACK(("from %p (%c)\n", pDrawable,
+ exaDrawableLocation(pDrawable)));
+
+ ExaFallbackPrepareReg(pDrawable, NULL, x, y, w, h,
+ EXA_PREPARE_SRC, FALSE);
+ swap(pExaScr, pScreen, GetImage);
+ pScreen->GetImage (pDrawable, x, y, w, h, format, planeMask, d);
+ swap(pExaScr, pScreen, GetImage);
+ exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+ EXA_POST_FALLBACK(pScreen);
+}
+
+void
+ExaCheckGetSpans (DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr ppt,
+ int *pwidth,
+ int nspans,
+ char *pdstStart)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+
+ EXA_PRE_FALLBACK(pScreen);
+ EXA_FALLBACK(("from %p (%c)\n", pDrawable, exaDrawableLocation(pDrawable)));
+ exaPrepareAccess (pDrawable, EXA_PREPARE_SRC);
+ swap(pExaScr, pScreen, GetSpans);
+ pScreen->GetSpans (pDrawable, wMax, ppt, pwidth, nspans, pdstStart);
+ swap(pExaScr, pScreen, GetSpans);
+ exaFinishAccess (pDrawable, EXA_PREPARE_SRC);
+ EXA_POST_FALLBACK(pScreen);
+}
+
+static void
+ExaSrcValidate(DrawablePtr pDrawable,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ ScreenPtr pScreen = pDrawable->pScreen;
+ ExaScreenPriv(pScreen);
+ PixmapPtr pPix = exaGetDrawablePixmap (pDrawable);
+ BoxRec box;
+ RegionRec reg;
+ RegionPtr dst;
+ int xoff, yoff;
+
+ exaGetDrawableDeltas(pDrawable, pPix, &xoff, &yoff);
+
+ box.x1 = x + xoff;
+ box.y1 = y + yoff;
+ box.x2 = box.x1 + width;
+ box.y2 = box.y1 + height;
+
+ dst = (pExaScr->srcPix == pPix) ? &pExaScr->srcReg :
+ &pExaScr->maskReg;
+
+ REGION_INIT(pScreen, ®, &box, 1);
+ REGION_UNION(pScreen, dst, dst, ®);
+ REGION_UNINIT(pScreen, ®);
+
+ swap(pExaScr, pScreen, SourceValidate);
+ pScreen->SourceValidate(pDrawable, x, y, width, height);
+ swap(pExaScr, pScreen, SourceValidate);
+}
+
+static Bool
+ExaPrepareCompositeReg(ScreenPtr pScreen,
+ CARD8 op,
+ PicturePtr pSrc,
+ PicturePtr pMask,
+ PicturePtr pDst,
+ INT16 xSrc,
+ INT16 ySrc,
+ INT16 xMask,
+ INT16 yMask,
+ INT16 xDst,
+ INT16 yDst,
+ CARD16 width,
+ CARD16 height)
+{
+ RegionRec region;
+ RegionPtr dstReg = NULL;
+ RegionPtr srcReg = NULL;
+ RegionPtr maskReg = NULL;
+ PixmapPtr pSrcPix = NULL;
+ PixmapPtr pMaskPix = NULL;
+ PixmapPtr pDstPix;
+ ExaScreenPriv(pScreen);
+ Bool ret;
+
+
+ REGION_NULL(pScreen, ®ion);
+
+ if (pSrc->pDrawable) {
+ pSrcPix = exaGetDrawablePixmap(pSrc->pDrawable);
+ REGION_NULL(pScreen, &pExaScr->srcReg);
+ srcReg = &pExaScr->srcReg;
+ pExaScr->srcPix = pSrcPix;
+ if (pSrc != pDst)
+ REGION_TRANSLATE(pScreen, pSrc->pCompositeClip,
+ -pSrc->pDrawable->x,
+ -pSrc->pDrawable->y);
+ }
+
+ if (pMask && pMask->pDrawable) {
+ pMaskPix = exaGetDrawablePixmap(pMask->pDrawable);
+ REGION_NULL(pScreen, &pExaScr->maskReg);
+ maskReg = &pExaScr->maskReg;
+ if (pMask != pDst && pMask != pSrc)
+ REGION_TRANSLATE(pScreen, pMask->pCompositeClip,
+ -pMask->pDrawable->x,
+ -pMask->pDrawable->y);
+ }
+
+ REGION_TRANSLATE(pScreen, pDst->pCompositeClip,
+ -pDst->pDrawable->x,
+ -pDst->pDrawable->y);
+
+ pExaScr->SavedSourceValidate = ExaSrcValidate;
+ swap(pExaScr, pScreen, SourceValidate);
+ ret = miComputeCompositeRegion (®ion, pSrc, pMask, pDst,
+ xSrc, ySrc, xMask, yMask,
+ xDst,
+ yDst,
+ width, height);
+ swap(pExaScr, pScreen, SourceValidate);
+
+ REGION_TRANSLATE(pScreen, pDst->pCompositeClip,
+ pDst->pDrawable->x,
+ pDst->pDrawable->y);
+ if (pSrc->pDrawable && pSrc != pDst)
+ REGION_TRANSLATE(pScreen, pSrc->pCompositeClip,
+ pSrc->pDrawable->x,
+ pSrc->pDrawable->y);
+ if (pMask && pMask->pDrawable && pMask != pDst && pMask != pSrc)
+ REGION_TRANSLATE(pScreen, pMask->pCompositeClip,
+ pMask->pDrawable->x,
+ pMask->pDrawable->y);
+
+ if (!ret) {
+ if (srcReg)
+ REGION_UNINIT(pScreen, srcReg);
+ if (maskReg)
+ REGION_UNINIT(pScreen, maskReg);
+
+ return FALSE;
+ }
+
+ /**
+ * Don't limit alphamaps readbacks for now until we've figured out how that
+ * should be done.
+ */
+
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
+ pExaScr->prepare_access_reg(exaGetDrawablePixmap(pSrc->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_SRC,
+ NULL);
+ if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+ pExaScr->prepare_access_reg(exaGetDrawablePixmap(pMask->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_MASK,
+ NULL);
+
+ if (pSrcPix)
+ pExaScr->prepare_access_reg(pSrcPix,
+ EXA_PREPARE_SRC,
+ srcReg);
+
+ if (pMaskPix)
+ pExaScr->prepare_access_reg(pMaskPix,
+ EXA_PREPARE_MASK,
+ maskReg);
+
+ if (srcReg)
+ REGION_UNINIT(pScreen, srcReg);
+ if (maskReg)
+ REGION_UNINIT(pScreen, maskReg);
+
+ pDstPix = exaGetDrawablePixmap(pDst->pDrawable);
+ if (!exaOpReadsDestination(op)) {
+ int xoff;
+ int yoff;
+
+ exaGetDrawableDeltas (pDst->pDrawable, pDstPix, &xoff, &yoff);
+ REGION_TRANSLATE(pScreen, ®ion, pDst->pDrawable->x + xoff,
+ pDst->pDrawable->y + yoff);
+ dstReg = ®ion;
+ }
+
+ if (pDst->alphaMap && pDst->alphaMap->pDrawable)
+ pExaScr->prepare_access_reg(exaGetDrawablePixmap(pDst->alphaMap->pDrawable),
+ EXA_PREPARE_AUX_DEST,
+ dstReg);
+ pExaScr->prepare_access_reg(pDstPix, EXA_PREPARE_DEST, dstReg);
+
+ REGION_UNINIT(pScreen, ®ion);
+ return TRUE;
+}
+
+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)
+{
+ ScreenPtr pScreen = pDst->pDrawable->pScreen;
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+#endif /* RENDER */
+ EXA_PRE_FALLBACK(pScreen);
+
+ if (pExaScr->prepare_access_reg) {
+ if (!ExaPrepareCompositeReg(pScreen, op, pSrc, pMask, pDst, xSrc,
+ ySrc, xMask, yMask, xDst, yDst, width,
+ height))
+ goto out_no_clip;
+ } else {
+
+ /* We need to prepare access to any separate alpha maps first,
+ * in case the driver doesn't support EXA_PREPARE_AUX*,
+ * in which case EXA_PREPARE_SRC may be used for moving them out.
+ */
+
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
+ exaPrepareAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
+ if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+ exaPrepareAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
+ if (pDst->alphaMap && pDst->alphaMap->pDrawable)
+ exaPrepareAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
+
+ exaPrepareAccess (pDst->pDrawable, EXA_PREPARE_DEST);
+
+ EXA_FALLBACK(("from picts %p/%p to pict %p\n",
+ pSrc, pMask, pDst));
+
+ if (pSrc->pDrawable != NULL)
+ exaPrepareAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
+ if (pMask && pMask->pDrawable != NULL)
+ exaPrepareAccess (pMask->pDrawable, EXA_PREPARE_MASK);
+ }
+
+#ifdef RENDER
+ swap(pExaScr, ps, Composite);
+ ps->Composite (op,
+ pSrc,
+ pMask,
+ pDst,
+ xSrc,
+ ySrc,
+ xMask,
+ yMask,
+ xDst,
+ yDst,
+ width,
+ height);
+ swap(pExaScr, ps, Composite);
+#endif /* RENDER */
+ if (pMask && pMask->pDrawable != NULL)
+ exaFinishAccess (pMask->pDrawable, EXA_PREPARE_MASK);
+ if (pSrc->pDrawable != NULL)
+ exaFinishAccess (pSrc->pDrawable, EXA_PREPARE_SRC);
+ exaFinishAccess (pDst->pDrawable, EXA_PREPARE_DEST);
+ if (pDst->alphaMap && pDst->alphaMap->pDrawable)
+ exaFinishAccess(pDst->alphaMap->pDrawable, EXA_PREPARE_AUX_DEST);
+ if (pSrc->alphaMap && pSrc->alphaMap->pDrawable)
+ exaFinishAccess(pSrc->alphaMap->pDrawable, EXA_PREPARE_AUX_SRC);
+ if (pMask && pMask->alphaMap && pMask->alphaMap->pDrawable)
+ exaFinishAccess(pMask->alphaMap->pDrawable, EXA_PREPARE_AUX_MASK);
+
+out_no_clip:
+ EXA_POST_FALLBACK(pScreen);
+}
+
+void
+ExaCheckAddTraps (PicturePtr pPicture,
+ INT16 x_off,
+ INT16 y_off,
+ int ntrap,
+ xTrap *traps)
+{
+ ScreenPtr pScreen = pPicture->pDrawable->pScreen;
+#ifdef RENDER
+ PictureScreenPtr ps = GetPictureScreen(pScreen);
+#endif /* RENDER */
+ EXA_PRE_FALLBACK(pScreen);
+
+ EXA_FALLBACK(("to pict %p (%c)\n",
+ exaDrawableLocation(pPicture->pDrawable)));
+ exaPrepareAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+#ifdef RENDER
+ swap(pExaScr, ps, AddTraps);
+ ps->AddTraps (pPicture, x_off, y_off, ntrap, traps);
+ swap(pExaScr, ps, AddTraps);
+#endif /* RENDER */
+ exaFinishAccess(pPicture->pDrawable, EXA_PREPARE_DEST);
+ EXA_POST_FALLBACK(pScreen);
+}
+
+/**
+ * Gets the 0,0 pixel of a pixmap. Used for doing solid fills of tiled pixmaps
+ * that happen to be 1x1. Pixmap must be at least 8bpp.
+ */
+CARD32
+exaGetPixmapFirstPixel (PixmapPtr pPixmap)
+{
+ switch (pPixmap->drawable.bitsPerPixel) {
+ case 32:
+ {
+ CARD32 pixel;
+
+ pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
+ ZPixmap, ~0, (char*)&pixel);
+ return pixel;
+ }
+ case 16:
+ {
+ CARD16 pixel;
+
+ pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
+ ZPixmap, ~0, (char*)&pixel);
+ return pixel;
+ }
+ case 8:
+ {
+ CARD8 pixel;
+
+ pPixmap->drawable.pScreen->GetImage(&pPixmap->drawable, 0, 0, 1, 1,
+ ZPixmap, ~0, (char*)&pixel);
+ return pixel;
+ }
+ default:
+ FatalError("%s called for invalid bpp %d\n", __FUNCTION__,
+ pPixmap->drawable.bitsPerPixel);
+ }
+}
diff --git a/xorg-server/exa/makefile b/xorg-server/exa/makefile new file mode 100644 index 000000000..5ad11a1ed --- /dev/null +++ b/xorg-server/exa/makefile @@ -0,0 +1,14 @@ +LIBRARY=libexa
+
+CSRCS = \
+ exa.c \
+ exa_classic.c \
+ exa_migration_classic.c \
+ exa_driver.c \
+ exa_mixed.c \
+ exa_migration_mixed.c \
+ exa_accel.c \
+ exa_glyphs.c \
+ exa_offscreen.c \
+ exa_render.c \
+ exa_unaccel.c
diff --git a/xorg-server/fb/fbpict.c b/xorg-server/fb/fbpict.c index 98286e1a3..cc7ce738d 100644 --- a/xorg-server/fb/fbpict.c +++ b/xorg-server/fb/fbpict.c @@ -31,9 +31,10 @@ #include "fb.h"
+#include "picturestr.h"
+
#ifdef RENDER
-#include "picturestr.h"
#include "mipict.h"
#include "fbpict.h"
diff --git a/xorg-server/fb/fbpixmap.c b/xorg-server/fb/fbpixmap.c index 311da9e62..c4c2c4aa7 100644 --- a/xorg-server/fb/fbpixmap.c +++ b/xorg-server/fb/fbpixmap.c @@ -323,11 +323,7 @@ fbPixmapToRegion(PixmapPtr pPix) #ifdef FB_DEBUG -#ifndef WIN32 #include <stdio.h> -#else -#include <dbg.h> -#endif static Bool fbValidateBits (FbStip *bits, int stride, FbStip data) @@ -336,12 +332,7 @@ fbValidateBits (FbStip *bits, int stride, FbStip data) { 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 + fprintf (stderr, "fbValidateBits failed at 0x%x (is 0x%x want 0x%x)\n",bits, *bits, data); return FALSE; } bits++; diff --git a/xorg-server/fb/makefile b/xorg-server/fb/makefile new file mode 100644 index 000000000..717c07332 --- /dev/null +++ b/xorg-server/fb/makefile @@ -0,0 +1,37 @@ +
+LIBRARY=libfb
+
+CCFLAGS:=$(CCFLAGS:-RTCc=)
+
+
+CSRCS = \
+ fb24_32.c \
+ fballpriv.c \
+ fbarc.c \
+ fbbits.c \
+ fbblt.c \
+ fbbltone.c \
+ fbcopy.c \
+ fbfill.c \
+ fbfillrect.c \
+ fbfillsp.c \
+ fbgc.c \
+ fbgetsp.c \
+ fbglyph.c \
+ fbimage.c \
+ fbline.c \
+ fboverlay.c \
+ fbpict.c \
+ fbpixmap.c \
+ fbpoint.c \
+ fbpush.c \
+ fbscreen.c \
+ fbseg.c \
+ fbsetsp.c \
+ fbsolid.c \
+ fbstipple.c \
+ fbtile.c \
+ fbtrap.c \
+ fbutil.c \
+ fbwindow.c \
+ fbcmap_mi.c
diff --git a/xorg-server/fonts.src/100dpi/makefile b/xorg-server/fonts.src/100dpi/makefile new file mode 100644 index 000000000..24057f7e6 --- /dev/null +++ b/xorg-server/fonts.src/100dpi/makefile @@ -0,0 +1,352 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +INC_BDF_RULES=1 + +all: $(BDFTOPCF) + +DESTDIR=$(MHMAKECONF)\xorg-server\fonts\100dpi + +BDF2UCS_FONT_FILES = \ + lutBS08 \ + lutBS10 \ + lutBS12 \ + lutBS14 \ + lutBS18 \ + lutBS19 \ + lutBS24 \ + lutRS08 \ + lutRS10 \ + lutRS12 \ + lutRS14 \ + lutRS18 \ + lutRS19 \ + lutRS24 \ + lubB08 \ + lubB10 \ + lubB12 \ + lubB14 \ + lubB18 \ + lubB19 \ + lubB24 \ + lubBI08 \ + lubBI10 \ + lubBI12 \ + lubBI14 \ + lubBI18 \ + lubBI19 \ + lubBI24 \ + lubI08 \ + lubI10 \ + lubI12 \ + lubI14 \ + lubI18 \ + lubI19 \ + lubI24 \ + luBIS08 \ + luBIS10 \ + luBIS12 \ + luBIS14 \ + luBIS18 \ + luBIS19 \ + luBIS24 \ + lubR08 \ + lubR10 \ + lubR12 \ + lubR14 \ + lubR18 \ + lubR19 \ + lubR24 \ + luBS08 \ + luBS10 \ + luBS12 \ + luBS14 \ + luBS18 \ + luBS19 \ + luBS24 \ + luIS08 \ + luIS10 \ + luIS12 \ + luIS14 \ + luIS18 \ + luIS19 \ + luIS24 \ + luRS08 \ + luRS10 \ + luRS12 \ + luRS14 \ + luRS18 \ + luRS19 \ + luRS24 \ + UTB___10 \ + UTB___12 \ + UTB___14 \ + UTB___18 \ + UTB___24 \ + UTBI__10 \ + UTBI__12 \ + UTBI__14 \ + UTBI__18 \ + UTBI__24 \ + UTI___10 \ + UTI___12 \ + UTI___14 \ + UTI___18 \ + UTI___24 \ + UTRG__10 \ + UTRG__12 \ + UTRG__14 \ + UTRG__18 \ + UTRG__24 \ + courB08 \ + courB10 \ + courB12 \ + courB14 \ + courB18 \ + courB24 \ + courBO08 \ + courBO10 \ + courBO12 \ + courBO14 \ + courBO18 \ + courBO24 \ + courO08 \ + courO10 \ + courO12 \ + courO14 \ + courO18 \ + courO24 \ + courR08 \ + courR10 \ + courR12 \ + courR14 \ + courR18 \ + courR24 \ + helvB08 \ + helvB10 \ + helvB12 \ + helvB14 \ + helvB18 \ + helvB24 \ + helvBO08 \ + helvBO10 \ + helvBO12 \ + helvBO14 \ + helvBO18 \ + helvBO24 \ + helvO08 \ + helvO10 \ + helvO12 \ + helvO14 \ + helvO18 \ + helvO24 \ + helvR08 \ + helvR10 \ + helvR12 \ + helvR14 \ + helvR18 \ + helvR24 \ + ncenB08 \ + ncenB10 \ + ncenB12 \ + ncenB14 \ + ncenB18 \ + ncenB24 \ + ncenBI08 \ + ncenBI10 \ + ncenBI12 \ + ncenBI14 \ + ncenBI18 \ + ncenBI24 \ + ncenI08 \ + ncenI10 \ + ncenI12 \ + ncenI14 \ + ncenI18 \ + ncenI24 \ + ncenR08 \ + ncenR10 \ + ncenR12 \ + ncenR14 \ + ncenR18 \ + ncenR24 \ + timB08 \ + timB10 \ + timB12 \ + timB14 \ + timB18 \ + timB24 \ + timBI08 \ + timBI10 \ + timBI12 \ + timBI14 \ + timBI18 \ + timBI24 \ + timI08 \ + timI10 \ + timI12 \ + timI14 \ + timI18 \ + timI24 \ + timR08 \ + timR10 \ + timR12 \ + timR14 \ + timR18 \ + timR24 +EXTRA_FONT_FILES = \ + symb08 \ + symb10 \ + symb12 \ + symb14 \ + symb18 \ + symb24 \ + charB08 \ + charB10 \ + charB12 \ + charB14 \ + charB18 \ + charB24 \ + charBI08 \ + charBI10 \ + charBI12 \ + charBI14 \ + charBI18 \ + charBI24 \ + charI08 \ + charI10 \ + charI12 \ + charI14 \ + charI18 \ + charI24 \ + charR08 \ + charR10 \ + charR12 \ + charR14 \ + charR18 \ + charR24 \ + tech14 \ + techB14 \ + term14 \ + termB14 +FONT_FILES = $(BDF2UCS_FONT_FILES) $(EXTRA_FONT_FILES) + +BDF_FILES = $(FONT_FILES:%=%.bdf) +PCF_FILES = $(FONT_FILES:%=$(DESTDIR)\%.pcf.gz) + +ISO8859_1_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-1.pcf.gz) + +ISO8859_2_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-2.pcf.gz) + +ISO8859_3_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-3.pcf.gz) + +ISO8859_4_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-4.pcf.gz) + +ISO8859_9_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-9.pcf.gz) + +ISO8859_10_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-10.pcf.gz) + +ISO8859_13_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-13.pcf.gz) + +ISO8859_14_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-14.pcf.gz) + +ISO8859_15_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-15.pcf.gz) + +UTIL_DIR = ..\font-util +UCS2ANY = $(UTIL_DIR)\$(OBJDIR)\ucs2any.exe + +load_makefile $(UTIL_DIR)\makefile MAKESERVER=0 DEBUG=$(DEBUG) + +$(DESTDIR)\%-ISO8859-1.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-1.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-1 ISO8859-1 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-1.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-1.bdf) + +$(DESTDIR)\%-ISO8859-2.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-2.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-2 ISO8859-2 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-2.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-2.bdf) + +$(DESTDIR)\%-ISO8859-3.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-3.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-3 ISO8859-3 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-3.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-3.bdf) + +$(DESTDIR)\%-ISO8859-4.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-4.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-4 ISO8859-4 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-4.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-4.bdf) + +$(DESTDIR)\%-ISO8859-9.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-9.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-9 ISO8859-9 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-9.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-9.bdf) + +$(DESTDIR)\%-ISO8859-10.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-10.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-10 ISO8859-10 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-10.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-10.bdf) + +$(DESTDIR)\%-ISO8859-13.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-13.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-13 ISO8859-13 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-13.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-13.bdf) + +$(DESTDIR)\%-ISO8859-14.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-14.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-14 ISO8859-14 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-14.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-14.bdf) + +$(DESTDIR)\%-ISO8859-15.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-15.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-15 ISO8859-15 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-15.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-15.bdf) + +font_DATA = \ + $(PCF_FILES) \ + $(ISO8859_1_PCF_FILES) \ + $(ISO8859_2_PCF_FILES) \ + $(ISO8859_3_PCF_FILES) \ + $(ISO8859_4_PCF_FILES) \ + $(ISO8859_9_PCF_FILES) \ + $(ISO8859_10_PCF_FILES) \ + $(ISO8859_13_PCF_FILES) \ + $(ISO8859_14_PCF_FILES) \ + $(ISO8859_15_PCF_FILES) + +all: $(DESTDIR) $(UCS2ANY) $(DESTDIR)\fonts.scale $(DESTDIR)\fonts.dir $(DESTDIR)\fonts.alias + +MKFONTSCALE=$(MHMAKECONF)\mkfontscale\$(OBJDIR)\mkfontscale.exe + +load_makefile $(MHMAKECONF)\mkfontscale\makefile MAKESERVER=0 DEBUG=$(DEBUG) + +$(DESTDIR)\fonts.scale: $(font_DATA) $(MKFONTSCALE) + del -e $@ + cd $(DESTDIR) & $(MKFONTSCALE) . + +$(DESTDIR)\fonts.dir: $(font_DATA) $(MKFONTSCALE) + del -e $@ + cd $(DESTDIR) & $(MKFONTSCALE) -b -s -l . + +$(DESTDIR)\fonts.alias: fonts.alias + copy $< $@ + diff --git a/xorg-server/fonts.src/75dpi/makefile b/xorg-server/fonts.src/75dpi/makefile new file mode 100644 index 000000000..e5c8002f0 --- /dev/null +++ b/xorg-server/fonts.src/75dpi/makefile @@ -0,0 +1,348 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +INC_BDF_RULES=1 + +all: $(BDFTOPCF) + +DESTDIR=$(MHMAKECONF)\xorg-server\fonts\75dpi + +BDF2UCS_FONT_FILES = \ + lutBS08 \ + lutBS10 \ + lutBS12 \ + lutBS14 \ + lutBS18 \ + lutBS19 \ + lutBS24 \ + lutRS08 \ + lutRS10 \ + lutRS12 \ + lutRS14 \ + lutRS18 \ + lutRS19 \ + lutRS24 \ + UTB___10 \ + UTB___12 \ + UTB___14 \ + UTB___18 \ + UTB___24 \ + UTBI__10 \ + UTBI__12 \ + UTBI__14 \ + UTBI__18 \ + UTBI__24 \ + UTI___10 \ + UTI___12 \ + UTI___14 \ + UTI___18 \ + UTI___24 \ + UTRG__10 \ + UTRG__12 \ + UTRG__14 \ + UTRG__18 \ + UTRG__24 \ + courB08 \ + courB10 \ + courB12 \ + courB14 \ + courB18 \ + courB24 \ + courBO08 \ + courBO10 \ + courBO12 \ + courBO14 \ + courBO18 \ + courBO24 \ + courO08 \ + courO10 \ + courO12 \ + courO14 \ + courO18 \ + courO24 \ + courR08 \ + courR10 \ + courR12 \ + courR14 \ + courR18 \ + courR24 \ + helvB08 \ + helvB10 \ + helvB12 \ + helvB14 \ + helvB18 \ + helvB24 \ + helvBO08 \ + helvBO10 \ + helvBO12 \ + helvBO14 \ + helvBO18 \ + helvBO24 \ + helvO08 \ + helvO10 \ + helvO12 \ + helvO14 \ + helvO18 \ + helvO24 \ + helvR08 \ + helvR10 \ + helvR12 \ + helvR14 \ + helvR18 \ + helvR24 \ + ncenB08 \ + ncenB10 \ + ncenB12 \ + ncenB14 \ + ncenB18 \ + ncenB24 \ + ncenBI08 \ + ncenBI10 \ + ncenBI12 \ + ncenBI14 \ + ncenBI18 \ + ncenBI24 \ + ncenI08 \ + ncenI10 \ + ncenI12 \ + ncenI14 \ + ncenI18 \ + ncenI24 \ + ncenR08 \ + ncenR10 \ + ncenR12 \ + ncenR14 \ + ncenR18 \ + ncenR24 \ + timB08 \ + timB10 \ + timB12 \ + timB14 \ + timB18 \ + timB24 \ + timBI08 \ + timBI10 \ + timBI12 \ + timBI14 \ + timBI18 \ + timBI24 \ + timI08 \ + timI10 \ + timI12 \ + timI14 \ + timI18 \ + timI24 \ + timR08 \ + timR10 \ + timR12 \ + timR14 \ + timR18 \ + timR24 \ + lubB08 \ + lubB10 \ + lubB12 \ + lubB14 \ + lubB18 \ + lubB19 \ + lubB24 \ + lubBI08 \ + lubBI10 \ + lubBI12 \ + lubBI14 \ + lubBI18 \ + lubBI19 \ + lubBI24 \ + lubI08 \ + lubI10 \ + lubI12 \ + lubI14 \ + lubI18 \ + lubI19 \ + lubI24 \ + luBIS08 \ + luBIS10 \ + luBIS12 \ + luBIS14 \ + luBIS18 \ + luBIS19 \ + luBIS24 \ + lubR08 \ + lubR10 \ + lubR12 \ + lubR14 \ + lubR18 \ + lubR19 \ + lubR24 \ + luBS08 \ + luBS10 \ + luBS12 \ + luBS14 \ + luBS18 \ + luBS19 \ + luBS24 \ + luIS08 \ + luIS10 \ + luIS12 \ + luIS14 \ + luIS18 \ + luIS19 \ + luIS24 \ + luRS08 \ + luRS10 \ + luRS12 \ + luRS14 \ + luRS18 \ + luRS19 \ + luRS24 +EXTRA_FONT_FILES = \ + charB08 \ + charB10 \ + charB12 \ + charB14 \ + charB18 \ + charB24 \ + charBI08 \ + charBI10 \ + charBI12 \ + charBI14 \ + charBI18 \ + charBI24 \ + charI08 \ + charI10 \ + charI12 \ + charI14 \ + charI18 \ + charI24 \ + charR08 \ + charR10 \ + charR12 \ + charR14 \ + charR18 \ + charR24 \ + tech14 \ + techB14 \ + term14 \ + termB14 \ + symb08 \ + symb10 \ + symb12 \ + symb14 \ + symb18 \ + symb24 +FONT_FILES = $(BDF2UCS_FONT_FILES) $(EXTRA_FONT_FILES) + +BDF_FILES = $(FONT_FILES:%=%.bdf) +PCF_FILES = $(FONT_FILES:%=$(DESTDIR)\%.pcf.gz) + +ISO8859_1_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-1.pcf.gz) + +ISO8859_2_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-2.pcf.gz) + +ISO8859_3_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-3.pcf.gz) + +ISO8859_4_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-4.pcf.gz) + +ISO8859_9_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-9.pcf.gz) + +ISO8859_10_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-10.pcf.gz) + +ISO8859_13_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-13.pcf.gz) + +ISO8859_14_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-14.pcf.gz) + +ISO8859_15_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-15.pcf.gz) + +UTIL_DIR = ..\font-util +UCS2ANY = $(UTIL_DIR)\$(OBJDIR)\ucs2any.exe + +load_makefile $(UTIL_DIR)\makefile MAKESERVER=0 DEBUG=$(DEBUG) + +$(DESTDIR)\%-ISO8859-1.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-1.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-1 ISO8859-1 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-1.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-1.bdf) + +$(DESTDIR)\%-ISO8859-2.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-2.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-2 ISO8859-2 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-2.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-2.bdf) + +$(DESTDIR)\%-ISO8859-3.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-3.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-3 ISO8859-3 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-3.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-3.bdf) + +$(DESTDIR)\%-ISO8859-4.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-4.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-4 ISO8859-4 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-4.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-4.bdf) + +$(DESTDIR)\%-ISO8859-9.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-9.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-9 ISO8859-9 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-9.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-9.bdf) + +$(DESTDIR)\%-ISO8859-10.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-10.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-10 ISO8859-10 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-10.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-10.bdf) + +$(DESTDIR)\%-ISO8859-13.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-13.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-13 ISO8859-13 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-13.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-13.bdf) + +$(DESTDIR)\%-ISO8859-14.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-14.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-14 ISO8859-14 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-14.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-14.bdf) + +$(DESTDIR)\%-ISO8859-15.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-15.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-15 ISO8859-15 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-15.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-15.bdf) + +font_DATA = \ + $(PCF_FILES) \ + $(ISO8859_1_PCF_FILES) \ + $(ISO8859_2_PCF_FILES) \ + $(ISO8859_3_PCF_FILES) \ + $(ISO8859_4_PCF_FILES) \ + $(ISO8859_9_PCF_FILES) \ + $(ISO8859_10_PCF_FILES) \ + $(ISO8859_13_PCF_FILES) \ + $(ISO8859_14_PCF_FILES) \ + $(ISO8859_15_PCF_FILES) + +all: $(DESTDIR) $(UCS2ANY) $(DESTDIR)\fonts.scale $(DESTDIR)\fonts.dir $(DESTDIR)\fonts.alias + +$(DESTDIR)\fonts.scale: $(font_DATA) $(MKFONTSCALE) + del -e $@ + cd $(DESTDIR) & $(MKFONTSCALE) . + +$(DESTDIR)\fonts.dir: $(font_DATA) $(MKFONTSCALE) + del -e $@ + cd $(DESTDIR) & $(MKFONTSCALE) -b -s -l . + +$(DESTDIR)\fonts.alias: fonts.alias + copy $< $@ + diff --git a/xorg-server/fonts.src/OTF/makefile b/xorg-server/fonts.src/OTF/makefile new file mode 100644 index 000000000..d546e354e --- /dev/null +++ b/xorg-server/fonts.src/OTF/makefile @@ -0,0 +1,53 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +INC_BDF_RULES=1 + +DESTDIR=$(MHMAKECONF)\xorg-server\fonts\OTF + +FONT_FILES = \ + SyrCOMAdiabene.otf \ + SyrCOMAntioch.otf \ + SyrCOMBatnanBold.otf \ + SyrCOMBatnan.otf \ + SyrCOMCtesiphon.otf \ + SyrCOMEdessa.otf \ + SyrCOMJerusalemBold.otf \ + SyrCOMJerusalemItalic.otf \ + SyrCOMJerusalem.otf \ + SyrCOMJerusalemOutline.otf \ + SyrCOMKharput.otf \ + SyrCOMMalankara.otf \ + SyrCOMMardinBold.otf \ + SyrCOMMardin.otf \ + SyrCOMMidyat.otf \ + SyrCOMNisibin.otf \ + SyrCOMNisibinOutline.otf \ + SyrCOMQenNeshrin.otf \ + SyrCOMTalada.otf \ + SyrCOMTurAbdin.otf \ + SyrCOMUrhoyBold.otf \ + SyrCOMUrhoy.otf \ + GohaTibebZemen.otf + +fontdir = . +font_DATA = $(FONT_FILES:%=$(DESTDIR)\%) + +all: $(DESTDIR) $(DESTDIR)\fonts.scale $(DESTDIR)\fonts.dir + +MKFONTSCALE=$(MHMAKECONF)\mkfontscale\$(OBJDIR)\mkfontscale.exe + +load_makefile $(MHMAKECONF)\mkfontscale\makefile MAKESERVER=0 DEBUG=$(DEBUG) + +$(DESTDIR)\fonts.scale: $(font_DATA) $(MKFONTSCALE) + del -e $@ + cd $(DESTDIR) & $(MKFONTSCALE) . + +$(DESTDIR)\fonts.dir: $(font_DATA) $(MKFONTSCALE) + del -e $@ + cd $(DESTDIR) & $(MKFONTSCALE) -b -s -l . +# $(FCCACHE) $(DESTDIR) + +$(DESTDIR)\%.otf: %.otf + copy $< $@ diff --git a/xorg-server/fonts.src/Speedo/makefile b/xorg-server/fonts.src/Speedo/makefile new file mode 100644 index 000000000..87f66559a --- /dev/null +++ b/xorg-server/fonts.src/Speedo/makefile @@ -0,0 +1,37 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +INC_BDF_RULES=1 + +DESTDIR=$(MHMAKECONF)\xorg-server\fonts\Speedo + +FONT_FILES = \ + font0419.spd \ + font0582.spd \ + font0583.spd \ + font0611.spd \ + font0648.spd \ + font0649.spd \ + font0709.spd \ + font0710.spd \ + fonts.scale + +fontdir = . +font_DATA = $(FONT_FILES:%=$(DESTDIR)\%) + +all: $(DESTDIR) $(DESTDIR)\fonts.dir $(DESTDIR)\fonts.scale + +MKFONTSCALE=$(MHMAKECONF)\mkfontscale\$(OBJDIR)\mkfontscale.exe + +load_makefile $(MHMAKECONF)\mkfontscale\makefile MAKESERVER=0 DEBUG=$(DEBUG) + +$(DESTDIR)\fonts.dir: $(font_DATA) $(MKFONTSCALE) + del -e $@ + cd $(DESTDIR) & $(MKFONTSCALE) -b -s -l . + +$(DESTDIR)\%.spd: %.spd + copy $< $@ + +$(DESTDIR)\%.scale: %.scale + copy $< $@ diff --git a/xorg-server/fonts.src/TTF/makefile b/xorg-server/fonts.src/TTF/makefile new file mode 100644 index 000000000..146240a9c --- /dev/null +++ b/xorg-server/fonts.src/TTF/makefile @@ -0,0 +1,54 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +INC_BDF_RULES=1 + +DESTDIR=$(MHMAKECONF)\xorg-server\fonts\TTF + + +FONT_FILES = \ + luximbi.ttf \ + luximb.ttf \ + luximri.ttf \ + luximr.ttf \ + luxirbi.ttf \ + luxirb.ttf \ + luxirri.ttf \ + luxirr.ttf \ + luxisbi.ttf \ + luxisb.ttf \ + luxisri.ttf \ + luxisr.ttf \ + Vera.ttf \ + VeraBd.ttf \ + VeraBI.ttf \ + VeraIt.ttf \ + VeraMoBd.ttf \ + VeraMoBI.ttf \ + VeraMoIt.ttf \ + VeraMono.ttf \ + VeraSe.ttf \ + VeraSeBd.ttf \ + GohaTibebZemen.ttf + +fontdir = . +font_DATA = $(FONT_FILES:%=$(DESTDIR)\%) + +all: $(DESTDIR) $(DESTDIR)\fonts.scale $(DESTDIR)\fonts.dir + +MKFONTSCALE=$(MHMAKECONF)\mkfontscale\$(OBJDIR)\mkfontscale.exe + +load_makefile $(MHMAKECONF)\mkfontscale\makefile MAKESERVER=0 DEBUG=$(DEBUG) + +$(DESTDIR)\fonts.scale: $(font_DATA) $(MKFONTSCALE) + del -e $@ + cd $(DESTDIR) & $(MKFONTSCALE) . + +$(DESTDIR)\fonts.dir: $(font_DATA) $(MKFONTSCALE) + del -e $@ + cd $(DESTDIR) & $(MKFONTSCALE) -b -s -l . +# $(FCCACHE) $(DESTDIR) + +$(DESTDIR)\%.ttf: %.ttf + copy $< $@ diff --git a/xorg-server/fonts.src/Type1/makefile b/xorg-server/fonts.src/Type1/makefile new file mode 100644 index 000000000..bc2b6b06f --- /dev/null +++ b/xorg-server/fonts.src/Type1/makefile @@ -0,0 +1,93 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +INC_BDF_RULES=1 + +DESTDIR=$(MHMAKECONF)\xorg-server\fonts\Type1 + +FONT_FILES = \ + cursor.pfa \ + UTB_____.afm \ + UTBI____.afm \ + UTBI____.pfa \ + UTB_____.pfa \ + UTI_____.afm \ + UTI_____.pfa \ + UTRG____.afm \ + UTRG____.pfa \ + cour.afm \ + courb.afm \ + courbi.afm \ + courbi.pfa \ + courb.pfa \ + couri.afm \ + couri.pfa \ + cour.pfa \ + l047013t.afm \ + l047013t.pfa \ + l047016t.afm \ + l047016t.pfa \ + l047033t.afm \ + l047033t.pfa \ + l047036t.afm \ + l047036t.pfa \ + l048013t.afm \ + l048013t.pfa \ + l048016t.afm \ + l048016t.pfa \ + l048033t.afm \ + l048033t.pfa \ + l048036t.afm \ + l048036t.pfa \ + l049013t.afm \ + l049013t.pfa \ + l049016t.afm \ + l049016t.pfa \ + l049033t.afm \ + l049033t.pfa \ + l049036t.afm \ + l049036t.pfa \ + c0419bt_.afm \ + c0419bt_.pfb \ + c0582bt_.afm \ + c0582bt_.pfb \ + c0583bt_.afm \ + c0583bt_.pfb \ + c0611bt_.afm \ + c0611bt_.pfb \ + c0632bt_.afm \ + c0632bt_.pfb \ + c0633bt_.afm \ + c0633bt_.pfb \ + c0648bt_.afm \ + c0648bt_.pfb \ + c0649bt_.afm \ + c0649bt_.pfb + +fontdir = . +font_DATA = $(FONT_FILES:%=$(DESTDIR)\%) + +all: $(DESTDIR) $(DESTDIR)\fonts.scale $(DESTDIR)\fonts.dir + +MKFONTSCALE=$(MHMAKECONF)\mkfontscale\$(OBJDIR)\mkfontscale.exe + +load_makefile $(MHMAKECONF)\mkfontscale\makefile MAKESERVER=0 DEBUG=$(DEBUG) + +$(DESTDIR)\fonts.scale: $(font_DATA) $(MKFONTSCALE) + del -e $@ + cd $(DESTDIR) & $(MKFONTSCALE) . + +$(DESTDIR)\fonts.dir: $(font_DATA) $(MKFONTSCALE) + del -e $@ + cd $(DESTDIR) & $(MKFONTSCALE) -b -s -l . +# $(FCCACHE) $(DESTDIR) + +$(DESTDIR)\%.afm: %.afm + copy $< $@ + +$(DESTDIR)\%.pfb: %.pfb + copy $< $@ + +$(DESTDIR)\%.pfa: %.pfa + copy $< $@ diff --git a/xorg-server/fonts.src/cyrillic/makefile b/xorg-server/fonts.src/cyrillic/makefile new file mode 100644 index 000000000..47a455a17 --- /dev/null +++ b/xorg-server/fonts.src/cyrillic/makefile @@ -0,0 +1,114 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +INC_BDF_RULES=1 + +DESTDIR=$(MHMAKECONF)\xorg-server\fonts\cyrillic + +FONT_FILES = \ + proof9x16 \ + koi12x24b \ + koi12x24 \ + koi5x8 \ + koi6x13b \ + koi6x13 \ + koi6x9 \ + koi7x14b \ + koi7x14 \ + koi8x13 \ + koi8x16b \ + koi8x16 \ + koi9x15b \ + koi9x15 \ + koi9x18b \ + koi9x18 \ + screen8x16b \ + screen8x16 \ + crox1cb \ + crox1c \ + crox1cbo \ + crox1co \ + crox1hb \ + crox1h \ + crox1hbo \ + crox1ho \ + crox1tb \ + crox1t \ + crox1tbo \ + crox1to \ + crox2cb \ + crox2c \ + crox2cbo \ + crox2co \ + crox2hb \ + crox2h \ + crox2hbo \ + crox2ho \ + crox2tb \ + crox2t \ + crox2tbo \ + crox2to \ + crox3cb \ + crox3c \ + crox3cbo \ + crox3co \ + crox3hb \ + crox3h \ + crox3hbo \ + crox3ho \ + crox3tb \ + crox3t \ + crox3tbo \ + crox3to \ + crox4hb \ + crox4h \ + crox4hbo \ + crox4ho \ + crox4tb \ + crox4t \ + crox4tbo \ + crox4to \ + crox5hb \ + crox5h \ + crox5hbo \ + crox5ho \ + crox5tb \ + crox5t \ + crox5tbo \ + crox5to \ + crox6hb \ + crox6h \ + crox6hbo \ + crox6ho \ + crox6tb \ + crox6t \ + crox6tbo \ + crox6to \ + koi10x16b \ + koi10x20 \ + koi6x10 \ + koinil2 + +BDF_FILES = $(FONT_FILES:%=%.bdf) +PCF_FILES = $(FONT_FILES:%=$(DESTDIR)\%.pcf.gz) + +font_DATA = $(PCF_FILES) + +MKFONTSCALE=$(MHMAKECONF)\mkfontscale\$(OBJDIR)\mkfontscale.exe + +load_makefile $(MHMAKECONF)\mkfontscale\makefile MAKESERVER=0 DEBUG=$(DEBUG) + +all: $(DESTDIR) $(MKFONTSCALE) $(DESTDIR)\fonts.scale $(DESTDIR)\fonts.dir $(DESTDIR)\fonts.alias + +$(DESTDIR)\fonts.scale: $(font_DATA) $(MKFONTSCALE) + del -e $@ + cd $(DESTDIR) & $(MKFONTSCALE) . + +$(DESTDIR)\fonts.dir: $(font_DATA) $(MKFONTSCALE) + del -e $@ + cd $(DESTDIR) & $(MKFONTSCALE) -b -s -l . + + +$(DESTDIR)\fonts.alias: fonts.alias + copy $< $@ diff --git a/xorg-server/fonts.src/encodings/large/makefile b/xorg-server/fonts.src/encodings/large/makefile new file mode 100644 index 000000000..0f168d046 --- /dev/null +++ b/xorg-server/fonts.src/encodings/large/makefile @@ -0,0 +1,40 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +INC_BDF_RULES=1 + +DESTDIR=$(MHMAKECONF)\xorg-server\fonts\encodings\large + +ENCODING_FILES = \ + big5.eten-0.enc \ + big5hkscs-0.enc \ + cns11643-1.enc \ + cns11643-2.enc \ + cns11643-3.enc \ + gb18030-0.enc \ + gb18030.2000-0.enc \ + gb18030.2000-1.enc \ + gb2312.1980-0.enc \ + gbk-0.enc \ + jisx0201.1976-0.enc \ + jisx0208.1990-0.enc \ + jisx0212.1990-0.enc \ + ksc5601.1987-0.enc \ + ksc5601.1992-3.enc \ + sun.unicode.india-0.enc + +COMPRESSED = $(ENCODING_FILES:%=$(DESTDIR)\%.gz) + +DATA_FILES = $(COMPRESSED) + +MKFONTSCALE=$(MHMAKECONF)\mkfontscale\$(OBJDIR)\mkfontscale.exe + +load_makefile $(MHMAKECONF)\mkfontscale\makefile MAKESERVER=0 DEBUG=$(DEBUG) + +all: $(DESTDIR)\encodings.dir + +$(DESTDIR)\encodings.dir: $(DATA_FILES) $(MKFONTSCALE) + cd "$(DESTDIR)" & $(MKFONTSCALE) -b -s -l -n -r -p .\large -e . . + + diff --git a/xorg-server/fonts.src/encodings/makefile b/xorg-server/fonts.src/encodings/makefile new file mode 100644 index 000000000..548d56ce5 --- /dev/null +++ b/xorg-server/fonts.src/encodings/makefile @@ -0,0 +1,63 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif +load_makefile large\makefile MAKESERVER=0 DEBUG=0 + +INC_BDF_RULES=1 + +DESTDIR=$(MHMAKECONF)\xorg-server\fonts\encodings + +ENCODING_FILES = \ + adobe-dingbats.enc \ + adobe-standard.enc \ + adobe-symbol.enc \ + armscii-8.enc \ + ascii-0.enc \ + dec-special.enc \ + ibm-cp437.enc \ + ibm-cp850.enc \ + ibm-cp852.enc \ + ibm-cp866.enc \ + iso8859-11.enc \ + iso8859-13.enc \ + iso8859-16.enc \ + iso8859-6.16.enc \ + iso8859-6.8x.enc \ + microsoft-cp1250.enc \ + microsoft-cp1251.enc \ + microsoft-cp1252.enc \ + microsoft-cp1253.enc \ + microsoft-cp1254.enc \ + microsoft-cp1255.enc \ + microsoft-cp1256.enc \ + microsoft-cp1257.enc \ + microsoft-cp1258.enc \ + microsoft-win3.1.enc \ + mulearabic-0.enc \ + mulearabic-1.enc \ + mulearabic-2.enc \ + mulelao-1.enc \ + suneu-greek.enc \ + tcvn-0.enc \ + tis620-2.enc \ + viscii1.1-1.enc + +COMPRESSED = $(ENCODING_FILES:%=$(DESTDIR)\%.gz) + +DATA_FILES = $(COMPRESSED) + +MKFONTSCALE=$(MHMAKECONF)\mkfontscale\$(OBJDIR)\mkfontscale.exe + +load_makefile $(MHMAKECONF)\mkfontscale\makefile MAKESERVER=0 DEBUG=$(DEBUG) + +$(DESTDIR)\encodings.dir: $(DATA_FILES) $(DESTDIR)\large\encodings.dir $(MKFONTSCALE) + cd "$(DESTDIR)" & $(MKFONTSCALE) -b -s -l -n -r -p . -e . -e large . + +all: $(DESTDIR)\encodings.dir + +.PHONY: cleanthis +cleanthis: + del -e $(DESTDIR) + +clean: cleanthis + diff --git a/xorg-server/fonts.src/font-util/makefile b/xorg-server/fonts.src/font-util/makefile new file mode 100644 index 000000000..13e196a03 --- /dev/null +++ b/xorg-server/fonts.src/font-util/makefile @@ -0,0 +1,5 @@ +TTYAPP = ucs2any + +CSRCS = ucs2any.c + +DEFINES += NEED_BASENAME diff --git a/xorg-server/fonts.src/makefile b/xorg-server/fonts.src/makefile new file mode 100644 index 000000000..9dce92d67 --- /dev/null +++ b/xorg-server/fonts.src/makefile @@ -0,0 +1 @@ +SUBDIRS=font-util 75dpi 100dpi cyrillic encodings misc OTF Speedo TTF Type1 diff --git a/xorg-server/fonts.src/misc/makefile b/xorg-server/fonts.src/misc/makefile new file mode 100644 index 000000000..290ae173a --- /dev/null +++ b/xorg-server/fonts.src/misc/makefile @@ -0,0 +1,340 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +INC_BDF_RULES=1 + +all: $(BDFTOPCF) + +DESTDIR=$(MHMAKECONF)\xorg-server\fonts\misc + +BDF2UCS_FONT_FILES = \ + clR6x12 \ + 4x6 \ + 5x7 \ + 5x8 \ + 6x9 \ + 6x10 \ + 6x12 \ + 6x13 \ + 6x13B \ + 6x13O \ + 7x13 \ + 7x13B \ + 7x13O \ + 7x14 \ + 7x14B \ + 8x13 \ + 8x13B \ + 8x13O \ + 9x15 \ + 9x15B \ + 9x18 \ + 9x18B \ + 10x20 +BDF2UCS_8_FONT_FILES = \ + clR6x12 \ + 4x6 \ + 5x7 \ + 5x8 \ + 6x9 \ + 6x10 \ + 6x12 \ + 6x13 \ + 6x13B \ + 7x13 \ + 7x13B \ + 7x14 \ + 7x14B \ + 8x13 \ + 8x13B \ + 9x15 \ + 9x15B \ + 9x18 \ + 9x18B \ + 10x20 +BDF2UCS_11_FONT_FILES = \ + 6x13 \ + 7x13 \ + 7x13B \ + 7x13O \ + 7x14 \ + 7x14B \ + 9x15 \ + 9x15B \ + 9x18 \ + 10x20 +BDF2UCS_KOI8_FONT_FILES = \ + clR6x12 \ + 4x6 \ + 5x7 \ + 5x8 \ + 6x9 \ + 6x10 \ + 6x12 \ + 6x13 \ + 7x13 \ + 7x14 \ + 8x13 \ + 9x15 \ + 9x18 \ + 10x20 +BDF2UCS_JISX0201_FONT_FILES = \ + 7x14 +EXTRA_FONT_FILES = \ + 12x13ja \ + 18x18ja \ + 18x18ko \ + k14 \ + nil2 \ + micro \ + jiskan16 \ + jiskan24 \ + gb16fs \ + gb16st \ + gb24st \ + deccurs \ + decsess \ + arabic24 \ + cursor \ + hanglg16 \ + hanglm16 \ + hanglm24 \ + cu12 \ + cu-alt12 \ + cu-arabic12 \ + cuarabic12 \ + cu-devnag12 \ + cudevnag12 \ + cu-lig12 \ + cu-pua12 \ + clB6x10 \ + clB6x12 \ + clB8x10 \ + clB8x12 \ + clB8x13 \ + clB8x14 \ + clB8x16 \ + clB8x8 \ + clB9x15 \ + clI6x12 \ + clI8x8 \ + clR4x6 \ + clR5x10 \ + clR5x6 \ + clR5x8 \ + clR6x10 \ + clR6x13 \ + clR6x6 \ + clR6x8 \ + clR7x10 \ + clR7x12 \ + clR7x14 \ + clR7x8 \ + clR8x10 \ + clR8x12 \ + clR8x13 \ + clR8x14 \ + clR8x16 \ + clR8x8 \ + clR9x15 \ + 12x24 \ + 12x24rk \ + 8x16 \ + 8x16rk \ + olcursor \ + olgl10 \ + olgl12 \ + olgl14 \ + olgl19 + +FONT_FILES = $(BDF2UCS_FONT_FILES) $(EXTRA_FONT_FILES) + +BDF_FILES = $(FONT_FILES:%=%.bdf) +PCF_FILES = $(FONT_FILES:%=$(DESTDIR)\%.pcf.gz) + +ISO8859_1_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-1.pcf.gz) + +ISO8859_2_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-2.pcf.gz) + +ISO8859_3_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-3.pcf.gz) + +ISO8859_4_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-4.pcf.gz) + +ISO8859_5_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-5.pcf.gz) + +ISO8859_7_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-7.pcf.gz) + +ISO8859_8_PCF_FILES = $(BDF2UCS_8_FONT_FILES:%=$(DESTDIR)\%-ISO8859-8.pcf.gz) + +ISO8859_9_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-9.pcf.gz) + +ISO8859_10_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-10.pcf.gz) + +ISO8859_11_PCF_FILES = $(BDF2UCS_11_FONT_FILES:%=$(DESTDIR)\%-ISO8859-11.pcf.gz) + +ISO8859_13_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-13.pcf.gz) + +ISO8859_14_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-14.pcf.gz) + +ISO8859_15_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-15.pcf.gz) + +ISO8859_16_PCF_FILES = $(BDF2UCS_FONT_FILES:%=$(DESTDIR)\%-ISO8859-16.pcf.gz) + +KOI8_R_PCF_FILES = $(BDF2UCS_KOI8_FONT_FILES:%=$(DESTDIR)\%-KOI8-R.pcf.gz) + +JISX0201_PCF_FILES = $(BDF2UCS_JISX0201_FONT_FILES:%=$(DESTDIR)\%-JISX0201.1976-0.pcf.gz) + +UTIL_DIR = ..\font-util +UCS2ANY = $(UTIL_DIR)\$(OBJDIR)\ucs2any.exe + +load_makefile $(UTIL_DIR)\makefile MAKESERVER=0 DEBUG=$(DEBUG) + +$(DESTDIR)\%-ISO8859-1.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-1.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-1 ISO8859-1 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-1.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-1.bdf) + +$(DESTDIR)\%-ISO8859-2.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-2.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-2 ISO8859-2 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-2.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-2.bdf) + +$(DESTDIR)\%-ISO8859-3.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-3.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-3 ISO8859-3 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-3.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-3.bdf) + +$(DESTDIR)\%-ISO8859-4.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-4.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-4 ISO8859-4 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-4.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-4.bdf) + +$(DESTDIR)\%-ISO8859-5.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-5.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-5 ISO8859-5 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-5.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-5.bdf) + +$(DESTDIR)\%-ISO8859-7.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-7.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-7 ISO8859-7 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-7.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-7.bdf) + +$(DESTDIR)\%-ISO8859-8.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-8.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-8 ISO8859-8 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-8.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-8.bdf) + +$(DESTDIR)\%-ISO8859-9.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-9.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-9 ISO8859-9 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-9.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-9.bdf) + +$(DESTDIR)\%-ISO8859-10.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-10.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-10 ISO8859-10 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-10.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-10.bdf) + +$(DESTDIR)\%-ISO8859-11.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-11.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-11 ISO8859-11 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-11.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-11.bdf) + +$(DESTDIR)\%-ISO8859-13.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-13.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-13 ISO8859-13 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-13.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-13.bdf) + +$(DESTDIR)\%-ISO8859-14.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-14.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-14 ISO8859-14 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-14.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-14.bdf) + +$(DESTDIR)\%-ISO8859-15.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-15.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-15 ISO8859-15 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-15.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-15.bdf) + +$(DESTDIR)\%-ISO8859-16.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-ISO8859-16.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-ISO8859-16 ISO8859-16 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-ISO8859-16.bdf) | gzip > $@ + @del $(<:%.bdf=%-ISO8859-16.bdf) + +$(DESTDIR)\%-KOI8-R.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-KOI8-R.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-KOI8-R KOI8-R + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-KOI8-R.bdf) | gzip > $@ + @del $(<:%.bdf=%-KOI8-R.bdf) + +$(DESTDIR)\%-JISX0201.1976-0.pcf.gz: %.bdf + @del -e $(<:%.bdf=%-JISX0201.1976-0.bdf) + $(UCS2ANY) $< $(UTIL_DIR)\map-JISX0201.1976-0 JISX0201.1976-0 + @del -e $@ + $(BDFTOPCF) -t $(<:%.bdf=%-JISX0201.1976-0.bdf) | gzip > $@ + @del $(<:%.bdf=%-JISX0201.1976-0.bdf) + +font_DATA = \ + $(PCF_FILES) \ + $(ISO8859_1_PCF_FILES) \ + $(ISO8859_2_PCF_FILES) \ + $(ISO8859_3_PCF_FILES) \ + $(ISO8859_4_PCF_FILES) \ + $(ISO8859_5_PCF_FILES) \ + $(ISO8859_7_PCF_FILES) \ + $(ISO8859_8_PCF_FILES) \ + $(ISO8859_9_PCF_FILES) \ + $(ISO8859_10_PCF_FILES) \ + $(ISO8859_11_PCF_FILES) \ + $(ISO8859_13_PCF_FILES) \ + $(ISO8859_14_PCF_FILES) \ + $(ISO8859_15_PCF_FILES) \ + $(ISO8859_16_PCF_FILES) \ + $(KOI8_R_PCF_FILES) \ + $(JISX0201_PCF_FILES) + +all: $(DESTDIR) $(UCS2ANY) $(DESTDIR)\fonts.scale $(DESTDIR)\fonts.dir $(DESTDIR)\fonts.alias + +MKFONTSCALE=$(MHMAKECONF)\mkfontscale\$(OBJDIR)\mkfontscale.exe + +load_makefile $(MHMAKECONF)\mkfontscale\makefile MAKESERVER=0 DEBUG=$(DEBUG) + +$(DESTDIR)\fonts.scale: $(font_DATA) $(MKFONTSCALE) + del -e $@ + cd $(DESTDIR) & $(MKFONTSCALE) . + +$(DESTDIR)\fonts.dir: $(font_DATA) $(MKFONTSCALE) + del -e $@ + cd $(DESTDIR) & $(MKFONTSCALE) -b -s -l . + +$(DESTDIR)\fonts.alias: fonts.alias + copy $< $@ + diff --git a/xorg-server/glx/glapi.c b/xorg-server/glx/glapi.c index d6a568e88..9cd703030 100644 --- a/xorg-server/glx/glapi.c +++ b/xorg-server/glx/glapi.c @@ -54,7 +54,11 @@ #include <dix-config.h> #include <X11/Xfuncproto.h> +#ifdef _MSC_VER +#define PUBLIC _declspec(dllexport) +#else #define PUBLIC _X_EXPORT +#endif #else diff --git a/xorg-server/glx/glapi.h b/xorg-server/glx/glapi.h index 8f2cf6621..68e5cd328 100644 --- a/xorg-server/glx/glapi.h +++ b/xorg-server/glx/glapi.h @@ -73,6 +73,11 @@ typedef void (*_glapi_warning_func)(void *ctx, const char *str, ...); */ #define MAX_EXTENSION_FUNCS 300 +#ifdef _MSC_VER +#define EXTERN _declspec(dllexport) +#else +#define EXTERN extern +#endif /** ** Define the GET_CURRENT_CONTEXT() macro. @@ -90,8 +95,8 @@ extern __thread void * _glapi_tls_Context #else -extern void *_glapi_Context; -extern struct _glapi_table *_glapi_Dispatch; +EXTERN void *_glapi_Context; +EXTERN struct _glapi_table *_glapi_Dispatch; # ifdef THREADS # define GET_CURRENT_CONTEXT(C) GLcontext *C = (GLcontext *) (_glapi_Context ? _glapi_Context : _glapi_get_context()) @@ -106,29 +111,29 @@ extern struct _glapi_table *_glapi_Dispatch; ** GL API public functions **/ -extern void +EXTERN void _glapi_noop_enable_warnings(GLboolean enable); -extern void +EXTERN void _glapi_set_warning_func(_glapi_warning_func func); -extern void +EXTERN void _glapi_check_multithread(void); -extern void +EXTERN void _glapi_set_context(void *context); -extern void * +EXTERN void * _glapi_get_context(void); -extern void +EXTERN void _glapi_set_dispatch(struct _glapi_table *dispatch); -extern struct _glapi_table * +EXTERN struct _glapi_table * _glapi_get_dispatch(void); @@ -144,7 +149,7 @@ struct _glapi_table * _glapi_get_override_dispatch(int layer); -extern GLuint +EXTERN GLuint _glapi_get_dispatch_table_size(void); @@ -152,11 +157,11 @@ extern void _glapi_check_table(const struct _glapi_table *table); -extern int +EXTERN int _glapi_add_dispatch( const char * const * function_names, const char * parameter_signature ); -extern GLint +EXTERN GLint _glapi_get_proc_offset(const char *funcName); diff --git a/xorg-server/glx/glheader.h b/xorg-server/glx/glheader.h new file mode 100644 index 000000000..1c0ee2c9e --- /dev/null +++ b/xorg-server/glx/glheader.h @@ -0,0 +1,24 @@ +#ifndef __GLHEADER_H__
+#define __GLHEADER_H__
+
+#define STDC_HEADERS 1
+
+#include <X11/Xwinsock.h>
+#include <X11/Xwindows.h>
+#include <assert.h>
+#define strcasecmp _stricmp
+
+#undef MINSHORT
+#undef MAXSHORT
+
+#define MINSHORT -32768
+#define MAXSHORT 32767
+
+#define PUBLIC
+
+#define GL_GLEXT_PROTOTYPES
+
+#define DRI_DRIVER_PATH "/usr/lib/dri"
+
+#endif
+
diff --git a/xorg-server/glx/glxcmds.c b/xorg-server/glx/glxcmds.c index 77afbf4b1..6c469b8f8 100644 --- a/xorg-server/glx/glxcmds.c +++ b/xorg-server/glx/glxcmds.c @@ -1,2422 +1,2426 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * 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 - * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <string.h> -#include <assert.h> - -#include "glxserver.h" -#include <GL/glxtokens.h> -#include <unpack.h> -#include "g_disptab.h" -#include <pixmapstr.h> -#include <windowstr.h> -#include "glxutil.h" -#include "glxext.h" -#include "glapitable.h" -#include "glapi.h" -#include "glthread.h" -#include "dispatch.h" -#include "indirect_dispatch.h" -#include "indirect_table.h" -#include "indirect_util.h" - -static int -validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err) -{ - /* - ** Check if screen exists. - */ - if (screen >= screenInfo.numScreens) { - client->errorValue = screen; - *err = BadValue; - return FALSE; - } - *pGlxScreen = glxGetScreen(screenInfo.screens[screen]); - - return TRUE; -} - -static int -validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id, - __GLXconfig **config, int *err) -{ - __GLXconfig *m; - - for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) - if (m->fbconfigID == id) { - *config = m; - return TRUE; - } - - client->errorValue = id; - *err = __glXError(GLXBadFBConfig); - - return FALSE; -} - -static int -validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id, - __GLXconfig **config, int *err) -{ - int i; - - for (i = 0; i < pGlxScreen->numVisuals; i++) - if (pGlxScreen->visuals[i]->visualID == id) { - *config = pGlxScreen->visuals[i]; - return TRUE; - } - - client->errorValue = id; - *err = BadValue; - - return FALSE; -} - -static int -validGlxFBConfigForWindow(ClientPtr client, __GLXconfig *config, - DrawablePtr pDraw, int *err) -{ - ScreenPtr pScreen = pDraw->pScreen; - VisualPtr pVisual = NULL; - XID vid; - int i; - - vid = wVisual((WindowPtr)pDraw); - for (i = 0; i < pScreen->numVisuals; i++) { - if (pScreen->visuals[i].vid == vid) { - pVisual = &pScreen->visuals[i]; - break; - } - } - - /* FIXME: What exactly should we check here... */ - if (pVisual->class != glxConvertToXVisualType(config->visualType) || - !(config->drawableType & GLX_WINDOW_BIT)) { - client->errorValue = pDraw->id; - *err = BadMatch; - return FALSE; - } - - return TRUE; -} - -static int -validGlxContext(ClientPtr client, XID id, int access_mode, - __GLXcontext **context, int *err) -{ - *err = dixLookupResourceByType((pointer *) context, id, - __glXContextRes, client, access_mode); - if (*err != Success) { - client->errorValue = id; - if (*err == BadValue) - *err = __glXError(GLXBadContext); - return FALSE; - } - - return TRUE; -} - -static int -validGlxDrawable(ClientPtr client, XID id, int type, int access_mode, - __GLXdrawable **drawable, int *err) -{ - int rc; - - rc = dixLookupResourceByType((pointer *) drawable, id, - __glXDrawableRes, client, access_mode); - if (rc != Success && rc != BadValue) { - *err = rc; - client->errorValue = id; - return FALSE; - } - - if (rc == BadValue || - (type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) { - client->errorValue = id; - switch (type) { - case GLX_DRAWABLE_WINDOW: - *err = __glXError(GLXBadWindow); - return FALSE; - case GLX_DRAWABLE_PIXMAP: - *err = __glXError(GLXBadPixmap); - return FALSE; - case GLX_DRAWABLE_PBUFFER: - *err = __glXError(GLXBadPbuffer); - return FALSE; - case GLX_DRAWABLE_ANY: - *err = __glXError(GLXBadDrawable); - return FALSE; - } - } - - return TRUE; -} - -void -__glXContextDestroy(__GLXcontext *context) -{ - __glXFlushContextCache(); -} - -static void __glXdirectContextDestroy(__GLXcontext *context) -{ - __glXContextDestroy(context); - xfree(context); -} - -static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen, - __GLXconfig *modes, - __GLXcontext *shareContext) -{ - __GLXcontext *context; - - context = xcalloc (1, sizeof (__GLXcontext)); - if (context == NULL) - return NULL; - - context->destroy = __glXdirectContextDestroy; - - return context; -} - -/** - * Create a GL context with the given properties. This routine is used - * to implement \c glXCreateContext, \c glXCreateNewContext, and - * \c glXCreateContextWithConfigSGIX. This works becuase of the hack way - * that GLXFBConfigs are implemented. Basically, the FBConfigID is the - * same as the VisualID. - */ - -static int -DoCreateContext(__GLXclientState *cl, GLXContextID gcId, - GLXContextID shareList, __GLXconfig *config, - __GLXscreen *pGlxScreen, GLboolean isDirect) -{ - ClientPtr client = cl->client; - __GLXcontext *glxc, *shareglxc; - int err; - - LEGAL_NEW_RESOURCE(gcId, client); - - /* - ** Find the display list space that we want to share. - ** - ** NOTE: In a multithreaded X server, we would need to keep a reference - ** count for each display list so that if one client detroyed a list that - ** another client was using, the list would not really be freed until it - ** was no longer in use. Since this sample implementation has no support - ** for multithreaded servers, we don't do this. - */ - if (shareList == None) { - shareglxc = 0; - } else { - if (!validGlxContext(client, shareList, DixReadAccess, - &shareglxc, &err)) - return err; - - if (shareglxc->isDirect) { - /* - ** NOTE: no support for sharing display lists between direct - ** contexts, even if they are in the same address space. - */ -#if 0 - /* Disabling this code seems to allow shared display lists - * and texture objects to work. We'll leave it disabled for now. - */ - client->errorValue = shareList; - return BadMatch; -#endif - } else { - /* - ** Create an indirect context regardless of what the client asked - ** for; this way we can share display list space with shareList. - */ - isDirect = GL_FALSE; - } - } - - /* - ** Allocate memory for the new context - */ - if (!isDirect) - glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc); - else - glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc); - if (!glxc) { - return BadAlloc; - } - - /* - ** Initially, setup the part of the context that could be used by - ** a GL core that needs windowing information (e.g., Mesa). - */ - glxc->pGlxScreen = pGlxScreen; - glxc->config = config; - - /* - ** Register this context as a resource. - */ - if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) { - (*glxc->destroy)(glxc); - client->errorValue = gcId; - return BadAlloc; - } - - /* - ** Finally, now that everything is working, setup the rest of the - ** context. - */ - glxc->id = gcId; - glxc->share_id = shareList; - glxc->idExists = GL_TRUE; - glxc->isCurrent = GL_FALSE; - glxc->isDirect = isDirect; - glxc->renderMode = GL_RENDER; - - __glXAddToContextList(glxc); - - return Success; -} - -int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc; - __GLXconfig *config; - __GLXscreen *pGlxScreen; - int err; - - if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) - return err; - if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err)) - return err; - - return DoCreateContext(cl, req->context, req->shareList, - config, pGlxScreen, req->isDirect); -} - -int __glXDisp_CreateNewContext(__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc; - __GLXconfig *config; - __GLXscreen *pGlxScreen; - int err; - - if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) - return err; - if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) - return err; - - return DoCreateContext(cl, req->context, req->shareList, - config, pGlxScreen, req->isDirect); -} - -int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreateContextWithConfigSGIXReq *req = - (xGLXCreateContextWithConfigSGIXReq *) pc; - __GLXconfig *config; - __GLXscreen *pGlxScreen; - int err; - - if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) - return err; - if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) - return err; - - return DoCreateContext(cl, req->context, req->shareList, - config, pGlxScreen, req->isDirect); -} -int __glXDisp_DestroyContext(__GLXclientState *cl, GLbyte *pc) -{ - xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc; - __GLXcontext *glxc; - int err; - - if (!validGlxContext(cl->client, req->context, DixDestroyAccess, - &glxc, &err)) - return err; - - FreeResourceByType(req->context, __glXContextRes, FALSE); - return Success; -} - -/*****************************************************************************/ - -/* -** For each client, the server keeps a table of all the contexts that are -** current for that client (each thread of a client may have its own current -** context). These routines add, change, and lookup contexts in the table. -*/ - -/* -** Add a current context, and return the tag that will be used to refer to it. -*/ -static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc) -{ - int i; - int num = cl->numCurrentContexts; - __GLXcontext **table = cl->currentContexts; - - if (!glxc) return -1; - - /* - ** Try to find an empty slot and use it. - */ - for (i=0; i < num; i++) { - if (!table[i]) { - table[i] = glxc; - return i+1; - } - } - /* - ** Didn't find a free slot, so we'll have to grow the table. - */ - if (!num) { - table = (__GLXcontext **) xalloc(sizeof(__GLXcontext *)); - } else { - table = (__GLXcontext **) xrealloc(table, - (num+1)*sizeof(__GLXcontext *)); - } - table[num] = glxc; - cl->currentContexts = table; - cl->numCurrentContexts++; - return num+1; -} - -/* -** Given a tag, change the current context for the corresponding entry. -*/ -static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc, - GLXContextTag tag) -{ - __GLXcontext **table = cl->currentContexts; - table[tag-1] = glxc; -} - -/* -** For this implementation we have chosen to simply use the index of the -** context's entry in the table as the context tag. A tag must be greater -** than 0. -*/ -__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag) -{ - int num = cl->numCurrentContexts; - - if (tag < 1 || tag > num) { - return 0; - } else { - return cl->currentContexts[tag-1]; - } -} - -/*****************************************************************************/ - -static void StopUsingContext(__GLXcontext *glxc) -{ - if (glxc) { - if (glxc == __glXLastContext) { - /* Tell server GL library */ - __glXLastContext = 0; - } - glxc->isCurrent = GL_FALSE; - if (!glxc->idExists) { - __glXFreeContext(glxc); - } - } -} - -static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc) -{ - glxc->isCurrent = GL_TRUE; - __glXLastContext = glxc; -} - -/** - * This is a helper function to handle the legacy (pre GLX 1.3) cases - * where passing an X window to glXMakeCurrent is valid. Given a - * resource ID, look up the GLX drawable if available, otherwise, make - * sure it's an X window and create a GLX drawable one the fly. - */ -static __GLXdrawable * -__glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client, - int *error) -{ - DrawablePtr pDraw; - __GLXdrawable *pGlxDraw; - int rc; - - if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY, - DixWriteAccess, &pGlxDraw, &rc)) { - if (glxc != NULL && pGlxDraw->config != glxc->config) { - client->errorValue = drawId; - *error = BadMatch; - return NULL; - } - - return pGlxDraw; - } - - /* The drawId wasn't a GLX drawable. Make sure it's a window and - * create a GLXWindow for it. Check that the drawable screen - * matches the context screen and that the context fbconfig is - * compatible with the window visual. */ - - rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess); - if (rc != Success || pDraw->type != DRAWABLE_WINDOW) { - client->errorValue = drawId; - *error = __glXError(GLXBadDrawable); - return NULL; - } - - if (pDraw->pScreen != glxc->pGlxScreen->pScreen) { - client->errorValue = pDraw->pScreen->myNum; - *error = BadMatch; - return NULL; - } - - if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error)) - return NULL; - - pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen, - pDraw, GLX_DRAWABLE_WINDOW, - drawId, glxc->config); - - /* since we are creating the drawablePrivate, drawId should be new */ - if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) { - pGlxDraw->destroy (pGlxDraw); - *error = BadAlloc; - return NULL; - } - - return pGlxDraw; -} - -/*****************************************************************************/ -/* -** Make an OpenGL context and drawable current. -*/ - -static int -DoMakeCurrent(__GLXclientState *cl, - GLXDrawable drawId, GLXDrawable readId, - GLXContextID contextId, GLXContextTag tag) -{ - ClientPtr client = cl->client; - xGLXMakeCurrentReply reply; - __GLXcontext *glxc, *prevglxc; - __GLXdrawable *drawPriv = NULL; - __GLXdrawable *readPriv = NULL; - int error; - GLuint mask; - - /* - ** If one is None and the other isn't, it's a bad match. - */ - - mask = (drawId == None) ? (1 << 0) : 0; - mask |= (readId == None) ? (1 << 1) : 0; - mask |= (contextId == None) ? (1 << 2) : 0; - - if ( (mask != 0x00) && (mask != 0x07) ) { - return BadMatch; - } - - /* - ** Lookup old context. If we have one, it must be in a usable state. - */ - if (tag != 0) { - prevglxc = __glXLookupContextByTag(cl, tag); - if (!prevglxc) { - /* - ** Tag for previous context is invalid. - */ - return __glXError(GLXBadContextTag); - } - if (prevglxc->renderMode != GL_RENDER) { - /* Oops. Not in render mode render. */ - client->errorValue = prevglxc->id; - return __glXError(GLXBadContextState); - } - } else { - prevglxc = 0; - } - - /* - ** Lookup new context. It must not be current for someone else. - */ - if (contextId != None) { - int status; - - if (!validGlxContext(client, contextId, DixUseAccess, &glxc, &error)) - return error; - if ((glxc != prevglxc) && glxc->isCurrent) { - /* Context is current to somebody else */ - return BadAccess; - } - - assert( drawId != None ); - assert( readId != None ); - - drawPriv = __glXGetDrawable(glxc, drawId, client, &status); - if (drawPriv == NULL) - return status; - - readPriv = __glXGetDrawable(glxc, readId, client, &status); - if (readPriv == NULL) - return status; - - } else { - /* Switching to no context. Ignore new drawable. */ - glxc = 0; - drawPriv = 0; - readPriv = 0; - } - - - if (prevglxc) { - /* - ** Flush the previous context if needed. - */ - if (__GLX_HAS_UNFLUSHED_CMDS(prevglxc)) { - if (__glXForceCurrent(cl, tag, (int *)&error)) { - CALL_Flush( GET_DISPATCH(), () ); - __GLX_NOTE_FLUSHED_CMDS(prevglxc); - } else { - return error; - } - } - - /* - ** Make the previous context not current. - */ - if (!(*prevglxc->loseCurrent)(prevglxc)) { - return __glXError(GLXBadContext); - } - __glXFlushContextCache(); - if (!prevglxc->isDirect) { - prevglxc->drawPriv = NULL; - prevglxc->readPriv = NULL; - } - } - - - if ((glxc != 0) && !glxc->isDirect) { - - glxc->drawPriv = drawPriv; - glxc->readPriv = readPriv; - - /* make the context current */ - if (!(*glxc->makeCurrent)(glxc)) { - glxc->drawPriv = NULL; - glxc->readPriv = NULL; - return __glXError(GLXBadContext); - } - - glxc->isCurrent = GL_TRUE; - } - - if (prevglxc) { - ChangeCurrentContext(cl, glxc, tag); - StopUsingContext(prevglxc); - } else { - tag = AddCurrentContext(cl, glxc); - } - - if (glxc) { - StartUsingContext(cl, glxc); - reply.contextTag = tag; - } else { - reply.contextTag = 0; - } - - reply.length = 0; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - if (client->swapped) { - __glXSwapMakeCurrentReply(client, &reply); - } else { - WriteToClient(client, sz_xGLXMakeCurrentReply, (char *)&reply); - } - return Success; -} - -int __glXDisp_MakeCurrent(__GLXclientState *cl, GLbyte *pc) -{ - xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc; - - return DoMakeCurrent( cl, req->drawable, req->drawable, - req->context, req->oldContextTag ); -} - -int __glXDisp_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc) -{ - xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc; - - return DoMakeCurrent( cl, req->drawable, req->readdrawable, - req->context, req->oldContextTag ); -} - -int __glXDisp_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc) -{ - xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc; - - return DoMakeCurrent( cl, req->drawable, req->readable, - req->context, req->oldContextTag ); -} - -int __glXDisp_IsDirect(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc; - xGLXIsDirectReply reply; - __GLXcontext *glxc; - int err; - - if (!validGlxContext(cl->client, req->context, DixReadAccess, &glxc, &err)) - return err; - - reply.isDirect = glxc->isDirect; - reply.length = 0; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - if (client->swapped) { - __glXSwapIsDirectReply(client, &reply); - } else { - WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply); - } - - return Success; -} - -int __glXDisp_QueryVersion(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc; - xGLXQueryVersionReply reply; - GLuint major, minor; - - major = req->majorVersion; - minor = req->minorVersion; - (void)major; - (void)minor; - - /* - ** Server should take into consideration the version numbers sent by the - ** client if it wants to work with older clients; however, in this - ** implementation the server just returns its version number. - */ - reply.majorVersion = glxMajorVersion; - reply.minorVersion = glxMinorVersion; - reply.length = 0; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - if (client->swapped) { - __glXSwapQueryVersionReply(client, &reply); - } else { - WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply); - } - return Success; -} - -int __glXDisp_WaitGL(__GLXclientState *cl, GLbyte *pc) -{ - xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc; - GLXContextTag tag = req->contextTag; - __GLXcontext *glxc = NULL; - int error; - - if (tag) { - glxc = __glXLookupContextByTag(cl, tag); - if (!glxc) - return __glXError(GLXBadContextTag); - - if (!__glXForceCurrent(cl, req->contextTag, &error)) - return error; - - CALL_Finish( GET_DISPATCH(), () ); - } - - if (glxc && glxc->drawPriv->waitGL) - (*glxc->drawPriv->waitGL)(glxc->drawPriv); - - return Success; -} - -int __glXDisp_WaitX(__GLXclientState *cl, GLbyte *pc) -{ - xGLXWaitXReq *req = (xGLXWaitXReq *)pc; - GLXContextTag tag = req->contextTag; - __GLXcontext *glxc = NULL; - int error; - - if (tag) { - glxc = __glXLookupContextByTag(cl, tag); - if (!glxc) - return __glXError(GLXBadContextTag); - - if (!__glXForceCurrent(cl, req->contextTag, &error)) - return error; - } - - if (glxc && glxc->drawPriv->waitX) - (*glxc->drawPriv->waitX)(glxc->drawPriv); - - return Success; -} - -int __glXDisp_CopyContext(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc; - GLXContextID source = req->source; - GLXContextID dest = req->dest; - GLXContextTag tag = req->contextTag; - unsigned long mask = req->mask; - __GLXcontext *src, *dst; - int error; - - if (!validGlxContext(cl->client, source, DixReadAccess, &src, &error)) - return error; - if (!validGlxContext(cl->client, dest, DixWriteAccess, &dst, &error)) - return error; - - /* - ** They must be in the same address space, and same screen. - ** NOTE: no support for direct rendering contexts here. - */ - if (src->isDirect || dst->isDirect || - (src->pGlxScreen != dst->pGlxScreen)) { - client->errorValue = source; - return BadMatch; - } - - /* - ** The destination context must not be current for any client. - */ - if (dst->isCurrent) { - client->errorValue = dest; - return BadAccess; - } - - if (tag) { - __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag); - - if (!tagcx) { - return __glXError(GLXBadContextTag); - } - if (tagcx != src) { - /* - ** This would be caused by a faulty implementation of the client - ** library. - */ - return BadMatch; - } - /* - ** In this case, glXCopyContext is in both GL and X streams, in terms - ** of sequentiality. - */ - if (__glXForceCurrent(cl, tag, &error)) { - /* - ** Do whatever is needed to make sure that all preceding requests - ** in both streams are completed before the copy is executed. - */ - CALL_Finish( GET_DISPATCH(), () ); - __GLX_NOTE_FLUSHED_CMDS(tagcx); - } else { - return error; - } - } - /* - ** Issue copy. The only reason for failure is a bad mask. - */ - if (!(*dst->copy)(dst, src, mask)) { - client->errorValue = mask; - return BadValue; - } - return Success; -} - -enum { - GLX_VIS_CONFIG_UNPAIRED = 18, - GLX_VIS_CONFIG_PAIRED = 20 -}; - -enum { - GLX_VIS_CONFIG_TOTAL = GLX_VIS_CONFIG_UNPAIRED + GLX_VIS_CONFIG_PAIRED -}; - -int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc) -{ - xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc; - ClientPtr client = cl->client; - xGLXGetVisualConfigsReply reply; - __GLXscreen *pGlxScreen; - __GLXconfig *modes; - CARD32 buf[GLX_VIS_CONFIG_TOTAL]; - int p, i, err; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) - return err; - - reply.numVisuals = pGlxScreen->numVisuals; - reply.numProps = GLX_VIS_CONFIG_TOTAL; - reply.length = (reply.numVisuals * __GLX_SIZE_CARD32 * GLX_VIS_CONFIG_TOTAL) >> 2; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - if (client->swapped) { - __GLX_SWAP_SHORT(&reply.sequenceNumber); - __GLX_SWAP_INT(&reply.length); - __GLX_SWAP_INT(&reply.numVisuals); - __GLX_SWAP_INT(&reply.numProps); - } - - WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply); - - for (i = 0; i < pGlxScreen->numVisuals; i++) { - modes = pGlxScreen->visuals[i]; - - p = 0; - buf[p++] = modes->visualID; - buf[p++] = glxConvertToXVisualType( modes->visualType ); - buf[p++] = (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE; - - buf[p++] = modes->redBits; - buf[p++] = modes->greenBits; - buf[p++] = modes->blueBits; - buf[p++] = modes->alphaBits; - buf[p++] = modes->accumRedBits; - buf[p++] = modes->accumGreenBits; - buf[p++] = modes->accumBlueBits; - buf[p++] = modes->accumAlphaBits; - - buf[p++] = modes->doubleBufferMode; - buf[p++] = modes->stereoMode; - - buf[p++] = modes->rgbBits; - buf[p++] = modes->depthBits; - buf[p++] = modes->stencilBits; - buf[p++] = modes->numAuxBuffers; - buf[p++] = modes->level; - - assert(p == GLX_VIS_CONFIG_UNPAIRED); - /* - ** Add token/value pairs for extensions. - */ - buf[p++] = GLX_VISUAL_CAVEAT_EXT; - buf[p++] = modes->visualRating; - buf[p++] = GLX_TRANSPARENT_TYPE; - buf[p++] = modes->transparentPixel; - buf[p++] = GLX_TRANSPARENT_RED_VALUE; - buf[p++] = modes->transparentRed; - buf[p++] = GLX_TRANSPARENT_GREEN_VALUE; - buf[p++] = modes->transparentGreen; - buf[p++] = GLX_TRANSPARENT_BLUE_VALUE; - buf[p++] = modes->transparentBlue; - buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE; - buf[p++] = modes->transparentAlpha; - buf[p++] = GLX_TRANSPARENT_INDEX_VALUE; - buf[p++] = modes->transparentIndex; - buf[p++] = GLX_SAMPLES_SGIS; - buf[p++] = modes->samples; - buf[p++] = GLX_SAMPLE_BUFFERS_SGIS; - buf[p++] = modes->sampleBuffers; - buf[p++] = 0; /* copy over visualSelectGroup (GLX_VISUAL_SELECT_GROUP_SGIX)? */ - buf[p++] = 0; - - assert(p == GLX_VIS_CONFIG_TOTAL); - if (client->swapped) { - __GLX_SWAP_INT_ARRAY(buf, p); - } - WriteToClient(client, __GLX_SIZE_CARD32 * p, (char *)buf); - } - return Success; -} - -#define __GLX_TOTAL_FBCONFIG_ATTRIBS (36) -#define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2) -/** - * Send the set of GLXFBConfigs to the client. There is not currently - * and interface into the driver on the server-side to get GLXFBConfigs, - * so we "invent" some based on the \c __GLXvisualConfig structures that - * the driver does supply. - * - * The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX - * is the same, so this routine pulls double duty. - */ - -static int -DoGetFBConfigs(__GLXclientState *cl, unsigned screen) -{ - ClientPtr client = cl->client; - xGLXGetFBConfigsReply reply; - __GLXscreen *pGlxScreen; - CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH]; - int p, err; - __GLXconfig *modes; - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_DECLARE_SWAP_ARRAY_VARIABLES; - - if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err)) - return err; - - reply.numFBConfigs = pGlxScreen->numFBConfigs; - reply.numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS; - reply.length = (__GLX_FBCONFIG_ATTRIBS_LENGTH * reply.numFBConfigs); - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - if (client->swapped) { - __GLX_SWAP_SHORT(&reply.sequenceNumber); - __GLX_SWAP_INT(&reply.length); - __GLX_SWAP_INT(&reply.numFBConfigs); - __GLX_SWAP_INT(&reply.numAttribs); - } - - WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply); - - for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) { - p = 0; - -#define WRITE_PAIR(tag,value) \ - do { buf[p++] = tag ; buf[p++] = value ; } while( 0 ) - - WRITE_PAIR( GLX_VISUAL_ID, modes->visualID ); - WRITE_PAIR( GLX_FBCONFIG_ID, modes->fbconfigID ); - WRITE_PAIR( GLX_X_RENDERABLE, GL_TRUE ); - - WRITE_PAIR( GLX_RGBA, - (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE ); - WRITE_PAIR( GLX_RENDER_TYPE, modes->renderType ); - WRITE_PAIR( GLX_DOUBLEBUFFER, modes->doubleBufferMode ); - WRITE_PAIR( GLX_STEREO, modes->stereoMode ); - - WRITE_PAIR( GLX_BUFFER_SIZE, modes->rgbBits ); - WRITE_PAIR( GLX_LEVEL, modes->level ); - WRITE_PAIR( GLX_AUX_BUFFERS, modes->numAuxBuffers ); - WRITE_PAIR( GLX_RED_SIZE, modes->redBits ); - WRITE_PAIR( GLX_GREEN_SIZE, modes->greenBits ); - WRITE_PAIR( GLX_BLUE_SIZE, modes->blueBits ); - WRITE_PAIR( GLX_ALPHA_SIZE, modes->alphaBits ); - WRITE_PAIR( GLX_ACCUM_RED_SIZE, modes->accumRedBits ); - WRITE_PAIR( GLX_ACCUM_GREEN_SIZE, modes->accumGreenBits ); - WRITE_PAIR( GLX_ACCUM_BLUE_SIZE, modes->accumBlueBits ); - WRITE_PAIR( GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits ); - WRITE_PAIR( GLX_DEPTH_SIZE, modes->depthBits ); - WRITE_PAIR( GLX_STENCIL_SIZE, modes->stencilBits ); - WRITE_PAIR( GLX_X_VISUAL_TYPE, modes->visualType ); - WRITE_PAIR( GLX_CONFIG_CAVEAT, modes->visualRating ); - WRITE_PAIR( GLX_TRANSPARENT_TYPE, modes->transparentPixel ); - WRITE_PAIR( GLX_TRANSPARENT_RED_VALUE, modes->transparentRed ); - WRITE_PAIR( GLX_TRANSPARENT_GREEN_VALUE, modes->transparentGreen ); - WRITE_PAIR( GLX_TRANSPARENT_BLUE_VALUE, modes->transparentBlue ); - WRITE_PAIR( GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha ); - WRITE_PAIR( GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex ); - WRITE_PAIR( GLX_SWAP_METHOD_OML, modes->swapMethod ); - WRITE_PAIR( GLX_SAMPLES_SGIS, modes->samples ); - WRITE_PAIR( GLX_SAMPLE_BUFFERS_SGIS, modes->sampleBuffers ); - /* GLX_VISUAL_SELECT_GROUP_SGIX ? */ - WRITE_PAIR( GLX_DRAWABLE_TYPE, modes->drawableType ); - WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGB_EXT, modes->bindToTextureRgb ); - WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGBA_EXT, modes->bindToTextureRgba ); - WRITE_PAIR( GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture ); - WRITE_PAIR( GLX_BIND_TO_TEXTURE_TARGETS_EXT, modes->bindToTextureTargets ); - - if (client->swapped) { - __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH); - } - WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_FBCONFIG_ATTRIBS_LENGTH, - (char *)buf); - } - return Success; -} - - -int __glXDisp_GetFBConfigs(__GLXclientState *cl, GLbyte *pc) -{ - xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc; - return DoGetFBConfigs(cl, req->screen); -} - -int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc) -{ - xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc; - return DoGetFBConfigs(cl, req->screen); -} - -GLboolean -__glXDrawableInit(__GLXdrawable *drawable, - __GLXscreen *screen, DrawablePtr pDraw, int type, - XID drawId, __GLXconfig *config) -{ - drawable->pDraw = pDraw; - drawable->type = type; - drawable->drawId = drawId; - drawable->config = config; - drawable->eventMask = 0; - - return GL_TRUE; -} - -void -__glXDrawableRelease(__GLXdrawable *drawable) -{ - ScreenPtr pScreen = drawable->pDraw->pScreen; - - switch (drawable->type) { - case GLX_DRAWABLE_PIXMAP: - case GLX_DRAWABLE_PBUFFER: - (*pScreen->DestroyPixmap)((PixmapPtr) drawable->pDraw); - break; - } -} - -static int -DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config, - DrawablePtr pDraw, XID glxDrawableId, int type) -{ - __GLXdrawable *pGlxDraw; - - LEGAL_NEW_RESOURCE(glxDrawableId, client); - - if (pGlxScreen->pScreen != pDraw->pScreen) - return BadMatch; - - pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw, type, - glxDrawableId, config); - if (pGlxDraw == NULL) - return BadAlloc; - - if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw)) { - pGlxDraw->destroy (pGlxDraw); - return BadAlloc; - } - - return Success; -} - -static int -DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config, - XID drawableId, XID glxDrawableId) -{ - DrawablePtr pDraw; - int err; - - err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess); - if (err != Success) { - client->errorValue = drawableId; - return err; - } - if (pDraw->type != DRAWABLE_PIXMAP) { - client->errorValue = drawableId; - return BadPixmap; - } - - err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw, - glxDrawableId, GLX_DRAWABLE_PIXMAP); - - if (err == Success) - ((PixmapPtr) pDraw)->refcnt++; - - return err; -} - -static void -determineTextureTarget(ClientPtr client, XID glxDrawableID, - CARD32 *attribs, CARD32 numAttribs) -{ - GLenum target = 0; - GLenum format = 0; - int i, err; - __GLXdrawable *pGlxDraw; - - if (!validGlxDrawable(client, glxDrawableID, GLX_DRAWABLE_PIXMAP, - DixWriteAccess, &pGlxDraw, &err)) - /* We just added it in CreatePixmap, so we should never get here. */ - return; - - for (i = 0; i < numAttribs; i++) { - if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) { - switch (attribs[2 * i + 1]) { - case GLX_TEXTURE_2D_EXT: - target = GL_TEXTURE_2D; - break; - case GLX_TEXTURE_RECTANGLE_EXT: - target = GL_TEXTURE_RECTANGLE_ARB; - break; - } - } - - if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT) - format = attribs[2 * i + 1]; - } - - if (!target) { - int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height; - - if (h & (h - 1) || w & (w - 1)) - target = GL_TEXTURE_RECTANGLE_ARB; - else - target = GL_TEXTURE_2D; - } - - pGlxDraw->target = target; - pGlxDraw->format = format; -} - -int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc; - __GLXconfig *config; - __GLXscreen *pGlxScreen; - int err; - - if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) - return err; - if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err)) - return err; - - return DoCreateGLXPixmap(cl->client, pGlxScreen, config, - req->pixmap, req->glxpixmap); -} - -int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc; - __GLXconfig *config; - __GLXscreen *pGlxScreen; - int err; - - if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) - return err; - if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) - return err; - - err = DoCreateGLXPixmap(cl->client, pGlxScreen, config, - req->pixmap, req->glxpixmap); - if (err != Success) - return err; - - determineTextureTarget(cl->client, req->glxpixmap, - (CARD32*) (req + 1), req->numAttribs); - - return Success; -} - -int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreateGLXPixmapWithConfigSGIXReq *req = - (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc; - __GLXconfig *config; - __GLXscreen *pGlxScreen; - int err; - - if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err)) - return err; - if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err)) - return err; - - return DoCreateGLXPixmap(cl->client, pGlxScreen, - config, req->pixmap, req->glxpixmap); -} - - -static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type) -{ - __GLXdrawable *pGlxDraw; - int err; - - if (!validGlxDrawable(cl->client, glxdrawable, type, - DixDestroyAccess, &pGlxDraw, &err)) - return err; - - FreeResource(glxdrawable, FALSE); - - return Success; -} - -int __glXDisp_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc) -{ - xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc; - - return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP); -} - -int __glXDisp_DestroyPixmap(__GLXclientState *cl, GLbyte *pc) -{ - xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc; - - return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP); -} - -static int -DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId, - int width, int height, XID glxDrawableId) -{ - __GLXconfig *config; - __GLXscreen *pGlxScreen; - PixmapPtr pPixmap; - int err; - - if (!validGlxScreen(client, screenNum, &pGlxScreen, &err)) - return err; - if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err)) - return err; - - __glXenterServer(GL_FALSE); - pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen, - width, height, config->rgbBits, 0); - __glXleaveServer(GL_FALSE); - - return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable, - glxDrawableId, GLX_DRAWABLE_PBUFFER); -} - -int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc; - CARD32 *attrs; - int width, height, i; - - attrs = (CARD32 *) (req + 1); - width = 0; - height = 0; - - for (i = 0; i < req->numAttribs; i++) { - switch (attrs[i * 2]) { - case GLX_PBUFFER_WIDTH: - width = attrs[i * 2 + 1]; - break; - case GLX_PBUFFER_HEIGHT: - height = attrs[i * 2 + 1]; - break; - case GLX_LARGEST_PBUFFER: - case GLX_PRESERVED_CONTENTS: - /* FIXME: huh... */ - break; - } - } - - return DoCreatePbuffer(cl->client, req->screen, req->fbconfig, - width, height, req->pbuffer); -} - -int __glXDisp_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc; - - return DoCreatePbuffer(cl->client, req->screen, req->fbconfig, - req->width, req->height, req->pbuffer); -} - -int __glXDisp_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc) -{ - xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc; - - return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER); -} - -int __glXDisp_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc) -{ - xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc; - - return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER); -} - -static int -DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable, - int numAttribs, CARD32 *attribs) -{ - __GLXdrawable *pGlxDraw; - int i, err; - - if (!validGlxDrawable(client, glxdrawable, GLX_DRAWABLE_ANY, - DixSetAttrAccess, &pGlxDraw, &err)) - return err; - - for (i = 0; i < numAttribs; i++) { - switch(attribs[i * 2]) { - case GLX_EVENT_MASK: - /* All we do is to record the event mask so we can send it - * back when queried. We never actually clobber the - * pbuffers, so we never need to send out the event. */ - pGlxDraw->eventMask = attribs[i * 2 + 1]; - break; - } - } - - return Success; -} - -int __glXDisp_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc) -{ - xGLXChangeDrawableAttributesReq *req = - (xGLXChangeDrawableAttributesReq *) pc; - - return DoChangeDrawableAttributes(cl->client, req->drawable, - req->numAttribs, (CARD32 *) (req + 1)); -} - -int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc) -{ - xGLXChangeDrawableAttributesSGIXReq *req = - (xGLXChangeDrawableAttributesSGIXReq *)pc; - - return DoChangeDrawableAttributes(cl->client, req->drawable, - req->numAttribs, (CARD32 *) (req + 1)); -} - -int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc) -{ - xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc; - __GLXconfig *config; - __GLXscreen *pGlxScreen; - ClientPtr client = cl->client; - DrawablePtr pDraw; - int err; - - if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) - return err; - if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err)) - return err; - - err = dixLookupDrawable(&pDraw, req->window, client, 0, DixAddAccess); - if (err != Success || pDraw->type != DRAWABLE_WINDOW) { - client->errorValue = req->window; - return BadWindow; - } - - if (!validGlxFBConfigForWindow(client, config, pDraw, &err)) - return err; - - return DoCreateGLXDrawable(client, pGlxScreen, config, - pDraw, req->glxwindow, GLX_DRAWABLE_WINDOW); -} - -int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc) -{ - xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc; - - return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW); -} - - -/*****************************************************************************/ - -/* -** NOTE: There is no portable implementation for swap buffers as of -** this time that is of value. Consequently, this code must be -** implemented by somebody other than SGI. -*/ -int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc; - GLXContextTag tag = req->contextTag; - XID drawId = req->drawable; - __GLXcontext *glxc = NULL; - __GLXdrawable *pGlxDraw; - int error; - - if (tag) { - glxc = __glXLookupContextByTag(cl, tag); - if (!glxc) { - return __glXError(GLXBadContextTag); - } - /* - ** The calling thread is swapping its current drawable. In this case, - ** glxSwapBuffers is in both GL and X streams, in terms of - ** sequentiality. - */ - if (__glXForceCurrent(cl, tag, &error)) { - /* - ** Do whatever is needed to make sure that all preceding requests - ** in both streams are completed before the swap is executed. - */ - CALL_Finish( GET_DISPATCH(), () ); - __GLX_NOTE_FLUSHED_CMDS(glxc); - } else { - return error; - } - } - - pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error); - if (pGlxDraw == NULL) - return error; - - if (pGlxDraw->type == DRAWABLE_WINDOW && - (*pGlxDraw->swapBuffers)(cl->client, pGlxDraw) == GL_FALSE) - return __glXError(GLXBadDrawable); - - return Success; -} - - -static int -DoQueryContext(__GLXclientState *cl, GLXContextID gcId) -{ - ClientPtr client = cl->client; - __GLXcontext *ctx; - xGLXQueryContextInfoEXTReply reply; - int nProps; - int *sendBuf, *pSendBuf; - int nReplyBytes; - int err; - - if (!validGlxContext(cl->client, gcId, DixReadAccess, &ctx, &err)) - return err; - - nProps = 3; - reply.length = nProps << 1; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.n = nProps; - - nReplyBytes = reply.length << 2; - sendBuf = (int *)xalloc((size_t)nReplyBytes); - if (sendBuf == NULL) { - return __glXError(GLXBadContext); /* XXX: Is this correct? */ - } - pSendBuf = sendBuf; - *pSendBuf++ = GLX_SHARE_CONTEXT_EXT; - *pSendBuf++ = (int)(ctx->share_id); - *pSendBuf++ = GLX_VISUAL_ID_EXT; - *pSendBuf++ = (int)(ctx->config->visualID); - *pSendBuf++ = GLX_SCREEN_EXT; - *pSendBuf++ = (int)(ctx->pGlxScreen->pScreen->myNum); - - if (client->swapped) { - __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf); - } else { - WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply); - WriteToClient(client, nReplyBytes, (char *)sendBuf); - } - xfree((char *)sendBuf); - - return Success; -} - -int __glXDisp_QueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc) -{ - xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc; - - return DoQueryContext(cl, req->context); -} - -int __glXDisp_QueryContext(__GLXclientState *cl, GLbyte *pc) -{ - xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc; - - return DoQueryContext(cl, req->context); -} - -int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc) -{ - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; - ClientPtr client = cl->client; - __GLXcontext *context; - __GLXdrawable *pGlxDraw; - GLXDrawable drawId; - int buffer; - int error; - - pc += __GLX_VENDPRIV_HDR_SIZE; - - drawId = *((CARD32 *) (pc)); - buffer = *((INT32 *) (pc + 4)); - - if (buffer != GLX_FRONT_LEFT_EXT) - return __glXError(GLXBadPixmap); - - context = __glXForceCurrent (cl, req->contextTag, &error); - if (!context) - return error; - - if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP, - DixReadAccess, &pGlxDraw, &error)) - return error; - - if (!context->textureFromPixmap) - return __glXError(GLXUnsupportedPrivateRequest); - - return context->textureFromPixmap->bindTexImage(context, - buffer, - pGlxDraw); -} - -int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc) -{ - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; - ClientPtr client = cl->client; - __GLXdrawable *pGlxDraw; - __GLXcontext *context; - GLXDrawable drawId; - int buffer; - int error; - - pc += __GLX_VENDPRIV_HDR_SIZE; - - drawId = *((CARD32 *) (pc)); - buffer = *((INT32 *) (pc + 4)); - - context = __glXForceCurrent (cl, req->contextTag, &error); - if (!context) - return error; - - if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP, - DixReadAccess, &pGlxDraw, &error)) - return error; - - if (!context->textureFromPixmap) - return __glXError(GLXUnsupportedPrivateRequest); - - return context->textureFromPixmap->releaseTexImage(context, - buffer, - pGlxDraw); -} - -int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc) -{ - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; - GLXContextTag tag = req->contextTag; - __GLXcontext *glxc = NULL; - __GLXdrawable *pGlxDraw; - ClientPtr client = cl->client; - GLXDrawable drawId; - int error; - int x, y, width, height; - - (void) client; - (void) req; - - pc += __GLX_VENDPRIV_HDR_SIZE; - - drawId = *((CARD32 *) (pc)); - x = *((INT32 *) (pc + 4)); - y = *((INT32 *) (pc + 8)); - width = *((INT32 *) (pc + 12)); - height = *((INT32 *) (pc + 16)); - - if (tag) { - glxc = __glXLookupContextByTag(cl, tag); - if (!glxc) { - return __glXError(GLXBadContextTag); - } - /* - ** The calling thread is swapping its current drawable. In this case, - ** glxSwapBuffers is in both GL and X streams, in terms of - ** sequentiality. - */ - if (__glXForceCurrent(cl, tag, &error)) { - /* - ** Do whatever is needed to make sure that all preceding requests - ** in both streams are completed before the swap is executed. - */ - CALL_Finish( GET_DISPATCH(), () ); - __GLX_NOTE_FLUSHED_CMDS(glxc); - } else { - return error; - } - } - - pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error); - if (!pGlxDraw) - return error; - - if (pGlxDraw == NULL || - pGlxDraw->type != GLX_DRAWABLE_WINDOW || - pGlxDraw->copySubBuffer == NULL) - return __glXError(GLXBadDrawable); - - (*pGlxDraw->copySubBuffer)(pGlxDraw, x, y, width, height); - - return Success; -} - -/* -** Get drawable attributes -*/ -static int -DoGetDrawableAttributes(__GLXclientState *cl, XID drawId) -{ - ClientPtr client = cl->client; - xGLXGetDrawableAttributesReply reply; - __GLXdrawable *pGlxDraw; - CARD32 attributes[6]; - int numAttribs, error; - - if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY, - DixGetAttrAccess, &pGlxDraw, &error)) - return error; - - numAttribs = 3; - reply.length = numAttribs << 1; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.numAttribs = numAttribs; - - attributes[0] = GLX_TEXTURE_TARGET_EXT; - attributes[1] = pGlxDraw->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT : - GLX_TEXTURE_RECTANGLE_EXT; - attributes[2] = GLX_Y_INVERTED_EXT; - attributes[3] = GL_FALSE; - attributes[4] = GLX_EVENT_MASK; - attributes[5] = pGlxDraw->eventMask; - - if (client->swapped) { - __glXSwapGetDrawableAttributesReply(client, &reply, attributes); - } else { - WriteToClient(client, sz_xGLXGetDrawableAttributesReply, - (char *)&reply); - WriteToClient(client, reply.length * sizeof (CARD32), - (char *)attributes); - } - - return Success; -} - -int __glXDisp_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc) -{ - xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc; - - return DoGetDrawableAttributes(cl, req->drawable); -} - -int __glXDisp_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc) -{ - xGLXGetDrawableAttributesSGIXReq *req = - (xGLXGetDrawableAttributesSGIXReq *)pc; - - return DoGetDrawableAttributes(cl, req->drawable); -} - -/************************************************************************/ - -/* -** Render and Renderlarge are not in the GLX API. They are used by the GLX -** client library to send batches of GL rendering commands. -*/ - -/* -** Execute all the drawing commands in a request. -*/ -int __glXDisp_Render(__GLXclientState *cl, GLbyte *pc) -{ - xGLXRenderReq *req; - ClientPtr client= cl->client; - int left, cmdlen, error; - int commandsDone; - CARD16 opcode; - __GLXrenderHeader *hdr; - __GLXcontext *glxc; - __GLX_DECLARE_SWAP_VARIABLES; - - req = (xGLXRenderReq *) pc; - if (client->swapped) { - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->contextTag); - } - - glxc = __glXForceCurrent(cl, req->contextTag, &error); - if (!glxc) { - return error; - } - - commandsDone = 0; - pc += sz_xGLXRenderReq; - left = (req->length << 2) - sz_xGLXRenderReq; - while (left > 0) { - __GLXrenderSizeData entry; - int extra; - __GLXdispatchRenderProcPtr proc; - int err; - - /* - ** Verify that the header length and the overall length agree. - ** Also, each command must be word aligned. - */ - hdr = (__GLXrenderHeader *) pc; - if (client->swapped) { - __GLX_SWAP_SHORT(&hdr->length); - __GLX_SWAP_SHORT(&hdr->opcode); - } - cmdlen = hdr->length; - opcode = hdr->opcode; - - /* - ** Check for core opcodes and grab entry data. - */ - err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry); - proc = (__GLXdispatchRenderProcPtr) - __glXGetProtocolDecodeFunction(& Render_dispatch_info, - opcode, client->swapped); - - if ((err < 0) || (proc == NULL)) { - client->errorValue = commandsDone; - return __glXError(GLXBadRenderRequest); - } - - if (entry.varsize) { - /* variable size command */ - extra = (*entry.varsize)(pc + __GLX_RENDER_HDR_SIZE, - client->swapped); - if (extra < 0) { - extra = 0; - } - if (cmdlen != __GLX_PAD(entry.bytes + extra)) { - return BadLength; - } - } else { - /* constant size command */ - if (cmdlen != __GLX_PAD(entry.bytes)) { - return BadLength; - } - } - if (left < cmdlen) { - return BadLength; - } - - /* - ** Skip over the header and execute the command. We allow the - ** caller to trash the command memory. This is useful especially - ** for things that require double alignment - they can just shift - ** the data towards lower memory (trashing the header) by 4 bytes - ** and achieve the required alignment. - */ - (*proc)(pc + __GLX_RENDER_HDR_SIZE); - pc += cmdlen; - left -= cmdlen; - commandsDone++; - } - __GLX_NOTE_UNFLUSHED_CMDS(glxc); - return Success; -} - - -/* -** Execute a large rendering request (one that spans multiple X requests). -*/ -int __glXDisp_RenderLarge(__GLXclientState *cl, GLbyte *pc) -{ - xGLXRenderLargeReq *req; - ClientPtr client= cl->client; - size_t dataBytes; - __GLXrenderLargeHeader *hdr; - __GLXcontext *glxc; - int error; - CARD16 opcode; - __GLX_DECLARE_SWAP_VARIABLES; - - req = (xGLXRenderLargeReq *) pc; - if (client->swapped) { - __GLX_SWAP_SHORT(&req->length); - __GLX_SWAP_INT(&req->contextTag); - __GLX_SWAP_INT(&req->dataBytes); - __GLX_SWAP_SHORT(&req->requestNumber); - __GLX_SWAP_SHORT(&req->requestTotal); - } - - glxc = __glXForceCurrent(cl, req->contextTag, &error); - if (!glxc) { - /* Reset in case this isn't 1st request. */ - __glXResetLargeCommandStatus(cl); - return error; - } - dataBytes = req->dataBytes; - - /* - ** Check the request length. - */ - if ((req->length << 2) != __GLX_PAD(dataBytes) + sz_xGLXRenderLargeReq) { - client->errorValue = req->length; - /* Reset in case this isn't 1st request. */ - __glXResetLargeCommandStatus(cl); - return BadLength; - } - pc += sz_xGLXRenderLargeReq; - - if (cl->largeCmdRequestsSoFar == 0) { - __GLXrenderSizeData entry; - int extra; - size_t cmdlen; - int err; - - /* - ** This is the first request of a multi request command. - ** Make enough space in the buffer, then copy the entire request. - */ - if (req->requestNumber != 1) { - client->errorValue = req->requestNumber; - return __glXError(GLXBadLargeRequest); - } - - hdr = (__GLXrenderLargeHeader *) pc; - if (client->swapped) { - __GLX_SWAP_INT(&hdr->length); - __GLX_SWAP_INT(&hdr->opcode); - } - cmdlen = hdr->length; - opcode = hdr->opcode; - - /* - ** Check for core opcodes and grab entry data. - */ - err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry); - if (err < 0) { - client->errorValue = opcode; - return __glXError(GLXBadLargeRequest); - } - - if (entry.varsize) { - /* - ** If it's a variable-size command (a command whose length must - ** be computed from its parameters), all the parameters needed - ** will be in the 1st request, so it's okay to do this. - */ - extra = (*entry.varsize)(pc + __GLX_RENDER_LARGE_HDR_SIZE, - client->swapped); - if (extra < 0) { - extra = 0; - } - /* large command's header is 4 bytes longer, so add 4 */ - if (cmdlen != __GLX_PAD(entry.bytes + 4 + extra)) { - return BadLength; - } - } else { - /* constant size command */ - if (cmdlen != __GLX_PAD(entry.bytes + 4)) { - return BadLength; - } - } - /* - ** Make enough space in the buffer, then copy the entire request. - */ - if (cl->largeCmdBufSize < cmdlen) { - if (!cl->largeCmdBuf) { - cl->largeCmdBuf = (GLbyte *) xalloc(cmdlen); - } else { - cl->largeCmdBuf = (GLbyte *) xrealloc(cl->largeCmdBuf, cmdlen); - } - if (!cl->largeCmdBuf) { - return BadAlloc; - } - cl->largeCmdBufSize = cmdlen; - } - memcpy(cl->largeCmdBuf, pc, dataBytes); - - cl->largeCmdBytesSoFar = dataBytes; - cl->largeCmdBytesTotal = cmdlen; - cl->largeCmdRequestsSoFar = 1; - cl->largeCmdRequestsTotal = req->requestTotal; - return Success; - - } else { - /* - ** We are receiving subsequent (i.e. not the first) requests of a - ** multi request command. - */ - - /* - ** Check the request number and the total request count. - */ - if (req->requestNumber != cl->largeCmdRequestsSoFar + 1) { - client->errorValue = req->requestNumber; - __glXResetLargeCommandStatus(cl); - return __glXError(GLXBadLargeRequest); - } - if (req->requestTotal != cl->largeCmdRequestsTotal) { - client->errorValue = req->requestTotal; - __glXResetLargeCommandStatus(cl); - return __glXError(GLXBadLargeRequest); - } - - /* - ** Check that we didn't get too much data. - */ - if ((cl->largeCmdBytesSoFar + dataBytes) > cl->largeCmdBytesTotal) { - client->errorValue = dataBytes; - __glXResetLargeCommandStatus(cl); - return __glXError(GLXBadLargeRequest); - } - memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, pc, dataBytes); - cl->largeCmdBytesSoFar += dataBytes; - cl->largeCmdRequestsSoFar++; - - if (req->requestNumber == cl->largeCmdRequestsTotal) { - __GLXdispatchRenderProcPtr proc; - - /* - ** This is the last request; it must have enough bytes to complete - ** the command. - */ - /* NOTE: the two pad macros have been added below; they are needed - ** because the client library pads the total byte count, but not - ** the per-request byte counts. The Protocol Encoding says the - ** total byte count should not be padded, so a proposal will be - ** made to the ARB to relax the padding constraint on the total - ** byte count, thus preserving backward compatibility. Meanwhile, - ** the padding done below fixes a bug that did not allow - ** large commands of odd sizes to be accepted by the server. - */ - if (__GLX_PAD(cl->largeCmdBytesSoFar) != - __GLX_PAD(cl->largeCmdBytesTotal)) { - client->errorValue = dataBytes; - __glXResetLargeCommandStatus(cl); - return __glXError(GLXBadLargeRequest); - } - hdr = (__GLXrenderLargeHeader *) cl->largeCmdBuf; - /* - ** The opcode and length field in the header had already been - ** swapped when the first request was received. - ** - ** Use the opcode to index into the procedure table. - */ - opcode = hdr->opcode; - - proc = (__GLXdispatchRenderProcPtr) - __glXGetProtocolDecodeFunction(& Render_dispatch_info, opcode, - client->swapped); - if (proc == NULL) { - client->errorValue = opcode; - return __glXError(GLXBadLargeRequest); - } - - /* - ** Skip over the header and execute the command. - */ - (*proc)(cl->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE); - __GLX_NOTE_UNFLUSHED_CMDS(glxc); - - /* - ** Reset for the next RenderLarge series. - */ - __glXResetLargeCommandStatus(cl); - } else { - /* - ** This is neither the first nor the last request. - */ - } - return Success; - } -} - -extern RESTYPE __glXSwapBarrierRes; - -int __glXDisp_BindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *) pc; - XID drawable = req->drawable; - int barrier = req->barrier; - DrawablePtr pDraw; - int screen, rc; - __GLXscreen *pGlxScreen; - - rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixGetAttrAccess); - pGlxScreen = glxGetScreen(pDraw->pScreen); - if (rc == Success && (pDraw->type == DRAWABLE_WINDOW)) { - screen = pDraw->pScreen->myNum; - if (pGlxScreen->swapBarrierFuncs) { - int ret = pGlxScreen->swapBarrierFuncs->bindSwapBarrierFunc(screen, drawable, barrier); - if (ret == Success) { - if (barrier) - /* add source for cleanup when drawable is gone */ - AddResource(drawable, __glXSwapBarrierRes, (pointer)(intptr_t)screen); - else - /* delete source */ - FreeResourceByType(drawable, __glXSwapBarrierRes, FALSE); - } - return ret; - } - } - client->errorValue = drawable; - return __glXError(GLXBadDrawable); -} - - -int __glXDisp_QueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXQueryMaxSwapBarriersSGIXReq *req = - (xGLXQueryMaxSwapBarriersSGIXReq *) pc; - xGLXQueryMaxSwapBarriersSGIXReply reply; - int screen = req->screen; - __GLXscreen *pGlxScreen; - - pGlxScreen = glxGetScreen(screenInfo.screens[screen]); - if (pGlxScreen->swapBarrierFuncs) - reply.max = pGlxScreen->swapBarrierFuncs->queryMaxSwapBarriersFunc(screen); - else - reply.max = 0; - - - reply.length = 0; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - - if (client->swapped) { - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_SWAP_SHORT(&reply.sequenceNumber); - } - - WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply, - (char *) &reply); - return Success; -} - -#define GLX_BAD_HYPERPIPE_SGIX 92 - -int __glXDisp_QueryHyperpipeNetworkSGIX(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXQueryHyperpipeNetworkSGIXReq * req = (xGLXQueryHyperpipeNetworkSGIXReq *) pc; - xGLXQueryHyperpipeNetworkSGIXReply reply; - int screen = req->screen; - void *rdata = NULL; - - int length=0; - int npipes=0; - - int n= 0; - __GLXscreen *pGlxScreen; - - pGlxScreen = glxGetScreen(screenInfo.screens[screen]); - if (pGlxScreen->hyperpipeFuncs) { - rdata = - (pGlxScreen->hyperpipeFuncs->queryHyperpipeNetworkFunc(screen, &npipes, &n)); - } - length = __GLX_PAD(n) >> 2; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = length; - reply.n = n; - reply.npipes = npipes; - - if (client->swapped) { - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_SWAP_SHORT(&reply.sequenceNumber); - __GLX_SWAP_INT(&reply.length); - __GLX_SWAP_INT(&reply.n); - __GLX_SWAP_INT(&reply.npipes); - } - WriteToClient(client, sz_xGLXQueryHyperpipeNetworkSGIXReply, - (char *) &reply); - - WriteToClient(client, length << 2, (char *)rdata); - - return Success; -} - -int __glXDisp_DestroyHyperpipeConfigSGIX (__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXDestroyHyperpipeConfigSGIXReq * req = - (xGLXDestroyHyperpipeConfigSGIXReq *) pc; - xGLXDestroyHyperpipeConfigSGIXReply reply; - int screen = req->screen; - int success = GLX_BAD_HYPERPIPE_SGIX; - int hpId ; - __GLXscreen *pGlxScreen; - - hpId = req->hpId; - - pGlxScreen = glxGetScreen(screenInfo.screens[screen]); - if (pGlxScreen->hyperpipeFuncs) { - success = pGlxScreen->hyperpipeFuncs->destroyHyperpipeConfigFunc(screen, hpId); - } - - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = __GLX_PAD(0) >> 2; - reply.n = 0; - reply.success = success; - - - if (client->swapped) { - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_SWAP_SHORT(&reply.sequenceNumber); - } - WriteToClient(client, - sz_xGLXDestroyHyperpipeConfigSGIXReply, - (char *) &reply); - return Success; -} - -int __glXDisp_QueryHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXQueryHyperpipeConfigSGIXReq * req = - (xGLXQueryHyperpipeConfigSGIXReq *) pc; - xGLXQueryHyperpipeConfigSGIXReply reply; - int screen = req->screen; - void *rdata = NULL; - int length; - int npipes=0; - int n= 0; - int hpId; - __GLXscreen *pGlxScreen; - - hpId = req->hpId; - - pGlxScreen = glxGetScreen(screenInfo.screens[screen]); - if (pGlxScreen->hyperpipeFuncs) { - rdata = pGlxScreen->hyperpipeFuncs->queryHyperpipeConfigFunc(screen, hpId,&npipes, &n); - } - - length = __GLX_PAD(n) >> 2; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = length; - reply.n = n; - reply.npipes = npipes; - - - if (client->swapped) { - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_SWAP_SHORT(&reply.sequenceNumber); - __GLX_SWAP_INT(&reply.length); - __GLX_SWAP_INT(&reply.n); - __GLX_SWAP_INT(&reply.npipes); - } - - WriteToClient(client, sz_xGLXQueryHyperpipeConfigSGIXReply, - (char *) &reply); - - WriteToClient(client, length << 2, (char *)rdata); - - return Success; -} - -int __glXDisp_HyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXHyperpipeConfigSGIXReq * req = - (xGLXHyperpipeConfigSGIXReq *) pc; - xGLXHyperpipeConfigSGIXReply reply; - int screen = req->screen; - void *rdata; - - int npipes=0, networkId; - int hpId=-1; - __GLXscreen *pGlxScreen; - - pGlxScreen = glxGetScreen(screenInfo.screens[screen]); - networkId = (int)req->networkId; - npipes = (int)req->npipes; - rdata = (void *)(req +1); - - if (pGlxScreen->hyperpipeFuncs) { - pGlxScreen->hyperpipeFuncs->hyperpipeConfigFunc(screen,networkId, - &hpId, &npipes, - (void *) rdata); - } - - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = __GLX_PAD(0) >> 2; - reply.n = 0; - reply.npipes = npipes; - reply.hpId = hpId; - - if (client->swapped) { - __GLX_DECLARE_SWAP_VARIABLES; - __GLX_SWAP_SHORT(&reply.sequenceNumber); - __GLX_SWAP_INT(&reply.npipes); - __GLX_SWAP_INT(&reply.hpId); - } - - WriteToClient(client, sz_xGLXHyperpipeConfigSGIXReply, - (char *) &reply); - - return Success; -} - - -/************************************************************************/ - -/* -** No support is provided for the vendor-private requests other than -** allocating the entry points in the dispatch table. -*/ - -int __glXDisp_VendorPrivate(__GLXclientState *cl, GLbyte *pc) -{ - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; - GLint vendorcode = req->vendorCode; - __GLXdispatchVendorPrivProcPtr proc; - - - proc = (__GLXdispatchVendorPrivProcPtr) - __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info, - vendorcode, 0); - if (proc != NULL) { - (*proc)(cl, (GLbyte*)req); - return Success; - } - - cl->client->errorValue = req->vendorCode; - return __glXError(GLXUnsupportedPrivateRequest); -} - -int __glXDisp_VendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc) -{ - xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc; - GLint vendorcode = req->vendorCode; - __GLXdispatchVendorPrivProcPtr proc; - - - proc = (__GLXdispatchVendorPrivProcPtr) - __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info, - vendorcode, 0); - if (proc != NULL) { - return (*proc)(cl, (GLbyte*)req); - } - - cl->client->errorValue = vendorcode; - return __glXError(GLXUnsupportedPrivateRequest); -} - -int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc; - xGLXQueryExtensionsStringReply reply; - __GLXscreen *pGlxScreen; - size_t n, length; - char *buf; - int err; - - if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) - return err; - - n = strlen(pGlxScreen->GLXextensions) + 1; - length = __GLX_PAD(n) >> 2; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = length; - reply.n = n; - - /* Allocate buffer to make sure it's a multiple of 4 bytes big.*/ - buf = (char *) xalloc(length << 2); - if (buf == NULL) - return BadAlloc; - memcpy(buf, pGlxScreen->GLXextensions, n); - - if (client->swapped) { - glxSwapQueryExtensionsStringReply(client, &reply, buf); - } else { - WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply); - WriteToClient(client, (int)(length << 2), (char *)buf); - } - - xfree(buf); - return Success; -} - -int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc) -{ - ClientPtr client = cl->client; - xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc; - xGLXQueryServerStringReply reply; - size_t n, length; - const char *ptr; - char *buf; - __GLXscreen *pGlxScreen; - int err; - char ver_str[16]; - - if (!validGlxScreen(client, req->screen, &pGlxScreen, &err)) - return err; - - switch(req->name) { - case GLX_VENDOR: - ptr = pGlxScreen->GLXvendor; - break; - case GLX_VERSION: - /* Return to the server version rather than the screen version - * to prevent confusion when they do not match. - */ - snprintf(ver_str, 16, "%d.%d", glxMajorVersion, glxMinorVersion); - ptr = ver_str; - break; - case GLX_EXTENSIONS: - ptr = pGlxScreen->GLXextensions; - break; - default: - return BadValue; - } - - n = strlen(ptr) + 1; - length = __GLX_PAD(n) >> 2; - reply.type = X_Reply; - reply.sequenceNumber = client->sequence; - reply.length = length; - reply.n = n; - - buf = (char *) xalloc(length << 2); - if (buf == NULL) { - return BadAlloc; - } - memcpy(buf, ptr, n); - - if (client->swapped) { - glxSwapQueryServerStringReply(client, &reply, buf); - } else { - WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply); - WriteToClient(client, (int)(length << 2), buf); - } - - xfree(buf); - return Success; -} - -int __glXDisp_ClientInfo(__GLXclientState *cl, GLbyte *pc) -{ - xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc; - const char *buf; - - cl->GLClientmajorVersion = req->major; - cl->GLClientminorVersion = req->minor; - if (cl->GLClientextensions) - xfree(cl->GLClientextensions); - buf = (const char *)(req+1); - cl->GLClientextensions = xstrdup(buf); - - return Success; -} +/*
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * 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
+ * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#else
+
+#include "glheader.h"
+
+#endif
+
+#include <string.h>
+#include <assert.h>
+
+#include "glxserver.h"
+#include <GL/glxtokens.h>
+#include <unpack.h>
+#include "g_disptab.h"
+#include <pixmapstr.h>
+#include <windowstr.h>
+#include "glxutil.h"
+#include "glxext.h"
+#include "glapitable.h"
+#include "glapi.h"
+#include "glthread.h"
+#include "dispatch.h"
+#include "indirect_dispatch.h"
+#include "indirect_table.h"
+#include "indirect_util.h"
+
+static int
+validGlxScreen(ClientPtr client, int screen, __GLXscreen **pGlxScreen, int *err)
+{
+ /*
+ ** Check if screen exists.
+ */
+ if (screen >= screenInfo.numScreens) {
+ client->errorValue = screen;
+ *err = BadValue;
+ return FALSE;
+ }
+ *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+
+ return TRUE;
+}
+
+static int
+validGlxFBConfig(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
+ __GLXconfig **config, int *err)
+{
+ __GLXconfig *m;
+
+ for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next)
+ if (m->fbconfigID == id) {
+ *config = m;
+ return TRUE;
+ }
+
+ client->errorValue = id;
+ *err = __glXError(GLXBadFBConfig);
+
+ return FALSE;
+}
+
+static int
+validGlxVisual(ClientPtr client, __GLXscreen *pGlxScreen, XID id,
+ __GLXconfig **config, int *err)
+{
+ int i;
+
+ for (i = 0; i < pGlxScreen->numVisuals; i++)
+ if (pGlxScreen->visuals[i]->visualID == id) {
+ *config = pGlxScreen->visuals[i];
+ return TRUE;
+ }
+
+ client->errorValue = id;
+ *err = BadValue;
+
+ return FALSE;
+}
+
+static int
+validGlxFBConfigForWindow(ClientPtr client, __GLXconfig *config,
+ DrawablePtr pDraw, int *err)
+{
+ ScreenPtr pScreen = pDraw->pScreen;
+ VisualPtr pVisual = NULL;
+ XID vid;
+ int i;
+
+ vid = wVisual((WindowPtr)pDraw);
+ for (i = 0; i < pScreen->numVisuals; i++) {
+ if (pScreen->visuals[i].vid == vid) {
+ pVisual = &pScreen->visuals[i];
+ break;
+ }
+ }
+
+ /* FIXME: What exactly should we check here... */
+ if (pVisual->class != glxConvertToXVisualType(config->visualType) ||
+ !(config->drawableType & GLX_WINDOW_BIT)) {
+ client->errorValue = pDraw->id;
+ *err = BadMatch;
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int
+validGlxContext(ClientPtr client, XID id, int access_mode,
+ __GLXcontext **context, int *err)
+{
+ *err = dixLookupResourceByType((pointer *) context, id,
+ __glXContextRes, client, access_mode);
+ if (*err != Success) {
+ client->errorValue = id;
+ if (*err == BadValue)
+ *err = __glXError(GLXBadContext);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static int
+validGlxDrawable(ClientPtr client, XID id, int type, int access_mode,
+ __GLXdrawable **drawable, int *err)
+{
+ int rc;
+
+ rc = dixLookupResourceByType((pointer *) drawable, id,
+ __glXDrawableRes, client, access_mode);
+ if (rc != Success && rc != BadValue) {
+ *err = rc;
+ client->errorValue = id;
+ return FALSE;
+ }
+
+ if (rc == BadValue ||
+ (type != GLX_DRAWABLE_ANY && type != (*drawable)->type)) {
+ client->errorValue = id;
+ switch (type) {
+ case GLX_DRAWABLE_WINDOW:
+ *err = __glXError(GLXBadWindow);
+ return FALSE;
+ case GLX_DRAWABLE_PIXMAP:
+ *err = __glXError(GLXBadPixmap);
+ return FALSE;
+ case GLX_DRAWABLE_PBUFFER:
+ *err = __glXError(GLXBadPbuffer);
+ return FALSE;
+ case GLX_DRAWABLE_ANY:
+ *err = __glXError(GLXBadDrawable);
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+void
+__glXContextDestroy(__GLXcontext *context)
+{
+ __glXFlushContextCache();
+}
+
+static void __glXdirectContextDestroy(__GLXcontext *context)
+{
+ __glXContextDestroy(context);
+ xfree(context);
+}
+
+static __GLXcontext *__glXdirectContextCreate(__GLXscreen *screen,
+ __GLXconfig *modes,
+ __GLXcontext *shareContext)
+{
+ __GLXcontext *context;
+
+ context = xcalloc (1, sizeof (__GLXcontext));
+ if (context == NULL)
+ return NULL;
+
+ context->destroy = __glXdirectContextDestroy;
+
+ return context;
+}
+
+/**
+ * Create a GL context with the given properties. This routine is used
+ * to implement \c glXCreateContext, \c glXCreateNewContext, and
+ * \c glXCreateContextWithConfigSGIX. This works becuase of the hack way
+ * that GLXFBConfigs are implemented. Basically, the FBConfigID is the
+ * same as the VisualID.
+ */
+
+static int
+DoCreateContext(__GLXclientState *cl, GLXContextID gcId,
+ GLXContextID shareList, __GLXconfig *config,
+ __GLXscreen *pGlxScreen, GLboolean isDirect)
+{
+ ClientPtr client = cl->client;
+ __GLXcontext *glxc, *shareglxc;
+ int err;
+
+ LEGAL_NEW_RESOURCE(gcId, client);
+
+ /*
+ ** Find the display list space that we want to share.
+ **
+ ** NOTE: In a multithreaded X server, we would need to keep a reference
+ ** count for each display list so that if one client detroyed a list that
+ ** another client was using, the list would not really be freed until it
+ ** was no longer in use. Since this sample implementation has no support
+ ** for multithreaded servers, we don't do this.
+ */
+ if (shareList == None) {
+ shareglxc = 0;
+ } else {
+ if (!validGlxContext(client, shareList, DixReadAccess,
+ &shareglxc, &err))
+ return err;
+
+ if (shareglxc->isDirect) {
+ /*
+ ** NOTE: no support for sharing display lists between direct
+ ** contexts, even if they are in the same address space.
+ */
+#if 0
+ /* Disabling this code seems to allow shared display lists
+ * and texture objects to work. We'll leave it disabled for now.
+ */
+ client->errorValue = shareList;
+ return BadMatch;
+#endif
+ } else {
+ /*
+ ** Create an indirect context regardless of what the client asked
+ ** for; this way we can share display list space with shareList.
+ */
+ isDirect = GL_FALSE;
+ }
+ }
+
+ /*
+ ** Allocate memory for the new context
+ */
+ if (!isDirect)
+ glxc = pGlxScreen->createContext(pGlxScreen, config, shareglxc);
+ else
+ glxc = __glXdirectContextCreate(pGlxScreen, config, shareglxc);
+ if (!glxc) {
+ return BadAlloc;
+ }
+
+ /*
+ ** Initially, setup the part of the context that could be used by
+ ** a GL core that needs windowing information (e.g., Mesa).
+ */
+ glxc->pGlxScreen = pGlxScreen;
+ glxc->config = config;
+
+ /*
+ ** Register this context as a resource.
+ */
+ if (!AddResource(gcId, __glXContextRes, (pointer)glxc)) {
+ (*glxc->destroy)(glxc);
+ client->errorValue = gcId;
+ return BadAlloc;
+ }
+
+ /*
+ ** Finally, now that everything is working, setup the rest of the
+ ** context.
+ */
+ glxc->id = gcId;
+ glxc->share_id = shareList;
+ glxc->idExists = GL_TRUE;
+ glxc->isCurrent = GL_FALSE;
+ glxc->isDirect = isDirect;
+ glxc->renderMode = GL_RENDER;
+
+ __glXAddToContextList(glxc);
+
+ return Success;
+}
+
+int __glXDisp_CreateContext(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateContextReq *req = (xGLXCreateContextReq *) pc;
+ __GLXconfig *config;
+ __GLXscreen *pGlxScreen;
+ int err;
+
+ if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
+ return err;
+ if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
+ return err;
+
+ return DoCreateContext(cl, req->context, req->shareList,
+ config, pGlxScreen, req->isDirect);
+}
+
+int __glXDisp_CreateNewContext(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateNewContextReq *req = (xGLXCreateNewContextReq *) pc;
+ __GLXconfig *config;
+ __GLXscreen *pGlxScreen;
+ int err;
+
+ if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
+ return err;
+ if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
+ return err;
+
+ return DoCreateContext(cl, req->context, req->shareList,
+ config, pGlxScreen, req->isDirect);
+}
+
+int __glXDisp_CreateContextWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateContextWithConfigSGIXReq *req =
+ (xGLXCreateContextWithConfigSGIXReq *) pc;
+ __GLXconfig *config;
+ __GLXscreen *pGlxScreen;
+ int err;
+
+ if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
+ return err;
+ if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
+ return err;
+
+ return DoCreateContext(cl, req->context, req->shareList,
+ config, pGlxScreen, req->isDirect);
+}
+int __glXDisp_DestroyContext(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXDestroyContextReq *req = (xGLXDestroyContextReq *) pc;
+ __GLXcontext *glxc;
+ int err;
+
+ if (!validGlxContext(cl->client, req->context, DixDestroyAccess,
+ &glxc, &err))
+ return err;
+
+ FreeResourceByType(req->context, __glXContextRes, FALSE);
+ return Success;
+}
+
+/*****************************************************************************/
+
+/*
+** For each client, the server keeps a table of all the contexts that are
+** current for that client (each thread of a client may have its own current
+** context). These routines add, change, and lookup contexts in the table.
+*/
+
+/*
+** Add a current context, and return the tag that will be used to refer to it.
+*/
+static int AddCurrentContext(__GLXclientState *cl, __GLXcontext *glxc)
+{
+ int i;
+ int num = cl->numCurrentContexts;
+ __GLXcontext **table = cl->currentContexts;
+
+ if (!glxc) return -1;
+
+ /*
+ ** Try to find an empty slot and use it.
+ */
+ for (i=0; i < num; i++) {
+ if (!table[i]) {
+ table[i] = glxc;
+ return i+1;
+ }
+ }
+ /*
+ ** Didn't find a free slot, so we'll have to grow the table.
+ */
+ if (!num) {
+ table = (__GLXcontext **) xalloc(sizeof(__GLXcontext *));
+ } else {
+ table = (__GLXcontext **) xrealloc(table,
+ (num+1)*sizeof(__GLXcontext *));
+ }
+ table[num] = glxc;
+ cl->currentContexts = table;
+ cl->numCurrentContexts++;
+ return num+1;
+}
+
+/*
+** Given a tag, change the current context for the corresponding entry.
+*/
+static void ChangeCurrentContext(__GLXclientState *cl, __GLXcontext *glxc,
+ GLXContextTag tag)
+{
+ __GLXcontext **table = cl->currentContexts;
+ table[tag-1] = glxc;
+}
+
+/*
+** For this implementation we have chosen to simply use the index of the
+** context's entry in the table as the context tag. A tag must be greater
+** than 0.
+*/
+__GLXcontext *__glXLookupContextByTag(__GLXclientState *cl, GLXContextTag tag)
+{
+ int num = cl->numCurrentContexts;
+
+ if (tag < 1 || tag > num) {
+ return 0;
+ } else {
+ return cl->currentContexts[tag-1];
+ }
+}
+
+/*****************************************************************************/
+
+static void StopUsingContext(__GLXcontext *glxc)
+{
+ if (glxc) {
+ if (glxc == __glXLastContext) {
+ /* Tell server GL library */
+ __glXLastContext = 0;
+ }
+ glxc->isCurrent = GL_FALSE;
+ if (!glxc->idExists) {
+ __glXFreeContext(glxc);
+ }
+ }
+}
+
+static void StartUsingContext(__GLXclientState *cl, __GLXcontext *glxc)
+{
+ glxc->isCurrent = GL_TRUE;
+ __glXLastContext = glxc;
+}
+
+/**
+ * This is a helper function to handle the legacy (pre GLX 1.3) cases
+ * where passing an X window to glXMakeCurrent is valid. Given a
+ * resource ID, look up the GLX drawable if available, otherwise, make
+ * sure it's an X window and create a GLX drawable one the fly.
+ */
+static __GLXdrawable *
+__glXGetDrawable(__GLXcontext *glxc, GLXDrawable drawId, ClientPtr client,
+ int *error)
+{
+ DrawablePtr pDraw;
+ __GLXdrawable *pGlxDraw;
+ int rc;
+
+ if (validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
+ DixWriteAccess, &pGlxDraw, &rc)) {
+ if (glxc != NULL && pGlxDraw->config != glxc->config) {
+ client->errorValue = drawId;
+ *error = BadMatch;
+ return NULL;
+ }
+
+ return pGlxDraw;
+ }
+
+ /* The drawId wasn't a GLX drawable. Make sure it's a window and
+ * create a GLXWindow for it. Check that the drawable screen
+ * matches the context screen and that the context fbconfig is
+ * compatible with the window visual. */
+
+ rc = dixLookupDrawable(&pDraw, drawId, client, 0, DixGetAttrAccess);
+ if (rc != Success || pDraw->type != DRAWABLE_WINDOW) {
+ client->errorValue = drawId;
+ *error = __glXError(GLXBadDrawable);
+ return NULL;
+ }
+
+ if (pDraw->pScreen != glxc->pGlxScreen->pScreen) {
+ client->errorValue = pDraw->pScreen->myNum;
+ *error = BadMatch;
+ return NULL;
+ }
+
+ if (!validGlxFBConfigForWindow(client, glxc->config, pDraw, error))
+ return NULL;
+
+ pGlxDraw = glxc->pGlxScreen->createDrawable(glxc->pGlxScreen,
+ pDraw, GLX_DRAWABLE_WINDOW,
+ drawId, glxc->config);
+
+ /* since we are creating the drawablePrivate, drawId should be new */
+ if (!AddResource(drawId, __glXDrawableRes, pGlxDraw)) {
+ pGlxDraw->destroy (pGlxDraw);
+ *error = BadAlloc;
+ return NULL;
+ }
+
+ return pGlxDraw;
+}
+
+/*****************************************************************************/
+/*
+** Make an OpenGL context and drawable current.
+*/
+
+static int
+DoMakeCurrent(__GLXclientState *cl,
+ GLXDrawable drawId, GLXDrawable readId,
+ GLXContextID contextId, GLXContextTag tag)
+{
+ ClientPtr client = cl->client;
+ xGLXMakeCurrentReply reply;
+ __GLXcontext *glxc, *prevglxc;
+ __GLXdrawable *drawPriv = NULL;
+ __GLXdrawable *readPriv = NULL;
+ int error;
+ GLuint mask;
+
+ /*
+ ** If one is None and the other isn't, it's a bad match.
+ */
+
+ mask = (drawId == None) ? (1 << 0) : 0;
+ mask |= (readId == None) ? (1 << 1) : 0;
+ mask |= (contextId == None) ? (1 << 2) : 0;
+
+ if ( (mask != 0x00) && (mask != 0x07) ) {
+ return BadMatch;
+ }
+
+ /*
+ ** Lookup old context. If we have one, it must be in a usable state.
+ */
+ if (tag != 0) {
+ prevglxc = __glXLookupContextByTag(cl, tag);
+ if (!prevglxc) {
+ /*
+ ** Tag for previous context is invalid.
+ */
+ return __glXError(GLXBadContextTag);
+ }
+ if (prevglxc->renderMode != GL_RENDER) {
+ /* Oops. Not in render mode render. */
+ client->errorValue = prevglxc->id;
+ return __glXError(GLXBadContextState);
+ }
+ } else {
+ prevglxc = 0;
+ }
+
+ /*
+ ** Lookup new context. It must not be current for someone else.
+ */
+ if (contextId != None) {
+ int status;
+
+ if (!validGlxContext(client, contextId, DixUseAccess, &glxc, &error))
+ return error;
+ if ((glxc != prevglxc) && glxc->isCurrent) {
+ /* Context is current to somebody else */
+ return BadAccess;
+ }
+
+ assert( drawId != None );
+ assert( readId != None );
+
+ drawPriv = __glXGetDrawable(glxc, drawId, client, &status);
+ if (drawPriv == NULL)
+ return status;
+
+ readPriv = __glXGetDrawable(glxc, readId, client, &status);
+ if (readPriv == NULL)
+ return status;
+
+ } else {
+ /* Switching to no context. Ignore new drawable. */
+ glxc = 0;
+ drawPriv = 0;
+ readPriv = 0;
+ }
+
+
+ if (prevglxc) {
+ /*
+ ** Flush the previous context if needed.
+ */
+ if (__GLX_HAS_UNFLUSHED_CMDS(prevglxc)) {
+ if (__glXForceCurrent(cl, tag, (int *)&error)) {
+ CALL_Flush( GET_DISPATCH(), () );
+ __GLX_NOTE_FLUSHED_CMDS(prevglxc);
+ } else {
+ return error;
+ }
+ }
+
+ /*
+ ** Make the previous context not current.
+ */
+ if (!(*prevglxc->loseCurrent)(prevglxc)) {
+ return __glXError(GLXBadContext);
+ }
+ __glXFlushContextCache();
+ if (!prevglxc->isDirect) {
+ prevglxc->drawPriv = NULL;
+ prevglxc->readPriv = NULL;
+ }
+ }
+
+
+ if ((glxc != 0) && !glxc->isDirect) {
+
+ glxc->drawPriv = drawPriv;
+ glxc->readPriv = readPriv;
+
+ /* make the context current */
+ if (!(*glxc->makeCurrent)(glxc)) {
+ glxc->drawPriv = NULL;
+ glxc->readPriv = NULL;
+ return __glXError(GLXBadContext);
+ }
+
+ glxc->isCurrent = GL_TRUE;
+ }
+
+ if (prevglxc) {
+ ChangeCurrentContext(cl, glxc, tag);
+ StopUsingContext(prevglxc);
+ } else {
+ tag = AddCurrentContext(cl, glxc);
+ }
+
+ if (glxc) {
+ StartUsingContext(cl, glxc);
+ reply.contextTag = tag;
+ } else {
+ reply.contextTag = 0;
+ }
+
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ __glXSwapMakeCurrentReply(client, &reply);
+ } else {
+ WriteToClient(client, sz_xGLXMakeCurrentReply, (char *)&reply);
+ }
+ return Success;
+}
+
+int __glXDisp_MakeCurrent(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) pc;
+
+ return DoMakeCurrent( cl, req->drawable, req->drawable,
+ req->context, req->oldContextTag );
+}
+
+int __glXDisp_MakeContextCurrent(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXMakeContextCurrentReq *req = (xGLXMakeContextCurrentReq *) pc;
+
+ return DoMakeCurrent( cl, req->drawable, req->readdrawable,
+ req->context, req->oldContextTag );
+}
+
+int __glXDisp_MakeCurrentReadSGI(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXMakeCurrentReadSGIReq *req = (xGLXMakeCurrentReadSGIReq *) pc;
+
+ return DoMakeCurrent( cl, req->drawable, req->readable,
+ req->context, req->oldContextTag );
+}
+
+int __glXDisp_IsDirect(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXIsDirectReq *req = (xGLXIsDirectReq *) pc;
+ xGLXIsDirectReply reply;
+ __GLXcontext *glxc;
+ int err;
+
+ if (!validGlxContext(cl->client, req->context, DixReadAccess, &glxc, &err))
+ return err;
+
+ reply.isDirect = glxc->isDirect;
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ __glXSwapIsDirectReply(client, &reply);
+ } else {
+ WriteToClient(client, sz_xGLXIsDirectReply, (char *)&reply);
+ }
+
+ return Success;
+}
+
+int __glXDisp_QueryVersion(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryVersionReq *req = (xGLXQueryVersionReq *) pc;
+ xGLXQueryVersionReply reply;
+ GLuint major, minor;
+
+ major = req->majorVersion;
+ minor = req->minorVersion;
+ (void)major;
+ (void)minor;
+
+ /*
+ ** Server should take into consideration the version numbers sent by the
+ ** client if it wants to work with older clients; however, in this
+ ** implementation the server just returns its version number.
+ */
+ reply.majorVersion = glxMajorVersion;
+ reply.minorVersion = glxMinorVersion;
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ __glXSwapQueryVersionReply(client, &reply);
+ } else {
+ WriteToClient(client, sz_xGLXQueryVersionReply, (char *)&reply);
+ }
+ return Success;
+}
+
+int __glXDisp_WaitGL(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXWaitGLReq *req = (xGLXWaitGLReq *)pc;
+ GLXContextTag tag = req->contextTag;
+ __GLXcontext *glxc = NULL;
+ int error;
+
+ if (tag) {
+ glxc = __glXLookupContextByTag(cl, tag);
+ if (!glxc)
+ return __glXError(GLXBadContextTag);
+
+ if (!__glXForceCurrent(cl, req->contextTag, &error))
+ return error;
+
+ CALL_Finish( GET_DISPATCH(), () );
+ }
+
+ if (glxc && glxc->drawPriv->waitGL)
+ (*glxc->drawPriv->waitGL)(glxc->drawPriv);
+
+ return Success;
+}
+
+int __glXDisp_WaitX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXWaitXReq *req = (xGLXWaitXReq *)pc;
+ GLXContextTag tag = req->contextTag;
+ __GLXcontext *glxc = NULL;
+ int error;
+
+ if (tag) {
+ glxc = __glXLookupContextByTag(cl, tag);
+ if (!glxc)
+ return __glXError(GLXBadContextTag);
+
+ if (!__glXForceCurrent(cl, req->contextTag, &error))
+ return error;
+ }
+
+ if (glxc && glxc->drawPriv->waitX)
+ (*glxc->drawPriv->waitX)(glxc->drawPriv);
+
+ return Success;
+}
+
+int __glXDisp_CopyContext(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXCopyContextReq *req = (xGLXCopyContextReq *) pc;
+ GLXContextID source = req->source;
+ GLXContextID dest = req->dest;
+ GLXContextTag tag = req->contextTag;
+ unsigned long mask = req->mask;
+ __GLXcontext *src, *dst;
+ int error;
+
+ if (!validGlxContext(cl->client, source, DixReadAccess, &src, &error))
+ return error;
+ if (!validGlxContext(cl->client, dest, DixWriteAccess, &dst, &error))
+ return error;
+
+ /*
+ ** They must be in the same address space, and same screen.
+ ** NOTE: no support for direct rendering contexts here.
+ */
+ if (src->isDirect || dst->isDirect ||
+ (src->pGlxScreen != dst->pGlxScreen)) {
+ client->errorValue = source;
+ return BadMatch;
+ }
+
+ /*
+ ** The destination context must not be current for any client.
+ */
+ if (dst->isCurrent) {
+ client->errorValue = dest;
+ return BadAccess;
+ }
+
+ if (tag) {
+ __GLXcontext *tagcx = __glXLookupContextByTag(cl, tag);
+
+ if (!tagcx) {
+ return __glXError(GLXBadContextTag);
+ }
+ if (tagcx != src) {
+ /*
+ ** This would be caused by a faulty implementation of the client
+ ** library.
+ */
+ return BadMatch;
+ }
+ /*
+ ** In this case, glXCopyContext is in both GL and X streams, in terms
+ ** of sequentiality.
+ */
+ if (__glXForceCurrent(cl, tag, &error)) {
+ /*
+ ** Do whatever is needed to make sure that all preceding requests
+ ** in both streams are completed before the copy is executed.
+ */
+ CALL_Finish( GET_DISPATCH(), () );
+ __GLX_NOTE_FLUSHED_CMDS(tagcx);
+ } else {
+ return error;
+ }
+ }
+ /*
+ ** Issue copy. The only reason for failure is a bad mask.
+ */
+ if (!(*dst->copy)(dst, src, mask)) {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ return Success;
+}
+
+enum {
+ GLX_VIS_CONFIG_UNPAIRED = 18,
+ GLX_VIS_CONFIG_PAIRED = 20
+};
+
+enum {
+ GLX_VIS_CONFIG_TOTAL = GLX_VIS_CONFIG_UNPAIRED + GLX_VIS_CONFIG_PAIRED
+};
+
+int __glXDisp_GetVisualConfigs(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXGetVisualConfigsReq *req = (xGLXGetVisualConfigsReq *) pc;
+ ClientPtr client = cl->client;
+ xGLXGetVisualConfigsReply reply;
+ __GLXscreen *pGlxScreen;
+ __GLXconfig *modes;
+ CARD32 buf[GLX_VIS_CONFIG_TOTAL];
+ int p, i, err;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
+ return err;
+
+ reply.numVisuals = pGlxScreen->numVisuals;
+ reply.numProps = GLX_VIS_CONFIG_TOTAL;
+ reply.length = (reply.numVisuals * __GLX_SIZE_CARD32 * GLX_VIS_CONFIG_TOTAL) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.numVisuals);
+ __GLX_SWAP_INT(&reply.numProps);
+ }
+
+ WriteToClient(client, sz_xGLXGetVisualConfigsReply, (char *)&reply);
+
+ for (i = 0; i < pGlxScreen->numVisuals; i++) {
+ modes = pGlxScreen->visuals[i];
+
+ p = 0;
+ buf[p++] = modes->visualID;
+ buf[p++] = glxConvertToXVisualType( modes->visualType );
+ buf[p++] = (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE;
+
+ buf[p++] = modes->redBits;
+ buf[p++] = modes->greenBits;
+ buf[p++] = modes->blueBits;
+ buf[p++] = modes->alphaBits;
+ buf[p++] = modes->accumRedBits;
+ buf[p++] = modes->accumGreenBits;
+ buf[p++] = modes->accumBlueBits;
+ buf[p++] = modes->accumAlphaBits;
+
+ buf[p++] = modes->doubleBufferMode;
+ buf[p++] = modes->stereoMode;
+
+ buf[p++] = modes->rgbBits;
+ buf[p++] = modes->depthBits;
+ buf[p++] = modes->stencilBits;
+ buf[p++] = modes->numAuxBuffers;
+ buf[p++] = modes->level;
+
+ assert(p == GLX_VIS_CONFIG_UNPAIRED);
+ /*
+ ** Add token/value pairs for extensions.
+ */
+ buf[p++] = GLX_VISUAL_CAVEAT_EXT;
+ buf[p++] = modes->visualRating;
+ buf[p++] = GLX_TRANSPARENT_TYPE;
+ buf[p++] = modes->transparentPixel;
+ buf[p++] = GLX_TRANSPARENT_RED_VALUE;
+ buf[p++] = modes->transparentRed;
+ buf[p++] = GLX_TRANSPARENT_GREEN_VALUE;
+ buf[p++] = modes->transparentGreen;
+ buf[p++] = GLX_TRANSPARENT_BLUE_VALUE;
+ buf[p++] = modes->transparentBlue;
+ buf[p++] = GLX_TRANSPARENT_ALPHA_VALUE;
+ buf[p++] = modes->transparentAlpha;
+ buf[p++] = GLX_TRANSPARENT_INDEX_VALUE;
+ buf[p++] = modes->transparentIndex;
+ buf[p++] = GLX_SAMPLES_SGIS;
+ buf[p++] = modes->samples;
+ buf[p++] = GLX_SAMPLE_BUFFERS_SGIS;
+ buf[p++] = modes->sampleBuffers;
+ buf[p++] = 0; /* copy over visualSelectGroup (GLX_VISUAL_SELECT_GROUP_SGIX)? */
+ buf[p++] = 0;
+
+ assert(p == GLX_VIS_CONFIG_TOTAL);
+ if (client->swapped) {
+ __GLX_SWAP_INT_ARRAY(buf, p);
+ }
+ WriteToClient(client, __GLX_SIZE_CARD32 * p, (char *)buf);
+ }
+ return Success;
+}
+
+#define __GLX_TOTAL_FBCONFIG_ATTRIBS (36)
+#define __GLX_FBCONFIG_ATTRIBS_LENGTH (__GLX_TOTAL_FBCONFIG_ATTRIBS * 2)
+/**
+ * Send the set of GLXFBConfigs to the client. There is not currently
+ * and interface into the driver on the server-side to get GLXFBConfigs,
+ * so we "invent" some based on the \c __GLXvisualConfig structures that
+ * the driver does supply.
+ *
+ * The reply format for both \c glXGetFBConfigs and \c glXGetFBConfigsSGIX
+ * is the same, so this routine pulls double duty.
+ */
+
+static int
+DoGetFBConfigs(__GLXclientState *cl, unsigned screen)
+{
+ ClientPtr client = cl->client;
+ xGLXGetFBConfigsReply reply;
+ __GLXscreen *pGlxScreen;
+ CARD32 buf[__GLX_FBCONFIG_ATTRIBS_LENGTH];
+ int p, err;
+ __GLXconfig *modes;
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_DECLARE_SWAP_ARRAY_VARIABLES;
+
+ if (!validGlxScreen(cl->client, screen, &pGlxScreen, &err))
+ return err;
+
+ reply.numFBConfigs = pGlxScreen->numFBConfigs;
+ reply.numAttribs = __GLX_TOTAL_FBCONFIG_ATTRIBS;
+ reply.length = (__GLX_FBCONFIG_ATTRIBS_LENGTH * reply.numFBConfigs);
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.numFBConfigs);
+ __GLX_SWAP_INT(&reply.numAttribs);
+ }
+
+ WriteToClient(client, sz_xGLXGetFBConfigsReply, (char *)&reply);
+
+ for (modes = pGlxScreen->fbconfigs; modes != NULL; modes = modes->next) {
+ p = 0;
+
+#define WRITE_PAIR(tag,value) \
+ do { buf[p++] = tag ; buf[p++] = value ; } while( 0 )
+
+ WRITE_PAIR( GLX_VISUAL_ID, modes->visualID );
+ WRITE_PAIR( GLX_FBCONFIG_ID, modes->fbconfigID );
+ WRITE_PAIR( GLX_X_RENDERABLE, GL_TRUE );
+
+ WRITE_PAIR( GLX_RGBA,
+ (modes->renderType & GLX_RGBA_BIT) ? GL_TRUE : GL_FALSE );
+ WRITE_PAIR( GLX_RENDER_TYPE, modes->renderType );
+ WRITE_PAIR( GLX_DOUBLEBUFFER, modes->doubleBufferMode );
+ WRITE_PAIR( GLX_STEREO, modes->stereoMode );
+
+ WRITE_PAIR( GLX_BUFFER_SIZE, modes->rgbBits );
+ WRITE_PAIR( GLX_LEVEL, modes->level );
+ WRITE_PAIR( GLX_AUX_BUFFERS, modes->numAuxBuffers );
+ WRITE_PAIR( GLX_RED_SIZE, modes->redBits );
+ WRITE_PAIR( GLX_GREEN_SIZE, modes->greenBits );
+ WRITE_PAIR( GLX_BLUE_SIZE, modes->blueBits );
+ WRITE_PAIR( GLX_ALPHA_SIZE, modes->alphaBits );
+ WRITE_PAIR( GLX_ACCUM_RED_SIZE, modes->accumRedBits );
+ WRITE_PAIR( GLX_ACCUM_GREEN_SIZE, modes->accumGreenBits );
+ WRITE_PAIR( GLX_ACCUM_BLUE_SIZE, modes->accumBlueBits );
+ WRITE_PAIR( GLX_ACCUM_ALPHA_SIZE, modes->accumAlphaBits );
+ WRITE_PAIR( GLX_DEPTH_SIZE, modes->depthBits );
+ WRITE_PAIR( GLX_STENCIL_SIZE, modes->stencilBits );
+ WRITE_PAIR( GLX_X_VISUAL_TYPE, modes->visualType );
+ WRITE_PAIR( GLX_CONFIG_CAVEAT, modes->visualRating );
+ WRITE_PAIR( GLX_TRANSPARENT_TYPE, modes->transparentPixel );
+ WRITE_PAIR( GLX_TRANSPARENT_RED_VALUE, modes->transparentRed );
+ WRITE_PAIR( GLX_TRANSPARENT_GREEN_VALUE, modes->transparentGreen );
+ WRITE_PAIR( GLX_TRANSPARENT_BLUE_VALUE, modes->transparentBlue );
+ WRITE_PAIR( GLX_TRANSPARENT_ALPHA_VALUE, modes->transparentAlpha );
+ WRITE_PAIR( GLX_TRANSPARENT_INDEX_VALUE, modes->transparentIndex );
+ WRITE_PAIR( GLX_SWAP_METHOD_OML, modes->swapMethod );
+ WRITE_PAIR( GLX_SAMPLES_SGIS, modes->samples );
+ WRITE_PAIR( GLX_SAMPLE_BUFFERS_SGIS, modes->sampleBuffers );
+ /* GLX_VISUAL_SELECT_GROUP_SGIX ? */
+ WRITE_PAIR( GLX_DRAWABLE_TYPE, modes->drawableType );
+ WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGB_EXT, modes->bindToTextureRgb );
+ WRITE_PAIR( GLX_BIND_TO_TEXTURE_RGBA_EXT, modes->bindToTextureRgba );
+ WRITE_PAIR( GLX_BIND_TO_MIPMAP_TEXTURE_EXT, modes->bindToMipmapTexture );
+ WRITE_PAIR( GLX_BIND_TO_TEXTURE_TARGETS_EXT, modes->bindToTextureTargets );
+
+ if (client->swapped) {
+ __GLX_SWAP_INT_ARRAY(buf, __GLX_FBCONFIG_ATTRIBS_LENGTH);
+ }
+ WriteToClient(client, __GLX_SIZE_CARD32 * __GLX_FBCONFIG_ATTRIBS_LENGTH,
+ (char *)buf);
+ }
+ return Success;
+}
+
+
+int __glXDisp_GetFBConfigs(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXGetFBConfigsReq *req = (xGLXGetFBConfigsReq *) pc;
+ return DoGetFBConfigs(cl, req->screen);
+}
+
+int __glXDisp_GetFBConfigsSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXGetFBConfigsSGIXReq *req = (xGLXGetFBConfigsSGIXReq *) pc;
+ return DoGetFBConfigs(cl, req->screen);
+}
+
+GLboolean
+__glXDrawableInit(__GLXdrawable *drawable,
+ __GLXscreen *screen, DrawablePtr pDraw, int type,
+ XID drawId, __GLXconfig *config)
+{
+ drawable->pDraw = pDraw;
+ drawable->type = type;
+ drawable->drawId = drawId;
+ drawable->config = config;
+ drawable->eventMask = 0;
+
+ return GL_TRUE;
+}
+
+void
+__glXDrawableRelease(__GLXdrawable *drawable)
+{
+ ScreenPtr pScreen = drawable->pDraw->pScreen;
+
+ switch (drawable->type) {
+ case GLX_DRAWABLE_PIXMAP:
+ case GLX_DRAWABLE_PBUFFER:
+ (*pScreen->DestroyPixmap)((PixmapPtr) drawable->pDraw);
+ break;
+ }
+}
+
+static int
+DoCreateGLXDrawable(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config,
+ DrawablePtr pDraw, XID glxDrawableId, int type)
+{
+ __GLXdrawable *pGlxDraw;
+
+ LEGAL_NEW_RESOURCE(glxDrawableId, client);
+
+ if (pGlxScreen->pScreen != pDraw->pScreen)
+ return BadMatch;
+
+ pGlxDraw = pGlxScreen->createDrawable(pGlxScreen, pDraw, type,
+ glxDrawableId, config);
+ if (pGlxDraw == NULL)
+ return BadAlloc;
+
+ if (!AddResource(glxDrawableId, __glXDrawableRes, pGlxDraw)) {
+ pGlxDraw->destroy (pGlxDraw);
+ return BadAlloc;
+ }
+
+ return Success;
+}
+
+static int
+DoCreateGLXPixmap(ClientPtr client, __GLXscreen *pGlxScreen, __GLXconfig *config,
+ XID drawableId, XID glxDrawableId)
+{
+ DrawablePtr pDraw;
+ int err;
+
+ err = dixLookupDrawable(&pDraw, drawableId, client, 0, DixAddAccess);
+ if (err != Success) {
+ client->errorValue = drawableId;
+ return err;
+ }
+ if (pDraw->type != DRAWABLE_PIXMAP) {
+ client->errorValue = drawableId;
+ return BadPixmap;
+ }
+
+ err = DoCreateGLXDrawable(client, pGlxScreen, config, pDraw,
+ glxDrawableId, GLX_DRAWABLE_PIXMAP);
+
+ if (err == Success)
+ ((PixmapPtr) pDraw)->refcnt++;
+
+ return err;
+}
+
+static void
+determineTextureTarget(ClientPtr client, XID glxDrawableID,
+ CARD32 *attribs, CARD32 numAttribs)
+{
+ GLenum target = 0;
+ GLenum format = 0;
+ int i, err;
+ __GLXdrawable *pGlxDraw;
+
+ if (!validGlxDrawable(client, glxDrawableID, GLX_DRAWABLE_PIXMAP,
+ DixWriteAccess, &pGlxDraw, &err))
+ /* We just added it in CreatePixmap, so we should never get here. */
+ return;
+
+ for (i = 0; i < numAttribs; i++) {
+ if (attribs[2 * i] == GLX_TEXTURE_TARGET_EXT) {
+ switch (attribs[2 * i + 1]) {
+ case GLX_TEXTURE_2D_EXT:
+ target = GL_TEXTURE_2D;
+ break;
+ case GLX_TEXTURE_RECTANGLE_EXT:
+ target = GL_TEXTURE_RECTANGLE_ARB;
+ break;
+ }
+ }
+
+ if (attribs[2 * i] == GLX_TEXTURE_FORMAT_EXT)
+ format = attribs[2 * i + 1];
+ }
+
+ if (!target) {
+ int w = pGlxDraw->pDraw->width, h = pGlxDraw->pDraw->height;
+
+ if (h & (h - 1) || w & (w - 1))
+ target = GL_TEXTURE_RECTANGLE_ARB;
+ else
+ target = GL_TEXTURE_2D;
+ }
+
+ pGlxDraw->target = target;
+ pGlxDraw->format = format;
+}
+
+int __glXDisp_CreateGLXPixmap(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateGLXPixmapReq *req = (xGLXCreateGLXPixmapReq *) pc;
+ __GLXconfig *config;
+ __GLXscreen *pGlxScreen;
+ int err;
+
+ if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
+ return err;
+ if (!validGlxVisual(cl->client, pGlxScreen, req->visual, &config, &err))
+ return err;
+
+ return DoCreateGLXPixmap(cl->client, pGlxScreen, config,
+ req->pixmap, req->glxpixmap);
+}
+
+int __glXDisp_CreatePixmap(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreatePixmapReq *req = (xGLXCreatePixmapReq *) pc;
+ __GLXconfig *config;
+ __GLXscreen *pGlxScreen;
+ int err;
+
+ if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
+ return err;
+ if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
+ return err;
+
+ err = DoCreateGLXPixmap(cl->client, pGlxScreen, config,
+ req->pixmap, req->glxpixmap);
+ if (err != Success)
+ return err;
+
+ determineTextureTarget(cl->client, req->glxpixmap,
+ (CARD32*) (req + 1), req->numAttribs);
+
+ return Success;
+}
+
+int __glXDisp_CreateGLXPixmapWithConfigSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateGLXPixmapWithConfigSGIXReq *req =
+ (xGLXCreateGLXPixmapWithConfigSGIXReq *) pc;
+ __GLXconfig *config;
+ __GLXscreen *pGlxScreen;
+ int err;
+
+ if (!validGlxScreen(cl->client, req->screen, &pGlxScreen, &err))
+ return err;
+ if (!validGlxFBConfig(cl->client, pGlxScreen, req->fbconfig, &config, &err))
+ return err;
+
+ return DoCreateGLXPixmap(cl->client, pGlxScreen,
+ config, req->pixmap, req->glxpixmap);
+}
+
+
+static int DoDestroyDrawable(__GLXclientState *cl, XID glxdrawable, int type)
+{
+ __GLXdrawable *pGlxDraw;
+ int err;
+
+ if (!validGlxDrawable(cl->client, glxdrawable, type,
+ DixDestroyAccess, &pGlxDraw, &err))
+ return err;
+
+ FreeResource(glxdrawable, FALSE);
+
+ return Success;
+}
+
+int __glXDisp_DestroyGLXPixmap(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXDestroyGLXPixmapReq *req = (xGLXDestroyGLXPixmapReq *) pc;
+
+ return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
+}
+
+int __glXDisp_DestroyPixmap(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXDestroyPixmapReq *req = (xGLXDestroyPixmapReq *) pc;
+
+ return DoDestroyDrawable(cl, req->glxpixmap, GLX_DRAWABLE_PIXMAP);
+}
+
+static int
+DoCreatePbuffer(ClientPtr client, int screenNum, XID fbconfigId,
+ int width, int height, XID glxDrawableId)
+{
+ __GLXconfig *config;
+ __GLXscreen *pGlxScreen;
+ PixmapPtr pPixmap;
+ int err;
+
+ if (!validGlxScreen(client, screenNum, &pGlxScreen, &err))
+ return err;
+ if (!validGlxFBConfig(client, pGlxScreen, fbconfigId, &config, &err))
+ return err;
+
+ __glXenterServer(GL_FALSE);
+ pPixmap = (*pGlxScreen->pScreen->CreatePixmap) (pGlxScreen->pScreen,
+ width, height, config->rgbBits, 0);
+ __glXleaveServer(GL_FALSE);
+
+ return DoCreateGLXDrawable(client, pGlxScreen, config, &pPixmap->drawable,
+ glxDrawableId, GLX_DRAWABLE_PBUFFER);
+}
+
+int __glXDisp_CreatePbuffer(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreatePbufferReq *req = (xGLXCreatePbufferReq *) pc;
+ CARD32 *attrs;
+ int width, height, i;
+
+ attrs = (CARD32 *) (req + 1);
+ width = 0;
+ height = 0;
+
+ for (i = 0; i < req->numAttribs; i++) {
+ switch (attrs[i * 2]) {
+ case GLX_PBUFFER_WIDTH:
+ width = attrs[i * 2 + 1];
+ break;
+ case GLX_PBUFFER_HEIGHT:
+ height = attrs[i * 2 + 1];
+ break;
+ case GLX_LARGEST_PBUFFER:
+ case GLX_PRESERVED_CONTENTS:
+ /* FIXME: huh... */
+ break;
+ }
+ }
+
+ return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
+ width, height, req->pbuffer);
+}
+
+int __glXDisp_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateGLXPbufferSGIXReq *req = (xGLXCreateGLXPbufferSGIXReq *) pc;
+
+ return DoCreatePbuffer(cl->client, req->screen, req->fbconfig,
+ req->width, req->height, req->pbuffer);
+}
+
+int __glXDisp_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc;
+
+ return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
+}
+
+int __glXDisp_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc;
+
+ return DoDestroyDrawable(cl, req->pbuffer, GLX_DRAWABLE_PBUFFER);
+}
+
+static int
+DoChangeDrawableAttributes(ClientPtr client, XID glxdrawable,
+ int numAttribs, CARD32 *attribs)
+{
+ __GLXdrawable *pGlxDraw;
+ int i, err;
+
+ if (!validGlxDrawable(client, glxdrawable, GLX_DRAWABLE_ANY,
+ DixSetAttrAccess, &pGlxDraw, &err))
+ return err;
+
+ for (i = 0; i < numAttribs; i++) {
+ switch(attribs[i * 2]) {
+ case GLX_EVENT_MASK:
+ /* All we do is to record the event mask so we can send it
+ * back when queried. We never actually clobber the
+ * pbuffers, so we never need to send out the event. */
+ pGlxDraw->eventMask = attribs[i * 2 + 1];
+ break;
+ }
+ }
+
+ return Success;
+}
+
+int __glXDisp_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXChangeDrawableAttributesReq *req =
+ (xGLXChangeDrawableAttributesReq *) pc;
+
+ return DoChangeDrawableAttributes(cl->client, req->drawable,
+ req->numAttribs, (CARD32 *) (req + 1));
+}
+
+int __glXDisp_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXChangeDrawableAttributesSGIXReq *req =
+ (xGLXChangeDrawableAttributesSGIXReq *)pc;
+
+ return DoChangeDrawableAttributes(cl->client, req->drawable,
+ req->numAttribs, (CARD32 *) (req + 1));
+}
+
+int __glXDisp_CreateWindow(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXCreateWindowReq *req = (xGLXCreateWindowReq *) pc;
+ __GLXconfig *config;
+ __GLXscreen *pGlxScreen;
+ ClientPtr client = cl->client;
+ DrawablePtr pDraw;
+ int err;
+
+ if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
+ return err;
+ if (!validGlxFBConfig(client, pGlxScreen, req->fbconfig, &config, &err))
+ return err;
+
+ err = dixLookupDrawable(&pDraw, req->window, client, 0, DixAddAccess);
+ if (err != Success || pDraw->type != DRAWABLE_WINDOW) {
+ client->errorValue = req->window;
+ return BadWindow;
+ }
+
+ if (!validGlxFBConfigForWindow(client, config, pDraw, &err))
+ return err;
+
+ return DoCreateGLXDrawable(client, pGlxScreen, config,
+ pDraw, req->glxwindow, GLX_DRAWABLE_WINDOW);
+}
+
+int __glXDisp_DestroyWindow(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXDestroyWindowReq *req = (xGLXDestroyWindowReq *) pc;
+
+ return DoDestroyDrawable(cl, req->glxwindow, GLX_DRAWABLE_WINDOW);
+}
+
+
+/*****************************************************************************/
+
+/*
+** NOTE: There is no portable implementation for swap buffers as of
+** this time that is of value. Consequently, this code must be
+** implemented by somebody other than SGI.
+*/
+int __glXDisp_SwapBuffers(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXSwapBuffersReq *req = (xGLXSwapBuffersReq *) pc;
+ GLXContextTag tag = req->contextTag;
+ XID drawId = req->drawable;
+ __GLXcontext *glxc = NULL;
+ __GLXdrawable *pGlxDraw;
+ int error;
+
+ if (tag) {
+ glxc = __glXLookupContextByTag(cl, tag);
+ if (!glxc) {
+ return __glXError(GLXBadContextTag);
+ }
+ /*
+ ** The calling thread is swapping its current drawable. In this case,
+ ** glxSwapBuffers is in both GL and X streams, in terms of
+ ** sequentiality.
+ */
+ if (__glXForceCurrent(cl, tag, &error)) {
+ /*
+ ** Do whatever is needed to make sure that all preceding requests
+ ** in both streams are completed before the swap is executed.
+ */
+ CALL_Finish( GET_DISPATCH(), () );
+ __GLX_NOTE_FLUSHED_CMDS(glxc);
+ } else {
+ return error;
+ }
+ }
+
+ pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
+ if (pGlxDraw == NULL)
+ return error;
+
+ if (pGlxDraw->type == DRAWABLE_WINDOW &&
+ (*pGlxDraw->swapBuffers)(cl->client, pGlxDraw) == GL_FALSE)
+ return __glXError(GLXBadDrawable);
+
+ return Success;
+}
+
+
+static int
+DoQueryContext(__GLXclientState *cl, GLXContextID gcId)
+{
+ ClientPtr client = cl->client;
+ __GLXcontext *ctx;
+ xGLXQueryContextInfoEXTReply reply;
+ int nProps;
+ int *sendBuf, *pSendBuf;
+ int nReplyBytes;
+ int err;
+
+ if (!validGlxContext(cl->client, gcId, DixReadAccess, &ctx, &err))
+ return err;
+
+ nProps = 3;
+ reply.length = nProps << 1;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.n = nProps;
+
+ nReplyBytes = reply.length << 2;
+ sendBuf = (int *)xalloc((size_t)nReplyBytes);
+ if (sendBuf == NULL) {
+ return __glXError(GLXBadContext); /* XXX: Is this correct? */
+ }
+ pSendBuf = sendBuf;
+ *pSendBuf++ = GLX_SHARE_CONTEXT_EXT;
+ *pSendBuf++ = (int)(ctx->share_id);
+ *pSendBuf++ = GLX_VISUAL_ID_EXT;
+ *pSendBuf++ = (int)(ctx->config->visualID);
+ *pSendBuf++ = GLX_SCREEN_EXT;
+ *pSendBuf++ = (int)(ctx->pGlxScreen->pScreen->myNum);
+
+ if (client->swapped) {
+ __glXSwapQueryContextInfoEXTReply(client, &reply, sendBuf);
+ } else {
+ WriteToClient(client, sz_xGLXQueryContextInfoEXTReply, (char *)&reply);
+ WriteToClient(client, nReplyBytes, (char *)sendBuf);
+ }
+ xfree((char *)sendBuf);
+
+ return Success;
+}
+
+int __glXDisp_QueryContextInfoEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXQueryContextInfoEXTReq *req = (xGLXQueryContextInfoEXTReq *) pc;
+
+ return DoQueryContext(cl, req->context);
+}
+
+int __glXDisp_QueryContext(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXQueryContextReq *req = (xGLXQueryContextReq *) pc;
+
+ return DoQueryContext(cl, req->context);
+}
+
+int __glXDisp_BindTexImageEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
+ ClientPtr client = cl->client;
+ __GLXcontext *context;
+ __GLXdrawable *pGlxDraw;
+ GLXDrawable drawId;
+ int buffer;
+ int error;
+
+ pc += __GLX_VENDPRIV_HDR_SIZE;
+
+ drawId = *((CARD32 *) (pc));
+ buffer = *((INT32 *) (pc + 4));
+
+ if (buffer != GLX_FRONT_LEFT_EXT)
+ return __glXError(GLXBadPixmap);
+
+ context = __glXForceCurrent (cl, req->contextTag, &error);
+ if (!context)
+ return error;
+
+ if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
+ DixReadAccess, &pGlxDraw, &error))
+ return error;
+
+ if (!context->textureFromPixmap)
+ return __glXError(GLXUnsupportedPrivateRequest);
+
+ return context->textureFromPixmap->bindTexImage(context,
+ buffer,
+ pGlxDraw);
+}
+
+int __glXDisp_ReleaseTexImageEXT(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
+ ClientPtr client = cl->client;
+ __GLXdrawable *pGlxDraw;
+ __GLXcontext *context;
+ GLXDrawable drawId;
+ int buffer;
+ int error;
+
+ pc += __GLX_VENDPRIV_HDR_SIZE;
+
+ drawId = *((CARD32 *) (pc));
+ buffer = *((INT32 *) (pc + 4));
+
+ context = __glXForceCurrent (cl, req->contextTag, &error);
+ if (!context)
+ return error;
+
+ if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_PIXMAP,
+ DixReadAccess, &pGlxDraw, &error))
+ return error;
+
+ if (!context->textureFromPixmap)
+ return __glXError(GLXUnsupportedPrivateRequest);
+
+ return context->textureFromPixmap->releaseTexImage(context,
+ buffer,
+ pGlxDraw);
+}
+
+int __glXDisp_CopySubBufferMESA(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
+ GLXContextTag tag = req->contextTag;
+ __GLXcontext *glxc = NULL;
+ __GLXdrawable *pGlxDraw;
+ ClientPtr client = cl->client;
+ GLXDrawable drawId;
+ int error;
+ int x, y, width, height;
+
+ (void) client;
+ (void) req;
+
+ pc += __GLX_VENDPRIV_HDR_SIZE;
+
+ drawId = *((CARD32 *) (pc));
+ x = *((INT32 *) (pc + 4));
+ y = *((INT32 *) (pc + 8));
+ width = *((INT32 *) (pc + 12));
+ height = *((INT32 *) (pc + 16));
+
+ if (tag) {
+ glxc = __glXLookupContextByTag(cl, tag);
+ if (!glxc) {
+ return __glXError(GLXBadContextTag);
+ }
+ /*
+ ** The calling thread is swapping its current drawable. In this case,
+ ** glxSwapBuffers is in both GL and X streams, in terms of
+ ** sequentiality.
+ */
+ if (__glXForceCurrent(cl, tag, &error)) {
+ /*
+ ** Do whatever is needed to make sure that all preceding requests
+ ** in both streams are completed before the swap is executed.
+ */
+ CALL_Finish( GET_DISPATCH(), () );
+ __GLX_NOTE_FLUSHED_CMDS(glxc);
+ } else {
+ return error;
+ }
+ }
+
+ pGlxDraw = __glXGetDrawable(glxc, drawId, client, &error);
+ if (!pGlxDraw)
+ return error;
+
+ if (pGlxDraw == NULL ||
+ pGlxDraw->type != GLX_DRAWABLE_WINDOW ||
+ pGlxDraw->copySubBuffer == NULL)
+ return __glXError(GLXBadDrawable);
+
+ (*pGlxDraw->copySubBuffer)(pGlxDraw, x, y, width, height);
+
+ return Success;
+}
+
+/*
+** Get drawable attributes
+*/
+static int
+DoGetDrawableAttributes(__GLXclientState *cl, XID drawId)
+{
+ ClientPtr client = cl->client;
+ xGLXGetDrawableAttributesReply reply;
+ __GLXdrawable *pGlxDraw;
+ CARD32 attributes[6];
+ int numAttribs, error;
+
+ if (!validGlxDrawable(client, drawId, GLX_DRAWABLE_ANY,
+ DixGetAttrAccess, &pGlxDraw, &error))
+ return error;
+
+ numAttribs = 3;
+ reply.length = numAttribs << 1;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.numAttribs = numAttribs;
+
+ attributes[0] = GLX_TEXTURE_TARGET_EXT;
+ attributes[1] = pGlxDraw->target == GL_TEXTURE_2D ? GLX_TEXTURE_2D_EXT :
+ GLX_TEXTURE_RECTANGLE_EXT;
+ attributes[2] = GLX_Y_INVERTED_EXT;
+ attributes[3] = GL_FALSE;
+ attributes[4] = GLX_EVENT_MASK;
+ attributes[5] = pGlxDraw->eventMask;
+
+ if (client->swapped) {
+ __glXSwapGetDrawableAttributesReply(client, &reply, attributes);
+ } else {
+ WriteToClient(client, sz_xGLXGetDrawableAttributesReply,
+ (char *)&reply);
+ WriteToClient(client, reply.length * sizeof (CARD32),
+ (char *)attributes);
+ }
+
+ return Success;
+}
+
+int __glXDisp_GetDrawableAttributes(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXGetDrawableAttributesReq *req = (xGLXGetDrawableAttributesReq *)pc;
+
+ return DoGetDrawableAttributes(cl, req->drawable);
+}
+
+int __glXDisp_GetDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXGetDrawableAttributesSGIXReq *req =
+ (xGLXGetDrawableAttributesSGIXReq *)pc;
+
+ return DoGetDrawableAttributes(cl, req->drawable);
+}
+
+/************************************************************************/
+
+/*
+** Render and Renderlarge are not in the GLX API. They are used by the GLX
+** client library to send batches of GL rendering commands.
+*/
+
+/*
+** Execute all the drawing commands in a request.
+*/
+int __glXDisp_Render(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXRenderReq *req;
+ ClientPtr client= cl->client;
+ int left, cmdlen, error;
+ int commandsDone;
+ CARD16 opcode;
+ __GLXrenderHeader *hdr;
+ __GLXcontext *glxc;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ req = (xGLXRenderReq *) pc;
+ if (client->swapped) {
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+ }
+
+ glxc = __glXForceCurrent(cl, req->contextTag, &error);
+ if (!glxc) {
+ return error;
+ }
+
+ commandsDone = 0;
+ pc += sz_xGLXRenderReq;
+ left = (req->length << 2) - sz_xGLXRenderReq;
+ while (left > 0) {
+ __GLXrenderSizeData entry;
+ int extra;
+ __GLXdispatchRenderProcPtr proc;
+ int err;
+
+ /*
+ ** Verify that the header length and the overall length agree.
+ ** Also, each command must be word aligned.
+ */
+ hdr = (__GLXrenderHeader *) pc;
+ if (client->swapped) {
+ __GLX_SWAP_SHORT(&hdr->length);
+ __GLX_SWAP_SHORT(&hdr->opcode);
+ }
+ cmdlen = hdr->length;
+ opcode = hdr->opcode;
+
+ /*
+ ** Check for core opcodes and grab entry data.
+ */
+ err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry);
+ proc = (__GLXdispatchRenderProcPtr)
+ __glXGetProtocolDecodeFunction(& Render_dispatch_info,
+ opcode, client->swapped);
+
+ if ((err < 0) || (proc == NULL)) {
+ client->errorValue = commandsDone;
+ return __glXError(GLXBadRenderRequest);
+ }
+
+ if (entry.varsize) {
+ /* variable size command */
+ extra = (*entry.varsize)(pc + __GLX_RENDER_HDR_SIZE,
+ client->swapped);
+ if (extra < 0) {
+ extra = 0;
+ }
+ if (cmdlen != __GLX_PAD(entry.bytes + extra)) {
+ return BadLength;
+ }
+ } else {
+ /* constant size command */
+ if (cmdlen != __GLX_PAD(entry.bytes)) {
+ return BadLength;
+ }
+ }
+ if (left < cmdlen) {
+ return BadLength;
+ }
+
+ /*
+ ** Skip over the header and execute the command. We allow the
+ ** caller to trash the command memory. This is useful especially
+ ** for things that require double alignment - they can just shift
+ ** the data towards lower memory (trashing the header) by 4 bytes
+ ** and achieve the required alignment.
+ */
+ (*proc)(pc + __GLX_RENDER_HDR_SIZE);
+ pc += cmdlen;
+ left -= cmdlen;
+ commandsDone++;
+ }
+ __GLX_NOTE_UNFLUSHED_CMDS(glxc);
+ return Success;
+}
+
+
+/*
+** Execute a large rendering request (one that spans multiple X requests).
+*/
+int __glXDisp_RenderLarge(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXRenderLargeReq *req;
+ ClientPtr client= cl->client;
+ size_t dataBytes;
+ __GLXrenderLargeHeader *hdr;
+ __GLXcontext *glxc;
+ int error;
+ CARD16 opcode;
+ __GLX_DECLARE_SWAP_VARIABLES;
+
+ req = (xGLXRenderLargeReq *) pc;
+ if (client->swapped) {
+ __GLX_SWAP_SHORT(&req->length);
+ __GLX_SWAP_INT(&req->contextTag);
+ __GLX_SWAP_INT(&req->dataBytes);
+ __GLX_SWAP_SHORT(&req->requestNumber);
+ __GLX_SWAP_SHORT(&req->requestTotal);
+ }
+
+ glxc = __glXForceCurrent(cl, req->contextTag, &error);
+ if (!glxc) {
+ /* Reset in case this isn't 1st request. */
+ __glXResetLargeCommandStatus(cl);
+ return error;
+ }
+ dataBytes = req->dataBytes;
+
+ /*
+ ** Check the request length.
+ */
+ if ((req->length << 2) != __GLX_PAD(dataBytes) + sz_xGLXRenderLargeReq) {
+ client->errorValue = req->length;
+ /* Reset in case this isn't 1st request. */
+ __glXResetLargeCommandStatus(cl);
+ return BadLength;
+ }
+ pc += sz_xGLXRenderLargeReq;
+
+ if (cl->largeCmdRequestsSoFar == 0) {
+ __GLXrenderSizeData entry;
+ int extra;
+ size_t cmdlen;
+ int err;
+
+ /*
+ ** This is the first request of a multi request command.
+ ** Make enough space in the buffer, then copy the entire request.
+ */
+ if (req->requestNumber != 1) {
+ client->errorValue = req->requestNumber;
+ return __glXError(GLXBadLargeRequest);
+ }
+
+ hdr = (__GLXrenderLargeHeader *) pc;
+ if (client->swapped) {
+ __GLX_SWAP_INT(&hdr->length);
+ __GLX_SWAP_INT(&hdr->opcode);
+ }
+ cmdlen = hdr->length;
+ opcode = hdr->opcode;
+
+ /*
+ ** Check for core opcodes and grab entry data.
+ */
+ err = __glXGetProtocolSizeData(& Render_dispatch_info, opcode, & entry);
+ if (err < 0) {
+ client->errorValue = opcode;
+ return __glXError(GLXBadLargeRequest);
+ }
+
+ if (entry.varsize) {
+ /*
+ ** If it's a variable-size command (a command whose length must
+ ** be computed from its parameters), all the parameters needed
+ ** will be in the 1st request, so it's okay to do this.
+ */
+ extra = (*entry.varsize)(pc + __GLX_RENDER_LARGE_HDR_SIZE,
+ client->swapped);
+ if (extra < 0) {
+ extra = 0;
+ }
+ /* large command's header is 4 bytes longer, so add 4 */
+ if (cmdlen != __GLX_PAD(entry.bytes + 4 + extra)) {
+ return BadLength;
+ }
+ } else {
+ /* constant size command */
+ if (cmdlen != __GLX_PAD(entry.bytes + 4)) {
+ return BadLength;
+ }
+ }
+ /*
+ ** Make enough space in the buffer, then copy the entire request.
+ */
+ if (cl->largeCmdBufSize < cmdlen) {
+ if (!cl->largeCmdBuf) {
+ cl->largeCmdBuf = (GLbyte *) xalloc(cmdlen);
+ } else {
+ cl->largeCmdBuf = (GLbyte *) xrealloc(cl->largeCmdBuf, cmdlen);
+ }
+ if (!cl->largeCmdBuf) {
+ return BadAlloc;
+ }
+ cl->largeCmdBufSize = cmdlen;
+ }
+ memcpy(cl->largeCmdBuf, pc, dataBytes);
+
+ cl->largeCmdBytesSoFar = dataBytes;
+ cl->largeCmdBytesTotal = cmdlen;
+ cl->largeCmdRequestsSoFar = 1;
+ cl->largeCmdRequestsTotal = req->requestTotal;
+ return Success;
+
+ } else {
+ /*
+ ** We are receiving subsequent (i.e. not the first) requests of a
+ ** multi request command.
+ */
+
+ /*
+ ** Check the request number and the total request count.
+ */
+ if (req->requestNumber != cl->largeCmdRequestsSoFar + 1) {
+ client->errorValue = req->requestNumber;
+ __glXResetLargeCommandStatus(cl);
+ return __glXError(GLXBadLargeRequest);
+ }
+ if (req->requestTotal != cl->largeCmdRequestsTotal) {
+ client->errorValue = req->requestTotal;
+ __glXResetLargeCommandStatus(cl);
+ return __glXError(GLXBadLargeRequest);
+ }
+
+ /*
+ ** Check that we didn't get too much data.
+ */
+ if ((cl->largeCmdBytesSoFar + dataBytes) > cl->largeCmdBytesTotal) {
+ client->errorValue = dataBytes;
+ __glXResetLargeCommandStatus(cl);
+ return __glXError(GLXBadLargeRequest);
+ }
+ memcpy(cl->largeCmdBuf + cl->largeCmdBytesSoFar, pc, dataBytes);
+ cl->largeCmdBytesSoFar += dataBytes;
+ cl->largeCmdRequestsSoFar++;
+
+ if (req->requestNumber == cl->largeCmdRequestsTotal) {
+ __GLXdispatchRenderProcPtr proc;
+
+ /*
+ ** This is the last request; it must have enough bytes to complete
+ ** the command.
+ */
+ /* NOTE: the two pad macros have been added below; they are needed
+ ** because the client library pads the total byte count, but not
+ ** the per-request byte counts. The Protocol Encoding says the
+ ** total byte count should not be padded, so a proposal will be
+ ** made to the ARB to relax the padding constraint on the total
+ ** byte count, thus preserving backward compatibility. Meanwhile,
+ ** the padding done below fixes a bug that did not allow
+ ** large commands of odd sizes to be accepted by the server.
+ */
+ if (__GLX_PAD(cl->largeCmdBytesSoFar) !=
+ __GLX_PAD(cl->largeCmdBytesTotal)) {
+ client->errorValue = dataBytes;
+ __glXResetLargeCommandStatus(cl);
+ return __glXError(GLXBadLargeRequest);
+ }
+ hdr = (__GLXrenderLargeHeader *) cl->largeCmdBuf;
+ /*
+ ** The opcode and length field in the header had already been
+ ** swapped when the first request was received.
+ **
+ ** Use the opcode to index into the procedure table.
+ */
+ opcode = hdr->opcode;
+
+ proc = (__GLXdispatchRenderProcPtr)
+ __glXGetProtocolDecodeFunction(& Render_dispatch_info, opcode,
+ client->swapped);
+ if (proc == NULL) {
+ client->errorValue = opcode;
+ return __glXError(GLXBadLargeRequest);
+ }
+
+ /*
+ ** Skip over the header and execute the command.
+ */
+ (*proc)(cl->largeCmdBuf + __GLX_RENDER_LARGE_HDR_SIZE);
+ __GLX_NOTE_UNFLUSHED_CMDS(glxc);
+
+ /*
+ ** Reset for the next RenderLarge series.
+ */
+ __glXResetLargeCommandStatus(cl);
+ } else {
+ /*
+ ** This is neither the first nor the last request.
+ */
+ }
+ return Success;
+ }
+}
+
+extern RESTYPE __glXSwapBarrierRes;
+
+int __glXDisp_BindSwapBarrierSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXBindSwapBarrierSGIXReq *req = (xGLXBindSwapBarrierSGIXReq *) pc;
+ XID drawable = req->drawable;
+ int barrier = req->barrier;
+ DrawablePtr pDraw;
+ int screen, rc;
+ __GLXscreen *pGlxScreen;
+
+ rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixGetAttrAccess);
+ pGlxScreen = glxGetScreen(pDraw->pScreen);
+ if (rc == Success && (pDraw->type == DRAWABLE_WINDOW)) {
+ screen = pDraw->pScreen->myNum;
+ if (pGlxScreen->swapBarrierFuncs) {
+ int ret = pGlxScreen->swapBarrierFuncs->bindSwapBarrierFunc(screen, drawable, barrier);
+ if (ret == Success) {
+ if (barrier)
+ /* add source for cleanup when drawable is gone */
+ AddResource(drawable, __glXSwapBarrierRes, (pointer)(intptr_t)screen);
+ else
+ /* delete source */
+ FreeResourceByType(drawable, __glXSwapBarrierRes, FALSE);
+ }
+ return ret;
+ }
+ }
+ client->errorValue = drawable;
+ return __glXError(GLXBadDrawable);
+}
+
+
+int __glXDisp_QueryMaxSwapBarriersSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryMaxSwapBarriersSGIXReq *req =
+ (xGLXQueryMaxSwapBarriersSGIXReq *) pc;
+ xGLXQueryMaxSwapBarriersSGIXReply reply;
+ int screen = req->screen;
+ __GLXscreen *pGlxScreen;
+
+ pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+ if (pGlxScreen->swapBarrierFuncs)
+ reply.max = pGlxScreen->swapBarrierFuncs->queryMaxSwapBarriersFunc(screen);
+ else
+ reply.max = 0;
+
+
+ reply.length = 0;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ }
+
+ WriteToClient(client, sz_xGLXQueryMaxSwapBarriersSGIXReply,
+ (char *) &reply);
+ return Success;
+}
+
+#define GLX_BAD_HYPERPIPE_SGIX 92
+
+int __glXDisp_QueryHyperpipeNetworkSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryHyperpipeNetworkSGIXReq * req = (xGLXQueryHyperpipeNetworkSGIXReq *) pc;
+ xGLXQueryHyperpipeNetworkSGIXReply reply;
+ int screen = req->screen;
+ void *rdata = NULL;
+
+ int length=0;
+ int npipes=0;
+
+ int n= 0;
+ __GLXscreen *pGlxScreen;
+
+ pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+ if (pGlxScreen->hyperpipeFuncs) {
+ rdata =
+ (pGlxScreen->hyperpipeFuncs->queryHyperpipeNetworkFunc(screen, &npipes, &n));
+ }
+ length = __GLX_PAD(n) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = length;
+ reply.n = n;
+ reply.npipes = npipes;
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.n);
+ __GLX_SWAP_INT(&reply.npipes);
+ }
+ WriteToClient(client, sz_xGLXQueryHyperpipeNetworkSGIXReply,
+ (char *) &reply);
+
+ WriteToClient(client, length << 2, (char *)rdata);
+
+ return Success;
+}
+
+int __glXDisp_DestroyHyperpipeConfigSGIX (__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXDestroyHyperpipeConfigSGIXReq * req =
+ (xGLXDestroyHyperpipeConfigSGIXReq *) pc;
+ xGLXDestroyHyperpipeConfigSGIXReply reply;
+ int screen = req->screen;
+ int success = GLX_BAD_HYPERPIPE_SGIX;
+ int hpId ;
+ __GLXscreen *pGlxScreen;
+
+ hpId = req->hpId;
+
+ pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+ if (pGlxScreen->hyperpipeFuncs) {
+ success = pGlxScreen->hyperpipeFuncs->destroyHyperpipeConfigFunc(screen, hpId);
+ }
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = __GLX_PAD(0) >> 2;
+ reply.n = 0;
+ reply.success = success;
+
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ }
+ WriteToClient(client,
+ sz_xGLXDestroyHyperpipeConfigSGIXReply,
+ (char *) &reply);
+ return Success;
+}
+
+int __glXDisp_QueryHyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryHyperpipeConfigSGIXReq * req =
+ (xGLXQueryHyperpipeConfigSGIXReq *) pc;
+ xGLXQueryHyperpipeConfigSGIXReply reply;
+ int screen = req->screen;
+ void *rdata = NULL;
+ int length;
+ int npipes=0;
+ int n= 0;
+ int hpId;
+ __GLXscreen *pGlxScreen;
+
+ hpId = req->hpId;
+
+ pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+ if (pGlxScreen->hyperpipeFuncs) {
+ rdata = pGlxScreen->hyperpipeFuncs->queryHyperpipeConfigFunc(screen, hpId,&npipes, &n);
+ }
+
+ length = __GLX_PAD(n) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = length;
+ reply.n = n;
+ reply.npipes = npipes;
+
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.length);
+ __GLX_SWAP_INT(&reply.n);
+ __GLX_SWAP_INT(&reply.npipes);
+ }
+
+ WriteToClient(client, sz_xGLXQueryHyperpipeConfigSGIXReply,
+ (char *) &reply);
+
+ WriteToClient(client, length << 2, (char *)rdata);
+
+ return Success;
+}
+
+int __glXDisp_HyperpipeConfigSGIX(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXHyperpipeConfigSGIXReq * req =
+ (xGLXHyperpipeConfigSGIXReq *) pc;
+ xGLXHyperpipeConfigSGIXReply reply;
+ int screen = req->screen;
+ void *rdata;
+
+ int npipes=0, networkId;
+ int hpId=-1;
+ __GLXscreen *pGlxScreen;
+
+ pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+ networkId = (int)req->networkId;
+ npipes = (int)req->npipes;
+ rdata = (void *)(req +1);
+
+ if (pGlxScreen->hyperpipeFuncs) {
+ pGlxScreen->hyperpipeFuncs->hyperpipeConfigFunc(screen,networkId,
+ &hpId, &npipes,
+ (void *) rdata);
+ }
+
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = __GLX_PAD(0) >> 2;
+ reply.n = 0;
+ reply.npipes = npipes;
+ reply.hpId = hpId;
+
+ if (client->swapped) {
+ __GLX_DECLARE_SWAP_VARIABLES;
+ __GLX_SWAP_SHORT(&reply.sequenceNumber);
+ __GLX_SWAP_INT(&reply.npipes);
+ __GLX_SWAP_INT(&reply.hpId);
+ }
+
+ WriteToClient(client, sz_xGLXHyperpipeConfigSGIXReply,
+ (char *) &reply);
+
+ return Success;
+}
+
+
+/************************************************************************/
+
+/*
+** No support is provided for the vendor-private requests other than
+** allocating the entry points in the dispatch table.
+*/
+
+int __glXDisp_VendorPrivate(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
+ GLint vendorcode = req->vendorCode;
+ __GLXdispatchVendorPrivProcPtr proc;
+
+
+ proc = (__GLXdispatchVendorPrivProcPtr)
+ __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info,
+ vendorcode, 0);
+ if (proc != NULL) {
+ (*proc)(cl, (GLbyte*)req);
+ return Success;
+ }
+
+ cl->client->errorValue = req->vendorCode;
+ return __glXError(GLXUnsupportedPrivateRequest);
+}
+
+int __glXDisp_VendorPrivateWithReply(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXVendorPrivateReq *req = (xGLXVendorPrivateReq *) pc;
+ GLint vendorcode = req->vendorCode;
+ __GLXdispatchVendorPrivProcPtr proc;
+
+
+ proc = (__GLXdispatchVendorPrivProcPtr)
+ __glXGetProtocolDecodeFunction(& VendorPriv_dispatch_info,
+ vendorcode, 0);
+ if (proc != NULL) {
+ return (*proc)(cl, (GLbyte*)req);
+ }
+
+ cl->client->errorValue = vendorcode;
+ return __glXError(GLXUnsupportedPrivateRequest);
+}
+
+int __glXDisp_QueryExtensionsString(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryExtensionsStringReq *req = (xGLXQueryExtensionsStringReq *) pc;
+ xGLXQueryExtensionsStringReply reply;
+ __GLXscreen *pGlxScreen;
+ size_t n, length;
+ char *buf;
+ int err;
+
+ if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
+ return err;
+
+ n = strlen(pGlxScreen->GLXextensions) + 1;
+ length = __GLX_PAD(n) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = length;
+ reply.n = n;
+
+ /* Allocate buffer to make sure it's a multiple of 4 bytes big.*/
+ buf = (char *) xalloc(length << 2);
+ if (buf == NULL)
+ return BadAlloc;
+ memcpy(buf, pGlxScreen->GLXextensions, n);
+
+ if (client->swapped) {
+ glxSwapQueryExtensionsStringReply(client, &reply, buf);
+ } else {
+ WriteToClient(client, sz_xGLXQueryExtensionsStringReply,(char *)&reply);
+ WriteToClient(client, (int)(length << 2), (char *)buf);
+ }
+
+ xfree(buf);
+ return Success;
+}
+
+int __glXDisp_QueryServerString(__GLXclientState *cl, GLbyte *pc)
+{
+ ClientPtr client = cl->client;
+ xGLXQueryServerStringReq *req = (xGLXQueryServerStringReq *) pc;
+ xGLXQueryServerStringReply reply;
+ size_t n, length;
+ const char *ptr;
+ char *buf;
+ __GLXscreen *pGlxScreen;
+ int err;
+ char ver_str[16];
+
+ if (!validGlxScreen(client, req->screen, &pGlxScreen, &err))
+ return err;
+
+ switch(req->name) {
+ case GLX_VENDOR:
+ ptr = pGlxScreen->GLXvendor;
+ break;
+ case GLX_VERSION:
+ /* Return to the server version rather than the screen version
+ * to prevent confusion when they do not match.
+ */
+ snprintf(ver_str, 16, "%d.%d", glxMajorVersion, glxMinorVersion);
+ ptr = ver_str;
+ break;
+ case GLX_EXTENSIONS:
+ ptr = pGlxScreen->GLXextensions;
+ break;
+ default:
+ return BadValue;
+ }
+
+ n = strlen(ptr) + 1;
+ length = __GLX_PAD(n) >> 2;
+ reply.type = X_Reply;
+ reply.sequenceNumber = client->sequence;
+ reply.length = length;
+ reply.n = n;
+
+ buf = (char *) xalloc(length << 2);
+ if (buf == NULL) {
+ return BadAlloc;
+ }
+ memcpy(buf, ptr, n);
+
+ if (client->swapped) {
+ glxSwapQueryServerStringReply(client, &reply, buf);
+ } else {
+ WriteToClient(client, sz_xGLXQueryServerStringReply, (char *)&reply);
+ WriteToClient(client, (int)(length << 2), buf);
+ }
+
+ xfree(buf);
+ return Success;
+}
+
+int __glXDisp_ClientInfo(__GLXclientState *cl, GLbyte *pc)
+{
+ xGLXClientInfoReq *req = (xGLXClientInfoReq *) pc;
+ const char *buf;
+
+ cl->GLClientmajorVersion = req->major;
+ cl->GLClientminorVersion = req->minor;
+ if (cl->GLClientextensions)
+ xfree(cl->GLClientextensions);
+ buf = (const char *)(req+1);
+ cl->GLClientextensions = xstrdup(buf);
+
+ return Success;
+}
diff --git a/xorg-server/glx/glxcmdsswap.c b/xorg-server/glx/glxcmdsswap.c index f1c0ce69f..a65839527 100644 --- a/xorg-server/glx/glxcmdsswap.c +++ b/xorg-server/glx/glxcmdsswap.c @@ -30,6 +30,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include <string.h> @@ -354,7 +358,7 @@ int __glXDispSwap_CreateGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc) int __glXDispSwap_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc) { - xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) req; + xGLXDestroyPbufferReq *req = (xGLXDestroyPbufferReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_INT(&req->pbuffer); @@ -364,7 +368,7 @@ int __glXDispSwap_DestroyPbuffer(__GLXclientState *cl, GLbyte *pc) int __glXDispSwap_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc) { - xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) req; + xGLXDestroyGLXPbufferSGIXReq *req = (xGLXDestroyGLXPbufferSGIXReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_SWAP_INT(&req->pbuffer); @@ -375,7 +379,7 @@ int __glXDispSwap_DestroyGLXPbufferSGIX(__GLXclientState *cl, GLbyte *pc) int __glXDispSwap_ChangeDrawableAttributes(__GLXclientState *cl, GLbyte *pc) { xGLXChangeDrawableAttributesReq *req = - (xGLXChangeDrawableAttributesReq *) req; + (xGLXChangeDrawableAttributesReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; CARD32 *attribs; @@ -392,7 +396,7 @@ int __glXDispSwap_ChangeDrawableAttributesSGIX(__GLXclientState *cl, GLbyte *pc) { xGLXChangeDrawableAttributesSGIXReq *req = - (xGLXChangeDrawableAttributesSGIXReq *) req; + (xGLXChangeDrawableAttributesSGIXReq *) pc; __GLX_DECLARE_SWAP_VARIABLES; __GLX_DECLARE_SWAP_ARRAY_VARIABLES; CARD32 *attribs; diff --git a/xorg-server/glx/glxdri.c b/xorg-server/glx/glxdri.c index 21e44d12d..910eb464e 100644 --- a/xorg-server/glx/glxdri.c +++ b/xorg-server/glx/glxdri.c @@ -1,1196 +1,1199 @@ -/* - * Copyright © 2006 Red Hat, 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 Red Hat, - * Inc not be used in advertising or publicity pertaining to - * distribution of the software without specific, written prior - * permission. Red Hat, Inc makes no representations about the - * suitability of this software for any purpose. It is provided "as - * is" without express or implied warranty. - * - * RED HAT, INC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN - * NO EVENT SHALL RED HAT, INC 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 <dix-config.h> -#endif - -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <sys/time.h> -#include <dlfcn.h> - -#include <drm.h> -#include <GL/gl.h> -#include <GL/internal/dri_interface.h> - -#include <windowstr.h> -#include <os.h> -#include <damage.h> - -#define _XF86DRI_SERVER_ -#include <drm_sarea.h> -#include <xf86drm.h> -#include <X11/dri/xf86driproto.h> -#include <xf86str.h> -#include <xf86.h> -#include <dri.h> - -#include "servermd.h" - -#define DRI_NEW_INTERFACE_ONLY -#include "glxserver.h" -#include "glxutil.h" -#include "glxdricommon.h" - -#include "g_disptab.h" -#include "glapitable.h" -#include "glapi.h" -#include "glthread.h" -#include "dispatch.h" -#include "extension_string.h" - -typedef struct __GLXDRIscreen __GLXDRIscreen; -typedef struct __GLXDRIcontext __GLXDRIcontext; -typedef struct __GLXDRIdrawable __GLXDRIdrawable; - -struct __GLXDRIscreen { - __GLXscreen base; - __DRIscreen *driScreen; - void *driver; - - xf86EnterVTProc *enterVT; - xf86LeaveVTProc *leaveVT; - - const __DRIcoreExtension *core; - const __DRIlegacyExtension *legacy; - const __DRIcopySubBufferExtension *copySubBuffer; - const __DRIswapControlExtension *swapControl; - -#ifdef __DRI_TEX_OFFSET - const __DRItexOffsetExtension *texOffset; - DRITexOffsetStartProcPtr texOffsetStart; - DRITexOffsetFinishProcPtr texOffsetFinish; - __GLXDRIdrawable *texOffsetOverride[16]; - GLuint lastTexOffsetOverride; -#endif - - unsigned char glx_enable_bits[__GLX_EXT_BYTES]; -}; - -struct __GLXDRIcontext { - __GLXcontext base; - __DRIcontext *driContext; - XID hwContextID; -}; - -struct __GLXDRIdrawable { - __GLXdrawable base; - __DRIdrawable *driDrawable; - - /* Pulled in from old __GLXpixmap */ -#ifdef __DRI_TEX_OFFSET - GLint texname; - __GLXDRIcontext *ctx; - unsigned long long offset; - DamagePtr pDamage; -#endif -}; - -static void -__glXDRIleaveServer(GLboolean rendering) -{ - int i; - - for (i = 0; rendering && i < screenInfo.numScreens; i++) { - __GLXDRIscreen * const screen = - (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]); - GLuint lastOverride = screen->lastTexOffsetOverride; - - if (lastOverride) { - __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride; - int j; - - for (j = 0; j < lastOverride; j++) { - __GLXDRIdrawable *pGlxPix = texOffsetOverride[j]; - - if (pGlxPix && pGlxPix->texname) { - pGlxPix->offset = - screen->texOffsetStart((PixmapPtr)pGlxPix->base.pDraw); - } - } - } - } - - DRIBlockHandler(NULL, NULL, NULL); - - for (i = 0; rendering && i < screenInfo.numScreens; i++) { - __GLXDRIscreen * const screen = - (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]); - GLuint lastOverride = screen->lastTexOffsetOverride; - - if (lastOverride) { - __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride; - int j; - - for (j = 0; j < lastOverride; j++) { - __GLXDRIdrawable *pGlxPix = texOffsetOverride[j]; - - if (pGlxPix && pGlxPix->texname) { - screen->texOffset->setTexOffset(pGlxPix->ctx->driContext, - pGlxPix->texname, - pGlxPix->offset, - pGlxPix->base.pDraw->depth, - ((PixmapPtr)pGlxPix->base.pDraw)->devKind); - } - } - } - } -} - -static void -__glXDRIenterServer(GLboolean rendering) -{ - int i; - - for (i = 0; rendering && i < screenInfo.numScreens; i++) { - __GLXDRIscreen * const screen = (__GLXDRIscreen *) - glxGetScreen(screenInfo.screens[i]); - - if (screen->lastTexOffsetOverride) { - CALL_Flush(GET_DISPATCH(), ()); - break; - } - } - - DRIWakeupHandler(NULL, 0, NULL); -} - - -static void -__glXDRIdoReleaseTexImage(__GLXDRIscreen *screen, __GLXDRIdrawable *drawable) -{ - GLuint lastOverride = screen->lastTexOffsetOverride; - - if (lastOverride) { - __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride; - int i; - - for (i = 0; i < lastOverride; i++) { - if (texOffsetOverride[i] == drawable) { - if (screen->texOffsetFinish) - screen->texOffsetFinish((PixmapPtr)drawable->base.pDraw); - - texOffsetOverride[i] = NULL; - - if (i + 1 == lastOverride) { - lastOverride = 0; - - while (i--) { - if (texOffsetOverride[i]) { - lastOverride = i + 1; - break; - } - } - - screen->lastTexOffsetOverride = lastOverride; - - break; - } - } - } - } -} - - -static void -__glXDRIdrawableDestroy(__GLXdrawable *drawable) -{ - __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; - __GLXDRIscreen *screen; - int i; - - for (i = 0; i < screenInfo.numScreens; i++) { - screen = (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]); - __glXDRIdoReleaseTexImage(screen, private); - } - - /* If the X window was destroyed, the dri DestroyWindow hook will - * aready have taken care of this, so only call if pDraw isn't NULL. */ - if (drawable->pDraw != NULL) { - screen = (__GLXDRIscreen *) glxGetScreen(drawable->pDraw->pScreen); - (*screen->core->destroyDrawable)(private->driDrawable); - - __glXenterServer(GL_FALSE); - DRIDestroyDrawable(drawable->pDraw->pScreen, - serverClient, drawable->pDraw); - __glXleaveServer(GL_FALSE); - } - - __glXDrawableRelease(drawable); - - xfree(private); -} - -static GLboolean -__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *basePrivate) -{ - __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate; - __GLXDRIscreen *screen = - (__GLXDRIscreen *) glxGetScreen(basePrivate->pDraw->pScreen); - - (*screen->core->swapBuffers)(private->driDrawable); - - return TRUE; -} - - -static int -__glXDRIdrawableSwapInterval(__GLXdrawable *baseDrawable, int interval) -{ - __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseDrawable; - __GLXDRIscreen *screen = - (__GLXDRIscreen *) glxGetScreen(baseDrawable->pDraw->pScreen); - - if (screen->swapControl) - screen->swapControl->setSwapInterval(draw->driDrawable, interval); - - return 0; -} - - -static void -__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate, - int x, int y, int w, int h) -{ - __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate; - __GLXDRIscreen *screen = (__GLXDRIscreen *) - glxGetScreen(basePrivate->pDraw->pScreen); - - if (screen->copySubBuffer) - screen->copySubBuffer->copySubBuffer(private->driDrawable, x, y, w, h); -} - -static void -__glXDRIcontextDestroy(__GLXcontext *baseContext) -{ - __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; - __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - Bool retval; - - screen->core->destroyContext(context->driContext); - - __glXenterServer(GL_FALSE); - retval = DRIDestroyContext(baseContext->pGlxScreen->pScreen, - context->hwContextID); - __glXleaveServer(GL_FALSE); - - __glXContextDestroy(&context->base); - xfree(context); -} - -static int -__glXDRIcontextMakeCurrent(__GLXcontext *baseContext) -{ - __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; - __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; - __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; - - return (*screen->core->bindContext)(context->driContext, - draw->driDrawable, - read->driDrawable); -} - -static int -__glXDRIcontextLoseCurrent(__GLXcontext *baseContext) -{ - __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; - __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - - return (*screen->core->unbindContext)(context->driContext); -} - -static int -__glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc, - unsigned long mask) -{ - __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst; - __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc; - __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen; - - return (*screen->core->copyContext)(dst->driContext, - src->driContext, mask); -} - -static int -__glXDRIcontextForceCurrent(__GLXcontext *baseContext) -{ - __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; - __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; - __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; - __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - - return (*screen->core->bindContext)(context->driContext, - draw->driDrawable, - read->driDrawable); -} - -static void -glxFillAlphaChannel (CARD32 *pixels, CARD32 rowstride, int width, int height) -{ - int i; - CARD32 *p, *end; - - rowstride /= 4; - - for (i = 0; i < height; i++) - { - p = pixels; - end = p + width; - while (p < end) - *p++ |= 0xFF000000; - pixels += rowstride; - } -} - -static Bool -testTexOffset(__GLXDRIscreen * const screen, PixmapPtr pPixmap) -{ - Bool ret; - - if (!screen->texOffsetStart || !screen->texOffset) - return FALSE; - - __glXenterServer(GL_FALSE); - ret = screen->texOffsetStart(pPixmap) != ~0ULL; - __glXleaveServer(GL_FALSE); - - return ret; -} - -/* - * (sticking this here for lack of a better place) - * Known issues with the GLX_EXT_texture_from_pixmap implementation: - * - In general we ignore the fbconfig, lots of examples follow - * - No fbconfig handling for multiple mipmap levels - * - No fbconfig handling for 1D textures - * - No fbconfig handling for TEXTURE_TARGET - * - No fbconfig exposure of Y inversion state - * - No GenerateMipmapEXT support (due to no FBO support) - * - No support for anything but 16bpp and 32bpp-sparse pixmaps - */ - -static int -__glXDRIbindTexImage(__GLXcontext *baseContext, - int buffer, - __GLXdrawable *glxPixmap) -{ - RegionPtr pRegion = NULL; - PixmapPtr pixmap; - int bpp, override = 0, texname; - GLenum format, type; - ScreenPtr pScreen = glxPixmap->pDraw->pScreen; - __GLXDRIdrawable *driDraw = (__GLXDRIdrawable *) glxPixmap; - __GLXDRIscreen * const screen = (__GLXDRIscreen *) glxGetScreen(pScreen); - - CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ? - GL_TEXTURE_BINDING_2D : - GL_TEXTURE_BINDING_RECTANGLE_NV, - &texname)); - - if (!texname) - return __glXError(GLXBadContextState); - - pixmap = (PixmapPtr) glxPixmap->pDraw; - - if (testTexOffset(screen, pixmap)) { - __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride; - int i, firstEmpty = 16; - - for (i = 0; i < 16; i++) { - if (texOffsetOverride[i] == driDraw) - goto alreadyin; - - if (firstEmpty == 16 && !texOffsetOverride[i]) - firstEmpty = i; - } - - if (firstEmpty == 16) { - ErrorF("%s: Failed to register texture offset override\n", __func__); - goto nooverride; - } - - if (firstEmpty >= screen->lastTexOffsetOverride) - screen->lastTexOffsetOverride = firstEmpty + 1; - - texOffsetOverride[firstEmpty] = driDraw; - -alreadyin: - override = 1; - - driDraw->ctx = (__GLXDRIcontext*)baseContext; - - if (texname == driDraw->texname) - return Success; - - driDraw->texname = texname; - - screen->texOffset->setTexOffset(driDraw->ctx->driContext, texname, 0, - pixmap->drawable.depth, - pixmap->devKind); - } -nooverride: - - if (!driDraw->pDamage) { - if (!override) { - driDraw->pDamage = DamageCreate(NULL, NULL, DamageReportNone, - TRUE, pScreen, NULL); - if (!driDraw->pDamage) - return BadAlloc; - - DamageRegister ((DrawablePtr) pixmap, driDraw->pDamage); - } - - pRegion = NULL; - } else { - pRegion = DamageRegion(driDraw->pDamage); - if (REGION_NIL(pRegion)) - return Success; - } - - /* XXX 24bpp packed, 8, etc */ - if (pixmap->drawable.depth >= 24) { - bpp = 4; - format = GL_BGRA; - type = -#if X_BYTE_ORDER == X_BIG_ENDIAN - !override ? GL_UNSIGNED_INT_8_8_8_8_REV : -#endif - GL_UNSIGNED_BYTE; - } else { - bpp = 2; - format = GL_RGB; - type = GL_UNSIGNED_SHORT_5_6_5; - } - - if (pRegion == NULL) - { - void *data = NULL; - - if (!override) { - unsigned pitch = PixmapBytePad(pixmap->drawable.width, - pixmap->drawable.depth); - - data = xalloc(pitch * pixmap->drawable.height); - - __glXenterServer(GL_FALSE); - pScreen->GetImage(&pixmap->drawable, 0 /*pixmap->drawable.x*/, - 0 /*pixmap->drawable.y*/, pixmap->drawable.width, - pixmap->drawable.height, ZPixmap, ~0, data); - __glXleaveServer(GL_FALSE); - - if (pixmap->drawable.depth == 24) - glxFillAlphaChannel(data, - pitch, - pixmap->drawable.width, - pixmap->drawable.height); - - CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH, - pitch / bpp) ); - CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, 0) ); - CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, 0) ); - } - - CALL_TexImage2D( GET_DISPATCH(), - (glxPixmap->target, - 0, - bpp == 4 ? 4 : 3, - pixmap->drawable.width, - pixmap->drawable.height, - 0, - format, - type, - data) ); - - xfree(data); - } else if (!override) { - int i, numRects; - BoxPtr p; - - numRects = REGION_NUM_RECTS (pRegion); - p = REGION_RECTS (pRegion); - - CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, 0) ); - CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, 0) ); - - for (i = 0; i < numRects; i++) - { - unsigned pitch = PixmapBytePad(p[i].x2 - p[i].x1, - pixmap->drawable.depth); - void *data = xalloc(pitch * (p[i].y2 - p[i].y1)); - - __glXenterServer(GL_FALSE); - pScreen->GetImage(&pixmap->drawable, /*pixmap->drawable.x +*/ p[i].x1, - /*pixmap->drawable.y*/ + p[i].y1, p[i].x2 - p[i].x1, - p[i].y2 - p[i].y1, ZPixmap, ~0, data); - __glXleaveServer(GL_FALSE); - - if (pixmap->drawable.depth == 24) - glxFillAlphaChannel(data, - pitch, - p[i].x2 - p[i].x1, - p[i].y2 - p[i].y1); - - CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH, - pitch / bpp) ); - - CALL_TexSubImage2D( GET_DISPATCH(), - (glxPixmap->target, - 0, - p[i].x1, p[i].y1, - p[i].x2 - p[i].x1, p[i].y2 - p[i].y1, - format, - type, - data) ); - - xfree(data); - } - } - - if (!override) - DamageEmpty(driDraw->pDamage); - - return Success; -} - -static int -__glXDRIreleaseTexImage(__GLXcontext *baseContext, - int buffer, - __GLXdrawable *pixmap) -{ - __GLXDRIscreen *screen = - (__GLXDRIscreen *) glxGetScreen(pixmap->pDraw->pScreen); - __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) pixmap; - - __glXDRIdoReleaseTexImage(screen, drawable); - - return Success; -} - -static __GLXtextureFromPixmap __glXDRItextureFromPixmap = { - __glXDRIbindTexImage, - __glXDRIreleaseTexImage -}; - -static void -__glXDRIscreenDestroy(__GLXscreen *baseScreen) -{ - __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; - - screen->core->destroyScreen(screen->driScreen); - - dlclose(screen->driver); - - __glXScreenDestroy(baseScreen); - - xfree(screen); -} - -static __GLXcontext * -__glXDRIscreenCreateContext(__GLXscreen *baseScreen, - __GLXconfig *glxConfig, - __GLXcontext *baseShareContext) -{ - __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; - __GLXDRIcontext *context, *shareContext; - __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; - VisualPtr visual; - int i; - GLboolean retval; - __DRIcontext *driShare; - drm_context_t hwContext; - ScreenPtr pScreen = baseScreen->pScreen; - - shareContext = (__GLXDRIcontext *) baseShareContext; - if (shareContext) - driShare = shareContext->driContext; - else - driShare = NULL; - - if (baseShareContext && baseShareContext->isDirect) - return NULL; - - context = xcalloc(1, sizeof *context); - if (context == NULL) - return NULL; - - context->base.destroy = __glXDRIcontextDestroy; - context->base.makeCurrent = __glXDRIcontextMakeCurrent; - context->base.loseCurrent = __glXDRIcontextLoseCurrent; - context->base.copy = __glXDRIcontextCopy; - context->base.forceCurrent = __glXDRIcontextForceCurrent; - - context->base.textureFromPixmap = &__glXDRItextureFromPixmap; - /* Find the requested X visual */ - visual = pScreen->visuals; - for (i = 0; i < pScreen->numVisuals; i++, visual++) - if (visual->vid == glxConfig->visualID) - break; - if (i == pScreen->numVisuals) - return NULL; - - context->hwContextID = FakeClientID(0); - - __glXenterServer(GL_FALSE); - retval = DRICreateContext(baseScreen->pScreen, visual, - context->hwContextID, &hwContext); - __glXleaveServer(GL_FALSE); - - if (!retval) - return NULL; - - context->driContext = - screen->legacy->createNewContext(screen->driScreen, - config->driConfig, - 0, /* render type */ - driShare, - hwContext, - context); - - if (context->driContext == NULL) { - __glXenterServer(GL_FALSE); - retval = DRIDestroyContext(baseScreen->pScreen, context->hwContextID); - __glXleaveServer(GL_FALSE); - xfree(context); - return NULL; - } - - return &context->base; -} - -static __GLXdrawable * -__glXDRIscreenCreateDrawable(__GLXscreen *screen, - DrawablePtr pDraw, - int type, - XID drawId, - __GLXconfig *glxConfig) -{ - __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; - __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; - __GLXDRIdrawable *private; - GLboolean retval; - drm_drawable_t hwDrawable; - - private = xcalloc(1, sizeof *private); - if (private == NULL) - return NULL; - - if (!__glXDrawableInit(&private->base, screen, - pDraw, type, drawId, glxConfig)) { - xfree(private); - return NULL; - } - - private->base.destroy = __glXDRIdrawableDestroy; - private->base.swapBuffers = __glXDRIdrawableSwapBuffers; - private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer; - private->base.waitX = NULL; - private->base.waitGL = NULL; - - __glXenterServer(GL_FALSE); - retval = DRICreateDrawable(screen->pScreen, serverClient, - pDraw, &hwDrawable); - __glXleaveServer(GL_FALSE); - - if (!retval) { - xfree(private); - return NULL; - } - - /* The last argument is 'attrs', which is used with pbuffers which - * we currently don't support. */ - - private->driDrawable = - (driScreen->legacy->createNewDrawable)(driScreen->driScreen, - config->driConfig, - hwDrawable, 0, NULL, private); - - if (private->driDrawable == NULL) { - __glXenterServer(GL_FALSE); - DRIDestroyDrawable(screen->pScreen, serverClient, pDraw); - __glXleaveServer(GL_FALSE); - xfree(private); - return NULL; - } - - return &private->base; -} - -static GLboolean -getDrawableInfo(__DRIdrawable *driDrawable, - unsigned int *index, unsigned int *stamp, - int *x, int *y, int *width, int *height, - int *numClipRects, drm_clip_rect_t **ppClipRects, - int *backX, int *backY, - int *numBackClipRects, drm_clip_rect_t **ppBackClipRects, - void *data) -{ - __GLXDRIdrawable *drawable = data; - ScreenPtr pScreen; - drm_clip_rect_t *pClipRects, *pBackClipRects; - GLboolean retval; - size_t size; - - /* If the X window has been destroyed, give up here. */ - if (drawable->base.pDraw == NULL) - return GL_FALSE; - - pScreen = drawable->base.pDraw->pScreen; - __glXenterServer(GL_FALSE); - retval = DRIGetDrawableInfo(pScreen, drawable->base.pDraw, index, stamp, - x, y, width, height, - numClipRects, &pClipRects, - backX, backY, - numBackClipRects, &pBackClipRects); - __glXleaveServer(GL_FALSE); - - if (retval && *numClipRects > 0) { - size = sizeof (drm_clip_rect_t) * *numClipRects; - *ppClipRects = xalloc (size); - - /* Clip cliprects to screen dimensions (redirected windows) */ - if (*ppClipRects != NULL) { - int i, j; - - for (i = 0, j = 0; i < *numClipRects; i++) { - (*ppClipRects)[j].x1 = max(pClipRects[i].x1, 0); - (*ppClipRects)[j].y1 = max(pClipRects[i].y1, 0); - (*ppClipRects)[j].x2 = min(pClipRects[i].x2, pScreen->width); - (*ppClipRects)[j].y2 = min(pClipRects[i].y2, pScreen->height); - - if ((*ppClipRects)[j].x1 < (*ppClipRects)[j].x2 && - (*ppClipRects)[j].y1 < (*ppClipRects)[j].y2) { - j++; - } - } - - if (*numClipRects != j) { - *numClipRects = j; - *ppClipRects = xrealloc (*ppClipRects, - sizeof (drm_clip_rect_t) * - *numClipRects); - } - } else - *numClipRects = 0; - } - else { - *ppClipRects = NULL; - *numClipRects = 0; - } - - if (retval && *numBackClipRects > 0) { - size = sizeof (drm_clip_rect_t) * *numBackClipRects; - *ppBackClipRects = xalloc (size); - if (*ppBackClipRects != NULL) - memcpy (*ppBackClipRects, pBackClipRects, size); - else - *numBackClipRects = 0; - } - else { - *ppBackClipRects = NULL; - *numBackClipRects = 0; - } - - return retval; -} - -static void __glXReportDamage(__DRIdrawable *driDraw, - int x, int y, - drm_clip_rect_t *rects, int num_rects, - GLboolean front_buffer, - void *data) -{ - __GLXDRIdrawable *drawable = data; - DrawablePtr pDraw = drawable->base.pDraw; - RegionRec region; - - __glXenterServer(GL_FALSE); - - REGION_INIT(pDraw->pScreen, ®ion, (BoxPtr) rects, num_rects); - REGION_TRANSLATE(pScreen, ®ion, pDraw->x, pDraw->y); - DamageRegionAppend(pDraw, ®ion); - /* This is wrong, this needs a seperate function. */ - DamageRegionProcessPending(pDraw); - REGION_UNINIT(pDraw->pScreen, ®ion); - - __glXleaveServer(GL_FALSE); -} - -static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = { - { __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION }, - getDrawableInfo -}; - -static const __DRIdamageExtension damageExtension = { - { __DRI_DAMAGE, __DRI_DAMAGE_VERSION }, - __glXReportDamage, -}; - -static const __DRIextension *loader_extensions[] = { - &systemTimeExtension.base, - &getDrawableInfoExtension.base, - &damageExtension.base, - NULL -}; - - - -static const char dri_driver_path[] = DRI_DRIVER_PATH; - -static Bool -glxDRIEnterVT (int index, int flags) -{ - __GLXDRIscreen *screen = (__GLXDRIscreen *) - glxGetScreen(screenInfo.screens[index]); - - LogMessage(X_INFO, "AIGLX: Resuming AIGLX clients after VT switch\n"); - - if (!(*screen->enterVT) (index, flags)) - return FALSE; - - glxResumeClients(); - - return TRUE; -} - -static void -glxDRILeaveVT (int index, int flags) -{ - __GLXDRIscreen *screen = (__GLXDRIscreen *) - glxGetScreen(screenInfo.screens[index]); - - LogMessage(X_INFO, "AIGLX: Suspending AIGLX clients for VT switch\n"); - - glxSuspendClients(); - - return (*screen->leaveVT) (index, flags); -} - -static void -initializeExtensions(__GLXDRIscreen *screen) -{ - const __DRIextension **extensions; - int i; - - extensions = screen->core->getExtensions(screen->driScreen); - - for (i = 0; extensions[i]; i++) { -#ifdef __DRI_READ_DRAWABLE - if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) { - __glXEnableExtension(screen->glx_enable_bits, - "GLX_SGI_make_current_read"); - - LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n"); - } -#endif - -#ifdef __DRI_COPY_SUB_BUFFER - if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { - screen->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i]; - __glXEnableExtension(screen->glx_enable_bits, - "GLX_MESA_copy_sub_buffer"); - - LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n"); - } -#endif - -#ifdef __DRI_SWAP_CONTROL - if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) { - screen->swapControl = (__DRIswapControlExtension *) extensions[i]; - __glXEnableExtension(screen->glx_enable_bits, - "GLX_SGI_swap_control"); - __glXEnableExtension(screen->glx_enable_bits, - "GLX_MESA_swap_control"); - - LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n"); - } -#endif - -#ifdef __DRI_TEX_OFFSET - if (strcmp(extensions[i]->name, __DRI_TEX_OFFSET) == 0) { - screen->texOffset = (__DRItexOffsetExtension *) extensions[i]; - LogMessage(X_INFO, "AIGLX: enabled GLX_texture_from_pixmap with driver support\n"); - } -#endif - /* Ignore unknown extensions */ - } -} - -extern __GLXconfig * -glxConvertConfigs(const __DRIcoreExtension *core, const __DRIconfig **configs); - -static __GLXscreen * -__glXDRIscreenProbe(ScreenPtr pScreen) -{ - drm_handle_t hSAREA; - drmAddress pSAREA = NULL; - char *BusID; - __DRIversion ddx_version; - __DRIversion dri_version; - __DRIversion drm_version; - __DRIframebuffer framebuffer; - int fd = -1; - int status; - drm_magic_t magic; - drmVersionPtr version; - int newlyopened; - char *driverName; - drm_handle_t hFB; - int junk; - __GLXDRIscreen *screen; - char filename[128]; - Bool isCapable; - size_t buffer_size; - ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; - const __DRIconfig **driConfigs; - const __DRIextension **extensions; - int i; - - if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") || - !DRIQueryDirectRenderingCapable(pScreen, &isCapable) || - !isCapable) { - LogMessage(X_INFO, - "AIGLX: Screen %d is not DRI capable\n", pScreen->myNum); - return NULL; - } - - screen = xcalloc(1, sizeof *screen); - if (screen == NULL) - return NULL; - - screen->base.destroy = __glXDRIscreenDestroy; - screen->base.createContext = __glXDRIscreenCreateContext; - screen->base.createDrawable = __glXDRIscreenCreateDrawable; - screen->base.swapInterval = __glXDRIdrawableSwapInterval; - screen->base.pScreen = pScreen; - - __glXInitExtensionEnableBits(screen->glx_enable_bits); - - /* DRI protocol version. */ - dri_version.major = XF86DRI_MAJOR_VERSION; - dri_version.minor = XF86DRI_MINOR_VERSION; - dri_version.patch = XF86DRI_PATCH_VERSION; - - if (!DRIOpenConnection(pScreen, &hSAREA, &BusID)) { - LogMessage(X_ERROR, "AIGLX error: DRIOpenConnection failed\n"); - goto handle_error; - } - - fd = drmOpenOnce(NULL, BusID, &newlyopened); - - if (fd < 0) { - LogMessage(X_ERROR, "AIGLX error: drmOpenOnce failed (%s)\n", - strerror(-fd)); - goto handle_error; - } - - if (drmGetMagic(fd, &magic)) { - LogMessage(X_ERROR, "AIGLX error: drmGetMagic failed\n"); - goto handle_error; - } - - version = drmGetVersion(fd); - if (version) { - drm_version.major = version->version_major; - drm_version.minor = version->version_minor; - drm_version.patch = version->version_patchlevel; - drmFreeVersion(version); - } - else { - drm_version.major = -1; - drm_version.minor = -1; - drm_version.patch = -1; - } - - if (newlyopened && !DRIAuthConnection(pScreen, magic)) { - LogMessage(X_ERROR, "AIGLX error: DRIAuthConnection failed\n"); - goto handle_error; - } - - /* Get device name (like "tdfx") and the ddx version numbers. - * We'll check the version in each DRI driver's "createNewScreen" - * function. */ - if (!DRIGetClientDriverName(pScreen, - &ddx_version.major, - &ddx_version.minor, - &ddx_version.patch, - &driverName)) { - LogMessage(X_ERROR, "AIGLX error: DRIGetClientDriverName failed\n"); - goto handle_error; - } - - snprintf(filename, sizeof filename, "%s/%s_dri.so", - dri_driver_path, driverName); - - screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); - if (screen->driver == NULL) { - LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n", - filename, dlerror()); - goto handle_error; - } - - extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS); - if (extensions == NULL) { - LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n", - driverName, dlerror()); - goto handle_error; - } - - for (i = 0; extensions[i]; i++) { - if (strcmp(extensions[i]->name, __DRI_CORE) == 0 && - extensions[i]->version >= __DRI_CORE_VERSION) { - screen->core = (__DRIcoreExtension *) extensions[i]; - } - - if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0 && - extensions[i]->version >= __DRI_LEGACY_VERSION) { - screen->legacy = (__DRIlegacyExtension *) extensions[i]; - } - } - - if (screen->core == NULL || screen->legacy == NULL) { - LogMessage(X_ERROR, - "AIGLX error: %s does not export required DRI extension\n", - driverName); - goto handle_error; - } - - /* - * Get device-specific info. pDevPriv will point to a struct - * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that - * has information about the screen size, depth, pitch, ancilliary - * buffers, DRM mmap handles, etc. - */ - if (!DRIGetDeviceInfo(pScreen, &hFB, &junk, - &framebuffer.size, &framebuffer.stride, - &framebuffer.dev_priv_size, &framebuffer.dev_priv)) { - LogMessage(X_ERROR, "AIGLX error: XF86DRIGetDeviceInfo failed\n"); - goto handle_error; - } - - framebuffer.width = pScreen->width; - framebuffer.height = pScreen->height; - - /* Map the framebuffer region. */ - status = drmMap(fd, hFB, framebuffer.size, - (drmAddressPtr)&framebuffer.base); - if (status != 0) { - LogMessage(X_ERROR, "AIGLX error: drmMap of framebuffer failed (%s)\n", - strerror(-status)); - goto handle_error; - } - - /* Map the SAREA region. Further mmap regions may be setup in - * each DRI driver's "createNewScreen" function. - */ - status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA); - if (status != 0) { - LogMessage(X_ERROR, "AIGLX error: drmMap of SAREA failed (%s)\n", - strerror(-status)); - goto handle_error; - } - - screen->driScreen = - (*screen->legacy->createNewScreen)(pScreen->myNum, - &ddx_version, - &dri_version, - &drm_version, - &framebuffer, - pSAREA, - fd, - loader_extensions, - &driConfigs, - screen); - - if (screen->driScreen == NULL) { - LogMessage(X_ERROR, - "AIGLX error: Calling driver entry point failed\n"); - goto handle_error; - } - - screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs); - - initializeExtensions(screen); - - DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart, - &screen->texOffsetFinish); - - __glXScreenInit(&screen->base, pScreen); - - /* The first call simply determines the length of the extension string. - * This allows us to allocate some memory to hold the extension string, - * but it requires that we call __glXGetExtensionString a second time. - */ - buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL); - if (buffer_size > 0) { - if (screen->base.GLXextensions != NULL) { - xfree(screen->base.GLXextensions); - } - - screen->base.GLXextensions = xnfalloc(buffer_size); - (void) __glXGetExtensionString(screen->glx_enable_bits, - screen->base.GLXextensions); - } - - __glXsetEnterLeaveServerFuncs(__glXDRIenterServer, __glXDRIleaveServer); - - screen->enterVT = pScrn->EnterVT; - pScrn->EnterVT = glxDRIEnterVT; - screen->leaveVT = pScrn->LeaveVT; - pScrn->LeaveVT = glxDRILeaveVT; - - LogMessage(X_INFO, - "AIGLX: Loaded and initialized %s\n", filename); - - return &screen->base; - - handle_error: - if (pSAREA != NULL) - drmUnmap(pSAREA, SAREA_MAX); - - if (framebuffer.base != NULL) - drmUnmap((drmAddress)framebuffer.base, framebuffer.size); - - if (fd >= 0) - drmCloseOnce(fd); - - DRICloseConnection(pScreen); - - if (screen->driver) - dlclose(screen->driver); - - xfree(screen); - - LogMessage(X_ERROR, "AIGLX: reverting to software rendering\n"); - - return NULL; -} - -_X_EXPORT __GLXprovider __glXDRIProvider = { - __glXDRIscreenProbe, - "DRI", - NULL -}; +/*
+ * Copyright © 2006 Red Hat, 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 Red Hat,
+ * Inc not be used in advertising or publicity pertaining to
+ * distribution of the software without specific, written prior
+ * permission. Red Hat, Inc makes no representations about the
+ * suitability of this software for any purpose. It is provided "as
+ * is" without express or implied warranty.
+ *
+ * RED HAT, INC DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
+ * NO EVENT SHALL RED HAT, INC 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 <dix-config.h>
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#ifndef _MSC_VER
+#include <sys/time.h>
+#include <dlfcn.h>
+
+#include <drm.h>
+#endif
+
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
+
+#include <windowstr.h>
+#include <os.h>
+#include <damage.h>
+
+#define _XF86DRI_SERVER_
+#include <drm_sarea.h>
+#include <xf86drm.h>
+#include <X11/dri/xf86driproto.h>
+#include <xf86str.h>
+#include <xf86.h>
+#include <dri.h>
+
+#include "servermd.h"
+
+#define DRI_NEW_INTERFACE_ONLY
+#include "glxserver.h"
+#include "glxutil.h"
+#include "glxdricommon.h"
+
+#include "g_disptab.h"
+#include "glapitable.h"
+#include "glapi.h"
+#include "glthread.h"
+#include "dispatch.h"
+#include "extension_string.h"
+
+typedef struct __GLXDRIscreen __GLXDRIscreen;
+typedef struct __GLXDRIcontext __GLXDRIcontext;
+typedef struct __GLXDRIdrawable __GLXDRIdrawable;
+
+struct __GLXDRIscreen {
+ __GLXscreen base;
+ __DRIscreen *driScreen;
+ void *driver;
+
+ xf86EnterVTProc *enterVT;
+ xf86LeaveVTProc *leaveVT;
+
+ const __DRIcoreExtension *core;
+ const __DRIlegacyExtension *legacy;
+ const __DRIcopySubBufferExtension *copySubBuffer;
+ const __DRIswapControlExtension *swapControl;
+
+#ifdef __DRI_TEX_OFFSET
+ const __DRItexOffsetExtension *texOffset;
+ DRITexOffsetStartProcPtr texOffsetStart;
+ DRITexOffsetFinishProcPtr texOffsetFinish;
+ __GLXDRIdrawable *texOffsetOverride[16];
+ GLuint lastTexOffsetOverride;
+#endif
+
+ unsigned char glx_enable_bits[__GLX_EXT_BYTES];
+};
+
+struct __GLXDRIcontext {
+ __GLXcontext base;
+ __DRIcontext *driContext;
+ XID hwContextID;
+};
+
+struct __GLXDRIdrawable {
+ __GLXdrawable base;
+ __DRIdrawable *driDrawable;
+
+ /* Pulled in from old __GLXpixmap */
+#ifdef __DRI_TEX_OFFSET
+ GLint texname;
+ __GLXDRIcontext *ctx;
+ unsigned long long offset;
+ DamagePtr pDamage;
+#endif
+};
+
+static void
+__glXDRIleaveServer(GLboolean rendering)
+{
+ int i;
+
+ for (i = 0; rendering && i < screenInfo.numScreens; i++) {
+ __GLXDRIscreen * const screen =
+ (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]);
+ GLuint lastOverride = screen->lastTexOffsetOverride;
+
+ if (lastOverride) {
+ __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
+ int j;
+
+ for (j = 0; j < lastOverride; j++) {
+ __GLXDRIdrawable *pGlxPix = texOffsetOverride[j];
+
+ if (pGlxPix && pGlxPix->texname) {
+ pGlxPix->offset =
+ screen->texOffsetStart((PixmapPtr)pGlxPix->base.pDraw);
+ }
+ }
+ }
+ }
+
+ DRIBlockHandler(NULL, NULL, NULL);
+
+ for (i = 0; rendering && i < screenInfo.numScreens; i++) {
+ __GLXDRIscreen * const screen =
+ (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]);
+ GLuint lastOverride = screen->lastTexOffsetOverride;
+
+ if (lastOverride) {
+ __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
+ int j;
+
+ for (j = 0; j < lastOverride; j++) {
+ __GLXDRIdrawable *pGlxPix = texOffsetOverride[j];
+
+ if (pGlxPix && pGlxPix->texname) {
+ screen->texOffset->setTexOffset(pGlxPix->ctx->driContext,
+ pGlxPix->texname,
+ pGlxPix->offset,
+ pGlxPix->base.pDraw->depth,
+ ((PixmapPtr)pGlxPix->base.pDraw)->devKind);
+ }
+ }
+ }
+ }
+}
+
+static void
+__glXDRIenterServer(GLboolean rendering)
+{
+ int i;
+
+ for (i = 0; rendering && i < screenInfo.numScreens; i++) {
+ __GLXDRIscreen * const screen = (__GLXDRIscreen *)
+ glxGetScreen(screenInfo.screens[i]);
+
+ if (screen->lastTexOffsetOverride) {
+ CALL_Flush(GET_DISPATCH(), ());
+ break;
+ }
+ }
+
+ DRIWakeupHandler(NULL, 0, NULL);
+}
+
+
+static void
+__glXDRIdoReleaseTexImage(__GLXDRIscreen *screen, __GLXDRIdrawable *drawable)
+{
+ GLuint lastOverride = screen->lastTexOffsetOverride;
+
+ if (lastOverride) {
+ __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
+ int i;
+
+ for (i = 0; i < lastOverride; i++) {
+ if (texOffsetOverride[i] == drawable) {
+ if (screen->texOffsetFinish)
+ screen->texOffsetFinish((PixmapPtr)drawable->base.pDraw);
+
+ texOffsetOverride[i] = NULL;
+
+ if (i + 1 == lastOverride) {
+ lastOverride = 0;
+
+ while (i--) {
+ if (texOffsetOverride[i]) {
+ lastOverride = i + 1;
+ break;
+ }
+ }
+
+ screen->lastTexOffsetOverride = lastOverride;
+
+ break;
+ }
+ }
+ }
+ }
+}
+
+
+static void
+__glXDRIdrawableDestroy(__GLXdrawable *drawable)
+{
+ __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+ __GLXDRIscreen *screen;
+ int i;
+
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ screen = (__GLXDRIscreen *) glxGetScreen(screenInfo.screens[i]);
+ __glXDRIdoReleaseTexImage(screen, private);
+ }
+
+ /* If the X window was destroyed, the dri DestroyWindow hook will
+ * aready have taken care of this, so only call if pDraw isn't NULL. */
+ if (drawable->pDraw != NULL) {
+ screen = (__GLXDRIscreen *) glxGetScreen(drawable->pDraw->pScreen);
+ (*screen->core->destroyDrawable)(private->driDrawable);
+
+ __glXenterServer(GL_FALSE);
+ DRIDestroyDrawable(drawable->pDraw->pScreen,
+ serverClient, drawable->pDraw);
+ __glXleaveServer(GL_FALSE);
+ }
+
+ __glXDrawableRelease(drawable);
+
+ xfree(private);
+}
+
+static GLboolean
+__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *basePrivate)
+{
+ __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
+ __GLXDRIscreen *screen =
+ (__GLXDRIscreen *) glxGetScreen(basePrivate->pDraw->pScreen);
+
+ (*screen->core->swapBuffers)(private->driDrawable);
+
+ return TRUE;
+}
+
+
+static int
+__glXDRIdrawableSwapInterval(__GLXdrawable *baseDrawable, int interval)
+{
+ __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseDrawable;
+ __GLXDRIscreen *screen =
+ (__GLXDRIscreen *) glxGetScreen(baseDrawable->pDraw->pScreen);
+
+ if (screen->swapControl)
+ screen->swapControl->setSwapInterval(draw->driDrawable, interval);
+
+ return 0;
+}
+
+
+static void
+__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate,
+ int x, int y, int w, int h)
+{
+ __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *)
+ glxGetScreen(basePrivate->pDraw->pScreen);
+
+ if (screen->copySubBuffer)
+ screen->copySubBuffer->copySubBuffer(private->driDrawable, x, y, w, h);
+}
+
+static void
+__glXDRIcontextDestroy(__GLXcontext *baseContext)
+{
+ __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
+ Bool retval;
+
+ screen->core->destroyContext(context->driContext);
+
+ __glXenterServer(GL_FALSE);
+ retval = DRIDestroyContext(baseContext->pGlxScreen->pScreen,
+ context->hwContextID);
+ __glXleaveServer(GL_FALSE);
+
+ __glXContextDestroy(&context->base);
+ xfree(context);
+}
+
+static int
+__glXDRIcontextMakeCurrent(__GLXcontext *baseContext)
+{
+ __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
+ __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
+ __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
+
+ return (*screen->core->bindContext)(context->driContext,
+ draw->driDrawable,
+ read->driDrawable);
+}
+
+static int
+__glXDRIcontextLoseCurrent(__GLXcontext *baseContext)
+{
+ __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
+
+ return (*screen->core->unbindContext)(context->driContext);
+}
+
+static int
+__glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc,
+ unsigned long mask)
+{
+ __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst;
+ __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen;
+
+ return (*screen->core->copyContext)(dst->driContext,
+ src->driContext, mask);
+}
+
+static int
+__glXDRIcontextForceCurrent(__GLXcontext *baseContext)
+{
+ __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+ __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
+ __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
+
+ return (*screen->core->bindContext)(context->driContext,
+ draw->driDrawable,
+ read->driDrawable);
+}
+
+static void
+glxFillAlphaChannel (CARD32 *pixels, CARD32 rowstride, int width, int height)
+{
+ int i;
+ CARD32 *p, *end;
+
+ rowstride /= 4;
+
+ for (i = 0; i < height; i++)
+ {
+ p = pixels;
+ end = p + width;
+ while (p < end)
+ *p++ |= 0xFF000000;
+ pixels += rowstride;
+ }
+}
+
+static Bool
+testTexOffset(__GLXDRIscreen * const screen, PixmapPtr pPixmap)
+{
+ Bool ret;
+
+ if (!screen->texOffsetStart || !screen->texOffset)
+ return FALSE;
+
+ __glXenterServer(GL_FALSE);
+ ret = screen->texOffsetStart(pPixmap) != ~0ULL;
+ __glXleaveServer(GL_FALSE);
+
+ return ret;
+}
+
+/*
+ * (sticking this here for lack of a better place)
+ * Known issues with the GLX_EXT_texture_from_pixmap implementation:
+ * - In general we ignore the fbconfig, lots of examples follow
+ * - No fbconfig handling for multiple mipmap levels
+ * - No fbconfig handling for 1D textures
+ * - No fbconfig handling for TEXTURE_TARGET
+ * - No fbconfig exposure of Y inversion state
+ * - No GenerateMipmapEXT support (due to no FBO support)
+ * - No support for anything but 16bpp and 32bpp-sparse pixmaps
+ */
+
+static int
+__glXDRIbindTexImage(__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *glxPixmap)
+{
+ RegionPtr pRegion = NULL;
+ PixmapPtr pixmap;
+ int bpp, override = 0, texname;
+ GLenum format, type;
+ ScreenPtr pScreen = glxPixmap->pDraw->pScreen;
+ __GLXDRIdrawable *driDraw = (__GLXDRIdrawable *) glxPixmap;
+ __GLXDRIscreen * const screen = (__GLXDRIscreen *) glxGetScreen(pScreen);
+
+ CALL_GetIntegerv(GET_DISPATCH(), (glxPixmap->target == GL_TEXTURE_2D ?
+ GL_TEXTURE_BINDING_2D :
+ GL_TEXTURE_BINDING_RECTANGLE_NV,
+ &texname));
+
+ if (!texname)
+ return __glXError(GLXBadContextState);
+
+ pixmap = (PixmapPtr) glxPixmap->pDraw;
+
+ if (testTexOffset(screen, pixmap)) {
+ __GLXDRIdrawable **texOffsetOverride = screen->texOffsetOverride;
+ int i, firstEmpty = 16;
+
+ for (i = 0; i < 16; i++) {
+ if (texOffsetOverride[i] == driDraw)
+ goto alreadyin;
+
+ if (firstEmpty == 16 && !texOffsetOverride[i])
+ firstEmpty = i;
+ }
+
+ if (firstEmpty == 16) {
+ ErrorF("%s: Failed to register texture offset override\n", __func__);
+ goto nooverride;
+ }
+
+ if (firstEmpty >= screen->lastTexOffsetOverride)
+ screen->lastTexOffsetOverride = firstEmpty + 1;
+
+ texOffsetOverride[firstEmpty] = driDraw;
+
+alreadyin:
+ override = 1;
+
+ driDraw->ctx = (__GLXDRIcontext*)baseContext;
+
+ if (texname == driDraw->texname)
+ return Success;
+
+ driDraw->texname = texname;
+
+ screen->texOffset->setTexOffset(driDraw->ctx->driContext, texname, 0,
+ pixmap->drawable.depth,
+ pixmap->devKind);
+ }
+nooverride:
+
+ if (!driDraw->pDamage) {
+ if (!override) {
+ driDraw->pDamage = DamageCreate(NULL, NULL, DamageReportNone,
+ TRUE, pScreen, NULL);
+ if (!driDraw->pDamage)
+ return BadAlloc;
+
+ DamageRegister ((DrawablePtr) pixmap, driDraw->pDamage);
+ }
+
+ pRegion = NULL;
+ } else {
+ pRegion = DamageRegion(driDraw->pDamage);
+ if (REGION_NIL(pRegion))
+ return Success;
+ }
+
+ /* XXX 24bpp packed, 8, etc */
+ if (pixmap->drawable.depth >= 24) {
+ bpp = 4;
+ format = GL_BGRA;
+ type =
+#if X_BYTE_ORDER == X_BIG_ENDIAN
+ !override ? GL_UNSIGNED_INT_8_8_8_8_REV :
+#endif
+ GL_UNSIGNED_BYTE;
+ } else {
+ bpp = 2;
+ format = GL_RGB;
+ type = GL_UNSIGNED_SHORT_5_6_5;
+ }
+
+ if (pRegion == NULL)
+ {
+ void *data = NULL;
+
+ if (!override) {
+ unsigned pitch = PixmapBytePad(pixmap->drawable.width,
+ pixmap->drawable.depth);
+
+ data = xalloc(pitch * pixmap->drawable.height);
+
+ __glXenterServer(GL_FALSE);
+ pScreen->GetImage(&pixmap->drawable, 0 /*pixmap->drawable.x*/,
+ 0 /*pixmap->drawable.y*/, pixmap->drawable.width,
+ pixmap->drawable.height, ZPixmap, ~0, data);
+ __glXleaveServer(GL_FALSE);
+
+ if (pixmap->drawable.depth == 24)
+ glxFillAlphaChannel(data,
+ pitch,
+ pixmap->drawable.width,
+ pixmap->drawable.height);
+
+ CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH,
+ pitch / bpp) );
+ CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, 0) );
+ CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, 0) );
+ }
+
+ CALL_TexImage2D( GET_DISPATCH(),
+ (glxPixmap->target,
+ 0,
+ bpp == 4 ? 4 : 3,
+ pixmap->drawable.width,
+ pixmap->drawable.height,
+ 0,
+ format,
+ type,
+ data) );
+
+ xfree(data);
+ } else if (!override) {
+ int i, numRects;
+ BoxPtr p;
+
+ numRects = REGION_NUM_RECTS (pRegion);
+ p = REGION_RECTS (pRegion);
+
+ CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_PIXELS, 0) );
+ CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_SKIP_ROWS, 0) );
+
+ for (i = 0; i < numRects; i++)
+ {
+ unsigned pitch = PixmapBytePad(p[i].x2 - p[i].x1,
+ pixmap->drawable.depth);
+ void *data = xalloc(pitch * (p[i].y2 - p[i].y1));
+
+ __glXenterServer(GL_FALSE);
+ pScreen->GetImage(&pixmap->drawable, /*pixmap->drawable.x +*/ p[i].x1,
+ /*pixmap->drawable.y*/ + p[i].y1, p[i].x2 - p[i].x1,
+ p[i].y2 - p[i].y1, ZPixmap, ~0, data);
+ __glXleaveServer(GL_FALSE);
+
+ if (pixmap->drawable.depth == 24)
+ glxFillAlphaChannel(data,
+ pitch,
+ p[i].x2 - p[i].x1,
+ p[i].y2 - p[i].y1);
+
+ CALL_PixelStorei( GET_DISPATCH(), (GL_UNPACK_ROW_LENGTH,
+ pitch / bpp) );
+
+ CALL_TexSubImage2D( GET_DISPATCH(),
+ (glxPixmap->target,
+ 0,
+ p[i].x1, p[i].y1,
+ p[i].x2 - p[i].x1, p[i].y2 - p[i].y1,
+ format,
+ type,
+ data) );
+
+ xfree(data);
+ }
+ }
+
+ if (!override)
+ DamageEmpty(driDraw->pDamage);
+
+ return Success;
+}
+
+static int
+__glXDRIreleaseTexImage(__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *pixmap)
+{
+ __GLXDRIscreen *screen =
+ (__GLXDRIscreen *) glxGetScreen(pixmap->pDraw->pScreen);
+ __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) pixmap;
+
+ __glXDRIdoReleaseTexImage(screen, drawable);
+
+ return Success;
+}
+
+static __GLXtextureFromPixmap __glXDRItextureFromPixmap = {
+ __glXDRIbindTexImage,
+ __glXDRIreleaseTexImage
+};
+
+static void
+__glXDRIscreenDestroy(__GLXscreen *baseScreen)
+{
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
+
+ screen->core->destroyScreen(screen->driScreen);
+
+ dlclose(screen->driver);
+
+ __glXScreenDestroy(baseScreen);
+
+ xfree(screen);
+}
+
+static __GLXcontext *
+__glXDRIscreenCreateContext(__GLXscreen *baseScreen,
+ __GLXconfig *glxConfig,
+ __GLXcontext *baseShareContext)
+{
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
+ __GLXDRIcontext *context, *shareContext;
+ __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
+ VisualPtr visual;
+ int i;
+ GLboolean retval;
+ __DRIcontext *driShare;
+ drm_context_t hwContext;
+ ScreenPtr pScreen = baseScreen->pScreen;
+
+ shareContext = (__GLXDRIcontext *) baseShareContext;
+ if (shareContext)
+ driShare = shareContext->driContext;
+ else
+ driShare = NULL;
+
+ if (baseShareContext && baseShareContext->isDirect)
+ return NULL;
+
+ context = xcalloc(1, sizeof *context);
+ if (context == NULL)
+ return NULL;
+
+ context->base.destroy = __glXDRIcontextDestroy;
+ context->base.makeCurrent = __glXDRIcontextMakeCurrent;
+ context->base.loseCurrent = __glXDRIcontextLoseCurrent;
+ context->base.copy = __glXDRIcontextCopy;
+ context->base.forceCurrent = __glXDRIcontextForceCurrent;
+
+ context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
+ /* Find the requested X visual */
+ visual = pScreen->visuals;
+ for (i = 0; i < pScreen->numVisuals; i++, visual++)
+ if (visual->vid == glxConfig->visualID)
+ break;
+ if (i == pScreen->numVisuals)
+ return NULL;
+
+ context->hwContextID = FakeClientID(0);
+
+ __glXenterServer(GL_FALSE);
+ retval = DRICreateContext(baseScreen->pScreen, visual,
+ context->hwContextID, &hwContext);
+ __glXleaveServer(GL_FALSE);
+
+ if (!retval)
+ return NULL;
+
+ context->driContext =
+ screen->legacy->createNewContext(screen->driScreen,
+ config->driConfig,
+ 0, /* render type */
+ driShare,
+ hwContext,
+ context);
+
+ if (context->driContext == NULL) {
+ __glXenterServer(GL_FALSE);
+ retval = DRIDestroyContext(baseScreen->pScreen, context->hwContextID);
+ __glXleaveServer(GL_FALSE);
+ xfree(context);
+ return NULL;
+ }
+
+ return &context->base;
+}
+
+static __GLXdrawable *
+__glXDRIscreenCreateDrawable(__GLXscreen *screen,
+ DrawablePtr pDraw,
+ int type,
+ XID drawId,
+ __GLXconfig *glxConfig)
+{
+ __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
+ __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
+ __GLXDRIdrawable *private;
+ GLboolean retval;
+ drm_drawable_t hwDrawable;
+
+ private = xcalloc(1, sizeof *private);
+ if (private == NULL)
+ return NULL;
+
+ if (!__glXDrawableInit(&private->base, screen,
+ pDraw, type, drawId, glxConfig)) {
+ xfree(private);
+ return NULL;
+ }
+
+ private->base.destroy = __glXDRIdrawableDestroy;
+ private->base.swapBuffers = __glXDRIdrawableSwapBuffers;
+ private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
+ private->base.waitX = NULL;
+ private->base.waitGL = NULL;
+
+ __glXenterServer(GL_FALSE);
+ retval = DRICreateDrawable(screen->pScreen, serverClient,
+ pDraw, &hwDrawable);
+ __glXleaveServer(GL_FALSE);
+
+ if (!retval) {
+ xfree(private);
+ return NULL;
+ }
+
+ /* The last argument is 'attrs', which is used with pbuffers which
+ * we currently don't support. */
+
+ private->driDrawable =
+ (driScreen->legacy->createNewDrawable)(driScreen->driScreen,
+ config->driConfig,
+ hwDrawable, 0, NULL, private);
+
+ if (private->driDrawable == NULL) {
+ __glXenterServer(GL_FALSE);
+ DRIDestroyDrawable(screen->pScreen, serverClient, pDraw);
+ __glXleaveServer(GL_FALSE);
+ xfree(private);
+ return NULL;
+ }
+
+ return &private->base;
+}
+
+static GLboolean
+getDrawableInfo(__DRIdrawable *driDrawable,
+ unsigned int *index, unsigned int *stamp,
+ int *x, int *y, int *width, int *height,
+ int *numClipRects, drm_clip_rect_t **ppClipRects,
+ int *backX, int *backY,
+ int *numBackClipRects, drm_clip_rect_t **ppBackClipRects,
+ void *data)
+{
+ __GLXDRIdrawable *drawable = data;
+ ScreenPtr pScreen;
+ drm_clip_rect_t *pClipRects, *pBackClipRects;
+ GLboolean retval;
+ size_t size;
+
+ /* If the X window has been destroyed, give up here. */
+ if (drawable->base.pDraw == NULL)
+ return GL_FALSE;
+
+ pScreen = drawable->base.pDraw->pScreen;
+ __glXenterServer(GL_FALSE);
+ retval = DRIGetDrawableInfo(pScreen, drawable->base.pDraw, index, stamp,
+ x, y, width, height,
+ numClipRects, &pClipRects,
+ backX, backY,
+ numBackClipRects, &pBackClipRects);
+ __glXleaveServer(GL_FALSE);
+
+ if (retval && *numClipRects > 0) {
+ size = sizeof (drm_clip_rect_t) * *numClipRects;
+ *ppClipRects = xalloc (size);
+
+ /* Clip cliprects to screen dimensions (redirected windows) */
+ if (*ppClipRects != NULL) {
+ int i, j;
+
+ for (i = 0, j = 0; i < *numClipRects; i++) {
+ (*ppClipRects)[j].x1 = max(pClipRects[i].x1, 0);
+ (*ppClipRects)[j].y1 = max(pClipRects[i].y1, 0);
+ (*ppClipRects)[j].x2 = min(pClipRects[i].x2, pScreen->width);
+ (*ppClipRects)[j].y2 = min(pClipRects[i].y2, pScreen->height);
+
+ if ((*ppClipRects)[j].x1 < (*ppClipRects)[j].x2 &&
+ (*ppClipRects)[j].y1 < (*ppClipRects)[j].y2) {
+ j++;
+ }
+ }
+
+ if (*numClipRects != j) {
+ *numClipRects = j;
+ *ppClipRects = xrealloc (*ppClipRects,
+ sizeof (drm_clip_rect_t) *
+ *numClipRects);
+ }
+ } else
+ *numClipRects = 0;
+ }
+ else {
+ *ppClipRects = NULL;
+ *numClipRects = 0;
+ }
+
+ if (retval && *numBackClipRects > 0) {
+ size = sizeof (drm_clip_rect_t) * *numBackClipRects;
+ *ppBackClipRects = xalloc (size);
+ if (*ppBackClipRects != NULL)
+ memcpy (*ppBackClipRects, pBackClipRects, size);
+ else
+ *numBackClipRects = 0;
+ }
+ else {
+ *ppBackClipRects = NULL;
+ *numBackClipRects = 0;
+ }
+
+ return retval;
+}
+
+static void __glXReportDamage(__DRIdrawable *driDraw,
+ int x, int y,
+ drm_clip_rect_t *rects, int num_rects,
+ GLboolean front_buffer,
+ void *data)
+{
+ __GLXDRIdrawable *drawable = data;
+ DrawablePtr pDraw = drawable->base.pDraw;
+ RegionRec region;
+
+ __glXenterServer(GL_FALSE);
+
+ REGION_INIT(pDraw->pScreen, ®ion, (BoxPtr) rects, num_rects);
+ REGION_TRANSLATE(pScreen, ®ion, pDraw->x, pDraw->y);
+ DamageRegionAppend(pDraw, ®ion);
+ /* This is wrong, this needs a seperate function. */
+ DamageRegionProcessPending(pDraw);
+ REGION_UNINIT(pDraw->pScreen, ®ion);
+
+ __glXleaveServer(GL_FALSE);
+}
+
+static const __DRIgetDrawableInfoExtension getDrawableInfoExtension = {
+ { __DRI_GET_DRAWABLE_INFO, __DRI_GET_DRAWABLE_INFO_VERSION },
+ getDrawableInfo
+};
+
+static const __DRIdamageExtension damageExtension = {
+ { __DRI_DAMAGE, __DRI_DAMAGE_VERSION },
+ __glXReportDamage,
+};
+
+static const __DRIextension *loader_extensions[] = {
+ &systemTimeExtension.base,
+ &getDrawableInfoExtension.base,
+ &damageExtension.base,
+ NULL
+};
+
+
+
+static const char dri_driver_path[] = DRI_DRIVER_PATH;
+
+static Bool
+glxDRIEnterVT (int index, int flags)
+{
+ __GLXDRIscreen *screen = (__GLXDRIscreen *)
+ glxGetScreen(screenInfo.screens[index]);
+
+ LogMessage(X_INFO, "AIGLX: Resuming AIGLX clients after VT switch\n");
+
+ if (!(*screen->enterVT) (index, flags))
+ return FALSE;
+
+ glxResumeClients();
+
+ return TRUE;
+}
+
+static void
+glxDRILeaveVT (int index, int flags)
+{
+ __GLXDRIscreen *screen = (__GLXDRIscreen *)
+ glxGetScreen(screenInfo.screens[index]);
+
+ LogMessage(X_INFO, "AIGLX: Suspending AIGLX clients for VT switch\n");
+
+ glxSuspendClients();
+
+ return (*screen->leaveVT) (index, flags);
+}
+
+static void
+initializeExtensions(__GLXDRIscreen *screen)
+{
+ const __DRIextension **extensions;
+ int i;
+
+ extensions = screen->core->getExtensions(screen->driScreen);
+
+ for (i = 0; extensions[i]; i++) {
+#ifdef __DRI_READ_DRAWABLE
+ if (strcmp(extensions[i]->name, __DRI_READ_DRAWABLE) == 0) {
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_SGI_make_current_read");
+
+ LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n");
+ }
+#endif
+
+#ifdef __DRI_COPY_SUB_BUFFER
+ if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
+ screen->copySubBuffer = (__DRIcopySubBufferExtension *) extensions[i];
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_MESA_copy_sub_buffer");
+
+ LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
+ }
+#endif
+
+#ifdef __DRI_SWAP_CONTROL
+ if (strcmp(extensions[i]->name, __DRI_SWAP_CONTROL) == 0) {
+ screen->swapControl = (__DRIswapControlExtension *) extensions[i];
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_SGI_swap_control");
+ __glXEnableExtension(screen->glx_enable_bits,
+ "GLX_MESA_swap_control");
+
+ LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
+ }
+#endif
+
+#ifdef __DRI_TEX_OFFSET
+ if (strcmp(extensions[i]->name, __DRI_TEX_OFFSET) == 0) {
+ screen->texOffset = (__DRItexOffsetExtension *) extensions[i];
+ LogMessage(X_INFO, "AIGLX: enabled GLX_texture_from_pixmap with driver support\n");
+ }
+#endif
+ /* Ignore unknown extensions */
+ }
+}
+
+extern __GLXconfig *
+glxConvertConfigs(const __DRIcoreExtension *core, const __DRIconfig **configs);
+
+static __GLXscreen *
+__glXDRIscreenProbe(ScreenPtr pScreen)
+{
+ drm_handle_t hSAREA;
+ drmAddress pSAREA = NULL;
+ char *BusID;
+ __DRIversion ddx_version;
+ __DRIversion dri_version;
+ __DRIversion drm_version;
+ __DRIframebuffer framebuffer;
+ int fd = -1;
+ int status;
+ drm_magic_t magic;
+ drmVersionPtr version;
+ int newlyopened;
+ char *driverName;
+ drm_handle_t hFB;
+ int junk;
+ __GLXDRIscreen *screen;
+ char filename[128];
+ Bool isCapable;
+ size_t buffer_size;
+ ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
+ const __DRIconfig **driConfigs;
+ const __DRIextension **extensions;
+ int i;
+
+ if (!xf86LoaderCheckSymbol("DRIQueryDirectRenderingCapable") ||
+ !DRIQueryDirectRenderingCapable(pScreen, &isCapable) ||
+ !isCapable) {
+ LogMessage(X_INFO,
+ "AIGLX: Screen %d is not DRI capable\n", pScreen->myNum);
+ return NULL;
+ }
+
+ screen = xcalloc(1, sizeof *screen);
+ if (screen == NULL)
+ return NULL;
+
+ screen->base.destroy = __glXDRIscreenDestroy;
+ screen->base.createContext = __glXDRIscreenCreateContext;
+ screen->base.createDrawable = __glXDRIscreenCreateDrawable;
+ screen->base.swapInterval = __glXDRIdrawableSwapInterval;
+ screen->base.pScreen = pScreen;
+
+ __glXInitExtensionEnableBits(screen->glx_enable_bits);
+
+ /* DRI protocol version. */
+ dri_version.major = XF86DRI_MAJOR_VERSION;
+ dri_version.minor = XF86DRI_MINOR_VERSION;
+ dri_version.patch = XF86DRI_PATCH_VERSION;
+
+ if (!DRIOpenConnection(pScreen, &hSAREA, &BusID)) {
+ LogMessage(X_ERROR, "AIGLX error: DRIOpenConnection failed\n");
+ goto handle_error;
+ }
+
+ fd = drmOpenOnce(NULL, BusID, &newlyopened);
+
+ if (fd < 0) {
+ LogMessage(X_ERROR, "AIGLX error: drmOpenOnce failed (%s)\n",
+ strerror(-fd));
+ goto handle_error;
+ }
+
+ if (drmGetMagic(fd, &magic)) {
+ LogMessage(X_ERROR, "AIGLX error: drmGetMagic failed\n");
+ goto handle_error;
+ }
+
+ version = drmGetVersion(fd);
+ if (version) {
+ drm_version.major = version->version_major;
+ drm_version.minor = version->version_minor;
+ drm_version.patch = version->version_patchlevel;
+ drmFreeVersion(version);
+ }
+ else {
+ drm_version.major = -1;
+ drm_version.minor = -1;
+ drm_version.patch = -1;
+ }
+
+ if (newlyopened && !DRIAuthConnection(pScreen, magic)) {
+ LogMessage(X_ERROR, "AIGLX error: DRIAuthConnection failed\n");
+ goto handle_error;
+ }
+
+ /* Get device name (like "tdfx") and the ddx version numbers.
+ * We'll check the version in each DRI driver's "createNewScreen"
+ * function. */
+ if (!DRIGetClientDriverName(pScreen,
+ &ddx_version.major,
+ &ddx_version.minor,
+ &ddx_version.patch,
+ &driverName)) {
+ LogMessage(X_ERROR, "AIGLX error: DRIGetClientDriverName failed\n");
+ goto handle_error;
+ }
+
+ snprintf(filename, sizeof filename, "%s/%s_dri.so",
+ dri_driver_path, driverName);
+
+ screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+ if (screen->driver == NULL) {
+ LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
+ filename, dlerror());
+ goto handle_error;
+ }
+
+ extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS);
+ if (extensions == NULL) {
+ LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
+ driverName, dlerror());
+ goto handle_error;
+ }
+
+ for (i = 0; extensions[i]; i++) {
+ if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
+ extensions[i]->version >= __DRI_CORE_VERSION) {
+ screen->core = (__DRIcoreExtension *) extensions[i];
+ }
+
+ if (strcmp(extensions[i]->name, __DRI_LEGACY) == 0 &&
+ extensions[i]->version >= __DRI_LEGACY_VERSION) {
+ screen->legacy = (__DRIlegacyExtension *) extensions[i];
+ }
+ }
+
+ if (screen->core == NULL || screen->legacy == NULL) {
+ LogMessage(X_ERROR,
+ "AIGLX error: %s does not export required DRI extension\n",
+ driverName);
+ goto handle_error;
+ }
+
+ /*
+ * Get device-specific info. pDevPriv will point to a struct
+ * (such as DRIRADEONRec in xfree86/driver/ati/radeon_dri.h) that
+ * has information about the screen size, depth, pitch, ancilliary
+ * buffers, DRM mmap handles, etc.
+ */
+ if (!DRIGetDeviceInfo(pScreen, &hFB, &junk,
+ &framebuffer.size, &framebuffer.stride,
+ &framebuffer.dev_priv_size, &framebuffer.dev_priv)) {
+ LogMessage(X_ERROR, "AIGLX error: XF86DRIGetDeviceInfo failed\n");
+ goto handle_error;
+ }
+
+ framebuffer.width = pScreen->width;
+ framebuffer.height = pScreen->height;
+
+ /* Map the framebuffer region. */
+ status = drmMap(fd, hFB, framebuffer.size,
+ (drmAddressPtr)&framebuffer.base);
+ if (status != 0) {
+ LogMessage(X_ERROR, "AIGLX error: drmMap of framebuffer failed (%s)\n",
+ strerror(-status));
+ goto handle_error;
+ }
+
+ /* Map the SAREA region. Further mmap regions may be setup in
+ * each DRI driver's "createNewScreen" function.
+ */
+ status = drmMap(fd, hSAREA, SAREA_MAX, &pSAREA);
+ if (status != 0) {
+ LogMessage(X_ERROR, "AIGLX error: drmMap of SAREA failed (%s)\n",
+ strerror(-status));
+ goto handle_error;
+ }
+
+ screen->driScreen =
+ (*screen->legacy->createNewScreen)(pScreen->myNum,
+ &ddx_version,
+ &dri_version,
+ &drm_version,
+ &framebuffer,
+ pSAREA,
+ fd,
+ loader_extensions,
+ &driConfigs,
+ screen);
+
+ if (screen->driScreen == NULL) {
+ LogMessage(X_ERROR,
+ "AIGLX error: Calling driver entry point failed\n");
+ goto handle_error;
+ }
+
+ screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs);
+
+ initializeExtensions(screen);
+
+ DRIGetTexOffsetFuncs(pScreen, &screen->texOffsetStart,
+ &screen->texOffsetFinish);
+
+ __glXScreenInit(&screen->base, pScreen);
+
+ /* The first call simply determines the length of the extension string.
+ * This allows us to allocate some memory to hold the extension string,
+ * but it requires that we call __glXGetExtensionString a second time.
+ */
+ buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
+ if (buffer_size > 0) {
+ if (screen->base.GLXextensions != NULL) {
+ xfree(screen->base.GLXextensions);
+ }
+
+ screen->base.GLXextensions = xnfalloc(buffer_size);
+ (void) __glXGetExtensionString(screen->glx_enable_bits,
+ screen->base.GLXextensions);
+ }
+
+ __glXsetEnterLeaveServerFuncs(__glXDRIenterServer, __glXDRIleaveServer);
+
+ screen->enterVT = pScrn->EnterVT;
+ pScrn->EnterVT = glxDRIEnterVT;
+ screen->leaveVT = pScrn->LeaveVT;
+ pScrn->LeaveVT = glxDRILeaveVT;
+
+ LogMessage(X_INFO,
+ "AIGLX: Loaded and initialized %s\n", filename);
+
+ return &screen->base;
+
+ handle_error:
+ if (pSAREA != NULL)
+ drmUnmap(pSAREA, SAREA_MAX);
+
+ if (framebuffer.base != NULL)
+ drmUnmap((drmAddress)framebuffer.base, framebuffer.size);
+
+ if (fd >= 0)
+ drmCloseOnce(fd);
+
+ DRICloseConnection(pScreen);
+
+ if (screen->driver)
+ dlclose(screen->driver);
+
+ xfree(screen);
+
+ LogMessage(X_ERROR, "AIGLX: reverting to software rendering\n");
+
+ return NULL;
+}
+
+_X_EXPORT __GLXprovider __glXDRIProvider = {
+ __glXDRIscreenProbe,
+ "DRI",
+ NULL
+};
diff --git a/xorg-server/glx/glxdricommon.c b/xorg-server/glx/glxdricommon.c index faaa3b7ae..028c77842 100644 --- a/xorg-server/glx/glxdricommon.c +++ b/xorg-server/glx/glxdricommon.c @@ -25,6 +25,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include <stdint.h> @@ -47,12 +51,16 @@ getUST(int64_t *ust) if (ust == NULL) return -EFAULT; +#ifdef _MSC_VER + __asm int 3; +#else if (gettimeofday(&tv, NULL) == 0) { ust[0] = (tv.tv_sec * 1000000) + tv.tv_usec; return 0; } else { return -errno; } + #endif } const __DRIsystemTimeExtension systemTimeExtension = { diff --git a/xorg-server/glx/glxdriswrast.c b/xorg-server/glx/glxdriswrast.c index c647d83ca..cf6c5ada9 100644 --- a/xorg-server/glx/glxdriswrast.c +++ b/xorg-server/glx/glxdriswrast.c @@ -1,536 +1,568 @@ -/* - * Copyright © 2008 George Sapountzis <gsap7@yahoo.gr> - * Copyright © 2008 Red Hat, 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 the - * copyright holders not be used in advertising or publicity - * pertaining to distribution of the software without specific, - * written prior permission. The copyright holders make 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. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <stdint.h> -#include <stdio.h> -#include <string.h> -#include <errno.h> -#include <sys/time.h> -#include <dlfcn.h> - -#include <GL/gl.h> -#include <GL/internal/dri_interface.h> -#include <GL/glxtokens.h> - -#include "scrnintstr.h" -#include "pixmapstr.h" -#include "gcstruct.h" -#include "os.h" - -#include "glxserver.h" -#include "glxutil.h" -#include "glxdricommon.h" - -#include "g_disptab.h" -#include "glapitable.h" -#include "glapi.h" -#include "glthread.h" -#include "dispatch.h" -#include "extension_string.h" - -/* RTLD_LOCAL is not defined on Cygwin */ -#ifdef __CYGWIN__ -#ifndef RTLD_LOCAL -#define RTLD_LOCAL 0 -#endif -#endif - -typedef struct __GLXDRIscreen __GLXDRIscreen; -typedef struct __GLXDRIcontext __GLXDRIcontext; -typedef struct __GLXDRIdrawable __GLXDRIdrawable; - -struct __GLXDRIscreen { - __GLXscreen base; - __DRIscreen *driScreen; - void *driver; - - const __DRIcoreExtension *core; - const __DRIswrastExtension *swrast; - const __DRIcopySubBufferExtension *copySubBuffer; - const __DRItexBufferExtension *texBuffer; -}; - -struct __GLXDRIcontext { - __GLXcontext base; - __DRIcontext *driContext; -}; - -struct __GLXDRIdrawable { - __GLXdrawable base; - __DRIdrawable *driDrawable; - __GLXDRIscreen *screen; - - GCPtr gc; /* scratch GC for span drawing */ - GCPtr swapgc; /* GC for swapping the color buffers */ -}; - -static void -__glXDRIdrawableDestroy(__GLXdrawable *drawable) -{ - __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; - const __DRIcoreExtension *core = private->screen->core; - - (*core->destroyDrawable)(private->driDrawable); - - FreeScratchGC(private->gc); - FreeScratchGC(private->swapgc); - - __glXDrawableRelease(drawable); - - xfree(private); -} - -static GLboolean -__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable) -{ - __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable; - const __DRIcoreExtension *core = private->screen->core; - - (*core->swapBuffers)(private->driDrawable); - - return TRUE; -} - -static void -__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate, - int x, int y, int w, int h) -{ - __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate; - const __DRIcopySubBufferExtension *copySubBuffer = - private->screen->copySubBuffer; - - if (copySubBuffer) - (*copySubBuffer->copySubBuffer)(private->driDrawable, x, y, w, h); -} - -static void -__glXDRIcontextDestroy(__GLXcontext *baseContext) -{ - __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; - __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - - (*screen->core->destroyContext)(context->driContext); - __glXContextDestroy(&context->base); - xfree(context); -} - -static int -__glXDRIcontextMakeCurrent(__GLXcontext *baseContext) -{ - __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; - __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; - __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; - __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - - return (*screen->core->bindContext)(context->driContext, - draw->driDrawable, - read->driDrawable); -} - -static int -__glXDRIcontextLoseCurrent(__GLXcontext *baseContext) -{ - __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; - __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - - return (*screen->core->unbindContext)(context->driContext); -} - -static int -__glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc, - unsigned long mask) -{ - __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst; - __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc; - __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen; - - return (*screen->core->copyContext)(dst->driContext, - src->driContext, mask); -} - -static int -__glXDRIcontextForceCurrent(__GLXcontext *baseContext) -{ - __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; - __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv; - __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv; - __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen; - - return (*screen->core->bindContext)(context->driContext, - draw->driDrawable, - read->driDrawable); -} - -#ifdef __DRI_TEX_BUFFER - -static int -__glXDRIbindTexImage(__GLXcontext *baseContext, - int buffer, - __GLXdrawable *glxPixmap) -{ - __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap; - const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer; - __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext; - - if (texBuffer == NULL) - return Success; - - texBuffer->setTexBuffer(context->driContext, - glxPixmap->target, - drawable->driDrawable); - - return Success; -} - -static int -__glXDRIreleaseTexImage(__GLXcontext *baseContext, - int buffer, - __GLXdrawable *pixmap) -{ - /* FIXME: Just unbind the texture? */ - return Success; -} - -#else - -static int -__glXDRIbindTexImage(__GLXcontext *baseContext, - int buffer, - __GLXdrawable *glxPixmap) -{ - return Success; -} - -static int -__glXDRIreleaseTexImage(__GLXcontext *baseContext, - int buffer, - __GLXdrawable *pixmap) -{ - return Success; -} - -#endif - -static __GLXtextureFromPixmap __glXDRItextureFromPixmap = { - __glXDRIbindTexImage, - __glXDRIreleaseTexImage -}; - -static void -__glXDRIscreenDestroy(__GLXscreen *baseScreen) -{ - __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; - - (*screen->core->destroyScreen)(screen->driScreen); - - dlclose(screen->driver); - - __glXScreenDestroy(baseScreen); - - xfree(screen); -} - -static __GLXcontext * -__glXDRIscreenCreateContext(__GLXscreen *baseScreen, - __GLXconfig *glxConfig, - __GLXcontext *baseShareContext) -{ - __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen; - __GLXDRIcontext *context, *shareContext; - __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; - const __DRIcoreExtension *core = screen->core; - __DRIcontext *driShare; - - shareContext = (__GLXDRIcontext *) baseShareContext; - if (shareContext) - driShare = shareContext->driContext; - else - driShare = NULL; - - context = xcalloc(1, sizeof *context); - if (context == NULL) - return NULL; - - context->base.destroy = __glXDRIcontextDestroy; - context->base.makeCurrent = __glXDRIcontextMakeCurrent; - context->base.loseCurrent = __glXDRIcontextLoseCurrent; - context->base.copy = __glXDRIcontextCopy; - context->base.forceCurrent = __glXDRIcontextForceCurrent; - context->base.textureFromPixmap = &__glXDRItextureFromPixmap; - - context->driContext = - (*core->createNewContext)(screen->driScreen, - config->driConfig, driShare, context); - - return &context->base; -} - -static void -glxChangeGC(GCPtr gc, BITS32 mask, CARD32 val) -{ - CARD32 v[1]; - v[0] = val; - dixChangeGC(NullClient, gc, mask, v, NULL); -} - -static __GLXdrawable * -__glXDRIscreenCreateDrawable(__GLXscreen *screen, - DrawablePtr pDraw, - int type, - XID drawId, - __GLXconfig *glxConfig) -{ - __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen; - __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig; - __GLXDRIdrawable *private; - - ScreenPtr pScreen = driScreen->base.pScreen; - - private = xcalloc(1, sizeof *private); - if (private == NULL) - return NULL; - - private->screen = driScreen; - if (!__glXDrawableInit(&private->base, screen, - pDraw, type, drawId, glxConfig)) { - xfree(private); - return NULL; - } - - private->base.destroy = __glXDRIdrawableDestroy; - private->base.swapBuffers = __glXDRIdrawableSwapBuffers; - private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer; - - private->gc = CreateScratchGC(pScreen, pDraw->depth); - private->swapgc = CreateScratchGC(pScreen, pDraw->depth); - - glxChangeGC(private->gc, GCFunction, GXcopy); - glxChangeGC(private->swapgc, GCFunction, GXcopy); - glxChangeGC(private->swapgc, GCGraphicsExposures, FALSE); - - private->driDrawable = - (*driScreen->swrast->createNewDrawable)(driScreen->driScreen, - config->driConfig, - private); - - return &private->base; -} - -static void -swrastGetDrawableInfo(__DRIdrawable *draw, - int *x, int *y, int *w, int *h, - void *loaderPrivate) -{ - __GLXDRIdrawable *drawable = loaderPrivate; - DrawablePtr pDraw = drawable->base.pDraw; - - *x = pDraw->x; - *y = pDraw->x; - *w = pDraw->width; - *h = pDraw->height; -} - -static void -swrastPutImage(__DRIdrawable *draw, int op, - int x, int y, int w, int h, char *data, - void *loaderPrivate) -{ - __GLXDRIdrawable *drawable = loaderPrivate; - DrawablePtr pDraw = drawable->base.pDraw; - GCPtr gc; - - switch (op) { - case __DRI_SWRAST_IMAGE_OP_DRAW: - gc = drawable->gc; - break; - case __DRI_SWRAST_IMAGE_OP_SWAP: - gc = drawable->swapgc; - break; - default: - return; - } - - ValidateGC(pDraw, gc); - - gc->ops->PutImage(pDraw, gc, pDraw->depth, - x, y, w, h, 0, ZPixmap, data); -} - -static void -swrastGetImage(__DRIdrawable *draw, - int x, int y, int w, int h, char *data, - void *loaderPrivate) -{ - __GLXDRIdrawable *drawable = loaderPrivate; - DrawablePtr pDraw = drawable->base.pDraw; - ScreenPtr pScreen = pDraw->pScreen; - - pScreen->GetImage(pDraw, x, y, w, h, ZPixmap, ~0L, data); -} - -static const __DRIswrastLoaderExtension swrastLoaderExtension = { - { __DRI_SWRAST_LOADER, __DRI_SWRAST_LOADER_VERSION }, - swrastGetDrawableInfo, - swrastPutImage, - swrastGetImage -}; - -static const __DRIextension *loader_extensions[] = { - &systemTimeExtension.base, - &swrastLoaderExtension.base, - NULL -}; - -static void -initializeExtensions(__GLXDRIscreen *screen) -{ - const __DRIextension **extensions; - int i; - - extensions = screen->core->getExtensions(screen->driScreen); - - for (i = 0; extensions[i]; i++) { -#ifdef __DRI_COPY_SUB_BUFFER - if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) { - screen->copySubBuffer = - (const __DRIcopySubBufferExtension *) extensions[i]; - /* GLX_MESA_copy_sub_buffer is always enabled. */ - } -#endif - -#ifdef __DRI_TEX_BUFFER - if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) { - screen->texBuffer = - (const __DRItexBufferExtension *) extensions[i]; - /* GLX_EXT_texture_from_pixmap is always enabled. */ - } -#endif - /* Ignore unknown extensions */ - } -} - -static const char dri_driver_path[] = DRI_DRIVER_PATH; - -static __GLXscreen * -__glXDRIscreenProbe(ScreenPtr pScreen) -{ - const char *driverName = "swrast"; - __GLXDRIscreen *screen; - char filename[128]; - const __DRIextension **extensions; - const __DRIconfig **driConfigs; - int i; - - screen = xcalloc(1, sizeof *screen); - if (screen == NULL) - return NULL; - - screen->base.destroy = __glXDRIscreenDestroy; - screen->base.createContext = __glXDRIscreenCreateContext; - screen->base.createDrawable = __glXDRIscreenCreateDrawable; - screen->base.swapInterval = NULL; - screen->base.pScreen = pScreen; - - snprintf(filename, sizeof filename, - "%s/%s_dri.so", dri_driver_path, driverName); - - screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL); - if (screen->driver == NULL) { - LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n", - filename, dlerror()); - goto handle_error; - } - - extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS); - if (extensions == NULL) { - LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n", - driverName, dlerror()); - goto handle_error; - } - - for (i = 0; extensions[i]; i++) { - if (strcmp(extensions[i]->name, __DRI_CORE) == 0 && - extensions[i]->version >= __DRI_CORE_VERSION) { - screen->core = (const __DRIcoreExtension *) extensions[i]; - } - if (strcmp(extensions[i]->name, __DRI_SWRAST) == 0 && - extensions[i]->version >= __DRI_SWRAST_VERSION) { - screen->swrast = (const __DRIswrastExtension *) extensions[i]; - } - } - - if (screen->core == NULL || screen->swrast == NULL) { - LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n", - driverName); - goto handle_error; - } - - screen->driScreen = - (*screen->swrast->createNewScreen)(pScreen->myNum, - loader_extensions, - &driConfigs, - screen); - - if (screen->driScreen == NULL) { - LogMessage(X_ERROR, - "AIGLX error: Calling driver entry point failed\n"); - goto handle_error; - } - - initializeExtensions(screen); - - screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs); - - __glXScreenInit(&screen->base, pScreen); - - screen->base.GLXmajor = 1; - screen->base.GLXminor = 4; - - LogMessage(X_INFO, - "AIGLX: Loaded and initialized %s\n", filename); - - return &screen->base; - - handle_error: - if (screen->driver) - dlclose(screen->driver); - - xfree(screen); - - LogMessage(X_ERROR, "GLX: could not load software renderer\n"); - - return NULL; -} - -_X_EXPORT __GLXprovider __glXDRISWRastProvider = { - __glXDRIscreenProbe, - "DRISWRAST", - NULL -}; +/*
+ * Copyright © 2008 George Sapountzis <gsap7@yahoo.gr>
+ * Copyright © 2008 Red Hat, 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 the
+ * copyright holders not be used in advertising or publicity
+ * pertaining to distribution of the software without specific,
+ * written prior permission. The copyright holders make 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.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#else
+
+#include "glheader.h"
+
+#endif
+
+#include <stdint.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/time.h>
+#include <dlfcn.h>
+
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
+#include <GL/glxtokens.h>
+
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "gcstruct.h"
+#include "os.h"
+
+#include "glxserver.h"
+#include "glxutil.h"
+#include "glxdricommon.h"
+
+#include "g_disptab.h"
+#include "glapitable.h"
+#include "glapi.h"
+#include "glthread.h"
+#include "dispatch.h"
+#include "extension_string.h"
+
+/* RTLD_LOCAL is not defined on Cygwin */
+#ifdef __CYGWIN__
+#ifndef RTLD_LOCAL
+#define RTLD_LOCAL 0
+#endif
+#endif
+
+#ifdef _MSC_VER
+#define dlerror() "Getting loadlibrary error string not implemented"
+#endif
+
+typedef struct __GLXDRIscreen __GLXDRIscreen;
+typedef struct __GLXDRIcontext __GLXDRIcontext;
+typedef struct __GLXDRIdrawable __GLXDRIdrawable;
+
+struct __GLXDRIscreen {
+ __GLXscreen base;
+ __DRIscreen *driScreen;
+ void *driver;
+
+ const __DRIcoreExtension *core;
+ const __DRIswrastExtension *swrast;
+ const __DRIcopySubBufferExtension *copySubBuffer;
+ const __DRItexBufferExtension *texBuffer;
+};
+
+struct __GLXDRIcontext {
+ __GLXcontext base;
+ __DRIcontext *driContext;
+};
+
+struct __GLXDRIdrawable {
+ __GLXdrawable base;
+ __DRIdrawable *driDrawable;
+ __GLXDRIscreen *screen;
+
+ GCPtr gc; /* scratch GC for span drawing */
+ GCPtr swapgc; /* GC for swapping the color buffers */
+};
+
+static void
+__glXDRIdrawableDestroy(__GLXdrawable *drawable)
+{
+ __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+ const __DRIcoreExtension *core = private->screen->core;
+
+ (*core->destroyDrawable)(private->driDrawable);
+
+ FreeScratchGC(private->gc);
+ FreeScratchGC(private->swapgc);
+
+ __glXDrawableRelease(drawable);
+
+ xfree(private);
+}
+
+static GLboolean
+__glXDRIdrawableSwapBuffers(ClientPtr client, __GLXdrawable *drawable)
+{
+ __GLXDRIdrawable *private = (__GLXDRIdrawable *) drawable;
+ const __DRIcoreExtension *core = private->screen->core;
+
+ (*core->swapBuffers)(private->driDrawable);
+
+ return TRUE;
+}
+
+static void
+__glXDRIdrawableCopySubBuffer(__GLXdrawable *basePrivate,
+ int x, int y, int w, int h)
+{
+ __GLXDRIdrawable *private = (__GLXDRIdrawable *) basePrivate;
+ const __DRIcopySubBufferExtension *copySubBuffer =
+ private->screen->copySubBuffer;
+
+ if (copySubBuffer)
+ (*copySubBuffer->copySubBuffer)(private->driDrawable, x, y, w, h);
+}
+
+static void
+__glXDRIcontextDestroy(__GLXcontext *baseContext)
+{
+ __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
+
+ (*screen->core->destroyContext)(context->driContext);
+ __glXContextDestroy(&context->base);
+ xfree(context);
+}
+
+static int
+__glXDRIcontextMakeCurrent(__GLXcontext *baseContext)
+{
+ __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+ __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
+ __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
+
+ return (*screen->core->bindContext)(context->driContext,
+ draw->driDrawable,
+ read->driDrawable);
+}
+
+static int
+__glXDRIcontextLoseCurrent(__GLXcontext *baseContext)
+{
+ __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
+
+ return (*screen->core->unbindContext)(context->driContext);
+}
+
+static int
+__glXDRIcontextCopy(__GLXcontext *baseDst, __GLXcontext *baseSrc,
+ unsigned long mask)
+{
+ __GLXDRIcontext *dst = (__GLXDRIcontext *) baseDst;
+ __GLXDRIcontext *src = (__GLXDRIcontext *) baseSrc;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) dst->base.pGlxScreen;
+
+ return (*screen->core->copyContext)(dst->driContext,
+ src->driContext, mask);
+}
+
+static int
+__glXDRIcontextForceCurrent(__GLXcontext *baseContext)
+{
+ __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+ __GLXDRIdrawable *draw = (__GLXDRIdrawable *) baseContext->drawPriv;
+ __GLXDRIdrawable *read = (__GLXDRIdrawable *) baseContext->readPriv;
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) context->base.pGlxScreen;
+
+ return (*screen->core->bindContext)(context->driContext,
+ draw->driDrawable,
+ read->driDrawable);
+}
+
+#ifdef __DRI_TEX_BUFFER
+
+static int
+__glXDRIbindTexImage(__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *glxPixmap)
+{
+ __GLXDRIdrawable *drawable = (__GLXDRIdrawable *) glxPixmap;
+ const __DRItexBufferExtension *texBuffer = drawable->screen->texBuffer;
+ __GLXDRIcontext *context = (__GLXDRIcontext *) baseContext;
+
+ if (texBuffer == NULL)
+ return Success;
+
+ texBuffer->setTexBuffer(context->driContext,
+ glxPixmap->target,
+ drawable->driDrawable);
+
+ return Success;
+}
+
+static int
+__glXDRIreleaseTexImage(__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *pixmap)
+{
+ /* FIXME: Just unbind the texture? */
+ return Success;
+}
+
+#else
+
+static int
+__glXDRIbindTexImage(__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *glxPixmap)
+{
+ return Success;
+}
+
+static int
+__glXDRIreleaseTexImage(__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *pixmap)
+{
+ return Success;
+}
+
+#endif
+
+static __GLXtextureFromPixmap __glXDRItextureFromPixmap = {
+ __glXDRIbindTexImage,
+ __glXDRIreleaseTexImage
+};
+
+static void
+__glXDRIscreenDestroy(__GLXscreen *baseScreen)
+{
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
+
+ (*screen->core->destroyScreen)(screen->driScreen);
+
+#ifdef _MSC_VER
+ FreeLibrary(screen->driver);
+#else
+ dlclose(screen->driver);
+#endif
+
+ __glXScreenDestroy(baseScreen);
+
+ xfree(screen);
+}
+
+static __GLXcontext *
+__glXDRIscreenCreateContext(__GLXscreen *baseScreen,
+ __GLXconfig *glxConfig,
+ __GLXcontext *baseShareContext)
+{
+ __GLXDRIscreen *screen = (__GLXDRIscreen *) baseScreen;
+ __GLXDRIcontext *context, *shareContext;
+ __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
+ const __DRIcoreExtension *core = screen->core;
+ __DRIcontext *driShare;
+
+ shareContext = (__GLXDRIcontext *) baseShareContext;
+ if (shareContext)
+ driShare = shareContext->driContext;
+ else
+ driShare = NULL;
+
+ context = xcalloc(1, sizeof *context);
+ if (context == NULL)
+ return NULL;
+
+ context->base.destroy = __glXDRIcontextDestroy;
+ context->base.makeCurrent = __glXDRIcontextMakeCurrent;
+ context->base.loseCurrent = __glXDRIcontextLoseCurrent;
+ context->base.copy = __glXDRIcontextCopy;
+ context->base.forceCurrent = __glXDRIcontextForceCurrent;
+ context->base.textureFromPixmap = &__glXDRItextureFromPixmap;
+
+ context->driContext =
+ (*core->createNewContext)(screen->driScreen,
+ config->driConfig, driShare, context);
+
+ return &context->base;
+}
+
+static void
+glxChangeGC(GCPtr gc, BITS32 mask, CARD32 val)
+{
+ CARD32 v[1];
+ v[0] = val;
+ dixChangeGC(NullClient, gc, mask, v, NULL);
+}
+
+static __GLXdrawable *
+__glXDRIscreenCreateDrawable(__GLXscreen *screen,
+ DrawablePtr pDraw,
+ int type,
+ XID drawId,
+ __GLXconfig *glxConfig)
+{
+ __GLXDRIscreen *driScreen = (__GLXDRIscreen *) screen;
+ __GLXDRIconfig *config = (__GLXDRIconfig *) glxConfig;
+ __GLXDRIdrawable *private;
+
+ ScreenPtr pScreen = driScreen->base.pScreen;
+
+ private = xcalloc(1, sizeof *private);
+ if (private == NULL)
+ return NULL;
+
+ private->screen = driScreen;
+ if (!__glXDrawableInit(&private->base, screen,
+ pDraw, type, drawId, glxConfig)) {
+ xfree(private);
+ return NULL;
+ }
+
+ private->base.destroy = __glXDRIdrawableDestroy;
+ private->base.swapBuffers = __glXDRIdrawableSwapBuffers;
+ private->base.copySubBuffer = __glXDRIdrawableCopySubBuffer;
+
+ private->gc = CreateScratchGC(pScreen, pDraw->depth);
+ private->swapgc = CreateScratchGC(pScreen, pDraw->depth);
+
+ glxChangeGC(private->gc, GCFunction, GXcopy);
+ glxChangeGC(private->swapgc, GCFunction, GXcopy);
+ glxChangeGC(private->swapgc, GCGraphicsExposures, FALSE);
+
+ private->driDrawable =
+ (*driScreen->swrast->createNewDrawable)(driScreen->driScreen,
+ config->driConfig,
+ private);
+
+ return &private->base;
+}
+
+static void
+swrastGetDrawableInfo(__DRIdrawable *draw,
+ int *x, int *y, int *w, int *h,
+ void *loaderPrivate)
+{
+ __GLXDRIdrawable *drawable = loaderPrivate;
+ DrawablePtr pDraw = drawable->base.pDraw;
+
+ *x = pDraw->x;
+ *y = pDraw->x;
+ *w = pDraw->width;
+ *h = pDraw->height;
+}
+
+static void
+swrastPutImage(__DRIdrawable *draw, int op,
+ int x, int y, int w, int h, char *data,
+ void *loaderPrivate)
+{
+ __GLXDRIdrawable *drawable = loaderPrivate;
+ DrawablePtr pDraw = drawable->base.pDraw;
+ GCPtr gc;
+
+ switch (op) {
+ case __DRI_SWRAST_IMAGE_OP_DRAW:
+ gc = drawable->gc;
+ break;
+ case __DRI_SWRAST_IMAGE_OP_SWAP:
+ gc = drawable->swapgc;
+ break;
+ default:
+ return;
+ }
+
+ ValidateGC(pDraw, gc);
+
+ gc->ops->PutImage(pDraw, gc, pDraw->depth,
+ x, y, w, h, 0, ZPixmap, data);
+}
+
+static void
+swrastGetImage(__DRIdrawable *draw,
+ int x, int y, int w, int h, char *data,
+ void *loaderPrivate)
+{
+ __GLXDRIdrawable *drawable = loaderPrivate;
+ DrawablePtr pDraw = drawable->base.pDraw;
+ ScreenPtr pScreen = pDraw->pScreen;
+
+ pScreen->GetImage(pDraw, x, y, w, h, ZPixmap, ~0L, data);
+}
+
+static const __DRIswrastLoaderExtension swrastLoaderExtension = {
+ { __DRI_SWRAST_LOADER, __DRI_SWRAST_LOADER_VERSION },
+ swrastGetDrawableInfo,
+ swrastPutImage,
+ swrastGetImage
+};
+
+static const __DRIextension *loader_extensions[] = {
+ &systemTimeExtension.base,
+ &swrastLoaderExtension.base,
+ NULL
+};
+
+static void
+initializeExtensions(__GLXDRIscreen *screen)
+{
+ const __DRIextension **extensions;
+ int i;
+
+ extensions = screen->core->getExtensions(screen->driScreen);
+
+ for (i = 0; extensions[i]; i++) {
+#ifdef __DRI_COPY_SUB_BUFFER
+ if (strcmp(extensions[i]->name, __DRI_COPY_SUB_BUFFER) == 0) {
+ screen->copySubBuffer =
+ (const __DRIcopySubBufferExtension *) extensions[i];
+ /* GLX_MESA_copy_sub_buffer is always enabled. */
+ }
+#endif
+
+#ifdef __DRI_TEX_BUFFER
+ if (strcmp(extensions[i]->name, __DRI_TEX_BUFFER) == 0) {
+ screen->texBuffer =
+ (const __DRItexBufferExtension *) extensions[i];
+ /* GLX_EXT_texture_from_pixmap is always enabled. */
+ }
+#endif
+ /* Ignore unknown extensions */
+ }
+}
+
+static const char dri_driver_path[] = DRI_DRIVER_PATH;
+
+static __GLXscreen *
+__glXDRIscreenProbe(ScreenPtr pScreen)
+{
+ const char *driverName = "swrast";
+ __GLXDRIscreen *screen;
+ char filename[128];
+ const __DRIextension **extensions;
+ const __DRIconfig **driConfigs;
+ int i;
+
+ screen = xcalloc(1, sizeof *screen);
+ if (screen == NULL)
+ return NULL;
+
+ screen->base.destroy = __glXDRIscreenDestroy;
+ screen->base.createContext = __glXDRIscreenCreateContext;
+ screen->base.createDrawable = __glXDRIscreenCreateDrawable;
+ screen->base.swapInterval = NULL;
+ screen->base.pScreen = pScreen;
+
+#ifdef _MSC_VER
+#ifdef _DEBUG
+#define DLLNAME "%s%s_dri_dbg.dll"
+#else
+#define DLLNAME "%s%s_dri.dll"
+#endif
+ snprintf(filename, sizeof filename,
+ DLLNAME, dri_driver_path, driverName);
+
+ screen->driver = LoadLibrary(filename);
+#else
+ snprintf(filename, sizeof filename,
+ "%s/%s_dri.so", dri_driver_path, driverName);
+
+ screen->driver = dlopen(filename, RTLD_LAZY | RTLD_LOCAL);
+#endif
+ if (screen->driver == NULL) {
+ LogMessage(X_ERROR, "AIGLX error: dlopen of %s failed (%s)\n",
+ filename, dlerror());
+ goto handle_error;
+ }
+
+#ifdef _MSC_VER
+ extensions = (const __DRIextension **)GetProcAddress(screen->driver, __DRI_DRIVER_EXTENSIONS);
+#else
+ extensions = dlsym(screen->driver, __DRI_DRIVER_EXTENSIONS);
+#endif
+ if (extensions == NULL) {
+ LogMessage(X_ERROR, "AIGLX error: %s exports no extensions (%s)\n",
+ driverName, dlerror());
+ goto handle_error;
+ }
+
+ for (i = 0; extensions[i]; i++) {
+ if (strcmp(extensions[i]->name, __DRI_CORE) == 0 &&
+ extensions[i]->version >= __DRI_CORE_VERSION) {
+ screen->core = (const __DRIcoreExtension *) extensions[i];
+ }
+ if (strcmp(extensions[i]->name, __DRI_SWRAST) == 0 &&
+ extensions[i]->version >= __DRI_SWRAST_VERSION) {
+ screen->swrast = (const __DRIswrastExtension *) extensions[i];
+ }
+ }
+
+ if (screen->core == NULL || screen->swrast == NULL) {
+ LogMessage(X_ERROR, "AIGLX error: %s exports no DRI extension\n",
+ driverName);
+ goto handle_error;
+ }
+
+ screen->driScreen =
+ (*screen->swrast->createNewScreen)(pScreen->myNum,
+ loader_extensions,
+ &driConfigs,
+ screen);
+
+ if (screen->driScreen == NULL) {
+ LogMessage(X_ERROR,
+ "AIGLX error: Calling driver entry point failed\n");
+ goto handle_error;
+ }
+
+ initializeExtensions(screen);
+
+ screen->base.fbconfigs = glxConvertConfigs(screen->core, driConfigs);
+
+ __glXScreenInit(&screen->base, pScreen);
+
+ screen->base.GLXmajor = 1;
+ screen->base.GLXminor = 4;
+
+ LogMessage(X_INFO,
+ "AIGLX: Loaded and initialized %s\n", filename);
+
+ return &screen->base;
+
+ handle_error:
+ if (screen->driver)
+#ifdef _MSC_VER
+ FreeLibrary(screen->driver);
+#else
+ dlclose(screen->driver);
+#endif
+
+ xfree(screen);
+
+ LogMessage(X_ERROR, "GLX: could not load software renderer\n");
+
+ return NULL;
+}
+
+_X_EXPORT __GLXprovider __glXDRISWRastProvider = {
+ __glXDRIscreenProbe,
+ "DRISWRAST",
+ NULL
+};
diff --git a/xorg-server/glx/glxext.c b/xorg-server/glx/glxext.c index 59bcfbed2..c1fedf3b9 100644 --- a/xorg-server/glx/glxext.c +++ b/xorg-server/glx/glxext.c @@ -30,6 +30,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include <string.h> @@ -125,8 +129,10 @@ static int glxBlockClients; static Bool DrawableGone(__GLXdrawable *glxPriv, XID xid) { __GLXcontext *c; + __GLXcontext *cnext; - for (c = glxAllContexts; c; c = c->next) { + for (c = glxAllContexts; c; c = cnext) { + cnext=c->next; /* Safe because c is going to be freed */ if (c->isCurrent && (c->drawPriv == glxPriv || c->readPriv == glxPriv)) { int i; diff --git a/xorg-server/glx/glxscreens.c b/xorg-server/glx/glxscreens.c index 58d8ee0b4..b2d1f8741 100644 --- a/xorg-server/glx/glxscreens.c +++ b/xorg-server/glx/glxscreens.c @@ -1,470 +1,474 @@ -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * 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 - * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <GL/glxtokens.h> -#include <string.h> -#include <windowstr.h> -#include <os.h> -#include <colormapst.h> - -#include "privates.h" -#include "glxserver.h" -#include "glxutil.h" -#include "glxext.h" -#include "protocol-versions.h" - -static int glxScreenPrivateKeyIndex; -static DevPrivateKey glxScreenPrivateKey = &glxScreenPrivateKeyIndex; - -const char GLServerVersion[] = "1.4"; -static const char GLServerExtensions[] = - "GL_ARB_depth_texture " - "GL_ARB_draw_buffers " - "GL_ARB_fragment_program " - "GL_ARB_fragment_program_shadow " - "GL_ARB_imaging " - "GL_ARB_multisample " - "GL_ARB_multitexture " - "GL_ARB_occlusion_query " - "GL_ARB_point_parameters " - "GL_ARB_point_sprite " - "GL_ARB_shadow " - "GL_ARB_shadow_ambient " - "GL_ARB_texture_border_clamp " - "GL_ARB_texture_compression " - "GL_ARB_texture_cube_map " - "GL_ARB_texture_env_add " - "GL_ARB_texture_env_combine " - "GL_ARB_texture_env_crossbar " - "GL_ARB_texture_env_dot3 " - "GL_ARB_texture_mirrored_repeat " - "GL_ARB_texture_non_power_of_two " - "GL_ARB_transpose_matrix " - "GL_ARB_vertex_program " - "GL_ARB_window_pos " - "GL_EXT_abgr " - "GL_EXT_bgra " - "GL_EXT_blend_color " - "GL_EXT_blend_equation_separate " - "GL_EXT_blend_func_separate " - "GL_EXT_blend_logic_op " - "GL_EXT_blend_minmax " - "GL_EXT_blend_subtract " - "GL_EXT_clip_volume_hint " - "GL_EXT_copy_texture " - "GL_EXT_draw_range_elements " - "GL_EXT_fog_coord " - "GL_EXT_framebuffer_object " - "GL_EXT_multi_draw_arrays " - "GL_EXT_packed_pixels " - "GL_EXT_paletted_texture " - "GL_EXT_point_parameters " - "GL_EXT_polygon_offset " - "GL_EXT_rescale_normal " - "GL_EXT_secondary_color " - "GL_EXT_separate_specular_color " - "GL_EXT_shadow_funcs " - "GL_EXT_shared_texture_palette " - "GL_EXT_stencil_two_side " - "GL_EXT_stencil_wrap " - "GL_EXT_subtexture " - "GL_EXT_texture " - "GL_EXT_texture3D " - "GL_EXT_texture_compression_dxt1 " - "GL_EXT_texture_compression_s3tc " - "GL_EXT_texture_edge_clamp " - "GL_EXT_texture_env_add " - "GL_EXT_texture_env_combine " - "GL_EXT_texture_env_dot3 " - "GL_EXT_texture_filter_anisotropic " - "GL_EXT_texture_lod " - "GL_EXT_texture_lod_bias " - "GL_EXT_texture_mirror_clamp " - "GL_EXT_texture_object " - "GL_EXT_texture_rectangle " - "GL_EXT_vertex_array " - "GL_3DFX_texture_compression_FXT1 " - "GL_APPLE_packed_pixels " - "GL_ATI_draw_buffers " - "GL_ATI_texture_env_combine3 " - "GL_ATI_texture_mirror_once " - "GL_HP_occlusion_test " - "GL_IBM_texture_mirrored_repeat " - "GL_INGR_blend_func_separate " - "GL_MESA_pack_invert " - "GL_MESA_ycbcr_texture " - "GL_NV_blend_square " - "GL_NV_depth_clamp " - "GL_NV_fog_distance " - "GL_NV_fragment_program " - "GL_NV_fragment_program_option " - "GL_NV_fragment_program2 " - "GL_NV_light_max_exponent " - "GL_NV_multisample_filter_hint " - "GL_NV_point_sprite " - "GL_NV_texgen_reflection " - "GL_NV_texture_compression_vtc " - "GL_NV_texture_env_combine4 " - "GL_NV_texture_expand_normal " - "GL_NV_texture_rectangle " - "GL_NV_vertex_program " - "GL_NV_vertex_program1_1 " - "GL_NV_vertex_program2 " - "GL_NV_vertex_program2_option " - "GL_NV_vertex_program3 " - "GL_OES_compressed_paletted_texture " - "GL_SGI_color_matrix " - "GL_SGI_color_table " - "GL_SGIS_generate_mipmap " - "GL_SGIS_multisample " - "GL_SGIS_point_parameters " - "GL_SGIS_texture_border_clamp " - "GL_SGIS_texture_edge_clamp " - "GL_SGIS_texture_lod " - "GL_SGIX_depth_texture " - "GL_SGIX_shadow " - "GL_SGIX_shadow_ambient " - "GL_SUN_slice_accum " - ; - -/* -** We have made the simplifying assuption that the same extensions are -** supported across all screens in a multi-screen system. -*/ -static char GLXServerVendorName[] = "SGI"; -unsigned glxMajorVersion = SERVER_GLX_MAJOR_VERSION; -unsigned glxMinorVersion = SERVER_GLX_MINOR_VERSION; -static char GLXServerExtensions[] = - "GLX_ARB_multisample " - "GLX_EXT_visual_info " - "GLX_EXT_visual_rating " - "GLX_EXT_import_context " - "GLX_EXT_texture_from_pixmap " - "GLX_OML_swap_method " - "GLX_SGI_make_current_read " -#ifndef __APPLE__ - "GLX_SGIS_multisample " - "GLX_SGIX_hyperpipe " - "GLX_SGIX_swap_barrier " -#endif - "GLX_SGIX_fbconfig " - "GLX_SGIX_pbuffer " - "GLX_MESA_copy_sub_buffer " - "GLX_INTEL_swap_event" - ; - -/* - * If your DDX driver wants to register support for swap barriers or hyperpipe - * topology, it should call __glXHyperpipeInit() or __glXSwapBarrierInit() - * with a dispatch table of functions to handle the requests. In the XFree86 - * DDX, for example, you would call these near the bottom of the driver's - * ScreenInit method, after DRI has been initialized. - * - * This should be replaced with a better method when we teach the server how - * to load DRI drivers. - */ - -void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs) -{ - __GLXscreen *pGlxScreen = glxGetScreen(screenInfo.screens[screen]); - - pGlxScreen->hyperpipeFuncs = funcs; -} - -void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs) -{ - __GLXscreen *pGlxScreen = glxGetScreen(screenInfo.screens[screen]); - - pGlxScreen->swapBarrierFuncs = funcs; -} - -static Bool -glxCloseScreen (int index, ScreenPtr pScreen) -{ - __GLXscreen *pGlxScreen = glxGetScreen(pScreen); - - pScreen->CloseScreen = pGlxScreen->CloseScreen; - pScreen->DestroyWindow = pGlxScreen->DestroyWindow; - - pGlxScreen->destroy(pGlxScreen); - - return pScreen->CloseScreen(index, pScreen); -} - -__GLXscreen * -glxGetScreen(ScreenPtr pScreen) -{ - return dixLookupPrivate(&pScreen->devPrivates, glxScreenPrivateKey); -} - -_X_EXPORT void GlxSetVisualConfigs(int nconfigs, - void *configs, void **privates) -{ - /* We keep this stub around for the DDX drivers that still - * call it. */ -} - -GLint glxConvertToXVisualType(int visualType) -{ - static const int x_visual_types[] = { - TrueColor, DirectColor, - PseudoColor, StaticColor, - GrayScale, StaticGray - }; - - return ( (unsigned) (visualType - GLX_TRUE_COLOR) < 6 ) - ? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1; -} - -/* This code inspired by composite/compinit.c. We could move this to - * mi/ and share it with composite.*/ - -static VisualPtr -AddScreenVisuals(ScreenPtr pScreen, int count, int d) -{ - int i; - DepthPtr depth; - - depth = NULL; - for (i = 0; i < pScreen->numDepths; i++) { - if (pScreen->allowedDepths[i].depth == d) { - depth = &pScreen->allowedDepths[i]; - break; - } - } - if (depth == NULL) - return NULL; - - if (ResizeVisualArray(pScreen, count, depth) == FALSE) - return NULL; - - /* Return a pointer to the first of the added visuals. */ - return pScreen->visuals + pScreen->numVisuals - count; -} - -static int -findFirstSet(unsigned int v) -{ - int i; - - for (i = 0; i < 32; i++) - if (v & (1 << i)) - return i; - - return -1; -} - -static void -initGlxVisual(VisualPtr visual, __GLXconfig *config) -{ - int maxBits; - maxBits = max(config->redBits, max(config->greenBits, config->blueBits)); - - config->visualID = visual->vid; - visual->class = glxConvertToXVisualType(config->visualType); - visual->bitsPerRGBValue = maxBits; - visual->ColormapEntries = 1 << maxBits; - visual->nplanes = config->redBits + config->greenBits + config->blueBits; - - visual->redMask = config->redMask; - visual->greenMask = config->greenMask; - visual->blueMask = config->blueMask; - visual->offsetRed = findFirstSet(config->redMask); - visual->offsetGreen = findFirstSet(config->greenMask); - visual->offsetBlue = findFirstSet(config->blueMask); -} - -static __GLXconfig * -pickFBConfig(__GLXscreen *pGlxScreen, VisualPtr visual) -{ - __GLXconfig *best = NULL, *config; - int best_score = 0; - - for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) { - int score = 0; - - if (config->redMask != visual->redMask || - config->greenMask != visual->greenMask || - config->blueMask != visual->blueMask) - continue; - if (config->visualRating != GLX_NONE) - continue; - if (glxConvertToXVisualType(config->visualType) != visual->class) - continue; - /* If it's the 32-bit RGBA visual, demand a 32-bit fbconfig. */ - if (visual->nplanes == 32 && config->rgbBits != 32) - continue; - /* Can't use the same FBconfig for multiple X visuals. I think. */ - if (config->visualID != 0) - continue; - - if (config->doubleBufferMode > 0) - score += 8; - if (config->depthBits > 0) - score += 4; - if (config->stencilBits > 0) - score += 2; - if (config->alphaBits > 0) - score++; - - if (score > best_score) { - best = config; - best_score = score; - } - } - - return best; -} - -static Bool -glxDestroyWindow(WindowPtr pWin) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - __GLXscreen *pGlxScreen = glxGetScreen(pScreen); - Bool retval = TRUE; - - FreeResource(pWin->drawable.id, FALSE); - - /* call lower wrapped functions */ - if (pGlxScreen->DestroyWindow) { - /* unwrap */ - pScreen->DestroyWindow = pGlxScreen->DestroyWindow; - - /* call lower layers */ - retval = (*pScreen->DestroyWindow)(pWin); - - /* rewrap */ - pGlxScreen->DestroyWindow = pScreen->DestroyWindow; - pScreen->DestroyWindow = glxDestroyWindow; - } - - return retval; -} - -void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen) -{ - __GLXconfig *m; - __GLXconfig *config; - int i; - - pGlxScreen->pScreen = pScreen; - pGlxScreen->GLextensions = xstrdup(GLServerExtensions); - pGlxScreen->GLXvendor = xstrdup(GLXServerVendorName); - pGlxScreen->GLXextensions = xstrdup(GLXServerExtensions); - - /* All GLX providers must support all of the functionality required for at - * least GLX 1.2. If the provider supports a higher version, the GLXminor - * version can be changed in the provider's screen-probe routine. For - * most providers, the screen-probe routine is the caller of this - * function. - */ - pGlxScreen->GLXmajor = 1; - pGlxScreen->GLXminor = 2; - - pGlxScreen->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = glxCloseScreen; - pGlxScreen->DestroyWindow = pScreen->DestroyWindow; - pScreen->DestroyWindow = glxDestroyWindow; - - i = 0; - for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) { - m->fbconfigID = FakeClientID(0); - m->visualID = 0; - i++; - } - pGlxScreen->numFBConfigs = i; - - pGlxScreen->visuals = - xcalloc(pGlxScreen->numFBConfigs, sizeof (__GLXconfig *)); - - /* First, try to choose featureful FBconfigs for the existing X visuals. - * Note that if multiple X visuals end up with the same FBconfig being - * chosen, the later X visuals don't get GLX visuals (because we want to - * prioritize the root visual being GLX). - */ - for (i = 0; i < pScreen->numVisuals; i++) { - VisualPtr visual = &pScreen->visuals[i]; - - config = pickFBConfig(pGlxScreen, visual); - if (config) { - pGlxScreen->visuals[pGlxScreen->numVisuals++] = config; - config->visualID = visual->vid; - } - } - - /* Then, add new visuals corresponding to all FBconfigs that didn't have - * an existing, appropriate visual. - */ - for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) { - int depth; - - VisualPtr visual; - - if (config->visualID != 0) - continue; - - /* Only count RGB bits and not alpha, as we're not trying to create - * visuals for compositing (that's what the 32-bit composite visual - * set up above is for. - */ - depth = config->redBits + config->greenBits + config->blueBits; - - /* Make sure that our FBconfig's depth can actually be displayed - * (corresponds to an existing visual). - */ - for (i = 0; i < pScreen->numVisuals; i++) { - if (depth == pScreen->visuals[i].nplanes) - break; - } - if (i == pScreen->numVisuals) - continue; - - /* Create a new X visual for our FBconfig. */ - visual = AddScreenVisuals(pScreen, 1, depth); - if (visual == NULL) - continue; - - pGlxScreen->visuals[pGlxScreen->numVisuals++] = config; - initGlxVisual(visual, config); - } - - dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, pGlxScreen); -} - -void __glXScreenDestroy(__GLXscreen *screen) -{ - xfree(screen->GLXvendor); - xfree(screen->GLXextensions); - xfree(screen->GLextensions); -} +/*
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * 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
+ * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#else
+
+#include "glheader.h"
+
+#endif
+
+#include <GL/glxtokens.h>
+#include <string.h>
+#include <windowstr.h>
+#include <os.h>
+#include <colormapst.h>
+
+#include "privates.h"
+#include "glxserver.h"
+#include "glxutil.h"
+#include "glxext.h"
+#include "protocol-versions.h"
+
+static int glxScreenPrivateKeyIndex;
+static DevPrivateKey glxScreenPrivateKey = &glxScreenPrivateKeyIndex;
+
+const char GLServerVersion[] = "1.4";
+static const char GLServerExtensions[] =
+ "GL_ARB_depth_texture "
+ "GL_ARB_draw_buffers "
+ "GL_ARB_fragment_program "
+ "GL_ARB_fragment_program_shadow "
+ "GL_ARB_imaging "
+ "GL_ARB_multisample "
+ "GL_ARB_multitexture "
+ "GL_ARB_occlusion_query "
+ "GL_ARB_point_parameters "
+ "GL_ARB_point_sprite "
+ "GL_ARB_shadow "
+ "GL_ARB_shadow_ambient "
+ "GL_ARB_texture_border_clamp "
+ "GL_ARB_texture_compression "
+ "GL_ARB_texture_cube_map "
+ "GL_ARB_texture_env_add "
+ "GL_ARB_texture_env_combine "
+ "GL_ARB_texture_env_crossbar "
+ "GL_ARB_texture_env_dot3 "
+ "GL_ARB_texture_mirrored_repeat "
+ "GL_ARB_texture_non_power_of_two "
+ "GL_ARB_transpose_matrix "
+ "GL_ARB_vertex_program "
+ "GL_ARB_window_pos "
+ "GL_EXT_abgr "
+ "GL_EXT_bgra "
+ "GL_EXT_blend_color "
+ "GL_EXT_blend_equation_separate "
+ "GL_EXT_blend_func_separate "
+ "GL_EXT_blend_logic_op "
+ "GL_EXT_blend_minmax "
+ "GL_EXT_blend_subtract "
+ "GL_EXT_clip_volume_hint "
+ "GL_EXT_copy_texture "
+ "GL_EXT_draw_range_elements "
+ "GL_EXT_fog_coord "
+ "GL_EXT_framebuffer_object "
+ "GL_EXT_multi_draw_arrays "
+ "GL_EXT_packed_pixels "
+ "GL_EXT_paletted_texture "
+ "GL_EXT_point_parameters "
+ "GL_EXT_polygon_offset "
+ "GL_EXT_rescale_normal "
+ "GL_EXT_secondary_color "
+ "GL_EXT_separate_specular_color "
+ "GL_EXT_shadow_funcs "
+ "GL_EXT_shared_texture_palette "
+ "GL_EXT_stencil_two_side "
+ "GL_EXT_stencil_wrap "
+ "GL_EXT_subtexture "
+ "GL_EXT_texture "
+ "GL_EXT_texture3D "
+ "GL_EXT_texture_compression_dxt1 "
+ "GL_EXT_texture_compression_s3tc "
+ "GL_EXT_texture_edge_clamp "
+ "GL_EXT_texture_env_add "
+ "GL_EXT_texture_env_combine "
+ "GL_EXT_texture_env_dot3 "
+ "GL_EXT_texture_filter_anisotropic "
+ "GL_EXT_texture_lod "
+ "GL_EXT_texture_lod_bias "
+ "GL_EXT_texture_mirror_clamp "
+ "GL_EXT_texture_object "
+ "GL_EXT_texture_rectangle "
+ "GL_EXT_vertex_array "
+ "GL_3DFX_texture_compression_FXT1 "
+ "GL_APPLE_packed_pixels "
+ "GL_ATI_draw_buffers "
+ "GL_ATI_texture_env_combine3 "
+ "GL_ATI_texture_mirror_once "
+ "GL_HP_occlusion_test "
+ "GL_IBM_texture_mirrored_repeat "
+ "GL_INGR_blend_func_separate "
+ "GL_MESA_pack_invert "
+ "GL_MESA_ycbcr_texture "
+ "GL_NV_blend_square "
+ "GL_NV_depth_clamp "
+ "GL_NV_fog_distance "
+ "GL_NV_fragment_program "
+ "GL_NV_fragment_program_option "
+ "GL_NV_fragment_program2 "
+ "GL_NV_light_max_exponent "
+ "GL_NV_multisample_filter_hint "
+ "GL_NV_point_sprite "
+ "GL_NV_texgen_reflection "
+ "GL_NV_texture_compression_vtc "
+ "GL_NV_texture_env_combine4 "
+ "GL_NV_texture_expand_normal "
+ "GL_NV_texture_rectangle "
+ "GL_NV_vertex_program "
+ "GL_NV_vertex_program1_1 "
+ "GL_NV_vertex_program2 "
+ "GL_NV_vertex_program2_option "
+ "GL_NV_vertex_program3 "
+ "GL_OES_compressed_paletted_texture "
+ "GL_SGI_color_matrix "
+ "GL_SGI_color_table "
+ "GL_SGIS_generate_mipmap "
+ "GL_SGIS_multisample "
+ "GL_SGIS_point_parameters "
+ "GL_SGIS_texture_border_clamp "
+ "GL_SGIS_texture_edge_clamp "
+ "GL_SGIS_texture_lod "
+ "GL_SGIX_depth_texture "
+ "GL_SGIX_shadow "
+ "GL_SGIX_shadow_ambient "
+ "GL_SUN_slice_accum "
+ ;
+
+/*
+** We have made the simplifying assuption that the same extensions are
+** supported across all screens in a multi-screen system.
+*/
+static char GLXServerVendorName[] = "SGI";
+unsigned glxMajorVersion = SERVER_GLX_MAJOR_VERSION;
+unsigned glxMinorVersion = SERVER_GLX_MINOR_VERSION;
+static char GLXServerExtensions[] =
+ "GLX_ARB_multisample "
+ "GLX_EXT_visual_info "
+ "GLX_EXT_visual_rating "
+ "GLX_EXT_import_context "
+ "GLX_EXT_texture_from_pixmap "
+ "GLX_OML_swap_method "
+ "GLX_SGI_make_current_read "
+#ifndef __APPLE__
+ "GLX_SGIS_multisample "
+ "GLX_SGIX_hyperpipe "
+ "GLX_SGIX_swap_barrier "
+#endif
+ "GLX_SGIX_fbconfig "
+ "GLX_SGIX_pbuffer "
+ "GLX_MESA_copy_sub_buffer "
+ "GLX_INTEL_swap_event"
+ ;
+
+/*
+ * If your DDX driver wants to register support for swap barriers or hyperpipe
+ * topology, it should call __glXHyperpipeInit() or __glXSwapBarrierInit()
+ * with a dispatch table of functions to handle the requests. In the XFree86
+ * DDX, for example, you would call these near the bottom of the driver's
+ * ScreenInit method, after DRI has been initialized.
+ *
+ * This should be replaced with a better method when we teach the server how
+ * to load DRI drivers.
+ */
+
+void __glXHyperpipeInit(int screen, __GLXHyperpipeExtensionFuncs *funcs)
+{
+ __GLXscreen *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+
+ pGlxScreen->hyperpipeFuncs = funcs;
+}
+
+void __glXSwapBarrierInit(int screen, __GLXSwapBarrierExtensionFuncs *funcs)
+{
+ __GLXscreen *pGlxScreen = glxGetScreen(screenInfo.screens[screen]);
+
+ pGlxScreen->swapBarrierFuncs = funcs;
+}
+
+static Bool
+glxCloseScreen (int index, ScreenPtr pScreen)
+{
+ __GLXscreen *pGlxScreen = glxGetScreen(pScreen);
+
+ pScreen->CloseScreen = pGlxScreen->CloseScreen;
+ pScreen->DestroyWindow = pGlxScreen->DestroyWindow;
+
+ pGlxScreen->destroy(pGlxScreen);
+
+ return pScreen->CloseScreen(index, pScreen);
+}
+
+__GLXscreen *
+glxGetScreen(ScreenPtr pScreen)
+{
+ return dixLookupPrivate(&pScreen->devPrivates, glxScreenPrivateKey);
+}
+
+_X_EXPORT void GlxSetVisualConfigs(int nconfigs,
+ void *configs, void **privates)
+{
+ /* We keep this stub around for the DDX drivers that still
+ * call it. */
+}
+
+GLint glxConvertToXVisualType(int visualType)
+{
+ static const int x_visual_types[] = {
+ TrueColor, DirectColor,
+ PseudoColor, StaticColor,
+ GrayScale, StaticGray
+ };
+
+ return ( (unsigned) (visualType - GLX_TRUE_COLOR) < 6 )
+ ? x_visual_types[ visualType - GLX_TRUE_COLOR ] : -1;
+}
+
+/* This code inspired by composite/compinit.c. We could move this to
+ * mi/ and share it with composite.*/
+
+static VisualPtr
+AddScreenVisuals(ScreenPtr pScreen, int count, int d)
+{
+ int i;
+ DepthPtr depth;
+
+ depth = NULL;
+ for (i = 0; i < pScreen->numDepths; i++) {
+ if (pScreen->allowedDepths[i].depth == d) {
+ depth = &pScreen->allowedDepths[i];
+ break;
+ }
+ }
+ if (depth == NULL)
+ return NULL;
+
+ if (ResizeVisualArray(pScreen, count, depth) == FALSE)
+ return NULL;
+
+ /* Return a pointer to the first of the added visuals. */
+ return pScreen->visuals + pScreen->numVisuals - count;
+}
+
+static int
+findFirstSet(unsigned int v)
+{
+ int i;
+
+ for (i = 0; i < 32; i++)
+ if (v & (1 << i))
+ return i;
+
+ return -1;
+}
+
+static void
+initGlxVisual(VisualPtr visual, __GLXconfig *config)
+{
+ int maxBits;
+ maxBits = max(config->redBits, max(config->greenBits, config->blueBits));
+
+ config->visualID = visual->vid;
+ visual->class = glxConvertToXVisualType(config->visualType);
+ visual->bitsPerRGBValue = maxBits;
+ visual->ColormapEntries = 1 << maxBits;
+ visual->nplanes = config->redBits + config->greenBits + config->blueBits;
+
+ visual->redMask = config->redMask;
+ visual->greenMask = config->greenMask;
+ visual->blueMask = config->blueMask;
+ visual->offsetRed = findFirstSet(config->redMask);
+ visual->offsetGreen = findFirstSet(config->greenMask);
+ visual->offsetBlue = findFirstSet(config->blueMask);
+}
+
+static __GLXconfig *
+pickFBConfig(__GLXscreen *pGlxScreen, VisualPtr visual)
+{
+ __GLXconfig *best = NULL, *config;
+ int best_score = 0;
+
+ for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) {
+ int score = 0;
+
+ if (config->redMask != visual->redMask ||
+ config->greenMask != visual->greenMask ||
+ config->blueMask != visual->blueMask)
+ continue;
+ if (config->visualRating != GLX_NONE)
+ continue;
+ if (glxConvertToXVisualType(config->visualType) != visual->class)
+ continue;
+ /* If it's the 32-bit RGBA visual, demand a 32-bit fbconfig. */
+ if (visual->nplanes == 32 && config->rgbBits != 32)
+ continue;
+ /* Can't use the same FBconfig for multiple X visuals. I think. */
+ if (config->visualID != 0)
+ continue;
+
+ if (config->doubleBufferMode > 0)
+ score += 8;
+ if (config->depthBits > 0)
+ score += 4;
+ if (config->stencilBits > 0)
+ score += 2;
+ if (config->alphaBits > 0)
+ score++;
+
+ if (score > best_score) {
+ best = config;
+ best_score = score;
+ }
+ }
+
+ return best;
+}
+
+static Bool
+glxDestroyWindow(WindowPtr pWin)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ __GLXscreen *pGlxScreen = glxGetScreen(pScreen);
+ Bool retval = TRUE;
+
+ FreeResource(pWin->drawable.id, FALSE);
+
+ /* call lower wrapped functions */
+ if (pGlxScreen->DestroyWindow) {
+ /* unwrap */
+ pScreen->DestroyWindow = pGlxScreen->DestroyWindow;
+
+ /* call lower layers */
+ retval = (*pScreen->DestroyWindow)(pWin);
+
+ /* rewrap */
+ pGlxScreen->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = glxDestroyWindow;
+ }
+
+ return retval;
+}
+
+void __glXScreenInit(__GLXscreen *pGlxScreen, ScreenPtr pScreen)
+{
+ __GLXconfig *m;
+ __GLXconfig *config;
+ int i;
+
+ pGlxScreen->pScreen = pScreen;
+ pGlxScreen->GLextensions = xstrdup(GLServerExtensions);
+ pGlxScreen->GLXvendor = xstrdup(GLXServerVendorName);
+ pGlxScreen->GLXextensions = xstrdup(GLXServerExtensions);
+
+ /* All GLX providers must support all of the functionality required for at
+ * least GLX 1.2. If the provider supports a higher version, the GLXminor
+ * version can be changed in the provider's screen-probe routine. For
+ * most providers, the screen-probe routine is the caller of this
+ * function.
+ */
+ pGlxScreen->GLXmajor = 1;
+ pGlxScreen->GLXminor = 2;
+
+ pGlxScreen->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = glxCloseScreen;
+ pGlxScreen->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = glxDestroyWindow;
+
+ i = 0;
+ for (m = pGlxScreen->fbconfigs; m != NULL; m = m->next) {
+ m->fbconfigID = FakeClientID(0);
+ m->visualID = 0;
+ i++;
+ }
+ pGlxScreen->numFBConfigs = i;
+
+ pGlxScreen->visuals =
+ xcalloc(pGlxScreen->numFBConfigs, sizeof (__GLXconfig *));
+
+ /* First, try to choose featureful FBconfigs for the existing X visuals.
+ * Note that if multiple X visuals end up with the same FBconfig being
+ * chosen, the later X visuals don't get GLX visuals (because we want to
+ * prioritize the root visual being GLX).
+ */
+ for (i = 0; i < pScreen->numVisuals; i++) {
+ VisualPtr visual = &pScreen->visuals[i];
+
+ config = pickFBConfig(pGlxScreen, visual);
+ if (config) {
+ pGlxScreen->visuals[pGlxScreen->numVisuals++] = config;
+ config->visualID = visual->vid;
+ }
+ }
+
+ /* Then, add new visuals corresponding to all FBconfigs that didn't have
+ * an existing, appropriate visual.
+ */
+ for (config = pGlxScreen->fbconfigs; config != NULL; config = config->next) {
+ int depth;
+
+ VisualPtr visual;
+
+ if (config->visualID != 0)
+ continue;
+
+ /* Only count RGB bits and not alpha, as we're not trying to create
+ * visuals for compositing (that's what the 32-bit composite visual
+ * set up above is for.
+ */
+ depth = config->redBits + config->greenBits + config->blueBits;
+
+ /* Make sure that our FBconfig's depth can actually be displayed
+ * (corresponds to an existing visual).
+ */
+ for (i = 0; i < pScreen->numVisuals; i++) {
+ if (depth == pScreen->visuals[i].nplanes)
+ break;
+ }
+ if (i == pScreen->numVisuals)
+ continue;
+
+ /* Create a new X visual for our FBconfig. */
+ visual = AddScreenVisuals(pScreen, 1, depth);
+ if (visual == NULL)
+ continue;
+
+ pGlxScreen->visuals[pGlxScreen->numVisuals++] = config;
+ initGlxVisual(visual, config);
+ }
+
+ dixSetPrivate(&pScreen->devPrivates, glxScreenPrivateKey, pGlxScreen);
+}
+
+void __glXScreenDestroy(__GLXscreen *screen)
+{
+ xfree(screen->GLXvendor);
+ xfree(screen->GLXextensions);
+ xfree(screen->GLextensions);
+}
diff --git a/xorg-server/glx/glxserver.h b/xorg-server/glx/glxserver.h index 1daf97758..296d453eb 100644 --- a/xorg-server/glx/glxserver.h +++ b/xorg-server/glx/glxserver.h @@ -1,254 +1,255 @@ -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#ifndef _GLX_server_h_ -#define _GLX_server_h_ - -/* - * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008) - * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and - * either this permission notice or a reference to - * http://oss.sgi.com/projects/FreeB/ - * 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 - * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc. - * shall not be used in advertising or otherwise to promote the sale, use or - * other dealings in this Software without prior written authorization from - * Silicon Graphics, Inc. - */ - -#include <X11/X.h> -#include <X11/Xproto.h> -#include <X11/Xmd.h> -#include <misc.h> -#include <dixstruct.h> -#include <pixmapstr.h> -#include <gcstruct.h> -#include <extnsionst.h> -#include <resource.h> -#include <scrnintstr.h> - -/* -** The X header misc.h defines these math functions. -*/ -#undef abs -#undef fabs - -#define GL_GLEXT_PROTOTYPES /* we want prototypes */ -#include <GL/gl.h> -#include <GL/glxproto.h> - -/* -** GLX resources. -*/ -typedef XID GLXContextID; -typedef XID GLXPixmap; -typedef XID GLXDrawable; - -typedef struct __GLXclientStateRec __GLXclientState; -typedef struct __GLXdrawable __GLXdrawable; -typedef struct __GLXcontext __GLXcontext; - -#include "glxscreens.h" -#include "glxdrawable.h" -#include "glxcontext.h" - -#ifndef True -#define True 1 -#endif -#ifndef False -#define False 0 -#endif - -extern __GLXscreen *glxGetScreen(ScreenPtr pScreen); -extern __GLXclientState *glxGetClient(ClientPtr pClient); - -/************************************************************************/ - -void GlxExtensionInit(void); - -void GlxSetVisualConfigs(int nconfigs, - void *configs, void **privates); - -void __glXScreenInitVisuals(__GLXscreen *screen); - -/* -** The last context used (from the server's persective) is cached. -*/ -extern __GLXcontext *__glXLastContext; -extern __GLXcontext *__glXForceCurrent(__GLXclientState*, GLXContextTag, int*); - -extern ClientPtr __pGlxClient; - -int __glXError(int error); - -/* -** Macros to set, unset, and retrieve the flag that says whether a context -** has unflushed commands. -*/ -#define __GLX_NOTE_UNFLUSHED_CMDS(glxc) glxc->hasUnflushedCommands = GL_TRUE -#define __GLX_NOTE_FLUSHED_CMDS(glxc) glxc->hasUnflushedCommands = GL_FALSE -#define __GLX_HAS_UNFLUSHED_CMDS(glxc) (glxc->hasUnflushedCommands) - -/************************************************************************/ - -typedef struct __GLXprovider __GLXprovider; -struct __GLXprovider { - __GLXscreen *(*screenProbe)(ScreenPtr pScreen); - const char *name; - __GLXprovider *next; -}; - -void GlxPushProvider(__GLXprovider *provider); - -enum { - GLX_MINIMAL_VISUALS, - GLX_TYPICAL_VISUALS, - GLX_ALL_VISUALS -}; - -void __glXsetEnterLeaveServerFuncs(void (*enter)(GLboolean), - void (*leave)(GLboolean)); -void __glXenterServer(GLboolean rendering); -void __glXleaveServer(GLboolean rendering); - -void glxSuspendClients(void); -void glxResumeClients(void); - -/* -** State kept per client. -*/ -struct __GLXclientStateRec { - /* - ** Whether this structure is currently being used to support a client. - */ - Bool inUse; - - /* - ** Buffer for returned data. - */ - GLbyte *returnBuf; - GLint returnBufSize; - - /* - ** Keep track of large rendering commands, which span multiple requests. - */ - GLint largeCmdBytesSoFar; /* bytes received so far */ - GLint largeCmdBytesTotal; /* total bytes expected */ - GLint largeCmdRequestsSoFar; /* requests received so far */ - GLint largeCmdRequestsTotal; /* total requests expected */ - GLbyte *largeCmdBuf; - GLint largeCmdBufSize; - - /* - ** Keep a list of all the contexts that are current for this client's - ** threads. - */ - __GLXcontext **currentContexts; - GLint numCurrentContexts; - - /* Back pointer to X client record */ - ClientPtr client; - - int GLClientmajorVersion; - int GLClientminorVersion; - char *GLClientextensions; -}; - -/************************************************************************/ - -/* -** Dispatch tables. -*/ -typedef void (*__GLXdispatchRenderProcPtr)(GLbyte *); -typedef int (*__GLXdispatchSingleProcPtr)(__GLXclientState *, GLbyte *); -typedef int (*__GLXdispatchVendorPrivProcPtr)(__GLXclientState *, GLbyte *); - -/* - * Dispatch for GLX commands. - */ -typedef int (*__GLXprocPtr)(__GLXclientState *, char *pc); - -/* - * Tables for computing the size of each rendering command. - */ -typedef int (*gl_proto_size_func)(const GLbyte *, Bool); - -typedef struct { - int bytes; - gl_proto_size_func varsize; -} __GLXrenderSizeData; - -/************************************************************************/ - -/* -** X resources. -*/ -extern RESTYPE __glXContextRes; -extern RESTYPE __glXClientRes; -extern RESTYPE __glXPixmapRes; -extern RESTYPE __glXDrawableRes; - -/************************************************************************/ - -/* -** Prototypes. -*/ - -extern char *__glXcombine_strings(const char *, const char *); - -/* -** Routines for sending swapped replies. -*/ - -extern void __glXSwapMakeCurrentReply(ClientPtr client, - xGLXMakeCurrentReply *reply); -extern void __glXSwapIsDirectReply(ClientPtr client, - xGLXIsDirectReply *reply); -extern void __glXSwapQueryVersionReply(ClientPtr client, - xGLXQueryVersionReply *reply); -extern void __glXSwapQueryContextInfoEXTReply(ClientPtr client, - xGLXQueryContextInfoEXTReply *reply, - int *buf); -extern void __glXSwapGetDrawableAttributesReply(ClientPtr client, - xGLXGetDrawableAttributesReply *reply, CARD32 *buf); -extern void glxSwapQueryExtensionsStringReply(ClientPtr client, - xGLXQueryExtensionsStringReply *reply, char *buf); -extern void glxSwapQueryServerStringReply(ClientPtr client, - xGLXQueryServerStringReply *reply, char *buf); - - -/* - * Routines for computing the size of variably-sized rendering commands. - */ - -extern int __glXTypeSize(GLenum enm); -extern int __glXImageSize(GLenum format, GLenum type, - GLenum target, GLsizei w, GLsizei h, GLsizei d, - GLint imageHeight, GLint rowLength, GLint skipImages, GLint skipRows, - GLint alignment); - -extern unsigned glxMajorVersion; -extern unsigned glxMinorVersion; - -extern int __glXEventBase; - -#endif /* !__GLX_server_h__ */ +#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef _GLX_server_h_
+#define _GLX_server_h_
+
+/*
+ * SGI FREE SOFTWARE LICENSE B (Version 2.0, Sept. 18, 2008)
+ * Copyright (C) 1991-2000 Silicon Graphics, 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 including the dates of first publication and
+ * either this permission notice or a reference to
+ * http://oss.sgi.com/projects/FreeB/
+ * 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
+ * SILICON GRAPHICS, INC. 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 Silicon Graphics, Inc.
+ * shall not be used in advertising or otherwise to promote the sale, use or
+ * other dealings in this Software without prior written authorization from
+ * Silicon Graphics, Inc.
+ */
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/Xmd.h>
+#include <misc.h>
+#include <dixstruct.h>
+#include <pixmapstr.h>
+#include <gcstruct.h>
+#include <extnsionst.h>
+#include <resource.h>
+#include <scrnintstr.h>
+
+/*
+** The X header misc.h defines these math functions.
+*/
+#undef abs
+#undef fabs
+
+#define GL_GLEXT_PROTOTYPES /* we want prototypes */
+#include <GL/gl.h>
+#include <GL/glext.h>
+#include <GL/glxproto.h>
+
+/*
+** GLX resources.
+*/
+typedef XID GLXContextID;
+typedef XID GLXPixmap;
+typedef XID GLXDrawable;
+
+typedef struct __GLXclientStateRec __GLXclientState;
+typedef struct __GLXdrawable __GLXdrawable;
+typedef struct __GLXcontext __GLXcontext;
+
+#include "glxscreens.h"
+#include "glxdrawable.h"
+#include "glxcontext.h"
+
+#ifndef True
+#define True 1
+#endif
+#ifndef False
+#define False 0
+#endif
+
+extern __GLXscreen *glxGetScreen(ScreenPtr pScreen);
+extern __GLXclientState *glxGetClient(ClientPtr pClient);
+
+/************************************************************************/
+
+void GlxExtensionInit(void);
+
+void GlxSetVisualConfigs(int nconfigs,
+ void *configs, void **privates);
+
+void __glXScreenInitVisuals(__GLXscreen *screen);
+
+/*
+** The last context used (from the server's persective) is cached.
+*/
+extern __GLXcontext *__glXLastContext;
+extern __GLXcontext *__glXForceCurrent(__GLXclientState*, GLXContextTag, int*);
+
+extern ClientPtr __pGlxClient;
+
+int __glXError(int error);
+
+/*
+** Macros to set, unset, and retrieve the flag that says whether a context
+** has unflushed commands.
+*/
+#define __GLX_NOTE_UNFLUSHED_CMDS(glxc) glxc->hasUnflushedCommands = GL_TRUE
+#define __GLX_NOTE_FLUSHED_CMDS(glxc) glxc->hasUnflushedCommands = GL_FALSE
+#define __GLX_HAS_UNFLUSHED_CMDS(glxc) (glxc->hasUnflushedCommands)
+
+/************************************************************************/
+
+typedef struct __GLXprovider __GLXprovider;
+struct __GLXprovider {
+ __GLXscreen *(*screenProbe)(ScreenPtr pScreen);
+ const char *name;
+ __GLXprovider *next;
+};
+
+void GlxPushProvider(__GLXprovider *provider);
+
+enum {
+ GLX_MINIMAL_VISUALS,
+ GLX_TYPICAL_VISUALS,
+ GLX_ALL_VISUALS
+};
+
+void __glXsetEnterLeaveServerFuncs(void (*enter)(GLboolean),
+ void (*leave)(GLboolean));
+void __glXenterServer(GLboolean rendering);
+void __glXleaveServer(GLboolean rendering);
+
+void glxSuspendClients(void);
+void glxResumeClients(void);
+
+/*
+** State kept per client.
+*/
+struct __GLXclientStateRec {
+ /*
+ ** Whether this structure is currently being used to support a client.
+ */
+ Bool inUse;
+
+ /*
+ ** Buffer for returned data.
+ */
+ GLbyte *returnBuf;
+ GLint returnBufSize;
+
+ /*
+ ** Keep track of large rendering commands, which span multiple requests.
+ */
+ GLint largeCmdBytesSoFar; /* bytes received so far */
+ GLint largeCmdBytesTotal; /* total bytes expected */
+ GLint largeCmdRequestsSoFar; /* requests received so far */
+ GLint largeCmdRequestsTotal; /* total requests expected */
+ GLbyte *largeCmdBuf;
+ GLint largeCmdBufSize;
+
+ /*
+ ** Keep a list of all the contexts that are current for this client's
+ ** threads.
+ */
+ __GLXcontext **currentContexts;
+ GLint numCurrentContexts;
+
+ /* Back pointer to X client record */
+ ClientPtr client;
+
+ int GLClientmajorVersion;
+ int GLClientminorVersion;
+ char *GLClientextensions;
+};
+
+/************************************************************************/
+
+/*
+** Dispatch tables.
+*/
+typedef void (*__GLXdispatchRenderProcPtr)(GLbyte *);
+typedef int (*__GLXdispatchSingleProcPtr)(__GLXclientState *, GLbyte *);
+typedef int (*__GLXdispatchVendorPrivProcPtr)(__GLXclientState *, GLbyte *);
+
+/*
+ * Dispatch for GLX commands.
+ */
+typedef int (*__GLXprocPtr)(__GLXclientState *, char *pc);
+
+/*
+ * Tables for computing the size of each rendering command.
+ */
+typedef int (*gl_proto_size_func)(const GLbyte *, Bool);
+
+typedef struct {
+ int bytes;
+ gl_proto_size_func varsize;
+} __GLXrenderSizeData;
+
+/************************************************************************/
+
+/*
+** X resources.
+*/
+extern RESTYPE __glXContextRes;
+extern RESTYPE __glXClientRes;
+extern RESTYPE __glXPixmapRes;
+extern RESTYPE __glXDrawableRes;
+
+/************************************************************************/
+
+/*
+** Prototypes.
+*/
+
+extern char *__glXcombine_strings(const char *, const char *);
+
+/*
+** Routines for sending swapped replies.
+*/
+
+extern void __glXSwapMakeCurrentReply(ClientPtr client,
+ xGLXMakeCurrentReply *reply);
+extern void __glXSwapIsDirectReply(ClientPtr client,
+ xGLXIsDirectReply *reply);
+extern void __glXSwapQueryVersionReply(ClientPtr client,
+ xGLXQueryVersionReply *reply);
+extern void __glXSwapQueryContextInfoEXTReply(ClientPtr client,
+ xGLXQueryContextInfoEXTReply *reply,
+ int *buf);
+extern void __glXSwapGetDrawableAttributesReply(ClientPtr client,
+ xGLXGetDrawableAttributesReply *reply, CARD32 *buf);
+extern void glxSwapQueryExtensionsStringReply(ClientPtr client,
+ xGLXQueryExtensionsStringReply *reply, char *buf);
+extern void glxSwapQueryServerStringReply(ClientPtr client,
+ xGLXQueryServerStringReply *reply, char *buf);
+
+
+/*
+ * Routines for computing the size of variably-sized rendering commands.
+ */
+
+extern int __glXTypeSize(GLenum enm);
+extern int __glXImageSize(GLenum format, GLenum type,
+ GLenum target, GLsizei w, GLsizei h, GLsizei d,
+ GLint imageHeight, GLint rowLength, GLint skipImages, GLint skipRows,
+ GLint alignment);
+
+extern unsigned glxMajorVersion;
+extern unsigned glxMinorVersion;
+
+extern int __glXEventBase;
+
+#endif /* !__GLX_server_h__ */
diff --git a/xorg-server/glx/indirect_dispatch.c b/xorg-server/glx/indirect_dispatch.c index 666551903..1da14750d 100644 --- a/xorg-server/glx/indirect_dispatch.c +++ b/xorg-server/glx/indirect_dispatch.c @@ -24,6 +24,13 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#else + +#include "glheader.h" + +#endif #include <X11/Xmd.h> #include <GL/gl.h> diff --git a/xorg-server/glx/indirect_dispatch_swap.c b/xorg-server/glx/indirect_dispatch_swap.c index 3221c809d..64d9dc99b 100644 --- a/xorg-server/glx/indirect_dispatch_swap.c +++ b/xorg-server/glx/indirect_dispatch_swap.c @@ -24,6 +24,13 @@ * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#else + +#include "glheader.h" + +#endif #include <X11/Xmd.h> #include <GL/gl.h> diff --git a/xorg-server/glx/indirect_program.c b/xorg-server/glx/indirect_program.c index 237da2908..165d12bd9 100644 --- a/xorg-server/glx/indirect_program.c +++ b/xorg-server/glx/indirect_program.c @@ -31,6 +31,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include "glxserver.h" diff --git a/xorg-server/glx/indirect_reqsize.c b/xorg-server/glx/indirect_reqsize.c index 35bb9370f..ed64d0f46 100644 --- a/xorg-server/glx/indirect_reqsize.c +++ b/xorg-server/glx/indirect_reqsize.c @@ -25,6 +25,13 @@ * SOFTWARE. */ +#ifdef HAVE_DIX_CONFIG_H +#include <dix-config.h> +#else + +#include "glheader.h" + +#endif #include <GL/gl.h> #include "glxserver.h" diff --git a/xorg-server/glx/indirect_size_get.c b/xorg-server/glx/indirect_size_get.c index 5a2dbed29..af4ec9e8e 100644 --- a/xorg-server/glx/indirect_size_get.c +++ b/xorg-server/glx/indirect_size_get.c @@ -25,6 +25,13 @@ * SOFTWARE.
*/
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#else
+
+#include "glheader.h"
+
+#endif
#include <GL/gl.h>
#include "indirect_size_get.h"
@@ -888,7 +895,9 @@ __glGetTexLevelParameterfv_size(GLenum e) case GL_TEXTURE_INTENSITY_SIZE:
/* case GL_TEXTURE_INTENSITY_SIZE_EXT:*/
case GL_TEXTURE_DEPTH:
+#ifndef _MSC_VER
case GL_TEXTURE_INDEX_SIZE_EXT:
+#endif
case GL_TEXTURE_COMPRESSED_IMAGE_SIZE:
/* case GL_TEXTURE_COMPRESSED_IMAGE_SIZE_ARB:*/
case GL_TEXTURE_COMPRESSED:
diff --git a/xorg-server/glx/indirect_table.c b/xorg-server/glx/indirect_table.c index cb3202605..b5ac86a5a 100644 --- a/xorg-server/glx/indirect_table.c +++ b/xorg-server/glx/indirect_table.c @@ -25,6 +25,10 @@ * SOFTWARE. */ +#ifndef HAVE_DIX_CONFIG_H +#include "glheader.h" +#endif + #include <inttypes.h> #include "glxserver.h" #include "glxext.h" diff --git a/xorg-server/glx/indirect_texture_compression.c b/xorg-server/glx/indirect_texture_compression.c index 5f44d7b1a..2de255533 100644 --- a/xorg-server/glx/indirect_texture_compression.c +++ b/xorg-server/glx/indirect_texture_compression.c @@ -25,6 +25,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include "glxserver.h" diff --git a/xorg-server/glx/indirect_util.c b/xorg-server/glx/indirect_util.c index 44309104e..2f48ab2b0 100644 --- a/xorg-server/glx/indirect_util.c +++ b/xorg-server/glx/indirect_util.c @@ -25,6 +25,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include <string.h> diff --git a/xorg-server/glx/makefile b/xorg-server/glx/makefile new file mode 100644 index 000000000..65eac87fb --- /dev/null +++ b/xorg-server/glx/makefile @@ -0,0 +1,42 @@ +LIBRARY=libglx
+
+DEFINES += GLAPIENTRY=__stdcall
+
+
+glapi_sources = \
+ indirect_dispatch.c \
+ indirect_dispatch_swap.c \
+ indirect_reqsize.c \
+ indirect_size_get.c \
+ indirect_table.c \
+ glapi.c \
+ glthread.c
+libglxdri_la_SOURCES = \
+ extension_string.c
+
+CSRCS = \
+ $(indirect_sources) \
+ $(glapi_sources) \
+ $(libglxdri_la_SOURCES) \
+ indirect_util.c \
+ indirect_program.c \
+ indirect_texture_compression.c \
+ glxcmds.c \
+ glxcmdsswap.c \
+ glxext.c \
+ glxdriswrast.c \
+ glxdricommon.c \
+ glxscreens.c \
+ render2.c \
+ render2swap.c \
+ renderpix.c \
+ renderpixswap.c \
+ rensize.c \
+ single2.c \
+ single2swap.c \
+ singlepix.c \
+ singlepixswap.c \
+ singlesize.c \
+ swap_interval.c \
+ xfont.c
+
diff --git a/xorg-server/glx/render2.c b/xorg-server/glx/render2.c index eb7c30ba0..32cee4160 100644 --- a/xorg-server/glx/render2.c +++ b/xorg-server/glx/render2.c @@ -30,6 +30,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include <glxserver.h> diff --git a/xorg-server/glx/render2swap.c b/xorg-server/glx/render2swap.c index 17354c4f8..59cb93a6a 100644 --- a/xorg-server/glx/render2swap.c +++ b/xorg-server/glx/render2swap.c @@ -30,6 +30,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include "glxserver.h" diff --git a/xorg-server/glx/renderpix.c b/xorg-server/glx/renderpix.c index 056e62c87..3e5612036 100644 --- a/xorg-server/glx/renderpix.c +++ b/xorg-server/glx/renderpix.c @@ -30,6 +30,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include "glxserver.h" diff --git a/xorg-server/glx/renderpixswap.c b/xorg-server/glx/renderpixswap.c index 9cd57410e..a73ed1e3c 100644 --- a/xorg-server/glx/renderpixswap.c +++ b/xorg-server/glx/renderpixswap.c @@ -30,6 +30,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include "glxserver.h" diff --git a/xorg-server/glx/rensize.c b/xorg-server/glx/rensize.c index 8a58e08d7..6b85dc116 100644 --- a/xorg-server/glx/rensize.c +++ b/xorg-server/glx/rensize.c @@ -30,6 +30,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include <GL/gl.h> @@ -219,7 +223,9 @@ int __glXImageSize( GLenum format, GLenum type, GLenum target, case GL_422_AVERAGE_EXT: case GL_422_REV_AVERAGE_EXT: case GL_DEPTH_STENCIL_NV: +#ifndef _MSC_VER case GL_DEPTH_STENCIL_MESA: +#endif case GL_YCBCR_MESA: case GL_LUMINANCE_ALPHA: elementsPerGroup = 2; @@ -258,11 +264,13 @@ int __glXImageSize( GLenum format, GLenum type, GLenum target, case GL_UNSIGNED_SHORT_1_5_5_5_REV: case GL_UNSIGNED_SHORT_8_8_APPLE: case GL_UNSIGNED_SHORT_8_8_REV_APPLE: +#ifndef _MSC_VER case GL_UNSIGNED_SHORT_15_1_MESA: case GL_UNSIGNED_SHORT_1_15_REV_MESA: bytesPerElement = 2; elementsPerGroup = 1; break; +#endif case GL_INT: case GL_UNSIGNED_INT: case GL_FLOAT: @@ -273,8 +281,10 @@ int __glXImageSize( GLenum format, GLenum type, GLenum target, case GL_UNSIGNED_INT_10_10_10_2: case GL_UNSIGNED_INT_2_10_10_10_REV: case GL_UNSIGNED_INT_24_8_NV: +#ifndef _MSC_VER case GL_UNSIGNED_INT_24_8_MESA: case GL_UNSIGNED_INT_8_24_REV_MESA: +#endif bytesPerElement = 4; elementsPerGroup = 1; break; diff --git a/xorg-server/glx/single2.c b/xorg-server/glx/single2.c index 50a59ed71..f6e474c46 100644 --- a/xorg-server/glx/single2.c +++ b/xorg-server/glx/single2.c @@ -30,6 +30,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include <string.h> diff --git a/xorg-server/glx/single2swap.c b/xorg-server/glx/single2swap.c index cf83bdc88..e27e97aee 100644 --- a/xorg-server/glx/single2swap.c +++ b/xorg-server/glx/single2swap.c @@ -30,6 +30,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include "glxserver.h" diff --git a/xorg-server/glx/singlepix.c b/xorg-server/glx/singlepix.c index a0a6a7918..656f1ec5e 100644 --- a/xorg-server/glx/singlepix.c +++ b/xorg-server/glx/singlepix.c @@ -30,6 +30,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include "glxserver.h" diff --git a/xorg-server/glx/singlepixswap.c b/xorg-server/glx/singlepixswap.c index a7febc9a6..c7d2d1562 100644 --- a/xorg-server/glx/singlepixswap.c +++ b/xorg-server/glx/singlepixswap.c @@ -30,6 +30,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include "glxserver.h" diff --git a/xorg-server/glx/singlesize.c b/xorg-server/glx/singlesize.c index 9e95dd3d3..a9a2be66b 100644 --- a/xorg-server/glx/singlesize.c +++ b/xorg-server/glx/singlesize.c @@ -30,6 +30,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include <GL/gl.h> diff --git a/xorg-server/glx/swap_interval.c b/xorg-server/glx/swap_interval.c index 0bae3247e..d8b4ab2b6 100644 --- a/xorg-server/glx/swap_interval.c +++ b/xorg-server/glx/swap_interval.c @@ -24,6 +24,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include "glxserver.h" diff --git a/xorg-server/glx/xfont.c b/xorg-server/glx/xfont.c index b8b466d87..2af5996f3 100644 --- a/xorg-server/glx/xfont.c +++ b/xorg-server/glx/xfont.c @@ -30,6 +30,10 @@ #ifdef HAVE_DIX_CONFIG_H #include <dix-config.h> +#else + +#include "glheader.h" + #endif #include "glxserver.h" diff --git a/xorg-server/hw/dmx/dmxinit.c b/xorg-server/hw/dmx/dmxinit.c index f481cf5c9..739c4ca7f 100644 --- a/xorg-server/hw/dmx/dmxinit.c +++ b/xorg-server/hw/dmx/dmxinit.c @@ -1,1041 +1,1042 @@ -/* - * 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 <kem@redhat.com> - * David H. Dawes <dawes@xfree86.org> - * Rickard E. (Rik) Faith <faith@redhat.com> - * - */ - -/** \file - * Provide expected functions for initialization from the ddx layer and - * global variables for the DMX server. */ - -#ifdef HAVE_DMX_CONFIG_H -#include <dmx-config.h> -#endif - -#include "dmx.h" -#include "dmxinit.h" -#include "dmxsync.h" -#include "dmxlog.h" -#include "dmxinput.h" -#include "dmxscrinit.h" -#include "dmxcursor.h" -#include "dmxfont.h" -#include "config/dmxconfig.h" -#include "dmxcb.h" -#include "dmxprop.h" -#include "dmxstat.h" -#ifdef RENDER -#include "dmxpict.h" -#endif - -#include <X11/Xos.h> /* For gettimeofday */ -#include "dixstruct.h" -#ifdef PANORAMIX -#include "panoramiXsrv.h" -#endif - -#include <signal.h> /* For SIGQUIT */ - -#ifdef GLXEXT -#include <GL/glx.h> -#include <GL/glxint.h> -#include "dmx_glxvisuals.h" -#include <X11/extensions/Xext.h> -#include <X11/extensions/extutil.h> - -extern void GlxSetVisualConfigs( - int nconfigs, - __GLXvisualConfig *configs, - void **configprivs -); -#endif /* GLXEXT */ - -/* Global variables available to all Xserver/hw/dmx routines. */ -int dmxNumScreens; -DMXScreenInfo *dmxScreens; - -int dmxNumInputs; -DMXInputInfo *dmxInputs; - -int dmxShadowFB = FALSE; - -XErrorEvent dmxLastErrorEvent; -Bool dmxErrorOccurred = FALSE; - -char *dmxFontPath = NULL; - -Bool dmxOffScreenOpt = TRUE; - -Bool dmxSubdividePrimitives = TRUE; - -Bool dmxLazyWindowCreation = TRUE; - -Bool dmxUseXKB = TRUE; - -int dmxDepth = 0; - -#ifndef GLXEXT -static Bool dmxGLXProxy = FALSE; -#else -Bool dmxGLXProxy = TRUE; - -Bool dmxGLXSwapGroupSupport = TRUE; - -Bool dmxGLXSyncSwap = FALSE; - -Bool dmxGLXFinishSwap = FALSE; -#endif - -Bool dmxIgnoreBadFontPaths = FALSE; - -Bool dmxAddRemoveScreens = FALSE; - -/* dmxErrorHandler catches errors that occur when calling one of the - * back-end servers. Some of this code is based on _XPrintDefaultError - * in xc/lib/X11/XlibInt.c */ -static int dmxErrorHandler(Display *dpy, XErrorEvent *ev) -{ -#define DMX_ERROR_BUF_SIZE 256 - /* RATS: these buffers are only used in - * length-limited calls. */ - char buf[DMX_ERROR_BUF_SIZE]; - char request[DMX_ERROR_BUF_SIZE]; - _XExtension *ext = NULL; - - dmxErrorOccurred = TRUE; - dmxLastErrorEvent = *ev; - - XGetErrorText(dpy, ev->error_code, buf, sizeof(buf)); - dmxLog(dmxWarning, "dmxErrorHandler: %s\n", buf); - - /* Find major opcode name */ - if (ev->request_code < 128) { - XmuSnprintf(request, sizeof(request), "%d", ev->request_code); - XGetErrorDatabaseText(dpy, "XRequest", request, "", buf, sizeof(buf)); - } else { - for (ext = dpy->ext_procs; - ext && ext->codes.major_opcode != ev->request_code; - ext = ext->next); - if (ext) strncpy(buf, ext->name, sizeof(buf)); - else buf[0] = '\0'; - } - dmxLog(dmxWarning, " Major opcode: %d (%s)\n", - ev->request_code, buf); - - /* Find minor opcode name */ - if (ev->request_code >= 128 && ext) { - XmuSnprintf(request, sizeof(request), "%d", ev->request_code); - XmuSnprintf(request, sizeof(request), "%s.%d", - ext->name, ev->minor_code); - XGetErrorDatabaseText(dpy, "XRequest", request, "", buf, sizeof(buf)); - dmxLog(dmxWarning, " Minor opcode: %d (%s)\n", - ev->minor_code, buf); - } - - /* Provide value information */ - switch (ev->error_code) { - case BadValue: - dmxLog(dmxWarning, " Value: 0x%x\n", - ev->resourceid); - break; - case BadAtom: - dmxLog(dmxWarning, " AtomID: 0x%x\n", - ev->resourceid); - break; - default: - dmxLog(dmxWarning, " ResourceID: 0x%x\n", - ev->resourceid); - break; - } - - /* Provide serial number information */ - dmxLog(dmxWarning, " Failed serial number: %d\n", - ev->serial); - dmxLog(dmxWarning, " Current serial number: %d\n", - dpy->request); - return 0; -} - -#ifdef GLXEXT -static int dmxNOPErrorHandler(Display *dpy, XErrorEvent *ev) -{ - return 0; -} -#endif - -Bool dmxOpenDisplay(DMXScreenInfo *dmxScreen) -{ - if (!(dmxScreen->beDisplay = XOpenDisplay(dmxScreen->name))) - return FALSE; - - dmxPropertyDisplay(dmxScreen); - return TRUE; -} - -void dmxSetErrorHandler(DMXScreenInfo *dmxScreen) -{ - XSetErrorHandler(dmxErrorHandler); -} - -static void dmxPrintScreenInfo(DMXScreenInfo *dmxScreen) -{ - XWindowAttributes attribs; - int ndepths = 0, *depths = NULL; - int i; - Display *dpy = dmxScreen->beDisplay; - Screen *s = DefaultScreenOfDisplay(dpy); - int scr = DefaultScreen(dpy); - - XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &attribs); - if (!(depths = XListDepths(dpy, scr, &ndepths))) ndepths = 0; - - dmxLogOutput(dmxScreen, "Name of display: %s\n", DisplayString(dpy)); - dmxLogOutput(dmxScreen, "Version number: %d.%d\n", - ProtocolVersion(dpy), ProtocolRevision(dpy)); - dmxLogOutput(dmxScreen, "Vendor string: %s\n", ServerVendor(dpy)); - if (!strstr(ServerVendor(dpy), "XFree86")) { - dmxLogOutput(dmxScreen, "Vendor release: %d\n", VendorRelease(dpy)); - } else { - /* This code based on xdpyinfo.c */ - int v = VendorRelease(dpy); - int major = -1, minor = -1, patch = -1, subpatch = -1; - - if (v < 336) - major = v / 100, minor = (v / 10) % 10, patch = v % 10; - else if (v < 3900) { - major = v / 1000; - minor = (v / 100) % 10; - if (((v / 10) % 10) || (v % 10)) { - patch = (v / 10) % 10; - if (v % 10) subpatch = v % 10; - } - } else if (v < 40000000) { - major = v / 1000; - minor = (v / 10) % 10; - if (v % 10) patch = v % 10; - } else { - major = v / 10000000; - minor = (v / 100000) % 100; - patch = (v / 1000) % 100; - if (v % 1000) subpatch = v % 1000; - } - dmxLogOutput(dmxScreen, "Vendor release: %d (XFree86 version: %d.%d", - v, major, minor); - if (patch > 0) dmxLogOutputCont(dmxScreen, ".%d", patch); - if (subpatch > 0) dmxLogOutputCont(dmxScreen, ".%d", subpatch); - dmxLogOutputCont(dmxScreen, ")\n"); - } - - - dmxLogOutput(dmxScreen, "Dimensions: %dx%d pixels\n", - attribs.width, attribs.height); - dmxLogOutput(dmxScreen, "%d depths on screen %d: ", ndepths, scr); - for (i = 0; i < ndepths; i++) - dmxLogOutputCont(dmxScreen, "%c%d", i ? ',' : ' ', depths[i]); - dmxLogOutputCont(dmxScreen, "\n"); - dmxLogOutput(dmxScreen, "Depth of root window: %d plane%s (%d)\n", - attribs.depth, attribs.depth == 1 ? "" : "s", - DisplayPlanes(dpy, scr)); - dmxLogOutput(dmxScreen, "Number of colormaps: %d min, %d max\n", - MinCmapsOfScreen(s), MaxCmapsOfScreen(s)); - dmxLogOutput(dmxScreen, "Options: backing-store %s, save-unders %s\n", - (DoesBackingStore (s) == NotUseful) ? "no" : - ((DoesBackingStore (s) == Always) ? "yes" : "when mapped"), - DoesSaveUnders (s) ? "yes" : "no"); - dmxLogOutput(dmxScreen, "Window Manager running: %s\n", - (dmxScreen->WMRunningOnBE) ? "yes" : "no"); - - if (dmxScreen->WMRunningOnBE) { - dmxLogOutputWarning(dmxScreen, - "Window manager running " - "-- colormaps not supported\n"); - } - XFree(depths); -} - -void dmxGetScreenAttribs(DMXScreenInfo *dmxScreen) -{ - XWindowAttributes attribs; - Display *dpy = dmxScreen->beDisplay; -#ifdef GLXEXT - int dummy; -#endif - - XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &attribs); - - dmxScreen->beWidth = attribs.width; - dmxScreen->beHeight = attribs.height; - - /* Fill in missing geometry information */ - if (dmxScreen->scrnXSign < 0) { - if (dmxScreen->scrnWidth) { - dmxScreen->scrnX = (attribs.width - dmxScreen->scrnWidth - - dmxScreen->scrnX); - } else { - dmxScreen->scrnWidth = attribs.width - dmxScreen->scrnX; - dmxScreen->scrnX = 0; - } - } - if (dmxScreen->scrnYSign < 0) { - if (dmxScreen->scrnHeight) { - dmxScreen->scrnY = (attribs.height - dmxScreen->scrnHeight - - dmxScreen->scrnY); - } else { - dmxScreen->scrnHeight = attribs.height - dmxScreen->scrnY; - dmxScreen->scrnY = 0; - } - } - if (!dmxScreen->scrnWidth) - dmxScreen->scrnWidth = attribs.width - dmxScreen->scrnX; - if (!dmxScreen->scrnHeight) - dmxScreen->scrnHeight = attribs.height - dmxScreen->scrnY; - - if (!dmxScreen->rootWidth) dmxScreen->rootWidth = dmxScreen->scrnWidth; - if (!dmxScreen->rootHeight) dmxScreen->rootHeight = dmxScreen->scrnHeight; - if (dmxScreen->rootWidth + dmxScreen->rootX > dmxScreen->scrnWidth) - dmxScreen->rootWidth = dmxScreen->scrnWidth - dmxScreen->rootX; - if (dmxScreen->rootHeight + dmxScreen->rootY > dmxScreen->scrnHeight) - dmxScreen->rootHeight = dmxScreen->scrnHeight - dmxScreen->rootY; - - /* FIXME: Get these from the back-end server */ - dmxScreen->beXDPI = 75; - dmxScreen->beYDPI = 75; - - dmxScreen->beDepth = attribs.depth; /* FIXME: verify that this - * works always. In - * particular, this will work - * well for depth=16, will fail - * because of colormap issues - * at depth 8. More work needs - * to be done here. */ - - if (dmxScreen->beDepth <= 8) dmxScreen->beBPP = 8; - else if (dmxScreen->beDepth <= 16) dmxScreen->beBPP = 16; - else dmxScreen->beBPP = 32; - -#ifdef GLXEXT - /* get the majorOpcode for the back-end GLX extension */ - XQueryExtension(dpy, "GLX", &dmxScreen->glxMajorOpcode, - &dummy, &dmxScreen->glxErrorBase); -#endif - - dmxPrintScreenInfo(dmxScreen); - dmxLogOutput(dmxScreen, "%dx%d+%d+%d on %dx%d at depth=%d, bpp=%d\n", - dmxScreen->scrnWidth, dmxScreen->scrnHeight, - dmxScreen->scrnX, dmxScreen->scrnY, - dmxScreen->beWidth, dmxScreen->beHeight, - dmxScreen->beDepth, dmxScreen->beBPP); - if (dmxScreen->beDepth == 8) - dmxLogOutputWarning(dmxScreen, - "Support for depth == 8 is not complete\n"); -} - -Bool dmxGetVisualInfo(DMXScreenInfo *dmxScreen) -{ - int i; - XVisualInfo visinfo; - - visinfo.screen = DefaultScreen(dmxScreen->beDisplay); - dmxScreen->beVisuals = XGetVisualInfo(dmxScreen->beDisplay, - VisualScreenMask, - &visinfo, - &dmxScreen->beNumVisuals); - - dmxScreen->beDefVisualIndex = -1; - - if (defaultColorVisualClass >= 0 || dmxDepth > 0) { - for (i = 0; i < dmxScreen->beNumVisuals; i++) - if (defaultColorVisualClass >= 0) { - if (dmxScreen->beVisuals[i].class == defaultColorVisualClass) { - if (dmxDepth > 0) { - if (dmxScreen->beVisuals[i].depth == dmxDepth) { - dmxScreen->beDefVisualIndex = i; - break; - } - } else { - dmxScreen->beDefVisualIndex = i; - break; - } - } - } else if (dmxScreen->beVisuals[i].depth == dmxDepth) { - dmxScreen->beDefVisualIndex = i; - break; - } - } else { - visinfo.visualid = - XVisualIDFromVisual(DefaultVisual(dmxScreen->beDisplay, - visinfo.screen)); - - for (i = 0; i < dmxScreen->beNumVisuals; i++) - if (visinfo.visualid == dmxScreen->beVisuals[i].visualid) { - dmxScreen->beDefVisualIndex = i; - break; - } - } - - for (i = 0; i < dmxScreen->beNumVisuals; i++) - dmxLogVisual(dmxScreen, &dmxScreen->beVisuals[i], - (i == dmxScreen->beDefVisualIndex)); - - return (dmxScreen->beDefVisualIndex >= 0); -} - -void dmxGetColormaps(DMXScreenInfo *dmxScreen) -{ - int i; - - dmxScreen->beNumDefColormaps = dmxScreen->beNumVisuals; - dmxScreen->beDefColormaps = xalloc(dmxScreen->beNumDefColormaps * - sizeof(*dmxScreen->beDefColormaps)); - - for (i = 0; i < dmxScreen->beNumDefColormaps; i++) - dmxScreen->beDefColormaps[i] = - XCreateColormap(dmxScreen->beDisplay, - DefaultRootWindow(dmxScreen->beDisplay), - dmxScreen->beVisuals[i].visual, - AllocNone); - - dmxScreen->beBlackPixel = BlackPixel(dmxScreen->beDisplay, - DefaultScreen(dmxScreen->beDisplay)); - dmxScreen->beWhitePixel = WhitePixel(dmxScreen->beDisplay, - DefaultScreen(dmxScreen->beDisplay)); -} - -void dmxGetPixmapFormats(DMXScreenInfo *dmxScreen) -{ - dmxScreen->beDepths = - XListDepths(dmxScreen->beDisplay, DefaultScreen(dmxScreen->beDisplay), - &dmxScreen->beNumDepths); - - dmxScreen->bePixmapFormats = - XListPixmapFormats(dmxScreen->beDisplay, - &dmxScreen->beNumPixmapFormats); -} - -static Bool dmxSetPixmapFormats(ScreenInfo *pScreenInfo, - DMXScreenInfo *dmxScreen) -{ - XPixmapFormatValues *bePixmapFormat; - PixmapFormatRec *format; - int i, j; - - pScreenInfo->imageByteOrder = ImageByteOrder(dmxScreen->beDisplay); - pScreenInfo->bitmapScanlineUnit = BitmapUnit(dmxScreen->beDisplay); - pScreenInfo->bitmapScanlinePad = BitmapPad(dmxScreen->beDisplay); - pScreenInfo->bitmapBitOrder = BitmapBitOrder(dmxScreen->beDisplay); - - pScreenInfo->numPixmapFormats = 0; - for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) { - bePixmapFormat = &dmxScreen->bePixmapFormats[i]; - for (j = 0; j < dmxScreen->beNumDepths; j++) - if ((bePixmapFormat->depth == 1) || - (bePixmapFormat->depth == dmxScreen->beDepths[j])) { - format = &pScreenInfo->formats[pScreenInfo->numPixmapFormats]; - - format->depth = bePixmapFormat->depth; - format->bitsPerPixel = bePixmapFormat->bits_per_pixel; - format->scanlinePad = bePixmapFormat->scanline_pad; - - pScreenInfo->numPixmapFormats++; - break; - } - } - - return TRUE; -} - -void dmxCheckForWM(DMXScreenInfo *dmxScreen) -{ - Status status; - XWindowAttributes xwa; - - status = XGetWindowAttributes(dmxScreen->beDisplay, - DefaultRootWindow(dmxScreen->beDisplay), - &xwa); - dmxScreen->WMRunningOnBE = - (status && - ((xwa.all_event_masks & SubstructureRedirectMask) || - (xwa.all_event_masks & SubstructureNotifyMask))); -} - -/** Initialize the display and collect relevant information about the - * display properties */ -static void dmxDisplayInit(DMXScreenInfo *dmxScreen) -{ - if (!dmxOpenDisplay(dmxScreen)) - dmxLog(dmxFatal, - "dmxOpenDisplay: Unable to open display %s\n", - dmxScreen->name); - - dmxSetErrorHandler(dmxScreen); - dmxCheckForWM(dmxScreen); - dmxGetScreenAttribs(dmxScreen); - - if (!dmxGetVisualInfo(dmxScreen)) - dmxLog(dmxFatal, "dmxGetVisualInfo: No matching visuals found\n"); - - dmxGetColormaps(dmxScreen); - dmxGetPixmapFormats(dmxScreen); -} - -/* If this doesn't compile, just add || defined(yoursystem) to the line - * below. This information is to help with bug reports and is not - * critical. */ -#if !defined(_POSIX_SOURCE) -static const char *dmxExecOS(void) { return ""; } -#else -#include <sys/utsname.h> -static const char *dmxExecOS(void) -{ - static char buffer[128]; - static int initialized = 0; - struct utsname u; - - if (!initialized++) { - memset(buffer, 0, sizeof(buffer)); - uname(&u); - XmuSnprintf(buffer, sizeof(buffer)-1, "%s %s %s", - u.sysname, u.release, u.version); - } - return buffer; -} -#endif - -static const char *dmxBuildCompiler(void) -{ - static char buffer[128]; - static int initialized = 0; - - if (!initialized++) { - memset(buffer, 0, sizeof(buffer)); -#if defined(__GNUC__) && defined(__GNUC_MINOR__) &&defined(__GNUC_PATCHLEVEL__) - XmuSnprintf(buffer, sizeof(buffer)-1, "gcc %d.%d.%d", - __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__); -#endif - } - return buffer; -} - -static const char *dmxExecHost(void) -{ - static char buffer[128]; - static int initialized = 0; - - if (!initialized++) { - memset(buffer, 0, sizeof(buffer)); - XmuGetHostname(buffer, sizeof(buffer) - 1); - } - return buffer; -} - -/** This routine is called in Xserver/dix/main.c from \a main(). */ -void InitOutput(ScreenInfo *pScreenInfo, int argc, char *argv[]) -{ - int i; - static unsigned long dmxGeneration = 0; -#ifdef GLXEXT - Bool glxSupported = TRUE; -#endif - - if (dmxGeneration != serverGeneration) { - int vendrel = VENDOR_RELEASE; - int major, minor, year, month, day; - - dmxGeneration = serverGeneration; - - major = vendrel / 100000000; - vendrel -= major * 100000000; - minor = vendrel / 1000000; - vendrel -= minor * 1000000; - year = vendrel / 10000; - vendrel -= year * 10000; - month = vendrel / 100; - vendrel -= month * 100; - day = vendrel; - - /* Add other epoch tests here */ - if (major > 0 && minor > 0) year += 2000; - - dmxLog(dmxInfo, "Generation: %d\n", dmxGeneration); - dmxLog(dmxInfo, "DMX version: %d.%d.%02d%02d%02d (%s)\n", - major, minor, year, month, day, VENDOR_STRING); - - SetVendorRelease(VENDOR_RELEASE); - SetVendorString(VENDOR_STRING); - - if (dmxGeneration == 1) { - dmxLog(dmxInfo, "DMX Build OS: %s (%s)\n", OSNAME, OSVENDOR); - dmxLog(dmxInfo, "DMX Build Compiler: %s\n", dmxBuildCompiler()); - dmxLog(dmxInfo, "DMX Execution OS: %s\n", dmxExecOS()); - dmxLog(dmxInfo, "DMX Execution Host: %s\n", dmxExecHost()); - } - dmxLog(dmxInfo, "MAXSCREENS: %d\n", MAXSCREENS); - - for (i = 0; i < dmxNumScreens; i++) { - if (dmxScreens[i].beDisplay) - dmxLog(dmxWarning, "Display \"%s\" still open\n", - dmxScreens[i].name); - dmxStatFree(dmxScreens[i].stat); - dmxScreens[i].stat = NULL; - } - for (i = 0; i < dmxNumInputs; i++) dmxInputFree(&dmxInputs[i]); - if (dmxScreens) free(dmxScreens); - if (dmxInputs) free(dmxInputs); - dmxScreens = NULL; - dmxInputs = NULL; - dmxNumScreens = 0; - dmxNumInputs = 0; - } - - /* Make sure that the command-line arguments are sane. */ - if (dmxAddRemoveScreens && dmxGLXProxy) { - /* Currently it is not possible to support GLX and Render - * extensions with dynamic screen addition/removal due to the - * state that each extension keeps, which cannot be restored. */ - dmxLog(dmxWarning, - "GLX Proxy and Render extensions do not yet support dynamic\n"); - dmxLog(dmxWarning, - "screen addition and removal. Please specify -noglxproxy\n"); - dmxLog(dmxWarning, - "and -norender on the command line or in the configuration\n"); - dmxLog(dmxWarning, - "file to disable these two extensions if you wish to use\n"); - dmxLog(dmxWarning, - "the dynamic addition and removal of screens support.\n"); - dmxLog(dmxFatal, - "Dynamic screen addition/removal error (see above).\n"); - } - - /* ddxProcessArgument has been called at this point, but any data - * from the configuration file has not been applied. Do so, and be - * sure we have at least one back-end display. */ - dmxConfigConfigure(); - if (!dmxNumScreens) - dmxLog(dmxFatal, "InitOutput: no back-end displays found\n"); - if (!dmxNumInputs) - dmxLog(dmxInfo, "InitOutput: no inputs found\n"); - - /* Disable lazy window creation optimization if offscreen - * optimization is disabled */ - if (!dmxOffScreenOpt && dmxLazyWindowCreation) { - dmxLog(dmxInfo, - "InitOutput: Disabling lazy window creation optimization\n"); - dmxLog(dmxInfo, - " since it requires the offscreen optimization\n"); - dmxLog(dmxInfo, - " to function properly.\n"); - dmxLazyWindowCreation = FALSE; - } - - /* Open each display and gather information about it. */ - for (i = 0; i < dmxNumScreens; i++) - dmxDisplayInit(&dmxScreens[i]); - -#if PANORAMIX - /* Register a Xinerama callback which will run from within - * PanoramiXCreateConnectionBlock. We can use the callback to - * determine if Xinerama is loaded and to check the visuals - * determined by PanoramiXConsolidate. */ - XineramaRegisterConnectionBlockCallback(dmxConnectionBlockCallback); -#endif - - /* Since we only have a single screen thus far, we only need to set - the pixmap formats to match that screen. FIXME: this isn't true.*/ - if (!dmxSetPixmapFormats(pScreenInfo, &dmxScreens[0])) return; - - /* Might want to install a signal handler to allow cleaning up after - * unexpected signals. The DIX/OS layer already handles SIGINT and - * SIGTERM, so everything is OK for expected signals. --DD - * - * SIGHUP, SIGINT, and SIGTERM are trapped in os/connection.c - * SIGQUIT is another common signal that is sent from the keyboard. - * Trap it here, to ensure that the keyboard modifier map and other - * state for the input devices are restored. (This makes the - * behavior of SIGQUIT somewhat unexpected, since it will be the - * same as the behavior of SIGINT. However, leaving the modifier - * map of the input devices empty is even more unexpected.) --RF - */ - OsSignal(SIGQUIT, GiveUp); - -#ifdef GLXEXT - /* Check if GLX extension exists on all back-end servers */ - for (i = 0; i < dmxNumScreens; i++) - glxSupported &= (dmxScreens[i].glxMajorOpcode > 0); -#endif - - /* Tell dix layer about the backend displays */ - for (i = 0; i < dmxNumScreens; i++) { - -#ifdef GLXEXT - if (glxSupported) { - /* - * Builds GLX configurations from the list of visuals - * supported by the back-end server, and give that - * configuration list to the glx layer - so that he will - * build the visuals accordingly. - */ - - DMXScreenInfo *dmxScreen = &dmxScreens[i]; - __GLXvisualConfig *configs = NULL; - dmxGlxVisualPrivate **configprivs = NULL; - int nconfigs = 0; - int (*oldErrorHandler)(Display *, XErrorEvent *); - int i; - - /* Catch errors if when using an older GLX w/o FBconfigs */ - oldErrorHandler = XSetErrorHandler(dmxNOPErrorHandler); - - /* Get FBConfigs of the back-end server */ - dmxScreen->fbconfigs = GetGLXFBConfigs(dmxScreen->beDisplay, - dmxScreen->glxMajorOpcode, - &dmxScreen->numFBConfigs); - - XSetErrorHandler(oldErrorHandler); - - dmxScreen->glxVisuals = - GetGLXVisualConfigs(dmxScreen->beDisplay, - DefaultScreen(dmxScreen->beDisplay), - &dmxScreen->numGlxVisuals); - - if (dmxScreen->fbconfigs) { - configs = - GetGLXVisualConfigsFromFBConfigs(dmxScreen->fbconfigs, - dmxScreen->numFBConfigs, - dmxScreen->beVisuals, - dmxScreen->beNumVisuals, - dmxScreen->glxVisuals, - dmxScreen->numGlxVisuals, - &nconfigs); - } else { - configs = dmxScreen->glxVisuals; - nconfigs = dmxScreen->numGlxVisuals; - } - - configprivs = xalloc(nconfigs * sizeof(dmxGlxVisualPrivate*)); - - if (configs != NULL && configprivs != NULL) { - - /* Initialize our private info for each visual - * (currently only x_visual_depth and x_visual_class) - */ - for (i = 0; i < nconfigs; i++) { - - configprivs[i] = (dmxGlxVisualPrivate *) - xalloc(sizeof(dmxGlxVisualPrivate)); - configprivs[i]->x_visual_depth = 0; - configprivs[i]->x_visual_class = 0; - - /* Find the visual depth */ - if (configs[i].vid > 0) { - int j; - for (j = 0; j < dmxScreen->beNumVisuals; j++) { - if (dmxScreen->beVisuals[j].visualid == - configs[i].vid) { - configprivs[i]->x_visual_depth = - dmxScreen->beVisuals[j].depth; - configprivs[i]->x_visual_class = - dmxScreen->beVisuals[j].class; - break; - } - } - } - } - - /* Hand out the glx configs to glx extension */ - GlxSetVisualConfigs(nconfigs, configs, (void**)configprivs); - - XFlush(dmxScreen->beDisplay); - } - } -#endif /* GLXEXT */ - - AddScreen(dmxScreenInit, argc, argv); - } - - /* Compute origin information. */ - dmxInitOrigins(); - - /* Compute overlap information. */ - dmxInitOverlap(); - - /* Make sure there is a global width/height available */ - dmxComputeWidthHeight(DMX_NO_RECOMPUTE_BOUNDING_BOX); - - /* FIXME: The following is temporarily placed here. When the DMX - * extension is available, it will be move there. - */ - dmxInitFonts(); - -#ifdef RENDER - /* Initialize the render extension */ - if (!noRenderExtension) - dmxInitRender(); -#endif - - /* Initialized things that need timer hooks */ - dmxStatInit(); - dmxSyncInit(); /* Calls RegisterBlockAndWakeupHandlers */ - - dmxLog(dmxInfo, "Shadow framebuffer support %s\n", - dmxShadowFB ? "enabled" : "disabled"); -} - -/* RATS: Assuming the fp string (which comes from the command-line argv - vector) is NULL-terminated, the buffer is large enough for the - strcpy. */ -static void dmxSetDefaultFontPath(char *fp) -{ - int fplen = strlen(fp) + 1; - - if (dmxFontPath) { - int len; - - len = strlen(dmxFontPath); - dmxFontPath = xrealloc(dmxFontPath, len+fplen+1); - dmxFontPath[len] = ','; - strncpy(&dmxFontPath[len+1], fp, fplen); - } else { - dmxFontPath = xalloc(fplen); - strncpy(dmxFontPath, fp, fplen); - } - - defaultFontPath = dmxFontPath; -} - -/** This function is called in Xserver/os/utils.c from \a AbortServer(). - * We must ensure that backend and console state is restored in the - * event the server shutdown wasn't clean. */ -void AbortDDX(void) -{ - int i; - - for (i=0; i < dmxNumScreens; i++) { - DMXScreenInfo *dmxScreen = &dmxScreens[i]; - - if (dmxScreen->beDisplay) XCloseDisplay(dmxScreen->beDisplay); - dmxScreen->beDisplay = NULL; - } -} - -#ifdef DDXBEFORERESET -void ddxBeforeReset(void) -{ -} -#endif - -/** This function is called in Xserver/dix/main.c from \a main() when - * dispatchException & DE_TERMINATE (which is the only way to exit the - * main loop without an interruption. */ -void ddxGiveUp(void) -{ - AbortDDX(); -} - -/** This function is called in Xserver/os/osinit.c from \a OsInit(). */ -void OsVendorInit(void) -{ -} - -/** This function is called in Xserver/os/utils.c from \a FatalError() - * and \a VFatalError(). (Note that setting the function pointer \a - * OsVendorVErrorFProc will cause \a VErrorF() (which is called by the - * two routines mentioned here, as well as by others) to use the - * referenced routine instead of \a vfprintf().) */ -void OsVendorFatalError(void) -{ -} - -/** Process our command line arguments. */ -int ddxProcessArgument(int argc, char *argv[], int i) -{ - int retval = 0; - - if (!strcmp(argv[i], "-display")) { - if (++i < argc) dmxConfigStoreDisplay(argv[i]); - retval = 2; - } else if (!strcmp(argv[i], "-inputfrom") || !strcmp(argv[i], "-input")) { - if (++i < argc) dmxConfigStoreInput(argv[i]); - retval = 2; - } else if (!strcmp(argv[i], "-xinputfrom") || !strcmp(argv[i],"-xinput")) { - if (++i < argc) dmxConfigStoreXInput(argv[i]); - retval = 2; - } else if (!strcmp(argv[i], "-noshadowfb")) { - dmxLog(dmxWarning, - "-noshadowfb has been deprecated " - "since it is now the default\n"); - dmxShadowFB = FALSE; - retval = 1; - } else if (!strcmp(argv[i], "-nomulticursor")) { - dmxCursorNoMulti(); - retval = 1; - } else if (!strcmp(argv[i], "-shadowfb")) { - dmxShadowFB = TRUE; - retval = 1; - } else if (!strcmp(argv[i], "-configfile")) { - if (++i < argc) dmxConfigStoreFile(argv[i]); - retval = 2; - } else if (!strcmp(argv[i], "-config")) { - if (++i < argc) dmxConfigStoreConfig(argv[i]); - retval = 2; - } else if (!strcmp(argv[i], "-fontpath")) { - if (++i < argc) dmxSetDefaultFontPath(argv[i]); - retval = 2; - } else if (!strcmp(argv[i], "-stat")) { - if ((i += 2) < argc) dmxStatActivate(argv[i-1], argv[i]); - retval = 3; - } else if (!strcmp(argv[i], "-syncbatch")) { - if (++i < argc) dmxSyncActivate(argv[i]); - retval = 2; - } else if (!strcmp(argv[i], "-nooffscreenopt")) { - dmxOffScreenOpt = FALSE; - retval = 1; - } else if (!strcmp(argv[i], "-nosubdivprims")) { - dmxSubdividePrimitives = FALSE; - retval = 1; - } else if (!strcmp(argv[i], "-nowindowopt")) { - dmxLazyWindowCreation = FALSE; - retval = 1; - } else if (!strcmp(argv[i], "-noxkb")) { - dmxUseXKB = FALSE; - retval = 1; - } else if (!strcmp(argv[i], "-depth")) { - if (++i < argc) dmxDepth = atoi(argv[i]); - retval = 2; - } else if (!strcmp(argv[i], "-norender")) { - noRenderExtension = TRUE; - retval = 1; -#ifdef GLXEXT - } else if (!strcmp(argv[i], "-noglxproxy")) { - dmxGLXProxy = FALSE; - retval = 1; - } else if (!strcmp(argv[i], "-noglxswapgroup")) { - dmxGLXSwapGroupSupport = FALSE; - retval = 1; - } else if (!strcmp(argv[i], "-glxsyncswap")) { - dmxGLXSyncSwap = TRUE; - retval = 1; - } else if (!strcmp(argv[i], "-glxfinishswap")) { - dmxGLXFinishSwap = TRUE; - retval = 1; -#endif - } else if (!strcmp(argv[i], "-ignorebadfontpaths")) { - dmxIgnoreBadFontPaths = TRUE; - retval = 1; - } else if (!strcmp(argv[i], "-addremovescreens")) { - dmxAddRemoveScreens = TRUE; - retval = 1; - } else if (!strcmp(argv[i], "-param")) { - if ((i += 2) < argc) { - if (!strcasecmp(argv[i-1], "xkbrules")) - dmxConfigSetXkbRules(argv[i]); - else if (!strcasecmp(argv[i-1], "xkbmodel")) - dmxConfigSetXkbModel(argv[i]); - else if (!strcasecmp(argv[i-1], "xkblayout")) - dmxConfigSetXkbLayout(argv[i]); - else if (!strcasecmp(argv[i-1], "xkbvariant")) - dmxConfigSetXkbVariant(argv[i]); - else if (!strcasecmp(argv[i-1], "xkboptions")) - dmxConfigSetXkbOptions(argv[i]); - else - dmxLog(dmxWarning, - "-param requires: XkbRules, XkbModel, XkbLayout," - " XkbVariant, or XkbOptions\n"); - } - retval = 3; - } - if (!serverGeneration) dmxConfigSetMaxScreens(); - return retval; -} - -/** Provide succinct usage information for the DMX server. */ -void ddxUseMsg(void) -{ - ErrorF("\n\nDevice Dependent Usage:\n"); - ErrorF("-display string Specify the back-end display(s)\n"); - ErrorF("-input string Specify input source for core device\n"); - ErrorF("-xinput string Specify input source for XInput device\n"); - ErrorF("-shadowfb Enable shadow frame buffer\n"); - ErrorF("-configfile file Read from a configuration file\n"); - ErrorF("-config config Select a specific configuration\n"); - ErrorF("-nomulticursor Turn of multiple cursor support\n"); - ErrorF("-fontpath Sets the default font path\n"); - ErrorF("-stat inter scrns Print out performance statistics\n"); - ErrorF("-syncbatch inter Set interval for XSync batching\n"); - ErrorF("-nooffscreenopt Disable offscreen optimization\n"); - ErrorF("-nosubdivprims Disable primitive subdivision\n"); - ErrorF(" optimization\n"); - ErrorF("-nowindowopt Disable lazy window creation optimization\n"); - ErrorF("-noxkb Disable use of the XKB extension with\n"); - ErrorF(" backend displays (cf. -kb).\n"); - ErrorF("-depth Specify the default root window depth\n"); - ErrorF("-norender Disable RENDER extension support\n"); -#ifdef GLXEXT - ErrorF("-noglxproxy Disable GLX Proxy\n"); - ErrorF("-noglxswapgroup Disable swap group and swap barrier\n"); - ErrorF(" extensions in GLX proxy\n"); - ErrorF("-glxsyncswap Force XSync after swap buffers\n"); - ErrorF("-glxfinishswap Force glFinish after swap buffers\n"); -#endif - ErrorF("-ignorebadfontpaths Ignore bad font paths during initialization\n"); - ErrorF("-addremovescreens Enable dynamic screen addition/removal\n"); - ErrorF("-param ... Specify configuration parameters (e.g.,\n"); - ErrorF(" XkbRules, XkbModel, XkbLayout, etc.)\n"); - ErrorF("\n"); - ErrorF(" If the -input string matches a -display string, then input\n" - " is taken from that backend display. (XInput cannot be taken\n" - " from a backend display.) Placing \",console\" after the\n" - " display name will force a console window to be opened on\n" - " that display in addition to the backend input. This is\n" - " useful if the backend window does not cover the whole\n" - " physical display.\n\n"); - - ErrorF(" Otherwise, if the -input or -xinput string specifies another\n" - " X display, then a console window will be created on that\n" - " display. Placing \",windows\" or \",nowindows\" after the\n" - " display name will control the display of window outlines in\n" - " the console.\n\n"); - - ErrorF(" -input or -xinput dummy specifies no input.\n"); - ErrorF(" -input or -xinput local specifies the use of a raw keyboard,\n" - " mouse, or other (extension) device:\n" - " -input local,kbd,ps2 will use a ps2 mouse\n" - " -input local,kbd,ms will use a serial mouse\n" - " -input local,usb-kbd,usb-mou will use USB devices \n" - " -xinput local,usb-oth will use a non-mouse and\n" - " non-keyboard USB device with XInput\n\n"); - - ErrorF(" Special Keys:\n"); - ErrorF(" Ctrl-Alt-g Server grab/ungrab (console only)\n"); - ErrorF(" Ctrl-Alt-f Fine (1-pixel) mouse mode (console only)\n"); - ErrorF(" Ctrl-Alt-q Quit (core devices only)\n"); - ErrorF(" Ctrl-Alt-F* Switch to VC (local only)\n"); -} +/*
+ * 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 <kem@redhat.com>
+ * David H. Dawes <dawes@xfree86.org>
+ * Rickard E. (Rik) Faith <faith@redhat.com>
+ *
+ */
+
+/** \file
+ * Provide expected functions for initialization from the ddx layer and
+ * global variables for the DMX server. */
+
+#ifdef HAVE_DMX_CONFIG_H
+#include <dmx-config.h>
+#endif
+
+#include "dmx.h"
+#include "dmxinit.h"
+#include "dmxsync.h"
+#include "dmxlog.h"
+#include "dmxinput.h"
+#include "dmxscrinit.h"
+#include "dmxcursor.h"
+#include "dmxfont.h"
+#include "config/dmxconfig.h"
+#include "dmxcb.h"
+#include "dmxprop.h"
+#include "dmxstat.h"
+#ifdef RENDER
+#include "dmxpict.h"
+#endif
+
+#include <X11/Xos.h> /* For gettimeofday */
+#include "dixstruct.h"
+#ifdef PANORAMIX
+#include "panoramiXsrv.h"
+#endif
+
+#include <signal.h> /* For SIGQUIT */
+
+#ifdef GLXEXT
+#include <GL/glx.h>
+#include <GL/glxint.h>
+#include "dmx_glxvisuals.h"
+#include <X11/extensions/Xext.h>
+#include <X11/extensions/extutil.h>
+
+extern void GlxSetVisualConfigs(
+ int nconfigs,
+ __GLXvisualConfig *configs,
+ void **configprivs
+);
+#endif /* GLXEXT */
+
+/* Global variables available to all Xserver/hw/dmx routines. */
+int dmxNumScreens;
+DMXScreenInfo *dmxScreens;
+
+int dmxNumInputs;
+DMXInputInfo *dmxInputs;
+
+int dmxShadowFB = FALSE;
+
+XErrorEvent dmxLastErrorEvent;
+Bool dmxErrorOccurred = FALSE;
+
+char *dmxFontPath = NULL;
+
+Bool dmxOffScreenOpt = TRUE;
+
+Bool dmxSubdividePrimitives = TRUE;
+
+Bool dmxLazyWindowCreation = TRUE;
+
+Bool dmxUseXKB = TRUE;
+
+int dmxDepth = 0;
+
+#ifndef GLXEXT
+static Bool dmxGLXProxy = FALSE;
+#else
+Bool dmxGLXProxy = TRUE;
+
+Bool dmxGLXSwapGroupSupport = TRUE;
+
+Bool dmxGLXSyncSwap = FALSE;
+
+Bool dmxGLXFinishSwap = FALSE;
+#endif
+
+Bool dmxIgnoreBadFontPaths = FALSE;
+
+Bool dmxAddRemoveScreens = FALSE;
+
+/* dmxErrorHandler catches errors that occur when calling one of the
+ * back-end servers. Some of this code is based on _XPrintDefaultError
+ * in xc/lib/X11/XlibInt.c */
+static int dmxErrorHandler(Display *dpy, XErrorEvent *ev)
+{
+#define DMX_ERROR_BUF_SIZE 256
+ /* RATS: these buffers are only used in
+ * length-limited calls. */
+ char buf[DMX_ERROR_BUF_SIZE];
+ char request[DMX_ERROR_BUF_SIZE];
+ _XExtension *ext = NULL;
+
+ dmxErrorOccurred = TRUE;
+ dmxLastErrorEvent = *ev;
+
+ XGetErrorText(dpy, ev->error_code, buf, sizeof(buf));
+ dmxLog(dmxWarning, "dmxErrorHandler: %s\n", buf);
+
+ /* Find major opcode name */
+ if (ev->request_code < 128) {
+ XmuSnprintf(request, sizeof(request), "%d", ev->request_code);
+ XGetErrorDatabaseText(dpy, "XRequest", request, "", buf, sizeof(buf));
+ } else {
+ for (ext = dpy->ext_procs;
+ ext && ext->codes.major_opcode != ev->request_code;
+ ext = ext->next);
+ if (ext) strncpy(buf, ext->name, sizeof(buf));
+ else buf[0] = '\0';
+ }
+ dmxLog(dmxWarning, " Major opcode: %d (%s)\n",
+ ev->request_code, buf);
+
+ /* Find minor opcode name */
+ if (ev->request_code >= 128 && ext) {
+ XmuSnprintf(request, sizeof(request), "%d", ev->request_code);
+ XmuSnprintf(request, sizeof(request), "%s.%d",
+ ext->name, ev->minor_code);
+ XGetErrorDatabaseText(dpy, "XRequest", request, "", buf, sizeof(buf));
+ dmxLog(dmxWarning, " Minor opcode: %d (%s)\n",
+ ev->minor_code, buf);
+ }
+
+ /* Provide value information */
+ switch (ev->error_code) {
+ case BadValue:
+ dmxLog(dmxWarning, " Value: 0x%x\n",
+ ev->resourceid);
+ break;
+ case BadAtom:
+ dmxLog(dmxWarning, " AtomID: 0x%x\n",
+ ev->resourceid);
+ break;
+ default:
+ dmxLog(dmxWarning, " ResourceID: 0x%x\n",
+ ev->resourceid);
+ break;
+ }
+
+ /* Provide serial number information */
+ dmxLog(dmxWarning, " Failed serial number: %d\n",
+ ev->serial);
+ dmxLog(dmxWarning, " Current serial number: %d\n",
+ dpy->request);
+ return 0;
+}
+
+#ifdef GLXEXT
+static int dmxNOPErrorHandler(Display *dpy, XErrorEvent *ev)
+{
+ return 0;
+}
+#endif
+
+Bool dmxOpenDisplay(DMXScreenInfo *dmxScreen)
+{
+ if (!(dmxScreen->beDisplay = XOpenDisplay(dmxScreen->name)))
+ return FALSE;
+
+ dmxPropertyDisplay(dmxScreen);
+ return TRUE;
+}
+
+void dmxSetErrorHandler(DMXScreenInfo *dmxScreen)
+{
+ XSetErrorHandler(dmxErrorHandler);
+}
+
+static void dmxPrintScreenInfo(DMXScreenInfo *dmxScreen)
+{
+ XWindowAttributes attribs;
+ int ndepths = 0, *depths = NULL;
+ int i;
+ Display *dpy = dmxScreen->beDisplay;
+ Screen *s = DefaultScreenOfDisplay(dpy);
+ int scr = DefaultScreen(dpy);
+
+ XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &attribs);
+ if (!(depths = XListDepths(dpy, scr, &ndepths))) ndepths = 0;
+
+ dmxLogOutput(dmxScreen, "Name of display: %s\n", DisplayString(dpy));
+ dmxLogOutput(dmxScreen, "Version number: %d.%d\n",
+ ProtocolVersion(dpy), ProtocolRevision(dpy));
+ dmxLogOutput(dmxScreen, "Vendor string: %s\n", ServerVendor(dpy));
+ if (!strstr(ServerVendor(dpy), "XFree86")) {
+ dmxLogOutput(dmxScreen, "Vendor release: %d\n", VendorRelease(dpy));
+ } else {
+ /* This code based on xdpyinfo.c */
+ int v = VendorRelease(dpy);
+ int major = -1, minor = -1, patch = -1, subpatch = -1;
+
+ if (v < 336)
+ major = v / 100, minor = (v / 10) % 10, patch = v % 10;
+ else if (v < 3900) {
+ major = v / 1000;
+ minor = (v / 100) % 10;
+ if (((v / 10) % 10) || (v % 10)) {
+ patch = (v / 10) % 10;
+ if (v % 10) subpatch = v % 10;
+ }
+ } else if (v < 40000000) {
+ major = v / 1000;
+ minor = (v / 10) % 10;
+ if (v % 10) patch = v % 10;
+ } else {
+ major = v / 10000000;
+ minor = (v / 100000) % 100;
+ patch = (v / 1000) % 100;
+ if (v % 1000) subpatch = v % 1000;
+ }
+ dmxLogOutput(dmxScreen, "Vendor release: %d (XFree86 version: %d.%d",
+ v, major, minor);
+ if (patch > 0) dmxLogOutputCont(dmxScreen, ".%d", patch);
+ if (subpatch > 0) dmxLogOutputCont(dmxScreen, ".%d", subpatch);
+ dmxLogOutputCont(dmxScreen, ")\n");
+ }
+
+
+ dmxLogOutput(dmxScreen, "Dimensions: %dx%d pixels\n",
+ attribs.width, attribs.height);
+ dmxLogOutput(dmxScreen, "%d depths on screen %d: ", ndepths, scr);
+ for (i = 0; i < ndepths; i++)
+ dmxLogOutputCont(dmxScreen, "%c%d", i ? ',' : ' ', depths[i]);
+ dmxLogOutputCont(dmxScreen, "\n");
+ dmxLogOutput(dmxScreen, "Depth of root window: %d plane%s (%d)\n",
+ attribs.depth, attribs.depth == 1 ? "" : "s",
+ DisplayPlanes(dpy, scr));
+ dmxLogOutput(dmxScreen, "Number of colormaps: %d min, %d max\n",
+ MinCmapsOfScreen(s), MaxCmapsOfScreen(s));
+ dmxLogOutput(dmxScreen, "Options: backing-store %s, save-unders %s\n",
+ (DoesBackingStore (s) == NotUseful) ? "no" :
+ ((DoesBackingStore (s) == Always) ? "yes" : "when mapped"),
+ DoesSaveUnders (s) ? "yes" : "no");
+ dmxLogOutput(dmxScreen, "Window Manager running: %s\n",
+ (dmxScreen->WMRunningOnBE) ? "yes" : "no");
+
+ if (dmxScreen->WMRunningOnBE) {
+ dmxLogOutputWarning(dmxScreen,
+ "Window manager running "
+ "-- colormaps not supported\n");
+ }
+ XFree(depths);
+}
+
+void dmxGetScreenAttribs(DMXScreenInfo *dmxScreen)
+{
+ XWindowAttributes attribs;
+ Display *dpy = dmxScreen->beDisplay;
+#ifdef GLXEXT
+ int dummy;
+#endif
+
+ XGetWindowAttributes(dpy, DefaultRootWindow(dpy), &attribs);
+
+ dmxScreen->beWidth = attribs.width;
+ dmxScreen->beHeight = attribs.height;
+
+ /* Fill in missing geometry information */
+ if (dmxScreen->scrnXSign < 0) {
+ if (dmxScreen->scrnWidth) {
+ dmxScreen->scrnX = (attribs.width - dmxScreen->scrnWidth
+ - dmxScreen->scrnX);
+ } else {
+ dmxScreen->scrnWidth = attribs.width - dmxScreen->scrnX;
+ dmxScreen->scrnX = 0;
+ }
+ }
+ if (dmxScreen->scrnYSign < 0) {
+ if (dmxScreen->scrnHeight) {
+ dmxScreen->scrnY = (attribs.height - dmxScreen->scrnHeight
+ - dmxScreen->scrnY);
+ } else {
+ dmxScreen->scrnHeight = attribs.height - dmxScreen->scrnY;
+ dmxScreen->scrnY = 0;
+ }
+ }
+ if (!dmxScreen->scrnWidth)
+ dmxScreen->scrnWidth = attribs.width - dmxScreen->scrnX;
+ if (!dmxScreen->scrnHeight)
+ dmxScreen->scrnHeight = attribs.height - dmxScreen->scrnY;
+
+ if (!dmxScreen->rootWidth) dmxScreen->rootWidth = dmxScreen->scrnWidth;
+ if (!dmxScreen->rootHeight) dmxScreen->rootHeight = dmxScreen->scrnHeight;
+ if (dmxScreen->rootWidth + dmxScreen->rootX > dmxScreen->scrnWidth)
+ dmxScreen->rootWidth = dmxScreen->scrnWidth - dmxScreen->rootX;
+ if (dmxScreen->rootHeight + dmxScreen->rootY > dmxScreen->scrnHeight)
+ dmxScreen->rootHeight = dmxScreen->scrnHeight - dmxScreen->rootY;
+
+ /* FIXME: Get these from the back-end server */
+ dmxScreen->beXDPI = 75;
+ dmxScreen->beYDPI = 75;
+
+ dmxScreen->beDepth = attribs.depth; /* FIXME: verify that this
+ * works always. In
+ * particular, this will work
+ * well for depth=16, will fail
+ * because of colormap issues
+ * at depth 8. More work needs
+ * to be done here. */
+
+ if (dmxScreen->beDepth <= 8) dmxScreen->beBPP = 8;
+ else if (dmxScreen->beDepth <= 16) dmxScreen->beBPP = 16;
+ else dmxScreen->beBPP = 32;
+
+#ifdef GLXEXT
+ /* get the majorOpcode for the back-end GLX extension */
+ XQueryExtension(dpy, "GLX", &dmxScreen->glxMajorOpcode,
+ &dummy, &dmxScreen->glxErrorBase);
+#endif
+
+ dmxPrintScreenInfo(dmxScreen);
+ dmxLogOutput(dmxScreen, "%dx%d+%d+%d on %dx%d at depth=%d, bpp=%d\n",
+ dmxScreen->scrnWidth, dmxScreen->scrnHeight,
+ dmxScreen->scrnX, dmxScreen->scrnY,
+ dmxScreen->beWidth, dmxScreen->beHeight,
+ dmxScreen->beDepth, dmxScreen->beBPP);
+ if (dmxScreen->beDepth == 8)
+ dmxLogOutputWarning(dmxScreen,
+ "Support for depth == 8 is not complete\n");
+}
+
+Bool dmxGetVisualInfo(DMXScreenInfo *dmxScreen)
+{
+ int i;
+ XVisualInfo visinfo;
+
+ visinfo.screen = DefaultScreen(dmxScreen->beDisplay);
+ dmxScreen->beVisuals = XGetVisualInfo(dmxScreen->beDisplay,
+ VisualScreenMask,
+ &visinfo,
+ &dmxScreen->beNumVisuals);
+
+ dmxScreen->beDefVisualIndex = -1;
+
+ if (defaultColorVisualClass >= 0 || dmxDepth > 0) {
+ for (i = 0; i < dmxScreen->beNumVisuals; i++)
+ if (defaultColorVisualClass >= 0) {
+ if (dmxScreen->beVisuals[i].class == defaultColorVisualClass) {
+ if (dmxDepth > 0) {
+ if (dmxScreen->beVisuals[i].depth == dmxDepth) {
+ dmxScreen->beDefVisualIndex = i;
+ break;
+ }
+ } else {
+ dmxScreen->beDefVisualIndex = i;
+ break;
+ }
+ }
+ } else if (dmxScreen->beVisuals[i].depth == dmxDepth) {
+ dmxScreen->beDefVisualIndex = i;
+ break;
+ }
+ } else {
+ visinfo.visualid =
+ XVisualIDFromVisual(DefaultVisual(dmxScreen->beDisplay,
+ visinfo.screen));
+
+ for (i = 0; i < dmxScreen->beNumVisuals; i++)
+ if (visinfo.visualid == dmxScreen->beVisuals[i].visualid) {
+ dmxScreen->beDefVisualIndex = i;
+ break;
+ }
+ }
+
+ for (i = 0; i < dmxScreen->beNumVisuals; i++)
+ dmxLogVisual(dmxScreen, &dmxScreen->beVisuals[i],
+ (i == dmxScreen->beDefVisualIndex));
+
+ return (dmxScreen->beDefVisualIndex >= 0);
+}
+
+void dmxGetColormaps(DMXScreenInfo *dmxScreen)
+{
+ int i;
+
+ dmxScreen->beNumDefColormaps = dmxScreen->beNumVisuals;
+ dmxScreen->beDefColormaps = xalloc(dmxScreen->beNumDefColormaps *
+ sizeof(*dmxScreen->beDefColormaps));
+
+ for (i = 0; i < dmxScreen->beNumDefColormaps; i++)
+ dmxScreen->beDefColormaps[i] =
+ XCreateColormap(dmxScreen->beDisplay,
+ DefaultRootWindow(dmxScreen->beDisplay),
+ dmxScreen->beVisuals[i].visual,
+ AllocNone);
+
+ dmxScreen->beBlackPixel = BlackPixel(dmxScreen->beDisplay,
+ DefaultScreen(dmxScreen->beDisplay));
+ dmxScreen->beWhitePixel = WhitePixel(dmxScreen->beDisplay,
+ DefaultScreen(dmxScreen->beDisplay));
+}
+
+void dmxGetPixmapFormats(DMXScreenInfo *dmxScreen)
+{
+ dmxScreen->beDepths =
+ XListDepths(dmxScreen->beDisplay, DefaultScreen(dmxScreen->beDisplay),
+ &dmxScreen->beNumDepths);
+
+ dmxScreen->bePixmapFormats =
+ XListPixmapFormats(dmxScreen->beDisplay,
+ &dmxScreen->beNumPixmapFormats);
+}
+
+static Bool dmxSetPixmapFormats(ScreenInfo *pScreenInfo,
+ DMXScreenInfo *dmxScreen)
+{
+ XPixmapFormatValues *bePixmapFormat;
+ PixmapFormatRec *format;
+ int i, j;
+
+ pScreenInfo->imageByteOrder = ImageByteOrder(dmxScreen->beDisplay);
+ pScreenInfo->bitmapScanlineUnit = BitmapUnit(dmxScreen->beDisplay);
+ pScreenInfo->bitmapScanlinePad = BitmapPad(dmxScreen->beDisplay);
+ pScreenInfo->bitmapBitOrder = BitmapBitOrder(dmxScreen->beDisplay);
+
+ pScreenInfo->numPixmapFormats = 0;
+ for (i = 0; i < dmxScreen->beNumPixmapFormats; i++) {
+ bePixmapFormat = &dmxScreen->bePixmapFormats[i];
+ for (j = 0; j < dmxScreen->beNumDepths; j++)
+ if ((bePixmapFormat->depth == 1) ||
+ (bePixmapFormat->depth == dmxScreen->beDepths[j])) {
+ format = &pScreenInfo->formats[pScreenInfo->numPixmapFormats];
+
+ format->depth = bePixmapFormat->depth;
+ format->bitsPerPixel = bePixmapFormat->bits_per_pixel;
+ format->scanlinePad = bePixmapFormat->scanline_pad;
+
+ pScreenInfo->numPixmapFormats++;
+ break;
+ }
+ }
+
+ return TRUE;
+}
+
+void dmxCheckForWM(DMXScreenInfo *dmxScreen)
+{
+ Status status;
+ XWindowAttributes xwa;
+
+ status = XGetWindowAttributes(dmxScreen->beDisplay,
+ DefaultRootWindow(dmxScreen->beDisplay),
+ &xwa);
+ dmxScreen->WMRunningOnBE =
+ (status &&
+ ((xwa.all_event_masks & SubstructureRedirectMask) ||
+ (xwa.all_event_masks & SubstructureNotifyMask)));
+}
+
+/** Initialize the display and collect relevant information about the
+ * display properties */
+static void dmxDisplayInit(DMXScreenInfo *dmxScreen)
+{
+ if (!dmxOpenDisplay(dmxScreen))
+ dmxLog(dmxFatal,
+ "dmxOpenDisplay: Unable to open display %s\n",
+ dmxScreen->name);
+
+ dmxSetErrorHandler(dmxScreen);
+ dmxCheckForWM(dmxScreen);
+ dmxGetScreenAttribs(dmxScreen);
+
+ if (!dmxGetVisualInfo(dmxScreen))
+ dmxLog(dmxFatal, "dmxGetVisualInfo: No matching visuals found\n");
+
+ dmxGetColormaps(dmxScreen);
+ dmxGetPixmapFormats(dmxScreen);
+}
+
+/* If this doesn't compile, just add || defined(yoursystem) to the line
+ * below. This information is to help with bug reports and is not
+ * critical. */
+#if !defined(_POSIX_SOURCE)
+static const char *dmxExecOS(void) { return ""; }
+#else
+#include <sys/utsname.h>
+static const char *dmxExecOS(void)
+{
+ static char buffer[128];
+ static int initialized = 0;
+ struct utsname u;
+
+ if (!initialized++) {
+ memset(buffer, 0, sizeof(buffer));
+ uname(&u);
+ XmuSnprintf(buffer, sizeof(buffer)-1, "%s %s %s",
+ u.sysname, u.release, u.version);
+ }
+ return buffer;
+}
+#endif
+
+static const char *dmxBuildCompiler(void)
+{
+ static char buffer[128];
+ static int initialized = 0;
+
+ if (!initialized++) {
+ memset(buffer, 0, sizeof(buffer));
+#if defined(__GNUC__) && defined(__GNUC_MINOR__) &&defined(__GNUC_PATCHLEVEL__)
+ XmuSnprintf(buffer, sizeof(buffer)-1, "gcc %d.%d.%d",
+ __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
+#endif
+ }
+ return buffer;
+}
+
+static const char *dmxExecHost(void)
+{
+ static char buffer[128];
+ static int initialized = 0;
+
+ if (!initialized++) {
+ memset(buffer, 0, sizeof(buffer));
+ XmuGetHostname(buffer, sizeof(buffer) - 1);
+ }
+ return buffer;
+}
+
+/** This routine is called in Xserver/dix/main.c from \a main(). */
+void InitOutput(ScreenInfo *pScreenInfo, int argc, char *argv[])
+{
+ int i;
+ static unsigned long dmxGeneration = 0;
+#ifdef GLXEXT
+ Bool glxSupported = TRUE;
+#endif
+
+ if (dmxGeneration != serverGeneration) {
+ int vendrel = VENDOR_RELEASE;
+ int major, minor, year, month, day;
+
+ dmxGeneration = serverGeneration;
+
+ major = vendrel / 100000000;
+ vendrel -= major * 100000000;
+ minor = vendrel / 1000000;
+ vendrel -= minor * 1000000;
+ year = vendrel / 10000;
+ vendrel -= year * 10000;
+ month = vendrel / 100;
+ vendrel -= month * 100;
+ day = vendrel;
+
+ /* Add other epoch tests here */
+ if (major > 0 && minor > 0) year += 2000;
+
+ dmxLog(dmxInfo, "Generation: %d\n", dmxGeneration);
+ dmxLog(dmxInfo, "DMX version: %d.%d.%02d%02d%02d (%s)\n",
+ major, minor, year, month, day, VENDOR_STRING);
+
+ SetVendorRelease(VENDOR_RELEASE);
+ SetVendorString(VENDOR_STRING);
+
+ if (dmxGeneration == 1) {
+ dmxLog(dmxInfo, "DMX Build OS: %s (%s)\n", OSNAME, OSVENDOR);
+ dmxLog(dmxInfo, "DMX Build Compiler: %s\n", dmxBuildCompiler());
+ dmxLog(dmxInfo, "DMX Execution OS: %s\n", dmxExecOS());
+ dmxLog(dmxInfo, "DMX Execution Host: %s\n", dmxExecHost());
+ }
+ dmxLog(dmxInfo, "MAXSCREENS: %d\n", MAXSCREENS);
+
+ for (i = 0; i < dmxNumScreens; i++) {
+ if (dmxScreens[i].beDisplay)
+ dmxLog(dmxWarning, "Display \"%s\" still open\n",
+ dmxScreens[i].name);
+ dmxStatFree(dmxScreens[i].stat);
+ dmxScreens[i].stat = NULL;
+ }
+ for (i = 0; i < dmxNumInputs; i++) dmxInputFree(&dmxInputs[i]);
+ if (dmxScreens) free(dmxScreens);
+ if (dmxInputs) free(dmxInputs);
+ dmxScreens = NULL;
+ dmxInputs = NULL;
+ dmxNumScreens = 0;
+ dmxNumInputs = 0;
+ }
+
+ /* Make sure that the command-line arguments are sane. */
+ if (dmxAddRemoveScreens && dmxGLXProxy) {
+ /* Currently it is not possible to support GLX and Render
+ * extensions with dynamic screen addition/removal due to the
+ * state that each extension keeps, which cannot be restored. */
+ dmxLog(dmxWarning,
+ "GLX Proxy and Render extensions do not yet support dynamic\n");
+ dmxLog(dmxWarning,
+ "screen addition and removal. Please specify -noglxproxy\n");
+ dmxLog(dmxWarning,
+ "and -norender on the command line or in the configuration\n");
+ dmxLog(dmxWarning,
+ "file to disable these two extensions if you wish to use\n");
+ dmxLog(dmxWarning,
+ "the dynamic addition and removal of screens support.\n");
+ dmxLog(dmxFatal,
+ "Dynamic screen addition/removal error (see above).\n");
+ }
+
+ /* ddxProcessArgument has been called at this point, but any data
+ * from the configuration file has not been applied. Do so, and be
+ * sure we have at least one back-end display. */
+ dmxConfigConfigure();
+ if (!dmxNumScreens)
+ dmxLog(dmxFatal, "InitOutput: no back-end displays found\n");
+ if (!dmxNumInputs)
+ dmxLog(dmxInfo, "InitOutput: no inputs found\n");
+
+ /* Disable lazy window creation optimization if offscreen
+ * optimization is disabled */
+ if (!dmxOffScreenOpt && dmxLazyWindowCreation) {
+ dmxLog(dmxInfo,
+ "InitOutput: Disabling lazy window creation optimization\n");
+ dmxLog(dmxInfo,
+ " since it requires the offscreen optimization\n");
+ dmxLog(dmxInfo,
+ " to function properly.\n");
+ dmxLazyWindowCreation = FALSE;
+ }
+
+ /* Open each display and gather information about it. */
+ for (i = 0; i < dmxNumScreens; i++)
+ dmxDisplayInit(&dmxScreens[i]);
+
+#if PANORAMIX
+ /* Register a Xinerama callback which will run from within
+ * PanoramiXCreateConnectionBlock. We can use the callback to
+ * determine if Xinerama is loaded and to check the visuals
+ * determined by PanoramiXConsolidate. */
+ XineramaRegisterConnectionBlockCallback(dmxConnectionBlockCallback);
+#endif
+
+ /* Since we only have a single screen thus far, we only need to set
+ the pixmap formats to match that screen. FIXME: this isn't true.*/
+ if (!dmxSetPixmapFormats(pScreenInfo, &dmxScreens[0])) return;
+
+ /* Might want to install a signal handler to allow cleaning up after
+ * unexpected signals. The DIX/OS layer already handles SIGINT and
+ * SIGTERM, so everything is OK for expected signals. --DD
+ *
+ * SIGHUP, SIGINT, and SIGTERM are trapped in os/connection.c
+ * SIGQUIT is another common signal that is sent from the keyboard.
+ * Trap it here, to ensure that the keyboard modifier map and other
+ * state for the input devices are restored. (This makes the
+ * behavior of SIGQUIT somewhat unexpected, since it will be the
+ * same as the behavior of SIGINT. However, leaving the modifier
+ * map of the input devices empty is even more unexpected.) --RF
+ */
+ OsSignal(SIGQUIT, GiveUp);
+
+#ifdef GLXEXT
+ /* Check if GLX extension exists on all back-end servers */
+ for (i = 0; i < dmxNumScreens; i++)
+ glxSupported &= (dmxScreens[i].glxMajorOpcode > 0);
+#endif
+
+ /* Tell dix layer about the backend displays */
+ for (i = 0; i < dmxNumScreens; i++) {
+
+#ifdef GLXEXT
+ if (glxSupported) {
+ /*
+ * Builds GLX configurations from the list of visuals
+ * supported by the back-end server, and give that
+ * configuration list to the glx layer - so that he will
+ * build the visuals accordingly.
+ */
+
+ DMXScreenInfo *dmxScreen = &dmxScreens[i];
+ __GLXvisualConfig *configs = NULL;
+ dmxGlxVisualPrivate **configprivs = NULL;
+ int nconfigs = 0;
+ int (*oldErrorHandler)(Display *, XErrorEvent *);
+ int i;
+
+ /* Catch errors if when using an older GLX w/o FBconfigs */
+ oldErrorHandler = XSetErrorHandler(dmxNOPErrorHandler);
+
+ /* Get FBConfigs of the back-end server */
+ dmxScreen->fbconfigs = GetGLXFBConfigs(dmxScreen->beDisplay,
+ dmxScreen->glxMajorOpcode,
+ &dmxScreen->numFBConfigs);
+
+ XSetErrorHandler(oldErrorHandler);
+
+ dmxScreen->glxVisuals =
+ GetGLXVisualConfigs(dmxScreen->beDisplay,
+ DefaultScreen(dmxScreen->beDisplay),
+ &dmxScreen->numGlxVisuals);
+
+ if (dmxScreen->fbconfigs) {
+ configs =
+ GetGLXVisualConfigsFromFBConfigs(dmxScreen->fbconfigs,
+ dmxScreen->numFBConfigs,
+ dmxScreen->beVisuals,
+ dmxScreen->beNumVisuals,
+ dmxScreen->glxVisuals,
+ dmxScreen->numGlxVisuals,
+ &nconfigs);
+ } else {
+ configs = dmxScreen->glxVisuals;
+ nconfigs = dmxScreen->numGlxVisuals;
+ }
+
+ configprivs = xalloc(nconfigs * sizeof(dmxGlxVisualPrivate*));
+
+ if (configs != NULL && configprivs != NULL) {
+
+ /* Initialize our private info for each visual
+ * (currently only x_visual_depth and x_visual_class)
+ */
+ for (i = 0; i < nconfigs; i++) {
+
+ configprivs[i] = (dmxGlxVisualPrivate *)
+ xalloc(sizeof(dmxGlxVisualPrivate));
+ configprivs[i]->x_visual_depth = 0;
+ configprivs[i]->x_visual_class = 0;
+
+ /* Find the visual depth */
+ if (configs[i].vid > 0) {
+ int j;
+ for (j = 0; j < dmxScreen->beNumVisuals; j++) {
+ if (dmxScreen->beVisuals[j].visualid ==
+ configs[i].vid) {
+ configprivs[i]->x_visual_depth =
+ dmxScreen->beVisuals[j].depth;
+ configprivs[i]->x_visual_class =
+ dmxScreen->beVisuals[j].class;
+ break;
+ }
+ }
+ }
+ }
+
+ /* Hand out the glx configs to glx extension */
+ GlxSetVisualConfigs(nconfigs, configs, (void**)configprivs);
+
+ XFlush(dmxScreen->beDisplay);
+ }
+ }
+#endif /* GLXEXT */
+
+ AddScreen(dmxScreenInit, argc, argv);
+ }
+
+ /* Compute origin information. */
+ dmxInitOrigins();
+
+ /* Compute overlap information. */
+ dmxInitOverlap();
+
+ /* Make sure there is a global width/height available */
+ dmxComputeWidthHeight(DMX_NO_RECOMPUTE_BOUNDING_BOX);
+
+ /* FIXME: The following is temporarily placed here. When the DMX
+ * extension is available, it will be move there.
+ */
+ dmxInitFonts();
+
+#ifdef RENDER
+ /* Initialize the render extension */
+ if (!noRenderExtension)
+ dmxInitRender();
+#endif
+
+ /* Initialized things that need timer hooks */
+ dmxStatInit();
+ dmxSyncInit(); /* Calls RegisterBlockAndWakeupHandlers */
+
+ dmxLog(dmxInfo, "Shadow framebuffer support %s\n",
+ dmxShadowFB ? "enabled" : "disabled");
+}
+
+/* RATS: Assuming the fp string (which comes from the command-line argv
+ vector) is NULL-terminated, the buffer is large enough for the
+ strcpy. */
+static void dmxSetDefaultFontPath(char *fp)
+{
+ int fplen = strlen(fp) + 1;
+
+ if (dmxFontPath) {
+ int len;
+
+ len = strlen(dmxFontPath);
+ dmxFontPath = xrealloc(dmxFontPath, len+fplen+1);
+ dmxFontPath[len] = ',';
+ strncpy(&dmxFontPath[len+1], fp, fplen);
+ } else {
+ dmxFontPath = xalloc(fplen);
+ strncpy(dmxFontPath, fp, fplen);
+ }
+
+ defaultFontPath = dmxFontPath;
+}
+
+/** This function is called in Xserver/os/utils.c from \a AbortServer().
+ * We must ensure that backend and console state is restored in the
+ * event the server shutdown wasn't clean. */
+void AbortDDX(void)
+{
+ int i;
+
+ for (i=0; i < dmxNumScreens; i++) {
+ DMXScreenInfo *dmxScreen = &dmxScreens[i];
+
+ if (dmxScreen->beDisplay) XCloseDisplay(dmxScreen->beDisplay);
+ dmxScreen->beDisplay = NULL;
+ }
+}
+
+#ifdef DDXBEFORERESET
+/* This function is called in Xserver/dix/dispatch.c */
+void ddxBeforeReset(void)
+{
+}
+#endif
+
+/** This function is called in Xserver/dix/main.c from \a main() when
+ * dispatchException & DE_TERMINATE (which is the only way to exit the
+ * main loop without an interruption. */
+void ddxGiveUp(void)
+{
+ AbortDDX();
+}
+
+/** This function is called in Xserver/os/osinit.c from \a OsInit(). */
+void OsVendorInit(void)
+{
+}
+
+/** This function is called in Xserver/os/utils.c from \a FatalError()
+ * and \a VFatalError(). (Note that setting the function pointer \a
+ * OsVendorVErrorFProc will cause \a VErrorF() (which is called by the
+ * two routines mentioned here, as well as by others) to use the
+ * referenced routine instead of \a vfprintf().) */
+void OsVendorFatalError(void)
+{
+}
+
+/** Process our command line arguments. */
+int ddxProcessArgument(int argc, char *argv[], int i)
+{
+ int retval = 0;
+
+ if (!strcmp(argv[i], "-display")) {
+ if (++i < argc) dmxConfigStoreDisplay(argv[i]);
+ retval = 2;
+ } else if (!strcmp(argv[i], "-inputfrom") || !strcmp(argv[i], "-input")) {
+ if (++i < argc) dmxConfigStoreInput(argv[i]);
+ retval = 2;
+ } else if (!strcmp(argv[i], "-xinputfrom") || !strcmp(argv[i],"-xinput")) {
+ if (++i < argc) dmxConfigStoreXInput(argv[i]);
+ retval = 2;
+ } else if (!strcmp(argv[i], "-noshadowfb")) {
+ dmxLog(dmxWarning,
+ "-noshadowfb has been deprecated "
+ "since it is now the default\n");
+ dmxShadowFB = FALSE;
+ retval = 1;
+ } else if (!strcmp(argv[i], "-nomulticursor")) {
+ dmxCursorNoMulti();
+ retval = 1;
+ } else if (!strcmp(argv[i], "-shadowfb")) {
+ dmxShadowFB = TRUE;
+ retval = 1;
+ } else if (!strcmp(argv[i], "-configfile")) {
+ if (++i < argc) dmxConfigStoreFile(argv[i]);
+ retval = 2;
+ } else if (!strcmp(argv[i], "-config")) {
+ if (++i < argc) dmxConfigStoreConfig(argv[i]);
+ retval = 2;
+ } else if (!strcmp(argv[i], "-fontpath")) {
+ if (++i < argc) dmxSetDefaultFontPath(argv[i]);
+ retval = 2;
+ } else if (!strcmp(argv[i], "-stat")) {
+ if ((i += 2) < argc) dmxStatActivate(argv[i-1], argv[i]);
+ retval = 3;
+ } else if (!strcmp(argv[i], "-syncbatch")) {
+ if (++i < argc) dmxSyncActivate(argv[i]);
+ retval = 2;
+ } else if (!strcmp(argv[i], "-nooffscreenopt")) {
+ dmxOffScreenOpt = FALSE;
+ retval = 1;
+ } else if (!strcmp(argv[i], "-nosubdivprims")) {
+ dmxSubdividePrimitives = FALSE;
+ retval = 1;
+ } else if (!strcmp(argv[i], "-nowindowopt")) {
+ dmxLazyWindowCreation = FALSE;
+ retval = 1;
+ } else if (!strcmp(argv[i], "-noxkb")) {
+ dmxUseXKB = FALSE;
+ retval = 1;
+ } else if (!strcmp(argv[i], "-depth")) {
+ if (++i < argc) dmxDepth = atoi(argv[i]);
+ retval = 2;
+ } else if (!strcmp(argv[i], "-norender")) {
+ noRenderExtension = TRUE;
+ retval = 1;
+#ifdef GLXEXT
+ } else if (!strcmp(argv[i], "-noglxproxy")) {
+ dmxGLXProxy = FALSE;
+ retval = 1;
+ } else if (!strcmp(argv[i], "-noglxswapgroup")) {
+ dmxGLXSwapGroupSupport = FALSE;
+ retval = 1;
+ } else if (!strcmp(argv[i], "-glxsyncswap")) {
+ dmxGLXSyncSwap = TRUE;
+ retval = 1;
+ } else if (!strcmp(argv[i], "-glxfinishswap")) {
+ dmxGLXFinishSwap = TRUE;
+ retval = 1;
+#endif
+ } else if (!strcmp(argv[i], "-ignorebadfontpaths")) {
+ dmxIgnoreBadFontPaths = TRUE;
+ retval = 1;
+ } else if (!strcmp(argv[i], "-addremovescreens")) {
+ dmxAddRemoveScreens = TRUE;
+ retval = 1;
+ } else if (!strcmp(argv[i], "-param")) {
+ if ((i += 2) < argc) {
+ if (!strcasecmp(argv[i-1], "xkbrules"))
+ dmxConfigSetXkbRules(argv[i]);
+ else if (!strcasecmp(argv[i-1], "xkbmodel"))
+ dmxConfigSetXkbModel(argv[i]);
+ else if (!strcasecmp(argv[i-1], "xkblayout"))
+ dmxConfigSetXkbLayout(argv[i]);
+ else if (!strcasecmp(argv[i-1], "xkbvariant"))
+ dmxConfigSetXkbVariant(argv[i]);
+ else if (!strcasecmp(argv[i-1], "xkboptions"))
+ dmxConfigSetXkbOptions(argv[i]);
+ else
+ dmxLog(dmxWarning,
+ "-param requires: XkbRules, XkbModel, XkbLayout,"
+ " XkbVariant, or XkbOptions\n");
+ }
+ retval = 3;
+ }
+ if (!serverGeneration) dmxConfigSetMaxScreens();
+ return retval;
+}
+
+/** Provide succinct usage information for the DMX server. */
+void ddxUseMsg(void)
+{
+ ErrorF("\n\nDevice Dependent Usage:\n");
+ ErrorF("-display string Specify the back-end display(s)\n");
+ ErrorF("-input string Specify input source for core device\n");
+ ErrorF("-xinput string Specify input source for XInput device\n");
+ ErrorF("-shadowfb Enable shadow frame buffer\n");
+ ErrorF("-configfile file Read from a configuration file\n");
+ ErrorF("-config config Select a specific configuration\n");
+ ErrorF("-nomulticursor Turn of multiple cursor support\n");
+ ErrorF("-fontpath Sets the default font path\n");
+ ErrorF("-stat inter scrns Print out performance statistics\n");
+ ErrorF("-syncbatch inter Set interval for XSync batching\n");
+ ErrorF("-nooffscreenopt Disable offscreen optimization\n");
+ ErrorF("-nosubdivprims Disable primitive subdivision\n");
+ ErrorF(" optimization\n");
+ ErrorF("-nowindowopt Disable lazy window creation optimization\n");
+ ErrorF("-noxkb Disable use of the XKB extension with\n");
+ ErrorF(" backend displays (cf. -kb).\n");
+ ErrorF("-depth Specify the default root window depth\n");
+ ErrorF("-norender Disable RENDER extension support\n");
+#ifdef GLXEXT
+ ErrorF("-noglxproxy Disable GLX Proxy\n");
+ ErrorF("-noglxswapgroup Disable swap group and swap barrier\n");
+ ErrorF(" extensions in GLX proxy\n");
+ ErrorF("-glxsyncswap Force XSync after swap buffers\n");
+ ErrorF("-glxfinishswap Force glFinish after swap buffers\n");
+#endif
+ ErrorF("-ignorebadfontpaths Ignore bad font paths during initialization\n");
+ ErrorF("-addremovescreens Enable dynamic screen addition/removal\n");
+ ErrorF("-param ... Specify configuration parameters (e.g.,\n");
+ ErrorF(" XkbRules, XkbModel, XkbLayout, etc.)\n");
+ ErrorF("\n");
+ ErrorF(" If the -input string matches a -display string, then input\n"
+ " is taken from that backend display. (XInput cannot be taken\n"
+ " from a backend display.) Placing \",console\" after the\n"
+ " display name will force a console window to be opened on\n"
+ " that display in addition to the backend input. This is\n"
+ " useful if the backend window does not cover the whole\n"
+ " physical display.\n\n");
+
+ ErrorF(" Otherwise, if the -input or -xinput string specifies another\n"
+ " X display, then a console window will be created on that\n"
+ " display. Placing \",windows\" or \",nowindows\" after the\n"
+ " display name will control the display of window outlines in\n"
+ " the console.\n\n");
+
+ ErrorF(" -input or -xinput dummy specifies no input.\n");
+ ErrorF(" -input or -xinput local specifies the use of a raw keyboard,\n"
+ " mouse, or other (extension) device:\n"
+ " -input local,kbd,ps2 will use a ps2 mouse\n"
+ " -input local,kbd,ms will use a serial mouse\n"
+ " -input local,usb-kbd,usb-mou will use USB devices \n"
+ " -xinput local,usb-oth will use a non-mouse and\n"
+ " non-keyboard USB device with XInput\n\n");
+
+ ErrorF(" Special Keys:\n");
+ ErrorF(" Ctrl-Alt-g Server grab/ungrab (console only)\n");
+ ErrorF(" Ctrl-Alt-f Fine (1-pixel) mouse mode (console only)\n");
+ ErrorF(" Ctrl-Alt-q Quit (core devices only)\n");
+ ErrorF(" Ctrl-Alt-F* Switch to VC (local only)\n");
+}
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.c b/xorg-server/hw/kdrive/ephyr/ephyr.c index b21559bba..6e61b8c5d 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyr.c +++ b/xorg-server/hw/kdrive/ephyr/ephyr.c @@ -1,1179 +1,1190 @@ -/* - * Xephyr - A kdrive X server thats runs in a host X window. - * Authored by Matthew Allum <mallum@openedhand.com> - * - * Copyright © 2004 Nokia - * - * 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 Nokia not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Nokia makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL NOKIA 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_CONFIG_H -#include <kdrive-config.h> -#endif -#include "ephyr.h" - -#include "inputstr.h" -#include "scrnintstr.h" -#include "ephyrlog.h" - -#ifdef XF86DRI -#include "ephyrdri.h" -#include "ephyrdriext.h" -#include "ephyrglxext.h" -#endif /* XF86DRI */ - -extern int KdTsPhyScreen; -#ifdef GLXEXT -extern Bool noGlxVisualInit; -#endif - -KdKeyboardInfo *ephyrKbd; -KdPointerInfo *ephyrMouse; -EphyrKeySyms ephyrKeySyms; -Bool ephyrNoDRI=FALSE ; -Bool ephyrNoXV=FALSE ; - -static int mouseState = 0; - -typedef struct _EphyrInputPrivate { - Bool enabled; -} EphyrKbdPrivate, EphyrPointerPrivate; - -Bool EphyrWantGrayScale = 0; - - -Bool -ephyrInitialize (KdCardInfo *card, EphyrPriv *priv) -{ - OsSignal(SIGUSR1, hostx_handle_signal); - - priv->base = 0; - priv->bytes_per_line = 0; - return TRUE; -} - -Bool -ephyrCardInit (KdCardInfo *card) -{ - EphyrPriv *priv; - - priv = (EphyrPriv *) xalloc (sizeof (EphyrPriv)); - if (!priv) - return FALSE; - - if (!ephyrInitialize (card, priv)) - { - xfree (priv); - return FALSE; - } - card->driver = priv; - - return TRUE; -} - -Bool -ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv) -{ - int width = 640, height = 480; - CARD32 redMask, greenMask, blueMask; - - if (hostx_want_screen_size(screen, &width, &height) - || !screen->width || !screen->height) - { - screen->width = width; - screen->height = height; - } - - if (EphyrWantGrayScale) - screen->fb.depth = 8; - - if (screen->fb.depth && screen->fb.depth != hostx_get_depth()) - { - if (screen->fb.depth < hostx_get_depth() - && (screen->fb.depth == 24 || screen->fb.depth == 16 - || screen->fb.depth == 8)) - { - hostx_set_server_depth(screen, screen->fb.depth); - } - else - ErrorF("\nXephyr: requested screen depth not supported, setting to match hosts.\n"); - } - - screen->fb.depth = hostx_get_server_depth(screen); - screen->rate = 72; - - if (screen->fb.depth <= 8) - { - if (EphyrWantGrayScale) - screen->fb.visuals = ((1 << StaticGray) | (1 << GrayScale)); - else - screen->fb.visuals = ((1 << StaticGray) | - (1 << GrayScale) | - (1 << StaticColor) | - (1 << PseudoColor) | - (1 << TrueColor) | - (1 << DirectColor)); - - screen->fb.redMask = 0x00; - screen->fb.greenMask = 0x00; - screen->fb.blueMask = 0x00; - screen->fb.depth = 8; - screen->fb.bitsPerPixel = 8; - } - else - { - screen->fb.visuals = (1 << TrueColor); - - if (screen->fb.depth <= 15) - { - screen->fb.depth = 15; - screen->fb.bitsPerPixel = 16; - } - else if (screen->fb.depth <= 16) - { - screen->fb.depth = 16; - screen->fb.bitsPerPixel = 16; - } - else if (screen->fb.depth <= 24) - { - screen->fb.depth = 24; - screen->fb.bitsPerPixel = 32; - } - else if (screen->fb.depth <= 30) - { - screen->fb.depth = 30; - screen->fb.bitsPerPixel = 32; - } - else - { - ErrorF("\nXephyr: Unsupported screen depth %d\n", - screen->fb.depth); - return FALSE; - } - - hostx_get_visual_masks (screen, &redMask, &greenMask, &blueMask); - - screen->fb.redMask = (Pixel) redMask; - screen->fb.greenMask = (Pixel) greenMask; - screen->fb.blueMask = (Pixel) blueMask; - - } - - scrpriv->randr = screen->randr; - - return ephyrMapFramebuffer (screen); -} - -Bool -ephyrScreenInit (KdScreenInfo *screen) -{ - EphyrScrPriv *scrpriv; - - scrpriv = xcalloc (1, sizeof (EphyrScrPriv)); - - if (!scrpriv) - return FALSE; - - screen->driver = scrpriv; - - if (!ephyrScreenInitialize (screen, scrpriv)) - { - screen->driver = 0; - xfree (scrpriv); - return FALSE; - } - - return TRUE; -} - -void* -ephyrWindowLinear (ScreenPtr pScreen, - CARD32 row, - CARD32 offset, - int mode, - CARD32 *size, - void *closure) -{ - KdScreenPriv(pScreen); - EphyrPriv *priv = pScreenPriv->card->driver; - - if (!pScreenPriv->enabled) - return 0; - - *size = priv->bytes_per_line; - return priv->base + row * priv->bytes_per_line + offset; -} - -/** - * Figure out display buffer size. If fakexa is enabled, allocate a larger - * buffer so that fakexa has space to put offscreen pixmaps. - */ -int -ephyrBufferHeight(KdScreenInfo *screen) -{ - int buffer_height; - if (ephyrFuncs.initAccel == NULL) - buffer_height = screen->height; - else - buffer_height = 3 * screen->height; - return buffer_height; -} - - -Bool -ephyrMapFramebuffer (KdScreenInfo *screen) -{ - EphyrScrPriv *scrpriv = screen->driver; - EphyrPriv *priv = screen->card->driver; - KdPointerMatrix m; - int buffer_height; - - EPHYR_LOG("screen->width: %d, screen->height: %d index=%d", - screen->width, screen->height, screen->mynum); - - KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height); - KdSetPointerMatrix (&m); - - priv->bytes_per_line = ((screen->width * screen->fb.bitsPerPixel + 31) >> 5) << 2; - - buffer_height = ephyrBufferHeight(screen); - - priv->base = hostx_screen_init (screen, screen->width, screen->height, buffer_height); - - if ((scrpriv->randr & RR_Rotate_0) && !(scrpriv->randr & RR_Reflect_All)) - { - scrpriv->shadow = FALSE; - - screen->fb.byteStride = priv->bytes_per_line; - screen->fb.pixelStride = screen->width; - screen->fb.frameBuffer = (CARD8 *) (priv->base); - } - else - { - /* Rotated/Reflected so we need to use shadow fb */ - scrpriv->shadow = TRUE; - - EPHYR_LOG("allocing shadow"); - - KdShadowFbAlloc (screen, - scrpriv->randr & (RR_Rotate_90|RR_Rotate_270)); - } - - return TRUE; -} - -void -ephyrSetScreenSizes (ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - - if (scrpriv->randr & (RR_Rotate_0|RR_Rotate_180)) - { - pScreen->width = screen->width; - pScreen->height = screen->height; - pScreen->mmWidth = screen->width_mm; - pScreen->mmHeight = screen->height_mm; - } - else - { - pScreen->width = screen->height; - pScreen->height = screen->width; - pScreen->mmWidth = screen->height_mm; - pScreen->mmHeight = screen->width_mm; - } -} - -Bool -ephyrUnmapFramebuffer (KdScreenInfo *screen) -{ - EphyrScrPriv *scrpriv = screen->driver; - - if (scrpriv->shadow) - KdShadowFbFree (screen); - - /* Note, priv->base will get freed when XImage recreated */ - - return TRUE; -} - -void -ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - - EPHYR_LOG("slow paint"); - - /* FIXME: Slow Rotated/Reflected updates could be much - * much faster efficiently updating via tranforming - * pBuf->pDamage regions - */ - shadowUpdateRotatePacked(pScreen, pBuf); - hostx_paint_rect(screen, 0,0,0,0, screen->width, screen->height); -} - -static void -ephyrInternalDamageRedisplay (ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - RegionPtr pRegion; - - if (!scrpriv || !scrpriv->pDamage) - return; - - pRegion = DamageRegion (scrpriv->pDamage); - - if (REGION_NOTEMPTY (pScreen, pRegion)) - { - int nbox; - BoxPtr pbox; - - nbox = REGION_NUM_RECTS (pRegion); - pbox = REGION_RECTS (pRegion); - - while (nbox--) - { - hostx_paint_rect(screen, - pbox->x1, pbox->y1, - pbox->x1, pbox->y1, - pbox->x2 - pbox->x1, - pbox->y2 - pbox->y1); - pbox++; - } - DamageEmpty (scrpriv->pDamage); - } -} - -static void -ephyrInternalDamageBlockHandler (pointer data, - OSTimePtr pTimeout, - pointer pRead) -{ - ScreenPtr pScreen = (ScreenPtr) data; - - ephyrInternalDamageRedisplay (pScreen); -} - -static void -ephyrInternalDamageWakeupHandler (pointer data, int i, pointer LastSelectMask) -{ - /* FIXME: Not needed ? */ -} - -Bool -ephyrSetInternalDamage (ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - PixmapPtr pPixmap = NULL; - - scrpriv->pDamage = DamageCreate ((DamageReportFunc) 0, - (DamageDestroyFunc) 0, - DamageReportNone, - TRUE, - pScreen, - pScreen); - - if (!RegisterBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler, - ephyrInternalDamageWakeupHandler, - (pointer) pScreen)) - return FALSE; - - pPixmap = (*pScreen->GetScreenPixmap) (pScreen); - - DamageRegister (&pPixmap->drawable, scrpriv->pDamage); - - return TRUE; -} - -void -ephyrUnsetInternalDamage (ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - PixmapPtr pPixmap = NULL; - - pPixmap = (*pScreen->GetScreenPixmap) (pScreen); - DamageUnregister (&pPixmap->drawable, scrpriv->pDamage); - DamageDestroy (scrpriv->pDamage); - - RemoveBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler, - ephyrInternalDamageWakeupHandler, - (pointer) pScreen); -} - -#ifdef RANDR -Bool -ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - RRScreenSizePtr pSize; - Rotation randr; - int n = 0; - - struct { int width, height; } sizes[] = - { - { 1600, 1200 }, - { 1400, 1050 }, - { 1280, 960 }, - { 1280, 1024 }, - { 1152, 864 }, - { 1024, 768 }, - { 832, 624 }, - { 800, 600 }, - { 720, 400 }, - { 480, 640 }, - { 640, 480 }, - { 640, 400 }, - { 320, 240 }, - { 240, 320 }, - { 160, 160 }, - { 0, 0 } - }; - - EPHYR_LOG("mark"); - - *rotations = RR_Rotate_All|RR_Reflect_All; - - if (!hostx_want_preexisting_window (screen) - && !hostx_want_fullscreen ()) /* only if no -parent switch */ - { - while (sizes[n].width != 0 && sizes[n].height != 0) - { - RRRegisterSize (pScreen, - sizes[n].width, - sizes[n].height, - (sizes[n].width * screen->width_mm)/screen->width, - (sizes[n].height *screen->height_mm)/screen->height - ); - n++; - } - } - - pSize = RRRegisterSize (pScreen, - screen->width, - screen->height, - screen->width_mm, - screen->height_mm); - - randr = KdSubRotation (scrpriv->randr, screen->randr); - - RRSetCurrentConfig (pScreen, randr, 0, pSize); - - return TRUE; -} - -Bool -ephyrRandRSetConfig (ScreenPtr pScreen, - Rotation randr, - int rate, - RRScreenSizePtr pSize) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - Bool wasEnabled = pScreenPriv->enabled; - EphyrScrPriv oldscr; - int oldwidth, oldheight, oldmmwidth, oldmmheight; - Bool oldshadow; - int newwidth, newheight; - - if (screen->randr & (RR_Rotate_0|RR_Rotate_180)) - { - newwidth = pSize->width; - newheight = pSize->height; - } - else - { - newwidth = pSize->height; - newheight = pSize->width; - } - - if (wasEnabled) - KdDisableScreen (pScreen); - - oldscr = *scrpriv; - - oldwidth = screen->width; - oldheight = screen->height; - oldmmwidth = pScreen->mmWidth; - oldmmheight = pScreen->mmHeight; - oldshadow = scrpriv->shadow; - - /* - * Set new configuration - */ - - scrpriv->randr = KdAddRotation (screen->randr, randr); - - ephyrUnmapFramebuffer (screen); - - screen->width = newwidth; - screen->height = newheight; - - if (!ephyrMapFramebuffer (screen)) - goto bail4; - - /* FIXME below should go in own call */ - - if (oldshadow) - KdShadowUnset (screen->pScreen); - else - ephyrUnsetInternalDamage(screen->pScreen); - - if (scrpriv->shadow) - { - if (!KdShadowSet (screen->pScreen, - scrpriv->randr, - ephyrShadowUpdate, - ephyrWindowLinear)) - goto bail4; - } - else - { - /* Without shadow fb ( non rotated ) we need - * to use damage to efficiently update display - * via signal regions what to copy from 'fb'. - */ - if (!ephyrSetInternalDamage(screen->pScreen)) - goto bail4; - } - - ephyrSetScreenSizes (screen->pScreen); - - /* - * Set frame buffer mapping - */ - (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen), - pScreen->width, - pScreen->height, - screen->fb.depth, - screen->fb.bitsPerPixel, - screen->fb.byteStride, - screen->fb.frameBuffer); - - /* set the subpixel order */ - - KdSetSubpixelOrder (pScreen, scrpriv->randr); - - if (wasEnabled) - KdEnableScreen (pScreen); - - return TRUE; - - bail4: - EPHYR_LOG("bailed"); - - ephyrUnmapFramebuffer (screen); - *scrpriv = oldscr; - (void) ephyrMapFramebuffer (screen); - - pScreen->width = oldwidth; - pScreen->height = oldheight; - pScreen->mmWidth = oldmmwidth; - pScreen->mmHeight = oldmmheight; - - if (wasEnabled) - KdEnableScreen (pScreen); - return FALSE; -} - -Bool -ephyrRandRInit (ScreenPtr pScreen) -{ - rrScrPrivPtr pScrPriv; - - if (!RRScreenInit (pScreen)) - return FALSE; - - pScrPriv = rrGetScrPriv(pScreen); - pScrPriv->rrGetInfo = ephyrRandRGetInfo; - pScrPriv->rrSetConfig = ephyrRandRSetConfig; - return TRUE; -} -#endif - -Bool -ephyrCreateColormap (ColormapPtr pmap) -{ - return fbInitializeColormap (pmap); -} - -Bool -ephyrInitScreen (ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - - EPHYR_LOG ("pScreen->myNum:%d\n", pScreen->myNum) ; - hostx_set_screen_number (screen, pScreen->myNum); - hostx_set_win_title (screen, "(ctrl+shift grabs mouse and keyboard)") ; - pScreen->CreateColormap = ephyrCreateColormap; - -#ifdef XV - if (!ephyrNoXV) { - if (!ephyrInitVideo (pScreen)) { - EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ; - } else { - EPHYR_LOG ("initialized xvideo okay\n") ; - } - } -#endif /*XV*/ - -#ifdef XF86DRI - if (!ephyrNoDRI && !hostx_has_dri ()) { - EPHYR_LOG ("host x does not support DRI. Disabling DRI forwarding\n") ; - ephyrNoDRI = TRUE ; -#ifdef GLXEXT - noGlxVisualInit = FALSE ; -#endif - } - if (!ephyrNoDRI) { - ephyrDRIExtensionInit (pScreen) ; - ephyrHijackGLXExtension () ; - } -#endif - -#ifdef GLXEXT - if (ephyrNoDRI) { - noGlxVisualInit = FALSE ; - } -#endif - - return TRUE; -} - -Bool -ephyrFinishInitScreen (ScreenPtr pScreen) -{ - /* FIXME: Calling this even if not using shadow. - * Seems harmless enough. But may be safer elsewhere. - */ - if (!shadowSetup (pScreen)) - return FALSE; - -#ifdef RANDR - if (!ephyrRandRInit (pScreen)) - return FALSE; -#endif - - return TRUE; -} - -Bool -ephyrCreateResources (ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - EphyrScrPriv *scrpriv = screen->driver; - - EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d", - pScreen, pScreen->myNum, scrpriv->shadow); - - if (scrpriv->shadow) - return KdShadowSet (pScreen, - scrpriv->randr, - ephyrShadowUpdate, - ephyrWindowLinear); - else - return ephyrSetInternalDamage(pScreen); -} - -void -ephyrPreserve (KdCardInfo *card) -{ -} - -Bool -ephyrEnable (ScreenPtr pScreen) -{ - return TRUE; -} - -Bool -ephyrDPMS (ScreenPtr pScreen, int mode) -{ - return TRUE; -} - -void -ephyrDisable (ScreenPtr pScreen) -{ -} - -void -ephyrRestore (KdCardInfo *card) -{ -} - -void -ephyrScreenFini (KdScreenInfo *screen) -{ - EphyrScrPriv *scrpriv = screen->driver; - if (scrpriv->shadow) { - KdShadowFbFree (screen); - } - xfree(screen->driver); - screen->driver = NULL; -} - -/* - * Port of Mark McLoughlin's Xnest fix for focus in + modifier bug. - * See https://bugs.freedesktop.org/show_bug.cgi?id=3030 - */ -void -ephyrUpdateModifierState(unsigned int state) -{ -#if 0 - DeviceIntPtr pkeydev; - KeyClassPtr keyc; - int i; - CARD8 mask; - - pkeydev = inputInfo.keyboard; - - if (!pkeydev) - return; - -/* This is pretty broken. - * - * What should happen is that focus out should do as a VT switch does in - * traditional servers: fake releases for all keys (and buttons too, come - * to think of it) currently down. Then, on focus in, get the state from - * the host, and fake keypresses for everything currently down. - * - * So I'm leaving this broken for a little while. Sorry, folks. - * - * -daniels - */ - - keyc = pkeydev->key; - - state = state & 0xff; - - if (keyc->state == state) - return; - - for (i = 0, mask = 1; i < 8; i++, mask <<= 1) - { - int key; - - /* Modifier is down, but shouldn't be */ - if ((keyc->state & mask) && !(state & mask)) - { - int count = keyc->modifierKeyCount[i]; - - for (key = 0; key < MAP_LENGTH; key++) - if (keyc->xkbInfo->desc->map->modmap[key] & mask) - { - int bit; - BYTE *kptr; - - kptr = &keyc->down[key >> 3]; - bit = 1 << (key & 7); - - if (*kptr & bit && ephyrKbd && - ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled) - KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); /* release */ - - if (--count == 0) - break; - } - } - - /* Modifier shoud be down, but isn't */ - if (!(keyc->state & mask) && (state & mask)) - for (key = 0; key < MAP_LENGTH; key++) - if (keyc->xkbInfo->desc->map->modmap[key] & mask) - { - if (keyc->xkbInfo->desc->map->modmap[key] & mask && ephyrKbd && - ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled) - KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); /* press */ - break; - } - } -#endif -} - -static void -ephyrBlockSigio (void) -{ - sigset_t set; - - sigemptyset (&set); - sigaddset (&set, SIGIO); - sigprocmask (SIG_BLOCK, &set, 0); -} - -static void -ephyrUnblockSigio (void) -{ - sigset_t set; - - sigemptyset (&set); - sigaddset (&set, SIGIO); - sigprocmask (SIG_UNBLOCK, &set, 0); -} - -static Bool -ephyrCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) -{ - return FALSE; -} - -static void -ephyrCrossScreen (ScreenPtr pScreen, Bool entering) -{ -} - -int ephyrCurScreen; /*current event screen*/ - -static void -ephyrWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) -{ - ephyrBlockSigio (); - ephyrCurScreen = pScreen->myNum; - miPointerWarpCursor (inputInfo.pointer, pScreen, x, y); - ephyrUnblockSigio (); -} - -miPointerScreenFuncRec ephyrPointerScreenFuncs = -{ - ephyrCursorOffScreen, - ephyrCrossScreen, - ephyrWarpCursor, - NULL, - NULL -}; - -#ifdef XF86DRI -/** - * find if the remote window denoted by a_remote - * is paired with an internal Window within the Xephyr server. - * If the remove window is paired with an internal window, send an - * expose event to the client insterested in the internal window expose event. - * - * Pairing happens when a drawable inside Xephyr is associated with - * a GL surface in a DRI environment. - * Look at the function ProcXF86DRICreateDrawable in ephyrdriext.c to - * know a paired window is created. - * - * This is useful to make GL drawables (only windows for now) handle - * expose events and send those events to clients. - */ -static void -ephyrExposePairedWindow (int a_remote) -{ - EphyrWindowPair *pair = NULL; - RegionRec reg; - ScreenPtr screen; - - if (!findWindowPairFromRemote (a_remote, &pair)) { - EPHYR_LOG ("did not find a pair for this window\n"); - return; - } - screen = pair->local->drawable.pScreen; - REGION_NULL (screen, ®); - REGION_COPY (screen, ®, &pair->local->clipList); - screen->WindowExposures (pair->local, ®, NullRegion); - REGION_UNINIT (screen, ®); -} -#endif /* XF86DRI */ - -void -ephyrPoll(void) -{ - EphyrHostXEvent ev; - - while (hostx_get_event(&ev)) - { - switch (ev.type) - { - case EPHYR_EV_MOUSE_MOTION: - if (!ephyrMouse || - !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) { - EPHYR_LOG ("skipping mouse motion:%d\n", ephyrCurScreen) ; - continue; - } - { - if (ev.data.mouse_motion.screen >=0 - && (ephyrCurScreen != ev.data.mouse_motion.screen)) - { - EPHYR_LOG ("warping mouse cursor. " - "cur_screen%d, motion_screen:%d\n", - ephyrCurScreen, ev.data.mouse_motion.screen) ; - if (ev.data.mouse_motion.screen >= 0) - { - ephyrWarpCursor - (inputInfo.pointer, screenInfo.screens[ev.data.mouse_motion.screen], - ev.data.mouse_motion.x, - ev.data.mouse_motion.y ); - } - } - else - { - int x=0, y=0; -#ifdef XF86DRI - EphyrWindowPair *pair = NULL; -#endif - EPHYR_LOG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ; - x = ev.data.mouse_motion.x; - y = ev.data.mouse_motion.y; - EPHYR_LOG ("initial (x,y):(%d,%d)\n", x, y) ; -#ifdef XF86DRI - EPHYR_LOG ("is this window peered by a gl drawable ?\n") ; - if (findWindowPairFromRemote (ev.data.mouse_motion.window, - &pair)) - { - EPHYR_LOG ("yes, it is peered\n") ; - x += pair->local->drawable.x; - y += pair->local->drawable.y; - } - else - { - EPHYR_LOG ("no, it is not peered\n") ; - } - EPHYR_LOG ("final (x,y):(%d,%d)\n", x, y) ; -#endif - KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 0); - } - } - break; - - case EPHYR_EV_MOUSE_PRESS: - if (!ephyrMouse || - !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) { - EPHYR_LOG ("skipping mouse press:%d\n", ephyrCurScreen) ; - continue; - } - EPHYR_LOG ("enqueuing mouse press:%d\n", ephyrCurScreen) ; - ephyrUpdateModifierState(ev.key_state); - mouseState |= ev.data.mouse_down.button_num; - KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0); - break; - - case EPHYR_EV_MOUSE_RELEASE: - if (!ephyrMouse || - !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) - continue; - ephyrUpdateModifierState(ev.key_state); - mouseState &= ~ev.data.mouse_up.button_num; - EPHYR_LOG ("enqueuing mouse release:%d\n", ephyrCurScreen) ; - KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0); - break; - - case EPHYR_EV_KEY_PRESS: - if (!ephyrKbd || - !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled) - continue; - ephyrUpdateModifierState(ev.key_state); - KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_down.scancode, FALSE); - break; - - case EPHYR_EV_KEY_RELEASE: - if (!ephyrKbd || - !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled) - continue; - KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE); - break; - -#ifdef XF86DRI - case EPHYR_EV_EXPOSE: - /* - * We only receive expose events when the expose event have - * be generated for a drawable that is a host X window managed - * by Xephyr. Host X windows managed by Xephyr exists for instance - * when Xephyr is asked to create a GL drawable in a DRI environment. - */ - ephyrExposePairedWindow (ev.data.expose.window); - break; -#endif /* XF86DRI */ - - default: - break; - } - } -} - -void -ephyrCardFini (KdCardInfo *card) -{ - EphyrPriv *priv = card->driver; - xfree (priv); -} - -void -ephyrGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs) -{ - /* XXX Not sure if this is right */ - - EPHYR_LOG("mark"); - - while (n--) - { - pdefs->red = 0; - pdefs->green = 0; - pdefs->blue = 0; - pdefs++; - } - -} - -void -ephyrPutColors (ScreenPtr pScreen, int n, xColorItem *pdefs) -{ - int min, max, p; - - /* XXX Not sure if this is right */ - - min = 256; - max = 0; - - while (n--) - { - p = pdefs->pixel; - if (p < min) - min = p; - if (p > max) - max = p; - - hostx_set_cmap_entry(p, - pdefs->red >> 8, - pdefs->green >> 8, - pdefs->blue >> 8); - pdefs++; - } -} - -/* Mouse calls */ - -static Status -MouseInit (KdPointerInfo *pi) -{ - pi->driverPrivate = (EphyrPointerPrivate *) - xcalloc(sizeof(EphyrPointerPrivate), 1); - ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE; - pi->nAxes = 3; - pi->nButtons = 32; - xfree(pi->name); - pi->name = strdup("Xephyr virtual mouse"); - ephyrMouse = pi; - return Success; -} - -static Status -MouseEnable (KdPointerInfo *pi) -{ - ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = TRUE; - return Success; -} - -static void -MouseDisable (KdPointerInfo *pi) -{ - ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE; - return; -} - -static void -MouseFini (KdPointerInfo *pi) -{ - ephyrMouse = NULL; - return; -} - -KdPointerDriver EphyrMouseDriver = { - "ephyr", - MouseInit, - MouseEnable, - MouseDisable, - MouseFini, - NULL, -}; - -/* Keyboard */ - -static Status -EphyrKeyboardInit (KdKeyboardInfo *ki) -{ - ki->driverPrivate = (EphyrKbdPrivate *) - xcalloc(sizeof(EphyrKbdPrivate), 1); - hostx_load_keymap(); - if (!ephyrKeySyms.map) { - ErrorF("Couldn't load keymap from host\n"); - return BadAlloc; - } - ki->minScanCode = ephyrKeySyms.minKeyCode; - ki->maxScanCode = ephyrKeySyms.maxKeyCode; - xfree(ki->name); - ki->name = strdup("Xephyr virtual keyboard"); - ephyrKbd = ki; - return Success; -} - -static Status -EphyrKeyboardEnable (KdKeyboardInfo *ki) -{ - ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = TRUE; - - return Success; -} - -static void -EphyrKeyboardDisable (KdKeyboardInfo *ki) -{ - ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = FALSE; -} - -static void -EphyrKeyboardFini (KdKeyboardInfo *ki) -{ - ephyrKbd = NULL; - return; -} - -static void -EphyrKeyboardLeds (KdKeyboardInfo *ki, int leds) -{ -} - -static void -EphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration) -{ -} - - -KdKeyboardDriver EphyrKeyboardDriver = { - "ephyr", - EphyrKeyboardInit, - EphyrKeyboardEnable, - EphyrKeyboardLeds, - EphyrKeyboardBell, - EphyrKeyboardDisable, - EphyrKeyboardFini, - NULL, -}; +/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@openedhand.com>
+ *
+ * Copyright © 2004 Nokia
+ *
+ * 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 Nokia not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Nokia makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL NOKIA 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_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "ephyr.h"
+
+#include "inputstr.h"
+#include "scrnintstr.h"
+#include "ephyrlog.h"
+
+#ifdef XF86DRI
+#include "ephyrdri.h"
+#include "ephyrdriext.h"
+#include "ephyrglxext.h"
+#endif /* XF86DRI */
+
+extern int KdTsPhyScreen;
+#ifdef GLXEXT
+extern Bool noGlxVisualInit;
+#endif
+
+KdKeyboardInfo *ephyrKbd;
+KdPointerInfo *ephyrMouse;
+EphyrKeySyms ephyrKeySyms;
+Bool ephyrNoDRI=FALSE ;
+Bool ephyrNoXV=FALSE ;
+
+static int mouseState = 0;
+
+typedef struct _EphyrInputPrivate {
+ Bool enabled;
+} EphyrKbdPrivate, EphyrPointerPrivate;
+
+Bool EphyrWantGrayScale = 0;
+
+
+Bool
+ephyrInitialize (KdCardInfo *card, EphyrPriv *priv)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ OsSignal(SIGUSR1, hostx_handle_signal);
+#endif
+ priv->base = 0;
+ priv->bytes_per_line = 0;
+ return TRUE;
+}
+
+Bool
+ephyrCardInit (KdCardInfo *card)
+{
+ EphyrPriv *priv;
+
+ priv = (EphyrPriv *) xalloc (sizeof (EphyrPriv));
+ if (!priv)
+ return FALSE;
+
+ if (!ephyrInitialize (card, priv))
+ {
+ xfree (priv);
+ return FALSE;
+ }
+ card->driver = priv;
+
+ return TRUE;
+}
+
+Bool
+ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv)
+{
+ int width = 640, height = 480;
+ CARD32 redMask, greenMask, blueMask;
+
+ if (hostx_want_screen_size(screen, &width, &height)
+ || !screen->width || !screen->height)
+ {
+ screen->width = width;
+ screen->height = height;
+ }
+
+ if (EphyrWantGrayScale)
+ screen->fb.depth = 8;
+
+ if (screen->fb.depth && screen->fb.depth != hostx_get_depth())
+ {
+ if (screen->fb.depth < hostx_get_depth()
+ && (screen->fb.depth == 24 || screen->fb.depth == 16
+ || screen->fb.depth == 8))
+ {
+ hostx_set_server_depth(screen, screen->fb.depth);
+ }
+ else
+ ErrorF("\nXephyr: requested screen depth not supported, setting to match hosts.\n");
+ }
+
+ screen->fb.depth = hostx_get_server_depth(screen);
+ screen->rate = 72;
+
+ if (screen->fb.depth <= 8)
+ {
+ if (EphyrWantGrayScale)
+ screen->fb.visuals = ((1 << StaticGray) | (1 << GrayScale));
+ else
+ screen->fb.visuals = ((1 << StaticGray) |
+ (1 << GrayScale) |
+ (1 << StaticColor) |
+ (1 << PseudoColor) |
+ (1 << TrueColor) |
+ (1 << DirectColor));
+
+ screen->fb.redMask = 0x00;
+ screen->fb.greenMask = 0x00;
+ screen->fb.blueMask = 0x00;
+ screen->fb.depth = 8;
+ screen->fb.bitsPerPixel = 8;
+ }
+ else
+ {
+ screen->fb.visuals = (1 << TrueColor);
+
+ if (screen->fb.depth <= 15)
+ {
+ screen->fb.depth = 15;
+ screen->fb.bitsPerPixel = 16;
+ }
+ else if (screen->fb.depth <= 16)
+ {
+ screen->fb.depth = 16;
+ screen->fb.bitsPerPixel = 16;
+ }
+ else if (screen->fb.depth <= 24)
+ {
+ screen->fb.depth = 24;
+ screen->fb.bitsPerPixel = 32;
+ }
+ else if (screen->fb.depth <= 30)
+ {
+ screen->fb.depth = 30;
+ screen->fb.bitsPerPixel = 32;
+ }
+ else
+ {
+ ErrorF("\nXephyr: Unsupported screen depth %d\n",
+ screen->fb.depth);
+ return FALSE;
+ }
+
+ hostx_get_visual_masks (screen, &redMask, &greenMask, &blueMask);
+
+ screen->fb.redMask = (Pixel) redMask;
+ screen->fb.greenMask = (Pixel) greenMask;
+ screen->fb.blueMask = (Pixel) blueMask;
+
+ }
+
+ scrpriv->randr = screen->randr;
+
+ return ephyrMapFramebuffer (screen);
+}
+
+Bool
+ephyrScreenInit (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv;
+
+ scrpriv = xcalloc (1, sizeof (EphyrScrPriv));
+
+ if (!scrpriv)
+ return FALSE;
+
+ screen->driver = scrpriv;
+
+ if (!ephyrScreenInitialize (screen, scrpriv))
+ {
+ screen->driver = 0;
+ xfree (scrpriv);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+void*
+ephyrWindowLinear (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size,
+ void *closure)
+{
+ KdScreenPriv(pScreen);
+ EphyrPriv *priv = pScreenPriv->card->driver;
+
+ if (!pScreenPriv->enabled)
+ return 0;
+
+ *size = priv->bytes_per_line;
+ return priv->base + row * priv->bytes_per_line + offset;
+}
+
+/**
+ * Figure out display buffer size. If fakexa is enabled, allocate a larger
+ * buffer so that fakexa has space to put offscreen pixmaps.
+ */
+int
+ephyrBufferHeight(KdScreenInfo *screen)
+{
+ int buffer_height;
+ if (ephyrFuncs.initAccel == NULL)
+ buffer_height = screen->height;
+ else
+ buffer_height = 3 * screen->height;
+ return buffer_height;
+}
+
+
+Bool
+ephyrMapFramebuffer (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv = screen->driver;
+ EphyrPriv *priv = screen->card->driver;
+ KdPointerMatrix m;
+ int buffer_height;
+
+ EPHYR_LOG("screen->width: %d, screen->height: %d index=%d",
+ screen->width, screen->height, screen->mynum);
+
+ KdComputePointerMatrix (&m, scrpriv->randr, screen->width, screen->height);
+ KdSetPointerMatrix (&m);
+
+ priv->bytes_per_line = ((screen->width * screen->fb.bitsPerPixel + 31) >> 5) << 2;
+
+ buffer_height = ephyrBufferHeight(screen);
+
+ priv->base = hostx_screen_init (screen, screen->width, screen->height, buffer_height);
+
+ if ((scrpriv->randr & RR_Rotate_0) && !(scrpriv->randr & RR_Reflect_All))
+ {
+ scrpriv->shadow = FALSE;
+
+ screen->fb.byteStride = priv->bytes_per_line;
+ screen->fb.pixelStride = screen->width;
+ screen->fb.frameBuffer = (CARD8 *) (priv->base);
+ }
+ else
+ {
+ /* Rotated/Reflected so we need to use shadow fb */
+ scrpriv->shadow = TRUE;
+
+ EPHYR_LOG("allocing shadow");
+
+ KdShadowFbAlloc (screen,
+ scrpriv->randr & (RR_Rotate_90|RR_Rotate_270));
+ }
+
+ return TRUE;
+}
+
+void
+ephyrSetScreenSizes (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+
+ if (scrpriv->randr & (RR_Rotate_0|RR_Rotate_180))
+ {
+ pScreen->width = screen->width;
+ pScreen->height = screen->height;
+ pScreen->mmWidth = screen->width_mm;
+ pScreen->mmHeight = screen->height_mm;
+ }
+ else
+ {
+ pScreen->width = screen->height;
+ pScreen->height = screen->width;
+ pScreen->mmWidth = screen->height_mm;
+ pScreen->mmHeight = screen->width_mm;
+ }
+}
+
+Bool
+ephyrUnmapFramebuffer (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv = screen->driver;
+
+ if (scrpriv->shadow)
+ KdShadowFbFree (screen);
+
+ /* Note, priv->base will get freed when XImage recreated */
+
+ return TRUE;
+}
+
+void
+ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+
+ EPHYR_LOG("slow paint");
+
+ /* FIXME: Slow Rotated/Reflected updates could be much
+ * much faster efficiently updating via tranforming
+ * pBuf->pDamage regions
+ */
+ shadowUpdateRotatePacked(pScreen, pBuf);
+ hostx_paint_rect(screen, 0,0,0,0, screen->width, screen->height);
+}
+
+static void
+ephyrInternalDamageRedisplay (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ RegionPtr pRegion;
+
+ if (!scrpriv || !scrpriv->pDamage)
+ return;
+
+ pRegion = DamageRegion (scrpriv->pDamage);
+
+ if (REGION_NOTEMPTY (pScreen, pRegion))
+ {
+ int nbox;
+ BoxPtr pbox;
+
+ nbox = REGION_NUM_RECTS (pRegion);
+ pbox = REGION_RECTS (pRegion);
+
+ while (nbox--)
+ {
+ hostx_paint_rect(screen,
+ pbox->x1, pbox->y1,
+ pbox->x1, pbox->y1,
+ pbox->x2 - pbox->x1,
+ pbox->y2 - pbox->y1);
+ pbox++;
+ }
+ DamageEmpty (scrpriv->pDamage);
+ }
+}
+
+static void
+ephyrInternalDamageBlockHandler (pointer data,
+ OSTimePtr pTimeout,
+ pointer pRead)
+{
+ ScreenPtr pScreen = (ScreenPtr) data;
+
+ ephyrInternalDamageRedisplay (pScreen);
+}
+
+static void
+ephyrInternalDamageWakeupHandler (pointer data, int i, pointer LastSelectMask)
+{
+ /* FIXME: Not needed ? */
+}
+
+Bool
+ephyrSetInternalDamage (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ PixmapPtr pPixmap = NULL;
+
+ scrpriv->pDamage = DamageCreate ((DamageReportFunc) 0,
+ (DamageDestroyFunc) 0,
+ DamageReportNone,
+ TRUE,
+ pScreen,
+ pScreen);
+
+ if (!RegisterBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler,
+ ephyrInternalDamageWakeupHandler,
+ (pointer) pScreen))
+ return FALSE;
+
+ pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
+
+ DamageRegister (&pPixmap->drawable, scrpriv->pDamage);
+
+ return TRUE;
+}
+
+void
+ephyrUnsetInternalDamage (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ PixmapPtr pPixmap = NULL;
+
+ pPixmap = (*pScreen->GetScreenPixmap) (pScreen);
+ DamageUnregister (&pPixmap->drawable, scrpriv->pDamage);
+ DamageDestroy (scrpriv->pDamage);
+
+ RemoveBlockAndWakeupHandlers (ephyrInternalDamageBlockHandler,
+ ephyrInternalDamageWakeupHandler,
+ (pointer) pScreen);
+}
+
+#ifdef RANDR
+Bool
+ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ RRScreenSizePtr pSize;
+ Rotation randr;
+ int n = 0;
+
+ struct { int width, height; } sizes[] =
+ {
+ { 1600, 1200 },
+ { 1400, 1050 },
+ { 1280, 960 },
+ { 1280, 1024 },
+ { 1152, 864 },
+ { 1024, 768 },
+ { 832, 624 },
+ { 800, 600 },
+ { 720, 400 },
+ { 480, 640 },
+ { 640, 480 },
+ { 640, 400 },
+ { 320, 240 },
+ { 240, 320 },
+ { 160, 160 },
+ { 0, 0 }
+ };
+
+ EPHYR_LOG("mark");
+
+ *rotations = RR_Rotate_All|RR_Reflect_All;
+
+ if (!hostx_want_preexisting_window (screen)
+ && !hostx_want_fullscreen ()) /* only if no -parent switch */
+ {
+ while (sizes[n].width != 0 && sizes[n].height != 0)
+ {
+ RRRegisterSize (pScreen,
+ sizes[n].width,
+ sizes[n].height,
+ (sizes[n].width * screen->width_mm)/screen->width,
+ (sizes[n].height *screen->height_mm)/screen->height
+ );
+ n++;
+ }
+ }
+
+ pSize = RRRegisterSize (pScreen,
+ screen->width,
+ screen->height,
+ screen->width_mm,
+ screen->height_mm);
+
+ randr = KdSubRotation (scrpriv->randr, screen->randr);
+
+ RRSetCurrentConfig (pScreen, randr, 0, pSize);
+
+ return TRUE;
+}
+
+Bool
+ephyrRandRSetConfig (ScreenPtr pScreen,
+ Rotation randr,
+ int rate,
+ RRScreenSizePtr pSize)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+ Bool wasEnabled = pScreenPriv->enabled;
+ EphyrScrPriv oldscr;
+ int oldwidth, oldheight, oldmmwidth, oldmmheight;
+ Bool oldshadow;
+ int newwidth, newheight;
+
+ if (screen->randr & (RR_Rotate_0|RR_Rotate_180))
+ {
+ newwidth = pSize->width;
+ newheight = pSize->height;
+ }
+ else
+ {
+ newwidth = pSize->height;
+ newheight = pSize->width;
+ }
+
+ if (wasEnabled)
+ KdDisableScreen (pScreen);
+
+ oldscr = *scrpriv;
+
+ oldwidth = screen->width;
+ oldheight = screen->height;
+ oldmmwidth = pScreen->mmWidth;
+ oldmmheight = pScreen->mmHeight;
+ oldshadow = scrpriv->shadow;
+
+ /*
+ * Set new configuration
+ */
+
+ scrpriv->randr = KdAddRotation (screen->randr, randr);
+
+ ephyrUnmapFramebuffer (screen);
+
+ screen->width = newwidth;
+ screen->height = newheight;
+
+ if (!ephyrMapFramebuffer (screen))
+ goto bail4;
+
+ /* FIXME below should go in own call */
+
+ if (oldshadow)
+ KdShadowUnset (screen->pScreen);
+ else
+ ephyrUnsetInternalDamage(screen->pScreen);
+
+ if (scrpriv->shadow)
+ {
+ if (!KdShadowSet (screen->pScreen,
+ scrpriv->randr,
+ ephyrShadowUpdate,
+ ephyrWindowLinear))
+ goto bail4;
+ }
+ else
+ {
+ /* Without shadow fb ( non rotated ) we need
+ * to use damage to efficiently update display
+ * via signal regions what to copy from 'fb'.
+ */
+ if (!ephyrSetInternalDamage(screen->pScreen))
+ goto bail4;
+ }
+
+ ephyrSetScreenSizes (screen->pScreen);
+
+ /*
+ * Set frame buffer mapping
+ */
+ (*pScreen->ModifyPixmapHeader) (fbGetScreenPixmap (pScreen),
+ pScreen->width,
+ pScreen->height,
+ screen->fb.depth,
+ screen->fb.bitsPerPixel,
+ screen->fb.byteStride,
+ screen->fb.frameBuffer);
+
+ /* set the subpixel order */
+
+ KdSetSubpixelOrder (pScreen, scrpriv->randr);
+
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+
+ return TRUE;
+
+ bail4:
+ EPHYR_LOG("bailed");
+
+ ephyrUnmapFramebuffer (screen);
+ *scrpriv = oldscr;
+ (void) ephyrMapFramebuffer (screen);
+
+ pScreen->width = oldwidth;
+ pScreen->height = oldheight;
+ pScreen->mmWidth = oldmmwidth;
+ pScreen->mmHeight = oldmmheight;
+
+ if (wasEnabled)
+ KdEnableScreen (pScreen);
+ return FALSE;
+}
+
+Bool
+ephyrRandRInit (ScreenPtr pScreen)
+{
+ rrScrPrivPtr pScrPriv;
+
+ if (!RRScreenInit (pScreen))
+ return FALSE;
+
+ pScrPriv = rrGetScrPriv(pScreen);
+ pScrPriv->rrGetInfo = ephyrRandRGetInfo;
+ pScrPriv->rrSetConfig = ephyrRandRSetConfig;
+ return TRUE;
+}
+#endif
+
+Bool
+ephyrCreateColormap (ColormapPtr pmap)
+{
+ return fbInitializeColormap (pmap);
+}
+
+Bool
+ephyrInitScreen (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+
+ EPHYR_LOG ("pScreen->myNum:%d\n", pScreen->myNum) ;
+ hostx_set_screen_number (screen, pScreen->myNum);
+ hostx_set_win_title (screen, "(ctrl+shift grabs mouse and keyboard)") ;
+ pScreen->CreateColormap = ephyrCreateColormap;
+
+#ifdef XV
+ if (!ephyrNoXV) {
+ if (!ephyrInitVideo (pScreen)) {
+ EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ;
+ } else {
+ EPHYR_LOG ("initialized xvideo okay\n") ;
+ }
+ }
+#endif /*XV*/
+
+#ifdef XF86DRI
+ if (!ephyrNoDRI && !hostx_has_dri ()) {
+ EPHYR_LOG ("host x does not support DRI. Disabling DRI forwarding\n") ;
+ ephyrNoDRI = TRUE ;
+#ifdef GLXEXT
+ noGlxVisualInit = FALSE ;
+#endif
+ }
+ if (!ephyrNoDRI) {
+ ephyrDRIExtensionInit (pScreen) ;
+ ephyrHijackGLXExtension () ;
+ }
+#endif
+
+#ifdef GLXEXT
+ if (ephyrNoDRI) {
+ noGlxVisualInit = FALSE ;
+ }
+#endif
+
+ return TRUE;
+}
+
+Bool
+ephyrFinishInitScreen (ScreenPtr pScreen)
+{
+ /* FIXME: Calling this even if not using shadow.
+ * Seems harmless enough. But may be safer elsewhere.
+ */
+ if (!shadowSetup (pScreen))
+ return FALSE;
+
+#ifdef RANDR
+ if (!ephyrRandRInit (pScreen))
+ return FALSE;
+#endif
+
+ return TRUE;
+}
+
+Bool
+ephyrCreateResources (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ EphyrScrPriv *scrpriv = screen->driver;
+
+ EPHYR_LOG("mark pScreen=%p mynum=%d shadow=%d",
+ pScreen, pScreen->myNum, scrpriv->shadow);
+
+ if (scrpriv->shadow)
+ return KdShadowSet (pScreen,
+ scrpriv->randr,
+ ephyrShadowUpdate,
+ ephyrWindowLinear);
+ else
+ return ephyrSetInternalDamage(pScreen);
+}
+
+void
+ephyrPreserve (KdCardInfo *card)
+{
+}
+
+Bool
+ephyrEnable (ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+Bool
+ephyrDPMS (ScreenPtr pScreen, int mode)
+{
+ return TRUE;
+}
+
+void
+ephyrDisable (ScreenPtr pScreen)
+{
+}
+
+void
+ephyrRestore (KdCardInfo *card)
+{
+}
+
+void
+ephyrScreenFini (KdScreenInfo *screen)
+{
+ EphyrScrPriv *scrpriv = screen->driver;
+ if (scrpriv->shadow) {
+ KdShadowFbFree (screen);
+ }
+ xfree(screen->driver);
+ screen->driver = NULL;
+}
+
+/*
+ * Port of Mark McLoughlin's Xnest fix for focus in + modifier bug.
+ * See https://bugs.freedesktop.org/show_bug.cgi?id=3030
+ */
+void
+ephyrUpdateModifierState(unsigned int state)
+{
+#if 0
+ DeviceIntPtr pkeydev;
+ KeyClassPtr keyc;
+ int i;
+ CARD8 mask;
+
+ pkeydev = inputInfo.keyboard;
+
+ if (!pkeydev)
+ return;
+
+/* This is pretty broken.
+ *
+ * What should happen is that focus out should do as a VT switch does in
+ * traditional servers: fake releases for all keys (and buttons too, come
+ * to think of it) currently down. Then, on focus in, get the state from
+ * the host, and fake keypresses for everything currently down.
+ *
+ * So I'm leaving this broken for a little while. Sorry, folks.
+ *
+ * -daniels
+ */
+
+ keyc = pkeydev->key;
+
+ state = state & 0xff;
+
+ if (keyc->state == state)
+ return;
+
+ for (i = 0, mask = 1; i < 8; i++, mask <<= 1)
+ {
+ int key;
+
+ /* Modifier is down, but shouldn't be */
+ if ((keyc->state & mask) && !(state & mask))
+ {
+ int count = keyc->modifierKeyCount[i];
+
+ for (key = 0; key < MAP_LENGTH; key++)
+ if (keyc->xkbInfo->desc->map->modmap[key] & mask)
+ {
+ int bit;
+ BYTE *kptr;
+
+ kptr = &keyc->down[key >> 3];
+ bit = 1 << (key & 7);
+
+ if (*kptr & bit && ephyrKbd &&
+ ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ KdEnqueueKeyboardEvent(ephyrKbd, key, TRUE); /* release */
+
+ if (--count == 0)
+ break;
+ }
+ }
+
+ /* Modifier shoud be down, but isn't */
+ if (!(keyc->state & mask) && (state & mask))
+ for (key = 0; key < MAP_LENGTH; key++)
+ if (keyc->xkbInfo->desc->map->modmap[key] & mask)
+ {
+ if (keyc->xkbInfo->desc->map->modmap[key] & mask && ephyrKbd &&
+ ((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ KdEnqueueKeyboardEvent(ephyrKbd, key, FALSE); /* press */
+ break;
+ }
+ }
+#endif
+}
+
+static void
+ephyrBlockSigio (void)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_BLOCK, &set, 0);
+#endif
+}
+
+static void
+ephyrUnblockSigio (void)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_UNBLOCK, &set, 0);
+#endif
+}
+
+static Bool
+ephyrCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
+{
+ return FALSE;
+}
+
+static void
+ephyrCrossScreen (ScreenPtr pScreen, Bool entering)
+{
+}
+
+int ephyrCurScreen; /*current event screen*/
+
+static void
+ephyrWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ ephyrBlockSigio ();
+ ephyrCurScreen = pScreen->myNum;
+ miPointerWarpCursor (inputInfo.pointer, pScreen, x, y);
+ ephyrUnblockSigio ();
+}
+
+miPointerScreenFuncRec ephyrPointerScreenFuncs =
+{
+ ephyrCursorOffScreen,
+ ephyrCrossScreen,
+ ephyrWarpCursor,
+ NULL,
+ NULL
+};
+
+#ifdef XF86DRI
+/**
+ * find if the remote window denoted by a_remote
+ * is paired with an internal Window within the Xephyr server.
+ * If the remove window is paired with an internal window, send an
+ * expose event to the client insterested in the internal window expose event.
+ *
+ * Pairing happens when a drawable inside Xephyr is associated with
+ * a GL surface in a DRI environment.
+ * Look at the function ProcXF86DRICreateDrawable in ephyrdriext.c to
+ * know a paired window is created.
+ *
+ * This is useful to make GL drawables (only windows for now) handle
+ * expose events and send those events to clients.
+ */
+static void
+ephyrExposePairedWindow (int a_remote)
+{
+ EphyrWindowPair *pair = NULL;
+ RegionRec reg;
+ ScreenPtr screen;
+
+ if (!findWindowPairFromRemote (a_remote, &pair)) {
+ EPHYR_LOG ("did not find a pair for this window\n");
+ return;
+ }
+ screen = pair->local->drawable.pScreen;
+ REGION_NULL (screen, ®);
+ REGION_COPY (screen, ®, &pair->local->clipList);
+ screen->WindowExposures (pair->local, ®, NullRegion);
+ REGION_UNINIT (screen, ®);
+}
+#endif /* XF86DRI */
+
+void
+ephyrPoll(void)
+{
+ EphyrHostXEvent ev;
+
+ while (hostx_get_event(&ev))
+ {
+ switch (ev.type)
+ {
+ case EPHYR_EV_MOUSE_MOTION:
+ if (!ephyrMouse ||
+ !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
+ EPHYR_LOG ("skipping mouse motion:%d\n", ephyrCurScreen) ;
+ continue;
+ }
+ {
+ if (ev.data.mouse_motion.screen >=0
+ && (ephyrCurScreen != ev.data.mouse_motion.screen))
+ {
+ EPHYR_LOG ("warping mouse cursor. "
+ "cur_screen%d, motion_screen:%d\n",
+ ephyrCurScreen, ev.data.mouse_motion.screen) ;
+ if (ev.data.mouse_motion.screen >= 0)
+ {
+ ephyrWarpCursor
+ (inputInfo.pointer, screenInfo.screens[ev.data.mouse_motion.screen],
+ ev.data.mouse_motion.x,
+ ev.data.mouse_motion.y );
+ }
+ }
+ else
+ {
+ int x=0, y=0;
+#ifdef XF86DRI
+ EphyrWindowPair *pair = NULL;
+#endif
+ EPHYR_LOG ("enqueuing mouse motion:%d\n", ephyrCurScreen) ;
+ x = ev.data.mouse_motion.x;
+ y = ev.data.mouse_motion.y;
+ EPHYR_LOG ("initial (x,y):(%d,%d)\n", x, y) ;
+#ifdef XF86DRI
+ EPHYR_LOG ("is this window peered by a gl drawable ?\n") ;
+ if (findWindowPairFromRemote (ev.data.mouse_motion.window,
+ &pair))
+ {
+ EPHYR_LOG ("yes, it is peered\n") ;
+ x += pair->local->drawable.x;
+ y += pair->local->drawable.y;
+ }
+ else
+ {
+ EPHYR_LOG ("no, it is not peered\n") ;
+ }
+ EPHYR_LOG ("final (x,y):(%d,%d)\n", x, y) ;
+#endif
+ KdEnqueuePointerEvent(ephyrMouse, mouseState, x, y, 0);
+ }
+ }
+ break;
+
+ case EPHYR_EV_MOUSE_PRESS:
+ if (!ephyrMouse ||
+ !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled) {
+ EPHYR_LOG ("skipping mouse press:%d\n", ephyrCurScreen) ;
+ continue;
+ }
+ EPHYR_LOG ("enqueuing mouse press:%d\n", ephyrCurScreen) ;
+ ephyrUpdateModifierState(ev.key_state);
+ mouseState |= ev.data.mouse_down.button_num;
+ KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
+ break;
+
+ case EPHYR_EV_MOUSE_RELEASE:
+ if (!ephyrMouse ||
+ !((EphyrPointerPrivate *)ephyrMouse->driverPrivate)->enabled)
+ continue;
+ ephyrUpdateModifierState(ev.key_state);
+ mouseState &= ~ev.data.mouse_up.button_num;
+ EPHYR_LOG ("enqueuing mouse release:%d\n", ephyrCurScreen) ;
+ KdEnqueuePointerEvent(ephyrMouse, mouseState|KD_MOUSE_DELTA, 0, 0, 0);
+ break;
+
+ case EPHYR_EV_KEY_PRESS:
+ if (!ephyrKbd ||
+ !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ continue;
+ ephyrUpdateModifierState(ev.key_state);
+ KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_down.scancode, FALSE);
+ break;
+
+ case EPHYR_EV_KEY_RELEASE:
+ if (!ephyrKbd ||
+ !((EphyrKbdPrivate *)ephyrKbd->driverPrivate)->enabled)
+ continue;
+ KdEnqueueKeyboardEvent (ephyrKbd, ev.data.key_up.scancode, TRUE);
+ break;
+
+#ifdef XF86DRI
+ case EPHYR_EV_EXPOSE:
+ /*
+ * We only receive expose events when the expose event have
+ * be generated for a drawable that is a host X window managed
+ * by Xephyr. Host X windows managed by Xephyr exists for instance
+ * when Xephyr is asked to create a GL drawable in a DRI environment.
+ */
+ ephyrExposePairedWindow (ev.data.expose.window);
+ break;
+#endif /* XF86DRI */
+
+ default:
+ break;
+ }
+ }
+}
+
+void
+ephyrCardFini (KdCardInfo *card)
+{
+ EphyrPriv *priv = card->driver;
+ xfree (priv);
+}
+
+void
+ephyrGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
+{
+ /* XXX Not sure if this is right */
+
+ EPHYR_LOG("mark");
+
+ while (n--)
+ {
+ pdefs->red = 0;
+ pdefs->green = 0;
+ pdefs->blue = 0;
+ pdefs++;
+ }
+
+}
+
+void
+ephyrPutColors (ScreenPtr pScreen, int n, xColorItem *pdefs)
+{
+ int min, max, p;
+
+ /* XXX Not sure if this is right */
+
+ min = 256;
+ max = 0;
+
+ while (n--)
+ {
+ p = pdefs->pixel;
+ if (p < min)
+ min = p;
+ if (p > max)
+ max = p;
+
+ hostx_set_cmap_entry(p,
+ pdefs->red >> 8,
+ pdefs->green >> 8,
+ pdefs->blue >> 8);
+ pdefs++;
+ }
+}
+
+/* Mouse calls */
+
+static Status
+MouseInit (KdPointerInfo *pi)
+{
+ pi->driverPrivate = (EphyrPointerPrivate *)
+ xcalloc(sizeof(EphyrPointerPrivate), 1);
+ ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE;
+ pi->nAxes = 3;
+ pi->nButtons = 32;
+ xfree(pi->name);
+ pi->name = strdup("Xephyr virtual mouse");
+ ephyrMouse = pi;
+ return Success;
+}
+
+static Status
+MouseEnable (KdPointerInfo *pi)
+{
+ ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = TRUE;
+ return Success;
+}
+
+static void
+MouseDisable (KdPointerInfo *pi)
+{
+ ((EphyrPointerPrivate *)pi->driverPrivate)->enabled = FALSE;
+ return;
+}
+
+static void
+MouseFini (KdPointerInfo *pi)
+{
+ ephyrMouse = NULL;
+ return;
+}
+
+KdPointerDriver EphyrMouseDriver = {
+ "ephyr",
+ MouseInit,
+ MouseEnable,
+ MouseDisable,
+ MouseFini,
+ NULL,
+};
+
+/* Keyboard */
+
+static Status
+EphyrKeyboardInit (KdKeyboardInfo *ki)
+{
+ ki->driverPrivate = (EphyrKbdPrivate *)
+ xcalloc(sizeof(EphyrKbdPrivate), 1);
+ hostx_load_keymap();
+ if (!ephyrKeySyms.map) {
+ ErrorF("Couldn't load keymap from host\n");
+ return BadAlloc;
+ }
+ ki->minScanCode = ephyrKeySyms.minKeyCode;
+ ki->maxScanCode = ephyrKeySyms.maxKeyCode;
+ xfree(ki->name);
+ ki->name = strdup("Xephyr virtual keyboard");
+ ephyrKbd = ki;
+ return Success;
+}
+
+static Status
+EphyrKeyboardEnable (KdKeyboardInfo *ki)
+{
+ ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = TRUE;
+
+ return Success;
+}
+
+static void
+EphyrKeyboardDisable (KdKeyboardInfo *ki)
+{
+ ((EphyrKbdPrivate *)ki->driverPrivate)->enabled = FALSE;
+}
+
+static void
+EphyrKeyboardFini (KdKeyboardInfo *ki)
+{
+ ephyrKbd = NULL;
+ return;
+}
+
+static void
+EphyrKeyboardLeds (KdKeyboardInfo *ki, int leds)
+{
+}
+
+static void
+EphyrKeyboardBell (KdKeyboardInfo *ki, int volume, int frequency, int duration)
+{
+}
+
+
+KdKeyboardDriver EphyrKeyboardDriver = {
+ "ephyr",
+ EphyrKeyboardInit,
+ EphyrKeyboardEnable,
+ EphyrKeyboardLeds,
+ EphyrKeyboardBell,
+ EphyrKeyboardDisable,
+ EphyrKeyboardFini,
+ NULL,
+};
diff --git a/xorg-server/hw/kdrive/ephyr/ephyr.h b/xorg-server/hw/kdrive/ephyr/ephyr.h index 41a82bf9d..e4ce84dee 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyr.h +++ b/xorg-server/hw/kdrive/ephyr/ephyr.h @@ -1,203 +1,207 @@ -/* - * Xephyr - A kdrive X server thats runs in a host X window. - * Authored by Matthew Allum <mallum@o-hand.com> - * - * Copyright © 2004 Nokia - * - * 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 Nokia not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Nokia makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL NOKIA 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 _EPHYR_H_ -#define _EPHYR_H_ -#include <stdio.h> -#include <unistd.h> -#include <signal.h> -#include <libgen.h> - -#include "os.h" /* for OsSignal() */ -#include "kdrive.h" -#include "hostx.h" -#include "exa.h" - -#ifdef RANDR -#include "randrstr.h" -#endif - -#include "damage.h" - -typedef struct _ephyrPriv { - CARD8 *base; - int bytes_per_line; -} EphyrPriv; - -typedef struct _ephyrFakexaPriv { - ExaDriverPtr exa; - Bool is_synced; - - /* The following are arguments and other information from Prepare* calls - * which are stored for use in the inner calls. - */ - int op; - PicturePtr pSrcPicture, pMaskPicture, pDstPicture; - void *saved_ptrs[3]; - PixmapPtr pDst, pSrc, pMask; - GCPtr pGC; -} EphyrFakexaPriv; - -typedef struct _ephyrScrPriv { - Rotation randr; - Bool shadow; - DamagePtr pDamage; - EphyrFakexaPriv *fakexa; -} EphyrScrPriv; - -extern KdCardFuncs ephyrFuncs; -extern KdKeyboardInfo *ephyrKbd; -extern KdPointerInfo *ephyrMouse; - -extern miPointerScreenFuncRec ephyrPointerScreenFuncs; - -Bool -ephyrInitialize (KdCardInfo *card, EphyrPriv *priv); - -Bool -ephyrCardInit (KdCardInfo *card); - -Bool -ephyrScreenInit (KdScreenInfo *screen); - -Bool -ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv); - -Bool -ephyrInitScreen (ScreenPtr pScreen); - -Bool -ephyrFinishInitScreen (ScreenPtr pScreen); - -Bool -ephyrCreateResources (ScreenPtr pScreen); - -void -ephyrPreserve (KdCardInfo *card); - -Bool -ephyrEnable (ScreenPtr pScreen); - -Bool -ephyrDPMS (ScreenPtr pScreen, int mode); - -void -ephyrDisable (ScreenPtr pScreen); - -void -ephyrRestore (KdCardInfo *card); - -void -ephyrScreenFini (KdScreenInfo *screen); - -void -ephyrCardFini (KdCardInfo *card); - -void -ephyrGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs); - -void -ephyrPutColors (ScreenPtr pScreen, int n, xColorItem *pdefs); - -Bool -ephyrMapFramebuffer (KdScreenInfo *screen); - -void * -ephyrWindowLinear (ScreenPtr pScreen, - CARD32 row, - CARD32 offset, - int mode, - CARD32 *size, - void *closure); - -void -ephyrSetScreenSizes (ScreenPtr pScreen); - -Bool -ephyrUnmapFramebuffer (KdScreenInfo *screen); - -void -ephyrUnsetInternalDamage (ScreenPtr pScreen); - -Bool -ephyrSetInternalDamage (ScreenPtr pScreen); - -Bool -ephyrCreateColormap (ColormapPtr pmap); - -void -ephyrPoll(void); - -#ifdef RANDR -Bool -ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations); - -Bool -ephyrRandRSetConfig (ScreenPtr pScreen, - Rotation randr, - int rate, - RRScreenSizePtr pSize); -Bool -ephyrRandRInit (ScreenPtr pScreen); - -void -ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf); - -#endif - -void -ephyrUpdateModifierState(unsigned int state); - -extern KdPointerDriver EphyrMouseDriver; - -extern KdKeyboardDriver EphyrKeyboardDriver; - -extern KdOsFuncs EphyrOsFuncs; - -extern Bool ephyrCursorInit(ScreenPtr pScreen); - -extern void ephyrCursorEnable(ScreenPtr pScreen); - -extern int ephyrBufferHeight(KdScreenInfo *screen); - -/* ephyr_draw.c */ - -Bool -ephyrDrawInit(ScreenPtr pScreen); - -void -ephyrDrawEnable(ScreenPtr pScreen); - -void -ephyrDrawDisable(ScreenPtr pScreen); - -void -ephyrDrawFini(ScreenPtr pScreen); - -/*ephyvideo.c*/ - -Bool ephyrInitVideo(ScreenPtr pScreen) ; - -#endif +/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@o-hand.com>
+ *
+ * Copyright © 2004 Nokia
+ *
+ * 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 Nokia not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Nokia makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL NOKIA 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 _EPHYR_H_
+#define _EPHYR_H_
+#include <stdio.h>
+#ifndef _MSC_VER
+#include <unistd.h>
+#include <libgen.h>
+#endif
+#include <signal.h>
+
+#include "os.h" /* for OsSignal() */
+#include "kdrive.h"
+#include "hostx.h"
+#include "exa.h"
+
+#ifdef RANDR
+#include "randrstr.h"
+#endif
+
+#include "damage.h"
+
+typedef struct _ephyrPriv {
+ CARD8 *base;
+ int bytes_per_line;
+} EphyrPriv;
+
+typedef struct _ephyrFakexaPriv {
+ ExaDriverPtr exa;
+ Bool is_synced;
+
+ /* The following are arguments and other information from Prepare* calls
+ * which are stored for use in the inner calls.
+ */
+ int op;
+ PicturePtr pSrcPicture, pMaskPicture, pDstPicture;
+ void *saved_ptrs[3];
+ PixmapPtr pDst, pSrc, pMask;
+ GCPtr pGC;
+} EphyrFakexaPriv;
+
+typedef struct _ephyrScrPriv {
+ Rotation randr;
+ Bool shadow;
+ DamagePtr pDamage;
+ EphyrFakexaPriv *fakexa;
+} EphyrScrPriv;
+
+extern KdCardFuncs ephyrFuncs;
+extern KdKeyboardInfo *ephyrKbd;
+extern KdPointerInfo *ephyrMouse;
+
+extern miPointerScreenFuncRec ephyrPointerScreenFuncs;
+
+Bool
+ephyrInitialize (KdCardInfo *card, EphyrPriv *priv);
+
+Bool
+ephyrCardInit (KdCardInfo *card);
+
+Bool
+ephyrScreenInit (KdScreenInfo *screen);
+
+Bool
+ephyrScreenInitialize (KdScreenInfo *screen, EphyrScrPriv *scrpriv);
+
+Bool
+ephyrInitScreen (ScreenPtr pScreen);
+
+Bool
+ephyrFinishInitScreen (ScreenPtr pScreen);
+
+Bool
+ephyrCreateResources (ScreenPtr pScreen);
+
+void
+ephyrPreserve (KdCardInfo *card);
+
+Bool
+ephyrEnable (ScreenPtr pScreen);
+
+Bool
+ephyrDPMS (ScreenPtr pScreen, int mode);
+
+void
+ephyrDisable (ScreenPtr pScreen);
+
+void
+ephyrRestore (KdCardInfo *card);
+
+void
+ephyrScreenFini (KdScreenInfo *screen);
+
+void
+ephyrCardFini (KdCardInfo *card);
+
+void
+ephyrGetColors (ScreenPtr pScreen, int n, xColorItem *pdefs);
+
+void
+ephyrPutColors (ScreenPtr pScreen, int n, xColorItem *pdefs);
+
+Bool
+ephyrMapFramebuffer (KdScreenInfo *screen);
+
+void *
+ephyrWindowLinear (ScreenPtr pScreen,
+ CARD32 row,
+ CARD32 offset,
+ int mode,
+ CARD32 *size,
+ void *closure);
+
+void
+ephyrSetScreenSizes (ScreenPtr pScreen);
+
+Bool
+ephyrUnmapFramebuffer (KdScreenInfo *screen);
+
+void
+ephyrUnsetInternalDamage (ScreenPtr pScreen);
+
+Bool
+ephyrSetInternalDamage (ScreenPtr pScreen);
+
+Bool
+ephyrCreateColormap (ColormapPtr pmap);
+
+void
+ephyrPoll(void);
+
+#ifdef RANDR
+Bool
+ephyrRandRGetInfo (ScreenPtr pScreen, Rotation *rotations);
+
+Bool
+ephyrRandRSetConfig (ScreenPtr pScreen,
+ Rotation randr,
+ int rate,
+ RRScreenSizePtr pSize);
+Bool
+ephyrRandRInit (ScreenPtr pScreen);
+
+void
+ephyrShadowUpdate (ScreenPtr pScreen, shadowBufPtr pBuf);
+
+#endif
+
+void
+ephyrUpdateModifierState(unsigned int state);
+
+extern KdPointerDriver EphyrMouseDriver;
+
+extern KdKeyboardDriver EphyrKeyboardDriver;
+
+extern KdOsFuncs EphyrOsFuncs;
+
+extern Bool ephyrCursorInit(ScreenPtr pScreen);
+
+extern void ephyrCursorEnable(ScreenPtr pScreen);
+
+extern int ephyrBufferHeight(KdScreenInfo *screen);
+
+extern int ephyrBufferHeight(KdScreenInfo *screen);
+
+/* ephyr_draw.c */
+
+Bool
+ephyrDrawInit(ScreenPtr pScreen);
+
+void
+ephyrDrawEnable(ScreenPtr pScreen);
+
+void
+ephyrDrawDisable(ScreenPtr pScreen);
+
+void
+ephyrDrawFini(ScreenPtr pScreen);
+
+/*ephyvideo.c*/
+
+Bool ephyrInitVideo(ScreenPtr pScreen) ;
+
+#endif
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrinit.c b/xorg-server/hw/kdrive/ephyr/ephyrinit.c index 27cab3b63..b90b92bac 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrinit.c +++ b/xorg-server/hw/kdrive/ephyr/ephyrinit.c @@ -1,415 +1,427 @@ -/* - * Xephyr - A kdrive X server thats runs in a host X window. - * Authored by Matthew Allum <mallum@o-hand.com> - * - * Copyright © 2004 Nokia - * - * 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 Nokia not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Nokia makes no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL NOKIA 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_CONFIG_H -#include <kdrive-config.h> -#endif -#include "ephyr.h" -#include "ephyrlog.h" - -extern Window EphyrPreExistingHostWin; -extern Bool EphyrWantGrayScale; -extern Bool kdHasPointer; -extern Bool kdHasKbd; - -#ifdef GLXEXT -extern Bool ephyrNoDRI; -extern Bool noGlxVisualInit; -#endif -extern Bool ephyrNoXV; - -#ifdef KDRIVE_EVDEV -extern KdPointerDriver LinuxEvdevMouseDriver; -extern KdKeyboardDriver LinuxEvdevKeyboardDriver; -#endif - -void processScreenArg (char *screen_size, char *parent_id) ; - -void -InitCard (char *name) -{ - EPHYR_DBG("mark"); - KdCardInfoAdd (&ephyrFuncs, 0); -} - -void -InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv) -{ - KdInitOutput (pScreenInfo, argc, argv); -} - -void -InitInput (int argc, char **argv) -{ - KdKeyboardInfo *ki; - KdPointerInfo *pi; - - KdAddKeyboardDriver(&EphyrKeyboardDriver); -#ifdef KDRIVE_EVDEV - KdAddKeyboardDriver(&LinuxEvdevKeyboardDriver); -#endif - KdAddPointerDriver(&EphyrMouseDriver); -#ifdef KDRIVE_EVDEV - KdAddPointerDriver(&LinuxEvdevMouseDriver); -#endif - - if (!kdHasKbd) { - ki = KdNewKeyboard(); - if (!ki) - FatalError("Couldn't create Xephyr keyboard\n"); - ki->driver = &EphyrKeyboardDriver; - KdAddKeyboard(ki); - } - - if (!kdHasPointer) { - pi = KdNewPointer(); - if (!pi) - FatalError("Couldn't create Xephyr pointer\n"); - pi->driver = &EphyrMouseDriver; - KdAddPointer(pi); - } - - KdInitInput(); -} - -void -CloseInput (void) -{ -} - -#ifdef DDXBEFORERESET -void -ddxBeforeReset (void) -{ -} -#endif - -void -ddxUseMsg (void) -{ - KdUseMsg(); - - ErrorF("\nXephyr Option Usage:\n"); - ErrorF("-parent <XID> Use existing window as Xephyr root win\n"); - ErrorF("-host-cursor Re-use exisiting X host server cursor\n"); - ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n"); - ErrorF("-grayscale Simulate 8bit grayscale\n"); - ErrorF("-fakexa Simulate acceleration using software rendering\n"); - ErrorF("-verbosity <level> Set log verbosity level\n"); -#ifdef GLXEXT - ErrorF("-nodri do not use DRI\n"); -#endif - ErrorF("-noxv do not use XV\n"); - ErrorF("-name [name] define the name in the WM_CLASS property\n"); - ErrorF("-title [title] set the window title in the WM_NAME property\n"); - ErrorF("\n"); - - exit(1); -} - -void -processScreenArg (char *screen_size, char *parent_id) -{ - KdCardInfo *card; - - InitCard (0); /*Put each screen on a separate card*/ - card = KdCardInfoLast (); - - if (card) - { - KdScreenInfo *screen; - unsigned long p_id = 0; - - screen = KdScreenInfoAdd (card); - KdParseScreen (screen, screen_size); - - if (parent_id) - { - p_id = strtol (parent_id, NULL, 0); - } - EPHYR_DBG ("screen number:%d\n", screen->mynum) ; - hostx_add_screen (screen, p_id, screen->mynum); - } - else - { - ErrorF("No matching card found!\n"); - } -} - -int -ddxProcessArgument (int argc, char **argv, int i) -{ - static char* parent = NULL; - EPHYR_DBG("mark argv[%d]='%s'", i, argv[i] ); - - if (i == 1) - { - hostx_use_resname(basename(argv[0]), 0); - } - - if (!strcmp (argv[i], "-parent")) - { - if(i+1 < argc) - { - int j; - /* If parent is specified and a screen argument follows, don't do - * anything, let the -screen handling init the rest */ - for (j = i; j < argc; j++) - { - if (!strcmp(argv[j], "-screen")) - { - parent = argv[i + 1]; - return 2; - } - } - - processScreenArg ("100x100", argv[i+1]); - return 2; - } - - UseMsg(); - exit(1); - } - else if (!strcmp (argv[i], "-screen")) - { - if ((i+1) < argc) - { - processScreenArg (argv[i+1], parent); - parent = NULL; - return 2; - } - - UseMsg(); - exit(1); - } - else if (!strcmp (argv[i], "-host-cursor")) - { - hostx_use_host_cursor(); - return 1; - } - else if (!strcmp (argv[i], "-fullscreen")) - { - hostx_use_fullscreen(); - return 1; - } - else if (!strcmp (argv[i], "-grayscale")) - { - EphyrWantGrayScale = 1; - return 1; - } - else if (!strcmp (argv[i], "-fakexa")) - { - ephyrFuncs.initAccel = ephyrDrawInit; - ephyrFuncs.enableAccel = ephyrDrawEnable; - ephyrFuncs.disableAccel = ephyrDrawDisable; - ephyrFuncs.finiAccel = ephyrDrawFini; - return 1; - } - else if (!strcmp (argv[i], "-verbosity")) - { - if(i+1 < argc && argv[i+1][0] != '-') - { - int verbosity=atoi (argv[i+1]) ; - LogSetParameter (XLOG_VERBOSITY, verbosity) ; - EPHYR_LOG ("set verbosiry to %d\n", verbosity) ; - return 2 ; - } - else - { - UseMsg() ; - exit(1) ; - } - } -#ifdef GLXEXT - else if (!strcmp (argv[i], "-nodri")) - { - noGlxVisualInit = FALSE ; - ephyrNoDRI = TRUE ; - EPHYR_LOG ("no direct rendering enabled\n") ; - return 1 ; - } -#endif - else if (!strcmp (argv[i], "-noxv")) - { - ephyrNoXV = TRUE ; - EPHYR_LOG ("no XVideo enabled\n") ; - return 1 ; - } - else if (!strcmp (argv[i], "-name")) - { - if (i+1 < argc && argv[i+1][0] != '-') - { - hostx_use_resname(argv[i+1], 1); - return 2; - } - else - { - UseMsg(); - return 0; - } - } - else if (!strcmp (argv[i], "-title")) - { - if (i+1 < argc && argv[i+1][0] != '-') - { - hostx_set_title(argv[i+1]); - return 2; - } - else - { - UseMsg(); - return 0; - } - } - else if (argv[i][0] == ':') - { - hostx_set_display_name(argv[i]); - } - /* Xnest compatibility */ - else if (!strcmp(argv[i], "-display")) - { - hostx_set_display_name(argv[i+1]); - return 2; - } - else if (!strcmp(argv[i], "-sync") || - !strcmp(argv[i], "-full") || - !strcmp(argv[i], "-sss") || - !strcmp(argv[i], "-install")) - { - return 1; - } - else if (!strcmp(argv[i], "-bw") || - !strcmp(argv[i], "-class") || - !strcmp(argv[i], "-geometry") || - !strcmp(argv[i], "-scrns")) - { - return 2; - } - /* end Xnest compat */ - - return KdProcessArgument (argc, argv, i); -} - -void -OsVendorInit (void) -{ - EPHYR_DBG("mark"); - - if (hostx_want_host_cursor()) - { - ephyrFuncs.initCursor = &ephyrCursorInit; - ephyrFuncs.enableCursor = &ephyrCursorEnable; - } - - KdOsInit (&EphyrOsFuncs); -} - -/* 'Fake' cursor stuff, could be improved */ - -static Bool -ephyrRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) -{ - return TRUE; -} - -static Bool -ephyrUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor) -{ - return TRUE; -} - -static void -ephyrSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y) -{ - ; -} - -static void -ephyrMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) -{ - ; -} - -static Bool -ephyrDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen) -{ - return TRUE; -} - -miPointerSpriteFuncRec EphyrPointerSpriteFuncs = { - ephyrRealizeCursor, - ephyrUnrealizeCursor, - ephyrSetCursor, - ephyrMoveCursor, - ephyrDeviceCursorInitialize, - NULL -}; - - -Bool -ephyrCursorInit(ScreenPtr pScreen) -{ - miPointerInitialize(pScreen, - &EphyrPointerSpriteFuncs, - &ephyrPointerScreenFuncs, - FALSE); - - return TRUE; -} - -void -ephyrCursorEnable(ScreenPtr pScreen) -{ - ; -} - -KdCardFuncs ephyrFuncs = { - ephyrCardInit, /* cardinit */ - ephyrScreenInit, /* scrinit */ - ephyrInitScreen, /* initScreen */ - ephyrFinishInitScreen, /* finishInitScreen */ - ephyrCreateResources, /* createRes */ - ephyrPreserve, /* preserve */ - ephyrEnable, /* enable */ - ephyrDPMS, /* dpms */ - ephyrDisable, /* disable */ - ephyrRestore, /* restore */ - ephyrScreenFini, /* scrfini */ - ephyrCardFini, /* cardfini */ - - 0, /* initCursor */ - 0, /* enableCursor */ - 0, /* disableCursor */ - 0, /* finiCursor */ - 0, /* recolorCursor */ - - 0, /* initAccel */ - 0, /* enableAccel */ - 0, /* disableAccel */ - 0, /* finiAccel */ - - ephyrGetColors,/* getColors */ - ephyrPutColors, /* putColors */ -}; +/*
+ * Xephyr - A kdrive X server thats runs in a host X window.
+ * Authored by Matthew Allum <mallum@o-hand.com>
+ *
+ * Copyright © 2004 Nokia
+ *
+ * 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 Nokia not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Nokia makes no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * NOKIA DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL NOKIA 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_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "ephyr.h"
+#include "ephyrlog.h"
+
+extern Window EphyrPreExistingHostWin;
+extern Bool EphyrWantGrayScale;
+extern Bool kdHasPointer;
+extern Bool kdHasKbd;
+
+#ifdef GLXEXT
+extern Bool ephyrNoDRI;
+extern Bool noGlxVisualInit;
+#endif
+extern Bool ephyrNoXV;
+
+#ifdef KDRIVE_EVDEV
+extern KdPointerDriver LinuxEvdevMouseDriver;
+extern KdKeyboardDriver LinuxEvdevKeyboardDriver;
+#endif
+
+void processScreenArg (char *screen_size, char *parent_id) ;
+
+void
+InitCard (char *name)
+{
+ EPHYR_DBG("mark");
+ KdCardInfoAdd (&ephyrFuncs, 0);
+}
+
+#ifndef _MSC_VER
+void
+InitOutput (ScreenInfo *pScreenInfo, int argc, char **argv)
+{
+ KdInitOutput (pScreenInfo, argc, argv);
+}
+
+void
+InitInput (int argc, char **argv)
+{
+ KdKeyboardInfo *ki;
+ KdPointerInfo *pi;
+
+ KdAddKeyboardDriver(&EphyrKeyboardDriver);
+#ifdef KDRIVE_EVDEV
+ KdAddKeyboardDriver(&LinuxEvdevKeyboardDriver);
+#endif
+ KdAddPointerDriver(&EphyrMouseDriver);
+#ifdef KDRIVE_EVDEV
+ KdAddPointerDriver(&LinuxEvdevMouseDriver);
+#endif
+
+ if (!kdHasKbd) {
+ ki = KdNewKeyboard();
+ if (!ki)
+ FatalError("Couldn't create Xephyr keyboard\n");
+ ki->driver = &EphyrKeyboardDriver;
+ KdAddKeyboard(ki);
+ }
+
+ if (!kdHasPointer) {
+ pi = KdNewPointer();
+ if (!pi)
+ FatalError("Couldn't create Xephyr pointer\n");
+ pi->driver = &EphyrMouseDriver;
+ KdAddPointer(pi);
+ }
+
+ KdInitInput();
+}
+
+void
+CloseInput (void)
+{
+}
+
+#ifdef DDXBEFORERESET
+void
+ddxBeforeReset (void)
+{
+}
+#endif
+
+void
+ddxUseMsg (void)
+{
+ KdUseMsg();
+
+ ErrorF("\nXephyr Option Usage:\n");
+ ErrorF("-parent <XID> Use existing window as Xephyr root win\n");
+ ErrorF("-host-cursor Re-use exisiting X host server cursor\n");
+ ErrorF("-fullscreen Attempt to run Xephyr fullscreen\n");
+ ErrorF("-grayscale Simulate 8bit grayscale\n");
+ ErrorF("-fakexa Simulate acceleration using software rendering\n");
+ ErrorF("-verbosity <level> Set log verbosity level\n");
+#ifdef GLXEXT
+ ErrorF("-nodri do not use DRI\n");
+#endif
+ ErrorF("-noxv do not use XV\n");
+ ErrorF("-name [name] define the name in the WM_CLASS property\n");
+ ErrorF("-title [title] set the window title in the WM_NAME property\n");
+ ErrorF("\n");
+
+ exit(1);
+}
+#endif
+
+void
+processScreenArg (char *screen_size, char *parent_id)
+{
+ KdCardInfo *card;
+
+ InitCard (0); /*Put each screen on a separate card*/
+ card = KdCardInfoLast ();
+
+ if (card)
+ {
+ KdScreenInfo *screen;
+ unsigned long p_id = 0;
+
+ screen = KdScreenInfoAdd (card);
+ KdParseScreen (screen, screen_size);
+
+ if (parent_id)
+ {
+ p_id = strtol (parent_id, NULL, 0);
+ }
+ EPHYR_DBG ("screen number:%d\n", screen->mynum) ;
+ hostx_add_screen (screen, p_id, screen->mynum);
+ }
+ else
+ {
+ ErrorF("No matching card found!\n");
+ }
+}
+
+#ifndef _MSC_VER
+int
+ddxProcessArgument (int argc, char **argv, int i)
+{
+ static char* parent = NULL;
+ EPHYR_DBG("mark argv[%d]='%s'", i, argv[i] );
+
+ if (i == 1)
+ {
+ hostx_use_resname(basename(argv[0]), 0);
+ }
+
+ if (!strcmp (argv[i], "-parent"))
+ {
+ if(i+1 < argc)
+ {
+ int j;
+ /* If parent is specified and a screen argument follows, don't do
+ * anything, let the -screen handling init the rest */
+ for (j = i; j < argc; j++)
+ {
+ if (!strcmp(argv[j], "-screen"))
+ {
+ parent = argv[i + 1];
+ return 2;
+ }
+ }
+
+ processScreenArg ("100x100", argv[i+1]);
+ return 2;
+ }
+
+ UseMsg();
+ exit(1);
+ }
+ else if (!strcmp (argv[i], "-screen"))
+ {
+ if ((i+1) < argc)
+ {
+ processScreenArg (argv[i+1], parent);
+ parent = NULL;
+ return 2;
+ }
+
+ UseMsg();
+ exit(1);
+ }
+ else if (!strcmp (argv[i], "-host-cursor"))
+ {
+ hostx_use_host_cursor();
+ return 1;
+ }
+ else if (!strcmp (argv[i], "-fullscreen"))
+ {
+ hostx_use_fullscreen();
+ return 1;
+ }
+ else if (!strcmp (argv[i], "-grayscale"))
+ {
+ EphyrWantGrayScale = 1;
+ return 1;
+ }
+ else if (!strcmp (argv[i], "-fakexa"))
+ {
+ ephyrFuncs.initAccel = ephyrDrawInit;
+ ephyrFuncs.enableAccel = ephyrDrawEnable;
+ ephyrFuncs.disableAccel = ephyrDrawDisable;
+ ephyrFuncs.finiAccel = ephyrDrawFini;
+ return 1;
+ }
+ else if (!strcmp (argv[i], "-verbosity"))
+ {
+ if(i+1 < argc && argv[i+1][0] != '-')
+ {
+ int verbosity=atoi (argv[i+1]) ;
+ LogSetParameter (XLOG_VERBOSITY, verbosity) ;
+ EPHYR_LOG ("set verbosiry to %d\n", verbosity) ;
+ return 2 ;
+ }
+ else
+ {
+ UseMsg() ;
+ exit(1) ;
+ }
+ }
+#ifdef GLXEXT
+ else if (!strcmp (argv[i], "-nodri"))
+ {
+ noGlxVisualInit = FALSE ;
+ ephyrNoDRI = TRUE ;
+ EPHYR_LOG ("no direct rendering enabled\n") ;
+ return 1 ;
+ }
+#endif
+ else if (!strcmp (argv[i], "-noxv"))
+ {
+ ephyrNoXV = TRUE ;
+ EPHYR_LOG ("no XVideo enabled\n") ;
+ return 1 ;
+ }
+ else if (!strcmp (argv[i], "-name"))
+ {
+ if (i+1 < argc && argv[i+1][0] != '-')
+ {
+ hostx_use_resname(argv[i+1], 1);
+ return 2;
+ }
+ else
+ {
+ UseMsg();
+ return 0;
+ }
+ }
+ else if (!strcmp (argv[i], "-title"))
+ {
+ if (i+1 < argc && argv[i+1][0] != '-')
+ {
+ hostx_set_title(argv[i+1]);
+ return 2;
+ }
+ else
+ {
+ UseMsg();
+ return 0;
+ }
+ }
+ else if (argv[i][0] == ':')
+ {
+ hostx_set_display_name(argv[i]);
+ }
+ /* Xnest compatibility */
+ else if (!strcmp(argv[i], "-display"))
+ {
+ hostx_set_display_name(argv[i+1]);
+ return 2;
+ }
+ else if (!strcmp(argv[i], "-sync") ||
+ !strcmp(argv[i], "-full") ||
+ !strcmp(argv[i], "-sss") ||
+ !strcmp(argv[i], "-install"))
+ {
+ return 1;
+ }
+ else if (!strcmp(argv[i], "-bw") ||
+ !strcmp(argv[i], "-class") ||
+ !strcmp(argv[i], "-geometry") ||
+ !strcmp(argv[i], "-scrns"))
+ {
+ return 2;
+ }
+ /* end Xnest compat */
+
+ return KdProcessArgument (argc, argv, i);
+}
+
+void
+OsVendorInit (void)
+{
+ EPHYR_DBG("mark");
+
+ if (hostx_want_host_cursor())
+ {
+ ephyrFuncs.initCursor = &ephyrCursorInit;
+ ephyrFuncs.enableCursor = &ephyrCursorEnable;
+ }
+
+ KdOsInit (&EphyrOsFuncs);
+}
+
+#ifdef DDXOSFATALERROR
+void
+OsVendorFatalError(void)
+{
+}
+#endif
+
+#endif
+
+/* 'Fake' cursor stuff, could be improved */
+
+static Bool
+ephyrRealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+{
+ return TRUE;
+}
+
+static Bool
+ephyrUnrealizeCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor)
+{
+ return TRUE;
+}
+
+static void
+ephyrSetCursor(DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, int y)
+{
+ ;
+}
+
+static void
+ephyrMoveCursor(DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ ;
+}
+
+static Bool
+ephyrDeviceCursorInitialize(DeviceIntPtr pDev, ScreenPtr pScreen)
+{
+ return TRUE;
+}
+
+miPointerSpriteFuncRec EphyrPointerSpriteFuncs = {
+ ephyrRealizeCursor,
+ ephyrUnrealizeCursor,
+ ephyrSetCursor,
+ ephyrMoveCursor,
+ ephyrDeviceCursorInitialize,
+ NULL
+};
+
+
+Bool
+ephyrCursorInit(ScreenPtr pScreen)
+{
+ miPointerInitialize(pScreen,
+ &EphyrPointerSpriteFuncs,
+ &ephyrPointerScreenFuncs,
+ FALSE);
+
+ return TRUE;
+}
+
+void
+ephyrCursorEnable(ScreenPtr pScreen)
+{
+ ;
+}
+
+KdCardFuncs ephyrFuncs = {
+ ephyrCardInit, /* cardinit */
+ ephyrScreenInit, /* scrinit */
+ ephyrInitScreen, /* initScreen */
+ ephyrFinishInitScreen, /* finishInitScreen */
+ ephyrCreateResources, /* createRes */
+ ephyrPreserve, /* preserve */
+ ephyrEnable, /* enable */
+ ephyrDPMS, /* dpms */
+ ephyrDisable, /* disable */
+ ephyrRestore, /* restore */
+ ephyrScreenFini, /* scrfini */
+ ephyrCardFini, /* cardfini */
+
+ 0, /* initCursor */
+ 0, /* enableCursor */
+ 0, /* disableCursor */
+ 0, /* finiCursor */
+ 0, /* recolorCursor */
+
+ 0, /* initAccel */
+ 0, /* enableAccel */
+ 0, /* disableAccel */
+ 0, /* finiAccel */
+
+ ephyrGetColors,/* getColors */
+ ephyrPutColors, /* putColors */
+};
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrlog.h b/xorg-server/hw/kdrive/ephyr/ephyrlog.h index a07a0a097..ba52a3bce 100644 --- a/xorg-server/hw/kdrive/ephyr/ephyrlog.h +++ b/xorg-server/hw/kdrive/ephyr/ephyrlog.h @@ -43,14 +43,14 @@ #ifndef EPHYR_LOG #define EPHYR_LOG(...) \ LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, "in %s:%d:%s: ",\ - __FILE__, __LINE__, __func__) ; \ + __FILE__, __LINE__, __FUNCTION__) ; \ LogMessageVerb(X_NOTICE, INFO_LOG_LEVEL, __VA_ARGS__) #endif /*nomadik_log*/ #ifndef EPHYR_LOG_ERROR #define EPHYR_LOG_ERROR(...) \ LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, "Error:in %s:%d:%s: ",\ - __FILE__, __LINE__, __func__) ; \ + __FILE__, __LINE__, __FUNCTION__) ; \ LogMessageVerb(X_NOTICE, ERROR_LOG_LEVEL, __VA_ARGS__) #endif /*EPHYR_LOG_ERROR*/ diff --git a/xorg-server/hw/kdrive/ephyr/hostx.c b/xorg-server/hw/kdrive/ephyr/hostx.c index d546370ba..7a828eb31 100644 --- a/xorg-server/hw/kdrive/ephyr/hostx.c +++ b/xorg-server/hw/kdrive/ephyr/hostx.c @@ -47,9 +47,11 @@ #include <string.h> /* for memset */ #include <time.h> +#ifndef _MSC_VER #include <sys/ipc.h> #include <sys/shm.h> #include <sys/time.h> +#endif #include <X11/Xlib.h> #include <X11/Xutil.h> @@ -208,7 +210,11 @@ hostx_add_screen (EphyrScreenInfo screen, void hostx_set_display_name (char *name) { +#ifdef _MSC_VER + __asm int 3; +#else HostX.server_dpy_name = strdup (name); +#endif } void @@ -475,6 +481,9 @@ hostx_init (void) } /* Try to get share memory ximages for a little bit more speed */ +#ifdef _MSC_VER + __asm int 3; +#else if (!XShmQueryExtension(HostX.dpy) || getenv("XEPHYR_NO_SHM")) { fprintf(stderr, "\nXephyr unable to use SHM XImages\n"); @@ -505,6 +514,7 @@ hostx_init (void) shmdt(shminfo.shmaddr); shmctl(shminfo.shmid, IPC_RMID, 0); } +#endif XFlush(HostX.dpy); @@ -647,7 +657,7 @@ hostx_screen_init (EphyrScreenInfo screen, struct EphyrHostScreen *host_screen = host_screen_from_screen_info (screen); if (!host_screen) { - fprintf (stderr, "%s: Error in accessing hostx data\n", __func__ ); + fprintf (stderr, "%s: Error in accessing hostx data\n", __FUNCTION__ ); exit(1); } @@ -662,10 +672,14 @@ hostx_screen_init (EphyrScreenInfo screen, if (HostX.have_shm) { +#ifdef _MSC_VER + __asm int 3; +#else XShmDetach(HostX.dpy, &host_screen->shminfo); XDestroyImage (host_screen->ximg); shmdt(host_screen->shminfo.shmaddr); shmctl(host_screen->shminfo.shmid, IPC_RMID, 0); +#endif } else { @@ -681,6 +695,9 @@ hostx_screen_init (EphyrScreenInfo screen, if (HostX.have_shm) { +#ifdef _MSC_VER +__asm int 3; +#else host_screen->ximg = XShmCreateImage (HostX.dpy, HostX.visual, HostX.depth, ZPixmap, NULL, &host_screen->shminfo, width, buffer_height ); @@ -706,6 +723,7 @@ hostx_screen_init (EphyrScreenInfo screen, XShmAttach(HostX.dpy, &host_screen->shminfo); shm_success = True; } +#endif } if (!shm_success) @@ -834,9 +852,13 @@ hostx_paint_rect (EphyrScreenInfo screen, if (HostX.have_shm) { +#ifdef _MSC_VER + __asm int 3; +#else XShmPutImage (HostX.dpy, host_screen->win, HostX.gc, host_screen->ximg, sx, sy, dx, dy, width, height, False); +#endif } else { @@ -852,6 +874,9 @@ hostx_paint_debug_rect (struct EphyrHostScreen *host_screen, int x, int y, int width, int height) { +#ifdef _MSC_VER + __asm int 3; +#else struct timespec tspec; tspec.tv_sec = HostX.damage_debug_msec / (1000000); @@ -867,6 +892,7 @@ hostx_paint_debug_rect (struct EphyrHostScreen *host_screen, /* nanosleep seems to work better than usleep for me... */ nanosleep(&tspec, NULL); +#endif } void @@ -1288,8 +1314,12 @@ hostx_set_window_bounding_rectangles (int a_window, rects[i].width, rects[i].height) ; } /*this aways returns 1*/ +#ifdef _MSC_VER + __asm int 3; +#else XShapeCombineRectangles (dpy, a_window, ShapeBounding, 0, 0, rects, a_num_rects, ShapeSet, YXBanded) ; +#endif is_ok = TRUE ; if (rects) { @@ -1325,8 +1355,12 @@ hostx_set_window_clipping_rectangles (int a_window, rects[i].width, rects[i].height) ; } /*this aways returns 1*/ +#ifdef _MSC_VER + __asm int 3; +#else XShapeCombineRectangles (dpy, a_window, ShapeClip, 0, 0, rects, a_num_rects, ShapeSet, YXBanded) ; +#endif is_ok = TRUE ; if (rects) { @@ -1341,12 +1375,16 @@ int hostx_has_xshape (void) { int event_base=0, error_base=0 ; +#ifdef _MSC_VER + __asm int 3; +#else Display *dpy=hostx_get_display () ; if (!XShapeQueryExtension (dpy, &event_base, &error_base)) { return FALSE ; } +#endif return TRUE; } diff --git a/xorg-server/hw/kdrive/ephyr/hostx.h b/xorg-server/hw/kdrive/ephyr/hostx.h index e65e0c9bc..f455b3003 100644 --- a/xorg-server/hw/kdrive/ephyr/hostx.h +++ b/xorg-server/hw/kdrive/ephyr/hostx.h @@ -35,8 +35,12 @@ #define EPHYR_DBG(x, a...) \ fprintf(stderr, __FILE__ ":%d,%s() " x "\n", __LINE__, __func__, ##a) #else +#ifdef _MSC_VER +#define EPHYR_DBG() +#else #define EPHYR_DBG(x, a...) do {} while (0) #endif +#endif typedef struct EphyrHostXVars EphyrHostXVars; typedef struct EphyrHostXEvent EphyrHostXEvent; diff --git a/xorg-server/hw/kdrive/ephyr/makefile b/xorg-server/hw/kdrive/ephyr/makefile new file mode 100644 index 000000000..eba9a93e1 --- /dev/null +++ b/xorg-server/hw/kdrive/ephyr/makefile @@ -0,0 +1,6 @@ +LIBRARY = libxephyr + +CSRCS=ephyrinit.c ephyr.c hostx.c + +INCLUDES += ..\src ..\..\..\exa + diff --git a/xorg-server/hw/kdrive/src/kdrive.c b/xorg-server/hw/kdrive/src/kdrive.c index 7675c1e86..7e3d3a095 100644 --- a/xorg-server/hw/kdrive/src/kdrive.c +++ b/xorg-server/hw/kdrive/src/kdrive.c @@ -1,1285 +1,1291 @@ -/* - * Copyright © 1999 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_CONFIG_H -#include <kdrive-config.h> -#endif -#include "kdrive.h" -#include <mivalidate.h> -#include <dixstruct.h> -#include "privates.h" -#ifdef RANDR -#include <randrstr.h> -#endif - -#ifdef XV -#include "kxv.h" -#endif - -#ifdef DPMSExtension -#include "dpmsproc.h" -#endif - -#ifdef HAVE_EXECINFO_H -#include <execinfo.h> -#endif - -#include <signal.h> - -typedef struct _kdDepths { - CARD8 depth; - CARD8 bpp; -} KdDepths; - -KdDepths kdDepths[] = { - { 1, 1 }, - { 4, 4 }, - { 8, 8 }, - { 15, 16 }, - { 16, 16 }, - { 24, 32 }, - { 32, 32 } -}; - -#define NUM_KD_DEPTHS (sizeof (kdDepths) / sizeof (kdDepths[0])) - -#define KD_DEFAULT_BUTTONS 5 - -static int kdScreenPrivateKeyIndex; -DevPrivateKey kdScreenPrivateKey = &kdScreenPrivateKeyIndex; -unsigned long kdGeneration; - -Bool kdVideoTest; -unsigned long kdVideoTestTime; -Bool kdEmulateMiddleButton; -Bool kdRawPointerCoordinates; -Bool kdDisableZaphod; -Bool kdAllowZap; -Bool kdEnabled; -int kdSubpixelOrder; -int kdVirtualTerminal = -1; -Bool kdSwitchPending; -char *kdSwitchCmd; -DDXPointRec kdOrigin; -Bool kdHasPointer = FALSE; -Bool kdHasKbd = FALSE; - -static Bool kdCaughtSignal = FALSE; - -/* - * Carry arguments from InitOutput through driver initialization - * to KdScreenInit - */ - -KdOsFuncs *kdOsFuncs; - -void -KdSetRootClip (ScreenPtr pScreen, BOOL enable) -{ - WindowPtr pWin = WindowTable[pScreen->myNum]; - WindowPtr pChild; - Bool WasViewable; - Bool anyMarked = FALSE; - WindowPtr pLayerWin; - BoxRec box; - - if (!pWin) - return; - WasViewable = (Bool)(pWin->viewable); - if (WasViewable) - { - for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib) - { - (void) (*pScreen->MarkOverlappedWindows)(pChild, - pChild, - &pLayerWin); - } - (*pScreen->MarkWindow) (pWin); - anyMarked = TRUE; - if (pWin->valdata) - { - if (HasBorder (pWin)) - { - RegionPtr borderVisible; - - borderVisible = REGION_CREATE(pScreen, NullBox, 1); - REGION_SUBTRACT(pScreen, borderVisible, - &pWin->borderClip, &pWin->winSize); - pWin->valdata->before.borderVisible = borderVisible; - } - pWin->valdata->before.resized = TRUE; - } - } - - if (enable) - { - box.x1 = 0; - box.y1 = 0; - box.x2 = pScreen->width; - box.y2 = pScreen->height; - pWin->drawable.width = pScreen->width; - pWin->drawable.height = pScreen->height; - REGION_INIT (pScreen, &pWin->winSize, &box, 1); - REGION_INIT (pScreen, &pWin->borderSize, &box, 1); - REGION_RESET(pScreen, &pWin->borderClip, &box); - REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); - } - else - { - REGION_EMPTY(pScreen, &pWin->borderClip); - REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); - } - - ResizeChildrenWinSize (pWin, 0, 0, 0, 0); - - if (WasViewable) - { - if (pWin->firstChild) - { - anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild, - pWin->firstChild, - (WindowPtr *)NULL); - } - else - { - (*pScreen->MarkWindow) (pWin); - anyMarked = TRUE; - } - - - if (anyMarked) - (*pScreen->ValidateTree)(pWin, NullWindow, VTOther); - } - - if (WasViewable) - { - if (anyMarked) - (*pScreen->HandleExposures)(pWin); - if (anyMarked && pScreen->PostValidateTree) - (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther); - } - if (pWin->realized) - WindowsRestructured (); -} - -void -KdDisableScreen (ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - - if (!pScreenPriv->enabled) - return; - if (!pScreenPriv->closed) - KdSetRootClip (pScreen, FALSE); - KdDisableColormap (pScreen); - if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->disableAccel) - (*pScreenPriv->card->cfuncs->disableAccel) (pScreen); - if (!pScreenPriv->screen->softCursor && pScreenPriv->card->cfuncs->disableCursor) - (*pScreenPriv->card->cfuncs->disableCursor) (pScreen); - if (pScreenPriv->card->cfuncs->dpms) - (*pScreenPriv->card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL); - pScreenPriv->enabled = FALSE; - if(pScreenPriv->card->cfuncs->disable) - (*pScreenPriv->card->cfuncs->disable) (pScreen); -} - -static void -KdDoSwitchCmd (char *reason) -{ - if (kdSwitchCmd) - { - char *command = xalloc (strlen (kdSwitchCmd) + - 1 + - strlen (reason) + - 1); - if (!command) - return; - strcpy (command, kdSwitchCmd); - strcat (command, " "); - strcat (command, reason); - system (command); - xfree (command); - } -} - -void -KdSuspend (void) -{ - KdCardInfo *card; - KdScreenInfo *screen; - - if (kdEnabled) - { - for (card = kdCardInfo; card; card = card->next) - { - for (screen = card->screenList; screen; screen = screen->next) - if (screen->mynum == card->selected && screen->pScreen) - KdDisableScreen (screen->pScreen); - if (card->driver && card->cfuncs->restore) - (*card->cfuncs->restore) (card); - } - KdDisableInput (); - KdDoSwitchCmd ("suspend"); - } -} - -void -KdDisableScreens (void) -{ - KdSuspend (); - if (kdEnabled) - { - if (kdOsFuncs->Disable) - (*kdOsFuncs->Disable) (); - kdEnabled = FALSE; - } -} - -Bool -KdEnableScreen (ScreenPtr pScreen) -{ - KdScreenPriv (pScreen); - - if (pScreenPriv->enabled) - return TRUE; - if(pScreenPriv->card->cfuncs->enable) - if (!(*pScreenPriv->card->cfuncs->enable) (pScreen)) - return FALSE; - pScreenPriv->enabled = TRUE; - pScreenPriv->dpmsState = KD_DPMS_NORMAL; - pScreenPriv->card->selected = pScreenPriv->screen->mynum; - if (!pScreenPriv->screen->softCursor && pScreenPriv->card->cfuncs->enableCursor) - (*pScreenPriv->card->cfuncs->enableCursor) (pScreen); - if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->enableAccel) - (*pScreenPriv->card->cfuncs->enableAccel) (pScreen); - KdEnableColormap (pScreen); - KdSetRootClip (pScreen, TRUE); - if (pScreenPriv->card->cfuncs->dpms) - (*pScreenPriv->card->cfuncs->dpms) (pScreen, pScreenPriv->dpmsState); - return TRUE; -} - -void -KdResume (void) -{ - KdCardInfo *card; - KdScreenInfo *screen; - - if (kdEnabled) - { - KdDoSwitchCmd ("resume"); - for (card = kdCardInfo; card; card = card->next) - { - if(card->cfuncs->preserve) - (*card->cfuncs->preserve) (card); - for (screen = card->screenList; screen; screen = screen->next) - if (screen->mynum == card->selected && screen->pScreen) - KdEnableScreen (screen->pScreen); - } - KdEnableInput (); - KdReleaseAllKeys (); - } -} - -void -KdEnableScreens (void) -{ - if (!kdEnabled) - { - kdEnabled = TRUE; - if (kdOsFuncs->Enable) - (*kdOsFuncs->Enable) (); - } - KdResume (); -} - -void -KdProcessSwitch (void) -{ - if (kdEnabled) - KdDisableScreens (); - else - KdEnableScreens (); -} - -void -AbortDDX(void) -{ - KdDisableScreens (); - if (kdOsFuncs) - { - if (kdEnabled && kdOsFuncs->Disable) - (*kdOsFuncs->Disable) (); - if (kdOsFuncs->Fini) - (*kdOsFuncs->Fini) (); - KdDoSwitchCmd ("stop"); - } - - if (kdCaughtSignal) - abort(); -} - -void -ddxGiveUp (void) -{ - AbortDDX (); -} - -Bool kdDumbDriver; -Bool kdSoftCursor; - -char * -KdParseFindNext (char *cur, char *delim, char *save, char *last) -{ - while (*cur && !strchr (delim, *cur)) - { - *save++ = *cur++; - } - *save = 0; - *last = *cur; - if (*cur) - cur++; - return cur; -} - -Rotation -KdAddRotation (Rotation a, Rotation b) -{ - Rotation rotate = (a & RR_Rotate_All) * (b & RR_Rotate_All); - Rotation reflect = (a & RR_Reflect_All) ^ (b & RR_Reflect_All); - - if (rotate > RR_Rotate_270) - rotate /= (RR_Rotate_270 * RR_Rotate_90); - return reflect | rotate; -} - -Rotation -KdSubRotation (Rotation a, Rotation b) -{ - Rotation rotate = (a & RR_Rotate_All) * 16 / (b & RR_Rotate_All); - Rotation reflect = (a & RR_Reflect_All) ^ (b & RR_Reflect_All); - - if (rotate > RR_Rotate_270) - rotate /= (RR_Rotate_270 * RR_Rotate_90); - return reflect | rotate; -} - -void -KdParseScreen (KdScreenInfo *screen, - char *arg) -{ - char delim; - char save[1024]; - int i; - int pixels, mm; - - screen->dumb = kdDumbDriver; - screen->softCursor = kdSoftCursor; - screen->origin = kdOrigin; - screen->randr = RR_Rotate_0; - screen->width = 0; - screen->height = 0; - screen->width_mm = 0; - screen->height_mm = 0; - screen->subpixel_order = kdSubpixelOrder; - screen->rate = 0; - screen->fb.depth = 0; - if (!arg) - return; - if (strlen (arg) >= sizeof (save)) - return; - - for (i = 0; i < 2; i++) - { - arg = KdParseFindNext (arg, "x/@XY", save, &delim); - if (!save[0]) - return; - - pixels = atoi(save); - mm = 0; - - if (delim == '/') - { - arg = KdParseFindNext (arg, "x@XY", save, &delim); - if (!save[0]) - return; - mm = atoi(save); - } - - if (i == 0) - { - screen->width = pixels; - screen->width_mm = mm; - } - else - { - screen->height = pixels; - screen->height_mm = mm; - } - if (delim != 'x' && delim != '@' && delim != 'X' && delim != 'Y') - return; - } - - kdOrigin.x += screen->width; - kdOrigin.y = 0; - kdDumbDriver = FALSE; - kdSoftCursor = FALSE; - kdSubpixelOrder = SubPixelUnknown; - - if (delim == '@') - { - arg = KdParseFindNext (arg, "xXY", save, &delim); - if (save[0]) - { - int rotate = atoi (save); - if (rotate < 45) - screen->randr = RR_Rotate_0; - else if (rotate < 135) - screen->randr = RR_Rotate_90; - else if (rotate < 225) - screen->randr = RR_Rotate_180; - else if (rotate < 315) - screen->randr = RR_Rotate_270; - else - screen->randr = RR_Rotate_0; - } - } - if (delim == 'X') - { - arg = KdParseFindNext (arg, "xY", save, &delim); - screen->randr |= RR_Reflect_X; - } - - if (delim == 'Y') - { - arg = KdParseFindNext (arg, "xY", save, &delim); - screen->randr |= RR_Reflect_Y; - } - - arg = KdParseFindNext (arg, "x/,", save, &delim); - if (save[0]) - { - screen->fb.depth = atoi(save); - if (delim == '/') - { - arg = KdParseFindNext (arg, "x,", save, &delim); - if (save[0]) - screen->fb.bitsPerPixel = atoi (save); - } - else - screen->fb.bitsPerPixel = 0; - } - - if (delim == 'x') - { - arg = KdParseFindNext (arg, "x", save, &delim); - if (save[0]) - screen->rate = atoi(save); - } -} - -/* - * Mouse argument syntax: - * - * device,protocol,options... - * - * Options are any of: - * 1-5 n button mouse - * 2button emulate middle button - * {NMO} Reorder buttons - */ - -void -KdParseRgba (char *rgba) -{ - if (!strcmp (rgba, "rgb")) - kdSubpixelOrder = SubPixelHorizontalRGB; - else if (!strcmp (rgba, "bgr")) - kdSubpixelOrder = SubPixelHorizontalBGR; - else if (!strcmp (rgba, "vrgb")) - kdSubpixelOrder = SubPixelVerticalRGB; - else if (!strcmp (rgba, "vbgr")) - kdSubpixelOrder = SubPixelVerticalBGR; - else if (!strcmp (rgba, "none")) - kdSubpixelOrder = SubPixelNone; - else - kdSubpixelOrder = SubPixelUnknown; -} - -void -KdUseMsg (void) -{ - ErrorF("\nTinyX Device Dependent Usage:\n"); - ErrorF("-screen WIDTH[/WIDTHMM]xHEIGHT[/HEIGHTMM][@ROTATION][X][Y][xDEPTH/BPP[xFREQ]] Specify screen characteristics\n"); - ErrorF("-rgba rgb/bgr/vrgb/vbgr/none Specify subpixel ordering for LCD panels\n"); - ErrorF("-mouse driver [,n,,options] Specify the pointer driver and its options (n is the number of buttons)\n"); - ErrorF("-keybd driver [,,options] Specify the keyboard driver and its options\n"); - ErrorF("-zaphod Disable cursor screen switching\n"); - ErrorF("-2button Emulate 3 button mouse\n"); - ErrorF("-3button Disable 3 button mouse emulation\n"); - ErrorF("-rawcoord Don't transform pointer coordinates on rotation\n"); - ErrorF("-dumb Disable hardware acceleration\n"); - ErrorF("-softCursor Force software cursor\n"); - ErrorF("-videoTest Start the server, pause momentarily and exit\n"); - ErrorF("-origin X,Y Locates the next screen in the the virtual screen (Xinerama)\n"); - ErrorF("-switchCmd Command to execute on vt switch\n"); - ErrorF("-zap Terminate server on Ctrl+Alt+Backspace\n"); - ErrorF("vtxx Use virtual terminal xx instead of the next available\n"); -} - -int -KdProcessArgument (int argc, char **argv, int i) -{ - KdCardInfo *card; - KdScreenInfo *screen; - - if (!strcmp (argv[i], "-screen")) - { - if ((i+1) < argc) - { - card = KdCardInfoLast (); - if (!card) - { - InitCard (0); - card = KdCardInfoLast (); - } - if (card) { - screen = KdScreenInfoAdd (card); - KdParseScreen (screen, argv[i+1]); - } else - ErrorF("No matching card found!\n"); - } - else - UseMsg (); - return 2; - } - if (!strcmp (argv[i], "-zaphod")) - { - kdDisableZaphod = TRUE; - return 1; - } - if (!strcmp (argv[i], "-zap")) - { - kdAllowZap = TRUE; - return 1; - } - if (!strcmp (argv[i], "-3button")) - { - kdEmulateMiddleButton = FALSE; - return 1; - } - if (!strcmp (argv[i], "-2button")) - { - kdEmulateMiddleButton = TRUE; - return 1; - } - if (!strcmp (argv[i], "-rawcoord")) - { - kdRawPointerCoordinates = 1; - return 1; - } - if (!strcmp (argv[i], "-dumb")) - { - kdDumbDriver = TRUE; - return 1; - } - if (!strcmp (argv[i], "-softCursor")) - { - kdSoftCursor = TRUE; - return 1; - } - if (!strcmp (argv[i], "-videoTest")) - { - kdVideoTest = TRUE; - return 1; - } - if (!strcmp (argv[i], "-origin")) - { - if ((i+1) < argc) - { - char *x = argv[i+1]; - char *y = strchr (x, ','); - if (x) - kdOrigin.x = atoi (x); - else - kdOrigin.x = 0; - if (y) - kdOrigin.y = atoi(y+1); - else - kdOrigin.y = 0; - } - else - UseMsg (); - return 2; - } - if (!strcmp (argv[i], "-rgba")) - { - if ((i+1) < argc) - KdParseRgba (argv[i+1]); - else - UseMsg (); - return 2; - } - if (!strcmp (argv[i], "-switchCmd")) - { - if ((i+1) < argc) - kdSwitchCmd = argv[i+1]; - else - UseMsg (); - return 2; - } - if (!strncmp (argv[i], "vt", 2) && - sscanf (argv[i], "vt%2d", &kdVirtualTerminal) == 1) - { - return 1; - } - if (!strcmp (argv[i], "-mouse") || - !strcmp (argv[i], "-pointer")) { - if (i + 1 >= argc) - UseMsg(); - KdAddConfigPointer(argv[i + 1]); - kdHasPointer = TRUE; - return 2; - } - if (!strcmp (argv[i], "-keybd")) { - if (i + 1 >= argc) - UseMsg(); - KdAddConfigKeyboard(argv[i + 1]); - kdHasKbd = TRUE; - return 2; - } - - return 0; -} - -/* - * These are getting tossed in here until I can think of where - * they really belong - */ - -void -KdOsInit (KdOsFuncs *pOsFuncs) -{ - kdOsFuncs = pOsFuncs; - if (pOsFuncs) - { - if (serverGeneration == 1) - { - KdDoSwitchCmd ("start"); - if (pOsFuncs->Init) - (*pOsFuncs->Init) (); - } - } -} - -Bool -KdAllocatePrivates (ScreenPtr pScreen) -{ - KdPrivScreenPtr pScreenPriv; - - if (kdGeneration != serverGeneration) - kdGeneration = serverGeneration; - - pScreenPriv = xcalloc(1, sizeof (*pScreenPriv)); - if (!pScreenPriv) - return FALSE; - KdSetScreenPriv (pScreen, pScreenPriv); - return TRUE; -} - -Bool -KdCreateScreenResources (ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdCardInfo *card = pScreenPriv->card; - Bool ret; - - pScreen->CreateScreenResources = pScreenPriv->CreateScreenResources; - if(pScreen->CreateScreenResources) - ret = (*pScreen->CreateScreenResources) (pScreen); - else - ret= -1; - pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources; - pScreen->CreateScreenResources = KdCreateScreenResources; - if (ret && card->cfuncs->createRes) - ret = (*card->cfuncs->createRes) (pScreen); - return ret; -} - -Bool -KdCloseScreen (int index, ScreenPtr pScreen) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - KdCardInfo *card = pScreenPriv->card; - Bool ret; - - pScreenPriv->closed = TRUE; - pScreen->CloseScreen = pScreenPriv->CloseScreen; - if(pScreen->CloseScreen) - ret = (*pScreen->CloseScreen) (index, pScreen); - else - ret = TRUE; - - if (pScreenPriv->dpmsState != KD_DPMS_NORMAL) - (*card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL); - - if (screen->mynum == card->selected) - KdDisableScreen (pScreen); - - /* - * Restore video hardware when last screen is closed - */ - if (screen == card->screenList) - { - if (kdEnabled && card->cfuncs->restore) - (*card->cfuncs->restore) (card); - } - - if (!pScreenPriv->screen->dumb && card->cfuncs->finiAccel) - (*card->cfuncs->finiAccel) (pScreen); - - if (!pScreenPriv->screen->softCursor && card->cfuncs->finiCursor) - (*card->cfuncs->finiCursor) (pScreen); - - if(card->cfuncs->scrfini) - (*card->cfuncs->scrfini) (screen); - - /* - * Clean up card when last screen is closed, DIX closes them in - * reverse order, thus we check for when the first in the list is closed - */ - if (screen == card->screenList) - { - if(card->cfuncs->cardfini) - (*card->cfuncs->cardfini) (card); - /* - * Clean up OS when last card is closed - */ - if (card == kdCardInfo) - { - if (kdEnabled) - { - kdEnabled = FALSE; - if(kdOsFuncs->Disable) - (*kdOsFuncs->Disable) (); - } - } - } - - pScreenPriv->screen->pScreen = 0; - - xfree ((pointer) pScreenPriv); - return ret; -} - -Bool -KdSaveScreen (ScreenPtr pScreen, int on) -{ - KdScreenPriv(pScreen); - int dpmsState; - - if (!pScreenPriv->card->cfuncs->dpms) - return FALSE; - - dpmsState = pScreenPriv->dpmsState; - switch (on) { - case SCREEN_SAVER_OFF: - dpmsState = KD_DPMS_NORMAL; - break; - case SCREEN_SAVER_ON: - if (dpmsState == KD_DPMS_NORMAL) - dpmsState = KD_DPMS_NORMAL+1; - break; - case SCREEN_SAVER_CYCLE: - if (dpmsState < KD_DPMS_MAX) - dpmsState++; - break; - case SCREEN_SAVER_FORCER: - break; - } - if (dpmsState != pScreenPriv->dpmsState) - { - if (pScreenPriv->enabled) - (*pScreenPriv->card->cfuncs->dpms) (pScreen, dpmsState); - pScreenPriv->dpmsState = dpmsState; - } - return TRUE; -} - -static Bool -KdCreateWindow (WindowPtr pWin) -{ -#ifndef PHOENIX - if (!pWin->parent) - { - KdScreenPriv(pWin->drawable.pScreen); - - if (!pScreenPriv->enabled) - { - REGION_EMPTY (pWin->drawable.pScreen, &pWin->borderClip); - REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList); - } - } -#endif - return fbCreateWindow (pWin); -} - -void -KdSetSubpixelOrder (ScreenPtr pScreen, Rotation randr) -{ - KdScreenPriv(pScreen); - KdScreenInfo *screen = pScreenPriv->screen; - int subpixel_order = screen->subpixel_order; - Rotation subpixel_dir; - int i; - - static struct { - int subpixel_order; - Rotation direction; - } orders[] = { - { SubPixelHorizontalRGB, RR_Rotate_0 }, - { SubPixelHorizontalBGR, RR_Rotate_180 }, - { SubPixelVerticalRGB, RR_Rotate_270 }, - { SubPixelVerticalBGR, RR_Rotate_90 }, - }; - - static struct { - int bit; - int normal; - int reflect; - } reflects[] = { - { RR_Reflect_X, SubPixelHorizontalRGB, SubPixelHorizontalBGR }, - { RR_Reflect_X, SubPixelHorizontalBGR, SubPixelHorizontalRGB }, - { RR_Reflect_Y, SubPixelVerticalRGB, SubPixelVerticalBGR }, - { RR_Reflect_Y, SubPixelVerticalRGB, SubPixelVerticalRGB }, - }; - - /* map subpixel to direction */ - for (i = 0; i < 4; i++) - if (orders[i].subpixel_order == subpixel_order) - break; - if (i < 4) - { - subpixel_dir = KdAddRotation (randr & RR_Rotate_All, orders[i].direction); - - /* map back to subpixel order */ - for (i = 0; i < 4; i++) - if (orders[i].direction & subpixel_dir) - { - subpixel_order = orders[i].subpixel_order; - break; - } - /* reflect */ - for (i = 0; i < 4; i++) - if ((randr & reflects[i].bit) && - reflects[i].normal == subpixel_order) - { - subpixel_order = reflects[i].reflect; - break; - } - } - PictureSetSubpixelOrder (pScreen, subpixel_order); -} - -/* Pass through AddScreen, which doesn't take any closure */ -static KdScreenInfo *kdCurrentScreen; - -Bool -KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) -{ - KdScreenInfo *screen = kdCurrentScreen; - KdCardInfo *card = screen->card; - KdPrivScreenPtr pScreenPriv; - /* - * note that screen->fb is set up for the nominal orientation - * of the screen; that means if randr is rotated, the values - * there should reflect a rotated frame buffer (or shadow). - */ - Bool rotated = (screen->randr & (RR_Rotate_90|RR_Rotate_270)) != 0; - int width, height, *width_mmp, *height_mmp; - - KdAllocatePrivates (pScreen); - - pScreenPriv = KdGetScreenPriv(pScreen); - - if (!rotated) - { - width = screen->width; - height = screen->height; - width_mmp = &screen->width_mm; - height_mmp = &screen->height_mm; - } - else - { - width = screen->height; - height = screen->width; - width_mmp = &screen->height_mm; - height_mmp = &screen->width_mm; - } - screen->pScreen = pScreen; - pScreenPriv->screen = screen; - pScreenPriv->card = card; - pScreenPriv->bytesPerPixel = screen->fb.bitsPerPixel >> 3; - pScreenPriv->dpmsState = KD_DPMS_NORMAL; -#ifdef PANORAMIX - dixScreenOrigins[pScreen->myNum] = screen->origin; -#endif - - if (!monitorResolution) - monitorResolution = 75; - /* - * This is done in this order so that backing store wraps - * our GC functions; fbFinishScreenInit initializes MI - * backing store - */ - if (!fbSetupScreen (pScreen, - screen->fb.frameBuffer, - width, height, - monitorResolution, monitorResolution, - screen->fb.pixelStride, - screen->fb.bitsPerPixel)) - { - return FALSE; - } - - /* - * Set colormap functions - */ - pScreen->InstallColormap = KdInstallColormap; - pScreen->UninstallColormap = KdUninstallColormap; - pScreen->ListInstalledColormaps = KdListInstalledColormaps; - pScreen->StoreColors = KdStoreColors; - - pScreen->SaveScreen = KdSaveScreen; - pScreen->CreateWindow = KdCreateWindow; - - if (!fbFinishScreenInit (pScreen, - screen->fb.frameBuffer, - width, height, - monitorResolution, monitorResolution, - screen->fb.pixelStride, - screen->fb.bitsPerPixel)) - { - return FALSE; - } - - /* - * Fix screen sizes; for some reason mi takes dpi instead of mm. - * Rounding errors are annoying - */ - if (*width_mmp) - pScreen->mmWidth = *width_mmp; - else - *width_mmp = pScreen->mmWidth; - if (*height_mmp) - pScreen->mmHeight = *height_mmp; - else - *height_mmp = pScreen->mmHeight; - - /* - * Plug in our own block/wakeup handlers. - * miScreenInit installs NoopDDA in both places - */ - pScreen->BlockHandler = KdBlockHandler; - pScreen->WakeupHandler = KdWakeupHandler; - -#ifdef RENDER - if (!fbPictureInit (pScreen, 0, 0)) - return FALSE; -#endif - if (card->cfuncs->initScreen) - if (!(*card->cfuncs->initScreen) (pScreen)) - return FALSE; - - if (!screen->dumb && card->cfuncs->initAccel) - if (!(*card->cfuncs->initAccel) (pScreen)) - screen->dumb = TRUE; - - if (card->cfuncs->finishInitScreen) - if (!(*card->cfuncs->finishInitScreen) (pScreen)) - return FALSE; - -#if 0 - fbInitValidateTree (pScreen); -#endif - -#if 0 - pScreen->backingStoreSupport = Always; - miInitializeBackingStore (pScreen); -#endif - - - /* - * Wrap CloseScreen, the order now is: - * KdCloseScreen - * miBSCloseScreen - * fbCloseScreen - */ - pScreenPriv->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = KdCloseScreen; - - pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources; - pScreen->CreateScreenResources = KdCreateScreenResources; - - if (screen->softCursor || - !card->cfuncs->initCursor || - !(*card->cfuncs->initCursor) (pScreen)) - { - /* Use MI for cursor display and event queueing. */ - screen->softCursor = TRUE; - miDCInitialize(pScreen, &kdPointerScreenFuncs); - } - - - if (!fbCreateDefColormap (pScreen)) - { - return FALSE; - } - - KdSetSubpixelOrder (pScreen, screen->randr); - - /* - * Enable the hardware - */ - if (!kdEnabled) - { - kdEnabled = TRUE; - if(kdOsFuncs->Enable) - (*kdOsFuncs->Enable) (); - } - - if (screen->mynum == card->selected) - { - if(card->cfuncs->preserve) - (*card->cfuncs->preserve) (card); - if(card->cfuncs->enable) - if (!(*card->cfuncs->enable) (pScreen)) - return FALSE; - pScreenPriv->enabled = TRUE; - if (!screen->softCursor && card->cfuncs->enableCursor) - (*card->cfuncs->enableCursor) (pScreen); - KdEnableColormap (pScreen); - if (!screen->dumb && card->cfuncs->enableAccel) - (*card->cfuncs->enableAccel) (pScreen); - } - - return TRUE; -} - -void -KdInitScreen (ScreenInfo *pScreenInfo, - KdScreenInfo *screen, - int argc, - char **argv) -{ - KdCardInfo *card = screen->card; - - (*card->cfuncs->scrinit) (screen); - - if (!card->cfuncs->initAccel) - screen->dumb = TRUE; - if (!card->cfuncs->initCursor) - screen->softCursor = TRUE; -} - -static Bool -KdSetPixmapFormats (ScreenInfo *pScreenInfo) -{ - CARD8 depthToBpp[33]; /* depth -> bpp map */ - KdCardInfo *card; - KdScreenInfo *screen; - int i; - int bpp; - PixmapFormatRec *format; - - for (i = 1; i <= 32; i++) - depthToBpp[i] = 0; - - /* - * Generate mappings between bitsPerPixel and depth, - * also ensure that all screens comply with protocol - * restrictions on equivalent formats for the same - * depth on different screens - */ - for (card = kdCardInfo; card; card = card->next) - { - for (screen = card->screenList; screen; screen = screen->next) - { - bpp = screen->fb.bitsPerPixel; - if (bpp == 24) - bpp = 32; - if (!depthToBpp[screen->fb.depth]) - depthToBpp[screen->fb.depth] = bpp; - else if (depthToBpp[screen->fb.depth] != bpp) - return FALSE; - } - } - - /* - * Fill in additional formats - */ - for (i = 0; i < NUM_KD_DEPTHS; i++) - if (!depthToBpp[kdDepths[i].depth]) - depthToBpp[kdDepths[i].depth] = kdDepths[i].bpp; - - pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER; - pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; - pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; - pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; - - pScreenInfo->numPixmapFormats = 0; - - for (i = 1; i <= 32; i++) - { - if (depthToBpp[i]) - { - format = &pScreenInfo->formats[pScreenInfo->numPixmapFormats++]; - format->depth = i; - format->bitsPerPixel = depthToBpp[i]; - format->scanlinePad = BITMAP_SCANLINE_PAD; - } - } - - return TRUE; -} - -static void -KdAddScreen (ScreenInfo *pScreenInfo, - KdScreenInfo *screen, - int argc, - char **argv) -{ - int i; - /* - * Fill in fb visual type masks for this screen - */ - for (i = 0; i < pScreenInfo->numPixmapFormats; i++) - { - unsigned long visuals; - Pixel rm, gm, bm; - - visuals = 0; - rm = gm = bm = 0; - if (pScreenInfo->formats[i].depth == screen->fb.depth) - { - visuals = screen->fb.visuals; - rm = screen->fb.redMask; - gm = screen->fb.greenMask; - bm = screen->fb.blueMask; - } - fbSetVisualTypesAndMasks (pScreenInfo->formats[i].depth, - visuals, - 8, - rm, gm, bm); - } - - kdCurrentScreen = screen; - - AddScreen (KdScreenInit, argc, argv); -} - -#if 0 /* This function is not used currently */ - -int -KdDepthToFb (ScreenPtr pScreen, int depth) -{ - KdScreenPriv(pScreen); - - for (fb = 0; fb <= KD_MAX_FB && pScreenPriv->screen->fb.frameBuffer; fb++) - if (pScreenPriv->screen->fb.depth == depth) - return fb; -} - -#endif - -static int -KdSignalWrapper (int signum) -{ - kdCaughtSignal = TRUE; - return 1; /* use generic OS layer cleanup & abort */ -} - -void -KdInitOutput (ScreenInfo *pScreenInfo, - int argc, - char **argv) -{ - KdCardInfo *card; - KdScreenInfo *screen; - - if (!kdCardInfo) - { - InitCard (0); - if (!(card = KdCardInfoLast ())) - FatalError("No matching cards found!\n"); - screen = KdScreenInfoAdd (card); - KdParseScreen (screen, 0); - } - /* - * Initialize all of the screens for all of the cards - */ - for (card = kdCardInfo; card; card = card->next) - { - int ret=1; - if(card->cfuncs->cardinit) - ret=(*card->cfuncs->cardinit) (card); - if (ret) - { - for (screen = card->screenList; screen; screen = screen->next) - KdInitScreen (pScreenInfo, screen, argc, argv); - } - } - - /* - * Merge the various pixmap formats together, this can fail - * when two screens share depth but not bitsPerPixel - */ - if (!KdSetPixmapFormats (pScreenInfo)) - return; - - /* - * Add all of the screens - */ - for (card = kdCardInfo; card; card = card->next) - for (screen = card->screenList; screen; screen = screen->next) - KdAddScreen (pScreenInfo, screen, argc, argv); - - OsRegisterSigWrapper(KdSignalWrapper); -} - -void -OsVendorFatalError(void) -{ -} - -int -DPMSSet(ClientPtr client, int level) -{ - return Success; -} - -Bool -DPMSSupported (void) -{ - return FALSE; -} +/*
+ * Copyright © 1999 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_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "kdrive.h"
+#include <mivalidate.h>
+#include <dixstruct.h>
+#include "privates.h"
+#ifdef RANDR
+#include <randrstr.h>
+#endif
+
+#ifdef XV
+#include "kxv.h"
+#endif
+
+#ifdef DPMSExtension
+#include "dpmsproc.h"
+#endif
+
+#ifdef HAVE_EXECINFO_H
+#include <execinfo.h>
+#endif
+
+#include <signal.h>
+
+typedef struct _kdDepths {
+ CARD8 depth;
+ CARD8 bpp;
+} KdDepths;
+
+KdDepths kdDepths[] = {
+ { 1, 1 },
+ { 4, 4 },
+ { 8, 8 },
+ { 15, 16 },
+ { 16, 16 },
+ { 24, 32 },
+ { 32, 32 }
+};
+
+#define NUM_KD_DEPTHS (sizeof (kdDepths) / sizeof (kdDepths[0]))
+
+#define KD_DEFAULT_BUTTONS 5
+
+static int kdScreenPrivateKeyIndex;
+DevPrivateKey kdScreenPrivateKey = &kdScreenPrivateKeyIndex;
+unsigned long kdGeneration;
+
+Bool kdVideoTest;
+unsigned long kdVideoTestTime;
+Bool kdEmulateMiddleButton;
+Bool kdRawPointerCoordinates;
+Bool kdDisableZaphod;
+Bool kdAllowZap;
+Bool kdEnabled;
+int kdSubpixelOrder;
+int kdVirtualTerminal = -1;
+Bool kdSwitchPending;
+char *kdSwitchCmd;
+DDXPointRec kdOrigin;
+Bool kdHasPointer = FALSE;
+Bool kdHasKbd = FALSE;
+
+static Bool kdCaughtSignal = FALSE;
+
+/*
+ * Carry arguments from InitOutput through driver initialization
+ * to KdScreenInit
+ */
+
+KdOsFuncs *kdOsFuncs;
+
+void
+KdSetRootClip (ScreenPtr pScreen, BOOL enable)
+{
+ WindowPtr pWin = WindowTable[pScreen->myNum];
+ WindowPtr pChild;
+ Bool WasViewable;
+ Bool anyMarked = FALSE;
+ WindowPtr pLayerWin;
+ BoxRec box;
+
+ if (!pWin)
+ return;
+ WasViewable = (Bool)(pWin->viewable);
+ if (WasViewable)
+ {
+ for (pChild = pWin->firstChild; pChild; pChild = pChild->nextSib)
+ {
+ (void) (*pScreen->MarkOverlappedWindows)(pChild,
+ pChild,
+ &pLayerWin);
+ }
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ if (pWin->valdata)
+ {
+ if (HasBorder (pWin))
+ {
+ RegionPtr borderVisible;
+
+ borderVisible = REGION_CREATE(pScreen, NullBox, 1);
+ REGION_SUBTRACT(pScreen, borderVisible,
+ &pWin->borderClip, &pWin->winSize);
+ pWin->valdata->before.borderVisible = borderVisible;
+ }
+ pWin->valdata->before.resized = TRUE;
+ }
+ }
+
+ if (enable)
+ {
+ box.x1 = 0;
+ box.y1 = 0;
+ box.x2 = pScreen->width;
+ box.y2 = pScreen->height;
+ pWin->drawable.width = pScreen->width;
+ pWin->drawable.height = pScreen->height;
+ REGION_INIT (pScreen, &pWin->winSize, &box, 1);
+ REGION_INIT (pScreen, &pWin->borderSize, &box, 1);
+ REGION_RESET(pScreen, &pWin->borderClip, &box);
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+ else
+ {
+ REGION_EMPTY(pScreen, &pWin->borderClip);
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+
+ ResizeChildrenWinSize (pWin, 0, 0, 0, 0);
+
+ if (WasViewable)
+ {
+ if (pWin->firstChild)
+ {
+ anyMarked |= (*pScreen->MarkOverlappedWindows)(pWin->firstChild,
+ pWin->firstChild,
+ (WindowPtr *)NULL);
+ }
+ else
+ {
+ (*pScreen->MarkWindow) (pWin);
+ anyMarked = TRUE;
+ }
+
+
+ if (anyMarked)
+ (*pScreen->ValidateTree)(pWin, NullWindow, VTOther);
+ }
+
+ if (WasViewable)
+ {
+ if (anyMarked)
+ (*pScreen->HandleExposures)(pWin);
+ if (anyMarked && pScreen->PostValidateTree)
+ (*pScreen->PostValidateTree)(pWin, NullWindow, VTOther);
+ }
+ if (pWin->realized)
+ WindowsRestructured ();
+}
+
+void
+KdDisableScreen (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+
+ if (!pScreenPriv->enabled)
+ return;
+ if (!pScreenPriv->closed)
+ KdSetRootClip (pScreen, FALSE);
+ KdDisableColormap (pScreen);
+ if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->disableAccel)
+ (*pScreenPriv->card->cfuncs->disableAccel) (pScreen);
+ if (!pScreenPriv->screen->softCursor && pScreenPriv->card->cfuncs->disableCursor)
+ (*pScreenPriv->card->cfuncs->disableCursor) (pScreen);
+ if (pScreenPriv->card->cfuncs->dpms)
+ (*pScreenPriv->card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL);
+ pScreenPriv->enabled = FALSE;
+ if(pScreenPriv->card->cfuncs->disable)
+ (*pScreenPriv->card->cfuncs->disable) (pScreen);
+}
+
+static void
+KdDoSwitchCmd (char *reason)
+{
+ if (kdSwitchCmd)
+ {
+ char *command = xalloc (strlen (kdSwitchCmd) +
+ 1 +
+ strlen (reason) +
+ 1);
+ if (!command)
+ return;
+ strcpy (command, kdSwitchCmd);
+ strcat (command, " ");
+ strcat (command, reason);
+ system (command);
+ xfree (command);
+ }
+}
+
+void
+KdSuspend (void)
+{
+ KdCardInfo *card;
+ KdScreenInfo *screen;
+
+ if (kdEnabled)
+ {
+ for (card = kdCardInfo; card; card = card->next)
+ {
+ for (screen = card->screenList; screen; screen = screen->next)
+ if (screen->mynum == card->selected && screen->pScreen)
+ KdDisableScreen (screen->pScreen);
+ if (card->driver && card->cfuncs->restore)
+ (*card->cfuncs->restore) (card);
+ }
+ KdDisableInput ();
+ KdDoSwitchCmd ("suspend");
+ }
+}
+
+void
+KdDisableScreens (void)
+{
+ KdSuspend ();
+ if (kdEnabled)
+ {
+ if (kdOsFuncs->Disable)
+ (*kdOsFuncs->Disable) ();
+ kdEnabled = FALSE;
+ }
+}
+
+Bool
+KdEnableScreen (ScreenPtr pScreen)
+{
+ KdScreenPriv (pScreen);
+
+ if (pScreenPriv->enabled)
+ return TRUE;
+ if(pScreenPriv->card->cfuncs->enable)
+ if (!(*pScreenPriv->card->cfuncs->enable) (pScreen))
+ return FALSE;
+ pScreenPriv->enabled = TRUE;
+ pScreenPriv->dpmsState = KD_DPMS_NORMAL;
+ pScreenPriv->card->selected = pScreenPriv->screen->mynum;
+ if (!pScreenPriv->screen->softCursor && pScreenPriv->card->cfuncs->enableCursor)
+ (*pScreenPriv->card->cfuncs->enableCursor) (pScreen);
+ if (!pScreenPriv->screen->dumb && pScreenPriv->card->cfuncs->enableAccel)
+ (*pScreenPriv->card->cfuncs->enableAccel) (pScreen);
+ KdEnableColormap (pScreen);
+ KdSetRootClip (pScreen, TRUE);
+ if (pScreenPriv->card->cfuncs->dpms)
+ (*pScreenPriv->card->cfuncs->dpms) (pScreen, pScreenPriv->dpmsState);
+ return TRUE;
+}
+
+void
+KdResume (void)
+{
+ KdCardInfo *card;
+ KdScreenInfo *screen;
+
+ if (kdEnabled)
+ {
+ KdDoSwitchCmd ("resume");
+ for (card = kdCardInfo; card; card = card->next)
+ {
+ if(card->cfuncs->preserve)
+ (*card->cfuncs->preserve) (card);
+ for (screen = card->screenList; screen; screen = screen->next)
+ if (screen->mynum == card->selected && screen->pScreen)
+ KdEnableScreen (screen->pScreen);
+ }
+ KdEnableInput ();
+ KdReleaseAllKeys ();
+ }
+}
+
+void
+KdEnableScreens (void)
+{
+ if (!kdEnabled)
+ {
+ kdEnabled = TRUE;
+ if (kdOsFuncs->Enable)
+ (*kdOsFuncs->Enable) ();
+ }
+ KdResume ();
+}
+
+void
+KdProcessSwitch (void)
+{
+ if (kdEnabled)
+ KdDisableScreens ();
+ else
+ KdEnableScreens ();
+}
+
+#ifndef _MSC_VER
+void
+AbortDDX(void)
+{
+ KdDisableScreens ();
+ if (kdOsFuncs)
+ {
+ if (kdEnabled && kdOsFuncs->Disable)
+ (*kdOsFuncs->Disable) ();
+ if (kdOsFuncs->Fini)
+ (*kdOsFuncs->Fini) ();
+ KdDoSwitchCmd ("stop");
+ }
+
+ if (kdCaughtSignal)
+ abort();
+}
+
+void
+ddxGiveUp (void)
+{
+ AbortDDX ();
+}
+#endif
+
+Bool kdDumbDriver;
+Bool kdSoftCursor;
+
+char *
+KdParseFindNext (char *cur, char *delim, char *save, char *last)
+{
+ while (*cur && !strchr (delim, *cur))
+ {
+ *save++ = *cur++;
+ }
+ *save = 0;
+ *last = *cur;
+ if (*cur)
+ cur++;
+ return cur;
+}
+
+Rotation
+KdAddRotation (Rotation a, Rotation b)
+{
+ Rotation rotate = (a & RR_Rotate_All) * (b & RR_Rotate_All);
+ Rotation reflect = (a & RR_Reflect_All) ^ (b & RR_Reflect_All);
+
+ if (rotate > RR_Rotate_270)
+ rotate /= (RR_Rotate_270 * RR_Rotate_90);
+ return reflect | rotate;
+}
+
+Rotation
+KdSubRotation (Rotation a, Rotation b)
+{
+ Rotation rotate = (a & RR_Rotate_All) * 16 / (b & RR_Rotate_All);
+ Rotation reflect = (a & RR_Reflect_All) ^ (b & RR_Reflect_All);
+
+ if (rotate > RR_Rotate_270)
+ rotate /= (RR_Rotate_270 * RR_Rotate_90);
+ return reflect | rotate;
+}
+
+void
+KdParseScreen (KdScreenInfo *screen,
+ char *arg)
+{
+ char delim;
+ char save[1024];
+ int i;
+ int pixels, mm;
+
+ screen->dumb = kdDumbDriver;
+ screen->softCursor = kdSoftCursor;
+ screen->origin = kdOrigin;
+ screen->randr = RR_Rotate_0;
+ screen->width = 0;
+ screen->height = 0;
+ screen->width_mm = 0;
+ screen->height_mm = 0;
+ screen->subpixel_order = kdSubpixelOrder;
+ screen->rate = 0;
+ screen->fb.depth = 0;
+ if (!arg)
+ return;
+ if (strlen (arg) >= sizeof (save))
+ return;
+
+ for (i = 0; i < 2; i++)
+ {
+ arg = KdParseFindNext (arg, "x/@XY", save, &delim);
+ if (!save[0])
+ return;
+
+ pixels = atoi(save);
+ mm = 0;
+
+ if (delim == '/')
+ {
+ arg = KdParseFindNext (arg, "x@XY", save, &delim);
+ if (!save[0])
+ return;
+ mm = atoi(save);
+ }
+
+ if (i == 0)
+ {
+ screen->width = pixels;
+ screen->width_mm = mm;
+ }
+ else
+ {
+ screen->height = pixels;
+ screen->height_mm = mm;
+ }
+ if (delim != 'x' && delim != '@' && delim != 'X' && delim != 'Y')
+ return;
+ }
+
+ kdOrigin.x += screen->width;
+ kdOrigin.y = 0;
+ kdDumbDriver = FALSE;
+ kdSoftCursor = FALSE;
+ kdSubpixelOrder = SubPixelUnknown;
+
+ if (delim == '@')
+ {
+ arg = KdParseFindNext (arg, "xXY", save, &delim);
+ if (save[0])
+ {
+ int rotate = atoi (save);
+ if (rotate < 45)
+ screen->randr = RR_Rotate_0;
+ else if (rotate < 135)
+ screen->randr = RR_Rotate_90;
+ else if (rotate < 225)
+ screen->randr = RR_Rotate_180;
+ else if (rotate < 315)
+ screen->randr = RR_Rotate_270;
+ else
+ screen->randr = RR_Rotate_0;
+ }
+ }
+ if (delim == 'X')
+ {
+ arg = KdParseFindNext (arg, "xY", save, &delim);
+ screen->randr |= RR_Reflect_X;
+ }
+
+ if (delim == 'Y')
+ {
+ arg = KdParseFindNext (arg, "xY", save, &delim);
+ screen->randr |= RR_Reflect_Y;
+ }
+
+ arg = KdParseFindNext (arg, "x/,", save, &delim);
+ if (save[0])
+ {
+ screen->fb.depth = atoi(save);
+ if (delim == '/')
+ {
+ arg = KdParseFindNext (arg, "x,", save, &delim);
+ if (save[0])
+ screen->fb.bitsPerPixel = atoi (save);
+ }
+ else
+ screen->fb.bitsPerPixel = 0;
+ }
+
+ if (delim == 'x')
+ {
+ arg = KdParseFindNext (arg, "x", save, &delim);
+ if (save[0])
+ screen->rate = atoi(save);
+ }
+}
+
+/*
+ * Mouse argument syntax:
+ *
+ * device,protocol,options...
+ *
+ * Options are any of:
+ * 1-5 n button mouse
+ * 2button emulate middle button
+ * {NMO} Reorder buttons
+ */
+
+void
+KdParseRgba (char *rgba)
+{
+ if (!strcmp (rgba, "rgb"))
+ kdSubpixelOrder = SubPixelHorizontalRGB;
+ else if (!strcmp (rgba, "bgr"))
+ kdSubpixelOrder = SubPixelHorizontalBGR;
+ else if (!strcmp (rgba, "vrgb"))
+ kdSubpixelOrder = SubPixelVerticalRGB;
+ else if (!strcmp (rgba, "vbgr"))
+ kdSubpixelOrder = SubPixelVerticalBGR;
+ else if (!strcmp (rgba, "none"))
+ kdSubpixelOrder = SubPixelNone;
+ else
+ kdSubpixelOrder = SubPixelUnknown;
+}
+
+void
+KdUseMsg (void)
+{
+ ErrorF("\nTinyX Device Dependent Usage:\n");
+ ErrorF("-screen WIDTH[/WIDTHMM]xHEIGHT[/HEIGHTMM][@ROTATION][X][Y][xDEPTH/BPP[xFREQ]] Specify screen characteristics\n");
+ ErrorF("-rgba rgb/bgr/vrgb/vbgr/none Specify subpixel ordering for LCD panels\n");
+ ErrorF("-mouse driver [,n,,options] Specify the pointer driver and its options (n is the number of buttons)\n");
+ ErrorF("-keybd driver [,,options] Specify the keyboard driver and its options\n");
+ ErrorF("-zaphod Disable cursor screen switching\n");
+ ErrorF("-2button Emulate 3 button mouse\n");
+ ErrorF("-3button Disable 3 button mouse emulation\n");
+ ErrorF("-rawcoord Don't transform pointer coordinates on rotation\n");
+ ErrorF("-dumb Disable hardware acceleration\n");
+ ErrorF("-softCursor Force software cursor\n");
+ ErrorF("-videoTest Start the server, pause momentarily and exit\n");
+ ErrorF("-origin X,Y Locates the next screen in the the virtual screen (Xinerama)\n");
+ ErrorF("-switchCmd Command to execute on vt switch\n");
+ ErrorF("-zap Terminate server on Ctrl+Alt+Backspace\n");
+ ErrorF("vtxx Use virtual terminal xx instead of the next available\n");
+}
+
+int
+KdProcessArgument (int argc, char **argv, int i)
+{
+ KdCardInfo *card;
+ KdScreenInfo *screen;
+
+ if (!strcmp (argv[i], "-screen"))
+ {
+ if ((i+1) < argc)
+ {
+ card = KdCardInfoLast ();
+ if (!card)
+ {
+ InitCard (0);
+ card = KdCardInfoLast ();
+ }
+ if (card) {
+ screen = KdScreenInfoAdd (card);
+ KdParseScreen (screen, argv[i+1]);
+ } else
+ ErrorF("No matching card found!\n");
+ }
+ else
+ UseMsg ();
+ return 2;
+ }
+ if (!strcmp (argv[i], "-zaphod"))
+ {
+ kdDisableZaphod = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-zap"))
+ {
+ kdAllowZap = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-3button"))
+ {
+ kdEmulateMiddleButton = FALSE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-2button"))
+ {
+ kdEmulateMiddleButton = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-rawcoord"))
+ {
+ kdRawPointerCoordinates = 1;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-dumb"))
+ {
+ kdDumbDriver = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-softCursor"))
+ {
+ kdSoftCursor = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-videoTest"))
+ {
+ kdVideoTest = TRUE;
+ return 1;
+ }
+ if (!strcmp (argv[i], "-origin"))
+ {
+ if ((i+1) < argc)
+ {
+ char *x = argv[i+1];
+ char *y = strchr (x, ',');
+ if (x)
+ kdOrigin.x = atoi (x);
+ else
+ kdOrigin.x = 0;
+ if (y)
+ kdOrigin.y = atoi(y+1);
+ else
+ kdOrigin.y = 0;
+ }
+ else
+ UseMsg ();
+ return 2;
+ }
+ if (!strcmp (argv[i], "-rgba"))
+ {
+ if ((i+1) < argc)
+ KdParseRgba (argv[i+1]);
+ else
+ UseMsg ();
+ return 2;
+ }
+ if (!strcmp (argv[i], "-switchCmd"))
+ {
+ if ((i+1) < argc)
+ kdSwitchCmd = argv[i+1];
+ else
+ UseMsg ();
+ return 2;
+ }
+ if (!strncmp (argv[i], "vt", 2) &&
+ sscanf (argv[i], "vt%2d", &kdVirtualTerminal) == 1)
+ {
+ return 1;
+ }
+ if (!strcmp (argv[i], "-mouse") ||
+ !strcmp (argv[i], "-pointer")) {
+ if (i + 1 >= argc)
+ UseMsg();
+ KdAddConfigPointer(argv[i + 1]);
+ kdHasPointer = TRUE;
+ return 2;
+ }
+ if (!strcmp (argv[i], "-keybd")) {
+ if (i + 1 >= argc)
+ UseMsg();
+ KdAddConfigKeyboard(argv[i + 1]);
+ kdHasKbd = TRUE;
+ return 2;
+ }
+
+ return 0;
+}
+
+/*
+ * These are getting tossed in here until I can think of where
+ * they really belong
+ */
+
+void
+KdOsInit (KdOsFuncs *pOsFuncs)
+{
+ kdOsFuncs = pOsFuncs;
+ if (pOsFuncs)
+ {
+ if (serverGeneration == 1)
+ {
+ KdDoSwitchCmd ("start");
+ if (pOsFuncs->Init)
+ (*pOsFuncs->Init) ();
+ }
+ }
+}
+
+Bool
+KdAllocatePrivates (ScreenPtr pScreen)
+{
+ KdPrivScreenPtr pScreenPriv;
+
+ if (kdGeneration != serverGeneration)
+ kdGeneration = serverGeneration;
+
+ pScreenPriv = xcalloc(1, sizeof (*pScreenPriv));
+ if (!pScreenPriv)
+ return FALSE;
+ KdSetScreenPriv (pScreen, pScreenPriv);
+ return TRUE;
+}
+
+Bool
+KdCreateScreenResources (ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdCardInfo *card = pScreenPriv->card;
+ Bool ret;
+
+ pScreen->CreateScreenResources = pScreenPriv->CreateScreenResources;
+ if(pScreen->CreateScreenResources)
+ ret = (*pScreen->CreateScreenResources) (pScreen);
+ else
+ ret= -1;
+ pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources;
+ pScreen->CreateScreenResources = KdCreateScreenResources;
+ if (ret && card->cfuncs->createRes)
+ ret = (*card->cfuncs->createRes) (pScreen);
+ return ret;
+}
+
+Bool
+KdCloseScreen (int index, ScreenPtr pScreen)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ KdCardInfo *card = pScreenPriv->card;
+ Bool ret;
+
+ pScreenPriv->closed = TRUE;
+ pScreen->CloseScreen = pScreenPriv->CloseScreen;
+ if(pScreen->CloseScreen)
+ ret = (*pScreen->CloseScreen) (index, pScreen);
+ else
+ ret = TRUE;
+
+ if (pScreenPriv->dpmsState != KD_DPMS_NORMAL)
+ (*card->cfuncs->dpms) (pScreen, KD_DPMS_NORMAL);
+
+ if (screen->mynum == card->selected)
+ KdDisableScreen (pScreen);
+
+ /*
+ * Restore video hardware when last screen is closed
+ */
+ if (screen == card->screenList)
+ {
+ if (kdEnabled && card->cfuncs->restore)
+ (*card->cfuncs->restore) (card);
+ }
+
+ if (!pScreenPriv->screen->dumb && card->cfuncs->finiAccel)
+ (*card->cfuncs->finiAccel) (pScreen);
+
+ if (!pScreenPriv->screen->softCursor && card->cfuncs->finiCursor)
+ (*card->cfuncs->finiCursor) (pScreen);
+
+ if(card->cfuncs->scrfini)
+ (*card->cfuncs->scrfini) (screen);
+
+ /*
+ * Clean up card when last screen is closed, DIX closes them in
+ * reverse order, thus we check for when the first in the list is closed
+ */
+ if (screen == card->screenList)
+ {
+ if(card->cfuncs->cardfini)
+ (*card->cfuncs->cardfini) (card);
+ /*
+ * Clean up OS when last card is closed
+ */
+ if (card == kdCardInfo)
+ {
+ if (kdEnabled)
+ {
+ kdEnabled = FALSE;
+ if(kdOsFuncs->Disable)
+ (*kdOsFuncs->Disable) ();
+ }
+ }
+ }
+
+ pScreenPriv->screen->pScreen = 0;
+
+ xfree ((pointer) pScreenPriv);
+ return ret;
+}
+
+Bool
+KdSaveScreen (ScreenPtr pScreen, int on)
+{
+ KdScreenPriv(pScreen);
+ int dpmsState;
+
+ if (!pScreenPriv->card->cfuncs->dpms)
+ return FALSE;
+
+ dpmsState = pScreenPriv->dpmsState;
+ switch (on) {
+ case SCREEN_SAVER_OFF:
+ dpmsState = KD_DPMS_NORMAL;
+ break;
+ case SCREEN_SAVER_ON:
+ if (dpmsState == KD_DPMS_NORMAL)
+ dpmsState = KD_DPMS_NORMAL+1;
+ break;
+ case SCREEN_SAVER_CYCLE:
+ if (dpmsState < KD_DPMS_MAX)
+ dpmsState++;
+ break;
+ case SCREEN_SAVER_FORCER:
+ break;
+ }
+ if (dpmsState != pScreenPriv->dpmsState)
+ {
+ if (pScreenPriv->enabled)
+ (*pScreenPriv->card->cfuncs->dpms) (pScreen, dpmsState);
+ pScreenPriv->dpmsState = dpmsState;
+ }
+ return TRUE;
+}
+
+static Bool
+KdCreateWindow (WindowPtr pWin)
+{
+#ifndef PHOENIX
+ if (!pWin->parent)
+ {
+ KdScreenPriv(pWin->drawable.pScreen);
+
+ if (!pScreenPriv->enabled)
+ {
+ REGION_EMPTY (pWin->drawable.pScreen, &pWin->borderClip);
+ REGION_BREAK (pWin->drawable.pScreen, &pWin->clipList);
+ }
+ }
+#endif
+ return fbCreateWindow (pWin);
+}
+
+void
+KdSetSubpixelOrder (ScreenPtr pScreen, Rotation randr)
+{
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ int subpixel_order = screen->subpixel_order;
+ Rotation subpixel_dir;
+ int i;
+
+ static struct {
+ int subpixel_order;
+ Rotation direction;
+ } orders[] = {
+ { SubPixelHorizontalRGB, RR_Rotate_0 },
+ { SubPixelHorizontalBGR, RR_Rotate_180 },
+ { SubPixelVerticalRGB, RR_Rotate_270 },
+ { SubPixelVerticalBGR, RR_Rotate_90 },
+ };
+
+ static struct {
+ int bit;
+ int normal;
+ int reflect;
+ } reflects[] = {
+ { RR_Reflect_X, SubPixelHorizontalRGB, SubPixelHorizontalBGR },
+ { RR_Reflect_X, SubPixelHorizontalBGR, SubPixelHorizontalRGB },
+ { RR_Reflect_Y, SubPixelVerticalRGB, SubPixelVerticalBGR },
+ { RR_Reflect_Y, SubPixelVerticalRGB, SubPixelVerticalRGB },
+ };
+
+ /* map subpixel to direction */
+ for (i = 0; i < 4; i++)
+ if (orders[i].subpixel_order == subpixel_order)
+ break;
+ if (i < 4)
+ {
+ subpixel_dir = KdAddRotation (randr & RR_Rotate_All, orders[i].direction);
+
+ /* map back to subpixel order */
+ for (i = 0; i < 4; i++)
+ if (orders[i].direction & subpixel_dir)
+ {
+ subpixel_order = orders[i].subpixel_order;
+ break;
+ }
+ /* reflect */
+ for (i = 0; i < 4; i++)
+ if ((randr & reflects[i].bit) &&
+ reflects[i].normal == subpixel_order)
+ {
+ subpixel_order = reflects[i].reflect;
+ break;
+ }
+ }
+ PictureSetSubpixelOrder (pScreen, subpixel_order);
+}
+
+/* Pass through AddScreen, which doesn't take any closure */
+static KdScreenInfo *kdCurrentScreen;
+
+Bool
+KdScreenInit(int index, ScreenPtr pScreen, int argc, char **argv)
+{
+ KdScreenInfo *screen = kdCurrentScreen;
+ KdCardInfo *card = screen->card;
+ KdPrivScreenPtr pScreenPriv;
+ /*
+ * note that screen->fb is set up for the nominal orientation
+ * of the screen; that means if randr is rotated, the values
+ * there should reflect a rotated frame buffer (or shadow).
+ */
+ Bool rotated = (screen->randr & (RR_Rotate_90|RR_Rotate_270)) != 0;
+ int width, height, *width_mmp, *height_mmp;
+
+ KdAllocatePrivates (pScreen);
+
+ pScreenPriv = KdGetScreenPriv(pScreen);
+
+ if (!rotated)
+ {
+ width = screen->width;
+ height = screen->height;
+ width_mmp = &screen->width_mm;
+ height_mmp = &screen->height_mm;
+ }
+ else
+ {
+ width = screen->height;
+ height = screen->width;
+ width_mmp = &screen->height_mm;
+ height_mmp = &screen->width_mm;
+ }
+ screen->pScreen = pScreen;
+ pScreenPriv->screen = screen;
+ pScreenPriv->card = card;
+ pScreenPriv->bytesPerPixel = screen->fb.bitsPerPixel >> 3;
+ pScreenPriv->dpmsState = KD_DPMS_NORMAL;
+#ifdef PANORAMIX
+ dixScreenOrigins[pScreen->myNum] = screen->origin;
+#endif
+
+ if (!monitorResolution)
+ monitorResolution = 75;
+ /*
+ * This is done in this order so that backing store wraps
+ * our GC functions; fbFinishScreenInit initializes MI
+ * backing store
+ */
+ if (!fbSetupScreen (pScreen,
+ screen->fb.frameBuffer,
+ width, height,
+ monitorResolution, monitorResolution,
+ screen->fb.pixelStride,
+ screen->fb.bitsPerPixel))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Set colormap functions
+ */
+ pScreen->InstallColormap = KdInstallColormap;
+ pScreen->UninstallColormap = KdUninstallColormap;
+ pScreen->ListInstalledColormaps = KdListInstalledColormaps;
+ pScreen->StoreColors = KdStoreColors;
+
+ pScreen->SaveScreen = KdSaveScreen;
+ pScreen->CreateWindow = KdCreateWindow;
+
+ if (!fbFinishScreenInit (pScreen,
+ screen->fb.frameBuffer,
+ width, height,
+ monitorResolution, monitorResolution,
+ screen->fb.pixelStride,
+ screen->fb.bitsPerPixel))
+ {
+ return FALSE;
+ }
+
+ /*
+ * Fix screen sizes; for some reason mi takes dpi instead of mm.
+ * Rounding errors are annoying
+ */
+ if (*width_mmp)
+ pScreen->mmWidth = *width_mmp;
+ else
+ *width_mmp = pScreen->mmWidth;
+ if (*height_mmp)
+ pScreen->mmHeight = *height_mmp;
+ else
+ *height_mmp = pScreen->mmHeight;
+
+ /*
+ * Plug in our own block/wakeup handlers.
+ * miScreenInit installs NoopDDA in both places
+ */
+ pScreen->BlockHandler = KdBlockHandler;
+ pScreen->WakeupHandler = KdWakeupHandler;
+
+#ifdef RENDER
+ if (!fbPictureInit (pScreen, 0, 0))
+ return FALSE;
+#endif
+ if (card->cfuncs->initScreen)
+ if (!(*card->cfuncs->initScreen) (pScreen))
+ return FALSE;
+
+ if (!screen->dumb && card->cfuncs->initAccel)
+ if (!(*card->cfuncs->initAccel) (pScreen))
+ screen->dumb = TRUE;
+
+ if (card->cfuncs->finishInitScreen)
+ if (!(*card->cfuncs->finishInitScreen) (pScreen))
+ return FALSE;
+
+#if 0
+ fbInitValidateTree (pScreen);
+#endif
+
+#if 0
+ pScreen->backingStoreSupport = Always;
+ miInitializeBackingStore (pScreen);
+#endif
+
+
+ /*
+ * Wrap CloseScreen, the order now is:
+ * KdCloseScreen
+ * miBSCloseScreen
+ * fbCloseScreen
+ */
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = KdCloseScreen;
+
+ pScreenPriv->CreateScreenResources = pScreen->CreateScreenResources;
+ pScreen->CreateScreenResources = KdCreateScreenResources;
+
+ if (screen->softCursor ||
+ !card->cfuncs->initCursor ||
+ !(*card->cfuncs->initCursor) (pScreen))
+ {
+ /* Use MI for cursor display and event queueing. */
+ screen->softCursor = TRUE;
+ miDCInitialize(pScreen, &kdPointerScreenFuncs);
+ }
+
+
+ if (!fbCreateDefColormap (pScreen))
+ {
+ return FALSE;
+ }
+
+ KdSetSubpixelOrder (pScreen, screen->randr);
+
+ /*
+ * Enable the hardware
+ */
+ if (!kdEnabled)
+ {
+ kdEnabled = TRUE;
+ if(kdOsFuncs->Enable)
+ (*kdOsFuncs->Enable) ();
+ }
+
+ if (screen->mynum == card->selected)
+ {
+ if(card->cfuncs->preserve)
+ (*card->cfuncs->preserve) (card);
+ if(card->cfuncs->enable)
+ if (!(*card->cfuncs->enable) (pScreen))
+ return FALSE;
+ pScreenPriv->enabled = TRUE;
+ if (!screen->softCursor && card->cfuncs->enableCursor)
+ (*card->cfuncs->enableCursor) (pScreen);
+ KdEnableColormap (pScreen);
+ if (!screen->dumb && card->cfuncs->enableAccel)
+ (*card->cfuncs->enableAccel) (pScreen);
+ }
+
+ return TRUE;
+}
+
+void
+KdInitScreen (ScreenInfo *pScreenInfo,
+ KdScreenInfo *screen,
+ int argc,
+ char **argv)
+{
+ KdCardInfo *card = screen->card;
+
+ (*card->cfuncs->scrinit) (screen);
+
+ if (!card->cfuncs->initAccel)
+ screen->dumb = TRUE;
+ if (!card->cfuncs->initCursor)
+ screen->softCursor = TRUE;
+}
+
+static Bool
+KdSetPixmapFormats (ScreenInfo *pScreenInfo)
+{
+ CARD8 depthToBpp[33]; /* depth -> bpp map */
+ KdCardInfo *card;
+ KdScreenInfo *screen;
+ int i;
+ int bpp;
+ PixmapFormatRec *format;
+
+ for (i = 1; i <= 32; i++)
+ depthToBpp[i] = 0;
+
+ /*
+ * Generate mappings between bitsPerPixel and depth,
+ * also ensure that all screens comply with protocol
+ * restrictions on equivalent formats for the same
+ * depth on different screens
+ */
+ for (card = kdCardInfo; card; card = card->next)
+ {
+ for (screen = card->screenList; screen; screen = screen->next)
+ {
+ bpp = screen->fb.bitsPerPixel;
+ if (bpp == 24)
+ bpp = 32;
+ if (!depthToBpp[screen->fb.depth])
+ depthToBpp[screen->fb.depth] = bpp;
+ else if (depthToBpp[screen->fb.depth] != bpp)
+ return FALSE;
+ }
+ }
+
+ /*
+ * Fill in additional formats
+ */
+ for (i = 0; i < NUM_KD_DEPTHS; i++)
+ if (!depthToBpp[kdDepths[i].depth])
+ depthToBpp[kdDepths[i].depth] = kdDepths[i].bpp;
+
+ pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
+ pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+ pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+ pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
+
+ pScreenInfo->numPixmapFormats = 0;
+
+ for (i = 1; i <= 32; i++)
+ {
+ if (depthToBpp[i])
+ {
+ format = &pScreenInfo->formats[pScreenInfo->numPixmapFormats++];
+ format->depth = i;
+ format->bitsPerPixel = depthToBpp[i];
+ format->scanlinePad = BITMAP_SCANLINE_PAD;
+ }
+ }
+
+ return TRUE;
+}
+
+static void
+KdAddScreen (ScreenInfo *pScreenInfo,
+ KdScreenInfo *screen,
+ int argc,
+ char **argv)
+{
+ int i;
+ /*
+ * Fill in fb visual type masks for this screen
+ */
+ for (i = 0; i < pScreenInfo->numPixmapFormats; i++)
+ {
+ unsigned long visuals;
+ Pixel rm, gm, bm;
+
+ visuals = 0;
+ rm = gm = bm = 0;
+ if (pScreenInfo->formats[i].depth == screen->fb.depth)
+ {
+ visuals = screen->fb.visuals;
+ rm = screen->fb.redMask;
+ gm = screen->fb.greenMask;
+ bm = screen->fb.blueMask;
+ }
+ fbSetVisualTypesAndMasks (pScreenInfo->formats[i].depth,
+ visuals,
+ 8,
+ rm, gm, bm);
+ }
+
+ kdCurrentScreen = screen;
+
+ AddScreen (KdScreenInit, argc, argv);
+}
+
+#if 0 /* This function is not used currently */
+
+int
+KdDepthToFb (ScreenPtr pScreen, int depth)
+{
+ KdScreenPriv(pScreen);
+
+ for (fb = 0; fb <= KD_MAX_FB && pScreenPriv->screen->fb.frameBuffer; fb++)
+ if (pScreenPriv->screen->fb.depth == depth)
+ return fb;
+}
+
+#endif
+
+static int
+KdSignalWrapper (int signum)
+{
+ kdCaughtSignal = TRUE;
+ return 1; /* use generic OS layer cleanup & abort */
+}
+
+void
+KdInitOutput (ScreenInfo *pScreenInfo,
+ int argc,
+ char **argv)
+{
+ KdCardInfo *card;
+ KdScreenInfo *screen;
+
+ if (!kdCardInfo)
+ {
+ InitCard (0);
+ if (!(card = KdCardInfoLast ()))
+ FatalError("No matching cards found!\n");
+ screen = KdScreenInfoAdd (card);
+ KdParseScreen (screen, 0);
+ }
+ /*
+ * Initialize all of the screens for all of the cards
+ */
+ for (card = kdCardInfo; card; card = card->next)
+ {
+ int ret=1;
+ if(card->cfuncs->cardinit)
+ ret=(*card->cfuncs->cardinit) (card);
+ if (ret)
+ {
+ for (screen = card->screenList; screen; screen = screen->next)
+ KdInitScreen (pScreenInfo, screen, argc, argv);
+ }
+ }
+
+ /*
+ * Merge the various pixmap formats together, this can fail
+ * when two screens share depth but not bitsPerPixel
+ */
+ if (!KdSetPixmapFormats (pScreenInfo))
+ return;
+
+ /*
+ * Add all of the screens
+ */
+ for (card = kdCardInfo; card; card = card->next)
+ for (screen = card->screenList; screen; screen = screen->next)
+ KdAddScreen (pScreenInfo, screen, argc, argv);
+
+ OsRegisterSigWrapper(KdSignalWrapper);
+}
+
+#ifndef _MSC_VER
+void
+OsVendorFatalError(void)
+{
+}
+#endif
+
+#ifndef _MSC_VER
+int
+DPMSSet(ClientPtr client, int level)
+{
+ return Success;
+}
+
+Bool
+DPMSSupported (void)
+{
+ return FALSE;
+}
+#endif
diff --git a/xorg-server/hw/kdrive/src/kinput.c b/xorg-server/hw/kdrive/src/kinput.c index a88f2dc61..9ba90e63f 100644 --- a/xorg-server/hw/kdrive/src/kinput.c +++ b/xorg-server/hw/kdrive/src/kinput.c @@ -1,2360 +1,2385 @@ -/* - * Copyright © 1999 Keith Packard - * Copyright © 2006 Nokia 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 the name of the authors not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. The authors make no - * representations about the suitability of this software for any purpose. It - * is provided "as is" without express or implied warranty. - * - * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THE AUTHORS 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_CONFIG_H -#include <kdrive-config.h> -#endif -#include "kdrive.h" -#include "inputstr.h" - -#define XK_PUBLISHING -#include <X11/keysym.h> -#if HAVE_X11_XF86KEYSYM_H -#include <X11/XF86keysym.h> -#endif -#include <signal.h> -#include <stdio.h> -#ifdef sun -#include <sys/file.h> /* needed for FNONBLOCK & FASYNC */ -#endif - -#include "xkbsrv.h" - -#include <X11/extensions/XI.h> -#include <X11/extensions/XIproto.h> -#include "XIstubs.h" /* even though we don't use stubs. cute, no? */ -#include "exevents.h" -#include "extinit.h" -#include "exglobals.h" -#include "eventstr.h" -#include "xserver-properties.h" - -#define AtomFromName(x) MakeAtom(x, strlen(x), 1) - -struct KdConfigDevice { - char *line; - struct KdConfigDevice *next; -}; - -/* kdKeyboards and kdPointers hold all the real devices. */ -static KdKeyboardInfo *kdKeyboards = NULL; -static KdPointerInfo *kdPointers = NULL; -static struct KdConfigDevice *kdConfigKeyboards = NULL; -static struct KdConfigDevice *kdConfigPointers = NULL; - -static KdKeyboardDriver *kdKeyboardDrivers = NULL; -static KdPointerDriver *kdPointerDrivers = NULL; - -static EventListPtr kdEvents = NULL; - -static Bool kdInputEnabled; -static Bool kdOffScreen; -static unsigned long kdOffScreenTime; -static KdPointerMatrix kdPointerMatrix = { - { { 1, 0, 0 }, - { 0, 1, 0 } } -}; - -void KdResetInputMachine (void); - -#define KD_MAX_INPUT_FDS 8 - -typedef struct _kdInputFd { - int fd; - void (*read) (int fd, void *closure); - int (*enable) (int fd, void *closure); - void (*disable) (int fd, void *closure); - void *closure; -} KdInputFd; - -static KdInputFd kdInputFds[KD_MAX_INPUT_FDS]; -static int kdNumInputFds; - -extern Bool kdRawPointerCoordinates; - -static void -KdSigio (int sig) -{ - int i; - - for (i = 0; i < kdNumInputFds; i++) - (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure); -} - -static void -KdBlockSigio (void) -{ - sigset_t set; - - sigemptyset (&set); - sigaddset (&set, SIGIO); - sigprocmask (SIG_BLOCK, &set, 0); -} - -static void -KdUnblockSigio (void) -{ - sigset_t set; - - sigemptyset (&set); - sigaddset (&set, SIGIO); - sigprocmask (SIG_UNBLOCK, &set, 0); -} - -#ifdef DEBUG_SIGIO - -void -KdAssertSigioBlocked (char *where) -{ - sigset_t set, old; - - sigemptyset (&set); - sigprocmask (SIG_BLOCK, &set, &old); - if (!sigismember (&old, SIGIO)) { - ErrorF ("SIGIO not blocked at %s\n", where); - KdBacktrace(0); - } -} - -#else - -#define KdAssertSigioBlocked(s) - -#endif - -static int kdnFds; - -#ifdef FNONBLOCK -#define NOBLOCK FNONBLOCK -#else -#define NOBLOCK FNDELAY -#endif - -void -KdResetInputMachine (void) -{ - KdPointerInfo *pi; - - for (pi = kdPointers; pi; pi = pi->next) { - pi->mouseState = start; - pi->eventHeld = FALSE; - } -} - -static void -KdNonBlockFd (int fd) -{ - int flags; - flags = fcntl (fd, F_GETFL); - flags |= FASYNC|NOBLOCK; - fcntl (fd, F_SETFL, flags); -} - -static void -KdAddFd (int fd) -{ - struct sigaction act; - sigset_t set; - - kdnFds++; - fcntl (fd, F_SETOWN, getpid()); - KdNonBlockFd (fd); - AddEnabledDevice (fd); - memset (&act, '\0', sizeof act); - act.sa_handler = KdSigio; - sigemptyset (&act.sa_mask); - sigaddset (&act.sa_mask, SIGIO); - sigaddset (&act.sa_mask, SIGALRM); - sigaddset (&act.sa_mask, SIGVTALRM); - sigaction (SIGIO, &act, 0); - sigemptyset (&set); - sigprocmask (SIG_SETMASK, &set, 0); -} - -static void -KdRemoveFd (int fd) -{ - struct sigaction act; - int flags; - - kdnFds--; - RemoveEnabledDevice (fd); - flags = fcntl (fd, F_GETFL); - flags &= ~(FASYNC|NOBLOCK); - fcntl (fd, F_SETFL, flags); - if (kdnFds == 0) - { - memset (&act, '\0', sizeof act); - act.sa_handler = SIG_IGN; - sigemptyset (&act.sa_mask); - sigaction (SIGIO, &act, 0); - } -} - -Bool -KdRegisterFd (int fd, void (*read) (int fd, void *closure), void *closure) -{ - if (kdNumInputFds == KD_MAX_INPUT_FDS) - return FALSE; - kdInputFds[kdNumInputFds].fd = fd; - kdInputFds[kdNumInputFds].read = read; - kdInputFds[kdNumInputFds].enable = 0; - kdInputFds[kdNumInputFds].disable = 0; - kdInputFds[kdNumInputFds].closure = closure; - kdNumInputFds++; - if (kdInputEnabled) - KdAddFd (fd); - return TRUE; -} - -void -KdUnregisterFd (void *closure, int fd, Bool do_close) -{ - int i, j; - - for (i = 0; i < kdNumInputFds; i++) { - if (kdInputFds[i].closure == closure && - (fd == -1 || kdInputFds[i].fd == fd)) { - if (kdInputEnabled) - KdRemoveFd (kdInputFds[i].fd); - if (do_close) - close (kdInputFds[i].fd); - kdNumInputFds--; - for (j = i; j < kdNumInputFds; j++) - kdInputFds[j] = kdInputFds[j+1]; - break; - } - } -} - -void -KdUnregisterFds (void *closure, Bool do_close) -{ - KdUnregisterFd(closure, -1, do_close); -} - -void -KdDisableInput (void) -{ - KdKeyboardInfo *ki; - KdPointerInfo *pi; - int found = 0, i = 0; - - KdBlockSigio(); - - for (ki = kdKeyboards; ki; ki = ki->next) { - if (ki->driver && ki->driver->Disable) - (*ki->driver->Disable) (ki); - } - - for (pi = kdPointers; pi; pi = pi->next) { - if (pi->driver && pi->driver->Disable) - (*pi->driver->Disable) (pi); - } - - if (kdNumInputFds) { - ErrorF("[KdDisableInput] Buggy drivers: still %d input fds left!", - kdNumInputFds); - i = 0; - while (i < kdNumInputFds) { - found = 0; - for (ki = kdKeyboards; ki; ki = ki->next) { - if (ki == kdInputFds[i].closure) { - ErrorF(" fd %d belongs to keybd driver %s\n", - kdInputFds[i].fd, - ki->driver && ki->driver->name ? - ki->driver->name : "(unnamed!)"); - found = 1; - break; - } - } - - if (found) { - i++; - continue; - } - - for (pi = kdPointers; pi; pi = pi->next) { - if (pi == kdInputFds[i].closure) { - ErrorF(" fd %d belongs to pointer driver %s\n", - kdInputFds[i].fd, - pi->driver && pi->driver->name ? - pi->driver->name : "(unnamed!)"); - break; - } - } - - if (found) { - i++; - continue; - } - - ErrorF(" fd %d not claimed by any active device!\n", - kdInputFds[i].fd); - KdUnregisterFd(kdInputFds[i].closure, kdInputFds[i].fd, TRUE); - } - } - - kdInputEnabled = FALSE; -} - -void -KdEnableInput (void) -{ - InternalEvent ev; - KdKeyboardInfo *ki; - KdPointerInfo *pi; - - kdInputEnabled = TRUE; - - for (ki = kdKeyboards; ki; ki = ki->next) { - if (ki->driver && ki->driver->Enable) - (*ki->driver->Enable) (ki); - } - - for (pi = kdPointers; pi; pi = pi->next) { - if (pi->driver && pi->driver->Enable) - (*pi->driver->Enable) (pi); - } - - /* reset screen saver */ - ev.any.time = GetTimeInMillis (); - NoticeEventTime (&ev); - - KdUnblockSigio (); -} - -static KdKeyboardDriver * -KdFindKeyboardDriver (char *name) -{ - KdKeyboardDriver *ret; - - /* ask a stupid question ... */ - if (!name) - return NULL; - - for (ret = kdKeyboardDrivers; ret; ret = ret->next) { - if (strcmp(ret->name, name) == 0) - return ret; - } - - return NULL; -} - -static KdPointerDriver * -KdFindPointerDriver (char *name) -{ - KdPointerDriver *ret; - - /* ask a stupid question ... */ - if (!name) - return NULL; - - for (ret = kdPointerDrivers; ret; ret = ret->next) { - if (strcmp(ret->name, name) == 0) - return ret; - } - - return NULL; -} - -static int -KdPointerProc(DeviceIntPtr pDevice, int onoff) -{ - DevicePtr pDev = (DevicePtr)pDevice; - KdPointerInfo *pi; - Atom xiclass; - Atom *btn_labels; - Atom *axes_labels; - - if (!pDev) - return BadImplementation; - - for (pi = kdPointers; pi; pi = pi->next) { - if (pi->dixdev && pi->dixdev->id == pDevice->id) - break; - } - - if (!pi || !pi->dixdev || pi->dixdev->id != pDevice->id) { - ErrorF("[KdPointerProc] Failed to find pointer for device %d!\n", - pDevice->id); - return BadImplementation; - } - - switch (onoff) - { - case DEVICE_INIT: -#ifdef DEBUG - ErrorF("initialising pointer %s ...\n", pi->name); -#endif - if (!pi->driver) { - if (!pi->driverPrivate) { - ErrorF("no driver specified for %s\n", pi->name); - return BadImplementation; - } - - pi->driver = KdFindPointerDriver(pi->driverPrivate); - if (!pi->driver) { - ErrorF("Couldn't find pointer driver %s\n", - pi->driverPrivate ? (char *) pi->driverPrivate : - "(unnamed)"); - return !Success; - } - xfree(pi->driverPrivate); - pi->driverPrivate = NULL; - } - - if (!pi->driver->Init) { - ErrorF("no init function\n"); - return BadImplementation; - } - - if ((*pi->driver->Init) (pi) != Success) { - return !Success; - } - - btn_labels = xcalloc(pi->nButtons, sizeof(Atom)); - if (!btn_labels) - return BadAlloc; - axes_labels = xcalloc(pi->nAxes, sizeof(Atom)); - if (!axes_labels) { - xfree(btn_labels); - return BadAlloc; - } - - switch(pi->nAxes) - { - default: - case 7: - btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT); - case 6: - btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT); - case 5: - btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); - case 4: - btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); - case 3: - btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); - case 2: - btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); - case 1: - btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); - case 0: - break; - } - - if (pi->nAxes >= 2) { - axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); - axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); - } - - InitPointerDeviceStruct(pDev, pi->map, pi->nButtons, btn_labels, - (PtrCtrlProcPtr)NoopDDA, - GetMotionHistorySize(), pi->nAxes, axes_labels); - - xfree(btn_labels); - xfree(axes_labels); - - if (pi->inputClass == KD_TOUCHSCREEN) { - InitAbsoluteClassDeviceStruct(pDevice); - xiclass = AtomFromName(XI_TOUCHSCREEN); - } - else { - xiclass = AtomFromName(XI_MOUSE); - } - - AssignTypeAndName(pi->dixdev, xiclass, - pi->name ? pi->name : "Generic KDrive Pointer"); - - return Success; - - case DEVICE_ON: - if (pDev->on == TRUE) - return Success; - - if (!pi->driver->Enable) { - ErrorF("no enable function\n"); - return BadImplementation; - } - - if ((*pi->driver->Enable) (pi) == Success) { - pDev->on = TRUE; - return Success; - } - else { - return BadImplementation; - } - - return Success; - - case DEVICE_OFF: - if (pDev->on == FALSE) { - return Success; - } - - if (!pi->driver->Disable) { - return BadImplementation; - } - else { - (*pi->driver->Disable) (pi); - pDev->on = FALSE; - return Success; - } - - return Success; - - case DEVICE_CLOSE: - if (pDev->on) { - if (!pi->driver->Disable) { - return BadImplementation; - } - (*pi->driver->Disable) (pi); - pDev->on = FALSE; - } - - if (!pi->driver->Fini) - return BadImplementation; - - (*pi->driver->Fini) (pi); - - KdRemovePointer(pi); - - return Success; - } - - /* NOTREACHED */ - return BadImplementation; -} - -Bool -LegalModifier(unsigned int key, DeviceIntPtr pDev) -{ - return TRUE; -} - -static void -KdBell (int volume, DeviceIntPtr pDev, pointer arg, int something) -{ - KeybdCtrl *ctrl = arg; - KdKeyboardInfo *ki = NULL; - - for (ki = kdKeyboards; ki; ki = ki->next) { - if (ki->dixdev && ki->dixdev->id == pDev->id) - break; - } - - if (!ki || !ki->dixdev || ki->dixdev->id != pDev->id || !ki->driver) - return; - - KdRingBell(ki, volume, ctrl->bell_pitch, ctrl->bell_duration); -} - -void -DDXRingBell(int volume, int pitch, int duration) -{ - KdKeyboardInfo *ki = NULL; - - if (kdOsFuncs->Bell) { - (*kdOsFuncs->Bell)(volume, pitch, duration); - } - else { - for (ki = kdKeyboards; ki; ki = ki->next) { - if (ki->dixdev->coreEvents) - KdRingBell(ki, volume, pitch, duration); - } - } -} - -void -KdRingBell(KdKeyboardInfo *ki, int volume, int pitch, int duration) -{ - if (!ki || !ki->driver || !ki->driver->Bell) - return; - - if (kdInputEnabled) - (*ki->driver->Bell) (ki, volume, pitch, duration); -} - - -static void -KdSetLeds (KdKeyboardInfo *ki, int leds) -{ - if (!ki || !ki->driver) - return; - - if (kdInputEnabled) { - if (ki->driver->Leds) - (*ki->driver->Leds) (ki, leds); - } -} - -void -KdSetLed (KdKeyboardInfo *ki, int led, Bool on) -{ - if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed) - return; - - NoteLedState (ki->dixdev, led, on); - KdSetLeds (ki, ki->dixdev->kbdfeed->ctrl.leds); -} - -void -KdSetPointerMatrix (KdPointerMatrix *matrix) -{ - kdPointerMatrix = *matrix; -} - -void -KdComputePointerMatrix (KdPointerMatrix *m, Rotation randr, int width, - int height) -{ - int x_dir = 1, y_dir = 1; - int i, j; - int size[2]; - - size[0] = width; size[1] = height; - if (randr & RR_Reflect_X) - x_dir = -1; - if (randr & RR_Reflect_Y) - y_dir = -1; - switch (randr & (RR_Rotate_All)) { - case RR_Rotate_0: - m->matrix[0][0] = x_dir; m->matrix[0][1] = 0; - m->matrix[1][0] = 0; m->matrix[1][1] = y_dir; - break; - case RR_Rotate_90: - m->matrix[0][0] = 0; m->matrix[0][1] = -x_dir; - m->matrix[1][0] = y_dir; m->matrix[1][1] = 0; - break; - case RR_Rotate_180: - m->matrix[0][0] = -x_dir; m->matrix[0][1] = 0; - m->matrix[1][0] = 0; m->matrix[1][1] = -y_dir; - break; - case RR_Rotate_270: - m->matrix[0][0] = 0; m->matrix[0][1] = x_dir; - m->matrix[1][0] = -y_dir; m->matrix[1][1] = 0; - break; - } - for (i = 0; i < 2; i++) - { - m->matrix[i][2] = 0; - for (j = 0 ; j < 2; j++) - if (m->matrix[i][j] < 0) - m->matrix[i][2] = size[j] - 1; - } -} - -void -KdScreenToPointerCoords (int *x, int *y) -{ - int (*m)[3] = kdPointerMatrix.matrix; - int div = m[0][1] * m[1][0] - m[1][1] * m[0][0]; - int sx = *x; - int sy = *y; - - *x = (m[0][1] * sy - m[0][1] * m[1][2] + m[1][1] * m[0][2] - m[1][1] * sx) / div; - *y = (m[1][0] * sx + m[0][0] * m[1][2] - m[1][0] * m[0][2] - m[0][0] * sy) / div; -} - -static void -KdKbdCtrl (DeviceIntPtr pDevice, KeybdCtrl *ctrl) -{ - KdKeyboardInfo *ki; - - for (ki = kdKeyboards; ki; ki = ki->next) { - if (ki->dixdev && ki->dixdev->id == pDevice->id) - break; - } - - if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id || !ki->driver) - return; - - KdSetLeds(ki, ctrl->leds); - ki->bellPitch = ctrl->bell_pitch; - ki->bellDuration = ctrl->bell_duration; -} - -extern KeybdCtrl defaultKeyboardControl; - -static int -KdKeyboardProc(DeviceIntPtr pDevice, int onoff) -{ - Bool ret; - DevicePtr pDev = (DevicePtr)pDevice; - KdKeyboardInfo *ki; - Atom xiclass; - XkbRMLVOSet rmlvo; - - if (!pDev) - return BadImplementation; - - for (ki = kdKeyboards; ki; ki = ki->next) { - if (ki->dixdev && ki->dixdev->id == pDevice->id) - break; - } - - if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id) { - return BadImplementation; - } - - switch (onoff) - { - case DEVICE_INIT: -#ifdef DEBUG - ErrorF("initialising keyboard %s\n", ki->name); -#endif - if (!ki->driver) { - if (!ki->driverPrivate) { - ErrorF("no driver specified!\n"); - return BadImplementation; - } - - ki->driver = KdFindKeyboardDriver(ki->driverPrivate); - if (!ki->driver) { - ErrorF("Couldn't find keyboard driver %s\n", - ki->driverPrivate ? (char *) ki->driverPrivate : - "(unnamed)"); - return !Success; - } - xfree(ki->driverPrivate); - ki->driverPrivate = NULL; - } - - if (!ki->driver->Init) { - ErrorF("Keyboard %s: no init function\n", ki->name); - return BadImplementation; - } - - if ((*ki->driver->Init) (ki) != Success) { - return !Success; - } - - memset(&rmlvo, 0, sizeof(rmlvo)); - rmlvo.rules = ki->xkbRules; - rmlvo.model = ki->xkbModel; - rmlvo.layout = ki->xkbLayout; - rmlvo.variant = ki->xkbVariant; - rmlvo.options = ki->xkbOptions; - ret = InitKeyboardDeviceStruct (pDevice, &rmlvo, KdBell, KdKbdCtrl); - if (!ret) { - ErrorF("Couldn't initialise keyboard %s\n", ki->name); - return BadImplementation; - } - - xiclass = AtomFromName(XI_KEYBOARD); - AssignTypeAndName(pDevice, xiclass, - ki->name ? ki->name : "Generic KDrive Keyboard"); - - KdResetInputMachine(); - - return Success; - - case DEVICE_ON: - if (pDev->on == TRUE) - return Success; - - if (!ki->driver->Enable) - return BadImplementation; - - if ((*ki->driver->Enable) (ki) != Success) { - return BadMatch; - } - - pDev->on = TRUE; - return Success; - - case DEVICE_OFF: - if (pDev->on == FALSE) - return Success; - - if (!ki->driver->Disable) - return BadImplementation; - - (*ki->driver->Disable) (ki); - pDev->on = FALSE; - - return Success; - - break; - - case DEVICE_CLOSE: - if (pDev->on) { - if (!ki->driver->Disable) - return BadImplementation; - - (*ki->driver->Disable) (ki); - pDev->on = FALSE; - } - - if (!ki->driver->Fini) - return BadImplementation; - - (*ki->driver->Fini) (ki); - - KdRemoveKeyboard(ki); - - return Success; - } - - /* NOTREACHED */ - return BadImplementation; -} - -void -KdAddPointerDriver (KdPointerDriver *driver) -{ - KdPointerDriver **prev; - - if (!driver) - return; - - for (prev = &kdPointerDrivers; *prev; prev = &(*prev)->next) { - if (*prev == driver) - return; - } - *prev = driver; -} - -void -KdRemovePointerDriver (KdPointerDriver *driver) -{ - KdPointerDriver *tmp; - - if (!driver) - return; - - /* FIXME remove all pointers using this driver */ - for (tmp = kdPointerDrivers; tmp; tmp = tmp->next) { - if (tmp->next == driver) - tmp->next = driver->next; - } - if (tmp == driver) - tmp = NULL; -} - -void -KdAddKeyboardDriver (KdKeyboardDriver *driver) -{ - KdKeyboardDriver **prev; - - if (!driver) - return; - - for (prev = &kdKeyboardDrivers; *prev; prev = &(*prev)->next) { - if (*prev == driver) - return; - } - *prev = driver; -} - -void -KdRemoveKeyboardDriver (KdKeyboardDriver *driver) -{ - KdKeyboardDriver *tmp; - - if (!driver) - return; - - /* FIXME remove all keyboards using this driver */ - for (tmp = kdKeyboardDrivers; tmp; tmp = tmp->next) { - if (tmp->next == driver) - tmp->next = driver->next; - } - if (tmp == driver) - tmp = NULL; -} - -KdKeyboardInfo * -KdNewKeyboard (void) -{ - KdKeyboardInfo *ki = xcalloc(sizeof(KdKeyboardInfo), 1); - if (!ki) - return NULL; - - ki->minScanCode = 0; - ki->maxScanCode = 0; - ki->leds = 0; - ki->bellPitch = 1000; - ki->bellDuration = 200; - ki->next = NULL; - ki->options = NULL; - ki->xkbRules = strdup(XKB_DFLT_RULES); - ki->xkbModel = strdup(XKB_DFLT_MODEL); - ki->xkbLayout = strdup(XKB_DFLT_LAYOUT); - ki->xkbVariant = strdup(XKB_DFLT_VARIANT); - ki->xkbOptions = strdup(XKB_DFLT_OPTIONS); - - return ki; -} - -int -KdAddConfigKeyboard (char *keyboard) -{ - struct KdConfigDevice **prev, *new; - - if (!keyboard) - return Success; - - new = (struct KdConfigDevice *) xcalloc(sizeof(struct KdConfigDevice), 1); - if (!new) - return BadAlloc; - - new->line = xstrdup(keyboard); - new->next = NULL; - - for (prev = &kdConfigKeyboards; *prev; prev = &(*prev)->next); - *prev = new; - - return Success; -} - -int -KdAddKeyboard (KdKeyboardInfo *ki) -{ - KdKeyboardInfo **prev; - - if (!ki) - return !Success; - - ki->dixdev = AddInputDevice(serverClient, KdKeyboardProc, TRUE); - if (!ki->dixdev) { - ErrorF("Couldn't register keyboard device %s\n", - ki->name ? ki->name : "(unnamed)"); - return !Success; - } - - ki->dixdev->deviceGrab.ActivateGrab = ActivateKeyboardGrab; - ki->dixdev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab; - RegisterOtherDevice(ki->dixdev); - -#ifdef DEBUG - ErrorF("added keyboard %s with dix id %d\n", ki->name, ki->dixdev->id); -#endif - - for (prev = &kdKeyboards; *prev; prev = &(*prev)->next); - *prev = ki; - - return Success; -} - -void -KdRemoveKeyboard (KdKeyboardInfo *ki) -{ - KdKeyboardInfo **prev; - - if (!ki) - return; - - for (prev = &kdKeyboards; *prev; prev = &(*prev)->next) { - if (*prev == ki) { - *prev = ki->next; - break; - } - } - - KdFreeKeyboard(ki); -} - -int -KdAddConfigPointer (char *pointer) -{ - struct KdConfigDevice **prev, *new; - - if (!pointer) - return Success; - - new = (struct KdConfigDevice *) xcalloc(sizeof(struct KdConfigDevice), 1); - if (!new) - return BadAlloc; - - new->line = xstrdup(pointer); - new->next = NULL; - - for (prev = &kdConfigPointers; *prev; prev = &(*prev)->next); - *prev = new; - - return Success; -} - -int -KdAddPointer (KdPointerInfo *pi) -{ - KdPointerInfo **prev; - - if (!pi) - return Success; - - pi->mouseState = start; - pi->eventHeld = FALSE; - - pi->dixdev = AddInputDevice(serverClient, KdPointerProc, TRUE); - if (!pi->dixdev) { - ErrorF("Couldn't add pointer device %s\n", - pi->name ? pi->name : "(unnamed)"); - return BadDevice; - } - - pi->dixdev->deviceGrab.ActivateGrab = ActivatePointerGrab; - pi->dixdev->deviceGrab.DeactivateGrab = DeactivatePointerGrab; - RegisterOtherDevice(pi->dixdev); - - for (prev = &kdPointers; *prev; prev = &(*prev)->next); - *prev = pi; - - return Success; -} - -void -KdRemovePointer (KdPointerInfo *pi) -{ - KdPointerInfo **prev; - - if (!pi) - return; - - for (prev = &kdPointers; *prev; prev = &(*prev)->next) { - if (*prev == pi) { - *prev = pi->next; - break; - } - } - - KdFreePointer(pi); -} - -/* - * You can call your kdriver server with something like: - * $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd - * evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br - */ -static Bool -KdGetOptions (InputOption **options, char *string) -{ - InputOption *newopt = NULL, **tmpo = NULL; - int tam_key = 0; - - newopt = xcalloc(1, sizeof (InputOption)); - if (!newopt) - return FALSE; - - for (tmpo = options; *tmpo; tmpo = &(*tmpo)->next) - ; /* Hello, I'm here */ - *tmpo = newopt; - - if (strchr(string, '=')) - { - tam_key = (strchr(string, '=') - string); - newopt->key = (char *)xalloc(tam_key); - strncpy(newopt->key, string, tam_key); - newopt->key[tam_key] = '\0'; - newopt->value = xstrdup(strchr(string, '=') + 1); - } - else - { - newopt->key = xstrdup(string); - newopt->value = NULL; - } - newopt->next = NULL; - - return TRUE; -} - -static void -KdParseKbdOptions (KdKeyboardInfo *ki) -{ - InputOption *option = NULL; - - for (option = ki->options; option; option = option->next) - { - if (strcasecmp(option->key, "XkbRules") == 0) - ki->xkbRules = option->value; - else if (strcasecmp(option->key, "XkbModel") == 0) - ki->xkbModel = option->value; - else if (strcasecmp(option->key, "XkbLayout") == 0) - ki->xkbLayout = option->value; - else if (strcasecmp(option->key, "XkbVariant") == 0) - ki->xkbVariant = option->value; - else if (strcasecmp(option->key, "XkbOptions") == 0) - ki->xkbOptions = option->value; - else if (!strcasecmp (option->key, "device")) - ki->path = strdup(option->value); - else - ErrorF("Kbd option key (%s) of value (%s) not assigned!\n", - option->key, option->value); - } -} - -KdKeyboardInfo * -KdParseKeyboard (char *arg) -{ - char save[1024]; - char delim; - InputOption *options = NULL; - KdKeyboardInfo *ki = NULL; - - ki = KdNewKeyboard(); - if (!ki) - return NULL; - - ki->name = strdup("Unknown KDrive Keyboard"); - ki->path = NULL; - ki->driver = NULL; - ki->driverPrivate = NULL; - ki->next = NULL; - - if (!arg) - { - ErrorF("keybd: no arg\n"); - KdFreeKeyboard (ki); - return NULL; - } - - if (strlen (arg) >= sizeof (save)) - { - ErrorF("keybd: arg too long\n"); - KdFreeKeyboard (ki); - return NULL; - } - - arg = KdParseFindNext (arg, ",", save, &delim); - if (!save[0]) - { - ErrorF("keybd: failed on save[0]\n"); - KdFreeKeyboard (ki); - return NULL; - } - - if (strcmp (save, "auto") == 0) - ki->driverPrivate = NULL; - else - ki->driverPrivate = xstrdup(save); - - if (delim != ',') - { - return ki; - } - - arg = KdParseFindNext (arg, ",", save, &delim); - - while (delim == ',') - { - arg = KdParseFindNext (arg, ",", save, &delim); - - if (!KdGetOptions(&options, save)) - { - KdFreeKeyboard(ki); - return NULL; - } - } - - if (options) - { - ki->options = options; - KdParseKbdOptions(ki); - } - - return ki; -} - -static void -KdParsePointerOptions (KdPointerInfo *pi) -{ - InputOption *option = NULL; - - for (option = pi->options; option; option = option->next) - { - if (!strcmp (option->key, "emulatemiddle")) - pi->emulateMiddleButton = TRUE; - else if (!strcmp (option->key, "noemulatemiddle")) - pi->emulateMiddleButton = FALSE; - else if (!strcmp (option->key, "transformcoord")) - pi->transformCoordinates = TRUE; - else if (!strcmp (option->key, "rawcoord")) - pi->transformCoordinates = FALSE; - else if (!strcasecmp (option->key, "device")) - pi->path = strdup(option->value); - else if (!strcasecmp (option->key, "protocol")) - pi->protocol = strdup(option->value); - else - ErrorF("Pointer option key (%s) of value (%s) not assigned!\n", - option->key, option->value); - } -} - -KdPointerInfo * -KdParsePointer (char *arg) -{ - char save[1024]; - char delim; - KdPointerInfo *pi = NULL; - InputOption *options = NULL; - int i = 0; - - pi = KdNewPointer(); - if (!pi) - return NULL; - pi->emulateMiddleButton = kdEmulateMiddleButton; - pi->transformCoordinates = !kdRawPointerCoordinates; - pi->protocol = NULL; - pi->nButtons = 5; /* XXX should not be hardcoded */ - pi->inputClass = KD_MOUSE; - - if (!arg) - { - ErrorF("mouse: no arg\n"); - KdFreePointer (pi); - return NULL; - } - - if (strlen (arg) >= sizeof (save)) - { - ErrorF("mouse: arg too long\n"); - KdFreePointer (pi); - return NULL; - } - arg = KdParseFindNext (arg, ",", save, &delim); - if (!save[0]) - { - ErrorF("failed on save[0]\n"); - KdFreePointer (pi); - return NULL; - } - - if (strcmp(save, "auto") == 0) - pi->driverPrivate = NULL; - else - pi->driverPrivate = xstrdup(save); - - if (delim != ',') - { - return pi; - } - - arg = KdParseFindNext (arg, ",", save, &delim); - - while (delim == ',') - { - arg = KdParseFindNext (arg, ",", save, &delim); - if (save[0] == '{') - { - char *s = save + 1; - i = 0; - while (*s && *s != '}') - { - if ('1' <= *s && *s <= '0' + pi->nButtons) - pi->map[i] = *s - '0'; - else - UseMsg (); - s++; - } - } - else - { - if (!KdGetOptions(&options, save)) - { - KdFreePointer(pi); - return NULL; - } - } - } - - if (options) - { - pi->options = options; - KdParsePointerOptions(pi); - } - - return pi; -} - - -void -KdInitInput (void) -{ - KdPointerInfo *pi; - KdKeyboardInfo *ki; - struct KdConfigDevice *dev; - - kdInputEnabled = TRUE; - - for (dev = kdConfigPointers; dev; dev = dev->next) { - pi = KdParsePointer(dev->line); - if (!pi) - ErrorF("Failed to parse pointer\n"); - if (KdAddPointer(pi) != Success) - ErrorF("Failed to add pointer!\n"); - } - for (dev = kdConfigKeyboards; dev; dev = dev->next) { - ki = KdParseKeyboard(dev->line); - if (!ki) - ErrorF("Failed to parse keyboard\n"); - if (KdAddKeyboard(ki) != Success) - ErrorF("Failed to add keyboard!\n"); - } - - mieqInit(); -} - -/* - * Middle button emulation state machine - * - * Possible transitions: - * Button 1 press v1 - * Button 1 release ^1 - * Button 2 press v2 - * Button 2 release ^2 - * Button 3 press v3 - * Button 3 release ^3 - * Button other press vo - * Button other release ^o - * Mouse motion <> - * Keyboard event k - * timeout ... - * outside box <-> - * - * States: - * start - * button_1_pend - * button_1_down - * button_2_down - * button_3_pend - * button_3_down - * synthetic_2_down_13 - * synthetic_2_down_3 - * synthetic_2_down_1 - * - * Transition diagram - * - * start - * v1 -> (hold) (settimeout) button_1_pend - * ^1 -> (deliver) start - * v2 -> (deliver) button_2_down - * ^2 -> (deliever) start - * v3 -> (hold) (settimeout) button_3_pend - * ^3 -> (deliver) start - * vo -> (deliver) start - * ^o -> (deliver) start - * <> -> (deliver) start - * k -> (deliver) start - * - * button_1_pend (button 1 is down, timeout pending) - * ^1 -> (release) (deliver) start - * v2 -> (release) (deliver) button_1_down - * ^2 -> (release) (deliver) button_1_down - * v3 -> (cleartimeout) (generate v2) synthetic_2_down_13 - * ^3 -> (release) (deliver) button_1_down - * vo -> (release) (deliver) button_1_down - * ^o -> (release) (deliver) button_1_down - * <-> -> (release) (deliver) button_1_down - * <> -> (deliver) button_1_pend - * k -> (release) (deliver) button_1_down - * ... -> (release) button_1_down - * - * button_1_down (button 1 is down) - * ^1 -> (deliver) start - * v2 -> (deliver) button_1_down - * ^2 -> (deliver) button_1_down - * v3 -> (deliver) button_1_down - * ^3 -> (deliver) button_1_down - * vo -> (deliver) button_1_down - * ^o -> (deliver) button_1_down - * <> -> (deliver) button_1_down - * k -> (deliver) button_1_down - * - * button_2_down (button 2 is down) - * v1 -> (deliver) button_2_down - * ^1 -> (deliver) button_2_down - * ^2 -> (deliver) start - * v3 -> (deliver) button_2_down - * ^3 -> (deliver) button_2_down - * vo -> (deliver) button_2_down - * ^o -> (deliver) button_2_down - * <> -> (deliver) button_2_down - * k -> (deliver) button_2_down - * - * button_3_pend (button 3 is down, timeout pending) - * v1 -> (generate v2) synthetic_2_down - * ^1 -> (release) (deliver) button_3_down - * v2 -> (release) (deliver) button_3_down - * ^2 -> (release) (deliver) button_3_down - * ^3 -> (release) (deliver) start - * vo -> (release) (deliver) button_3_down - * ^o -> (release) (deliver) button_3_down - * <-> -> (release) (deliver) button_3_down - * <> -> (deliver) button_3_pend - * k -> (release) (deliver) button_3_down - * ... -> (release) button_3_down - * - * button_3_down (button 3 is down) - * v1 -> (deliver) button_3_down - * ^1 -> (deliver) button_3_down - * v2 -> (deliver) button_3_down - * ^2 -> (deliver) button_3_down - * ^3 -> (deliver) start - * vo -> (deliver) button_3_down - * ^o -> (deliver) button_3_down - * <> -> (deliver) button_3_down - * k -> (deliver) button_3_down - * - * synthetic_2_down_13 (button 1 and 3 are down) - * ^1 -> (generate ^2) synthetic_2_down_3 - * v2 -> synthetic_2_down_13 - * ^2 -> synthetic_2_down_13 - * ^3 -> (generate ^2) synthetic_2_down_1 - * vo -> (deliver) synthetic_2_down_13 - * ^o -> (deliver) synthetic_2_down_13 - * <> -> (deliver) synthetic_2_down_13 - * k -> (deliver) synthetic_2_down_13 - * - * synthetic_2_down_3 (button 3 is down) - * v1 -> (deliver) synthetic_2_down_3 - * ^1 -> (deliver) synthetic_2_down_3 - * v2 -> synthetic_2_down_3 - * ^2 -> synthetic_2_down_3 - * ^3 -> start - * vo -> (deliver) synthetic_2_down_3 - * ^o -> (deliver) synthetic_2_down_3 - * <> -> (deliver) synthetic_2_down_3 - * k -> (deliver) synthetic_2_down_3 - * - * synthetic_2_down_1 (button 1 is down) - * ^1 -> start - * v2 -> synthetic_2_down_1 - * ^2 -> synthetic_2_down_1 - * v3 -> (deliver) synthetic_2_down_1 - * ^3 -> (deliver) synthetic_2_down_1 - * vo -> (deliver) synthetic_2_down_1 - * ^o -> (deliver) synthetic_2_down_1 - * <> -> (deliver) synthetic_2_down_1 - * k -> (deliver) synthetic_2_down_1 - */ - -typedef enum _inputClass { - down_1, up_1, - down_2, up_2, - down_3, up_3, - down_o, up_o, - motion, outside_box, - keyboard, timeout, - num_input_class -} KdInputClass; - -typedef enum _inputAction { - noop, - hold, - setto, - deliver, - release, - clearto, - gen_down_2, - gen_up_2 -} KdInputAction; - -#define MAX_ACTIONS 2 - -typedef struct _inputTransition { - KdInputAction actions[MAX_ACTIONS]; - KdPointerState nextState; -} KdInputTransition; - -static const -KdInputTransition kdInputMachine[num_input_states][num_input_class] = { - /* start */ - { - { { hold, setto }, button_1_pend }, /* v1 */ - { { deliver, noop }, start }, /* ^1 */ - { { deliver, noop }, button_2_down }, /* v2 */ - { { deliver, noop }, start }, /* ^2 */ - { { hold, setto }, button_3_pend }, /* v3 */ - { { deliver, noop }, start }, /* ^3 */ - { { deliver, noop }, start }, /* vo */ - { { deliver, noop }, start }, /* ^o */ - { { deliver, noop }, start }, /* <> */ - { { deliver, noop }, start }, /* <-> */ - { { noop, noop }, start }, /* k */ - { { noop, noop }, start }, /* ... */ - }, - /* button_1_pend */ - { - { { noop, noop }, button_1_pend }, /* v1 */ - { { release, deliver }, start }, /* ^1 */ - { { release, deliver }, button_1_down }, /* v2 */ - { { release, deliver }, button_1_down }, /* ^2 */ - { { clearto, gen_down_2 }, synth_2_down_13 }, /* v3 */ - { { release, deliver }, button_1_down }, /* ^3 */ - { { release, deliver }, button_1_down }, /* vo */ - { { release, deliver }, button_1_down }, /* ^o */ - { { deliver, noop }, button_1_pend }, /* <> */ - { { release, deliver }, button_1_down }, /* <-> */ - { { noop, noop }, button_1_down }, /* k */ - { { release, noop }, button_1_down }, /* ... */ - }, - /* button_1_down */ - { - { { noop, noop }, button_1_down }, /* v1 */ - { { deliver, noop }, start }, /* ^1 */ - { { deliver, noop }, button_1_down }, /* v2 */ - { { deliver, noop }, button_1_down }, /* ^2 */ - { { deliver, noop }, button_1_down }, /* v3 */ - { { deliver, noop }, button_1_down }, /* ^3 */ - { { deliver, noop }, button_1_down }, /* vo */ - { { deliver, noop }, button_1_down }, /* ^o */ - { { deliver, noop }, button_1_down }, /* <> */ - { { deliver, noop }, button_1_down }, /* <-> */ - { { noop, noop }, button_1_down }, /* k */ - { { noop, noop }, button_1_down }, /* ... */ - }, - /* button_2_down */ - { - { { deliver, noop }, button_2_down }, /* v1 */ - { { deliver, noop }, button_2_down }, /* ^1 */ - { { noop, noop }, button_2_down }, /* v2 */ - { { deliver, noop }, start }, /* ^2 */ - { { deliver, noop }, button_2_down }, /* v3 */ - { { deliver, noop }, button_2_down }, /* ^3 */ - { { deliver, noop }, button_2_down }, /* vo */ - { { deliver, noop }, button_2_down }, /* ^o */ - { { deliver, noop }, button_2_down }, /* <> */ - { { deliver, noop }, button_2_down }, /* <-> */ - { { noop, noop }, button_2_down }, /* k */ - { { noop, noop }, button_2_down }, /* ... */ - }, - /* button_3_pend */ - { - { { clearto, gen_down_2 }, synth_2_down_13 }, /* v1 */ - { { release, deliver }, button_3_down }, /* ^1 */ - { { release, deliver }, button_3_down }, /* v2 */ - { { release, deliver }, button_3_down }, /* ^2 */ - { { release, deliver }, button_3_down }, /* v3 */ - { { release, deliver }, start }, /* ^3 */ - { { release, deliver }, button_3_down }, /* vo */ - { { release, deliver }, button_3_down }, /* ^o */ - { { deliver, noop }, button_3_pend }, /* <> */ - { { release, deliver }, button_3_down }, /* <-> */ - { { release, noop }, button_3_down }, /* k */ - { { release, noop }, button_3_down }, /* ... */ - }, - /* button_3_down */ - { - { { deliver, noop }, button_3_down }, /* v1 */ - { { deliver, noop }, button_3_down }, /* ^1 */ - { { deliver, noop }, button_3_down }, /* v2 */ - { { deliver, noop }, button_3_down }, /* ^2 */ - { { noop, noop }, button_3_down }, /* v3 */ - { { deliver, noop }, start }, /* ^3 */ - { { deliver, noop }, button_3_down }, /* vo */ - { { deliver, noop }, button_3_down }, /* ^o */ - { { deliver, noop }, button_3_down }, /* <> */ - { { deliver, noop }, button_3_down }, /* <-> */ - { { noop, noop }, button_3_down }, /* k */ - { { noop, noop }, button_3_down }, /* ... */ - }, - /* synthetic_2_down_13 */ - { - { { noop, noop }, synth_2_down_13 }, /* v1 */ - { { gen_up_2, noop }, synth_2_down_3 }, /* ^1 */ - { { noop, noop }, synth_2_down_13 }, /* v2 */ - { { noop, noop }, synth_2_down_13 }, /* ^2 */ - { { noop, noop }, synth_2_down_13 }, /* v3 */ - { { gen_up_2, noop }, synth_2_down_1 }, /* ^3 */ - { { deliver, noop }, synth_2_down_13 }, /* vo */ - { { deliver, noop }, synth_2_down_13 }, /* ^o */ - { { deliver, noop }, synth_2_down_13 }, /* <> */ - { { deliver, noop }, synth_2_down_13 }, /* <-> */ - { { noop, noop }, synth_2_down_13 }, /* k */ - { { noop, noop }, synth_2_down_13 }, /* ... */ - }, - /* synthetic_2_down_3 */ - { - { { deliver, noop }, synth_2_down_3 }, /* v1 */ - { { deliver, noop }, synth_2_down_3 }, /* ^1 */ - { { deliver, noop }, synth_2_down_3 }, /* v2 */ - { { deliver, noop }, synth_2_down_3 }, /* ^2 */ - { { noop, noop }, synth_2_down_3 }, /* v3 */ - { { noop, noop }, start }, /* ^3 */ - { { deliver, noop }, synth_2_down_3 }, /* vo */ - { { deliver, noop }, synth_2_down_3 }, /* ^o */ - { { deliver, noop }, synth_2_down_3 }, /* <> */ - { { deliver, noop }, synth_2_down_3 }, /* <-> */ - { { noop, noop }, synth_2_down_3 }, /* k */ - { { noop, noop }, synth_2_down_3 }, /* ... */ - }, - /* synthetic_2_down_1 */ - { - { { noop, noop }, synth_2_down_1 }, /* v1 */ - { { noop, noop }, start }, /* ^1 */ - { { deliver, noop }, synth_2_down_1 }, /* v2 */ - { { deliver, noop }, synth_2_down_1 }, /* ^2 */ - { { deliver, noop }, synth_2_down_1 }, /* v3 */ - { { deliver, noop }, synth_2_down_1 }, /* ^3 */ - { { deliver, noop }, synth_2_down_1 }, /* vo */ - { { deliver, noop }, synth_2_down_1 }, /* ^o */ - { { deliver, noop }, synth_2_down_1 }, /* <> */ - { { deliver, noop }, synth_2_down_1 }, /* <-> */ - { { noop, noop }, synth_2_down_1 }, /* k */ - { { noop, noop }, synth_2_down_1 }, /* ... */ - }, -}; - -#define EMULATION_WINDOW 10 -#define EMULATION_TIMEOUT 100 - -static int -KdInsideEmulationWindow (KdPointerInfo *pi, int x, int y, int z) -{ - pi->emulationDx = pi->heldEvent.x - x; - pi->emulationDy = pi->heldEvent.y - y; - - return (abs (pi->emulationDx) < EMULATION_WINDOW && - abs (pi->emulationDy) < EMULATION_WINDOW); -} - -static KdInputClass -KdClassifyInput (KdPointerInfo *pi, int type, int x, int y, int z, int b) -{ - switch (type) { - case ButtonPress: - switch (b) { - case 1: return down_1; - case 2: return down_2; - case 3: return down_3; - default: return down_o; - } - break; - case ButtonRelease: - switch (b) { - case 1: return up_1; - case 2: return up_2; - case 3: return up_3; - default: return up_o; - } - break; - case MotionNotify: - if (pi->eventHeld && !KdInsideEmulationWindow(pi, x, y, z)) - return outside_box; - else - return motion; - default: - return keyboard; - } - return keyboard; -} - -#ifdef DEBUG -char *kdStateNames[] = { - "start", - "button_1_pend", - "button_1_down", - "button_2_down", - "button_3_pend", - "button_3_down", - "synth_2_down_13", - "synth_2_down_3", - "synthetic_2_down_1", - "num_input_states" -}; - -char *kdClassNames[] = { - "down_1", "up_1", - "down_2", "up_2", - "down_3", "up_3", - "motion", "ouside_box", - "keyboard", "timeout", - "num_input_class" -}; - -char *kdActionNames[] = { - "noop", - "hold", - "setto", - "deliver", - "release", - "clearto", - "gen_down_2", - "gen_up_2", -}; -#endif /* DEBUG */ - -static void -KdQueueEvent (DeviceIntPtr pDev, InternalEvent *ev) -{ - KdAssertSigioBlocked ("KdQueueEvent"); - mieqEnqueue (pDev, ev); -} - -/* We return true if we're stealing the event. */ -static Bool -KdRunMouseMachine (KdPointerInfo *pi, KdInputClass c, int type, int x, int y, - int z, int b, int absrel) -{ - const KdInputTransition *t; - int a; - - c = KdClassifyInput(pi, type, x, y, z, b); - t = &kdInputMachine[pi->mouseState][c]; - for (a = 0; a < MAX_ACTIONS; a++) - { - switch (t->actions[a]) { - case noop: - break; - case hold: - pi->eventHeld = TRUE; - pi->emulationDx = 0; - pi->emulationDy = 0; - pi->heldEvent.type = type; - pi->heldEvent.x = x; - pi->heldEvent.y = y; - pi->heldEvent.z = z; - pi->heldEvent.flags = b; - pi->heldEvent.absrel = absrel; - return TRUE; - break; - case setto: - pi->emulationTimeout = GetTimeInMillis () + EMULATION_TIMEOUT; - pi->timeoutPending = TRUE; - break; - case deliver: - _KdEnqueuePointerEvent (pi, pi->heldEvent.type, pi->heldEvent.x, - pi->heldEvent.y, pi->heldEvent.z, - pi->heldEvent.flags, pi->heldEvent.absrel, - TRUE); - break; - case release: - pi->eventHeld = FALSE; - pi->timeoutPending = FALSE; - _KdEnqueuePointerEvent (pi, pi->heldEvent.type, pi->heldEvent.x, - pi->heldEvent.y, pi->heldEvent.z, - pi->heldEvent.flags, pi->heldEvent.absrel, - TRUE); - return TRUE; - break; - case clearto: - pi->timeoutPending = FALSE; - break; - case gen_down_2: - _KdEnqueuePointerEvent (pi, ButtonPress, x, y, z, 2, absrel, - TRUE); - pi->eventHeld = FALSE; - return TRUE; - break; - case gen_up_2: - _KdEnqueuePointerEvent (pi, ButtonRelease, x, y, z, 2, absrel, - TRUE); - return TRUE; - break; - } - } - pi->mouseState = t->nextState; - return FALSE; -} - -static int -KdHandlePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, int b, - int absrel) -{ - if (pi->emulateMiddleButton) - return KdRunMouseMachine (pi, KdClassifyInput(pi, type, x, y, z, b), - type, x, y, z, b, absrel); - return FALSE; -} - -static void -KdReceiveTimeout (KdPointerInfo *pi) -{ - KdRunMouseMachine (pi, timeout, 0, 0, 0, 0, 0, 0); -} - -/* - * kdCheckTermination - * - * This function checks for the key sequence that terminates the server. When - * detected, it sets the dispatchException flag and returns. The key sequence - * is: - * Control-Alt - * It's assumed that the server will be waken up by the caller when this - * function returns. - */ - -extern int nClients; - -void -KdReleaseAllKeys (void) -{ -#if 0 - int key, nEvents, i; - KdKeyboardInfo *ki; - - KdBlockSigio (); - - for (ki = kdKeyboards; ki; ki = ki->next) { - for (key = ki->keySyms.minKeyCode; key < ki->keySyms.maxKeyCode; - key++) { - if (key_is_down(ki->dixdev, key, KEY_POSTED | KEY_PROCESSED)) { - KdHandleKeyboardEvent(ki, KeyRelease, key); - GetEventList(&kdEvents); - nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key); - for (i = 0; i < nEvents; i++) - KdQueueEvent (ki->dixdev, (kdEvents + i)->event); - } - } - } - - KdUnblockSigio (); -#endif -} - -static void -KdCheckLock (void) -{ - KeyClassPtr keyc = NULL; - Bool isSet = FALSE, shouldBeSet = FALSE; - KdKeyboardInfo *tmp = NULL; - - for (tmp = kdKeyboards; tmp; tmp = tmp->next) { - if (tmp->LockLed && tmp->dixdev && tmp->dixdev->key) { - keyc = tmp->dixdev->key; - isSet = (tmp->leds & (1 << (tmp->LockLed-1))) != 0; - /* FIXME: Just use XKB indicators! */ - shouldBeSet = !!(XkbStateFieldFromRec(&keyc->xkbInfo->state) & LockMask); - if (isSet != shouldBeSet) - KdSetLed (tmp, tmp->LockLed, shouldBeSet); - } - } -} - -void -KdEnqueueKeyboardEvent(KdKeyboardInfo *ki, - unsigned char scan_code, - unsigned char is_up) -{ - unsigned char key_code; - KeyClassPtr keyc = NULL; - KeybdCtrl *ctrl = NULL; - int type, nEvents, i; - - if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key) - return; - - keyc = ki->dixdev->key; - ctrl = &ki->dixdev->kbdfeed->ctrl; - - if (scan_code >= ki->minScanCode && scan_code <= ki->maxScanCode) - { - key_code = scan_code + KD_MIN_KEYCODE - ki->minScanCode; - - /* - * Set up this event -- the type may be modified below - */ - if (is_up) - type = KeyRelease; - else - type = KeyPress; - - GetEventList(&kdEvents); - - nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, type, key_code); - for (i = 0; i < nEvents; i++) - KdQueueEvent(ki->dixdev, (InternalEvent *)((kdEvents + i)->event)); - } - else { - ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n", - ki->name, scan_code, ki->minScanCode, ki->maxScanCode); - } -} - -/* - * kdEnqueuePointerEvent - * - * This function converts hardware mouse event information into X event - * information. A mouse movement event is passed off to MI to generate - * a MotionNotify event, if appropriate. Button events are created and - * passed off to MI for enqueueing. - */ - -/* FIXME do something a little more clever to deal with multiple axes here */ -void -KdEnqueuePointerEvent(KdPointerInfo *pi, unsigned long flags, int rx, int ry, - int rz) -{ - CARD32 ms; - unsigned char buttons; - int x, y, z; - int (*matrix)[3] = kdPointerMatrix.matrix; - unsigned long button; - int n; - int dixflags = 0; - - if (!pi) - return; - - ms = GetTimeInMillis(); - - /* we don't need to transform z, so we don't. */ - if (flags & KD_MOUSE_DELTA) { - if (pi->transformCoordinates) { - x = matrix[0][0] * rx + matrix[0][1] * ry; - y = matrix[1][0] * rx + matrix[1][1] * ry; - } - else { - x = rx; - y = ry; - } - } - else { - if (pi->transformCoordinates) { - x = matrix[0][0] * rx + matrix[0][1] * ry + matrix[0][2]; - y = matrix[1][0] * rx + matrix[1][1] * ry + matrix[1][2]; - } - else { - x = rx; - y = ry; - } - } - z = rz; - - if (flags & KD_MOUSE_DELTA) - { - if (x || y || z) - { - dixflags = POINTER_RELATIVE | POINTER_ACCELERATE; - _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, FALSE); - } - } else - { - dixflags = POINTER_ABSOLUTE; - if (x != pi->dixdev->last.valuators[0] || - y != pi->dixdev->last.valuators[1]) - _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, FALSE); - } - - buttons = flags; - - for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; - button <<= 1, n++) { - if (((pi->buttonState & button) ^ (buttons & button)) && - !(buttons & button)) { - _KdEnqueuePointerEvent(pi, ButtonRelease, x, y, z, n, - dixflags, FALSE); - } - } - for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons; - button <<= 1, n++) { - if (((pi->buttonState & button) ^ (buttons & button)) && - (buttons & button)) { - _KdEnqueuePointerEvent(pi, ButtonPress, x, y, z, n, - dixflags, FALSE); - } - } - - pi->buttonState = buttons; -} - -void -_KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, - int b, int absrel, Bool force) -{ - int nEvents = 0, i = 0; - int valuators[3] = { x, y, z }; - - /* TRUE from KdHandlePointerEvent, means 'we swallowed the event'. */ - if (!force && KdHandlePointerEvent(pi, type, x, y, z, b, absrel)) - return; - - GetEventList(&kdEvents); - nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel, - 0, 3, valuators); - for (i = 0; i < nEvents; i++) - KdQueueEvent(pi->dixdev, (InternalEvent *)((kdEvents + i)->event)); -} - -void -KdBlockHandler (int screen, - pointer blockData, - pointer timeout, - pointer readmask) -{ - KdPointerInfo *pi; - int myTimeout=0; - - for (pi = kdPointers; pi; pi = pi->next) - { - if (pi->timeoutPending) - { - int ms; - - ms = pi->emulationTimeout - GetTimeInMillis (); - if (ms < 1) - ms = 1; - if(ms<myTimeout || myTimeout==0) - myTimeout=ms; - } - } - /* if we need to poll for events, do that */ - if(kdOsFuncs->pollEvents) - { - (*kdOsFuncs->pollEvents)(); - myTimeout=20; - } - if(myTimeout>0) - AdjustWaitForDelay (timeout, myTimeout); -} - -void -KdWakeupHandler (int screen, - pointer data, - unsigned long lresult, - pointer readmask) -{ - int result = (int) lresult; - fd_set *pReadmask = (fd_set *) readmask; - int i; - KdPointerInfo *pi; - - if (kdInputEnabled && result > 0) - { - for (i = 0; i < kdNumInputFds; i++) - if (FD_ISSET (kdInputFds[i].fd, pReadmask)) - { - KdBlockSigio (); - (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure); - KdUnblockSigio (); - } - } - for (pi = kdPointers; pi; pi = pi->next) - { - if (pi->timeoutPending) - { - if ((long) (GetTimeInMillis () - pi->emulationTimeout) >= 0) - { - pi->timeoutPending = FALSE; - KdBlockSigio (); - KdReceiveTimeout (pi); - KdUnblockSigio (); - } - } - } - if (kdSwitchPending) - KdProcessSwitch (); -} - -#define KdScreenOrigin(pScreen) (&(KdGetScreenPriv(pScreen)->screen->origin)) - -static Bool -KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y) -{ - ScreenPtr pScreen = *ppScreen; - ScreenPtr pNewScreen; - int n; - int dx, dy; - int best_x, best_y; - int n_best_x, n_best_y; - CARD32 ms; - - if (kdDisableZaphod || screenInfo.numScreens <= 1) - return FALSE; - - if (0 <= *x && *x < pScreen->width && 0 <= *y && *y < pScreen->height) - return FALSE; - - ms = GetTimeInMillis (); - if (kdOffScreen && (int) (ms - kdOffScreenTime) < 1000) - return FALSE; - kdOffScreen = TRUE; - kdOffScreenTime = ms; - n_best_x = -1; - best_x = 32767; - n_best_y = -1; - best_y = 32767; - for (n = 0; n < screenInfo.numScreens; n++) - { - pNewScreen = screenInfo.screens[n]; - if (pNewScreen == pScreen) - continue; - dx = KdScreenOrigin(pNewScreen)->x - KdScreenOrigin(pScreen)->x; - dy = KdScreenOrigin(pNewScreen)->y - KdScreenOrigin(pScreen)->y; - if (*x < 0) - { - if (dx <= 0 && -dx < best_x) - { - best_x = -dx; - n_best_x = n; - } - } - else if (*x >= pScreen->width) - { - if (dx >= 0 && dx < best_x) - { - best_x = dx; - n_best_x = n; - } - } - if (*y < 0) - { - if (dy <= 0 && -dy < best_y) - { - best_y = -dy; - n_best_y = n; - } - } - else if (*y >= pScreen->height) - { - if (dy >= 0 && dy < best_y) - { - best_y = dy; - n_best_y = n; - } - } - } - if (best_y < best_x) - n_best_x = n_best_y; - if (n_best_x == -1) - return FALSE; - pNewScreen = screenInfo.screens[n_best_x]; - - if (*x < 0) - *x += pNewScreen->width; - if (*y < 0) - *y += pNewScreen->height; - - if (*x >= pScreen->width) - *x -= pScreen->width; - if (*y >= pScreen->height) - *y -= pScreen->height; - - *ppScreen = pNewScreen; - return TRUE; -} - -static void -KdCrossScreen(ScreenPtr pScreen, Bool entering) -{ -#ifndef XIPAQ - if (entering) - KdEnableScreen (pScreen); - else - KdDisableScreen (pScreen); -#endif -} - -int KdCurScreen; /* current event screen */ - -static void -KdWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) -{ - KdBlockSigio (); - KdCurScreen = pScreen->myNum; - miPointerWarpCursor(pDev, pScreen, x, y); - KdUnblockSigio (); -} - -miPointerScreenFuncRec kdPointerScreenFuncs = -{ - KdCursorOffScreen, - KdCrossScreen, - KdWarpCursor -}; - -void -ProcessInputEvents (void) -{ - mieqProcessInputEvents(); - miPointerUpdateSprite(inputInfo.pointer); - if (kdSwitchPending) - KdProcessSwitch (); - KdCheckLock (); -} - -/* FIXME use XSECURITY to work out whether the client should be allowed to - * open and close. */ -void -OpenInputDevice(DeviceIntPtr pDev, ClientPtr client, int *status) -{ - if (!pDev) - *status = BadDevice; - else - *status = Success; -} - -void -CloseInputDevice(DeviceIntPtr pDev, ClientPtr client) -{ - return; -} - -/* We initialise all input devices at startup. */ -void -AddOtherInputDevices(void) -{ - return; -} - -/* At the moment, absolute/relative is up to the client. */ -int -SetDeviceMode(register ClientPtr client, DeviceIntPtr pDev, int mode) -{ - return BadMatch; -} - -int -SetDeviceValuators(register ClientPtr client, DeviceIntPtr pDev, - int *valuators, int first_valuator, int num_valuators) -{ - return BadMatch; -} - -int -ChangeDeviceControl(register ClientPtr client, DeviceIntPtr pDev, - xDeviceCtl *control) -{ - switch (control->control) { - case DEVICE_RESOLUTION: - /* FIXME do something more intelligent here */ - return BadMatch; - - case DEVICE_ABS_CALIB: - case DEVICE_ABS_AREA: - return Success; - - case DEVICE_CORE: - return BadMatch; - case DEVICE_ENABLE: - return Success; - - default: - return BadMatch; - } - - /* NOTREACHED */ - return BadImplementation; -} - -int -NewInputDeviceRequest(InputOption *options, InputAttributes *attrs, - DeviceIntPtr *pdev) -{ - InputOption *option = NULL; - KdPointerInfo *pi = NULL; - KdKeyboardInfo *ki = NULL; - - for (option = options; option; option = option->next) { - if (strcmp(option->key, "type") == 0) { - if (strcmp(option->value, "pointer") == 0) { - pi = KdNewPointer(); - if (!pi) - return BadAlloc; - } - else if (strcmp(option->value, "keyboard") == 0) { - ki = KdNewKeyboard(); - if (!ki) - return BadAlloc; - } - else { - ErrorF("unrecognised device type!\n"); - return BadValue; - } - } -#ifdef CONFIG_HAL - else if (strcmp(option->key, "_source") == 0 && - strcmp(option->value, "server/hal") == 0) - { - ErrorF("Ignoring device from HAL.\n"); - return BadValue; - } -#endif -#ifdef CONFIG_UDEV - else if (strcmp(option->key, "_source") == 0 && - strcmp(option->value, "server/udev") == 0) - { - ErrorF("Ignoring device from udev.\n"); - return BadValue; - } -#endif - } - - if (!ki && !pi) { - ErrorF("unrecognised device identifier!\n"); - return BadValue; - } - - /* FIXME: change this code below to use KdParseKbdOptions and - * KdParsePointerOptions */ - for (option = options; option; option = option->next) { - if (strcmp(option->key, "device") == 0) { - if (pi && option->value) - pi->path = strdup(option->value); - else if (ki && option->value) - ki->path = strdup(option->value); - } - else if (strcmp(option->key, "driver") == 0) { - if (pi) { - pi->driver = KdFindPointerDriver(option->value); - if (!pi->driver) { - ErrorF("couldn't find driver!\n"); - KdFreePointer(pi); - return BadValue; - } - pi->options = options; - } - else if (ki) { - ki->driver = KdFindKeyboardDriver(option->value); - if (!ki->driver) { - ErrorF("couldn't find driver!\n"); - KdFreeKeyboard(ki); - return BadValue; - } - ki->options = options; - } - } - } - - if (pi) { - if (KdAddPointer(pi) != Success || - ActivateDevice(pi->dixdev, TRUE) != Success || - EnableDevice(pi->dixdev, TRUE) != TRUE) { - ErrorF("couldn't add or enable pointer\n"); - return BadImplementation; - } - } - else if (ki) { - if (KdAddKeyboard(ki) != Success || - ActivateDevice(ki->dixdev, TRUE) != Success || - EnableDevice(ki->dixdev, TRUE) != TRUE) { - ErrorF("couldn't add or enable keyboard\n"); - return BadImplementation; - } - } - - if (pi) { - *pdev = pi->dixdev; - } else if(ki) { - *pdev = ki->dixdev; - } - - return Success; -} - -void -DeleteInputDeviceRequest(DeviceIntPtr pDev) -{ - RemoveDevice(pDev, TRUE); -} +/*
+ * Copyright © 1999 Keith Packard
+ * Copyright © 2006 Nokia 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 the name of the authors not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. The authors make no
+ * representations about the suitability of this software for any purpose. It
+ * is provided "as is" without express or implied warranty.
+ *
+ * THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THE AUTHORS 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_CONFIG_H
+#include <kdrive-config.h>
+#endif
+#include "kdrive.h"
+#include "inputstr.h"
+
+#define XK_PUBLISHING
+#include <X11/keysym.h>
+#if HAVE_X11_XF86KEYSYM_H
+#include <X11/XF86keysym.h>
+#endif
+#include <signal.h>
+#include <stdio.h>
+#ifdef sun
+#include <sys/file.h> /* needed for FNONBLOCK & FASYNC */
+#endif
+
+#include "xkbsrv.h"
+
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include "XIstubs.h" /* even though we don't use stubs. cute, no? */
+#include "exevents.h"
+#include "extinit.h"
+#include "exglobals.h"
+#include "eventstr.h"
+#include "xserver-properties.h"
+
+#define AtomFromName(x) MakeAtom(x, strlen(x), 1)
+
+struct KdConfigDevice {
+ char *line;
+ struct KdConfigDevice *next;
+};
+
+/* kdKeyboards and kdPointers hold all the real devices. */
+static KdKeyboardInfo *kdKeyboards = NULL;
+static KdPointerInfo *kdPointers = NULL;
+static struct KdConfigDevice *kdConfigKeyboards = NULL;
+static struct KdConfigDevice *kdConfigPointers = NULL;
+
+static KdKeyboardDriver *kdKeyboardDrivers = NULL;
+static KdPointerDriver *kdPointerDrivers = NULL;
+
+static EventListPtr kdEvents = NULL;
+
+static Bool kdInputEnabled;
+static Bool kdOffScreen;
+static unsigned long kdOffScreenTime;
+static KdPointerMatrix kdPointerMatrix = {
+ { { 1, 0, 0 },
+ { 0, 1, 0 } }
+};
+
+void KdResetInputMachine (void);
+
+#define KD_MAX_INPUT_FDS 8
+
+typedef struct _kdInputFd {
+ int fd;
+ void (*read) (int fd, void *closure);
+ int (*enable) (int fd, void *closure);
+ void (*disable) (int fd, void *closure);
+ void *closure;
+} KdInputFd;
+
+static KdInputFd kdInputFds[KD_MAX_INPUT_FDS];
+static int kdNumInputFds;
+
+extern Bool kdRawPointerCoordinates;
+
+static void
+KdSigio (int sig)
+{
+ int i;
+
+ for (i = 0; i < kdNumInputFds; i++)
+ (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure);
+}
+
+static void
+KdBlockSigio (void)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_BLOCK, &set, 0);
+#endif
+}
+
+static void
+KdUnblockSigio (void)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ sigset_t set;
+
+ sigemptyset (&set);
+ sigaddset (&set, SIGIO);
+ sigprocmask (SIG_UNBLOCK, &set, 0);
+#endif
+}
+
+#ifdef DEBUG_SIGIO
+
+void
+KdAssertSigioBlocked (char *where)
+{
+ sigset_t set, old;
+
+ sigemptyset (&set);
+ sigprocmask (SIG_BLOCK, &set, &old);
+ if (!sigismember (&old, SIGIO)) {
+ ErrorF ("SIGIO not blocked at %s\n", where);
+ KdBacktrace(0);
+ }
+}
+
+#else
+
+#define KdAssertSigioBlocked(s)
+
+#endif
+
+static int kdnFds;
+
+#ifdef FNONBLOCK
+#define NOBLOCK FNONBLOCK
+#else
+#define NOBLOCK FNDELAY
+#endif
+
+void
+KdResetInputMachine (void)
+{
+ KdPointerInfo *pi;
+
+ for (pi = kdPointers; pi; pi = pi->next) {
+ pi->mouseState = start;
+ pi->eventHeld = FALSE;
+ }
+}
+
+static void
+KdNonBlockFd (int fd)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ int flags;
+ flags = fcntl (fd, F_GETFL);
+ flags |= FASYNC|NOBLOCK;
+ fcntl (fd, F_SETFL, flags);
+#endif
+}
+
+static void
+KdAddFd (int fd)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ struct sigaction act;
+ sigset_t set;
+
+ kdnFds++;
+ fcntl (fd, F_SETOWN, getpid());
+ KdNonBlockFd (fd);
+ AddEnabledDevice (fd);
+ memset (&act, '\0', sizeof act);
+ act.sa_handler = KdSigio;
+ sigemptyset (&act.sa_mask);
+ sigaddset (&act.sa_mask, SIGIO);
+ sigaddset (&act.sa_mask, SIGALRM);
+ sigaddset (&act.sa_mask, SIGVTALRM);
+ sigaction (SIGIO, &act, 0);
+ sigemptyset (&set);
+ sigprocmask (SIG_SETMASK, &set, 0);
+#endif
+}
+
+static void
+KdRemoveFd (int fd)
+{
+#ifdef _MSC_VER
+ __asm int 3;
+#else
+ struct sigaction act;
+ int flags;
+
+ kdnFds--;
+ RemoveEnabledDevice (fd);
+ flags = fcntl (fd, F_GETFL);
+ flags &= ~(FASYNC|NOBLOCK);
+ fcntl (fd, F_SETFL, flags);
+ if (kdnFds == 0)
+ {
+ memset (&act, '\0', sizeof act);
+ act.sa_handler = SIG_IGN;
+ sigemptyset (&act.sa_mask);
+ sigaction (SIGIO, &act, 0);
+ }
+#endif
+}
+
+Bool
+KdRegisterFd (int fd, void (*read) (int fd, void *closure), void *closure)
+{
+ if (kdNumInputFds == KD_MAX_INPUT_FDS)
+ return FALSE;
+ kdInputFds[kdNumInputFds].fd = fd;
+ kdInputFds[kdNumInputFds].read = read;
+ kdInputFds[kdNumInputFds].enable = 0;
+ kdInputFds[kdNumInputFds].disable = 0;
+ kdInputFds[kdNumInputFds].closure = closure;
+ kdNumInputFds++;
+ if (kdInputEnabled)
+ KdAddFd (fd);
+ return TRUE;
+}
+
+void
+KdUnregisterFd (void *closure, int fd, Bool do_close)
+{
+ int i, j;
+
+ for (i = 0; i < kdNumInputFds; i++) {
+ if (kdInputFds[i].closure == closure &&
+ (fd == -1 || kdInputFds[i].fd == fd)) {
+ if (kdInputEnabled)
+ KdRemoveFd (kdInputFds[i].fd);
+ if (do_close)
+ close (kdInputFds[i].fd);
+ kdNumInputFds--;
+ for (j = i; j < kdNumInputFds; j++)
+ kdInputFds[j] = kdInputFds[j+1];
+ break;
+ }
+ }
+}
+
+void
+KdUnregisterFds (void *closure, Bool do_close)
+{
+ KdUnregisterFd(closure, -1, do_close);
+}
+
+void
+KdDisableInput (void)
+{
+ KdKeyboardInfo *ki;
+ KdPointerInfo *pi;
+ int found = 0, i = 0;
+
+ KdBlockSigio();
+
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki->driver && ki->driver->Disable)
+ (*ki->driver->Disable) (ki);
+ }
+
+ for (pi = kdPointers; pi; pi = pi->next) {
+ if (pi->driver && pi->driver->Disable)
+ (*pi->driver->Disable) (pi);
+ }
+
+ if (kdNumInputFds) {
+ ErrorF("[KdDisableInput] Buggy drivers: still %d input fds left!",
+ kdNumInputFds);
+ i = 0;
+ while (i < kdNumInputFds) {
+ found = 0;
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki == kdInputFds[i].closure) {
+ ErrorF(" fd %d belongs to keybd driver %s\n",
+ kdInputFds[i].fd,
+ ki->driver && ki->driver->name ?
+ ki->driver->name : "(unnamed!)");
+ found = 1;
+ break;
+ }
+ }
+
+ if (found) {
+ i++;
+ continue;
+ }
+
+ for (pi = kdPointers; pi; pi = pi->next) {
+ if (pi == kdInputFds[i].closure) {
+ ErrorF(" fd %d belongs to pointer driver %s\n",
+ kdInputFds[i].fd,
+ pi->driver && pi->driver->name ?
+ pi->driver->name : "(unnamed!)");
+ break;
+ }
+ }
+
+ if (found) {
+ i++;
+ continue;
+ }
+
+ ErrorF(" fd %d not claimed by any active device!\n",
+ kdInputFds[i].fd);
+ KdUnregisterFd(kdInputFds[i].closure, kdInputFds[i].fd, TRUE);
+ }
+ }
+
+ kdInputEnabled = FALSE;
+}
+
+void
+KdEnableInput (void)
+{
+ InternalEvent ev;
+ KdKeyboardInfo *ki;
+ KdPointerInfo *pi;
+
+ kdInputEnabled = TRUE;
+
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki->driver && ki->driver->Enable)
+ (*ki->driver->Enable) (ki);
+ }
+
+ for (pi = kdPointers; pi; pi = pi->next) {
+ if (pi->driver && pi->driver->Enable)
+ (*pi->driver->Enable) (pi);
+ }
+
+ /* reset screen saver */
+ ev.any.time = GetTimeInMillis ();
+ NoticeEventTime (&ev);
+
+ KdUnblockSigio ();
+}
+
+static KdKeyboardDriver *
+KdFindKeyboardDriver (char *name)
+{
+ KdKeyboardDriver *ret;
+
+ /* ask a stupid question ... */
+ if (!name)
+ return NULL;
+
+ for (ret = kdKeyboardDrivers; ret; ret = ret->next) {
+ if (strcmp(ret->name, name) == 0)
+ return ret;
+ }
+
+ return NULL;
+}
+
+static KdPointerDriver *
+KdFindPointerDriver (char *name)
+{
+ KdPointerDriver *ret;
+
+ /* ask a stupid question ... */
+ if (!name)
+ return NULL;
+
+ for (ret = kdPointerDrivers; ret; ret = ret->next) {
+ if (strcmp(ret->name, name) == 0)
+ return ret;
+ }
+
+ return NULL;
+}
+
+static int
+KdPointerProc(DeviceIntPtr pDevice, int onoff)
+{
+ DevicePtr pDev = (DevicePtr)pDevice;
+ KdPointerInfo *pi;
+ Atom xiclass;
+ Atom *btn_labels;
+ Atom *axes_labels;
+
+ if (!pDev)
+ return BadImplementation;
+
+ for (pi = kdPointers; pi; pi = pi->next) {
+ if (pi->dixdev && pi->dixdev->id == pDevice->id)
+ break;
+ }
+
+ if (!pi || !pi->dixdev || pi->dixdev->id != pDevice->id) {
+ ErrorF("[KdPointerProc] Failed to find pointer for device %d!\n",
+ pDevice->id);
+ return BadImplementation;
+ }
+
+ switch (onoff)
+ {
+ case DEVICE_INIT:
+#ifdef DEBUG
+ ErrorF("initialising pointer %s ...\n", pi->name);
+#endif
+ if (!pi->driver) {
+ if (!pi->driverPrivate) {
+ ErrorF("no driver specified for %s\n", pi->name);
+ return BadImplementation;
+ }
+
+ pi->driver = KdFindPointerDriver(pi->driverPrivate);
+ if (!pi->driver) {
+ ErrorF("Couldn't find pointer driver %s\n",
+ pi->driverPrivate ? (char *) pi->driverPrivate :
+ "(unnamed)");
+ return !Success;
+ }
+ xfree(pi->driverPrivate);
+ pi->driverPrivate = NULL;
+ }
+
+ if (!pi->driver->Init) {
+ ErrorF("no init function\n");
+ return BadImplementation;
+ }
+
+ if ((*pi->driver->Init) (pi) != Success) {
+ return !Success;
+ }
+
+ btn_labels = xcalloc(pi->nButtons, sizeof(Atom));
+ if (!btn_labels)
+ return BadAlloc;
+ axes_labels = xcalloc(pi->nAxes, sizeof(Atom));
+ if (!axes_labels) {
+ xfree(btn_labels);
+ return BadAlloc;
+ }
+
+ switch(pi->nAxes)
+ {
+ default:
+ case 7:
+ btn_labels[6] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_RIGHT);
+ case 6:
+ btn_labels[5] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_HWHEEL_LEFT);
+ case 5:
+ btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
+ case 4:
+ btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
+ case 3:
+ btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
+ case 2:
+ btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
+ case 1:
+ btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
+ case 0:
+ break;
+ }
+
+ if (pi->nAxes >= 2) {
+ axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
+ axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
+ }
+
+ InitPointerDeviceStruct(pDev, pi->map, pi->nButtons, btn_labels,
+ (PtrCtrlProcPtr)NoopDDA,
+ GetMotionHistorySize(), pi->nAxes, axes_labels);
+
+ xfree(btn_labels);
+ xfree(axes_labels);
+
+ if (pi->inputClass == KD_TOUCHSCREEN) {
+ InitAbsoluteClassDeviceStruct(pDevice);
+ xiclass = AtomFromName(XI_TOUCHSCREEN);
+ }
+ else {
+ xiclass = AtomFromName(XI_MOUSE);
+ }
+
+ AssignTypeAndName(pi->dixdev, xiclass,
+ pi->name ? pi->name : "Generic KDrive Pointer");
+
+ return Success;
+
+ case DEVICE_ON:
+ if (pDev->on == TRUE)
+ return Success;
+
+ if (!pi->driver->Enable) {
+ ErrorF("no enable function\n");
+ return BadImplementation;
+ }
+
+ if ((*pi->driver->Enable) (pi) == Success) {
+ pDev->on = TRUE;
+ return Success;
+ }
+ else {
+ return BadImplementation;
+ }
+
+ return Success;
+
+ case DEVICE_OFF:
+ if (pDev->on == FALSE) {
+ return Success;
+ }
+
+ if (!pi->driver->Disable) {
+ return BadImplementation;
+ }
+ else {
+ (*pi->driver->Disable) (pi);
+ pDev->on = FALSE;
+ return Success;
+ }
+
+ return Success;
+
+ case DEVICE_CLOSE:
+ if (pDev->on) {
+ if (!pi->driver->Disable) {
+ return BadImplementation;
+ }
+ (*pi->driver->Disable) (pi);
+ pDev->on = FALSE;
+ }
+
+ if (!pi->driver->Fini)
+ return BadImplementation;
+
+ (*pi->driver->Fini) (pi);
+
+ KdRemovePointer(pi);
+
+ return Success;
+ }
+
+ /* NOTREACHED */
+ return BadImplementation;
+}
+
+#ifndef _MSC_VER
+Bool
+LegalModifier(unsigned int key, DeviceIntPtr pDev)
+{
+ return TRUE;
+}
+#endif
+
+static void
+KdBell (int volume, DeviceIntPtr pDev, pointer arg, int something)
+{
+ KeybdCtrl *ctrl = arg;
+ KdKeyboardInfo *ki = NULL;
+
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki->dixdev && ki->dixdev->id == pDev->id)
+ break;
+ }
+
+ if (!ki || !ki->dixdev || ki->dixdev->id != pDev->id || !ki->driver)
+ return;
+
+ KdRingBell(ki, volume, ctrl->bell_pitch, ctrl->bell_duration);
+}
+
+#ifndef _MSC_VER
+void
+DDXRingBell(int volume, int pitch, int duration)
+{
+ KdKeyboardInfo *ki = NULL;
+
+ if (kdOsFuncs->Bell) {
+ (*kdOsFuncs->Bell)(volume, pitch, duration);
+ }
+ else {
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki->dixdev->coreEvents)
+ KdRingBell(ki, volume, pitch, duration);
+ }
+ }
+}
+#endif
+void
+KdRingBell(KdKeyboardInfo *ki, int volume, int pitch, int duration)
+{
+ if (!ki || !ki->driver || !ki->driver->Bell)
+ return;
+
+ if (kdInputEnabled)
+ (*ki->driver->Bell) (ki, volume, pitch, duration);
+}
+
+
+static void
+KdSetLeds (KdKeyboardInfo *ki, int leds)
+{
+ if (!ki || !ki->driver)
+ return;
+
+ if (kdInputEnabled) {
+ if (ki->driver->Leds)
+ (*ki->driver->Leds) (ki, leds);
+ }
+}
+
+void
+KdSetLed (KdKeyboardInfo *ki, int led, Bool on)
+{
+ if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed)
+ return;
+
+ NoteLedState (ki->dixdev, led, on);
+ KdSetLeds (ki, ki->dixdev->kbdfeed->ctrl.leds);
+}
+
+void
+KdSetPointerMatrix (KdPointerMatrix *matrix)
+{
+ kdPointerMatrix = *matrix;
+}
+
+void
+KdComputePointerMatrix (KdPointerMatrix *m, Rotation randr, int width,
+ int height)
+{
+ int x_dir = 1, y_dir = 1;
+ int i, j;
+ int size[2];
+
+ size[0] = width; size[1] = height;
+ if (randr & RR_Reflect_X)
+ x_dir = -1;
+ if (randr & RR_Reflect_Y)
+ y_dir = -1;
+ switch (randr & (RR_Rotate_All)) {
+ case RR_Rotate_0:
+ m->matrix[0][0] = x_dir; m->matrix[0][1] = 0;
+ m->matrix[1][0] = 0; m->matrix[1][1] = y_dir;
+ break;
+ case RR_Rotate_90:
+ m->matrix[0][0] = 0; m->matrix[0][1] = -x_dir;
+ m->matrix[1][0] = y_dir; m->matrix[1][1] = 0;
+ break;
+ case RR_Rotate_180:
+ m->matrix[0][0] = -x_dir; m->matrix[0][1] = 0;
+ m->matrix[1][0] = 0; m->matrix[1][1] = -y_dir;
+ break;
+ case RR_Rotate_270:
+ m->matrix[0][0] = 0; m->matrix[0][1] = x_dir;
+ m->matrix[1][0] = -y_dir; m->matrix[1][1] = 0;
+ break;
+ }
+ for (i = 0; i < 2; i++)
+ {
+ m->matrix[i][2] = 0;
+ for (j = 0 ; j < 2; j++)
+ if (m->matrix[i][j] < 0)
+ m->matrix[i][2] = size[j] - 1;
+ }
+}
+
+void
+KdScreenToPointerCoords (int *x, int *y)
+{
+ int (*m)[3] = kdPointerMatrix.matrix;
+ int div = m[0][1] * m[1][0] - m[1][1] * m[0][0];
+ int sx = *x;
+ int sy = *y;
+
+ *x = (m[0][1] * sy - m[0][1] * m[1][2] + m[1][1] * m[0][2] - m[1][1] * sx) / div;
+ *y = (m[1][0] * sx + m[0][0] * m[1][2] - m[1][0] * m[0][2] - m[0][0] * sy) / div;
+}
+
+static void
+KdKbdCtrl (DeviceIntPtr pDevice, KeybdCtrl *ctrl)
+{
+ KdKeyboardInfo *ki;
+
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki->dixdev && ki->dixdev->id == pDevice->id)
+ break;
+ }
+
+ if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id || !ki->driver)
+ return;
+
+ KdSetLeds(ki, ctrl->leds);
+ ki->bellPitch = ctrl->bell_pitch;
+ ki->bellDuration = ctrl->bell_duration;
+}
+
+extern KeybdCtrl defaultKeyboardControl;
+
+static int
+KdKeyboardProc(DeviceIntPtr pDevice, int onoff)
+{
+ Bool ret;
+ DevicePtr pDev = (DevicePtr)pDevice;
+ KdKeyboardInfo *ki;
+ Atom xiclass;
+ XkbRMLVOSet rmlvo;
+
+ if (!pDev)
+ return BadImplementation;
+
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ if (ki->dixdev && ki->dixdev->id == pDevice->id)
+ break;
+ }
+
+ if (!ki || !ki->dixdev || ki->dixdev->id != pDevice->id) {
+ return BadImplementation;
+ }
+
+ switch (onoff)
+ {
+ case DEVICE_INIT:
+#ifdef DEBUG
+ ErrorF("initialising keyboard %s\n", ki->name);
+#endif
+ if (!ki->driver) {
+ if (!ki->driverPrivate) {
+ ErrorF("no driver specified!\n");
+ return BadImplementation;
+ }
+
+ ki->driver = KdFindKeyboardDriver(ki->driverPrivate);
+ if (!ki->driver) {
+ ErrorF("Couldn't find keyboard driver %s\n",
+ ki->driverPrivate ? (char *) ki->driverPrivate :
+ "(unnamed)");
+ return !Success;
+ }
+ xfree(ki->driverPrivate);
+ ki->driverPrivate = NULL;
+ }
+
+ if (!ki->driver->Init) {
+ ErrorF("Keyboard %s: no init function\n", ki->name);
+ return BadImplementation;
+ }
+
+ if ((*ki->driver->Init) (ki) != Success) {
+ return !Success;
+ }
+
+ memset(&rmlvo, 0, sizeof(rmlvo));
+ rmlvo.rules = ki->xkbRules;
+ rmlvo.model = ki->xkbModel;
+ rmlvo.layout = ki->xkbLayout;
+ rmlvo.variant = ki->xkbVariant;
+ rmlvo.options = ki->xkbOptions;
+ ret = InitKeyboardDeviceStruct (pDevice, &rmlvo, KdBell, KdKbdCtrl);
+ if (!ret) {
+ ErrorF("Couldn't initialise keyboard %s\n", ki->name);
+ return BadImplementation;
+ }
+
+ xiclass = AtomFromName(XI_KEYBOARD);
+ AssignTypeAndName(pDevice, xiclass,
+ ki->name ? ki->name : "Generic KDrive Keyboard");
+
+ KdResetInputMachine();
+
+ return Success;
+
+ case DEVICE_ON:
+ if (pDev->on == TRUE)
+ return Success;
+
+ if (!ki->driver->Enable)
+ return BadImplementation;
+
+ if ((*ki->driver->Enable) (ki) != Success) {
+ return BadMatch;
+ }
+
+ pDev->on = TRUE;
+ return Success;
+
+ case DEVICE_OFF:
+ if (pDev->on == FALSE)
+ return Success;
+
+ if (!ki->driver->Disable)
+ return BadImplementation;
+
+ (*ki->driver->Disable) (ki);
+ pDev->on = FALSE;
+
+ return Success;
+
+ break;
+
+ case DEVICE_CLOSE:
+ if (pDev->on) {
+ if (!ki->driver->Disable)
+ return BadImplementation;
+
+ (*ki->driver->Disable) (ki);
+ pDev->on = FALSE;
+ }
+
+ if (!ki->driver->Fini)
+ return BadImplementation;
+
+ (*ki->driver->Fini) (ki);
+
+ KdRemoveKeyboard(ki);
+
+ return Success;
+ }
+
+ /* NOTREACHED */
+ return BadImplementation;
+}
+
+void
+KdAddPointerDriver (KdPointerDriver *driver)
+{
+ KdPointerDriver **prev;
+
+ if (!driver)
+ return;
+
+ for (prev = &kdPointerDrivers; *prev; prev = &(*prev)->next) {
+ if (*prev == driver)
+ return;
+ }
+ *prev = driver;
+}
+
+void
+KdRemovePointerDriver (KdPointerDriver *driver)
+{
+ KdPointerDriver *tmp;
+
+ if (!driver)
+ return;
+
+ /* FIXME remove all pointers using this driver */
+ for (tmp = kdPointerDrivers; tmp; tmp = tmp->next) {
+ if (tmp->next == driver)
+ tmp->next = driver->next;
+ }
+ if (tmp == driver)
+ tmp = NULL;
+}
+
+void
+KdAddKeyboardDriver (KdKeyboardDriver *driver)
+{
+ KdKeyboardDriver **prev;
+
+ if (!driver)
+ return;
+
+ for (prev = &kdKeyboardDrivers; *prev; prev = &(*prev)->next) {
+ if (*prev == driver)
+ return;
+ }
+ *prev = driver;
+}
+
+void
+KdRemoveKeyboardDriver (KdKeyboardDriver *driver)
+{
+ KdKeyboardDriver *tmp;
+
+ if (!driver)
+ return;
+
+ /* FIXME remove all keyboards using this driver */
+ for (tmp = kdKeyboardDrivers; tmp; tmp = tmp->next) {
+ if (tmp->next == driver)
+ tmp->next = driver->next;
+ }
+ if (tmp == driver)
+ tmp = NULL;
+}
+
+KdKeyboardInfo *
+KdNewKeyboard (void)
+{
+ KdKeyboardInfo *ki = xcalloc(sizeof(KdKeyboardInfo), 1);
+ if (!ki)
+ return NULL;
+
+ ki->minScanCode = 0;
+ ki->maxScanCode = 0;
+ ki->leds = 0;
+ ki->bellPitch = 1000;
+ ki->bellDuration = 200;
+ ki->next = NULL;
+ ki->options = NULL;
+ ki->xkbRules = strdup(XKB_DFLT_RULES);
+ ki->xkbModel = strdup(XKB_DFLT_MODEL);
+ ki->xkbLayout = strdup(XKB_DFLT_LAYOUT);
+ ki->xkbVariant = strdup(XKB_DFLT_VARIANT);
+ ki->xkbOptions = strdup(XKB_DFLT_OPTIONS);
+
+ return ki;
+}
+
+int
+KdAddConfigKeyboard (char *keyboard)
+{
+ struct KdConfigDevice **prev, *new;
+
+ if (!keyboard)
+ return Success;
+
+ new = (struct KdConfigDevice *) xcalloc(sizeof(struct KdConfigDevice), 1);
+ if (!new)
+ return BadAlloc;
+
+ new->line = xstrdup(keyboard);
+ new->next = NULL;
+
+ for (prev = &kdConfigKeyboards; *prev; prev = &(*prev)->next);
+ *prev = new;
+
+ return Success;
+}
+
+int
+KdAddKeyboard (KdKeyboardInfo *ki)
+{
+ KdKeyboardInfo **prev;
+
+ if (!ki)
+ return !Success;
+
+ ki->dixdev = AddInputDevice(serverClient, KdKeyboardProc, TRUE);
+ if (!ki->dixdev) {
+ ErrorF("Couldn't register keyboard device %s\n",
+ ki->name ? ki->name : "(unnamed)");
+ return !Success;
+ }
+
+ ki->dixdev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
+ ki->dixdev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
+ RegisterOtherDevice(ki->dixdev);
+
+#ifdef DEBUG
+ ErrorF("added keyboard %s with dix id %d\n", ki->name, ki->dixdev->id);
+#endif
+
+ for (prev = &kdKeyboards; *prev; prev = &(*prev)->next);
+ *prev = ki;
+
+ return Success;
+}
+
+void
+KdRemoveKeyboard (KdKeyboardInfo *ki)
+{
+ KdKeyboardInfo **prev;
+
+ if (!ki)
+ return;
+
+ for (prev = &kdKeyboards; *prev; prev = &(*prev)->next) {
+ if (*prev == ki) {
+ *prev = ki->next;
+ break;
+ }
+ }
+
+ KdFreeKeyboard(ki);
+}
+
+int
+KdAddConfigPointer (char *pointer)
+{
+ struct KdConfigDevice **prev, *new;
+
+ if (!pointer)
+ return Success;
+
+ new = (struct KdConfigDevice *) xcalloc(sizeof(struct KdConfigDevice), 1);
+ if (!new)
+ return BadAlloc;
+
+ new->line = xstrdup(pointer);
+ new->next = NULL;
+
+ for (prev = &kdConfigPointers; *prev; prev = &(*prev)->next);
+ *prev = new;
+
+ return Success;
+}
+
+int
+KdAddPointer (KdPointerInfo *pi)
+{
+ KdPointerInfo **prev;
+
+ if (!pi)
+ return Success;
+
+ pi->mouseState = start;
+ pi->eventHeld = FALSE;
+
+ pi->dixdev = AddInputDevice(serverClient, KdPointerProc, TRUE);
+ if (!pi->dixdev) {
+ ErrorF("Couldn't add pointer device %s\n",
+ pi->name ? pi->name : "(unnamed)");
+ return BadDevice;
+ }
+
+ pi->dixdev->deviceGrab.ActivateGrab = ActivatePointerGrab;
+ pi->dixdev->deviceGrab.DeactivateGrab = DeactivatePointerGrab;
+ RegisterOtherDevice(pi->dixdev);
+
+ for (prev = &kdPointers; *prev; prev = &(*prev)->next);
+ *prev = pi;
+
+ return Success;
+}
+
+void
+KdRemovePointer (KdPointerInfo *pi)
+{
+ KdPointerInfo **prev;
+
+ if (!pi)
+ return;
+
+ for (prev = &kdPointers; *prev; prev = &(*prev)->next) {
+ if (*prev == pi) {
+ *prev = pi->next;
+ break;
+ }
+ }
+
+ KdFreePointer(pi);
+}
+
+/*
+ * You can call your kdriver server with something like:
+ * $ ./hw/kdrive/yourserver/X :1 -mouse evdev,,device=/dev/input/event4 -keybd
+ * evdev,,device=/dev/input/event1,xkbmodel=abnt2,xkblayout=br
+ */
+static Bool
+KdGetOptions (InputOption **options, char *string)
+{
+ InputOption *newopt = NULL, **tmpo = NULL;
+ int tam_key = 0;
+
+ newopt = xcalloc(1, sizeof (InputOption));
+ if (!newopt)
+ return FALSE;
+
+ for (tmpo = options; *tmpo; tmpo = &(*tmpo)->next)
+ ; /* Hello, I'm here */
+ *tmpo = newopt;
+
+ if (strchr(string, '='))
+ {
+ tam_key = (strchr(string, '=') - string);
+ newopt->key = (char *)xalloc(tam_key);
+ strncpy(newopt->key, string, tam_key);
+ newopt->key[tam_key] = '\0';
+ newopt->value = xstrdup(strchr(string, '=') + 1);
+ }
+ else
+ {
+ newopt->key = xstrdup(string);
+ newopt->value = NULL;
+ }
+ newopt->next = NULL;
+
+ return TRUE;
+}
+
+static void
+KdParseKbdOptions (KdKeyboardInfo *ki)
+{
+ InputOption *option = NULL;
+
+ for (option = ki->options; option; option = option->next)
+ {
+ if (strcasecmp(option->key, "XkbRules") == 0)
+ ki->xkbRules = option->value;
+ else if (strcasecmp(option->key, "XkbModel") == 0)
+ ki->xkbModel = option->value;
+ else if (strcasecmp(option->key, "XkbLayout") == 0)
+ ki->xkbLayout = option->value;
+ else if (strcasecmp(option->key, "XkbVariant") == 0)
+ ki->xkbVariant = option->value;
+ else if (strcasecmp(option->key, "XkbOptions") == 0)
+ ki->xkbOptions = option->value;
+ else if (!strcasecmp (option->key, "device"))
+ ki->path = strdup(option->value);
+ else
+ ErrorF("Kbd option key (%s) of value (%s) not assigned!\n",
+ option->key, option->value);
+ }
+}
+
+KdKeyboardInfo *
+KdParseKeyboard (char *arg)
+{
+ char save[1024];
+ char delim;
+ InputOption *options = NULL;
+ KdKeyboardInfo *ki = NULL;
+
+ ki = KdNewKeyboard();
+ if (!ki)
+ return NULL;
+
+ ki->name = strdup("Unknown KDrive Keyboard");
+ ki->path = NULL;
+ ki->driver = NULL;
+ ki->driverPrivate = NULL;
+ ki->next = NULL;
+
+ if (!arg)
+ {
+ ErrorF("keybd: no arg\n");
+ KdFreeKeyboard (ki);
+ return NULL;
+ }
+
+ if (strlen (arg) >= sizeof (save))
+ {
+ ErrorF("keybd: arg too long\n");
+ KdFreeKeyboard (ki);
+ return NULL;
+ }
+
+ arg = KdParseFindNext (arg, ",", save, &delim);
+ if (!save[0])
+ {
+ ErrorF("keybd: failed on save[0]\n");
+ KdFreeKeyboard (ki);
+ return NULL;
+ }
+
+ if (strcmp (save, "auto") == 0)
+ ki->driverPrivate = NULL;
+ else
+ ki->driverPrivate = xstrdup(save);
+
+ if (delim != ',')
+ {
+ return ki;
+ }
+
+ arg = KdParseFindNext (arg, ",", save, &delim);
+
+ while (delim == ',')
+ {
+ arg = KdParseFindNext (arg, ",", save, &delim);
+
+ if (!KdGetOptions(&options, save))
+ {
+ KdFreeKeyboard(ki);
+ return NULL;
+ }
+ }
+
+ if (options)
+ {
+ ki->options = options;
+ KdParseKbdOptions(ki);
+ }
+
+ return ki;
+}
+
+static void
+KdParsePointerOptions (KdPointerInfo *pi)
+{
+ InputOption *option = NULL;
+
+ for (option = pi->options; option; option = option->next)
+ {
+ if (!strcmp (option->key, "emulatemiddle"))
+ pi->emulateMiddleButton = TRUE;
+ else if (!strcmp (option->key, "noemulatemiddle"))
+ pi->emulateMiddleButton = FALSE;
+ else if (!strcmp (option->key, "transformcoord"))
+ pi->transformCoordinates = TRUE;
+ else if (!strcmp (option->key, "rawcoord"))
+ pi->transformCoordinates = FALSE;
+ else if (!strcasecmp (option->key, "device"))
+ pi->path = strdup(option->value);
+ else if (!strcasecmp (option->key, "protocol"))
+ pi->protocol = strdup(option->value);
+ else
+ ErrorF("Pointer option key (%s) of value (%s) not assigned!\n",
+ option->key, option->value);
+ }
+}
+
+KdPointerInfo *
+KdParsePointer (char *arg)
+{
+ char save[1024];
+ char delim;
+ KdPointerInfo *pi = NULL;
+ InputOption *options = NULL;
+ int i = 0;
+
+ pi = KdNewPointer();
+ if (!pi)
+ return NULL;
+ pi->emulateMiddleButton = kdEmulateMiddleButton;
+ pi->transformCoordinates = !kdRawPointerCoordinates;
+ pi->protocol = NULL;
+ pi->nButtons = 5; /* XXX should not be hardcoded */
+ pi->inputClass = KD_MOUSE;
+
+ if (!arg)
+ {
+ ErrorF("mouse: no arg\n");
+ KdFreePointer (pi);
+ return NULL;
+ }
+
+ if (strlen (arg) >= sizeof (save))
+ {
+ ErrorF("mouse: arg too long\n");
+ KdFreePointer (pi);
+ return NULL;
+ }
+ arg = KdParseFindNext (arg, ",", save, &delim);
+ if (!save[0])
+ {
+ ErrorF("failed on save[0]\n");
+ KdFreePointer (pi);
+ return NULL;
+ }
+
+ if (strcmp(save, "auto") == 0)
+ pi->driverPrivate = NULL;
+ else
+ pi->driverPrivate = xstrdup(save);
+
+ if (delim != ',')
+ {
+ return pi;
+ }
+
+ arg = KdParseFindNext (arg, ",", save, &delim);
+
+ while (delim == ',')
+ {
+ arg = KdParseFindNext (arg, ",", save, &delim);
+ if (save[0] == '{')
+ {
+ char *s = save + 1;
+ i = 0;
+ while (*s && *s != '}')
+ {
+ if ('1' <= *s && *s <= '0' + pi->nButtons)
+ pi->map[i] = *s - '0';
+ else
+ UseMsg ();
+ s++;
+ }
+ }
+ else
+ {
+ if (!KdGetOptions(&options, save))
+ {
+ KdFreePointer(pi);
+ return NULL;
+ }
+ }
+ }
+
+ if (options)
+ {
+ pi->options = options;
+ KdParsePointerOptions(pi);
+ }
+
+ return pi;
+}
+
+
+void
+KdInitInput (void)
+{
+ KdPointerInfo *pi;
+ KdKeyboardInfo *ki;
+ struct KdConfigDevice *dev;
+
+ kdInputEnabled = TRUE;
+
+ for (dev = kdConfigPointers; dev; dev = dev->next) {
+ pi = KdParsePointer(dev->line);
+ if (!pi)
+ ErrorF("Failed to parse pointer\n");
+ if (KdAddPointer(pi) != Success)
+ ErrorF("Failed to add pointer!\n");
+ }
+ for (dev = kdConfigKeyboards; dev; dev = dev->next) {
+ ki = KdParseKeyboard(dev->line);
+ if (!ki)
+ ErrorF("Failed to parse keyboard\n");
+ if (KdAddKeyboard(ki) != Success)
+ ErrorF("Failed to add keyboard!\n");
+ }
+
+ mieqInit();
+}
+
+/*
+ * Middle button emulation state machine
+ *
+ * Possible transitions:
+ * Button 1 press v1
+ * Button 1 release ^1
+ * Button 2 press v2
+ * Button 2 release ^2
+ * Button 3 press v3
+ * Button 3 release ^3
+ * Button other press vo
+ * Button other release ^o
+ * Mouse motion <>
+ * Keyboard event k
+ * timeout ...
+ * outside box <->
+ *
+ * States:
+ * start
+ * button_1_pend
+ * button_1_down
+ * button_2_down
+ * button_3_pend
+ * button_3_down
+ * synthetic_2_down_13
+ * synthetic_2_down_3
+ * synthetic_2_down_1
+ *
+ * Transition diagram
+ *
+ * start
+ * v1 -> (hold) (settimeout) button_1_pend
+ * ^1 -> (deliver) start
+ * v2 -> (deliver) button_2_down
+ * ^2 -> (deliever) start
+ * v3 -> (hold) (settimeout) button_3_pend
+ * ^3 -> (deliver) start
+ * vo -> (deliver) start
+ * ^o -> (deliver) start
+ * <> -> (deliver) start
+ * k -> (deliver) start
+ *
+ * button_1_pend (button 1 is down, timeout pending)
+ * ^1 -> (release) (deliver) start
+ * v2 -> (release) (deliver) button_1_down
+ * ^2 -> (release) (deliver) button_1_down
+ * v3 -> (cleartimeout) (generate v2) synthetic_2_down_13
+ * ^3 -> (release) (deliver) button_1_down
+ * vo -> (release) (deliver) button_1_down
+ * ^o -> (release) (deliver) button_1_down
+ * <-> -> (release) (deliver) button_1_down
+ * <> -> (deliver) button_1_pend
+ * k -> (release) (deliver) button_1_down
+ * ... -> (release) button_1_down
+ *
+ * button_1_down (button 1 is down)
+ * ^1 -> (deliver) start
+ * v2 -> (deliver) button_1_down
+ * ^2 -> (deliver) button_1_down
+ * v3 -> (deliver) button_1_down
+ * ^3 -> (deliver) button_1_down
+ * vo -> (deliver) button_1_down
+ * ^o -> (deliver) button_1_down
+ * <> -> (deliver) button_1_down
+ * k -> (deliver) button_1_down
+ *
+ * button_2_down (button 2 is down)
+ * v1 -> (deliver) button_2_down
+ * ^1 -> (deliver) button_2_down
+ * ^2 -> (deliver) start
+ * v3 -> (deliver) button_2_down
+ * ^3 -> (deliver) button_2_down
+ * vo -> (deliver) button_2_down
+ * ^o -> (deliver) button_2_down
+ * <> -> (deliver) button_2_down
+ * k -> (deliver) button_2_down
+ *
+ * button_3_pend (button 3 is down, timeout pending)
+ * v1 -> (generate v2) synthetic_2_down
+ * ^1 -> (release) (deliver) button_3_down
+ * v2 -> (release) (deliver) button_3_down
+ * ^2 -> (release) (deliver) button_3_down
+ * ^3 -> (release) (deliver) start
+ * vo -> (release) (deliver) button_3_down
+ * ^o -> (release) (deliver) button_3_down
+ * <-> -> (release) (deliver) button_3_down
+ * <> -> (deliver) button_3_pend
+ * k -> (release) (deliver) button_3_down
+ * ... -> (release) button_3_down
+ *
+ * button_3_down (button 3 is down)
+ * v1 -> (deliver) button_3_down
+ * ^1 -> (deliver) button_3_down
+ * v2 -> (deliver) button_3_down
+ * ^2 -> (deliver) button_3_down
+ * ^3 -> (deliver) start
+ * vo -> (deliver) button_3_down
+ * ^o -> (deliver) button_3_down
+ * <> -> (deliver) button_3_down
+ * k -> (deliver) button_3_down
+ *
+ * synthetic_2_down_13 (button 1 and 3 are down)
+ * ^1 -> (generate ^2) synthetic_2_down_3
+ * v2 -> synthetic_2_down_13
+ * ^2 -> synthetic_2_down_13
+ * ^3 -> (generate ^2) synthetic_2_down_1
+ * vo -> (deliver) synthetic_2_down_13
+ * ^o -> (deliver) synthetic_2_down_13
+ * <> -> (deliver) synthetic_2_down_13
+ * k -> (deliver) synthetic_2_down_13
+ *
+ * synthetic_2_down_3 (button 3 is down)
+ * v1 -> (deliver) synthetic_2_down_3
+ * ^1 -> (deliver) synthetic_2_down_3
+ * v2 -> synthetic_2_down_3
+ * ^2 -> synthetic_2_down_3
+ * ^3 -> start
+ * vo -> (deliver) synthetic_2_down_3
+ * ^o -> (deliver) synthetic_2_down_3
+ * <> -> (deliver) synthetic_2_down_3
+ * k -> (deliver) synthetic_2_down_3
+ *
+ * synthetic_2_down_1 (button 1 is down)
+ * ^1 -> start
+ * v2 -> synthetic_2_down_1
+ * ^2 -> synthetic_2_down_1
+ * v3 -> (deliver) synthetic_2_down_1
+ * ^3 -> (deliver) synthetic_2_down_1
+ * vo -> (deliver) synthetic_2_down_1
+ * ^o -> (deliver) synthetic_2_down_1
+ * <> -> (deliver) synthetic_2_down_1
+ * k -> (deliver) synthetic_2_down_1
+ */
+
+typedef enum _inputClass {
+ down_1, up_1,
+ down_2, up_2,
+ down_3, up_3,
+ down_o, up_o,
+ motion, outside_box,
+ keyboard, timeout,
+ num_input_class
+} KdInputClass;
+
+typedef enum _inputAction {
+ noop,
+ hold,
+ setto,
+ deliver,
+ release,
+ clearto,
+ gen_down_2,
+ gen_up_2
+} KdInputAction;
+
+#define MAX_ACTIONS 2
+
+typedef struct _inputTransition {
+ KdInputAction actions[MAX_ACTIONS];
+ KdPointerState nextState;
+} KdInputTransition;
+
+static const
+KdInputTransition kdInputMachine[num_input_states][num_input_class] = {
+ /* start */
+ {
+ { { hold, setto }, button_1_pend }, /* v1 */
+ { { deliver, noop }, start }, /* ^1 */
+ { { deliver, noop }, button_2_down }, /* v2 */
+ { { deliver, noop }, start }, /* ^2 */
+ { { hold, setto }, button_3_pend }, /* v3 */
+ { { deliver, noop }, start }, /* ^3 */
+ { { deliver, noop }, start }, /* vo */
+ { { deliver, noop }, start }, /* ^o */
+ { { deliver, noop }, start }, /* <> */
+ { { deliver, noop }, start }, /* <-> */
+ { { noop, noop }, start }, /* k */
+ { { noop, noop }, start }, /* ... */
+ },
+ /* button_1_pend */
+ {
+ { { noop, noop }, button_1_pend }, /* v1 */
+ { { release, deliver }, start }, /* ^1 */
+ { { release, deliver }, button_1_down }, /* v2 */
+ { { release, deliver }, button_1_down }, /* ^2 */
+ { { clearto, gen_down_2 }, synth_2_down_13 }, /* v3 */
+ { { release, deliver }, button_1_down }, /* ^3 */
+ { { release, deliver }, button_1_down }, /* vo */
+ { { release, deliver }, button_1_down }, /* ^o */
+ { { deliver, noop }, button_1_pend }, /* <> */
+ { { release, deliver }, button_1_down }, /* <-> */
+ { { noop, noop }, button_1_down }, /* k */
+ { { release, noop }, button_1_down }, /* ... */
+ },
+ /* button_1_down */
+ {
+ { { noop, noop }, button_1_down }, /* v1 */
+ { { deliver, noop }, start }, /* ^1 */
+ { { deliver, noop }, button_1_down }, /* v2 */
+ { { deliver, noop }, button_1_down }, /* ^2 */
+ { { deliver, noop }, button_1_down }, /* v3 */
+ { { deliver, noop }, button_1_down }, /* ^3 */
+ { { deliver, noop }, button_1_down }, /* vo */
+ { { deliver, noop }, button_1_down }, /* ^o */
+ { { deliver, noop }, button_1_down }, /* <> */
+ { { deliver, noop }, button_1_down }, /* <-> */
+ { { noop, noop }, button_1_down }, /* k */
+ { { noop, noop }, button_1_down }, /* ... */
+ },
+ /* button_2_down */
+ {
+ { { deliver, noop }, button_2_down }, /* v1 */
+ { { deliver, noop }, button_2_down }, /* ^1 */
+ { { noop, noop }, button_2_down }, /* v2 */
+ { { deliver, noop }, start }, /* ^2 */
+ { { deliver, noop }, button_2_down }, /* v3 */
+ { { deliver, noop }, button_2_down }, /* ^3 */
+ { { deliver, noop }, button_2_down }, /* vo */
+ { { deliver, noop }, button_2_down }, /* ^o */
+ { { deliver, noop }, button_2_down }, /* <> */
+ { { deliver, noop }, button_2_down }, /* <-> */
+ { { noop, noop }, button_2_down }, /* k */
+ { { noop, noop }, button_2_down }, /* ... */
+ },
+ /* button_3_pend */
+ {
+ { { clearto, gen_down_2 }, synth_2_down_13 }, /* v1 */
+ { { release, deliver }, button_3_down }, /* ^1 */
+ { { release, deliver }, button_3_down }, /* v2 */
+ { { release, deliver }, button_3_down }, /* ^2 */
+ { { release, deliver }, button_3_down }, /* v3 */
+ { { release, deliver }, start }, /* ^3 */
+ { { release, deliver }, button_3_down }, /* vo */
+ { { release, deliver }, button_3_down }, /* ^o */
+ { { deliver, noop }, button_3_pend }, /* <> */
+ { { release, deliver }, button_3_down }, /* <-> */
+ { { release, noop }, button_3_down }, /* k */
+ { { release, noop }, button_3_down }, /* ... */
+ },
+ /* button_3_down */
+ {
+ { { deliver, noop }, button_3_down }, /* v1 */
+ { { deliver, noop }, button_3_down }, /* ^1 */
+ { { deliver, noop }, button_3_down }, /* v2 */
+ { { deliver, noop }, button_3_down }, /* ^2 */
+ { { noop, noop }, button_3_down }, /* v3 */
+ { { deliver, noop }, start }, /* ^3 */
+ { { deliver, noop }, button_3_down }, /* vo */
+ { { deliver, noop }, button_3_down }, /* ^o */
+ { { deliver, noop }, button_3_down }, /* <> */
+ { { deliver, noop }, button_3_down }, /* <-> */
+ { { noop, noop }, button_3_down }, /* k */
+ { { noop, noop }, button_3_down }, /* ... */
+ },
+ /* synthetic_2_down_13 */
+ {
+ { { noop, noop }, synth_2_down_13 }, /* v1 */
+ { { gen_up_2, noop }, synth_2_down_3 }, /* ^1 */
+ { { noop, noop }, synth_2_down_13 }, /* v2 */
+ { { noop, noop }, synth_2_down_13 }, /* ^2 */
+ { { noop, noop }, synth_2_down_13 }, /* v3 */
+ { { gen_up_2, noop }, synth_2_down_1 }, /* ^3 */
+ { { deliver, noop }, synth_2_down_13 }, /* vo */
+ { { deliver, noop }, synth_2_down_13 }, /* ^o */
+ { { deliver, noop }, synth_2_down_13 }, /* <> */
+ { { deliver, noop }, synth_2_down_13 }, /* <-> */
+ { { noop, noop }, synth_2_down_13 }, /* k */
+ { { noop, noop }, synth_2_down_13 }, /* ... */
+ },
+ /* synthetic_2_down_3 */
+ {
+ { { deliver, noop }, synth_2_down_3 }, /* v1 */
+ { { deliver, noop }, synth_2_down_3 }, /* ^1 */
+ { { deliver, noop }, synth_2_down_3 }, /* v2 */
+ { { deliver, noop }, synth_2_down_3 }, /* ^2 */
+ { { noop, noop }, synth_2_down_3 }, /* v3 */
+ { { noop, noop }, start }, /* ^3 */
+ { { deliver, noop }, synth_2_down_3 }, /* vo */
+ { { deliver, noop }, synth_2_down_3 }, /* ^o */
+ { { deliver, noop }, synth_2_down_3 }, /* <> */
+ { { deliver, noop }, synth_2_down_3 }, /* <-> */
+ { { noop, noop }, synth_2_down_3 }, /* k */
+ { { noop, noop }, synth_2_down_3 }, /* ... */
+ },
+ /* synthetic_2_down_1 */
+ {
+ { { noop, noop }, synth_2_down_1 }, /* v1 */
+ { { noop, noop }, start }, /* ^1 */
+ { { deliver, noop }, synth_2_down_1 }, /* v2 */
+ { { deliver, noop }, synth_2_down_1 }, /* ^2 */
+ { { deliver, noop }, synth_2_down_1 }, /* v3 */
+ { { deliver, noop }, synth_2_down_1 }, /* ^3 */
+ { { deliver, noop }, synth_2_down_1 }, /* vo */
+ { { deliver, noop }, synth_2_down_1 }, /* ^o */
+ { { deliver, noop }, synth_2_down_1 }, /* <> */
+ { { deliver, noop }, synth_2_down_1 }, /* <-> */
+ { { noop, noop }, synth_2_down_1 }, /* k */
+ { { noop, noop }, synth_2_down_1 }, /* ... */
+ },
+};
+
+#define EMULATION_WINDOW 10
+#define EMULATION_TIMEOUT 100
+
+static int
+KdInsideEmulationWindow (KdPointerInfo *pi, int x, int y, int z)
+{
+ pi->emulationDx = pi->heldEvent.x - x;
+ pi->emulationDy = pi->heldEvent.y - y;
+
+ return (abs (pi->emulationDx) < EMULATION_WINDOW &&
+ abs (pi->emulationDy) < EMULATION_WINDOW);
+}
+
+static KdInputClass
+KdClassifyInput (KdPointerInfo *pi, int type, int x, int y, int z, int b)
+{
+ switch (type) {
+ case ButtonPress:
+ switch (b) {
+ case 1: return down_1;
+ case 2: return down_2;
+ case 3: return down_3;
+ default: return down_o;
+ }
+ break;
+ case ButtonRelease:
+ switch (b) {
+ case 1: return up_1;
+ case 2: return up_2;
+ case 3: return up_3;
+ default: return up_o;
+ }
+ break;
+ case MotionNotify:
+ if (pi->eventHeld && !KdInsideEmulationWindow(pi, x, y, z))
+ return outside_box;
+ else
+ return motion;
+ default:
+ return keyboard;
+ }
+ return keyboard;
+}
+
+#ifdef DEBUG
+char *kdStateNames[] = {
+ "start",
+ "button_1_pend",
+ "button_1_down",
+ "button_2_down",
+ "button_3_pend",
+ "button_3_down",
+ "synth_2_down_13",
+ "synth_2_down_3",
+ "synthetic_2_down_1",
+ "num_input_states"
+};
+
+char *kdClassNames[] = {
+ "down_1", "up_1",
+ "down_2", "up_2",
+ "down_3", "up_3",
+ "motion", "ouside_box",
+ "keyboard", "timeout",
+ "num_input_class"
+};
+
+char *kdActionNames[] = {
+ "noop",
+ "hold",
+ "setto",
+ "deliver",
+ "release",
+ "clearto",
+ "gen_down_2",
+ "gen_up_2",
+};
+#endif /* DEBUG */
+
+static void
+KdQueueEvent (DeviceIntPtr pDev, InternalEvent *ev)
+{
+ KdAssertSigioBlocked ("KdQueueEvent");
+ mieqEnqueue (pDev, ev);
+}
+
+/* We return true if we're stealing the event. */
+static Bool
+KdRunMouseMachine (KdPointerInfo *pi, KdInputClass c, int type, int x, int y,
+ int z, int b, int absrel)
+{
+ const KdInputTransition *t;
+ int a;
+
+ c = KdClassifyInput(pi, type, x, y, z, b);
+ t = &kdInputMachine[pi->mouseState][c];
+ for (a = 0; a < MAX_ACTIONS; a++)
+ {
+ switch (t->actions[a]) {
+ case noop:
+ break;
+ case hold:
+ pi->eventHeld = TRUE;
+ pi->emulationDx = 0;
+ pi->emulationDy = 0;
+ pi->heldEvent.type = type;
+ pi->heldEvent.x = x;
+ pi->heldEvent.y = y;
+ pi->heldEvent.z = z;
+ pi->heldEvent.flags = b;
+ pi->heldEvent.absrel = absrel;
+ return TRUE;
+ break;
+ case setto:
+ pi->emulationTimeout = GetTimeInMillis () + EMULATION_TIMEOUT;
+ pi->timeoutPending = TRUE;
+ break;
+ case deliver:
+ _KdEnqueuePointerEvent (pi, pi->heldEvent.type, pi->heldEvent.x,
+ pi->heldEvent.y, pi->heldEvent.z,
+ pi->heldEvent.flags, pi->heldEvent.absrel,
+ TRUE);
+ break;
+ case release:
+ pi->eventHeld = FALSE;
+ pi->timeoutPending = FALSE;
+ _KdEnqueuePointerEvent (pi, pi->heldEvent.type, pi->heldEvent.x,
+ pi->heldEvent.y, pi->heldEvent.z,
+ pi->heldEvent.flags, pi->heldEvent.absrel,
+ TRUE);
+ return TRUE;
+ break;
+ case clearto:
+ pi->timeoutPending = FALSE;
+ break;
+ case gen_down_2:
+ _KdEnqueuePointerEvent (pi, ButtonPress, x, y, z, 2, absrel,
+ TRUE);
+ pi->eventHeld = FALSE;
+ return TRUE;
+ break;
+ case gen_up_2:
+ _KdEnqueuePointerEvent (pi, ButtonRelease, x, y, z, 2, absrel,
+ TRUE);
+ return TRUE;
+ break;
+ }
+ }
+ pi->mouseState = t->nextState;
+ return FALSE;
+}
+
+static int
+KdHandlePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z, int b,
+ int absrel)
+{
+ if (pi->emulateMiddleButton)
+ return KdRunMouseMachine (pi, KdClassifyInput(pi, type, x, y, z, b),
+ type, x, y, z, b, absrel);
+ return FALSE;
+}
+
+static void
+KdReceiveTimeout (KdPointerInfo *pi)
+{
+ KdRunMouseMachine (pi, timeout, 0, 0, 0, 0, 0, 0);
+}
+
+/*
+ * kdCheckTermination
+ *
+ * This function checks for the key sequence that terminates the server. When
+ * detected, it sets the dispatchException flag and returns. The key sequence
+ * is:
+ * Control-Alt
+ * It's assumed that the server will be waken up by the caller when this
+ * function returns.
+ */
+
+extern int nClients;
+
+void
+KdReleaseAllKeys (void)
+{
+#if 0
+ int key, nEvents, i;
+ KdKeyboardInfo *ki;
+
+ KdBlockSigio ();
+
+ for (ki = kdKeyboards; ki; ki = ki->next) {
+ for (key = ki->keySyms.minKeyCode; key < ki->keySyms.maxKeyCode;
+ key++) {
+ if (key_is_down(ki->dixdev, key, KEY_POSTED | KEY_PROCESSED)) {
+ KdHandleKeyboardEvent(ki, KeyRelease, key);
+ GetEventList(&kdEvents);
+ nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key);
+ for (i = 0; i < nEvents; i++)
+ KdQueueEvent (ki->dixdev, (kdEvents + i)->event);
+ }
+ }
+ }
+
+ KdUnblockSigio ();
+#endif
+}
+
+static void
+KdCheckLock (void)
+{
+ KeyClassPtr keyc = NULL;
+ Bool isSet = FALSE, shouldBeSet = FALSE;
+ KdKeyboardInfo *tmp = NULL;
+
+ for (tmp = kdKeyboards; tmp; tmp = tmp->next) {
+ if (tmp->LockLed && tmp->dixdev && tmp->dixdev->key) {
+ keyc = tmp->dixdev->key;
+ isSet = (tmp->leds & (1 << (tmp->LockLed-1))) != 0;
+ /* FIXME: Just use XKB indicators! */
+ shouldBeSet = !!(XkbStateFieldFromRec(&keyc->xkbInfo->state) & LockMask);
+ if (isSet != shouldBeSet)
+ KdSetLed (tmp, tmp->LockLed, shouldBeSet);
+ }
+ }
+}
+
+void
+KdEnqueueKeyboardEvent(KdKeyboardInfo *ki,
+ unsigned char scan_code,
+ unsigned char is_up)
+{
+ unsigned char key_code;
+ KeyClassPtr keyc = NULL;
+ KeybdCtrl *ctrl = NULL;
+ int type, nEvents, i;
+
+ if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key)
+ return;
+
+ keyc = ki->dixdev->key;
+ ctrl = &ki->dixdev->kbdfeed->ctrl;
+
+ if (scan_code >= ki->minScanCode && scan_code <= ki->maxScanCode)
+ {
+ key_code = scan_code + KD_MIN_KEYCODE - ki->minScanCode;
+
+ /*
+ * Set up this event -- the type may be modified below
+ */
+ if (is_up)
+ type = KeyRelease;
+ else
+ type = KeyPress;
+
+ GetEventList(&kdEvents);
+
+ nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, type, key_code);
+ for (i = 0; i < nEvents; i++)
+ KdQueueEvent(ki->dixdev, (InternalEvent *)((kdEvents + i)->event));
+ }
+ else {
+ ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n",
+ ki->name, scan_code, ki->minScanCode, ki->maxScanCode);
+ }
+}
+
+/*
+ * kdEnqueuePointerEvent
+ *
+ * This function converts hardware mouse event information into X event
+ * information. A mouse movement event is passed off to MI to generate
+ * a MotionNotify event, if appropriate. Button events are created and
+ * passed off to MI for enqueueing.
+ */
+
+/* FIXME do something a little more clever to deal with multiple axes here */
+void
+KdEnqueuePointerEvent(KdPointerInfo *pi, unsigned long flags, int rx, int ry,
+ int rz)
+{
+ CARD32 ms;
+ unsigned char buttons;
+ int x, y, z;
+ int (*matrix)[3] = kdPointerMatrix.matrix;
+ unsigned long button;
+ int n;
+ int dixflags = 0;
+
+ if (!pi)
+ return;
+
+ ms = GetTimeInMillis();
+
+ /* we don't need to transform z, so we don't. */
+ if (flags & KD_MOUSE_DELTA) {
+ if (pi->transformCoordinates) {
+ x = matrix[0][0] * rx + matrix[0][1] * ry;
+ y = matrix[1][0] * rx + matrix[1][1] * ry;
+ }
+ else {
+ x = rx;
+ y = ry;
+ }
+ }
+ else {
+ if (pi->transformCoordinates) {
+ x = matrix[0][0] * rx + matrix[0][1] * ry + matrix[0][2];
+ y = matrix[1][0] * rx + matrix[1][1] * ry + matrix[1][2];
+ }
+ else {
+ x = rx;
+ y = ry;
+ }
+ }
+ z = rz;
+
+ if (flags & KD_MOUSE_DELTA)
+ {
+ if (x || y || z)
+ {
+ dixflags = POINTER_RELATIVE | POINTER_ACCELERATE;
+ _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, FALSE);
+ }
+ } else
+ {
+ dixflags = POINTER_ABSOLUTE;
+ if (x != pi->dixdev->last.valuators[0] ||
+ y != pi->dixdev->last.valuators[1])
+ _KdEnqueuePointerEvent(pi, MotionNotify, x, y, z, 0, dixflags, FALSE);
+ }
+
+ buttons = flags;
+
+ for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons;
+ button <<= 1, n++) {
+ if (((pi->buttonState & button) ^ (buttons & button)) &&
+ !(buttons & button)) {
+ _KdEnqueuePointerEvent(pi, ButtonRelease, x, y, z, n,
+ dixflags, FALSE);
+ }
+ }
+ for (button = KD_BUTTON_1, n = 1; n <= pi->nButtons;
+ button <<= 1, n++) {
+ if (((pi->buttonState & button) ^ (buttons & button)) &&
+ (buttons & button)) {
+ _KdEnqueuePointerEvent(pi, ButtonPress, x, y, z, n,
+ dixflags, FALSE);
+ }
+ }
+
+ pi->buttonState = buttons;
+}
+
+void
+_KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z,
+ int b, int absrel, Bool force)
+{
+ int nEvents = 0, i = 0;
+ int valuators[3] = { x, y, z };
+
+ /* TRUE from KdHandlePointerEvent, means 'we swallowed the event'. */
+ if (!force && KdHandlePointerEvent(pi, type, x, y, z, b, absrel))
+ return;
+
+ GetEventList(&kdEvents);
+ nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel,
+ 0, 3, valuators);
+ for (i = 0; i < nEvents; i++)
+ KdQueueEvent(pi->dixdev, (InternalEvent *)((kdEvents + i)->event));
+}
+
+void
+KdBlockHandler (int screen,
+ pointer blockData,
+ pointer timeout,
+ pointer readmask)
+{
+ KdPointerInfo *pi;
+ int myTimeout=0;
+
+ for (pi = kdPointers; pi; pi = pi->next)
+ {
+ if (pi->timeoutPending)
+ {
+ int ms;
+
+ ms = pi->emulationTimeout - GetTimeInMillis ();
+ if (ms < 1)
+ ms = 1;
+ if(ms<myTimeout || myTimeout==0)
+ myTimeout=ms;
+ }
+ }
+ /* if we need to poll for events, do that */
+ if(kdOsFuncs->pollEvents)
+ {
+ (*kdOsFuncs->pollEvents)();
+ myTimeout=20;
+ }
+ if(myTimeout>0)
+ AdjustWaitForDelay (timeout, myTimeout);
+}
+
+void
+KdWakeupHandler (int screen,
+ pointer data,
+ unsigned long lresult,
+ pointer readmask)
+{
+ int result = (int) lresult;
+ fd_set *pReadmask = (fd_set *) readmask;
+ int i;
+ KdPointerInfo *pi;
+
+ if (kdInputEnabled && result > 0)
+ {
+ for (i = 0; i < kdNumInputFds; i++)
+ if (FD_ISSET (kdInputFds[i].fd, pReadmask))
+ {
+ KdBlockSigio ();
+ (*kdInputFds[i].read) (kdInputFds[i].fd, kdInputFds[i].closure);
+ KdUnblockSigio ();
+ }
+ }
+ for (pi = kdPointers; pi; pi = pi->next)
+ {
+ if (pi->timeoutPending)
+ {
+ if ((long) (GetTimeInMillis () - pi->emulationTimeout) >= 0)
+ {
+ pi->timeoutPending = FALSE;
+ KdBlockSigio ();
+ KdReceiveTimeout (pi);
+ KdUnblockSigio ();
+ }
+ }
+ }
+ if (kdSwitchPending)
+ KdProcessSwitch ();
+}
+
+#define KdScreenOrigin(pScreen) (&(KdGetScreenPriv(pScreen)->screen->origin))
+
+static Bool
+KdCursorOffScreen(ScreenPtr *ppScreen, int *x, int *y)
+{
+ ScreenPtr pScreen = *ppScreen;
+ ScreenPtr pNewScreen;
+ int n;
+ int dx, dy;
+ int best_x, best_y;
+ int n_best_x, n_best_y;
+ CARD32 ms;
+
+ if (kdDisableZaphod || screenInfo.numScreens <= 1)
+ return FALSE;
+
+ if (0 <= *x && *x < pScreen->width && 0 <= *y && *y < pScreen->height)
+ return FALSE;
+
+ ms = GetTimeInMillis ();
+ if (kdOffScreen && (int) (ms - kdOffScreenTime) < 1000)
+ return FALSE;
+ kdOffScreen = TRUE;
+ kdOffScreenTime = ms;
+ n_best_x = -1;
+ best_x = 32767;
+ n_best_y = -1;
+ best_y = 32767;
+ for (n = 0; n < screenInfo.numScreens; n++)
+ {
+ pNewScreen = screenInfo.screens[n];
+ if (pNewScreen == pScreen)
+ continue;
+ dx = KdScreenOrigin(pNewScreen)->x - KdScreenOrigin(pScreen)->x;
+ dy = KdScreenOrigin(pNewScreen)->y - KdScreenOrigin(pScreen)->y;
+ if (*x < 0)
+ {
+ if (dx <= 0 && -dx < best_x)
+ {
+ best_x = -dx;
+ n_best_x = n;
+ }
+ }
+ else if (*x >= pScreen->width)
+ {
+ if (dx >= 0 && dx < best_x)
+ {
+ best_x = dx;
+ n_best_x = n;
+ }
+ }
+ if (*y < 0)
+ {
+ if (dy <= 0 && -dy < best_y)
+ {
+ best_y = -dy;
+ n_best_y = n;
+ }
+ }
+ else if (*y >= pScreen->height)
+ {
+ if (dy >= 0 && dy < best_y)
+ {
+ best_y = dy;
+ n_best_y = n;
+ }
+ }
+ }
+ if (best_y < best_x)
+ n_best_x = n_best_y;
+ if (n_best_x == -1)
+ return FALSE;
+ pNewScreen = screenInfo.screens[n_best_x];
+
+ if (*x < 0)
+ *x += pNewScreen->width;
+ if (*y < 0)
+ *y += pNewScreen->height;
+
+ if (*x >= pScreen->width)
+ *x -= pScreen->width;
+ if (*y >= pScreen->height)
+ *y -= pScreen->height;
+
+ *ppScreen = pNewScreen;
+ return TRUE;
+}
+
+static void
+KdCrossScreen(ScreenPtr pScreen, Bool entering)
+{
+#ifndef XIPAQ
+ if (entering)
+ KdEnableScreen (pScreen);
+ else
+ KdDisableScreen (pScreen);
+#endif
+}
+
+int KdCurScreen; /* current event screen */
+
+static void
+KdWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
+{
+ KdBlockSigio ();
+ KdCurScreen = pScreen->myNum;
+ miPointerWarpCursor(pDev, pScreen, x, y);
+ KdUnblockSigio ();
+}
+
+miPointerScreenFuncRec kdPointerScreenFuncs =
+{
+ KdCursorOffScreen,
+ KdCrossScreen,
+ KdWarpCursor
+};
+
+#ifndef _MSC_VER
+void
+ProcessInputEvents (void)
+{
+ mieqProcessInputEvents();
+ miPointerUpdateSprite(inputInfo.pointer);
+ if (kdSwitchPending)
+ KdProcessSwitch ();
+ KdCheckLock ();
+}
+#endif
+
+/* FIXME use XSECURITY to work out whether the client should be allowed to
+ * open and close. */
+void
+OpenInputDevice(DeviceIntPtr pDev, ClientPtr client, int *status)
+{
+ if (!pDev)
+ *status = BadDevice;
+ else
+ *status = Success;
+}
+
+void
+CloseInputDevice(DeviceIntPtr pDev, ClientPtr client)
+{
+ return;
+}
+
+/* We initialise all input devices at startup. */
+void
+AddOtherInputDevices(void)
+{
+ return;
+}
+
+/* At the moment, absolute/relative is up to the client. */
+int
+SetDeviceMode(register ClientPtr client, DeviceIntPtr pDev, int mode)
+{
+ return BadMatch;
+}
+
+int
+SetDeviceValuators(register ClientPtr client, DeviceIntPtr pDev,
+ int *valuators, int first_valuator, int num_valuators)
+{
+ return BadMatch;
+}
+
+int
+ChangeDeviceControl(register ClientPtr client, DeviceIntPtr pDev,
+ xDeviceCtl *control)
+{
+ switch (control->control) {
+ case DEVICE_RESOLUTION:
+ /* FIXME do something more intelligent here */
+ return BadMatch;
+
+ case DEVICE_ABS_CALIB:
+ case DEVICE_ABS_AREA:
+ return Success;
+
+ case DEVICE_CORE:
+ return BadMatch;
+ case DEVICE_ENABLE:
+ return Success;
+
+ default:
+ return BadMatch;
+ }
+
+ /* NOTREACHED */
+ return BadImplementation;
+}
+
+int
+NewInputDeviceRequest(InputOption *options, InputAttributes *attrs,
+ DeviceIntPtr *pdev)
+{
+ InputOption *option = NULL;
+ KdPointerInfo *pi = NULL;
+ KdKeyboardInfo *ki = NULL;
+
+ for (option = options; option; option = option->next) {
+ if (strcmp(option->key, "type") == 0) {
+ if (strcmp(option->value, "pointer") == 0) {
+ pi = KdNewPointer();
+ if (!pi)
+ return BadAlloc;
+ }
+ else if (strcmp(option->value, "keyboard") == 0) {
+ ki = KdNewKeyboard();
+ if (!ki)
+ return BadAlloc;
+ }
+ else {
+ ErrorF("unrecognised device type!\n");
+ return BadValue;
+ }
+ }
+#ifdef CONFIG_HAL
+ else if (strcmp(option->key, "_source") == 0 &&
+ strcmp(option->value, "server/hal") == 0)
+ {
+ ErrorF("Ignoring device from HAL.\n");
+ return BadValue;
+ }
+#endif
+#ifdef CONFIG_UDEV
+ else if (strcmp(option->key, "_source") == 0 &&
+ strcmp(option->value, "server/udev") == 0)
+ {
+ ErrorF("Ignoring device from udev.\n");
+ return BadValue;
+ }
+#endif
+ }
+
+ if (!ki && !pi) {
+ ErrorF("unrecognised device identifier!\n");
+ return BadValue;
+ }
+
+ /* FIXME: change this code below to use KdParseKbdOptions and
+ * KdParsePointerOptions */
+ for (option = options; option; option = option->next) {
+ if (strcmp(option->key, "device") == 0) {
+ if (pi && option->value)
+ pi->path = strdup(option->value);
+ else if (ki && option->value)
+ ki->path = strdup(option->value);
+ }
+ else if (strcmp(option->key, "driver") == 0) {
+ if (pi) {
+ pi->driver = KdFindPointerDriver(option->value);
+ if (!pi->driver) {
+ ErrorF("couldn't find driver!\n");
+ KdFreePointer(pi);
+ return BadValue;
+ }
+ pi->options = options;
+ }
+ else if (ki) {
+ ki->driver = KdFindKeyboardDriver(option->value);
+ if (!ki->driver) {
+ ErrorF("couldn't find driver!\n");
+ KdFreeKeyboard(ki);
+ return BadValue;
+ }
+ ki->options = options;
+ }
+ }
+ }
+
+ if (pi) {
+ if (KdAddPointer(pi) != Success ||
+ ActivateDevice(pi->dixdev, TRUE) != Success ||
+ EnableDevice(pi->dixdev, TRUE) != TRUE) {
+ ErrorF("couldn't add or enable pointer\n");
+ return BadImplementation;
+ }
+ }
+ else if (ki) {
+ if (KdAddKeyboard(ki) != Success ||
+ ActivateDevice(ki->dixdev, TRUE) != Success ||
+ EnableDevice(ki->dixdev, TRUE) != TRUE) {
+ ErrorF("couldn't add or enable keyboard\n");
+ return BadImplementation;
+ }
+ }
+
+ if (pi) {
+ *pdev = pi->dixdev;
+ } else if(ki) {
+ *pdev = ki->dixdev;
+ }
+
+ return Success;
+}
+
+void
+DeleteInputDeviceRequest(DeviceIntPtr pDev)
+{
+ RemoveDevice(pDev, TRUE);
+}
diff --git a/xorg-server/hw/kdrive/src/makefile b/xorg-server/hw/kdrive/src/makefile new file mode 100644 index 000000000..e3a826faa --- /dev/null +++ b/xorg-server/hw/kdrive/src/makefile @@ -0,0 +1,14 @@ +LIBRARY = libkdrive + +CSRCS = \ + kcmap.c \ + kcurscol.c \ + kdrive.c \ + kinfo.c \ + kinput.c \ + kmap.c \ + kmode.c \ + kshadow.c + + + diff --git a/xorg-server/hw/xfree86/common/compiler.h b/xorg-server/hw/xfree86/common/compiler.h index ded71ee22..6414dd4a9 100644 --- a/xorg-server/hw/xfree86/common/compiler.h +++ b/xorg-server/hw/xfree86/common/compiler.h @@ -1,1376 +1,1376 @@ -/* - * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. - * - * 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 Thomas Roell not be used in - * advertising or publicity pertaining to distribution of the software without - * specific, written prior permission. Thomas Roell makes no representations - * about the suitability of this software for any purpose. It is provided - * "as is" without express or implied warranty. - * - * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO - * EVENT SHALL THOMAS ROELL 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 (c) 1994-2003 by The XFree86 Project, Inc. - * - * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 copyright holder(s) - * and author(s) 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 copyright holder(s) and author(s). - */ - -#ifndef _COMPILER_H - -# define _COMPILER_H - -#if defined(__SUNPRO_C) -# define DO_PROTOTYPES -#endif - -/* Map Sun compiler platform defines to gcc-style used in the code */ -#if defined(__amd64) && !defined(__amd64__) -# define __amd64__ -#endif -#if defined(__i386) && !defined(__i386__) -# define __i386__ -#endif -#if defined(__sparc) && !defined(__sparc__) -# define __sparc__ -#endif -#if defined(__sparcv9) && !defined(__sparc64__) -# define __sparc64__ -#endif - -#ifndef _X_EXPORT -# include <X11/Xfuncproto.h> -#endif - -# include <pixman.h> /* for uint*_t types */ - -/* Allow drivers to use the GCC-supported __inline__ and/or __inline. */ -# ifndef __inline__ -# if defined(__GNUC__) - /* gcc has __inline__ */ -# elif defined(__HIGHC__) -# define __inline__ _Inline -# else -# define __inline__ /**/ -# endif -# endif /* __inline__ */ -# ifndef __inline -# if defined(__GNUC__) - /* gcc has __inline */ -# elif defined(__HIGHC__) -# define __inline _Inline -# else -# define __inline /**/ -# endif -# endif /* __inline */ - -/* Support gcc's __FUNCTION__ for people using other compilers */ -#if !defined(__GNUC__) && !defined(__FUNCTION__) -# define __FUNCTION__ __func__ /* C99 */ -#endif - -# if defined(NO_INLINE) || defined(DO_PROTOTYPES) - -# if !defined(__arm__) -# if !defined(__sparc__) && !defined(__sparc) && !defined(__arm32__) \ - && !(defined(__alpha__) && defined(linux)) \ - && !(defined(__ia64__) && defined(linux)) \ - -extern _X_EXPORT void outb(unsigned short, unsigned char); -extern _X_EXPORT void outw(unsigned short, unsigned short); -extern _X_EXPORT void outl(unsigned short, unsigned int); -extern _X_EXPORT unsigned int inb(unsigned short); -extern _X_EXPORT unsigned int inw(unsigned short); -extern _X_EXPORT unsigned int inl(unsigned short); - -# else /* __sparc__, __arm32__, __alpha__*/ - -extern _X_EXPORT void outb(unsigned long, unsigned char); -extern _X_EXPORT void outw(unsigned long, unsigned short); -extern _X_EXPORT void outl(unsigned long, unsigned int); -extern _X_EXPORT unsigned int inb(unsigned long); -extern _X_EXPORT unsigned int inw(unsigned long); -extern _X_EXPORT unsigned int inl(unsigned long); - -# endif /* __sparc__, __arm32__, __alpha__ */ -# endif /* __arm__ */ - -# if defined(__powerpc__) && !defined(__OpenBSD__) -extern unsigned long ldq_u(unsigned long *); -extern unsigned long ldl_u(unsigned int *); -extern unsigned long ldw_u(unsigned short *); -extern void stq_u(unsigned long, unsigned long *); -extern void stl_u(unsigned long, unsigned int *); -extern void stw_u(unsigned long, unsigned short *); -extern void mem_barrier(void); -extern void write_mem_barrier(void); -extern void stl_brx(unsigned long, volatile unsigned char *, int); -extern void stw_brx(unsigned short, volatile unsigned char *, int); -extern unsigned long ldl_brx(volatile unsigned char *, int); -extern unsigned short ldw_brx(volatile unsigned char *, int); -# endif /* __powerpc__ && !__OpenBSD */ - -# endif /* NO_INLINE || DO_PROTOTYPES */ - -# ifndef NO_INLINE -# ifdef __GNUC__ -# ifdef __i386__ - -# ifdef __SSE__ -# define write_mem_barrier() __asm__ __volatile__ ("sfence" : : : "memory") -# else -# define write_mem_barrier() __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory") -# endif - -# ifdef __SSE2__ -# define mem_barrier() __asm__ __volatile__ ("mfence" : : : "memory") -# else -# define mem_barrier() __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory") -# endif - -# elif defined __alpha__ - -# define mem_barrier() __asm__ __volatile__ ("mb" : : : "memory") -# define write_mem_barrier() __asm__ __volatile__ ("wmb" : : : "memory") - -# elif defined __amd64__ - -# define mem_barrier() __asm__ __volatile__ ("mfence" : : : "memory") -# define write_mem_barrier() __asm__ __volatile__ ("sfence" : : : "memory") - -# elif defined __ia64__ - -# ifndef __INTEL_COMPILER -# define mem_barrier() __asm__ __volatile__ ("mf" : : : "memory") -# define write_mem_barrier() __asm__ __volatile__ ("mf" : : : "memory") -# else -# include "ia64intrin.h" -# define mem_barrier() __mf() -# define write_mem_barrier() __mf() -# endif - -# elif defined __mips__ - /* Note: sync instruction requires MIPS II instruction set */ -# define mem_barrier() \ - __asm__ __volatile__( \ - ".set push\n\t" \ - ".set noreorder\n\t" \ - ".set mips2\n\t" \ - "sync\n\t" \ - ".set pop" \ - : /* no output */ \ - : /* no input */ \ - : "memory") -# define write_mem_barrier() mem_barrier() - -# elif defined __powerpc__ - -# if defined(linux) && defined(__powerpc64__) -# include <linux/version.h> -# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) -# include <asm/memory.h> -# endif -# endif /* defined(linux) && defined(__powerpc64__) */ - -# ifndef eieio /* We deal with arch-specific eieio() routines above... */ -# define eieio() __asm__ __volatile__ ("eieio" ::: "memory") -# endif /* eieio */ -# define mem_barrier() eieio() -# define write_mem_barrier() eieio() - -# elif defined __sparc__ - -# define barrier() __asm__ __volatile__ (".word 0x8143e00a" : : : "memory") -# define mem_barrier() /* XXX: nop for now */ -# define write_mem_barrier() /* XXX: nop for now */ -# endif -# endif /* __GNUC__ */ -# endif /* NO_INLINE */ - -# ifndef mem_barrier -# define mem_barrier() /* NOP */ -# endif - -# ifndef write_mem_barrier -# define write_mem_barrier() /* NOP */ -# endif - - -# ifndef NO_INLINE -# ifdef __GNUC__ - -/* Define some packed structures to use with unaligned accesses */ - -struct __una_u64 { uint64_t x __attribute__((packed)); }; -struct __una_u32 { uint32_t x __attribute__((packed)); }; -struct __una_u16 { uint16_t x __attribute__((packed)); }; - -/* Elemental unaligned loads */ - -static __inline__ uint64_t ldq_u(uint64_t *p) -{ - const struct __una_u64 *ptr = (const struct __una_u64 *) p; - return ptr->x; -} - -static __inline__ uint32_t ldl_u(uint32_t *p) -{ - const struct __una_u32 *ptr = (const struct __una_u32 *) p; - return ptr->x; -} - -static __inline__ uint16_t ldw_u(uint16_t *p) -{ - const struct __una_u16 *ptr = (const struct __una_u16 *) p; - return ptr->x; -} - -/* Elemental unaligned stores */ - -static __inline__ void stq_u(uint64_t val, uint64_t *p) -{ - struct __una_u64 *ptr = (struct __una_u64 *) p; - ptr->x = val; -} - -static __inline__ void stl_u(uint32_t val, uint32_t *p) -{ - struct __una_u32 *ptr = (struct __una_u32 *) p; - ptr->x = val; -} - -static __inline__ void stw_u(uint16_t val, uint16_t *p) -{ - struct __una_u16 *ptr = (struct __una_u16 *) p; - ptr->x = val; -} -# else /* !__GNUC__ */ - -#include <string.h> /* needed for memmove */ - -static __inline__ uint64_t ldq_u(uint64_t *p) -{ - uint64_t ret; - memmove(&ret, p, sizeof(*p)); - return ret; -} - -static __inline__ uint32_t ldl_u(uint32_t *p) -{ - uint32_t ret; - memmove(&ret, p, sizeof(*p)); - return ret; -} - -static __inline__ uint16_t ldw_u(uint16_t *p) -{ - uint16_t ret; - memmove(&ret, p, sizeof(*p)); - return ret; -} - -static __inline__ void stq_u(uint64_t val, uint64_t *p) -{ - uint64_t tmp = val; - memmove(p, &tmp, sizeof(*p)); -} - -static __inline__ void stl_u(uint32_t val, uint32_t *p) -{ - uint32_t tmp = val; - memmove(p, &tmp, sizeof(*p)); -} - -static __inline__ void stw_u(uint16_t val, uint16_t *p) -{ - uint16_t tmp = val; - memmove(p, &tmp, sizeof(*p)); -} - -# endif /* __GNUC__ */ -# endif /* NO_INLINE */ - -# ifndef NO_INLINE -# ifdef __GNUC__ -# if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && (defined(__alpha__)) - -# ifdef linux -/* for Linux on Alpha, we use the LIBC _inx/_outx routines */ -/* note that the appropriate setup via "ioperm" needs to be done */ -/* *before* any inx/outx is done. */ - -extern _X_EXPORT void _outb(unsigned char val, unsigned long port); -extern _X_EXPORT void _outw(unsigned short val, unsigned long port); -extern _X_EXPORT void _outl(unsigned int val, unsigned long port); -extern _X_EXPORT unsigned int _inb(unsigned long port); -extern _X_EXPORT unsigned int _inw(unsigned long port); -extern _X_EXPORT unsigned int _inl(unsigned long port); - -static __inline__ void -outb(unsigned long port, unsigned char val) -{ - _outb(val, port); -} - -static __inline__ void -outw(unsigned long port, unsigned short val) -{ - _outw(val, port); -} - -static __inline__ void -outl(unsigned long port, unsigned int val) -{ - _outl(val, port); -} - -static __inline__ unsigned int -inb(unsigned long port) -{ - return _inb(port); -} - -static __inline__ unsigned int -inw(unsigned long port) -{ - return _inw(port); -} - -static __inline__ unsigned int -inl(unsigned long port) -{ - return _inl(port); -} - -# endif /* linux */ - -# if (defined(__FreeBSD__) || defined(__OpenBSD__)) \ - && !defined(DO_PROTOTYPES) - -/* for FreeBSD and OpenBSD on Alpha, we use the libio (resp. libalpha) */ -/* inx/outx routines */ -/* note that the appropriate setup via "ioperm" needs to be done */ -/* *before* any inx/outx is done. */ - -extern _X_EXPORT void outb(unsigned int port, unsigned char val); -extern _X_EXPORT void outw(unsigned int port, unsigned short val); -extern _X_EXPORT void outl(unsigned int port, unsigned int val); -extern _X_EXPORT unsigned char inb(unsigned int port); -extern _X_EXPORT unsigned short inw(unsigned int port); -extern _X_EXPORT unsigned int inl(unsigned int port); - -# endif /* (__FreeBSD__ || __OpenBSD__ ) && !DO_PROTOTYPES */ - - -#if defined(__NetBSD__) -#include <machine/pio.h> -#endif /* __NetBSD__ */ - -# elif defined(linux) && defined(__ia64__) - -# include <inttypes.h> - -# include <sys/io.h> - -# undef outb -# undef outw -# undef outl -# undef inb -# undef inw -# undef inl -extern _X_EXPORT void outb(unsigned long port, unsigned char val); -extern _X_EXPORT void outw(unsigned long port, unsigned short val); -extern _X_EXPORT void outl(unsigned long port, unsigned int val); -extern _X_EXPORT unsigned int inb(unsigned long port); -extern _X_EXPORT unsigned int inw(unsigned long port); -extern _X_EXPORT unsigned int inl(unsigned long port); - -# elif (defined(linux) || defined(__FreeBSD__)) && defined(__amd64__) - -# include <inttypes.h> - -static __inline__ void -outb(unsigned short port, unsigned char val) -{ - __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port)); -} - - -static __inline__ void -outw(unsigned short port, unsigned short val) -{ - __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port)); -} - -static __inline__ void -outl(unsigned short port, unsigned int val) -{ - __asm__ __volatile__("outl %0,%1" : :"a" (val), "d" (port)); -} - -static __inline__ unsigned int -inb(unsigned short port) -{ - unsigned char ret; - __asm__ __volatile__("inb %1,%0" : - "=a" (ret) : - "d" (port)); - return ret; -} - -static __inline__ unsigned int -inw(unsigned short port) -{ - unsigned short ret; - __asm__ __volatile__("inw %1,%0" : - "=a" (ret) : - "d" (port)); - return ret; -} - -static __inline__ unsigned int -inl(unsigned short port) -{ - unsigned int ret; - __asm__ __volatile__("inl %1,%0" : - "=a" (ret) : - "d" (port)); - return ret; -} - -# elif (defined(linux) || defined(sun) || defined(__OpenBSD__) || defined(__FreeBSD__)) && defined(__sparc__) - -# ifndef ASI_PL -# define ASI_PL 0x88 -# endif - -static __inline__ void -outb(unsigned long port, unsigned char val) -{ - __asm__ __volatile__("stba %0, [%1] %2" - : /* No outputs */ - : "r" (val), "r" (port), "i" (ASI_PL)); - barrier(); -} - -static __inline__ void -outw(unsigned long port, unsigned short val) -{ - __asm__ __volatile__("stha %0, [%1] %2" - : /* No outputs */ - : "r" (val), "r" (port), "i" (ASI_PL)); - barrier(); -} - -static __inline__ void -outl(unsigned long port, unsigned int val) -{ - __asm__ __volatile__("sta %0, [%1] %2" - : /* No outputs */ - : "r" (val), "r" (port), "i" (ASI_PL)); - barrier(); -} - -static __inline__ unsigned int -inb(unsigned long port) -{ - unsigned int ret; - __asm__ __volatile__("lduba [%1] %2, %0" - : "=r" (ret) - : "r" (port), "i" (ASI_PL)); - return ret; -} - -static __inline__ unsigned int -inw(unsigned long port) -{ - unsigned int ret; - __asm__ __volatile__("lduha [%1] %2, %0" - : "=r" (ret) - : "r" (port), "i" (ASI_PL)); - return ret; -} - -static __inline__ unsigned int -inl(unsigned long port) -{ - unsigned int ret; - __asm__ __volatile__("lda [%1] %2, %0" - : "=r" (ret) - : "r" (port), "i" (ASI_PL)); - return ret; -} - -static __inline__ unsigned char -xf86ReadMmio8(__volatile__ void *base, const unsigned long offset) -{ - unsigned long addr = ((unsigned long)base) + offset; - unsigned char ret; - - __asm__ __volatile__("lduba [%1] %2, %0" - : "=r" (ret) - : "r" (addr), "i" (ASI_PL)); - return ret; -} - -static __inline__ unsigned short -xf86ReadMmio16Be(__volatile__ void *base, const unsigned long offset) -{ - unsigned long addr = ((unsigned long)base) + offset; - unsigned short ret; - - __asm__ __volatile__("lduh [%1], %0" - : "=r" (ret) - : "r" (addr)); - return ret; -} - -static __inline__ unsigned short -xf86ReadMmio16Le(__volatile__ void *base, const unsigned long offset) -{ - unsigned long addr = ((unsigned long)base) + offset; - unsigned short ret; - - __asm__ __volatile__("lduha [%1] %2, %0" - : "=r" (ret) - : "r" (addr), "i" (ASI_PL)); - return ret; -} - -static __inline__ unsigned int -xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset) -{ - unsigned long addr = ((unsigned long)base) + offset; - unsigned int ret; - - __asm__ __volatile__("ld [%1], %0" - : "=r" (ret) - : "r" (addr)); - return ret; -} - -static __inline__ unsigned int -xf86ReadMmio32Le(__volatile__ void *base, const unsigned long offset) -{ - unsigned long addr = ((unsigned long)base) + offset; - unsigned int ret; - - __asm__ __volatile__("lda [%1] %2, %0" - : "=r" (ret) - : "r" (addr), "i" (ASI_PL)); - return ret; -} - -static __inline__ void -xf86WriteMmio8(__volatile__ void *base, const unsigned long offset, - const unsigned int val) -{ - unsigned long addr = ((unsigned long)base) + offset; - - __asm__ __volatile__("stba %0, [%1] %2" - : /* No outputs */ - : "r" (val), "r" (addr), "i" (ASI_PL)); - barrier(); -} - -static __inline__ void -xf86WriteMmio16Be(__volatile__ void *base, const unsigned long offset, - const unsigned int val) -{ - unsigned long addr = ((unsigned long)base) + offset; - - __asm__ __volatile__("sth %0, [%1]" - : /* No outputs */ - : "r" (val), "r" (addr)); - barrier(); -} - -static __inline__ void -xf86WriteMmio16Le(__volatile__ void *base, const unsigned long offset, - const unsigned int val) -{ - unsigned long addr = ((unsigned long)base) + offset; - - __asm__ __volatile__("stha %0, [%1] %2" - : /* No outputs */ - : "r" (val), "r" (addr), "i" (ASI_PL)); - barrier(); -} - -static __inline__ void -xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset, - const unsigned int val) -{ - unsigned long addr = ((unsigned long)base) + offset; - - __asm__ __volatile__("st %0, [%1]" - : /* No outputs */ - : "r" (val), "r" (addr)); - barrier(); -} - -static __inline__ void -xf86WriteMmio32Le(__volatile__ void *base, const unsigned long offset, - const unsigned int val) -{ - unsigned long addr = ((unsigned long)base) + offset; - - __asm__ __volatile__("sta %0, [%1] %2" - : /* No outputs */ - : "r" (val), "r" (addr), "i" (ASI_PL)); - barrier(); -} - -static __inline__ void -xf86WriteMmio8NB(__volatile__ void *base, const unsigned long offset, - const unsigned int val) -{ - unsigned long addr = ((unsigned long)base) + offset; - - __asm__ __volatile__("stba %0, [%1] %2" - : /* No outputs */ - : "r" (val), "r" (addr), "i" (ASI_PL)); -} - -static __inline__ void -xf86WriteMmio16BeNB(__volatile__ void *base, const unsigned long offset, - const unsigned int val) -{ - unsigned long addr = ((unsigned long)base) + offset; - - __asm__ __volatile__("sth %0, [%1]" - : /* No outputs */ - : "r" (val), "r" (addr)); -} - -static __inline__ void -xf86WriteMmio16LeNB(__volatile__ void *base, const unsigned long offset, - const unsigned int val) -{ - unsigned long addr = ((unsigned long)base) + offset; - - __asm__ __volatile__("stha %0, [%1] %2" - : /* No outputs */ - : "r" (val), "r" (addr), "i" (ASI_PL)); -} - -static __inline__ void -xf86WriteMmio32BeNB(__volatile__ void *base, const unsigned long offset, - const unsigned int val) -{ - unsigned long addr = ((unsigned long)base) + offset; - - __asm__ __volatile__("st %0, [%1]" - : /* No outputs */ - : "r" (val), "r" (addr)); -} - -static __inline__ void -xf86WriteMmio32LeNB(__volatile__ void *base, const unsigned long offset, - const unsigned int val) -{ - unsigned long addr = ((unsigned long)base) + offset; - - __asm__ __volatile__("sta %0, [%1] %2" - : /* No outputs */ - : "r" (val), "r" (addr), "i" (ASI_PL)); -} - -# elif defined(__mips__) || (defined(__arm32__) && !defined(__linux__)) -# ifdef __arm32__ -# define PORT_SIZE long -# else -# define PORT_SIZE short -# endif - -_X_EXPORT unsigned int IOPortBase; /* Memory mapped I/O port area */ - -static __inline__ void -outb(unsigned PORT_SIZE port, unsigned char val) -{ - *(volatile unsigned char*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val; -} - -static __inline__ void -outw(unsigned PORT_SIZE port, unsigned short val) -{ - *(volatile unsigned short*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val; -} - -static __inline__ void -outl(unsigned PORT_SIZE port, unsigned int val) -{ - *(volatile unsigned int*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val; -} - -static __inline__ unsigned int -inb(unsigned PORT_SIZE port) -{ - return *(volatile unsigned char*)(((unsigned PORT_SIZE)(port))+IOPortBase); -} - -static __inline__ unsigned int -inw(unsigned PORT_SIZE port) -{ - return *(volatile unsigned short*)(((unsigned PORT_SIZE)(port))+IOPortBase); -} - -static __inline__ unsigned int -inl(unsigned PORT_SIZE port) -{ - return *(volatile unsigned int*)(((unsigned PORT_SIZE)(port))+IOPortBase); -} - - -# if defined(__mips__) -# ifdef linux /* don't mess with other OSs */ -# if X_BYTE_ORDER == X_BIG_ENDIAN -static __inline__ unsigned int -xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset) -{ - unsigned long addr = ((unsigned long)base) + offset; - unsigned int ret; - - __asm__ __volatile__("lw %0, 0(%1)" - : "=r" (ret) - : "r" (addr)); - return ret; -} - -static __inline__ void -xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset, - const unsigned int val) -{ - unsigned long addr = ((unsigned long)base) + offset; - - __asm__ __volatile__("sw %0, 0(%1)" - : /* No outputs */ - : "r" (val), "r" (addr)); -} -# endif -# endif /* !linux */ -# endif /* __mips__ */ - -# elif (defined(linux) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)) && defined(__powerpc__) - -# ifndef MAP_FAILED -# define MAP_FAILED ((void *)-1) -# endif - -extern _X_EXPORT volatile unsigned char *ioBase; - -static __inline__ unsigned char -xf86ReadMmio8(__volatile__ void *base, const unsigned long offset) -{ - register unsigned char val; - __asm__ __volatile__( - "lbzx %0,%1,%2\n\t" - "eieio" - : "=r" (val) - : "b" (base), "r" (offset), - "m" (*((volatile unsigned char *)base+offset))); - return val; -} - -static __inline__ unsigned short -xf86ReadMmio16Be(__volatile__ void *base, const unsigned long offset) -{ - register unsigned short val; - __asm__ __volatile__( - "lhzx %0,%1,%2\n\t" - "eieio" - : "=r" (val) - : "b" (base), "r" (offset), - "m" (*((volatile unsigned char *)base+offset))); - return val; -} - -static __inline__ unsigned short -xf86ReadMmio16Le(__volatile__ void *base, const unsigned long offset) -{ - register unsigned short val; - __asm__ __volatile__( - "lhbrx %0,%1,%2\n\t" - "eieio" - : "=r" (val) - : "b" (base), "r" (offset), - "m" (*((volatile unsigned char *)base+offset))); - return val; -} - -static __inline__ unsigned int -xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset) -{ - register unsigned int val; - __asm__ __volatile__( - "lwzx %0,%1,%2\n\t" - "eieio" - : "=r" (val) - : "b" (base), "r" (offset), - "m" (*((volatile unsigned char *)base+offset))); - return val; -} - -static __inline__ unsigned int -xf86ReadMmio32Le(__volatile__ void *base, const unsigned long offset) -{ - register unsigned int val; - __asm__ __volatile__( - "lwbrx %0,%1,%2\n\t" - "eieio" - : "=r" (val) - : "b" (base), "r" (offset), - "m" (*((volatile unsigned char *)base+offset))); - return val; -} - -static __inline__ void -xf86WriteMmioNB8(__volatile__ void *base, const unsigned long offset, - const unsigned char val) -{ - __asm__ __volatile__( - "stbx %1,%2,%3\n\t" - : "=m" (*((volatile unsigned char *)base+offset)) - : "r" (val), "b" (base), "r" (offset)); -} - -static __inline__ void -xf86WriteMmioNB16Le(__volatile__ void *base, const unsigned long offset, - const unsigned short val) -{ - __asm__ __volatile__( - "sthbrx %1,%2,%3\n\t" - : "=m" (*((volatile unsigned char *)base+offset)) - : "r" (val), "b" (base), "r" (offset)); -} - -static __inline__ void -xf86WriteMmioNB16Be(__volatile__ void *base, const unsigned long offset, - const unsigned short val) -{ - __asm__ __volatile__( - "sthx %1,%2,%3\n\t" - : "=m" (*((volatile unsigned char *)base+offset)) - : "r" (val), "b" (base), "r" (offset)); -} - -static __inline__ void -xf86WriteMmioNB32Le(__volatile__ void *base, const unsigned long offset, - const unsigned int val) -{ - __asm__ __volatile__( - "stwbrx %1,%2,%3\n\t" - : "=m" (*((volatile unsigned char *)base+offset)) - : "r" (val), "b" (base), "r" (offset)); -} - -static __inline__ void -xf86WriteMmioNB32Be(__volatile__ void *base, const unsigned long offset, - const unsigned int val) -{ - __asm__ __volatile__( - "stwx %1,%2,%3\n\t" - : "=m" (*((volatile unsigned char *)base+offset)) - : "r" (val), "b" (base), "r" (offset)); -} - -static __inline__ void -xf86WriteMmio8(__volatile__ void *base, const unsigned long offset, - const unsigned char val) -{ - xf86WriteMmioNB8(base, offset, val); - eieio(); -} - -static __inline__ void -xf86WriteMmio16Le(__volatile__ void *base, const unsigned long offset, - const unsigned short val) -{ - xf86WriteMmioNB16Le(base, offset, val); - eieio(); -} - -static __inline__ void -xf86WriteMmio16Be(__volatile__ void *base, const unsigned long offset, - const unsigned short val) -{ - xf86WriteMmioNB16Be(base, offset, val); - eieio(); -} - -static __inline__ void -xf86WriteMmio32Le(__volatile__ void *base, const unsigned long offset, - const unsigned int val) -{ - xf86WriteMmioNB32Le(base, offset, val); - eieio(); -} - -static __inline__ void -xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset, - const unsigned int val) -{ - xf86WriteMmioNB32Be(base, offset, val); - eieio(); -} - - -static __inline__ void -outb(unsigned short port, unsigned char value) -{ - if(ioBase == MAP_FAILED) return; - xf86WriteMmio8((void *)ioBase, port, value); -} - -static __inline__ void -outw(unsigned short port, unsigned short value) -{ - if(ioBase == MAP_FAILED) return; - xf86WriteMmio16Le((void *)ioBase, port, value); -} - -static __inline__ void -outl(unsigned short port, unsigned int value) -{ - if(ioBase == MAP_FAILED) return; - xf86WriteMmio32Le((void *)ioBase, port, value); -} - -static __inline__ unsigned int -inb(unsigned short port) -{ - if(ioBase == MAP_FAILED) return 0; - return xf86ReadMmio8((void *)ioBase, port); -} - -static __inline__ unsigned int -inw(unsigned short port) -{ - if(ioBase == MAP_FAILED) return 0; - return xf86ReadMmio16Le((void *)ioBase, port); -} - -static __inline__ unsigned int -inl(unsigned short port) -{ - if(ioBase == MAP_FAILED) return 0; - return xf86ReadMmio32Le((void *)ioBase, port); -} - -#elif defined(__arm__) && defined(__linux__) - -/* for Linux on ARM, we use the LIBC inx/outx routines */ -/* note that the appropriate setup via "ioperm" needs to be done */ -/* *before* any inx/outx is done. */ - -#include <sys/io.h> - -static __inline__ void -xf_outb(unsigned short port, unsigned char val) -{ - outb(val, port); -} - -static __inline__ void -xf_outw(unsigned short port, unsigned short val) -{ - outw(val, port); -} - -static __inline__ void -xf_outl(unsigned short port, unsigned int val) -{ - outl(val, port); -} - -#define outb xf_outb -#define outw xf_outw -#define outl xf_outl - -# else /* ix86 */ - -# if !defined(__SUNPRO_C) -# if !defined(FAKEIT) && !defined(__mc68000__) && !defined(__arm__) && !defined(__sh__) && !defined(__hppa__) && !defined(__s390__) && !defined(__m32r__) -# ifdef GCCUSESGAS - -/* - * If gcc uses gas rather than the native assembler, the syntax of these - * inlines has to be different. DHD - */ - -static __inline__ void -outb(unsigned short port, unsigned char val) -{ - __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port)); -} - - -static __inline__ void -outw(unsigned short port, unsigned short val) -{ - __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port)); -} - -static __inline__ void -outl(unsigned short port, unsigned int val) -{ - __asm__ __volatile__("outl %0,%1" : :"a" (val), "d" (port)); -} - -static __inline__ unsigned int -inb(unsigned short port) -{ - unsigned char ret; - __asm__ __volatile__("inb %1,%0" : - "=a" (ret) : - "d" (port)); - return ret; -} - -static __inline__ unsigned int -inw(unsigned short port) -{ - unsigned short ret; - __asm__ __volatile__("inw %1,%0" : - "=a" (ret) : - "d" (port)); - return ret; -} - -static __inline__ unsigned int -inl(unsigned short port) -{ - unsigned int ret; - __asm__ __volatile__("inl %1,%0" : - "=a" (ret) : - "d" (port)); - return ret; -} - -# else /* GCCUSESGAS */ - -static __inline__ void -outb(unsigned short port, unsigned char val) -{ - __asm__ __volatile__("out%B0 (%1)" : :"a" (val), "d" (port)); -} - -static __inline__ void -outw(unsigned short port, unsigned short val) -{ - __asm__ __volatile__("out%W0 (%1)" : :"a" (val), "d" (port)); -} - -static __inline__ void -outl(unsigned short port, unsigned int val) -{ - __asm__ __volatile__("out%L0 (%1)" : :"a" (val), "d" (port)); -} - -static __inline__ unsigned int -inb(unsigned short port) -{ - unsigned char ret; - __asm__ __volatile__("in%B0 (%1)" : - "=a" (ret) : - "d" (port)); - return ret; -} - -static __inline__ unsigned int -inw(unsigned short port) -{ - unsigned short ret; - __asm__ __volatile__("in%W0 (%1)" : - "=a" (ret) : - "d" (port)); - return ret; -} - -static __inline__ unsigned int -inl(unsigned short port) -{ - unsigned int ret; - __asm__ __volatile__("in%L0 (%1)" : - "=a" (ret) : - "d" (port)); - return ret; -} - -# endif /* GCCUSESGAS */ - -# else /* !defined(FAKEIT) && !defined(__mc68000__) && !defined(__arm__) && !defined(__sh__) && !defined(__hppa__) && !defined(__m32r__) */ - -static __inline__ void -outb(unsigned short port, unsigned char val) -{ -} - -static __inline__ void -outw(unsigned short port, unsigned short val) -{ -} - -static __inline__ void -outl(unsigned short port, unsigned int val) -{ -} - -static __inline__ unsigned int -inb(unsigned short port) -{ - return 0; -} - -static __inline__ unsigned int -inw(unsigned short port) -{ - return 0; -} - -static __inline__ unsigned int -inl(unsigned short port) -{ - return 0; -} - -# endif /* FAKEIT */ -# endif /* __SUNPRO_C */ - -# endif /* ix86 */ - -# else /* !GNUC */ -# if defined(__STDC__) && (__STDC__ == 1) -# ifndef asm -# define asm __asm -# endif -# endif -# ifndef SCO325 -# if defined(__UNIXWARE__) -# /* avoid including <sys/types.h> for <sys/inline.h> on UnixWare */ -# define ushort unsigned short -# define ushort_t unsigned short -# define ulong unsigned long -# define ulong_t unsigned long -# define uint_t unsigned int -# define uchar_t unsigned char -# endif /* __UNIXWARE__ */ -# if !defined(__SUNPRO_C) -# include <sys/inline.h> -# endif -# else -# include "scoasm.h" -# endif -# if !defined(__HIGHC__) && !defined(__SUNPRO_C) || \ - defined(__USLC__) -# pragma asm partial_optimization outl -# pragma asm partial_optimization outw -# pragma asm partial_optimization outb -# pragma asm partial_optimization inl -# pragma asm partial_optimization inw -# pragma asm partial_optimization inb -# endif -# endif /* __GNUC__ */ - -# endif /* NO_INLINE */ - -# ifdef __alpha__ -/* entry points for Mmio memory access routines */ -extern _X_EXPORT int (*xf86ReadMmio8)(void *, unsigned long); -extern _X_EXPORT int (*xf86ReadMmio16)(void *, unsigned long); -# ifndef STANDALONE_MMIO -extern _X_EXPORT int (*xf86ReadMmio32)(void *, unsigned long); -# else -/* Some DRI 3D drivers need MMIO_IN32. */ -static __inline__ int -xf86ReadMmio32(void *Base, unsigned long Offset) -{ - mem_barrier(); - return *(volatile unsigned int*)((unsigned long)Base+(Offset)); -} -# endif -extern _X_EXPORT void (*xf86WriteMmio8)(int, void *, unsigned long); -extern _X_EXPORT void (*xf86WriteMmio16)(int, void *, unsigned long); -extern _X_EXPORT void (*xf86WriteMmio32)(int, void *, unsigned long); -extern _X_EXPORT void (*xf86WriteMmioNB8)(int, void *, unsigned long); -extern _X_EXPORT void (*xf86WriteMmioNB16)(int, void *, unsigned long); -extern _X_EXPORT void (*xf86WriteMmioNB32)(int, void *, unsigned long); -extern _X_EXPORT void xf86SlowBCopyFromBus(unsigned char *, unsigned char *, int); -extern _X_EXPORT void xf86SlowBCopyToBus(unsigned char *, unsigned char *, int); - -/* Some macros to hide the system dependencies for MMIO accesses */ -/* Changed to kill noise generated by gcc's -Wcast-align */ -# define MMIO_IN8(base, offset) (*xf86ReadMmio8)(base, offset) -# define MMIO_IN16(base, offset) (*xf86ReadMmio16)(base, offset) -# ifndef STANDALONE_MMIO -# define MMIO_IN32(base, offset) (*xf86ReadMmio32)(base, offset) -# else -# define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset) -# endif - -# define MMIO_OUT32(base, offset, val) \ - do { \ - write_mem_barrier(); \ - *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val); \ - } while (0) -# define MMIO_ONB32(base, offset, val) \ - *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val) - -# define MMIO_OUT8(base, offset, val) \ - (*xf86WriteMmio8)((CARD8)(val), base, offset) -# define MMIO_OUT16(base, offset, val) \ - (*xf86WriteMmio16)((CARD16)(val), base, offset) -# define MMIO_ONB8(base, offset, val) \ - (*xf86WriteMmioNB8)((CARD8)(val), base, offset) -# define MMIO_ONB16(base, offset, val) \ - (*xf86WriteMmioNB16)((CARD16)(val), base, offset) -# define MMIO_MOVE32(base, offset, val) \ - MMIO_OUT32(base, offset, val) - -# elif defined(__powerpc__) - /* - * we provide byteswapping and no byteswapping functions here - * with byteswapping as default, - * drivers that don't need byteswapping should define PPC_MMIO_IS_BE - */ -# define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset) -# define MMIO_OUT8(base, offset, val) \ - xf86WriteMmio8(base, offset, (CARD8)(val)) -# define MMIO_ONB8(base, offset, val) \ - xf86WriteMmioNB8(base, offset, (CARD8)(val)) - -# if defined(PPC_MMIO_IS_BE) /* No byteswapping */ -# define MMIO_IN16(base, offset) xf86ReadMmio16Be(base, offset) -# define MMIO_IN32(base, offset) xf86ReadMmio32Be(base, offset) -# define MMIO_OUT16(base, offset, val) \ - xf86WriteMmio16Be(base, offset, (CARD16)(val)) -# define MMIO_OUT32(base, offset, val) \ - xf86WriteMmio32Be(base, offset, (CARD32)(val)) -# define MMIO_ONB16(base, offset, val) \ - xf86WriteMmioNB16Be(base, offset, (CARD16)(val)) -# define MMIO_ONB32(base, offset, val) \ - xf86WriteMmioNB32Be(base, offset, (CARD32)(val)) -# else /* byteswapping is the default */ -# define MMIO_IN16(base, offset) xf86ReadMmio16Le(base, offset) -# define MMIO_IN32(base, offset) xf86ReadMmio32Le(base, offset) -# define MMIO_OUT16(base, offset, val) \ - xf86WriteMmio16Le(base, offset, (CARD16)(val)) -# define MMIO_OUT32(base, offset, val) \ - xf86WriteMmio32Le(base, offset, (CARD32)(val)) -# define MMIO_ONB16(base, offset, val) \ - xf86WriteMmioNB16Le(base, offset, (CARD16)(val)) -# define MMIO_ONB32(base, offset, val) \ - xf86WriteMmioNB32Le(base, offset, (CARD32)(val)) -# endif - -# define MMIO_MOVE32(base, offset, val) \ - xf86WriteMmio32Be(base, offset, (CARD32)(val)) - -# elif defined(__sparc__) || defined(sparc) || defined(__sparc) - /* - * Like powerpc, we provide byteswapping and no byteswapping functions - * here with byteswapping as default, drivers that don't need byteswapping - * should define SPARC_MMIO_IS_BE (perhaps create a generic macro so that we - * do not need to use PPC_MMIO_IS_BE and the sparc one in all the same places - * of drivers?). - */ -# define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset) -# define MMIO_OUT8(base, offset, val) \ - xf86WriteMmio8(base, offset, (CARD8)(val)) -# define MMIO_ONB8(base, offset, val) \ - xf86WriteMmio8NB(base, offset, (CARD8)(val)) - -# if defined(SPARC_MMIO_IS_BE) /* No byteswapping */ -# define MMIO_IN16(base, offset) xf86ReadMmio16Be(base, offset) -# define MMIO_IN32(base, offset) xf86ReadMmio32Be(base, offset) -# define MMIO_OUT16(base, offset, val) \ - xf86WriteMmio16Be(base, offset, (CARD16)(val)) -# define MMIO_OUT32(base, offset, val) \ - xf86WriteMmio32Be(base, offset, (CARD32)(val)) -# define MMIO_ONB16(base, offset, val) \ - xf86WriteMmio16BeNB(base, offset, (CARD16)(val)) -# define MMIO_ONB32(base, offset, val) \ - xf86WriteMmio32BeNB(base, offset, (CARD32)(val)) -# else /* byteswapping is the default */ -# define MMIO_IN16(base, offset) xf86ReadMmio16Le(base, offset) -# define MMIO_IN32(base, offset) xf86ReadMmio32Le(base, offset) -# define MMIO_OUT16(base, offset, val) \ - xf86WriteMmio16Le(base, offset, (CARD16)(val)) -# define MMIO_OUT32(base, offset, val) \ - xf86WriteMmio32Le(base, offset, (CARD32)(val)) -# define MMIO_ONB16(base, offset, val) \ - xf86WriteMmio16LeNB(base, offset, (CARD16)(val)) -# define MMIO_ONB32(base, offset, val) \ - xf86WriteMmio32LeNB(base, offset, (CARD32)(val)) -# endif - -# define MMIO_MOVE32(base, offset, val) \ - xf86WriteMmio32Be(base, offset, (CARD32)(val)) - -# else /* !__alpha__ && !__powerpc__ && !__sparc__ */ - -# define MMIO_IN8(base, offset) \ - *(volatile CARD8 *)(((CARD8*)(base)) + (offset)) -# define MMIO_IN16(base, offset) \ - *(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset)) -# define MMIO_IN32(base, offset) \ - *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) -# define MMIO_OUT8(base, offset, val) \ - *(volatile CARD8 *)(((CARD8*)(base)) + (offset)) = (val) -# define MMIO_OUT16(base, offset, val) \ - *(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset)) = (val) -# define MMIO_OUT32(base, offset, val) \ - *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val) -# define MMIO_ONB8(base, offset, val) MMIO_OUT8(base, offset, val) -# define MMIO_ONB16(base, offset, val) MMIO_OUT16(base, offset, val) -# define MMIO_ONB32(base, offset, val) MMIO_OUT32(base, offset, val) - -# define MMIO_MOVE32(base, offset, val) MMIO_OUT32(base, offset, val) - -# endif /* __alpha__ */ - -/* - * With Intel, the version in os-support/misc/SlowBcopy.s is used. - * This avoids port I/O during the copy (which causes problems with - * some hardware). - */ -# ifdef __alpha__ -# define slowbcopy_tobus(src,dst,count) xf86SlowBCopyToBus(src,dst,count) -# define slowbcopy_frombus(src,dst,count) xf86SlowBCopyFromBus(src,dst,count) -# else /* __alpha__ */ -# define slowbcopy_tobus(src,dst,count) xf86SlowBcopy(src,dst,count) -# define slowbcopy_frombus(src,dst,count) xf86SlowBcopy(src,dst,count) -# endif /* __alpha__ */ - -#endif /* _COMPILER_H */ +/*
+ * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany.
+ *
+ * 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 Thomas Roell not be used in
+ * advertising or publicity pertaining to distribution of the software without
+ * specific, written prior permission. Thomas Roell makes no representations
+ * about the suitability of this software for any purpose. It is provided
+ * "as is" without express or implied warranty.
+ *
+ * THOMAS ROELL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
+ * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
+ * EVENT SHALL THOMAS ROELL 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 (c) 1994-2003 by The XFree86 Project, Inc.
+ *
+ * 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 COPYRIGHT HOLDER(S) OR AUTHOR(S) 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 copyright holder(s)
+ * and author(s) 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 copyright holder(s) and author(s).
+ */
+
+#ifndef _COMPILER_H
+
+# define _COMPILER_H
+
+#if defined(__SUNPRO_C)
+# define DO_PROTOTYPES
+#endif
+
+/* Map Sun compiler platform defines to gcc-style used in the code */
+#if defined(__amd64) && !defined(__amd64__)
+# define __amd64__
+#endif
+#if defined(__i386) && !defined(__i386__)
+# define __i386__
+#endif
+#if defined(__sparc) && !defined(__sparc__)
+# define __sparc__
+#endif
+#if defined(__sparcv9) && !defined(__sparc64__)
+# define __sparc64__
+#endif
+
+#ifndef _X_EXPORT
+# include <X11/Xfuncproto.h>
+#endif
+
+# include <pixman.h> /* for uint*_t types */
+
+/* Allow drivers to use the GCC-supported __inline__ and/or __inline. */
+# ifndef __inline__
+# if defined(__GNUC__)
+ /* gcc has __inline__ */
+# elif defined(__HIGHC__)
+# define __inline__ _Inline
+# else
+# define __inline__ /**/
+# endif
+# endif /* __inline__ */
+# ifndef __inline
+# if defined(__GNUC__) || defined(_MSC_VER)
+ /* gcc has __inline */
+# elif defined(__HIGHC__)
+# define __inline _Inline
+# else
+# define __inline /**/
+# endif
+# endif /* __inline */
+
+/* Support gcc's __FUNCTION__ for people using other compilers */
+#if !defined(__GNUC__) && !defined(__FUNCTION__)
+# define __FUNCTION__ __func__ /* C99 */
+#endif
+
+# if defined(NO_INLINE) || defined(DO_PROTOTYPES)
+
+# if !defined(__arm__)
+# if !defined(__sparc__) && !defined(__sparc) && !defined(__arm32__) \
+ && !(defined(__alpha__) && defined(linux)) \
+ && !(defined(__ia64__) && defined(linux)) \
+
+extern _X_EXPORT void outb(unsigned short, unsigned char);
+extern _X_EXPORT void outw(unsigned short, unsigned short);
+extern _X_EXPORT void outl(unsigned short, unsigned int);
+extern _X_EXPORT unsigned int inb(unsigned short);
+extern _X_EXPORT unsigned int inw(unsigned short);
+extern _X_EXPORT unsigned int inl(unsigned short);
+
+# else /* __sparc__, __arm32__, __alpha__*/
+
+extern _X_EXPORT void outb(unsigned long, unsigned char);
+extern _X_EXPORT void outw(unsigned long, unsigned short);
+extern _X_EXPORT void outl(unsigned long, unsigned int);
+extern _X_EXPORT unsigned int inb(unsigned long);
+extern _X_EXPORT unsigned int inw(unsigned long);
+extern _X_EXPORT unsigned int inl(unsigned long);
+
+# endif /* __sparc__, __arm32__, __alpha__ */
+# endif /* __arm__ */
+
+# if defined(__powerpc__) && !defined(__OpenBSD__)
+extern unsigned long ldq_u(unsigned long *);
+extern unsigned long ldl_u(unsigned int *);
+extern unsigned long ldw_u(unsigned short *);
+extern void stq_u(unsigned long, unsigned long *);
+extern void stl_u(unsigned long, unsigned int *);
+extern void stw_u(unsigned long, unsigned short *);
+extern void mem_barrier(void);
+extern void write_mem_barrier(void);
+extern void stl_brx(unsigned long, volatile unsigned char *, int);
+extern void stw_brx(unsigned short, volatile unsigned char *, int);
+extern unsigned long ldl_brx(volatile unsigned char *, int);
+extern unsigned short ldw_brx(volatile unsigned char *, int);
+# endif /* __powerpc__ && !__OpenBSD */
+
+# endif /* NO_INLINE || DO_PROTOTYPES */
+
+# ifndef NO_INLINE
+# ifdef __GNUC__
+# ifdef __i386__
+
+# ifdef __SSE__
+# define write_mem_barrier() __asm__ __volatile__ ("sfence" : : : "memory")
+# else
+# define write_mem_barrier() __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory")
+# endif
+
+# ifdef __SSE2__
+# define mem_barrier() __asm__ __volatile__ ("mfence" : : : "memory")
+# else
+# define mem_barrier() __asm__ __volatile__ ("lock; addl $0,0(%%esp)" : : : "memory")
+# endif
+
+# elif defined __alpha__
+
+# define mem_barrier() __asm__ __volatile__ ("mb" : : : "memory")
+# define write_mem_barrier() __asm__ __volatile__ ("wmb" : : : "memory")
+
+# elif defined __amd64__
+
+# define mem_barrier() __asm__ __volatile__ ("mfence" : : : "memory")
+# define write_mem_barrier() __asm__ __volatile__ ("sfence" : : : "memory")
+
+# elif defined __ia64__
+
+# ifndef __INTEL_COMPILER
+# define mem_barrier() __asm__ __volatile__ ("mf" : : : "memory")
+# define write_mem_barrier() __asm__ __volatile__ ("mf" : : : "memory")
+# else
+# include "ia64intrin.h"
+# define mem_barrier() __mf()
+# define write_mem_barrier() __mf()
+# endif
+
+# elif defined __mips__
+ /* Note: sync instruction requires MIPS II instruction set */
+# define mem_barrier() \
+ __asm__ __volatile__( \
+ ".set push\n\t" \
+ ".set noreorder\n\t" \
+ ".set mips2\n\t" \
+ "sync\n\t" \
+ ".set pop" \
+ : /* no output */ \
+ : /* no input */ \
+ : "memory")
+# define write_mem_barrier() mem_barrier()
+
+# elif defined __powerpc__
+
+# if defined(linux) && defined(__powerpc64__)
+# include <linux/version.h>
+# if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
+# include <asm/memory.h>
+# endif
+# endif /* defined(linux) && defined(__powerpc64__) */
+
+# ifndef eieio /* We deal with arch-specific eieio() routines above... */
+# define eieio() __asm__ __volatile__ ("eieio" ::: "memory")
+# endif /* eieio */
+# define mem_barrier() eieio()
+# define write_mem_barrier() eieio()
+
+# elif defined __sparc__
+
+# define barrier() __asm__ __volatile__ (".word 0x8143e00a" : : : "memory")
+# define mem_barrier() /* XXX: nop for now */
+# define write_mem_barrier() /* XXX: nop for now */
+# endif
+# endif /* __GNUC__ */
+# endif /* NO_INLINE */
+
+# ifndef mem_barrier
+# define mem_barrier() /* NOP */
+# endif
+
+# ifndef write_mem_barrier
+# define write_mem_barrier() /* NOP */
+# endif
+
+
+# ifndef NO_INLINE
+# ifdef __GNUC__
+
+/* Define some packed structures to use with unaligned accesses */
+
+struct __una_u64 { uint64_t x __attribute__((packed)); };
+struct __una_u32 { uint32_t x __attribute__((packed)); };
+struct __una_u16 { uint16_t x __attribute__((packed)); };
+
+/* Elemental unaligned loads */
+
+static __inline__ uint64_t ldq_u(uint64_t *p)
+{
+ const struct __una_u64 *ptr = (const struct __una_u64 *) p;
+ return ptr->x;
+}
+
+static __inline__ uint32_t ldl_u(uint32_t *p)
+{
+ const struct __una_u32 *ptr = (const struct __una_u32 *) p;
+ return ptr->x;
+}
+
+static __inline__ uint16_t ldw_u(uint16_t *p)
+{
+ const struct __una_u16 *ptr = (const struct __una_u16 *) p;
+ return ptr->x;
+}
+
+/* Elemental unaligned stores */
+
+static __inline__ void stq_u(uint64_t val, uint64_t *p)
+{
+ struct __una_u64 *ptr = (struct __una_u64 *) p;
+ ptr->x = val;
+}
+
+static __inline__ void stl_u(uint32_t val, uint32_t *p)
+{
+ struct __una_u32 *ptr = (struct __una_u32 *) p;
+ ptr->x = val;
+}
+
+static __inline__ void stw_u(uint16_t val, uint16_t *p)
+{
+ struct __una_u16 *ptr = (struct __una_u16 *) p;
+ ptr->x = val;
+}
+# else /* !__GNUC__ */
+
+#include <string.h> /* needed for memmove */
+
+static __inline__ uint64_t ldq_u(uint64_t *p)
+{
+ uint64_t ret;
+ memmove(&ret, p, sizeof(*p));
+ return ret;
+}
+
+static __inline__ uint32_t ldl_u(uint32_t *p)
+{
+ uint32_t ret;
+ memmove(&ret, p, sizeof(*p));
+ return ret;
+}
+
+static __inline__ uint16_t ldw_u(uint16_t *p)
+{
+ uint16_t ret;
+ memmove(&ret, p, sizeof(*p));
+ return ret;
+}
+
+static __inline__ void stq_u(uint64_t val, uint64_t *p)
+{
+ uint64_t tmp = val;
+ memmove(p, &tmp, sizeof(*p));
+}
+
+static __inline__ void stl_u(uint32_t val, uint32_t *p)
+{
+ uint32_t tmp = val;
+ memmove(p, &tmp, sizeof(*p));
+}
+
+static __inline__ void stw_u(uint16_t val, uint16_t *p)
+{
+ uint16_t tmp = val;
+ memmove(p, &tmp, sizeof(*p));
+}
+
+# endif /* __GNUC__ */
+# endif /* NO_INLINE */
+
+# ifndef NO_INLINE
+# ifdef __GNUC__
+# if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && (defined(__alpha__))
+
+# ifdef linux
+/* for Linux on Alpha, we use the LIBC _inx/_outx routines */
+/* note that the appropriate setup via "ioperm" needs to be done */
+/* *before* any inx/outx is done. */
+
+extern _X_EXPORT void _outb(unsigned char val, unsigned long port);
+extern _X_EXPORT void _outw(unsigned short val, unsigned long port);
+extern _X_EXPORT void _outl(unsigned int val, unsigned long port);
+extern _X_EXPORT unsigned int _inb(unsigned long port);
+extern _X_EXPORT unsigned int _inw(unsigned long port);
+extern _X_EXPORT unsigned int _inl(unsigned long port);
+
+static __inline__ void
+outb(unsigned long port, unsigned char val)
+{
+ _outb(val, port);
+}
+
+static __inline__ void
+outw(unsigned long port, unsigned short val)
+{
+ _outw(val, port);
+}
+
+static __inline__ void
+outl(unsigned long port, unsigned int val)
+{
+ _outl(val, port);
+}
+
+static __inline__ unsigned int
+inb(unsigned long port)
+{
+ return _inb(port);
+}
+
+static __inline__ unsigned int
+inw(unsigned long port)
+{
+ return _inw(port);
+}
+
+static __inline__ unsigned int
+inl(unsigned long port)
+{
+ return _inl(port);
+}
+
+# endif /* linux */
+
+# if (defined(__FreeBSD__) || defined(__OpenBSD__)) \
+ && !defined(DO_PROTOTYPES)
+
+/* for FreeBSD and OpenBSD on Alpha, we use the libio (resp. libalpha) */
+/* inx/outx routines */
+/* note that the appropriate setup via "ioperm" needs to be done */
+/* *before* any inx/outx is done. */
+
+extern _X_EXPORT void outb(unsigned int port, unsigned char val);
+extern _X_EXPORT void outw(unsigned int port, unsigned short val);
+extern _X_EXPORT void outl(unsigned int port, unsigned int val);
+extern _X_EXPORT unsigned char inb(unsigned int port);
+extern _X_EXPORT unsigned short inw(unsigned int port);
+extern _X_EXPORT unsigned int inl(unsigned int port);
+
+# endif /* (__FreeBSD__ || __OpenBSD__ ) && !DO_PROTOTYPES */
+
+
+#if defined(__NetBSD__)
+#include <machine/pio.h>
+#endif /* __NetBSD__ */
+
+# elif defined(linux) && defined(__ia64__)
+
+# include <inttypes.h>
+
+# include <sys/io.h>
+
+# undef outb
+# undef outw
+# undef outl
+# undef inb
+# undef inw
+# undef inl
+extern _X_EXPORT void outb(unsigned long port, unsigned char val);
+extern _X_EXPORT void outw(unsigned long port, unsigned short val);
+extern _X_EXPORT void outl(unsigned long port, unsigned int val);
+extern _X_EXPORT unsigned int inb(unsigned long port);
+extern _X_EXPORT unsigned int inw(unsigned long port);
+extern _X_EXPORT unsigned int inl(unsigned long port);
+
+# elif (defined(linux) || defined(__FreeBSD__)) && defined(__amd64__)
+
+# include <inttypes.h>
+
+static __inline__ void
+outb(unsigned short port, unsigned char val)
+{
+ __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port));
+}
+
+
+static __inline__ void
+outw(unsigned short port, unsigned short val)
+{
+ __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port));
+}
+
+static __inline__ void
+outl(unsigned short port, unsigned int val)
+{
+ __asm__ __volatile__("outl %0,%1" : :"a" (val), "d" (port));
+}
+
+static __inline__ unsigned int
+inb(unsigned short port)
+{
+ unsigned char ret;
+ __asm__ __volatile__("inb %1,%0" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inw(unsigned short port)
+{
+ unsigned short ret;
+ __asm__ __volatile__("inw %1,%0" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inl(unsigned short port)
+{
+ unsigned int ret;
+ __asm__ __volatile__("inl %1,%0" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+# elif (defined(linux) || defined(sun) || defined(__OpenBSD__) || defined(__FreeBSD__)) && defined(__sparc__)
+
+# ifndef ASI_PL
+# define ASI_PL 0x88
+# endif
+
+static __inline__ void
+outb(unsigned long port, unsigned char val)
+{
+ __asm__ __volatile__("stba %0, [%1] %2"
+ : /* No outputs */
+ : "r" (val), "r" (port), "i" (ASI_PL));
+ barrier();
+}
+
+static __inline__ void
+outw(unsigned long port, unsigned short val)
+{
+ __asm__ __volatile__("stha %0, [%1] %2"
+ : /* No outputs */
+ : "r" (val), "r" (port), "i" (ASI_PL));
+ barrier();
+}
+
+static __inline__ void
+outl(unsigned long port, unsigned int val)
+{
+ __asm__ __volatile__("sta %0, [%1] %2"
+ : /* No outputs */
+ : "r" (val), "r" (port), "i" (ASI_PL));
+ barrier();
+}
+
+static __inline__ unsigned int
+inb(unsigned long port)
+{
+ unsigned int ret;
+ __asm__ __volatile__("lduba [%1] %2, %0"
+ : "=r" (ret)
+ : "r" (port), "i" (ASI_PL));
+ return ret;
+}
+
+static __inline__ unsigned int
+inw(unsigned long port)
+{
+ unsigned int ret;
+ __asm__ __volatile__("lduha [%1] %2, %0"
+ : "=r" (ret)
+ : "r" (port), "i" (ASI_PL));
+ return ret;
+}
+
+static __inline__ unsigned int
+inl(unsigned long port)
+{
+ unsigned int ret;
+ __asm__ __volatile__("lda [%1] %2, %0"
+ : "=r" (ret)
+ : "r" (port), "i" (ASI_PL));
+ return ret;
+}
+
+static __inline__ unsigned char
+xf86ReadMmio8(__volatile__ void *base, const unsigned long offset)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+ unsigned char ret;
+
+ __asm__ __volatile__("lduba [%1] %2, %0"
+ : "=r" (ret)
+ : "r" (addr), "i" (ASI_PL));
+ return ret;
+}
+
+static __inline__ unsigned short
+xf86ReadMmio16Be(__volatile__ void *base, const unsigned long offset)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+ unsigned short ret;
+
+ __asm__ __volatile__("lduh [%1], %0"
+ : "=r" (ret)
+ : "r" (addr));
+ return ret;
+}
+
+static __inline__ unsigned short
+xf86ReadMmio16Le(__volatile__ void *base, const unsigned long offset)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+ unsigned short ret;
+
+ __asm__ __volatile__("lduha [%1] %2, %0"
+ : "=r" (ret)
+ : "r" (addr), "i" (ASI_PL));
+ return ret;
+}
+
+static __inline__ unsigned int
+xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+ unsigned int ret;
+
+ __asm__ __volatile__("ld [%1], %0"
+ : "=r" (ret)
+ : "r" (addr));
+ return ret;
+}
+
+static __inline__ unsigned int
+xf86ReadMmio32Le(__volatile__ void *base, const unsigned long offset)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+ unsigned int ret;
+
+ __asm__ __volatile__("lda [%1] %2, %0"
+ : "=r" (ret)
+ : "r" (addr), "i" (ASI_PL));
+ return ret;
+}
+
+static __inline__ void
+xf86WriteMmio8(__volatile__ void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("stba %0, [%1] %2"
+ : /* No outputs */
+ : "r" (val), "r" (addr), "i" (ASI_PL));
+ barrier();
+}
+
+static __inline__ void
+xf86WriteMmio16Be(__volatile__ void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("sth %0, [%1]"
+ : /* No outputs */
+ : "r" (val), "r" (addr));
+ barrier();
+}
+
+static __inline__ void
+xf86WriteMmio16Le(__volatile__ void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("stha %0, [%1] %2"
+ : /* No outputs */
+ : "r" (val), "r" (addr), "i" (ASI_PL));
+ barrier();
+}
+
+static __inline__ void
+xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("st %0, [%1]"
+ : /* No outputs */
+ : "r" (val), "r" (addr));
+ barrier();
+}
+
+static __inline__ void
+xf86WriteMmio32Le(__volatile__ void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("sta %0, [%1] %2"
+ : /* No outputs */
+ : "r" (val), "r" (addr), "i" (ASI_PL));
+ barrier();
+}
+
+static __inline__ void
+xf86WriteMmio8NB(__volatile__ void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("stba %0, [%1] %2"
+ : /* No outputs */
+ : "r" (val), "r" (addr), "i" (ASI_PL));
+}
+
+static __inline__ void
+xf86WriteMmio16BeNB(__volatile__ void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("sth %0, [%1]"
+ : /* No outputs */
+ : "r" (val), "r" (addr));
+}
+
+static __inline__ void
+xf86WriteMmio16LeNB(__volatile__ void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("stha %0, [%1] %2"
+ : /* No outputs */
+ : "r" (val), "r" (addr), "i" (ASI_PL));
+}
+
+static __inline__ void
+xf86WriteMmio32BeNB(__volatile__ void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("st %0, [%1]"
+ : /* No outputs */
+ : "r" (val), "r" (addr));
+}
+
+static __inline__ void
+xf86WriteMmio32LeNB(__volatile__ void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("sta %0, [%1] %2"
+ : /* No outputs */
+ : "r" (val), "r" (addr), "i" (ASI_PL));
+}
+
+# elif defined(__mips__) || (defined(__arm32__) && !defined(__linux__))
+# ifdef __arm32__
+# define PORT_SIZE long
+# else
+# define PORT_SIZE short
+# endif
+
+_X_EXPORT unsigned int IOPortBase; /* Memory mapped I/O port area */
+
+static __inline__ void
+outb(unsigned PORT_SIZE port, unsigned char val)
+{
+ *(volatile unsigned char*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val;
+}
+
+static __inline__ void
+outw(unsigned PORT_SIZE port, unsigned short val)
+{
+ *(volatile unsigned short*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val;
+}
+
+static __inline__ void
+outl(unsigned PORT_SIZE port, unsigned int val)
+{
+ *(volatile unsigned int*)(((unsigned PORT_SIZE)(port))+IOPortBase) = val;
+}
+
+static __inline__ unsigned int
+inb(unsigned PORT_SIZE port)
+{
+ return *(volatile unsigned char*)(((unsigned PORT_SIZE)(port))+IOPortBase);
+}
+
+static __inline__ unsigned int
+inw(unsigned PORT_SIZE port)
+{
+ return *(volatile unsigned short*)(((unsigned PORT_SIZE)(port))+IOPortBase);
+}
+
+static __inline__ unsigned int
+inl(unsigned PORT_SIZE port)
+{
+ return *(volatile unsigned int*)(((unsigned PORT_SIZE)(port))+IOPortBase);
+}
+
+
+# if defined(__mips__)
+# ifdef linux /* don't mess with other OSs */
+# if X_BYTE_ORDER == X_BIG_ENDIAN
+static __inline__ unsigned int
+xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+ unsigned int ret;
+
+ __asm__ __volatile__("lw %0, 0(%1)"
+ : "=r" (ret)
+ : "r" (addr));
+ return ret;
+}
+
+static __inline__ void
+xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ unsigned long addr = ((unsigned long)base) + offset;
+
+ __asm__ __volatile__("sw %0, 0(%1)"
+ : /* No outputs */
+ : "r" (val), "r" (addr));
+}
+# endif
+# endif /* !linux */
+# endif /* __mips__ */
+
+# elif (defined(linux) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__)) && defined(__powerpc__)
+
+# ifndef MAP_FAILED
+# define MAP_FAILED ((void *)-1)
+# endif
+
+extern _X_EXPORT volatile unsigned char *ioBase;
+
+static __inline__ unsigned char
+xf86ReadMmio8(__volatile__ void *base, const unsigned long offset)
+{
+ register unsigned char val;
+ __asm__ __volatile__(
+ "lbzx %0,%1,%2\n\t"
+ "eieio"
+ : "=r" (val)
+ : "b" (base), "r" (offset),
+ "m" (*((volatile unsigned char *)base+offset)));
+ return val;
+}
+
+static __inline__ unsigned short
+xf86ReadMmio16Be(__volatile__ void *base, const unsigned long offset)
+{
+ register unsigned short val;
+ __asm__ __volatile__(
+ "lhzx %0,%1,%2\n\t"
+ "eieio"
+ : "=r" (val)
+ : "b" (base), "r" (offset),
+ "m" (*((volatile unsigned char *)base+offset)));
+ return val;
+}
+
+static __inline__ unsigned short
+xf86ReadMmio16Le(__volatile__ void *base, const unsigned long offset)
+{
+ register unsigned short val;
+ __asm__ __volatile__(
+ "lhbrx %0,%1,%2\n\t"
+ "eieio"
+ : "=r" (val)
+ : "b" (base), "r" (offset),
+ "m" (*((volatile unsigned char *)base+offset)));
+ return val;
+}
+
+static __inline__ unsigned int
+xf86ReadMmio32Be(__volatile__ void *base, const unsigned long offset)
+{
+ register unsigned int val;
+ __asm__ __volatile__(
+ "lwzx %0,%1,%2\n\t"
+ "eieio"
+ : "=r" (val)
+ : "b" (base), "r" (offset),
+ "m" (*((volatile unsigned char *)base+offset)));
+ return val;
+}
+
+static __inline__ unsigned int
+xf86ReadMmio32Le(__volatile__ void *base, const unsigned long offset)
+{
+ register unsigned int val;
+ __asm__ __volatile__(
+ "lwbrx %0,%1,%2\n\t"
+ "eieio"
+ : "=r" (val)
+ : "b" (base), "r" (offset),
+ "m" (*((volatile unsigned char *)base+offset)));
+ return val;
+}
+
+static __inline__ void
+xf86WriteMmioNB8(__volatile__ void *base, const unsigned long offset,
+ const unsigned char val)
+{
+ __asm__ __volatile__(
+ "stbx %1,%2,%3\n\t"
+ : "=m" (*((volatile unsigned char *)base+offset))
+ : "r" (val), "b" (base), "r" (offset));
+}
+
+static __inline__ void
+xf86WriteMmioNB16Le(__volatile__ void *base, const unsigned long offset,
+ const unsigned short val)
+{
+ __asm__ __volatile__(
+ "sthbrx %1,%2,%3\n\t"
+ : "=m" (*((volatile unsigned char *)base+offset))
+ : "r" (val), "b" (base), "r" (offset));
+}
+
+static __inline__ void
+xf86WriteMmioNB16Be(__volatile__ void *base, const unsigned long offset,
+ const unsigned short val)
+{
+ __asm__ __volatile__(
+ "sthx %1,%2,%3\n\t"
+ : "=m" (*((volatile unsigned char *)base+offset))
+ : "r" (val), "b" (base), "r" (offset));
+}
+
+static __inline__ void
+xf86WriteMmioNB32Le(__volatile__ void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ __asm__ __volatile__(
+ "stwbrx %1,%2,%3\n\t"
+ : "=m" (*((volatile unsigned char *)base+offset))
+ : "r" (val), "b" (base), "r" (offset));
+}
+
+static __inline__ void
+xf86WriteMmioNB32Be(__volatile__ void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ __asm__ __volatile__(
+ "stwx %1,%2,%3\n\t"
+ : "=m" (*((volatile unsigned char *)base+offset))
+ : "r" (val), "b" (base), "r" (offset));
+}
+
+static __inline__ void
+xf86WriteMmio8(__volatile__ void *base, const unsigned long offset,
+ const unsigned char val)
+{
+ xf86WriteMmioNB8(base, offset, val);
+ eieio();
+}
+
+static __inline__ void
+xf86WriteMmio16Le(__volatile__ void *base, const unsigned long offset,
+ const unsigned short val)
+{
+ xf86WriteMmioNB16Le(base, offset, val);
+ eieio();
+}
+
+static __inline__ void
+xf86WriteMmio16Be(__volatile__ void *base, const unsigned long offset,
+ const unsigned short val)
+{
+ xf86WriteMmioNB16Be(base, offset, val);
+ eieio();
+}
+
+static __inline__ void
+xf86WriteMmio32Le(__volatile__ void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ xf86WriteMmioNB32Le(base, offset, val);
+ eieio();
+}
+
+static __inline__ void
+xf86WriteMmio32Be(__volatile__ void *base, const unsigned long offset,
+ const unsigned int val)
+{
+ xf86WriteMmioNB32Be(base, offset, val);
+ eieio();
+}
+
+
+static __inline__ void
+outb(unsigned short port, unsigned char value)
+{
+ if(ioBase == MAP_FAILED) return;
+ xf86WriteMmio8((void *)ioBase, port, value);
+}
+
+static __inline__ void
+outw(unsigned short port, unsigned short value)
+{
+ if(ioBase == MAP_FAILED) return;
+ xf86WriteMmio16Le((void *)ioBase, port, value);
+}
+
+static __inline__ void
+outl(unsigned short port, unsigned int value)
+{
+ if(ioBase == MAP_FAILED) return;
+ xf86WriteMmio32Le((void *)ioBase, port, value);
+}
+
+static __inline__ unsigned int
+inb(unsigned short port)
+{
+ if(ioBase == MAP_FAILED) return 0;
+ return xf86ReadMmio8((void *)ioBase, port);
+}
+
+static __inline__ unsigned int
+inw(unsigned short port)
+{
+ if(ioBase == MAP_FAILED) return 0;
+ return xf86ReadMmio16Le((void *)ioBase, port);
+}
+
+static __inline__ unsigned int
+inl(unsigned short port)
+{
+ if(ioBase == MAP_FAILED) return 0;
+ return xf86ReadMmio32Le((void *)ioBase, port);
+}
+
+#elif defined(__arm__) && defined(__linux__)
+
+/* for Linux on ARM, we use the LIBC inx/outx routines */
+/* note that the appropriate setup via "ioperm" needs to be done */
+/* *before* any inx/outx is done. */
+
+#include <sys/io.h>
+
+static __inline__ void
+xf_outb(unsigned short port, unsigned char val)
+{
+ outb(val, port);
+}
+
+static __inline__ void
+xf_outw(unsigned short port, unsigned short val)
+{
+ outw(val, port);
+}
+
+static __inline__ void
+xf_outl(unsigned short port, unsigned int val)
+{
+ outl(val, port);
+}
+
+#define outb xf_outb
+#define outw xf_outw
+#define outl xf_outl
+
+# else /* ix86 */
+
+# if !defined(__SUNPRO_C)
+# if !defined(FAKEIT) && !defined(__mc68000__) && !defined(__arm__) && !defined(__sh__) && !defined(__hppa__) && !defined(__s390__) && !defined(__m32r__)
+# ifdef GCCUSESGAS
+
+/*
+ * If gcc uses gas rather than the native assembler, the syntax of these
+ * inlines has to be different. DHD
+ */
+
+static __inline__ void
+outb(unsigned short port, unsigned char val)
+{
+ __asm__ __volatile__("outb %0,%1" : :"a" (val), "d" (port));
+}
+
+
+static __inline__ void
+outw(unsigned short port, unsigned short val)
+{
+ __asm__ __volatile__("outw %0,%1" : :"a" (val), "d" (port));
+}
+
+static __inline__ void
+outl(unsigned short port, unsigned int val)
+{
+ __asm__ __volatile__("outl %0,%1" : :"a" (val), "d" (port));
+}
+
+static __inline__ unsigned int
+inb(unsigned short port)
+{
+ unsigned char ret;
+ __asm__ __volatile__("inb %1,%0" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inw(unsigned short port)
+{
+ unsigned short ret;
+ __asm__ __volatile__("inw %1,%0" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inl(unsigned short port)
+{
+ unsigned int ret;
+ __asm__ __volatile__("inl %1,%0" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+# else /* GCCUSESGAS */
+
+static __inline__ void
+outb(unsigned short port, unsigned char val)
+{
+ __asm__ __volatile__("out%B0 (%1)" : :"a" (val), "d" (port));
+}
+
+static __inline__ void
+outw(unsigned short port, unsigned short val)
+{
+ __asm__ __volatile__("out%W0 (%1)" : :"a" (val), "d" (port));
+}
+
+static __inline__ void
+outl(unsigned short port, unsigned int val)
+{
+ __asm__ __volatile__("out%L0 (%1)" : :"a" (val), "d" (port));
+}
+
+static __inline__ unsigned int
+inb(unsigned short port)
+{
+ unsigned char ret;
+ __asm__ __volatile__("in%B0 (%1)" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inw(unsigned short port)
+{
+ unsigned short ret;
+ __asm__ __volatile__("in%W0 (%1)" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+static __inline__ unsigned int
+inl(unsigned short port)
+{
+ unsigned int ret;
+ __asm__ __volatile__("in%L0 (%1)" :
+ "=a" (ret) :
+ "d" (port));
+ return ret;
+}
+
+# endif /* GCCUSESGAS */
+
+# else /* !defined(FAKEIT) && !defined(__mc68000__) && !defined(__arm__) && !defined(__sh__) && !defined(__hppa__) && !defined(__m32r__) */
+
+static __inline__ void
+outb(unsigned short port, unsigned char val)
+{
+}
+
+static __inline__ void
+outw(unsigned short port, unsigned short val)
+{
+}
+
+static __inline__ void
+outl(unsigned short port, unsigned int val)
+{
+}
+
+static __inline__ unsigned int
+inb(unsigned short port)
+{
+ return 0;
+}
+
+static __inline__ unsigned int
+inw(unsigned short port)
+{
+ return 0;
+}
+
+static __inline__ unsigned int
+inl(unsigned short port)
+{
+ return 0;
+}
+
+# endif /* FAKEIT */
+# endif /* __SUNPRO_C */
+
+# endif /* ix86 */
+
+# else /* !GNUC */
+# if defined(__STDC__) && (__STDC__ == 1)
+# ifndef asm
+# define asm __asm
+# endif
+# endif
+# ifndef SCO325
+# if defined(__UNIXWARE__)
+# /* avoid including <sys/types.h> for <sys/inline.h> on UnixWare */
+# define ushort unsigned short
+# define ushort_t unsigned short
+# define ulong unsigned long
+# define ulong_t unsigned long
+# define uint_t unsigned int
+# define uchar_t unsigned char
+# endif /* __UNIXWARE__ */
+# if !defined(__SUNPRO_C) && !defined(_MSC_VER)
+# include <sys/inline.h>
+# endif
+# else
+# include "scoasm.h"
+# endif
+# if (!defined(__HIGHC__) && !defined(__SUNPRO_C) && !defined(_MSC_VER)) || \
+ defined(__USLC__)
+# pragma asm partial_optimization outl
+# pragma asm partial_optimization outw
+# pragma asm partial_optimization outb
+# pragma asm partial_optimization inl
+# pragma asm partial_optimization inw
+# pragma asm partial_optimization inb
+# endif
+# endif /* __GNUC__ */
+
+# endif /* NO_INLINE */
+
+# ifdef __alpha__
+/* entry points for Mmio memory access routines */
+extern _X_EXPORT int (*xf86ReadMmio8)(void *, unsigned long);
+extern _X_EXPORT int (*xf86ReadMmio16)(void *, unsigned long);
+# ifndef STANDALONE_MMIO
+extern _X_EXPORT int (*xf86ReadMmio32)(void *, unsigned long);
+# else
+/* Some DRI 3D drivers need MMIO_IN32. */
+static __inline__ int
+xf86ReadMmio32(void *Base, unsigned long Offset)
+{
+ mem_barrier();
+ return *(volatile unsigned int*)((unsigned long)Base+(Offset));
+}
+# endif
+extern _X_EXPORT void (*xf86WriteMmio8)(int, void *, unsigned long);
+extern _X_EXPORT void (*xf86WriteMmio16)(int, void *, unsigned long);
+extern _X_EXPORT void (*xf86WriteMmio32)(int, void *, unsigned long);
+extern _X_EXPORT void (*xf86WriteMmioNB8)(int, void *, unsigned long);
+extern _X_EXPORT void (*xf86WriteMmioNB16)(int, void *, unsigned long);
+extern _X_EXPORT void (*xf86WriteMmioNB32)(int, void *, unsigned long);
+extern _X_EXPORT void xf86SlowBCopyFromBus(unsigned char *, unsigned char *, int);
+extern _X_EXPORT void xf86SlowBCopyToBus(unsigned char *, unsigned char *, int);
+
+/* Some macros to hide the system dependencies for MMIO accesses */
+/* Changed to kill noise generated by gcc's -Wcast-align */
+# define MMIO_IN8(base, offset) (*xf86ReadMmio8)(base, offset)
+# define MMIO_IN16(base, offset) (*xf86ReadMmio16)(base, offset)
+# ifndef STANDALONE_MMIO
+# define MMIO_IN32(base, offset) (*xf86ReadMmio32)(base, offset)
+# else
+# define MMIO_IN32(base, offset) xf86ReadMmio32(base, offset)
+# endif
+
+# define MMIO_OUT32(base, offset, val) \
+ do { \
+ write_mem_barrier(); \
+ *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val); \
+ } while (0)
+# define MMIO_ONB32(base, offset, val) \
+ *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val)
+
+# define MMIO_OUT8(base, offset, val) \
+ (*xf86WriteMmio8)((CARD8)(val), base, offset)
+# define MMIO_OUT16(base, offset, val) \
+ (*xf86WriteMmio16)((CARD16)(val), base, offset)
+# define MMIO_ONB8(base, offset, val) \
+ (*xf86WriteMmioNB8)((CARD8)(val), base, offset)
+# define MMIO_ONB16(base, offset, val) \
+ (*xf86WriteMmioNB16)((CARD16)(val), base, offset)
+# define MMIO_MOVE32(base, offset, val) \
+ MMIO_OUT32(base, offset, val)
+
+# elif defined(__powerpc__)
+ /*
+ * we provide byteswapping and no byteswapping functions here
+ * with byteswapping as default,
+ * drivers that don't need byteswapping should define PPC_MMIO_IS_BE
+ */
+# define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset)
+# define MMIO_OUT8(base, offset, val) \
+ xf86WriteMmio8(base, offset, (CARD8)(val))
+# define MMIO_ONB8(base, offset, val) \
+ xf86WriteMmioNB8(base, offset, (CARD8)(val))
+
+# if defined(PPC_MMIO_IS_BE) /* No byteswapping */
+# define MMIO_IN16(base, offset) xf86ReadMmio16Be(base, offset)
+# define MMIO_IN32(base, offset) xf86ReadMmio32Be(base, offset)
+# define MMIO_OUT16(base, offset, val) \
+ xf86WriteMmio16Be(base, offset, (CARD16)(val))
+# define MMIO_OUT32(base, offset, val) \
+ xf86WriteMmio32Be(base, offset, (CARD32)(val))
+# define MMIO_ONB16(base, offset, val) \
+ xf86WriteMmioNB16Be(base, offset, (CARD16)(val))
+# define MMIO_ONB32(base, offset, val) \
+ xf86WriteMmioNB32Be(base, offset, (CARD32)(val))
+# else /* byteswapping is the default */
+# define MMIO_IN16(base, offset) xf86ReadMmio16Le(base, offset)
+# define MMIO_IN32(base, offset) xf86ReadMmio32Le(base, offset)
+# define MMIO_OUT16(base, offset, val) \
+ xf86WriteMmio16Le(base, offset, (CARD16)(val))
+# define MMIO_OUT32(base, offset, val) \
+ xf86WriteMmio32Le(base, offset, (CARD32)(val))
+# define MMIO_ONB16(base, offset, val) \
+ xf86WriteMmioNB16Le(base, offset, (CARD16)(val))
+# define MMIO_ONB32(base, offset, val) \
+ xf86WriteMmioNB32Le(base, offset, (CARD32)(val))
+# endif
+
+# define MMIO_MOVE32(base, offset, val) \
+ xf86WriteMmio32Be(base, offset, (CARD32)(val))
+
+# elif defined(__sparc__) || defined(sparc) || defined(__sparc)
+ /*
+ * Like powerpc, we provide byteswapping and no byteswapping functions
+ * here with byteswapping as default, drivers that don't need byteswapping
+ * should define SPARC_MMIO_IS_BE (perhaps create a generic macro so that we
+ * do not need to use PPC_MMIO_IS_BE and the sparc one in all the same places
+ * of drivers?).
+ */
+# define MMIO_IN8(base, offset) xf86ReadMmio8(base, offset)
+# define MMIO_OUT8(base, offset, val) \
+ xf86WriteMmio8(base, offset, (CARD8)(val))
+# define MMIO_ONB8(base, offset, val) \
+ xf86WriteMmio8NB(base, offset, (CARD8)(val))
+
+# if defined(SPARC_MMIO_IS_BE) /* No byteswapping */
+# define MMIO_IN16(base, offset) xf86ReadMmio16Be(base, offset)
+# define MMIO_IN32(base, offset) xf86ReadMmio32Be(base, offset)
+# define MMIO_OUT16(base, offset, val) \
+ xf86WriteMmio16Be(base, offset, (CARD16)(val))
+# define MMIO_OUT32(base, offset, val) \
+ xf86WriteMmio32Be(base, offset, (CARD32)(val))
+# define MMIO_ONB16(base, offset, val) \
+ xf86WriteMmio16BeNB(base, offset, (CARD16)(val))
+# define MMIO_ONB32(base, offset, val) \
+ xf86WriteMmio32BeNB(base, offset, (CARD32)(val))
+# else /* byteswapping is the default */
+# define MMIO_IN16(base, offset) xf86ReadMmio16Le(base, offset)
+# define MMIO_IN32(base, offset) xf86ReadMmio32Le(base, offset)
+# define MMIO_OUT16(base, offset, val) \
+ xf86WriteMmio16Le(base, offset, (CARD16)(val))
+# define MMIO_OUT32(base, offset, val) \
+ xf86WriteMmio32Le(base, offset, (CARD32)(val))
+# define MMIO_ONB16(base, offset, val) \
+ xf86WriteMmio16LeNB(base, offset, (CARD16)(val))
+# define MMIO_ONB32(base, offset, val) \
+ xf86WriteMmio32LeNB(base, offset, (CARD32)(val))
+# endif
+
+# define MMIO_MOVE32(base, offset, val) \
+ xf86WriteMmio32Be(base, offset, (CARD32)(val))
+
+# else /* !__alpha__ && !__powerpc__ && !__sparc__ */
+
+# define MMIO_IN8(base, offset) \
+ *(volatile CARD8 *)(((CARD8*)(base)) + (offset))
+# define MMIO_IN16(base, offset) \
+ *(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset))
+# define MMIO_IN32(base, offset) \
+ *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset))
+# define MMIO_OUT8(base, offset, val) \
+ *(volatile CARD8 *)(((CARD8*)(base)) + (offset)) = (val)
+# define MMIO_OUT16(base, offset, val) \
+ *(volatile CARD16 *)(void *)(((CARD8*)(base)) + (offset)) = (val)
+# define MMIO_OUT32(base, offset, val) \
+ *(volatile CARD32 *)(void *)(((CARD8*)(base)) + (offset)) = (val)
+# define MMIO_ONB8(base, offset, val) MMIO_OUT8(base, offset, val)
+# define MMIO_ONB16(base, offset, val) MMIO_OUT16(base, offset, val)
+# define MMIO_ONB32(base, offset, val) MMIO_OUT32(base, offset, val)
+
+# define MMIO_MOVE32(base, offset, val) MMIO_OUT32(base, offset, val)
+
+# endif /* __alpha__ */
+
+/*
+ * With Intel, the version in os-support/misc/SlowBcopy.s is used.
+ * This avoids port I/O during the copy (which causes problems with
+ * some hardware).
+ */
+# ifdef __alpha__
+# define slowbcopy_tobus(src,dst,count) xf86SlowBCopyToBus(src,dst,count)
+# define slowbcopy_frombus(src,dst,count) xf86SlowBCopyFromBus(src,dst,count)
+# else /* __alpha__ */
+# define slowbcopy_tobus(src,dst,count) xf86SlowBcopy(src,dst,count)
+# define slowbcopy_frombus(src,dst,count) xf86SlowBcopy(src,dst,count)
+# endif /* __alpha__ */
+
+#endif /* _COMPILER_H */
diff --git a/xorg-server/hw/xwin/InitInput.c b/xorg-server/hw/xwin/InitInput.c index 705e618de..7d886a9fc 100644 --- a/xorg-server/hw/xwin/InitInput.c +++ b/xorg-server/hw/xwin/InitInput.c @@ -32,7 +32,7 @@ #include "win.h" #include "dixstruct.h" #include "inputstr.h" - +#include <unistd.h> /* * Local function prototypes @@ -91,15 +91,7 @@ LegalModifier (unsigned int uiKey, DeviceIntPtr pDevice) void ProcessInputEvents (void) { -#if 0 - ErrorF ("ProcessInputEvents\n"); -#endif - mieqProcessInputEvents (); - -#if 0 - ErrorF ("ProcessInputEvents - returning\n"); -#endif } @@ -114,9 +106,7 @@ void DDXRingBell(int volume, int pitch, int duration) void InitInput (int argc, char *argv[]) { -#if CYGDEBUG winDebug ("InitInput\n"); -#endif #ifdef XWIN_CLIPBOARD /* @@ -167,12 +157,12 @@ InitInput (int argc, char *argv[]) } #endif -#if CYGDEBUG winDebug ("InitInput - returning\n"); -#endif } void CloseInput (void) { + g_pwinPointer=NULL; + g_pwinKeyboard=NULL; } diff --git a/xorg-server/hw/xwin/InitOutput.c b/xorg-server/hw/xwin/InitOutput.c index acb7d4ab2..8520e2375 100644 --- a/xorg-server/hw/xwin/InitOutput.c +++ b/xorg-server/hw/xwin/InitOutput.c @@ -1,1139 +1,1174 @@ -/* - -Copyright 1993, 1998 The Open Group -Copyright (C) Colin Harrison 2005-2008 - -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. - -*/ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" -#include "winmsg.h" -#include "winconfig.h" -#include "winprefs.h" -#ifdef XWIN_CLIPBOARD -#include "X11/Xlocale.h" -#endif -#ifdef DPMSExtension -#include "dpmsproc.h" -#endif -#ifdef __CYGWIN__ -#include <mntent.h> -#endif -#if defined(WIN32) -#include "xkbsrv.h" -#endif -#ifdef RELOCATE_PROJECTROOT -#include <shlobj.h> -typedef HRESULT (*SHGETFOLDERPATHPROC)( - HWND hwndOwner, - int nFolder, - HANDLE hToken, - DWORD dwFlags, - LPTSTR pszPath -); -#endif - - -/* - * References to external symbols - */ - -extern int g_iNumScreens; -extern winScreenInfo g_ScreenInfo[]; -extern int g_iLastScreen; -extern char * g_pszCommandLine; -extern Bool g_fSilentFatalError; - -extern char * g_pszLogFile; -extern Bool g_fLogFileChanged; -extern int g_iLogVerbose; -Bool g_fLogInited; - -extern Bool g_fXdmcpEnabled; -extern Bool g_fAuthEnabled; -#ifdef HAS_DEVWINDOWS -extern int g_fdMessageQueue; -#endif -extern const char * g_pszQueryHost; -extern HINSTANCE g_hInstance; - -#ifdef XWIN_CLIPBOARD -extern Bool g_fUnicodeClipboard; -extern Bool g_fClipboardLaunched; -extern Bool g_fClipboardStarted; -extern pthread_t g_ptClipboardProc; -extern HWND g_hwndClipboard; -extern Bool g_fClipboard; -#endif - -extern HMODULE g_hmodDirectDraw; -extern FARPROC g_fpDirectDrawCreate; -extern FARPROC g_fpDirectDrawCreateClipper; - -extern HMODULE g_hmodCommonControls; -extern FARPROC g_fpTrackMouseEvent; -extern Bool g_fNoHelpMessageBox; -extern Bool g_fSilentDupError; - - -/* - * Function prototypes - */ - -#ifdef XWIN_CLIPBOARD -static void -winClipboardShutdown (void); -#endif - -#if defined(DDXOSVERRORF) -void -OsVendorVErrorF (const char *pszFormat, va_list va_args); -#endif - -void -winInitializeDefaultScreens (void); - -static Bool -winCheckDisplayNumber (void); - -void -winLogCommandLine (int argc, char *argv[]); - -void -winLogVersionInfo (void); - -Bool -winValidateArgs (void); - -#ifdef RELOCATE_PROJECTROOT -const char * -winGetBaseDir(void); -#endif - -/* - * For the depth 24 pixmap we default to 32 bits per pixel, but - * we change this pixmap format later if we detect that the display - * is going to be running at 24 bits per pixel. - * - * FIXME: On second thought, don't DIBs only support 32 bits per pixel? - * DIBs are the underlying bitmap used for DirectDraw surfaces, so it - * seems that all pixmap formats with depth 24 would be 32 bits per pixel. - * Confirm whether depth 24 DIBs can have 24 bits per pixel, then remove/keep - * the bits per pixel adjustment and update this comment to reflect the - * situation. Harold Hunt - 2002/07/02 - */ - -static PixmapFormatRec g_PixmapFormats[] = { - { 1, 1, BITMAP_SCANLINE_PAD }, - { 4, 8, BITMAP_SCANLINE_PAD }, - { 8, 8, BITMAP_SCANLINE_PAD }, - { 15, 16, BITMAP_SCANLINE_PAD }, - { 16, 16, BITMAP_SCANLINE_PAD }, - { 24, 32, BITMAP_SCANLINE_PAD }, -#ifdef RENDER - { 32, 32, BITMAP_SCANLINE_PAD } -#endif -}; - -const int NUMFORMATS = sizeof (g_PixmapFormats) / sizeof (g_PixmapFormats[0]); - -#ifdef XWIN_CLIPBOARD -static void -winClipboardShutdown (void) -{ - /* Close down clipboard resources */ - if (g_fClipboard && g_fClipboardLaunched && g_fClipboardStarted) - { - /* Synchronously destroy the clipboard window */ - if (g_hwndClipboard != NULL) - { - SendMessage (g_hwndClipboard, WM_DESTROY, 0, 0); - /* NOTE: g_hwndClipboard is set to NULL in winclipboardthread.c */ - } - else - return; - - /* Wait for the clipboard thread to exit */ - pthread_join (g_ptClipboardProc, NULL); - - g_fClipboardLaunched = FALSE; - g_fClipboardStarted = FALSE; - - winDebug ("winClipboardShutdown - Clipboard thread has exited.\n"); - } -} -#endif - - -#if defined(DDXBEFORERESET) -/* - * Called right before KillAllClients when the server is going to reset, - * allows us to shutdown our seperate threads cleanly. - */ - -void -ddxBeforeReset (void) -{ - winDebug ("ddxBeforeReset - Hello\n"); - -#ifdef XWIN_CLIPBOARD - winClipboardShutdown (); -#endif -} -#endif - - -/* See Porting Layer Definition - p. 57 */ -void -ddxGiveUp (void) -{ - int i; - -#if CYGDEBUG - winDebug ("ddxGiveUp\n"); -#endif - - /* Perform per-screen deinitialization */ - for (i = 0; i < g_iNumScreens; ++i) - { - /* Delete the tray icon */ - if (!g_ScreenInfo[i].fNoTrayIcon && g_ScreenInfo[i].pScreen) - winDeleteNotifyIcon (winGetScreenPriv (g_ScreenInfo[i].pScreen)); - } - -#ifdef XWIN_MULTIWINDOW - /* Notify the worker threads we're exiting */ - winDeinitMultiWindowWM (); -#endif - -#ifdef HAS_DEVWINDOWS - /* Close our handle to our message queue */ - if (g_fdMessageQueue != WIN_FD_INVALID) - { - /* Close /dev/windows */ - close (g_fdMessageQueue); - - /* Set the file handle to invalid */ - g_fdMessageQueue = WIN_FD_INVALID; - } -#endif - - if (!g_fLogInited) { - LogInit (g_pszLogFile, NULL); - g_fLogInited = TRUE; - } - LogClose (); - - /* - * At this point we aren't creating any new screens, so - * we are guaranteed to not need the DirectDraw functions. - */ - if (g_hmodDirectDraw != NULL) - { - FreeLibrary (g_hmodDirectDraw); - g_hmodDirectDraw = NULL; - g_fpDirectDrawCreate = NULL; - g_fpDirectDrawCreateClipper = NULL; - } - - /* Unload our TrackMouseEvent funtion pointer */ - if (g_hmodCommonControls != NULL) - { - FreeLibrary (g_hmodCommonControls); - g_hmodCommonControls = NULL; - g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA; - } - - /* Free concatenated command line */ - if (g_pszCommandLine) - { - free (g_pszCommandLine); - g_pszCommandLine = NULL; - } - - /* Remove our keyboard hook if it is installed */ - winRemoveKeyboardHookLL (); - - /* Tell Windows that we want to end the app */ - PostQuitMessage (0); -} - - -/* See Porting Layer Definition - p. 57 */ -void -AbortDDX (void) -{ -#if CYGDEBUG - winDebug ("AbortDDX\n"); -#endif - ddxGiveUp (); -} - -#ifdef __CYGWIN__ -/* hasmntopt is currently not implemented for cygwin */ -static const char *winCheckMntOpt(const struct mntent *mnt, const char *opt) -{ - const char *s; - size_t len; - if (mnt == NULL) - return NULL; - if (opt == NULL) - return NULL; - if (mnt->mnt_opts == NULL) - return NULL; - - len = strlen(opt); - s = strstr(mnt->mnt_opts, opt); - if (s == NULL) - return NULL; - if ((s == mnt->mnt_opts || *(s-1) == ',') && (s[len] == 0 || s[len] == ',')) - return (char *)opt; - return NULL; -} - -static void -winCheckMount(void) -{ - FILE *mnt; - struct mntent *ent; - - enum { none = 0, sys_root, user_root, sys_tmp, user_tmp } - level = none, curlevel; - BOOL binary = TRUE; - - mnt = setmntent("/etc/mtab", "r"); - if (mnt == NULL) - { - ErrorF("setmntent failed"); - return; - } - - while ((ent = getmntent(mnt)) != NULL) - { - BOOL system = (winCheckMntOpt(ent, "user") != NULL); - BOOL root = (strcmp(ent->mnt_dir, "/") == 0); - BOOL tmp = (strcmp(ent->mnt_dir, "/tmp") == 0); - - if (system) - { - if (root) - curlevel = sys_root; - else if (tmp) - curlevel = sys_tmp; - else - continue; - } - else - { - if (root) - curlevel = user_root; - else if (tmp) - curlevel = user_tmp; - else - continue; - } - - if (curlevel <= level) - continue; - level = curlevel; - - if ((winCheckMntOpt(ent, "binary") == NULL) || - (winCheckMntOpt(ent, "binmode") == NULL)) - binary = 0; - else - binary = 1; - } - - if (endmntent(mnt) != 1) - { - ErrorF("endmntent failed"); - return; - } - - if (!binary) - winMsg(X_WARNING, "/tmp mounted in textmode\n"); -} -#else -static void -winCheckMount(void) -{ -} -#endif - -#ifdef RELOCATE_PROJECTROOT -const char * -winGetBaseDir(void) -{ - static BOOL inited = FALSE; - static char buffer[MAX_PATH]; - if (!inited) - { - char *fendptr; - HMODULE module = GetModuleHandle(NULL); - DWORD size = GetModuleFileName(module, buffer, sizeof(buffer)); - if (sizeof(buffer) > 0) - buffer[sizeof(buffer)-1] = 0; - - fendptr = buffer + size; - while (fendptr > buffer) - { - if (*fendptr == '\\' || *fendptr == '/') - { - *fendptr = 0; - break; - } - fendptr--; - } - inited = TRUE; - } - return buffer; -} -#endif - -static void -winFixupPaths (void) -{ - BOOL changed_fontpath = FALSE; - MessageType font_from = X_DEFAULT; -#ifdef RELOCATE_PROJECTROOT - const char *basedir = winGetBaseDir(); - size_t basedirlen = strlen(basedir); -#endif - -#ifdef READ_FONTDIRS - { - /* Open fontpath configuration file */ - FILE *fontdirs = fopen(ETCX11DIR "/font-dirs", "rt"); - if (fontdirs != NULL) - { - char buffer[256]; - int needs_sep = TRUE; - int comment_block = FALSE; - - /* get defautl fontpath */ - char *fontpath = xstrdup(defaultFontPath); - size_t size = strlen(fontpath); - - /* read all lines */ - while (!feof(fontdirs)) - { - size_t blen; - char *hashchar; - char *str; - int has_eol = FALSE; - - /* read one line */ - str = fgets(buffer, sizeof(buffer), fontdirs); - if (str == NULL) /* stop on error or eof */ - break; - - if (strchr(str, '\n') != NULL) - has_eol = TRUE; - - /* check if block is continued comment */ - if (comment_block) - { - /* ignore all input */ - *str = 0; - blen = 0; - if (has_eol) /* check if line ended in this block */ - comment_block = FALSE; - } - else - { - /* find comment character. ignore all trailing input */ - hashchar = strchr(str, '#'); - if (hashchar != NULL) - { - *hashchar = 0; - if (!has_eol) /* mark next block as continued comment */ - comment_block = TRUE; - } - } - - /* strip whitespaces from beginning */ - while (*str == ' ' || *str == '\t') - str++; - - /* get size, strip whitespaces from end */ - blen = strlen(str); - while (blen > 0 && (str[blen-1] == ' ' || - str[blen-1] == '\t' || str[blen-1] == '\n')) - { - str[--blen] = 0; - } - - /* still something left to add? */ - if (blen > 0) - { - size_t newsize = size + blen; - /* reserve one character more for ',' */ - if (needs_sep) - newsize++; - - /* allocate memory */ - if (fontpath == NULL) - fontpath = malloc(newsize+1); - else - fontpath = realloc(fontpath, newsize+1); - - /* add separator */ - if (needs_sep) - { - fontpath[size] = ','; - size++; - needs_sep = FALSE; - } - - /* mark next line as new entry */ - if (has_eol) - needs_sep = TRUE; - - /* add block */ - strncpy(fontpath + size, str, blen); - fontpath[newsize] = 0; - size = newsize; - } - } - - /* cleanup */ - fclose(fontdirs); - defaultFontPath = xstrdup(fontpath); - free(fontpath); - changed_fontpath = TRUE; - font_from = X_CONFIG; - } - } -#endif /* READ_FONTDIRS */ -#ifdef RELOCATE_PROJECTROOT - { - const char *libx11dir = PROJECTROOT "/lib/X11"; - size_t libx11dir_len = strlen(libx11dir); - char *newfp = NULL; - size_t newfp_len = 0; - const char *endptr, *ptr, *oldptr = defaultFontPath; - - endptr = oldptr + strlen(oldptr); - ptr = strchr(oldptr, ','); - if (ptr == NULL) - ptr = endptr; - while (ptr != NULL) - { - size_t oldfp_len = (ptr - oldptr); - size_t newsize = oldfp_len; - char *newpath = malloc(newsize + 1); - strncpy(newpath, oldptr, newsize); - newpath[newsize] = 0; - - - if (strncmp(libx11dir, newpath, libx11dir_len) == 0) - { - char *compose; - newsize = newsize - libx11dir_len + basedirlen; - compose = malloc(newsize + 1); - strcpy(compose, basedir); - strncat(compose, newpath + libx11dir_len, newsize - basedirlen); - compose[newsize] = 0; - free(newpath); - newpath = compose; - } - - oldfp_len = newfp_len; - if (oldfp_len > 0) - newfp_len ++; /* space for separator */ - newfp_len += newsize; - - if (newfp == NULL) - newfp = malloc(newfp_len + 1); - else - newfp = realloc(newfp, newfp_len + 1); - - if (oldfp_len > 0) - { - strcpy(newfp + oldfp_len, ","); - oldfp_len++; - } - strcpy(newfp + oldfp_len, newpath); - - free(newpath); - - if (*ptr == 0) - { - oldptr = ptr; - ptr = NULL; - } else - { - oldptr = ptr + 1; - ptr = strchr(oldptr, ','); - if (ptr == NULL) - ptr = endptr; - } - } - - defaultFontPath = xstrdup(newfp); - free(newfp); - changed_fontpath = TRUE; - } -#endif /* RELOCATE_PROJECTROOT */ - if (changed_fontpath) - winMsg (font_from, "FontPath set to \"%s\"\n", defaultFontPath); - -#ifdef RELOCATE_PROJECTROOT - if (getenv("XKEYSYMDB") == NULL) - { - char buffer[MAX_PATH]; - snprintf(buffer, sizeof(buffer), "XKEYSYMDB=%s\\XKeysymDB", - basedir); - buffer[sizeof(buffer)-1] = 0; - putenv(buffer); - } - if (getenv("XERRORDB") == NULL) - { - char buffer[MAX_PATH]; - snprintf(buffer, sizeof(buffer), "XERRORDB=%s\\XErrorDB", - basedir); - buffer[sizeof(buffer)-1] = 0; - putenv(buffer); - } - if (getenv("XLOCALEDIR") == NULL) - { - char buffer[MAX_PATH]; - snprintf(buffer, sizeof(buffer), "XLOCALEDIR=%s\\locale", - basedir); - buffer[sizeof(buffer)-1] = 0; - putenv(buffer); - } - if (getenv("HOME") == NULL) - { - HMODULE shfolder; - SHGETFOLDERPATHPROC shgetfolderpath = NULL; - char buffer[MAX_PATH + 5]; - strncpy(buffer, "HOME=", 5); - - /* Try to load SHGetFolderPath from shfolder.dll and shell32.dll */ - - shfolder = LoadLibrary("shfolder.dll"); - /* fallback to shell32.dll */ - if (shfolder == NULL) - shfolder = LoadLibrary("shell32.dll"); - - /* resolve SHGetFolderPath */ - if (shfolder != NULL) - shgetfolderpath = (SHGETFOLDERPATHPROC)GetProcAddress(shfolder, "SHGetFolderPathA"); - - /* query appdata directory */ - if (shgetfolderpath && - shgetfolderpath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0, - buffer + 5) == 0) - { - putenv(buffer); - } else - { - winMsg (X_ERROR, "Can not determine HOME directory\n"); - } - if (shfolder != NULL) - FreeLibrary(shfolder); - } - if (!g_fLogFileChanged) { - static char buffer[MAX_PATH]; - DWORD size = GetTempPath(sizeof(buffer), buffer); - if (size && size < sizeof(buffer)) - { - snprintf(buffer + size, sizeof(buffer) - size, - "XWin.%s.log", display); - buffer[sizeof(buffer)-1] = 0; - g_pszLogFile = buffer; - winMsg (X_DEFAULT, "Logfile set to \"%s\"\n", g_pszLogFile); - } - } - { - static char xkbbasedir[MAX_PATH]; - - snprintf(xkbbasedir, sizeof(xkbbasedir), "%s\\xkb", basedir); - if (sizeof(xkbbasedir) > 0) - xkbbasedir[sizeof(xkbbasedir)-1] = 0; - XkbBaseDirectory = xkbbasedir; - XkbBinDirectory = basedir; - } -#endif /* RELOCATE_PROJECTROOT */ -} - -void -OsVendorInit (void) -{ - /* Re-initialize global variables on server reset */ - winInitializeGlobals (); - - LogInit (NULL, NULL); - LogSetParameter (XLOG_VERBOSITY, g_iLogVerbose); - - winFixupPaths(); - -#ifdef DDXOSVERRORF - if (!OsVendorVErrorFProc) - OsVendorVErrorFProc = OsVendorVErrorF; -#endif - - if (!g_fLogInited) { - /* keep this order. If LogInit fails it calls Abort which then calls - * ddxGiveUp where LogInit is called again and creates an infinite - * recursion. If we set g_fLogInited to TRUE before the init we - * avoid the second call - */ - g_fLogInited = TRUE; - LogInit (g_pszLogFile, NULL); - } - LogSetParameter (XLOG_FLUSH, 1); - LogSetParameter (XLOG_VERBOSITY, g_iLogVerbose); - LogSetParameter (XLOG_FILE_VERBOSITY, g_iLogVerbose); - - /* Log the version information */ - if (serverGeneration == 1) - winLogVersionInfo (); - - winCheckMount(); - - /* Add a default screen if no screens were specified */ - if (g_iNumScreens == 0) - { - winDebug ("OsVendorInit - Creating bogus screen 0\n"); - - /* - * We need to initialize default screens if no arguments - * were processed. Otherwise, the default screens would - * already have been initialized by ddxProcessArgument (). - */ - winInitializeDefaultScreens (); - - /* - * Add a screen 0 using the defaults set by - * winInitializeDefaultScreens () and any additional parameters - * processed by ddxProcessArgument (). - */ - g_iNumScreens = 1; - g_iLastScreen = 0; - - /* We have to flag this as an explicit screen, even though it isn't */ - g_ScreenInfo[0].fExplicitScreen = TRUE; - } -} - - -static void -winUseMsg (void) -{ - ErrorF("\n"); - ErrorF("\n"); - ErrorF(EXECUTABLE_NAME " Device Dependent Usage:\n"); - ErrorF("\n"); - -#ifdef XWIN_CLIPBOARD - ErrorF ("-[no]clipboard\n" - "\tEnable [disable] the clipboard integration. Default is enabled.\n"); -#endif - - ErrorF ("-clipupdates num_boxes\n" - "\tUse a clipping region to constrain shadow update blits to\n" - "\tthe updated region when num_boxes, or more, are in the\n" - "\tupdated region.\n"); - -#ifdef XWIN_XF86CONFIG - ErrorF ("-config\n" - "\tSpecify a configuration file.\n"); - - ErrorF ("-configdir\n" - "\tSpecify a configuration directory.\n"); -#endif - - ErrorF ("-depth bits_per_pixel\n" - "\tSpecify an optional bitdepth to use in fullscreen mode\n" - "\twith a DirectDraw engine.\n"); - - ErrorF ("-emulate3buttons [timeout]\n" - "\tEmulate 3 button mouse with an optional timeout in\n" - "\tmilliseconds.\n"); - -#ifdef XWIN_EMULATEPSEUDO - ErrorF ("-emulatepseudo\n" - "\tCreate a depth 8 PseudoColor visual when running in\n" - "\tdepths 15, 16, 24, or 32, collectively known as TrueColor\n" - "\tdepths. The PseudoColor visual does not have correct colors,\n" - "\tand it may crash, but it at least allows you to run your\n" - "\tapplication in TrueColor modes.\n"); -#endif - - ErrorF ("-engine engine_type_id\n" - "\tOverride the server's automatically selected engine type:\n" - "\t\t1 - Shadow GDI\n" - "\t\t2 - Shadow DirectDraw\n" - "\t\t4 - Shadow DirectDraw4 Non-Locking\n" -#ifdef XWIN_NATIVEGDI - "\t\t16 - Native GDI - experimental\n" -#endif - ); - - ErrorF ("-fullscreen\n" - "\tRun the server in fullscreen mode.\n"); - - ErrorF ("-ignoreinput\n" - "\tIgnore keyboard and mouse input.\n"); - -#ifdef XWIN_MULTIWINDOWEXTWM - ErrorF ("-internalwm\n" - "\tRun the internal window manager.\n"); -#endif - -#ifdef XWIN_XF86CONFIG - ErrorF ("-keyboard\n" - "\tSpecify a keyboard device from the configuration file.\n"); -#endif - - ErrorF ("-[no]keyhook\n" - "\tGrab special Windows keypresses like Alt-Tab or the Menu " - "key.\n"); - - ErrorF ("-lesspointer\n" - "\tHide the windows mouse pointer when it is over any\n" - "\t" EXECUTABLE_NAME " window. This prevents ghost cursors appearing when\n" - "\tthe Windows cursor is drawn on top of the X cursor\n"); - - ErrorF ("-logfile filename\n" - "\tWrite log messages to <filename>.\n"); - - ErrorF ("-logverbose verbosity\n" - "\tSet the verbosity of log messages. [NOTE: Only a few messages\n" - "\trespect the settings yet]\n" - "\t\t0 - only print fatal error.\n" - "\t\t1 - print additional configuration information.\n" - "\t\t2 - print additional runtime information [default].\n" - "\t\t3 - print debugging and tracing information.\n"); - - ErrorF ("-[no]multimonitors or -[no]multiplemonitors\n" - "\tUse the entire virtual screen if multiple\n" - "\tmonitors are present.\n"); - -#ifdef XWIN_MULTIWINDOW - ErrorF ("-multiwindow\n" - "\tRun the server in multi-window mode.\n"); -#endif - -#ifdef XWIN_MULTIWINDOWEXTWM - ErrorF ("-mwextwm\n" - "\tRun the server in multi-window external window manager mode.\n"); -#endif - - ErrorF ("-nodecoration\n" - "\tDo not draw a window border, title bar, etc. Windowed\n" - "\tmode only.\n"); - -#ifdef XWIN_CLIPBOARD - ErrorF ("-nounicodeclipboard\n" - "\tDo not use Unicode clipboard even if on a NT-based platform.\n"); -#endif - - ErrorF ("-refresh rate_in_Hz\n" - "\tSpecify an optional refresh rate to use in fullscreen mode\n" - "\twith a DirectDraw engine.\n"); - - ErrorF ("-rootless\n" - "\tRun the server in rootless mode.\n"); - - ErrorF ("-screen scr_num [width height [x y] | [[WxH[+X+Y]][@m]] ]\n" - "\tEnable screen scr_num and optionally specify a width and\n" - "\theight and initial position for that screen. Additionally\n" - "\ta monitor number can be specified to start the server on,\n" - "\tat which point, all coordinates become relative to that\n" - "\tmonitor (Not for Windows NT4 and 95). Examples:\n" - "\t -screen 0 800x600+100+100@2 ; 2nd monitor offset 100,100 size 800x600\n" - "\t -screen 0 1024x768@3 ; 3rd monitor size 1024x768\n" - "\t -screen 0 @1 ; on 1st monitor using its full resolution (the default)\n"); - - ErrorF ("-scrollbars\n" - "\tIn windowed mode, allow screens bigger than the Windows desktop.\n" - "\tMoreover, if the window has decorations, one can now resize\n" - "\tit.\n"); - - ErrorF ("-silent-dup-error\n" - "\tIf another instance of " EXECUTABLE_NAME " with the same display number is running\n" - "\texit silently and don’t display any error message.\n"); - - ErrorF ("-swcursor\n" - "\tDisable the usage of the Windows cursor and use the X11 software\n" - "\tcursor instead.\n"); - - ErrorF ("-[no]trayicon\n" - "\tDo not create a tray icon. Default is to create one\n" - "\ticon per screen. You can globally disable tray icons with\n" - "\t-notrayicon, then enable it for specific screens with\n" - "\t-trayicon for those screens.\n"); - - ErrorF ("-[no]unixkill\n" - "\tCtrl+Alt+Backspace exits the X Server.\n"); - - ErrorF ("-[no]winkill\n" - "\tAlt+F4 exits the X Server.\n"); - - ErrorF ("-xkblayout XKBLayout\n" - "\tEquivalent to XKBLayout in XF86Config files.\n" - "\tFor example: -xkblayout de\n"); - - ErrorF ("-xkbmodel XKBModel\n" - "\tEquivalent to XKBModel in XF86Config files.\n"); - - ErrorF ("-xkboptions XKBOptions\n" - "\tEquivalent to XKBOptions in XF86Config files.\n"); - - ErrorF ("-xkbrules XKBRules\n" - "\tEquivalent to XKBRules in XF86Config files.\n"); - - ErrorF ("-xkbvariant XKBVariant\n" - "\tEquivalent to XKBVariant in XF86Config files.\n" - "\tFor example: -xkbvariant nodeadkeys\n"); -} - -/* See Porting Layer Definition - p. 57 */ -void -ddxUseMsg(void) -{ - /* Set a flag so that FatalError won't give duplicate warning message */ - g_fSilentFatalError = TRUE; - - winUseMsg(); - - /* Log file will not be opened for UseMsg unless we open it now */ - if (!g_fLogInited) { - LogInit (g_pszLogFile, NULL); - g_fLogInited = TRUE; - } - LogClose (); - - /* Notify user where UseMsg text can be found.*/ - if (!g_fNoHelpMessageBox) - winMessageBoxF ("The " PROJECT_NAME " help text has been printed to " - "/tmp/XWin.log.\n" - "Please open /tmp/XWin.log to read the help text.\n", - MB_ICONINFORMATION); -} - -/* See Porting Layer Definition - p. 20 */ -/* - * Do any global initialization, then initialize each screen. - * - * NOTE: We use ddxProcessArgument, so we don't need to touch argc and argv - */ - -void -InitOutput (ScreenInfo *screenInfo, int argc, char *argv[]) -{ - int i; - - /* Log the command line */ - winLogCommandLine (argc, argv); - -#if CYGDEBUG - winDebug ("InitOutput\n"); -#endif - - /* Validate command-line arguments */ - if (serverGeneration == 1 && !winValidateArgs ()) - { - FatalError ("InitOutput - Invalid command-line arguments found. " - "Exiting.\n"); - } - - /* Check for duplicate invocation on same display number.*/ - if (serverGeneration == 1 && !winCheckDisplayNumber ()) - { - if (g_fSilentDupError) - g_fSilentFatalError = TRUE; - FatalError ("InitOutput - Duplicate invocation on display " - "number: %s. Exiting.\n", display); - } - -#ifdef XWIN_XF86CONFIG - /* Try to read the xorg.conf-style configuration file */ - if (!winReadConfigfile ()) - winErrorFVerb (1, "InitOutput - Error reading config file\n"); -#else - winMsg(X_INFO, "xorg.conf is not supported\n"); - winMsg(X_INFO, "See http://x.cygwin.com/docs/faq/cygwin-x-faq.html " - "for more information\n"); - winConfigFiles (); -#endif - - /* Load preferences from XWinrc file */ - LoadPreferences(); - - /* Setup global screen info parameters */ - screenInfo->imageByteOrder = IMAGE_BYTE_ORDER; - screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; - screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; - screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; - screenInfo->numPixmapFormats = NUMFORMATS; - - /* Describe how we want common pixmap formats padded */ - for (i = 0; i < NUMFORMATS; i++) - { - screenInfo->formats[i] = g_PixmapFormats[i]; - } - - /* Load pointers to DirectDraw functions */ - winGetDDProcAddresses (); - - /* Detect supported engines */ - winDetectSupportedEngines (); - - /* Load common controls library */ - g_hmodCommonControls = LoadLibraryEx ("comctl32.dll", NULL, 0); - - /* Load TrackMouseEvent function pointer */ - g_fpTrackMouseEvent = GetProcAddress (g_hmodCommonControls, - "_TrackMouseEvent"); - if (g_fpTrackMouseEvent == NULL) - { - winErrorFVerb (1, "InitOutput - Could not get pointer to function\n" - "\t_TrackMouseEvent in comctl32.dll. Try installing\n" - "\tInternet Explorer 3.0 or greater if you have not\n" - "\talready.\n"); - - /* Free the library since we won't need it */ - FreeLibrary (g_hmodCommonControls); - g_hmodCommonControls = NULL; - - /* Set function pointer to point to no operation function */ - g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA; - } - - /* Store the instance handle */ - g_hInstance = GetModuleHandle (NULL); - - /* Initialize each screen */ - for (i = 0; i < g_iNumScreens; ++i) - { - /* Initialize the screen */ - if (-1 == AddScreen (winScreenInit, argc, argv)) - { - FatalError ("InitOutput - Couldn't add screen %d", i); - } - } - -#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) - - /* Generate a cookie used by internal clients for authorization */ - if (g_fXdmcpEnabled || g_fAuthEnabled) - winGenerateAuthorization (); - - /* Perform some one time initialization */ - if (1 == serverGeneration) - { - /* - * setlocale applies to all threads in the current process. - * Apply locale specified in LANG environment variable. - */ - setlocale (LC_ALL, ""); - } -#endif - -#if CYGDEBUG || YES - winDebug ("InitOutput - Returning.\n"); -#endif -} - - -/* - * winCheckDisplayNumber - Check if another instance of Cygwin/X is - * already running on the same display number. If no one exists, - * make a mutex to prevent new instances from running on the same display. - * - * return FALSE if the display number is already used. - */ - -static Bool -winCheckDisplayNumber (void) -{ - int nDisp; - HANDLE mutex; - char name[MAX_PATH]; - char * pszPrefix = '\0'; - OSVERSIONINFO osvi = {0}; - - /* Check display range */ - nDisp = atoi (display); - if (nDisp < 0 || nDisp > 65535) - { - ErrorF ("winCheckDisplayNumber - Bad display number: %d\n", nDisp); - return FALSE; - } - - /* Set first character of mutex name to null */ - name[0] = '\0'; - - /* Get operating system version information */ - osvi.dwOSVersionInfoSize = sizeof (osvi); - GetVersionEx (&osvi); - - /* Want a mutex shared among all terminals on NT > 4.0 */ - if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT - && osvi.dwMajorVersion >= 5) - { - pszPrefix = "Global\\"; - } - - /* Setup Cygwin/X specific part of name */ - snprintf (name, sizeof(name), "%sCYGWINX_DISPLAY:%d", pszPrefix, nDisp); - - /* Windows automatically releases the mutex when this process exits */ - mutex = CreateMutex (NULL, FALSE, name); - if (!mutex) - { - LPVOID lpMsgBuf; - - /* Display a fancy error message */ - FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError (), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, NULL); - ErrorF ("winCheckDisplayNumber - CreateMutex failed: %s\n", - (LPSTR)lpMsgBuf); - LocalFree (lpMsgBuf); - - return FALSE; - } - if (GetLastError () == ERROR_ALREADY_EXISTS) - { - ErrorF ("winCheckDisplayNumber - " - PROJECT_NAME " is already running on display %d\n", - nDisp); - return FALSE; - } - - return TRUE; -} +/*
+
+Copyright 1993, 1998 The Open Group
+Copyright (C) Colin Harrison 2005-2008
+
+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.
+
+*/
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include "winmsg.h"
+#include "winconfig.h"
+#include "winprefs.h"
+#ifdef XWIN_CLIPBOARD
+#include "X11/Xlocale.h"
+#endif
+#ifdef DPMSExtension
+#include "dpmsproc.h"
+#endif
+#ifdef __CYGWIN__
+#include <mntent.h>
+#endif
+#if defined(WIN32)
+#include "xkbsrv.h"
+#endif
+
+#ifdef RELOCATE_PROJECTROOT
+#undef Status
+#include <shlobj.h>
+typedef HRESULT (__stdcall * SHGETFOLDERPATHPROC)(
+ HWND hwndOwner,
+ int nFolder,
+ HANDLE hToken,
+ DWORD dwFlags,
+ LPSTR pszPath
+);
+#endif
+
+
+/*
+ * References to external symbols
+ */
+
+extern int g_iNumScreens;
+extern winScreenInfo g_ScreenInfo[];
+extern int g_iLastScreen;
+extern char * g_pszCommandLine;
+extern Bool g_fSilentFatalError;
+
+extern const char * g_pszLogFile;
+extern Bool g_fLogFileChanged;
+extern int g_iLogVerbose;
+Bool g_fLogInited;
+
+extern Bool g_fXdmcpEnabled;
+extern Bool g_fAuthEnabled;
+#ifdef HAS_DEVWINDOWS
+extern int g_fdMessageQueue;
+#endif
+extern const char * g_pszQueryHost;
+extern HINSTANCE g_hInstance;
+
+#ifdef XWIN_CLIPBOARD
+extern Bool g_fUnicodeClipboard;
+extern Bool g_fClipboardLaunched;
+extern Bool g_fClipboardStarted;
+extern pthread_t g_ptClipboardProc;
+extern HWND g_hwndClipboard;
+extern Bool g_fClipboard;
+#endif
+
+extern HMODULE g_hmodDirectDraw;
+extern FARPROC g_fpDirectDrawCreate;
+extern FARPROC g_fpDirectDrawCreateClipper;
+
+extern HMODULE g_hmodCommonControls;
+extern FARPROC g_fpTrackMouseEvent;
+extern Bool g_fNoHelpMessageBox;
+extern Bool g_fSilentDupError;
+extern Bool g_fNativeGl;
+
+/*
+ * Function prototypes
+ */
+
+#ifdef XWIN_CLIPBOARD
+static void
+winClipboardShutdown (void);
+#endif
+
+#if defined(DDXOSVERRORF)
+void
+OsVendorVErrorF (const char *pszFormat, va_list va_args);
+#endif
+
+void
+winInitializeDefaultScreens (void);
+
+static Bool
+winCheckDisplayNumber (void);
+
+void
+winLogCommandLine (int argc, char *argv[]);
+
+void
+winLogVersionInfo (void);
+
+Bool
+winValidateArgs (void);
+
+#ifdef RELOCATE_PROJECTROOT
+const char *
+winGetBaseDir(void);
+#endif
+
+static
+void glx_debugging(void);
+
+/*
+ * For the depth 24 pixmap we default to 32 bits per pixel, but
+ * we change this pixmap format later if we detect that the display
+ * is going to be running at 24 bits per pixel.
+ *
+ * FIXME: On second thought, don't DIBs only support 32 bits per pixel?
+ * DIBs are the underlying bitmap used for DirectDraw surfaces, so it
+ * seems that all pixmap formats with depth 24 would be 32 bits per pixel.
+ * Confirm whether depth 24 DIBs can have 24 bits per pixel, then remove/keep
+ * the bits per pixel adjustment and update this comment to reflect the
+ * situation. Harold Hunt - 2002/07/02
+ */
+
+static PixmapFormatRec g_PixmapFormats[] = {
+ { 1, 1, BITMAP_SCANLINE_PAD },
+ { 4, 8, BITMAP_SCANLINE_PAD },
+ { 8, 8, BITMAP_SCANLINE_PAD },
+ { 15, 16, BITMAP_SCANLINE_PAD },
+ { 16, 16, BITMAP_SCANLINE_PAD },
+ { 24, 32, BITMAP_SCANLINE_PAD },
+#ifdef RENDER
+ { 32, 32, BITMAP_SCANLINE_PAD }
+#endif
+};
+
+const int NUMFORMATS = sizeof (g_PixmapFormats) / sizeof (g_PixmapFormats[0]);
+
+#ifdef XWIN_CLIPBOARD
+static void
+winClipboardShutdown (void)
+{
+ /* Close down clipboard resources */
+ if (g_fClipboard && g_fClipboardLaunched && g_fClipboardStarted)
+ {
+ /* Synchronously destroy the clipboard window */
+ if (g_hwndClipboard != NULL)
+ {
+ SendMessage (g_hwndClipboard, WM_DESTROY, 0, 0);
+ /* NOTE: g_hwndClipboard is set to NULL in winclipboardthread.c */
+ }
+ else
+ return;
+
+ /* Wait for the clipboard thread to exit */
+ pthread_join (g_ptClipboardProc, NULL);
+
+ winDebug ("winClipboardShutdown - Clipboard thread has exited.\n");
+ }
+}
+#endif
+
+
+#if defined(DDXBEFORERESET)
+/*
+ * Called right before KillAllClients when the server is going to reset,
+ * allows us to shutdown our seperate threads cleanly.
+ */
+
+void
+ddxBeforeReset (void)
+{
+ winDebug ("ddxBeforeReset - Hello\n");
+
+#ifdef XWIN_CLIPBOARD
+ winClipboardShutdown ();
+#endif
+}
+#endif
+
+
+/* See Porting Layer Definition - p. 57 */
+void
+ddxGiveUp (void)
+{
+ int i;
+
+ winDebug ("ddxGiveUp\n");
+
+ /* Perform per-screen deinitialization */
+ for (i = 0; i < g_iNumScreens; ++i)
+ {
+ /* Delete the tray icon */
+ if (!g_ScreenInfo[i].fNoTrayIcon && g_ScreenInfo[i].pScreen)
+ winDeleteNotifyIcon (winGetScreenPriv (g_ScreenInfo[i].pScreen));
+ }
+
+#ifdef XWIN_MULTIWINDOW
+ /* Notify the worker threads we're exiting */
+ winDeinitMultiWindowWM ();
+#endif
+
+#ifdef HAS_DEVWINDOWS
+ /* Close our handle to our message queue */
+ if (g_fdMessageQueue != WIN_FD_INVALID)
+ {
+ /* Close /dev/windows */
+ close (g_fdMessageQueue);
+
+ /* Set the file handle to invalid */
+ g_fdMessageQueue = WIN_FD_INVALID;
+ }
+#endif
+
+ if (!g_fLogInited) {
+ g_pszLogFile = LogInit (g_pszLogFile, NULL);
+ g_fLogInited = TRUE;
+ }
+ LogClose ();
+
+ /*
+ * At this point we aren't creating any new screens, so
+ * we are guaranteed to not need the DirectDraw functions.
+ */
+ if (g_hmodDirectDraw != NULL)
+ {
+ FreeLibrary (g_hmodDirectDraw);
+ g_hmodDirectDraw = NULL;
+ g_fpDirectDrawCreate = NULL;
+ g_fpDirectDrawCreateClipper = NULL;
+ }
+
+ /* Unload our TrackMouseEvent funtion pointer */
+ if (g_hmodCommonControls != NULL)
+ {
+ FreeLibrary (g_hmodCommonControls);
+ g_hmodCommonControls = NULL;
+ g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA;
+ }
+
+ /* Free concatenated command line */
+ if (g_pszCommandLine)
+ {
+ free (g_pszCommandLine);
+ g_pszCommandLine = NULL;
+ }
+
+ /* Remove our keyboard hook if it is installed */
+ winRemoveKeyboardHookLL ();
+
+ /* Tell Windows that we want to end the app */
+ PostQuitMessage (0);
+}
+
+
+/* See Porting Layer Definition - p. 57 */
+void
+AbortDDX (void)
+{
+ winDebug ("AbortDDX\n");
+ ddxGiveUp ();
+}
+
+#ifdef __CYGWIN__
+/* hasmntopt is currently not implemented for cygwin */
+static const char *winCheckMntOpt(const struct mntent *mnt, const char *opt)
+{
+ const char *s;
+ size_t len;
+ if (mnt == NULL)
+ return NULL;
+ if (opt == NULL)
+ return NULL;
+ if (mnt->mnt_opts == NULL)
+ return NULL;
+
+ len = strlen(opt);
+ s = strstr(mnt->mnt_opts, opt);
+ if (s == NULL)
+ return NULL;
+ if ((s == mnt->mnt_opts || *(s-1) == ',') && (s[len] == 0 || s[len] == ','))
+ return (char *)opt;
+ return NULL;
+}
+
+static void
+winCheckMount(void)
+{
+ FILE *mnt;
+ struct mntent *ent;
+
+ enum { none = 0, sys_root, user_root, sys_tmp, user_tmp }
+ level = none, curlevel;
+ BOOL binary = TRUE;
+
+ mnt = setmntent("/etc/mtab", "r");
+ if (mnt == NULL)
+ {
+ ErrorF("setmntent failed");
+ return;
+ }
+
+ while ((ent = getmntent(mnt)) != NULL)
+ {
+ BOOL system = (winCheckMntOpt(ent, "user") != NULL);
+ BOOL root = (strcmp(ent->mnt_dir, "/") == 0);
+ BOOL tmp = (strcmp(ent->mnt_dir, "/tmp") == 0);
+
+ if (system)
+ {
+ if (root)
+ curlevel = sys_root;
+ else if (tmp)
+ curlevel = sys_tmp;
+ else
+ continue;
+ }
+ else
+ {
+ if (root)
+ curlevel = user_root;
+ else if (tmp)
+ curlevel = user_tmp;
+ else
+ continue;
+ }
+
+ if (curlevel <= level)
+ continue;
+ level = curlevel;
+
+ if ((winCheckMntOpt(ent, "binary") == NULL) ||
+ (winCheckMntOpt(ent, "binmode") == NULL))
+ binary = 0;
+ else
+ binary = 1;
+ }
+
+ if (endmntent(mnt) != 1)
+ {
+ ErrorF("endmntent failed");
+ return;
+ }
+
+#ifdef WINDBG
+ if (!binary)
+ winDebug("/tmp mounted in textmode\n");
+#endif
+}
+#else
+static void
+winCheckMount(void)
+{
+}
+#endif
+
+#ifdef RELOCATE_PROJECTROOT
+const char *
+winGetBaseDir(void)
+{
+ static BOOL inited = FALSE;
+ static char buffer[MAX_PATH];
+ if (!inited)
+ {
+ char *fendptr;
+ HMODULE module = GetModuleHandle(NULL);
+ DWORD size = GetModuleFileName(module, buffer, sizeof(buffer));
+ if (sizeof(buffer) > 0)
+ buffer[sizeof(buffer)-1] = 0;
+
+ fendptr = buffer + size;
+ while (fendptr > buffer)
+ {
+ if (*fendptr == '\\' || *fendptr == '/')
+ {
+ *fendptr = 0;
+ break;
+ }
+ fendptr--;
+ }
+ inited = TRUE;
+ }
+ return buffer;
+}
+#endif
+
+static void
+winFixupPaths (void)
+{
+ BOOL changed_fontpath = FALSE;
+ MessageType font_from = X_DEFAULT;
+#ifdef RELOCATE_PROJECTROOT
+ const char *basedir = winGetBaseDir();
+ size_t basedirlen = strlen(basedir);
+#endif
+
+#ifdef READ_FONTDIRS
+ {
+ /* Open fontpath configuration file */
+#if defined WIN32 && defined __MINGW32__
+ static Bool once = False;
+ char buffer[MAX_PATH];
+ snprintf(buffer, sizeof(buffer), "%s\\font-dirs", basedir);
+ buffer[sizeof(buffer)-1] = 0;
+ FILE *fontdirs = fopen(buffer, "rt");
+ if (once) fontdirs = NULL;
+ else once = True;
+#else
+ FILE *fontdirs = fopen(ETCX11DIR "/font-dirs", "rt");
+#endif
+ if (fontdirs != NULL)
+ {
+ char buffer[256];
+ int needs_sep = TRUE;
+ int comment_block = FALSE;
+
+ /* get defautl fontpath */
+ char *fontpath = xstrdup(defaultFontPath);
+ size_t size = strlen(fontpath);
+
+ /* read all lines */
+ while (!feof(fontdirs))
+ {
+ size_t blen;
+ char *hashchar;
+ char *str;
+ int has_eol = FALSE;
+
+ /* read one line */
+ str = fgets(buffer, sizeof(buffer), fontdirs);
+ if (str == NULL) /* stop on error or eof */
+ break;
+
+ if (strchr(str, '\n') != NULL)
+ has_eol = TRUE;
+
+ /* check if block is continued comment */
+ if (comment_block)
+ {
+ /* ignore all input */
+ *str = 0;
+ blen = 0;
+ if (has_eol) /* check if line ended in this block */
+ comment_block = FALSE;
+ }
+ else
+ {
+ /* find comment character. ignore all trailing input */
+ hashchar = strchr(str, '#');
+ if (hashchar != NULL)
+ {
+ *hashchar = 0;
+ if (!has_eol) /* mark next block as continued comment */
+ comment_block = TRUE;
+ }
+ }
+
+ /* strip whitespaces from beginning */
+ while (*str == ' ' || *str == '\t')
+ str++;
+
+ /* get size, strip whitespaces from end */
+ blen = strlen(str);
+ while (blen > 0 && (str[blen-1] == ' ' ||
+ str[blen-1] == '\t' || str[blen-1] == '\n'))
+ {
+ str[--blen] = 0;
+ }
+
+ /* still something left to add? */
+ if (blen > 0)
+ {
+ size_t newsize = size + blen;
+ /* reserve one character more for ',' */
+ if (needs_sep)
+ newsize++;
+
+ /* allocate memory */
+ if (fontpath == NULL)
+ fontpath = malloc(newsize+1);
+ else
+ fontpath = realloc(fontpath, newsize+1);
+
+ /* add separator */
+ if (needs_sep)
+ {
+ fontpath[size] = ',';
+ size++;
+ needs_sep = FALSE;
+ }
+
+ /* mark next line as new entry */
+ if (has_eol)
+ needs_sep = TRUE;
+
+ /* add block */
+ strncpy(fontpath + size, str, blen);
+ fontpath[newsize] = 0;
+ size = newsize;
+ }
+ }
+
+ /* cleanup */
+ fclose(fontdirs);
+ defaultFontPath = xstrdup(fontpath);
+ free(fontpath);
+ changed_fontpath = TRUE;
+ font_from = X_CONFIG;
+ }
+ }
+#endif /* READ_FONTDIRS */
+#ifdef RELOCATE_PROJECTROOT
+ {
+ const char *libx11dir = PROJECTROOT "/lib/X11";
+ size_t libx11dir_len = strlen(libx11dir);
+ char *newfp = NULL;
+ size_t newfp_len = 0;
+ const char *endptr, *ptr, *oldptr = defaultFontPath;
+
+ endptr = oldptr + strlen(oldptr);
+ ptr = strchr(oldptr, ',');
+ if (ptr == NULL)
+ ptr = endptr;
+ while (ptr != NULL)
+ {
+ size_t oldfp_len = (ptr - oldptr);
+ size_t newsize = oldfp_len;
+ char *newpath = malloc(newsize + 1);
+ strncpy(newpath, oldptr, newsize);
+ newpath[newsize] = 0;
+
+
+ if (strncmp(libx11dir, newpath, libx11dir_len) == 0)
+ {
+ char *compose;
+ newsize = newsize - libx11dir_len + basedirlen;
+ compose = malloc(newsize + 1);
+ strcpy(compose, basedir);
+ strncat(compose, newpath + libx11dir_len, newsize - basedirlen);
+ compose[newsize] = 0;
+ free(newpath);
+ newpath = compose;
+ }
+
+ oldfp_len = newfp_len;
+ if (oldfp_len > 0)
+ newfp_len ++; /* space for separator */
+ newfp_len += newsize;
+
+ if (newfp == NULL)
+ newfp = malloc(newfp_len + 1);
+ else
+ newfp = realloc(newfp, newfp_len + 1);
+
+ if (oldfp_len > 0)
+ {
+ strcpy(newfp + oldfp_len, ",");
+ oldfp_len++;
+ }
+ strcpy(newfp + oldfp_len, newpath);
+
+ free(newpath);
+
+ if (*ptr == 0)
+ {
+ oldptr = ptr;
+ ptr = NULL;
+ } else
+ {
+ oldptr = ptr + 1;
+ ptr = strchr(oldptr, ',');
+ if (ptr == NULL)
+ ptr = endptr;
+ }
+ }
+
+ defaultFontPath = xstrdup(newfp);
+ free(newfp);
+ changed_fontpath = TRUE;
+ }
+#endif /* RELOCATE_PROJECTROOT */
+ if (changed_fontpath)
+ winDebug ("FontPath set to \"%s\"\n", defaultFontPath);
+
+#ifdef RELOCATE_PROJECTROOT
+ if (getenv("XKEYSYMDB") == NULL)
+ {
+ char buffer[MAX_PATH];
+ snprintf(buffer, sizeof(buffer), "XKEYSYMDB=%s\\XKeysymDB",
+ basedir);
+ buffer[sizeof(buffer)-1] = 0;
+ putenv(buffer);
+ }
+ if (getenv("XERRORDB") == NULL)
+ {
+ char buffer[MAX_PATH];
+ snprintf(buffer, sizeof(buffer), "XERRORDB=%s\\XErrorDB",
+ basedir);
+ buffer[sizeof(buffer)-1] = 0;
+ putenv(buffer);
+ }
+ if (getenv("XLOCALEDIR") == NULL)
+ {
+ char buffer[MAX_PATH];
+ snprintf(buffer, sizeof(buffer), "XLOCALEDIR=%s\\locale",
+ basedir);
+ buffer[sizeof(buffer)-1] = 0;
+ putenv(buffer);
+ }
+ if (getenv("XHOSTPREFIX") == NULL)
+ {
+ char buffer[MAX_PATH];
+ snprintf(buffer, sizeof(buffer), "XHOSTPREFIX=%s\\X",
+ basedir);
+ buffer[sizeof(buffer)-1] = 0;
+ putenv(buffer);
+ }
+ if (getenv("HOME") == NULL)
+ {
+ HMODULE shfolder;
+ SHGETFOLDERPATHPROC shgetfolderpath = NULL;
+ char buffer[MAX_PATH + 5];
+ strncpy(buffer, "HOME=", 5);
+
+ /* Try to load SHGetFolderPath from shfolder.dll and shell32.dll */
+
+ shfolder = LoadLibrary("shfolder.dll");
+ /* fallback to shell32.dll */
+ if (shfolder == NULL)
+ shfolder = LoadLibrary("shell32.dll");
+
+ /* resolve SHGetFolderPath */
+ if (shfolder != NULL)
+ shgetfolderpath = (SHGETFOLDERPATHPROC)GetProcAddress(shfolder, "SHGetFolderPathA");
+
+ /* query appdata directory */
+ if (shgetfolderpath &&
+ shgetfolderpath(NULL, CSIDL_APPDATA|CSIDL_FLAG_CREATE, NULL, 0,
+ buffer + 5) == 0)
+ {
+ putenv(buffer);
+ } else
+ {
+ ErrorF ("Can not determine HOME directory\n");
+ }
+ if (shfolder != NULL)
+ FreeLibrary(shfolder);
+ }
+ if (!g_fLogFileChanged) {
+ static char buffer[MAX_PATH];
+ DWORD size = GetTempPath(sizeof(buffer), buffer);
+ if (size && size < sizeof(buffer))
+ {
+ snprintf(buffer + size, sizeof(buffer) - size,
+ "VCXSrv.%s.log", display);
+ buffer[sizeof(buffer)-1] = 0;
+ g_pszLogFile = buffer;
+ GetLongPathName(buffer, buffer, MAX_PATH);
+ winDebug ("Logfile set to \"%s\"\n", g_pszLogFile);
+ }
+ }
+ {
+ static char xkbbasedir[MAX_PATH];
+
+ snprintf(xkbbasedir, sizeof(xkbbasedir), "%s\\xkbdata", basedir);
+ if (sizeof(xkbbasedir) > 0)
+ xkbbasedir[sizeof(xkbbasedir)-1] = 0;
+ XkbBaseDirectory = xkbbasedir;
+ XkbBinDirectory = basedir;
+ }
+#endif /* RELOCATE_PROJECTROOT */
+}
+
+void
+OsVendorInit (void)
+{
+ /* Re-initialize global variables on server reset */
+ winInitializeGlobals ();
+
+ winFixupPaths();
+
+#ifdef DDXOSVERRORF
+ if (!OsVendorVErrorFProc)
+ OsVendorVErrorFProc = OsVendorVErrorF;
+#endif
+
+ if (!g_fLogInited) {
+ /* keep this order. If LogInit fails it calls Abort which then calls
+ * ddxGiveUp where LogInit is called again and creates an infinite
+ * recursion. If we set g_fLogInited to TRUE before the init we
+ * avoid the second call
+ */
+ g_fLogInited = TRUE;
+ g_pszLogFile = LogInit (g_pszLogFile, NULL);
+ }
+ LogSetParameter (XLOG_FLUSH, 1);
+ LogSetParameter (XLOG_VERBOSITY, g_iLogVerbose);
+ LogSetParameter (XLOG_FILE_VERBOSITY, g_iLogVerbose);
+
+ /* Log the version information */
+ if (serverGeneration == 1)
+ winLogVersionInfo ();
+
+ winCheckMount();
+
+ /* Add a default screen if no screens were specified */
+ if (g_iNumScreens == 0)
+ {
+ winDebug ("OsVendorInit - Creating bogus screen 0\n");
+
+ /*
+ * We need to initialize default screens if no arguments
+ * were processed. Otherwise, the default screens would
+ * already have been initialized by ddxProcessArgument ().
+ */
+ winInitializeDefaultScreens ();
+
+ /*
+ * Add a screen 0 using the defaults set by
+ * winInitializeDefaultScreens () and any additional parameters
+ * processed by ddxProcessArgument ().
+ */
+ g_iNumScreens = 1;
+ g_iLastScreen = 0;
+
+ /* We have to flag this as an explicit screen, even though it isn't */
+ g_ScreenInfo[0].fExplicitScreen = TRUE;
+ }
+}
+
+
+static void
+winUseMsg (void)
+{
+ ErrorF("\n");
+ ErrorF("\n");
+ ErrorF(EXECUTABLE_NAME " Device Dependent Usage:\n");
+ ErrorF("\n");
+
+#ifdef XWIN_CLIPBOARD
+ ErrorF ("-[no]clipboard\n"
+ "\tEnable [disable] the clipboard integration. Default is enabled.\n");
+#endif
+
+ ErrorF ("-clipupdates num_boxes\n"
+ "\tUse a clipping region to constrain shadow update blits to\n"
+ "\tthe updated region when num_boxes, or more, are in the\n"
+ "\tupdated region.\n");
+
+#ifdef XWIN_XF86CONFIG
+ ErrorF ("-config\n"
+ "\tSpecify a configuration file.\n");
+
+ ErrorF ("-configdir\n"
+ "\tSpecify a configuration directory.\n");
+#endif
+
+ ErrorF ("-depth bits_per_pixel\n"
+ "\tSpecify an optional bitdepth to use in fullscreen mode\n"
+ "\twith a DirectDraw engine.\n");
+
+ ErrorF ("-emulate3buttons [timeout]\n"
+ "\tEmulate 3 button mouse with an optional timeout in\n"
+ "\tmilliseconds.\n");
+
+#ifdef XWIN_EMULATEPSEUDO
+ ErrorF ("-emulatepseudo\n"
+ "\tCreate a depth 8 PseudoColor visual when running in\n"
+ "\tdepths 15, 16, 24, or 32, collectively known as TrueColor\n"
+ "\tdepths. The PseudoColor visual does not have correct colors,\n"
+ "\tand it may crash, but it at least allows you to run your\n"
+ "\tapplication in TrueColor modes.\n");
+#endif
+
+ ErrorF ("-engine engine_type_id\n"
+ "\tOverride the server's automatically selected engine type:\n"
+ "\t\t1 - Shadow GDI\n"
+ "\t\t2 - Shadow DirectDraw\n"
+ "\t\t4 - Shadow DirectDraw4 Non-Locking\n"
+#ifdef XWIN_NATIVEGDI
+ "\t\t16 - Native GDI - experimental\n"
+#endif
+ );
+
+ ErrorF ("-fullscreen\n"
+ "\tRun the server in fullscreen mode.\n");
+
+ ErrorF ("-ignoreinput\n"
+ "\tIgnore keyboard and mouse input.\n");
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+ ErrorF ("-internalwm\n"
+ "\tRun the internal window manager.\n");
+#endif
+
+#ifdef XWIN_XF86CONFIG
+ ErrorF ("-keyboard\n"
+ "\tSpecify a keyboard device from the configuration file.\n");
+#endif
+
+ ErrorF ("-[no]keyhook\n"
+ "\tGrab special Windows keypresses like Alt-Tab or the Menu "
+ "key.\n");
+
+ ErrorF ("-lesspointer\n"
+ "\tHide the windows mouse pointer when it is over any\n"
+ "\t" EXECUTABLE_NAME " window. This prevents ghost cursors appearing when\n"
+ "\tthe Windows cursor is drawn on top of the X cursor\n");
+
+ ErrorF ("-logfile filename\n"
+ "\tWrite log messages to <filename>.\n");
+
+ ErrorF ("-logverbose verbosity\n"
+ "\tSet the verbosity of log messages. [NOTE: Only a few messages\n"
+ "\trespect the settings yet]\n"
+ "\t\t0 - only print fatal error.\n"
+ "\t\t1 - print additional configuration information.\n"
+ "\t\t2 - print additional runtime information [default].\n"
+ "\t\t3 - print debugging and tracing information.\n");
+
+ ErrorF ("-[no]multimonitors or -[no]multiplemonitors\n"
+ "\tUse the entire virtual screen if multiple\n"
+ "\tmonitors are present.\n");
+
+#ifdef XWIN_MULTIWINDOW
+ ErrorF ("-multiwindow\n"
+ "\tRun the server in multi-window mode.\n");
+#endif
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+ ErrorF ("-mwextwm\n"
+ "\tRun the server in multi-window external window manager mode.\n");
+#endif
+
+ ErrorF ("-nodecoration\n"
+ "\tDo not draw a window border, title bar, etc. Windowed\n"
+ "\tmode only.\n");
+
+#ifdef XWIN_CLIPBOARD
+ ErrorF ("-nounicodeclipboard\n"
+ "\tDo not use Unicode clipboard even if on a NT-based platform.\n");
+#endif
+
+ ErrorF ("-refresh rate_in_Hz\n"
+ "\tSpecify an optional refresh rate to use in fullscreen mode\n"
+ "\twith a DirectDraw engine.\n");
+
+ ErrorF ("-rootless\n"
+ "\tRun the server in rootless mode.\n");
+
+ ErrorF ("-screen scr_num [width height [x y] | [[WxH[+X+Y]][@m]] ]\n"
+ "\tEnable screen scr_num and optionally specify a width and\n"
+ "\theight and initial position for that screen. Additionally\n"
+ "\ta monitor number can be specified to start the server on,\n"
+ "\tat which point, all coordinates become relative to that\n"
+ "\tmonitor (Not for Windows NT4 and 95). Examples:\n"
+ "\t -screen 0 800x600+100+100@2 ; 2nd monitor offset 100,100 size 800x600\n"
+ "\t -screen 0 1024x768@3 ; 3rd monitor size 1024x768\n"
+ "\t -screen 0 @1 ; on 1st monitor using its full resolution (the default)\n");
+
+ ErrorF ("-scrollbars\n"
+ "\tIn windowed mode, allow screens bigger than the Windows desktop.\n"
+ "\tMoreover, if the window has decorations, one can now resize\n"
+ "\tit.\n");
+
+ ErrorF ("-silent-dup-error\n"
+ "\tIf another instance of " EXECUTABLE_NAME " with the same display number is running\n"
+ "\texit silently and don’t display any error message.\n");
+
+ ErrorF ("-swcursor\n"
+ "\tDisable the usage of the Windows cursor and use the X11 software\n"
+ "\tcursor instead.\n");
+
+ ErrorF ("-[no]trayicon\n"
+ "\tDo not create a tray icon. Default is to create one\n"
+ "\ticon per screen. You can globally disable tray icons with\n"
+ "\t-notrayicon, then enable it for specific screens with\n"
+ "\t-trayicon for those screens.\n");
+
+ ErrorF ("-[no]unixkill\n"
+ "\tCtrl+Alt+Backspace exits the X Server.\n");
+
+ ErrorF ("-[no]winkill\n"
+ "\tAlt+F4 exits the X Server.\n");
+
+ ErrorF ("-xkblayout XKBLayout\n"
+ "\tEquivalent to XKBLayout in XF86Config files.\n"
+ "\tFor example: -xkblayout de\n");
+
+ ErrorF ("-xkbmodel XKBModel\n"
+ "\tEquivalent to XKBModel in XF86Config files.\n");
+
+ ErrorF ("-xkboptions XKBOptions\n"
+ "\tEquivalent to XKBOptions in XF86Config files.\n");
+
+ ErrorF ("-xkbrules XKBRules\n"
+ "\tEquivalent to XKBRules in XF86Config files.\n");
+
+ ErrorF ("-xkbvariant XKBVariant\n"
+ "\tEquivalent to XKBVariant in XF86Config files.\n"
+ "\tFor example: -xkbvariant nodeadkeys\n");
+
+#ifdef XWIN_GLX_WINDOWS
+ ErrorF ("-[no]wgl\n"
+ "\tEnable the GLX extension to use the native Windows WGL interface for accelerated OpenGL\n");
+#endif
+}
+
+/* See Porting Layer Definition - p. 57 */
+void
+ddxUseMsg(void)
+{
+ /* Set a flag so that FatalError won't give duplicate warning message */
+ g_fSilentFatalError = TRUE;
+
+ winUseMsg();
+
+ /* Log file will not be opened for UseMsg unless we open it now */
+ if (!g_fLogInited) {
+ g_pszLogFile = LogInit (g_pszLogFile, NULL);
+ g_fLogInited = TRUE;
+ }
+ LogClose ();
+
+ /* Notify user where UseMsg text can be found.*/
+ if (!g_fNoHelpMessageBox)
+ winMessageBoxF ("The " PROJECT_NAME " help text has been printed to "
+ "%s.\n"
+ "Please open %s to read the help text.\n",
+ MB_ICONINFORMATION, g_pszLogFile, g_pszLogFile);
+}
+
+/* See Porting Layer Definition - p. 20 */
+/*
+ * Do any global initialization, then initialize each screen.
+ *
+ * NOTE: We use ddxProcessArgument, so we don't need to touch argc and argv
+ */
+
+void
+InitOutput (ScreenInfo *screenInfo, int argc, char *argv[])
+{
+ int i;
+
+ /* Log the command line */
+ winLogCommandLine (argc, argv);
+
+ winDebug ("InitOutput\n");
+
+ /* Validate command-line arguments */
+ if (serverGeneration == 1 && !winValidateArgs ())
+ {
+ FatalError ("InitOutput - Invalid command-line arguments found. "
+ "Exiting.\n");
+ }
+
+ /* Check for duplicate invocation on same display number.*/
+ if (serverGeneration == 1 && !winCheckDisplayNumber ())
+ {
+ if (g_fSilentDupError)
+ g_fSilentFatalError = TRUE;
+ FatalError ("InitOutput - Duplicate invocation on display "
+ "number: %s. Exiting.\n", display);
+ }
+
+#ifdef XWIN_XF86CONFIG
+ /* Try to read the xorg.conf-style configuration file */
+ if (!winReadConfigfile ())
+ ErrorF ("InitOutput - Error reading config file\n");
+#else
+ winConfigFiles ();
+#endif
+
+ /* Load preferences from XWinrc file */
+ LoadPreferences();
+
+ /* Setup global screen info parameters */
+ screenInfo->imageByteOrder = IMAGE_BYTE_ORDER;
+ screenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD;
+ screenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT;
+ screenInfo->bitmapBitOrder = BITMAP_BIT_ORDER;
+ screenInfo->numPixmapFormats = NUMFORMATS;
+
+ /* Describe how we want common pixmap formats padded */
+ for (i = 0; i < NUMFORMATS; i++)
+ {
+ screenInfo->formats[i] = g_PixmapFormats[i];
+ }
+
+ /* Load pointers to DirectDraw functions */
+ winGetDDProcAddresses ();
+
+ /* Detect supported engines */
+ winDetectSupportedEngines ();
+
+ /* Load common controls library */
+ g_hmodCommonControls = LoadLibraryEx ("comctl32.dll", NULL, 0);
+
+ /* Load TrackMouseEvent function pointer */
+ g_fpTrackMouseEvent = GetProcAddress (g_hmodCommonControls,
+ "_TrackMouseEvent");
+ if (g_fpTrackMouseEvent == NULL)
+ {
+ ErrorF ("InitOutput - Could not get pointer to function\n"
+ "\t_TrackMouseEvent in comctl32.dll. Try installing\n"
+ "\tInternet Explorer 3.0 or greater if you have not\n"
+ "\talready.\n");
+
+ /* Free the library since we won't need it */
+ FreeLibrary (g_hmodCommonControls);
+ g_hmodCommonControls = NULL;
+
+ /* Set function pointer to point to no operation function */
+ g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA;
+ }
+
+ /* Store the instance handle */
+ g_hInstance = GetModuleHandle (NULL);
+
+ /* Initialize each screen */
+ for (i = 0; i < g_iNumScreens; ++i)
+ {
+ /* Initialize the screen */
+ if (-1 == AddScreen (winScreenInit, argc, argv))
+ {
+ FatalError ("InitOutput - Couldn't add screen %d", i);
+ }
+ }
+
+#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
+
+ /* Generate a cookie used by internal clients for authorization */
+ if (g_fXdmcpEnabled || g_fAuthEnabled)
+ winGenerateAuthorization ();
+
+ /* Perform some one time initialization */
+ if (1 == serverGeneration)
+ {
+ /*
+ * setlocale applies to all threads in the current process.
+ * Apply locale specified in LANG environment variable.
+ */
+ setlocale (LC_ALL, "");
+
+ glx_debugging();
+ }
+#endif
+
+ winDebug ("InitOutput - Returning.\n");
+}
+
+
+/*
+ * winCheckDisplayNumber - Check if another instance of Cygwin/X is
+ * already running on the same display number. If no one exists,
+ * make a mutex to prevent new instances from running on the same display.
+ *
+ * return FALSE if the display number is already used.
+ */
+
+static Bool
+winCheckDisplayNumber (void)
+{
+ int nDisp;
+ HANDLE mutex;
+ char name[MAX_PATH];
+ char * pszPrefix = '\0';
+ OSVERSIONINFO osvi = {0};
+
+ /* Check display range */
+ nDisp = atoi (display);
+ if (nDisp < 0 || nDisp > 59535)
+ {
+ ErrorF ("winCheckDisplayNumber - Bad display number: %d\n", nDisp);
+ return FALSE;
+ }
+
+ /* Set first character of mutex name to null */
+ name[0] = '\0';
+
+ /* Get operating system version information */
+ osvi.dwOSVersionInfoSize = sizeof (osvi);
+ GetVersionEx (&osvi);
+
+ /* Want a mutex shared among all terminals on NT > 4.0 */
+ if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT
+ && osvi.dwMajorVersion >= 5)
+ {
+ pszPrefix = "Global\\";
+ }
+
+ /* Setup Cygwin/X specific part of name */
+ snprintf (name, sizeof(name), "%sCYGWINX_DISPLAY:%d", pszPrefix, nDisp);
+
+ /* Windows automatically releases the mutex when this process exits */
+ mutex = CreateMutex (NULL, FALSE, name);
+ if (!mutex)
+ {
+ LPVOID lpMsgBuf;
+
+ /* Display a fancy error message */
+ FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM |
+ FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ GetLastError (),
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &lpMsgBuf,
+ 0, NULL);
+ ErrorF ("winCheckDisplayNumber - CreateMutex failed: %s\n",
+ (LPSTR)lpMsgBuf);
+ LocalFree (lpMsgBuf);
+
+ return FALSE;
+ }
+ if (GetLastError () == ERROR_ALREADY_EXISTS)
+ {
+ ErrorF ("winCheckDisplayNumber - "
+ "VCXsrv, Xming or Cygwin/X is already running on display %d\n",
+ nDisp);
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/* GLX debugging helpers */
+#include <../glx/glapi.h>
+
+static
+void warn_func(void * p1, const char *format, ...) {
+ va_list v;
+ va_start(v, format);
+ vfprintf(stderr, format, v);
+ va_end(v);
+ fprintf(stderr,"\n");
+}
+
+static
+void glx_debugging(void)
+{
+ _glapi_set_warning_func(warn_func);
+ _glapi_noop_enable_warnings(TRUE);
+}
diff --git a/xorg-server/hw/xwin/Makefile.am b/xorg-server/hw/xwin/Makefile.am index 8b1897235..8b6b6a06d 100644 --- a/xorg-server/hw/xwin/Makefile.am +++ b/xorg-server/hw/xwin/Makefile.am @@ -13,9 +13,10 @@ DEFS_CLIPBOARD = -DXWIN_CLIPBOARD endif if XWIN_GLX_WINDOWS -SRCS_GLX_WINDOWS = \ - winpriv.c +GLX_DIR = glx DEFS_GLX_WINDOWS = -DXWIN_GLX_WINDOWS +XWIN_GLX_LIBS = $(top_builddir)/hw/xwin/glx/libXwinGLX.la +XWIN_GLX_LINK_FLAGS = -lopengl32 endif if XWIN_MULTIWINDOW @@ -120,13 +121,13 @@ SRCS = InitInput.c \ winpriv.h \ winresource.h \ winwindow.h \ + windisplay.c \ XWin.rc \ $(top_srcdir)/Xext/dpmsstubs.c \ $(top_srcdir)/Xi/stubs.c \ $(top_srcdir)/mi/miinitext.c \ $(top_srcdir)/fb/fbcmap_mi.c \ $(SRCS_CLIPBOARD) \ - $(SRCS_GLX_WINDOWS) \ $(SRCS_MULTIWINDOW) \ $(SRCS_MULTIWINDOWEXTWM) \ $(SRCS_NATIVEGDI) \ @@ -147,14 +148,13 @@ XWin_SOURCES = $(SRCS) INCLUDES = -I$(top_srcdir)/miext/rootless -XWin_DEPENDENCIES = $(XWIN_LIBS) -XWin_LDADD = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS) +XWin_DEPENDENCIES = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) +XWin_LDADD = $(MULTIWINDOWEXTWM_LIBS) $(XWIN_GLX_LIBS) $(XWIN_GLX_LINK_FLAGS) $(XWIN_LIBS) $(MAIN_LIB) $(XSERVER_LIBS) $(XSERVER_SYS_LIBS) $(XWIN_SYS_LIBS) +XWin_LDFLAGS = -mwindows .rc.o: $(WINDRES) --use-temp-file -i $< --input-format=rc -o $@ -O coff -I $(top_builddir)/include -XWin_LDFLAGS = -mwindows -static - winprefsyacc.h: winprefsyacc.c winprefslex.c: winprefslex.l winprefsyacc.c winprefsyacc.h @@ -165,12 +165,8 @@ AM_YFLAGS = -d AM_LFLAGS = -i AM_CFLAGS = -DHAVE_XWIN_CONFIG_H $(DIX_CFLAGS) \ $(XWINMODULES_CFLAGS) \ - -DXFree86Server - -GLX_EXTRAS = \ - glx/glwindows.h \ - glx/glwrap.c \ - glx/indirect.c + -DXFree86Server \ + -I$(top_srcdir) MAN_SRCS = XWin.man.pre XWinrc.man.pre @@ -196,7 +192,6 @@ xwinconfig_DATA = system.XWinrc include $(top_srcdir)/cpprules.in EXTRA_DIST = \ - $(GLX_EXTRAS) \ $(MAN_SRCS) \ X.ico \ XWin.rc \ @@ -223,3 +218,6 @@ EXTRA_DIST = \ relink: rm -f XWin$(EXEEXT) && $(MAKE) XWin$(EXEEXT) + +SUBDIRS = $(GLX_DIR) . +DIST_SUBDIRS = glx . diff --git a/xorg-server/hw/xwin/XWin.rc b/xorg-server/hw/xwin/XWin.rc index 539bd0e4d..57e7478b6 100644 --- a/xorg-server/hw/xwin/XWin.rc +++ b/xorg-server/hw/xwin/XWin.rc @@ -1,108 +1,105 @@ -/* - *Copyright (C) 2002-2004 Harold L Hunt II All Rights Reserved. - *Copyright (C) 2008 Yaakov Selkowitz 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 HAROLD L HUNT II 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 names of the authors - *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 authors. - * - * Authors: Harold L Hunt II, Yaakov Selkowitz - */ - -#include <windows.h> -#include "winresource.h" -#include "xwin-config.h" -#include "version-config.h" - -/* - * Dialogs - */ - -/* About */ -ABOUT_BOX DIALOGEX 32, 32, 260, 105 -STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_TABSTOP | DS_CENTERMOUSE -CAPTION "About " XVENDORNAMESHORT -FONT 8, "MS Shell Dlg 2" -BEGIN - CONTROL IDI_XWIN, IDC_STATIC, "Static", SS_ICON, 8, 8, 32, 32 - LTEXT XVENDORNAMESHORT " X Server ", IDC_STATIC, 36, 8, 220, 8 - LTEXT VENDOR_MAN_VERSION, IDC_STATIC, 36, 18, 220, 8 - LTEXT BUILDERSTRING, IDC_STATIC, 36, 28, 220, 8 - LTEXT "This software is licensed under the terms of the MIT/X11 License.", IDC_STATIC, 36, 48, 220, 20 - CONTROL __VENDORDWEBSUPPORT__, ID_ABOUT_WEBSITE, "Button", - BS_OWNERDRAW | WS_TABSTOP, 36, 68, 68, 8 - DEFPUSHBUTTON "&OK", IDOK, 105, 85, 50, 15 -END - - -/* Depth change */ - -DEPTH_CHANGE_BOX DIALOGEX 32, 32, 180, 100 -STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | DS_CENTERMOUSE -FONT 8, "MS Shell Dlg 2" -CAPTION XVENDORNAMESHORT -BEGIN - DEFPUSHBUTTON "Dismiss", IDOK, 66, 80, 50, 14 - CTEXT XVENDORNAMESHORT, IDC_STATIC, 40, 12, 100, 8 - CTEXT "Disruptive screen configuration change.", IDC_STATIC, 7, 40, 166, 8 - CTEXT "Restore previous resolution to use " XVENDORNAMESHORT ".", IDC_STATIC, 7, 52, 166, 8 -END - - -/* Exit */ - -EXIT_DIALOG DIALOGEX 32, 32, 180, 78 -STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_TABSTOP | DS_CENTERMOUSE -FONT 8, "MS Shell Dlg 2" -CAPTION "Exit " XVENDORNAMESHORT "?" -BEGIN - PUSHBUTTON "E&xit", IDOK, 55, 56, 30, 14 - DEFPUSHBUTTON "&Cancel", IDCANCEL, 95, 56, 30, 14 - CTEXT "E&xiting will close all screens running on this display.", IDC_STATIC, 7, 12, 166, 8 - CTEXT "No information about connected clients available.", IDC_CLIENTS_CONNECTED, 7, 24, 166, 8 - CTEXT "Proceed with shutdown of this display/server?", IDC_STATIC, 7, 36, 166, 8 -END - - -/* - * Menus - */ - -IDM_TRAYICON_MENU MENU -BEGIN - POPUP "TRAYICON_MENU" - BEGIN - MENUITEM "&Hide Root Window", ID_APP_HIDE_ROOT - MENUITEM "&About...", ID_APP_ABOUT - MENUITEM SEPARATOR - MENUITEM "E&xit...", ID_APP_EXIT - END -END - - -/* - * Icons - */ - -IDI_XWIN ICON "X.ico" -CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "XWin.exe.manifest" +/*
+ *Copyright (C) 2002-2004 Harold L Hunt II All Rights Reserved.
+ *Copyright (C) 2008 Yaakov Selkowitz 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 HAROLD L HUNT II 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 names of the authors
+ *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 authors.
+ *
+ * Authors: Harold L Hunt II, Yaakov Selkowitz
+ */
+
+#include <windows.h>
+#include "winresource.h"
+#include "xwin-config.h"
+
+/*
+ * Dialogs
+ */
+
+/* About */
+ABOUT_BOX DIALOGEX 32, 32, 260, 95
+STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_TABSTOP | DS_CENTERMOUSE
+CAPTION "About "XVENDORNAMESHORT
+FONT 8, "MS Shell Dlg 2"
+BEGIN
+ CONTROL IDI_XWIN, IDC_STATIC, "Static", SS_ICON, 8, 8, 32, 32
+ LTEXT "VcXsrv X Server ", IDC_STATIC, 36, 8, 220, 8
+ LTEXT "http://www.hc-consult.be", IDC_STATIC, 36, 18, 220, 8
+ LTEXT "marc@hc-consult.be", IDC_STATIC, 36, 28, 220, 8
+ LTEXT "Version 1.7.99.6 (25 Jan 2010)", IDC_STATIC, 36, 38, 220, 8
+ DEFPUSHBUTTON "OK", IDOK, 105, 75, 50, 15
+END
+
+
+/* Depth change */
+
+DEPTH_CHANGE_BOX DIALOGEX 32, 32, 180, 100
+STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | DS_CENTERMOUSE
+FONT 8, "MS Shell Dlg 2"
+CAPTION XVENDORNAMESHORT
+BEGIN
+ DEFPUSHBUTTON "Dismiss", IDOK, 66, 80, 50, 14
+ CTEXT XVENDORNAMESHORT, IDC_STATIC, 40, 12, 100, 8
+ CTEXT "Disruptive screen configuration change.", IDC_STATIC, 7, 40, 166, 8
+ CTEXT "Restore previous resolution to use "XVENDORNAMESHORT".", IDC_STATIC, 7, 52, 166, 8
+END
+
+
+/* Exit */
+
+EXIT_DIALOG DIALOGEX 32, 32, 180, 78
+STYLE WS_POPUP | WS_CAPTION | WS_SYSMENU | WS_VISIBLE | WS_TABSTOP | DS_CENTERMOUSE
+FONT 8, "MS Shell Dlg 2"
+CAPTION "Exit "XVENDORNAMESHORT"?"
+BEGIN
+ PUSHBUTTON "E&xit", IDOK, 55, 56, 30, 14
+ DEFPUSHBUTTON "&Cancel", IDCANCEL, 95, 56, 30, 14
+ CTEXT "E&xiting will close all screens running on this display.", IDC_STATIC, 7, 12, 166, 8
+ CTEXT "No information about connected clients available.", IDC_CLIENTS_CONNECTED, 7, 24, 166, 8
+ CTEXT "Proceed with shutdown of this display/server?", IDC_STATIC, 7, 36, 166, 8
+END
+
+
+/*
+ * Menus
+ */
+
+IDM_TRAYICON_MENU MENU
+BEGIN
+ POPUP "TRAYICON_MENU"
+ BEGIN
+ MENUITEM "&Hide Root Window", ID_APP_HIDE_ROOT
+ MENUITEM "&About...", ID_APP_ABOUT
+ MENUITEM SEPARATOR
+ MENUITEM "E&xit...", ID_APP_EXIT
+ END
+END
+
+
+/*
+ * Icons
+ */
+
+IDI_XWIN ICON "X.ico"
+/* CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "XWin.exe.manifest"*/
diff --git a/xorg-server/hw/xwin/ddraw.h b/xorg-server/hw/xwin/ddraw.h deleted file mode 100644 index 2eb7c2674..000000000 --- a/xorg-server/hw/xwin/ddraw.h +++ /dev/null @@ -1,2106 +0,0 @@ -#ifndef __XWIN_DDRAW_H -#define __XWIN_DDRAW_H - -#include <winnt.h> -#include <wingdi.h> -#include <objbase.h> - -#if defined(NONAMELESSUNION) && !defined(DUMMYUNIONNAME1) -#define DUMMYUNIONNAME1 u1 -#endif - -#define ICOM_CALL_( xfn, p, args) (p)->lpVtbl->xfn args - -# ifdef UNICODE -# define WINELIB_NAME_AW(func) func##W -# else -# define WINELIB_NAME_AW(func) func##A -# endif /* UNICODE */ -#define DECL_WINELIB_TYPE_AW(type) typedef WINELIB_NAME_AW(type) type; - -#ifdef __cplusplus -extern "C" { -#endif /* defined(__cplusplus) */ - -#ifndef DIRECTDRAW_VERSION -#define DIRECTDRAW_VERSION 0x0700 -#endif /* DIRECTDRAW_VERSION */ - -/***************************************************************************** - * Predeclare the interfaces - */ -DEFINE_GUID( CLSID_DirectDraw, 0xD7B70EE0,0x4340,0x11CF,0xB0,0x63,0x00,0x20,0xAF,0xC2,0xCD,0x35 ); -DEFINE_GUID( CLSID_DirectDraw7, 0x3C305196,0x50DB,0x11D3,0x9C,0xFE,0x00,0xC0,0x4F,0xD9,0x30,0xC5 ); -DEFINE_GUID( CLSID_DirectDrawClipper, 0x593817A0,0x7DB3,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xb9,0x33,0x56 ); -DEFINE_GUID( IID_IDirectDraw, 0x6C14DB80,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); -DEFINE_GUID( IID_IDirectDraw2, 0xB3A6F3E0,0x2B43,0x11CF,0xA2,0xDE,0x00,0xAA,0x00,0xB9,0x33,0x56 ); -DEFINE_GUID( IID_IDirectDraw4, 0x9c59509a,0x39bd,0x11d1,0x8c,0x4a,0x00,0xc0,0x4f,0xd9,0x30,0xc5 ); -DEFINE_GUID( IID_IDirectDraw7, 0x15e65ec0,0x3b9c,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b ); -DEFINE_GUID( IID_IDirectDrawSurface, 0x6C14DB81,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); -DEFINE_GUID( IID_IDirectDrawSurface2, 0x57805885,0x6eec,0x11cf,0x94,0x41,0xa8,0x23,0x03,0xc1,0x0e,0x27 ); -DEFINE_GUID( IID_IDirectDrawSurface3, 0xDA044E00,0x69B2,0x11D0,0xA1,0xD5,0x00,0xAA,0x00,0xB8,0xDF,0xBB ); -DEFINE_GUID( IID_IDirectDrawSurface4, 0x0B2B8630,0xAD35,0x11D0,0x8E,0xA6,0x00,0x60,0x97,0x97,0xEA,0x5B ); -DEFINE_GUID( IID_IDirectDrawSurface7, 0x06675a80,0x3b9b,0x11d2,0xb9,0x2f,0x00,0x60,0x97,0x97,0xea,0x5b ); -DEFINE_GUID( IID_IDirectDrawPalette, 0x6C14DB84,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); -DEFINE_GUID( IID_IDirectDrawClipper, 0x6C14DB85,0xA733,0x11CE,0xA5,0x21,0x00,0x20,0xAF,0x0B,0xE5,0x60 ); -DEFINE_GUID( IID_IDirectDrawColorControl,0x4B9F0EE0,0x0D7E,0x11D0,0x9B,0x06,0x00,0xA0,0xC9,0x03,0xA3,0xB8 ); -DEFINE_GUID( IID_IDirectDrawGammaControl,0x69C11C3E,0xB46B,0x11D1,0xAD,0x7A,0x00,0xC0,0x4F,0xC2,0x9B,0x4E ); - -typedef struct IDirectDraw *LPDIRECTDRAW; -typedef struct IDirectDraw2 *LPDIRECTDRAW2; -typedef struct IDirectDraw4 *LPDIRECTDRAW4; -typedef struct IDirectDraw7 *LPDIRECTDRAW7; -typedef struct IDirectDrawClipper *LPDIRECTDRAWCLIPPER; -typedef struct IDirectDrawPalette *LPDIRECTDRAWPALETTE; -typedef struct IDirectDrawSurface *LPDIRECTDRAWSURFACE; -typedef struct IDirectDrawSurface2 *LPDIRECTDRAWSURFACE2; -typedef struct IDirectDrawSurface3 *LPDIRECTDRAWSURFACE3; -typedef struct IDirectDrawSurface4 *LPDIRECTDRAWSURFACE4; -typedef struct IDirectDrawSurface7 *LPDIRECTDRAWSURFACE7; -typedef struct IDirectDrawColorControl *LPDIRECTDRAWCOLORCONTROL; -typedef struct IDirectDrawGammaControl *LPDIRECTDRAWGAMMACONTROL; - - -#define DDENUMRET_CANCEL 0 -#define DDENUMRET_OK 1 - -#define DD_OK 0 - - -#define _FACDD 0x876 -#define MAKE_DDHRESULT( code ) MAKE_HRESULT( 1, _FACDD, code ) - -#define DDERR_ALREADYINITIALIZED MAKE_DDHRESULT( 5 ) -#define DDERR_CANNOTATTACHSURFACE MAKE_DDHRESULT( 10 ) -#define DDERR_CANNOTDETACHSURFACE MAKE_DDHRESULT( 20 ) -#define DDERR_CURRENTLYNOTAVAIL MAKE_DDHRESULT( 40 ) -#define DDERR_EXCEPTION MAKE_DDHRESULT( 55 ) -#define DDERR_GENERIC E_FAIL -#define DDERR_HEIGHTALIGN MAKE_DDHRESULT( 90 ) -#define DDERR_INCOMPATIBLEPRIMARY MAKE_DDHRESULT( 95 ) -#define DDERR_INVALIDCAPS MAKE_DDHRESULT( 100 ) -#define DDERR_INVALIDCLIPLIST MAKE_DDHRESULT( 110 ) -#define DDERR_INVALIDMODE MAKE_DDHRESULT( 120 ) -#define DDERR_INVALIDOBJECT MAKE_DDHRESULT( 130 ) -#define DDERR_INVALIDPARAMS E_INVALIDARG -#define DDERR_INVALIDPIXELFORMAT MAKE_DDHRESULT( 145 ) -#define DDERR_INVALIDRECT MAKE_DDHRESULT( 150 ) -#define DDERR_LOCKEDSURFACES MAKE_DDHRESULT( 160 ) -#define DDERR_NO3D MAKE_DDHRESULT( 170 ) -#define DDERR_NOALPHAHW MAKE_DDHRESULT( 180 ) -#define DDERR_NOSTEREOHARDWARE MAKE_DDHRESULT( 181 ) -#define DDERR_NOSURFACELEFT MAKE_DDHRESULT( 182 ) -#define DDERR_NOCLIPLIST MAKE_DDHRESULT( 205 ) -#define DDERR_NOCOLORCONVHW MAKE_DDHRESULT( 210 ) -#define DDERR_NOCOOPERATIVELEVELSET MAKE_DDHRESULT( 212 ) -#define DDERR_NOCOLORKEY MAKE_DDHRESULT( 215 ) -#define DDERR_NOCOLORKEYHW MAKE_DDHRESULT( 220 ) -#define DDERR_NODIRECTDRAWSUPPORT MAKE_DDHRESULT( 222 ) -#define DDERR_NOEXCLUSIVEMODE MAKE_DDHRESULT( 225 ) -#define DDERR_NOFLIPHW MAKE_DDHRESULT( 230 ) -#define DDERR_NOGDI MAKE_DDHRESULT( 240 ) -#define DDERR_NOMIRRORHW MAKE_DDHRESULT( 250 ) -#define DDERR_NOTFOUND MAKE_DDHRESULT( 255 ) -#define DDERR_NOOVERLAYHW MAKE_DDHRESULT( 260 ) -#define DDERR_OVERLAPPINGRECTS MAKE_DDHRESULT( 270 ) -#define DDERR_NORASTEROPHW MAKE_DDHRESULT( 280 ) -#define DDERR_NOROTATIONHW MAKE_DDHRESULT( 290 ) -#define DDERR_NOSTRETCHHW MAKE_DDHRESULT( 310 ) -#define DDERR_NOT4BITCOLOR MAKE_DDHRESULT( 316 ) -#define DDERR_NOT4BITCOLORINDEX MAKE_DDHRESULT( 317 ) -#define DDERR_NOT8BITCOLOR MAKE_DDHRESULT( 320 ) -#define DDERR_NOTEXTUREHW MAKE_DDHRESULT( 330 ) -#define DDERR_NOVSYNCHW MAKE_DDHRESULT( 335 ) -#define DDERR_NOZBUFFERHW MAKE_DDHRESULT( 340 ) -#define DDERR_NOZOVERLAYHW MAKE_DDHRESULT( 350 ) -#define DDERR_OUTOFCAPS MAKE_DDHRESULT( 360 ) -#define DDERR_OUTOFMEMORY E_OUTOFMEMORY -#define DDERR_OUTOFVIDEOMEMORY MAKE_DDHRESULT( 380 ) -#define DDERR_OVERLAYCANTCLIP MAKE_DDHRESULT( 382 ) -#define DDERR_OVERLAYCOLORKEYONLYONEACTIVE MAKE_DDHRESULT( 384 ) -#define DDERR_PALETTEBUSY MAKE_DDHRESULT( 387 ) -#define DDERR_COLORKEYNOTSET MAKE_DDHRESULT( 400 ) -#define DDERR_SURFACEALREADYATTACHED MAKE_DDHRESULT( 410 ) -#define DDERR_SURFACEALREADYDEPENDENT MAKE_DDHRESULT( 420 ) -#define DDERR_SURFACEBUSY MAKE_DDHRESULT( 430 ) -#define DDERR_CANTLOCKSURFACE MAKE_DDHRESULT( 435 ) -#define DDERR_SURFACEISOBSCURED MAKE_DDHRESULT( 440 ) -#define DDERR_SURFACELOST MAKE_DDHRESULT( 450 ) -#define DDERR_SURFACENOTATTACHED MAKE_DDHRESULT( 460 ) -#define DDERR_TOOBIGHEIGHT MAKE_DDHRESULT( 470 ) -#define DDERR_TOOBIGSIZE MAKE_DDHRESULT( 480 ) -#define DDERR_TOOBIGWIDTH MAKE_DDHRESULT( 490 ) -#define DDERR_UNSUPPORTED E_NOTIMPL -#define DDERR_UNSUPPORTEDFORMAT MAKE_DDHRESULT( 510 ) -#define DDERR_UNSUPPORTEDMASK MAKE_DDHRESULT( 520 ) -#define DDERR_INVALIDSTREAM MAKE_DDHRESULT( 521 ) -#define DDERR_VERTICALBLANKINPROGRESS MAKE_DDHRESULT( 537 ) -#define DDERR_WASSTILLDRAWING MAKE_DDHRESULT( 540 ) -#define DDERR_DDSCAPSCOMPLEXREQUIRED MAKE_DDHRESULT( 542 ) -#define DDERR_XALIGN MAKE_DDHRESULT( 560 ) -#define DDERR_INVALIDDIRECTDRAWGUID MAKE_DDHRESULT( 561 ) -#define DDERR_DIRECTDRAWALREADYCREATED MAKE_DDHRESULT( 562 ) -#define DDERR_NODIRECTDRAWHW MAKE_DDHRESULT( 563 ) -#define DDERR_PRIMARYSURFACEALREADYEXISTS MAKE_DDHRESULT( 564 ) -#define DDERR_NOEMULATION MAKE_DDHRESULT( 565 ) -#define DDERR_REGIONTOOSMALL MAKE_DDHRESULT( 566 ) -#define DDERR_CLIPPERISUSINGHWND MAKE_DDHRESULT( 567 ) -#define DDERR_NOCLIPPERATTACHED MAKE_DDHRESULT( 568 ) -#define DDERR_NOHWND MAKE_DDHRESULT( 569 ) -#define DDERR_HWNDSUBCLASSED MAKE_DDHRESULT( 570 ) -#define DDERR_HWNDALREADYSET MAKE_DDHRESULT( 571 ) -#define DDERR_NOPALETTEATTACHED MAKE_DDHRESULT( 572 ) -#define DDERR_NOPALETTEHW MAKE_DDHRESULT( 573 ) -#define DDERR_BLTFASTCANTCLIP MAKE_DDHRESULT( 574 ) -#define DDERR_NOBLTHW MAKE_DDHRESULT( 575 ) -#define DDERR_NODDROPSHW MAKE_DDHRESULT( 576 ) -#define DDERR_OVERLAYNOTVISIBLE MAKE_DDHRESULT( 577 ) -#define DDERR_NOOVERLAYDEST MAKE_DDHRESULT( 578 ) -#define DDERR_INVALIDPOSITION MAKE_DDHRESULT( 579 ) -#define DDERR_NOTAOVERLAYSURFACE MAKE_DDHRESULT( 580 ) -#define DDERR_EXCLUSIVEMODEALREADYSET MAKE_DDHRESULT( 581 ) -#define DDERR_NOTFLIPPABLE MAKE_DDHRESULT( 582 ) -#define DDERR_CANTDUPLICATE MAKE_DDHRESULT( 583 ) -#define DDERR_NOTLOCKED MAKE_DDHRESULT( 584 ) -#define DDERR_CANTCREATEDC MAKE_DDHRESULT( 585 ) -#define DDERR_NODC MAKE_DDHRESULT( 586 ) -#define DDERR_WRONGMODE MAKE_DDHRESULT( 587 ) -#define DDERR_IMPLICITLYCREATED MAKE_DDHRESULT( 588 ) -#define DDERR_NOTPALETTIZED MAKE_DDHRESULT( 589 ) -#define DDERR_UNSUPPORTEDMODE MAKE_DDHRESULT( 590 ) -#define DDERR_NOMIPMAPHW MAKE_DDHRESULT( 591 ) -#define DDERR_INVALIDSURFACETYPE MAKE_DDHRESULT( 592 ) -#define DDERR_NOOPTIMIZEHW MAKE_DDHRESULT( 600 ) -#define DDERR_NOTLOADED MAKE_DDHRESULT( 601 ) -#define DDERR_NOFOCUSWINDOW MAKE_DDHRESULT( 602 ) -#define DDERR_NOTONMIPMAPSUBLEVEL MAKE_DDHRESULT( 603 ) -#define DDERR_DCALREADYCREATED MAKE_DDHRESULT( 620 ) -#define DDERR_NONONLOCALVIDMEM MAKE_DDHRESULT( 630 ) -#define DDERR_CANTPAGELOCK MAKE_DDHRESULT( 640 ) -#define DDERR_CANTPAGEUNLOCK MAKE_DDHRESULT( 660 ) -#define DDERR_NOTPAGELOCKED MAKE_DDHRESULT( 680 ) -#define DDERR_MOREDATA MAKE_DDHRESULT( 690 ) -#define DDERR_EXPIRED MAKE_DDHRESULT( 691 ) -#define DDERR_TESTFINISHED MAKE_DDHRESULT( 692 ) -#define DDERR_NEWMODE MAKE_DDHRESULT( 693 ) -#define DDERR_D3DNOTINITIALIZED MAKE_DDHRESULT( 694 ) -#define DDERR_VIDEONOTACTIVE MAKE_DDHRESULT( 695 ) -#define DDERR_NOMONITORINFORMATION MAKE_DDHRESULT( 696 ) -#define DDERR_NODRIVERSUPPORT MAKE_DDHRESULT( 697 ) -#define DDERR_DEVICEDOESNTOWNSURFACE MAKE_DDHRESULT( 699 ) -#define DDERR_NOTINITIALIZED CO_E_NOTINITIALIZED - -/* dwFlags for Blt* */ -#define DDBLT_ALPHADEST 0x00000001 -#define DDBLT_ALPHADESTCONSTOVERRIDE 0x00000002 -#define DDBLT_ALPHADESTNEG 0x00000004 -#define DDBLT_ALPHADESTSURFACEOVERRIDE 0x00000008 -#define DDBLT_ALPHAEDGEBLEND 0x00000010 -#define DDBLT_ALPHASRC 0x00000020 -#define DDBLT_ALPHASRCCONSTOVERRIDE 0x00000040 -#define DDBLT_ALPHASRCNEG 0x00000080 -#define DDBLT_ALPHASRCSURFACEOVERRIDE 0x00000100 -#define DDBLT_ASYNC 0x00000200 -#define DDBLT_COLORFILL 0x00000400 -#define DDBLT_DDFX 0x00000800 -#define DDBLT_DDROPS 0x00001000 -#define DDBLT_KEYDEST 0x00002000 -#define DDBLT_KEYDESTOVERRIDE 0x00004000 -#define DDBLT_KEYSRC 0x00008000 -#define DDBLT_KEYSRCOVERRIDE 0x00010000 -#define DDBLT_ROP 0x00020000 -#define DDBLT_ROTATIONANGLE 0x00040000 -#define DDBLT_ZBUFFER 0x00080000 -#define DDBLT_ZBUFFERDESTCONSTOVERRIDE 0x00100000 -#define DDBLT_ZBUFFERDESTOVERRIDE 0x00200000 -#define DDBLT_ZBUFFERSRCCONSTOVERRIDE 0x00400000 -#define DDBLT_ZBUFFERSRCOVERRIDE 0x00800000 -#define DDBLT_WAIT 0x01000000 -#define DDBLT_DEPTHFILL 0x02000000 -#define DDBLT_DONOTWAIT 0x08000000 - -/* dwTrans for BltFast */ -#define DDBLTFAST_NOCOLORKEY 0x00000000 -#define DDBLTFAST_SRCCOLORKEY 0x00000001 -#define DDBLTFAST_DESTCOLORKEY 0x00000002 -#define DDBLTFAST_WAIT 0x00000010 -#define DDBLTFAST_DONOTWAIT 0x00000020 - -/* dwFlags for Flip */ -#define DDFLIP_WAIT 0x00000001 -#define DDFLIP_EVEN 0x00000002 /* only valid for overlay */ -#define DDFLIP_ODD 0x00000004 /* only valid for overlay */ -#define DDFLIP_NOVSYNC 0x00000008 -#define DDFLIP_STEREO 0x00000010 -#define DDFLIP_DONOTWAIT 0x00000020 - -/* dwFlags for GetBltStatus */ -#define DDGBS_CANBLT 0x00000001 -#define DDGBS_ISBLTDONE 0x00000002 - -/* dwFlags for IDirectDrawSurface7::GetFlipStatus */ -#define DDGFS_CANFLIP 1L -#define DDGFS_ISFLIPDONE 2L - -/* dwFlags for IDirectDrawSurface7::SetPrivateData */ -#define DDSPD_IUNKNOWNPTR 1L -#define DDSPD_VOLATILE 2L - -/* DDSCAPS.dwCaps */ -/* reserved1, was 3d capable */ -#define DDSCAPS_RESERVED1 0x00000001 -/* surface contains alpha information */ -#define DDSCAPS_ALPHA 0x00000002 -/* this surface is a backbuffer */ -#define DDSCAPS_BACKBUFFER 0x00000004 -/* complex surface structure */ -#define DDSCAPS_COMPLEX 0x00000008 -/* part of surface flipping structure */ -#define DDSCAPS_FLIP 0x00000010 -/* this surface is the frontbuffer surface */ -#define DDSCAPS_FRONTBUFFER 0x00000020 -/* this is a plain offscreen surface */ -#define DDSCAPS_OFFSCREENPLAIN 0x00000040 -/* overlay */ -#define DDSCAPS_OVERLAY 0x00000080 -/* palette objects can be created and attached to us */ -#define DDSCAPS_PALETTE 0x00000100 -/* primary surface (the one the user looks at currently)(right eye)*/ -#define DDSCAPS_PRIMARYSURFACE 0x00000200 -/* primary surface for left eye */ -#define DDSCAPS_PRIMARYSURFACELEFT 0x00000400 -/* surface exists in systemmemory */ -#define DDSCAPS_SYSTEMMEMORY 0x00000800 -/* surface can be used as a texture */ -#define DDSCAPS_TEXTURE 0x00001000 -/* surface may be destination for 3d rendering */ -#define DDSCAPS_3DDEVICE 0x00002000 -/* surface exists in videomemory */ -#define DDSCAPS_VIDEOMEMORY 0x00004000 -/* surface changes immediately visible */ -#define DDSCAPS_VISIBLE 0x00008000 -/* write only surface */ -#define DDSCAPS_WRITEONLY 0x00010000 -/* zbuffer surface */ -#define DDSCAPS_ZBUFFER 0x00020000 -/* has its own DC */ -#define DDSCAPS_OWNDC 0x00040000 -/* surface should be able to receive live video */ -#define DDSCAPS_LIVEVIDEO 0x00080000 -/* should be able to have a hw codec decompress stuff into it */ -#define DDSCAPS_HWCODEC 0x00100000 -/* mode X (320x200 or 320x240) surface */ -#define DDSCAPS_MODEX 0x00200000 -/* one mipmap surface (1 level) */ -#define DDSCAPS_MIPMAP 0x00400000 -#define DDSCAPS_RESERVED2 0x00800000 -/* memory allocation delayed until Load() */ -#define DDSCAPS_ALLOCONLOAD 0x04000000 -/* Indicates that the surface will receive data from a video port */ -#define DDSCAPS_VIDEOPORT 0x08000000 -/* surface is in local videomemory */ -#define DDSCAPS_LOCALVIDMEM 0x10000000 -/* surface is in nonlocal videomemory */ -#define DDSCAPS_NONLOCALVIDMEM 0x20000000 -/* surface is a standard VGA mode surface (NOT ModeX) */ -#define DDSCAPS_STANDARDVGAMODE 0x40000000 -/* optimized? surface */ -#define DDSCAPS_OPTIMIZED 0x80000000 - -typedef struct _DDSCAPS { - DWORD dwCaps; /* capabilities of surface wanted */ -} DDSCAPS,*LPDDSCAPS; - -/* DDSCAPS2.dwCaps2 */ -/* indicates the surface will receive data from a video port using - deinterlacing hardware. */ -#define DDSCAPS2_HARDWAREDEINTERLACE 0x00000002 -/* indicates the surface will be locked very frequently. */ -#define DDSCAPS2_HINTDYNAMIC 0x00000004 -/* indicates surface can be re-ordered or retiled on load() */ -#define DDSCAPS2_HINTSTATIC 0x00000008 -/* indicates surface to be managed by directdraw/direct3D */ -#define DDSCAPS2_TEXTUREMANAGE 0x00000010 -/* reserved bits */ -#define DDSCAPS2_RESERVED1 0x00000020 -#define DDSCAPS2_RESERVED2 0x00000040 -/* indicates surface will never be locked again */ -#define DDSCAPS2_OPAQUE 0x00000080 -/* set at CreateSurface() time to indicate antialising will be used */ -#define DDSCAPS2_HINTANTIALIASING 0x00000100 -/* set at CreateSurface() time to indicate cubic environment map */ -#define DDSCAPS2_CUBEMAP 0x00000200 -/* face flags for cube maps */ -#define DDSCAPS2_CUBEMAP_POSITIVEX 0x00000400 -#define DDSCAPS2_CUBEMAP_NEGATIVEX 0x00000800 -#define DDSCAPS2_CUBEMAP_POSITIVEY 0x00001000 -#define DDSCAPS2_CUBEMAP_NEGATIVEY 0x00002000 -#define DDSCAPS2_CUBEMAP_POSITIVEZ 0x00004000 -#define DDSCAPS2_CUBEMAP_NEGATIVEZ 0x00008000 -/* specifies all faces of a cube for CreateSurface() */ -#define DDSCAPS2_CUBEMAP_ALLFACES ( DDSCAPS2_CUBEMAP_POSITIVEX |\ - DDSCAPS2_CUBEMAP_NEGATIVEX |\ - DDSCAPS2_CUBEMAP_POSITIVEY |\ - DDSCAPS2_CUBEMAP_NEGATIVEY |\ - DDSCAPS2_CUBEMAP_POSITIVEZ |\ - DDSCAPS2_CUBEMAP_NEGATIVEZ ) -/* set for mipmap sublevels on DirectX7 and later. ignored by CreateSurface() */ -#define DDSCAPS2_MIPMAPSUBLEVEL 0x00010000 -/* indicates texture surface to be managed by Direct3D *only* */ -#define DDSCAPS2_D3DTEXTUREMANAGE 0x00020000 -/* indicates managed surface that can safely be lost */ -#define DDSCAPS2_DONOTPERSIST 0x00040000 -/* indicates surface is part of a stereo flipping chain */ -#define DDSCAPS2_STEREOSURFACELEFT 0x00080000 - -typedef struct _DDSCAPS2 { - DWORD dwCaps; /* capabilities of surface wanted */ - DWORD dwCaps2; /* additional capabilities */ - DWORD dwCaps3; /* reserved capabilities */ - DWORD dwCaps4; /* more reserved capabilities */ -} DDSCAPS2,*LPDDSCAPS2; - -#define DD_ROP_SPACE (256/32) /* space required to store ROP array */ - -typedef struct _DDCAPS_DX7 /* DirectX 7 version of caps struct */ -{ - DWORD dwSize; /* size of the DDDRIVERCAPS structure */ - DWORD dwCaps; /* driver specific capabilities */ - DWORD dwCaps2; /* more driver specific capabilites */ - DWORD dwCKeyCaps; /* color key capabilities of the surface */ - DWORD dwFXCaps; /* driver specific stretching and effects capabilites */ - DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */ - DWORD dwPalCaps; /* palette capabilities */ - DWORD dwSVCaps; /* stereo vision capabilities */ - DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */ - DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */ - DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */ - DWORD dwVidMemTotal; /* total amount of video memory */ - DWORD dwVidMemFree; /* amount of free video memory */ - DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */ - DWORD dwCurrVisibleOverlays; /* current number of visible overlays */ - DWORD dwNumFourCCCodes; /* number of four cc codes */ - DWORD dwAlignBoundarySrc; /* source rectangle alignment */ - DWORD dwAlignSizeSrc; /* source rectangle byte size */ - DWORD dwAlignBoundaryDest; /* dest rectangle alignment */ - DWORD dwAlignSizeDest; /* dest rectangle byte size */ - DWORD dwAlignStrideAlign; /* stride alignment */ - DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */ - DDSCAPS ddsOldCaps; /* old DDSCAPS - superceded for DirectX6+ */ - DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwReserved1; - DWORD dwReserved2; - DWORD dwReserved3; - DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */ - DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */ - DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */ - DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */ - DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */ - DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */ - DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */ - DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */ - DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */ - DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */ - DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */ - DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */ - DWORD dwMaxVideoPorts; /* maximum number of usable video ports */ - DWORD dwCurrVideoPorts; /* current number of video ports used */ - DWORD dwSVBCaps2; /* more driver specific capabilities for System->Vmem blts */ - DWORD dwNLVBCaps; /* driver specific capabilities for non-local->local vidmem blts */ - DWORD dwNLVBCaps2; /* more driver specific capabilities non-local->local vidmem blts */ - DWORD dwNLVBCKeyCaps; /* driver color key capabilities for non-local->local vidmem blts */ - DWORD dwNLVBFXCaps; /* driver FX capabilities for non-local->local blts */ - DWORD dwNLVBRops[DD_ROP_SPACE]; /* ROPS supported for non-local->local blts */ - DDSCAPS2 ddsCaps; /* surface capabilities */ -} DDCAPS_DX7,*LPDDCAPS_DX7; - -typedef struct _DDCAPS_DX6 /* DirectX 6 version of caps struct */ -{ - DWORD dwSize; /* size of the DDDRIVERCAPS structure */ - DWORD dwCaps; /* driver specific capabilities */ - DWORD dwCaps2; /* more driver specific capabilites */ - DWORD dwCKeyCaps; /* color key capabilities of the surface */ - DWORD dwFXCaps; /* driver specific stretching and effects capabilites */ - DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */ - DWORD dwPalCaps; /* palette capabilities */ - DWORD dwSVCaps; /* stereo vision capabilities */ - DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */ - DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */ - DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */ - DWORD dwVidMemTotal; /* total amount of video memory */ - DWORD dwVidMemFree; /* amount of free video memory */ - DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */ - DWORD dwCurrVisibleOverlays; /* current number of visible overlays */ - DWORD dwNumFourCCCodes; /* number of four cc codes */ - DWORD dwAlignBoundarySrc; /* source rectangle alignment */ - DWORD dwAlignSizeSrc; /* source rectangle byte size */ - DWORD dwAlignBoundaryDest; /* dest rectangle alignment */ - DWORD dwAlignSizeDest; /* dest rectangle byte size */ - DWORD dwAlignStrideAlign; /* stride alignment */ - DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */ - DDSCAPS ddsOldCaps; /* old DDSCAPS - superceded for DirectX6+ */ - DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwReserved1; - DWORD dwReserved2; - DWORD dwReserved3; - DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */ - DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */ - DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */ - DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */ - DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */ - DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */ - DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */ - DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */ - DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */ - DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */ - DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */ - DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */ - DWORD dwMaxVideoPorts; /* maximum number of usable video ports */ - DWORD dwCurrVideoPorts; /* current number of video ports used */ - DWORD dwSVBCaps2; /* more driver specific capabilities for System->Vmem blts */ - DWORD dwNLVBCaps; /* driver specific capabilities for non-local->local vidmem blts */ - DWORD dwNLVBCaps2; /* more driver specific capabilities non-local->local vidmem blts */ - DWORD dwNLVBCKeyCaps; /* driver color key capabilities for non-local->local vidmem blts */ - DWORD dwNLVBFXCaps; /* driver FX capabilities for non-local->local blts */ - DWORD dwNLVBRops[DD_ROP_SPACE]; /* ROPS supported for non-local->local blts */ - /* and one new member for DirectX 6 */ - DDSCAPS2 ddsCaps; /* surface capabilities */ -} DDCAPS_DX6,*LPDDCAPS_DX6; - -typedef struct _DDCAPS_DX5 /* DirectX5 version of caps struct */ -{ - DWORD dwSize; /* size of the DDDRIVERCAPS structure */ - DWORD dwCaps; /* driver specific capabilities */ - DWORD dwCaps2; /* more driver specific capabilites */ - DWORD dwCKeyCaps; /* color key capabilities of the surface */ - DWORD dwFXCaps; /* driver specific stretching and effects capabilites */ - DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */ - DWORD dwPalCaps; /* palette capabilities */ - DWORD dwSVCaps; /* stereo vision capabilities */ - DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */ - DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */ - DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */ - DWORD dwVidMemTotal; /* total amount of video memory */ - DWORD dwVidMemFree; /* amount of free video memory */ - DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */ - DWORD dwCurrVisibleOverlays; /* current number of visible overlays */ - DWORD dwNumFourCCCodes; /* number of four cc codes */ - DWORD dwAlignBoundarySrc; /* source rectangle alignment */ - DWORD dwAlignSizeSrc; /* source rectangle byte size */ - DWORD dwAlignBoundaryDest; /* dest rectangle alignment */ - DWORD dwAlignSizeDest; /* dest rectangle byte size */ - DWORD dwAlignStrideAlign; /* stride alignment */ - DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */ - DDSCAPS ddsCaps; /* DDSCAPS structure has all the general capabilities */ - DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwReserved1; - DWORD dwReserved2; - DWORD dwReserved3; - DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */ - DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */ - DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */ - DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */ - DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */ - DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */ - DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */ - DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */ - DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */ - DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */ - DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */ - DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */ - /* the following are the new DirectX 5 members */ - DWORD dwMaxVideoPorts; /* maximum number of usable video ports */ - DWORD dwCurrVideoPorts; /* current number of video ports used */ - DWORD dwSVBCaps2; /* more driver specific capabilities for System->Vmem blts */ - DWORD dwNLVBCaps; /* driver specific capabilities for non-local->local vidmem blts */ - DWORD dwNLVBCaps2; /* more driver specific capabilities non-local->local vidmem blts */ - DWORD dwNLVBCKeyCaps; /* driver color key capabilities for non-local->local vidmem blts */ - DWORD dwNLVBFXCaps; /* driver FX capabilities for non-local->local blts */ - DWORD dwNLVBRops[DD_ROP_SPACE]; /* ROPS supported for non-local->local blts */ -} DDCAPS_DX5,*LPDDCAPS_DX5; - -typedef struct _DDCAPS_DX3 /* DirectX3 version of caps struct */ -{ - DWORD dwSize; /* size of the DDDRIVERCAPS structure */ - DWORD dwCaps; /* driver specific capabilities */ - DWORD dwCaps2; /* more driver specific capabilites */ - DWORD dwCKeyCaps; /* color key capabilities of the surface */ - DWORD dwFXCaps; /* driver specific stretching and effects capabilites */ - DWORD dwFXAlphaCaps; /* alpha driver specific capabilities */ - DWORD dwPalCaps; /* palette capabilities */ - DWORD dwSVCaps; /* stereo vision capabilities */ - DWORD dwAlphaBltConstBitDepths; /* DDBD_2,4,8 */ - DWORD dwAlphaBltPixelBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwAlphaBltSurfaceBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwAlphaOverlayConstBitDepths; /* DDBD_2,4,8 */ - DWORD dwAlphaOverlayPixelBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwAlphaOverlaySurfaceBitDepths; /* DDBD_1,2,4,8 */ - DWORD dwZBufferBitDepths; /* DDBD_8,16,24,32 */ - DWORD dwVidMemTotal; /* total amount of video memory */ - DWORD dwVidMemFree; /* amount of free video memory */ - DWORD dwMaxVisibleOverlays; /* maximum number of visible overlays */ - DWORD dwCurrVisibleOverlays; /* current number of visible overlays */ - DWORD dwNumFourCCCodes; /* number of four cc codes */ - DWORD dwAlignBoundarySrc; /* source rectangle alignment */ - DWORD dwAlignSizeSrc; /* source rectangle byte size */ - DWORD dwAlignBoundaryDest; /* dest rectangle alignment */ - DWORD dwAlignSizeDest; /* dest rectangle byte size */ - DWORD dwAlignStrideAlign; /* stride alignment */ - DWORD dwRops[DD_ROP_SPACE]; /* ROPS supported */ - DDSCAPS ddsCaps; /* DDSCAPS structure has all the general capabilities */ - DWORD dwMinOverlayStretch; /* minimum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMaxOverlayStretch; /* maximum overlay stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMinLiveVideoStretch; /* minimum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMaxLiveVideoStretch; /* maximum live video stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMinHwCodecStretch; /* minimum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwMaxHwCodecStretch; /* maximum hardware codec stretch factor multiplied by 1000, eg 1000 == 1.0, 1300 == 1.3 */ - DWORD dwReserved1; - DWORD dwReserved2; - DWORD dwReserved3; - DWORD dwSVBCaps; /* driver specific capabilities for System->Vmem blts */ - DWORD dwSVBCKeyCaps; /* driver color key capabilities for System->Vmem blts */ - DWORD dwSVBFXCaps; /* driver FX capabilities for System->Vmem blts */ - DWORD dwSVBRops[DD_ROP_SPACE];/* ROPS supported for System->Vmem blts */ - DWORD dwVSBCaps; /* driver specific capabilities for Vmem->System blts */ - DWORD dwVSBCKeyCaps; /* driver color key capabilities for Vmem->System blts */ - DWORD dwVSBFXCaps; /* driver FX capabilities for Vmem->System blts */ - DWORD dwVSBRops[DD_ROP_SPACE];/* ROPS supported for Vmem->System blts */ - DWORD dwSSBCaps; /* driver specific capabilities for System->System blts */ - DWORD dwSSBCKeyCaps; /* driver color key capabilities for System->System blts */ - DWORD dwSSBFXCaps; /* driver FX capabilities for System->System blts */ - DWORD dwSSBRops[DD_ROP_SPACE];/* ROPS supported for System->System blts */ - DWORD dwReserved4; - DWORD dwReserved5; - DWORD dwReserved6; -} DDCAPS_DX3,*LPDDCAPS_DX3; - -/* set caps struct according to DIRECTDRAW_VERSION */ - -#if DIRECTDRAW_VERSION <= 0x300 -typedef DDCAPS_DX3 DDCAPS; -#elif DIRECTDRAW_VERSION <= 0x500 -typedef DDCAPS_DX5 DDCAPS; -#elif DIRECTDRAW_VERSION <= 0x600 -typedef DDCAPS_DX6 DDCAPS; -#else -typedef DDCAPS_DX7 DDCAPS; -#endif - -typedef DDCAPS *LPDDCAPS; - -/* DDCAPS.dwCaps */ -#define DDCAPS_3D 0x00000001 -#define DDCAPS_ALIGNBOUNDARYDEST 0x00000002 -#define DDCAPS_ALIGNSIZEDEST 0x00000004 -#define DDCAPS_ALIGNBOUNDARYSRC 0x00000008 -#define DDCAPS_ALIGNSIZESRC 0x00000010 -#define DDCAPS_ALIGNSTRIDE 0x00000020 -#define DDCAPS_BLT 0x00000040 -#define DDCAPS_BLTQUEUE 0x00000080 -#define DDCAPS_BLTFOURCC 0x00000100 -#define DDCAPS_BLTSTRETCH 0x00000200 -#define DDCAPS_GDI 0x00000400 -#define DDCAPS_OVERLAY 0x00000800 -#define DDCAPS_OVERLAYCANTCLIP 0x00001000 -#define DDCAPS_OVERLAYFOURCC 0x00002000 -#define DDCAPS_OVERLAYSTRETCH 0x00004000 -#define DDCAPS_PALETTE 0x00008000 -#define DDCAPS_PALETTEVSYNC 0x00010000 -#define DDCAPS_READSCANLINE 0x00020000 -#define DDCAPS_STEREOVIEW 0x00040000 -#define DDCAPS_VBI 0x00080000 -#define DDCAPS_ZBLTS 0x00100000 -#define DDCAPS_ZOVERLAYS 0x00200000 -#define DDCAPS_COLORKEY 0x00400000 -#define DDCAPS_ALPHA 0x00800000 -#define DDCAPS_COLORKEYHWASSIST 0x01000000 -#define DDCAPS_NOHARDWARE 0x02000000 -#define DDCAPS_BLTCOLORFILL 0x04000000 -#define DDCAPS_BANKSWITCHED 0x08000000 -#define DDCAPS_BLTDEPTHFILL 0x10000000 -#define DDCAPS_CANCLIP 0x20000000 -#define DDCAPS_CANCLIPSTRETCHED 0x40000000 -#define DDCAPS_CANBLTSYSMEM 0x80000000 - -/* DDCAPS.dwCaps2 */ -#define DDCAPS2_CERTIFIED 0x00000001 -#define DDCAPS2_NO2DDURING3DSCENE 0x00000002 -#define DDCAPS2_VIDEOPORT 0x00000004 -#define DDCAPS2_AUTOFLIPOVERLAY 0x00000008 -#define DDCAPS2_CANBOBINTERLEAVED 0x00000010 -#define DDCAPS2_CANBOBNONINTERLEAVED 0x00000020 -#define DDCAPS2_COLORCONTROLOVERLAY 0x00000040 -#define DDCAPS2_COLORCONTROLPRIMARY 0x00000080 -#define DDCAPS2_CANDROPZ16BIT 0x00000100 -#define DDCAPS2_NONLOCALVIDMEM 0x00000200 -#define DDCAPS2_NONLOCALVIDMEMCAPS 0x00000400 -#define DDCAPS2_NOPAGELOCKREQUIRED 0x00000800 -#define DDCAPS2_WIDESURFACES 0x00001000 -#define DDCAPS2_CANFLIPODDEVEN 0x00002000 -#define DDCAPS2_CANBOBHARDWARE 0x00004000 -#define DDCAPS2_COPYFOURCC 0x00008000 -#define DDCAPS2_PRIMARYGAMMA 0x00020000 -#define DDCAPS2_CANRENDERWINDOWED 0x00080000 -#define DDCAPS2_CANCALIBRATEGAMMA 0x00100000 -#define DDCAPS2_FLIPINTERVAL 0x00200000 -#define DDCAPS2_FLIPNOVSYNC 0x00400000 -#define DDCAPS2_CANMANAGETEXTURE 0x00800000 -#define DDCAPS2_TEXMANINNONLOCALVIDMEM 0x01000000 -#define DDCAPS2_STEREO 0x02000000 -#define DDCAPS2_SYSTONONLOCAL_AS_SYSTOLOCAL 0x04000000 - - -/* Set/Get Colour Key Flags */ -#define DDCKEY_COLORSPACE 0x00000001 /* Struct is single colour space */ -#define DDCKEY_DESTBLT 0x00000002 /* To be used as dest for blt */ -#define DDCKEY_DESTOVERLAY 0x00000004 /* To be used as dest for CK overlays */ -#define DDCKEY_SRCBLT 0x00000008 /* To be used as src for blt */ -#define DDCKEY_SRCOVERLAY 0x00000010 /* To be used as src for CK overlays */ - -typedef struct _DDCOLORKEY -{ - DWORD dwColorSpaceLowValue;/* low boundary of color space that is to - * be treated as Color Key, inclusive - */ - DWORD dwColorSpaceHighValue;/* high boundary of color space that is - * to be treated as Color Key, inclusive - */ -} DDCOLORKEY,*LPDDCOLORKEY; - -/* ddCKEYCAPS bits */ -#define DDCKEYCAPS_DESTBLT 0x00000001 -#define DDCKEYCAPS_DESTBLTCLRSPACE 0x00000002 -#define DDCKEYCAPS_DESTBLTCLRSPACEYUV 0x00000004 -#define DDCKEYCAPS_DESTBLTYUV 0x00000008 -#define DDCKEYCAPS_DESTOVERLAY 0x00000010 -#define DDCKEYCAPS_DESTOVERLAYCLRSPACE 0x00000020 -#define DDCKEYCAPS_DESTOVERLAYCLRSPACEYUV 0x00000040 -#define DDCKEYCAPS_DESTOVERLAYONEACTIVE 0x00000080 -#define DDCKEYCAPS_DESTOVERLAYYUV 0x00000100 -#define DDCKEYCAPS_SRCBLT 0x00000200 -#define DDCKEYCAPS_SRCBLTCLRSPACE 0x00000400 -#define DDCKEYCAPS_SRCBLTCLRSPACEYUV 0x00000800 -#define DDCKEYCAPS_SRCBLTYUV 0x00001000 -#define DDCKEYCAPS_SRCOVERLAY 0x00002000 -#define DDCKEYCAPS_SRCOVERLAYCLRSPACE 0x00004000 -#define DDCKEYCAPS_SRCOVERLAYCLRSPACEYUV 0x00008000 -#define DDCKEYCAPS_SRCOVERLAYONEACTIVE 0x00010000 -#define DDCKEYCAPS_SRCOVERLAYYUV 0x00020000 -#define DDCKEYCAPS_NOCOSTOVERLAY 0x00040000 - -typedef struct _DDPIXELFORMAT { - DWORD dwSize; /* 0: size of structure */ - DWORD dwFlags; /* 4: pixel format flags */ - DWORD dwFourCC; /* 8: (FOURCC code) */ - union { - DWORD dwRGBBitCount; /* C: how many bits per pixel */ - DWORD dwYUVBitCount; /* C: how many bits per pixel */ - DWORD dwZBufferBitDepth; /* C: how many bits for z buffers */ - DWORD dwAlphaBitDepth; /* C: how many bits for alpha channels*/ - DWORD dwLuminanceBitCount; - DWORD dwBumpBitCount; - } DUMMYUNIONNAME1; - union { - DWORD dwRBitMask; /* 10: mask for red bit*/ - DWORD dwYBitMask; /* 10: mask for Y bits*/ - DWORD dwStencilBitDepth; - DWORD dwLuminanceBitMask; - DWORD dwBumpDuBitMask; - } DUMMYUNIONNAME2; - union { - DWORD dwGBitMask; /* 14: mask for green bits*/ - DWORD dwUBitMask; /* 14: mask for U bits*/ - DWORD dwZBitMask; - DWORD dwBumpDvBitMask; - } DUMMYUNIONNAME3; - union { - DWORD dwBBitMask; /* 18: mask for blue bits*/ - DWORD dwVBitMask; /* 18: mask for V bits*/ - DWORD dwStencilBitMask; - DWORD dwBumpLuminanceBitMask; - } DUMMYUNIONNAME4; - union { - DWORD dwRGBAlphaBitMask; /* 1C: mask for alpha channel */ - DWORD dwYUVAlphaBitMask; /* 1C: mask for alpha channel */ - DWORD dwLuminanceAlphaBitMask; - DWORD dwRGBZBitMask; /* 1C: mask for Z channel */ - DWORD dwYUVZBitMask; /* 1C: mask for Z channel */ - } DUMMYUNIONNAME5; - /* 20: next structure */ -} DDPIXELFORMAT,*LPDDPIXELFORMAT; - -/* DDCAPS.dwFXCaps */ -#define DDFXCAPS_BLTALPHA 0x00000001 -#define DDFXCAPS_OVERLAYALPHA 0x00000004 -#define DDFXCAPS_BLTARITHSTRETCHYN 0x00000010 -#define DDFXCAPS_BLTARITHSTRETCHY 0x00000020 -#define DDFXCAPS_BLTMIRRORLEFTRIGHT 0x00000040 -#define DDFXCAPS_BLTMIRRORUPDOWN 0x00000080 -#define DDFXCAPS_BLTROTATION 0x00000100 -#define DDFXCAPS_BLTROTATION90 0x00000200 -#define DDFXCAPS_BLTSHRINKX 0x00000400 -#define DDFXCAPS_BLTSHRINKXN 0x00000800 -#define DDFXCAPS_BLTSHRINKY 0x00001000 -#define DDFXCAPS_BLTSHRINKYN 0x00002000 -#define DDFXCAPS_BLTSTRETCHX 0x00004000 -#define DDFXCAPS_BLTSTRETCHXN 0x00008000 -#define DDFXCAPS_BLTSTRETCHY 0x00010000 -#define DDFXCAPS_BLTSTRETCHYN 0x00020000 -#define DDFXCAPS_OVERLAYARITHSTRETCHY 0x00040000 -#define DDFXCAPS_OVERLAYARITHSTRETCHYN 0x00000008 -#define DDFXCAPS_OVERLAYSHRINKX 0x00080000 -#define DDFXCAPS_OVERLAYSHRINKXN 0x00100000 -#define DDFXCAPS_OVERLAYSHRINKY 0x00200000 -#define DDFXCAPS_OVERLAYSHRINKYN 0x00400000 -#define DDFXCAPS_OVERLAYSTRETCHX 0x00800000 -#define DDFXCAPS_OVERLAYSTRETCHXN 0x01000000 -#define DDFXCAPS_OVERLAYSTRETCHY 0x02000000 -#define DDFXCAPS_OVERLAYSTRETCHYN 0x04000000 -#define DDFXCAPS_OVERLAYMIRRORLEFTRIGHT 0x08000000 -#define DDFXCAPS_OVERLAYMIRRORUPDOWN 0x10000000 - -#define DDFXCAPS_OVERLAYFILTER DDFXCAPS_OVERLAYARITHSTRETCHY - -/* DDCAPS.dwFXAlphaCaps */ -#define DDFXALPHACAPS_BLTALPHAEDGEBLEND 0x00000001 -#define DDFXALPHACAPS_BLTALPHAPIXELS 0x00000002 -#define DDFXALPHACAPS_BLTALPHAPIXELSNEG 0x00000004 -#define DDFXALPHACAPS_BLTALPHASURFACES 0x00000008 -#define DDFXALPHACAPS_BLTALPHASURFACESNEG 0x00000010 -#define DDFXALPHACAPS_OVERLAYALPHAEDGEBLEND 0x00000020 -#define DDFXALPHACAPS_OVERLAYALPHAPIXELS 0x00000040 -#define DDFXALPHACAPS_OVERLAYALPHAPIXELSNEG 0x00000080 -#define DDFXALPHACAPS_OVERLAYALPHASURFACES 0x00000100 -#define DDFXALPHACAPS_OVERLAYALPHASURFACESNEG 0x00000200 - -/* DDCAPS.dwPalCaps */ -#define DDPCAPS_4BIT 0x00000001 -#define DDPCAPS_8BITENTRIES 0x00000002 -#define DDPCAPS_8BIT 0x00000004 -#define DDPCAPS_INITIALIZE 0x00000008 -#define DDPCAPS_PRIMARYSURFACE 0x00000010 -#define DDPCAPS_PRIMARYSURFACELEFT 0x00000020 -#define DDPCAPS_ALLOW256 0x00000040 -#define DDPCAPS_VSYNC 0x00000080 -#define DDPCAPS_1BIT 0x00000100 -#define DDPCAPS_2BIT 0x00000200 -#define DDPCAPS_ALPHA 0x00000400 - -/* DDCAPS.dwSVCaps */ -/* the first 4 of these are now obsolete */ -#if DIRECTDRAW_VERSION >= 0x700 /* FIXME: I'm not sure when this switch occured */ -#define DDSVCAPS_RESERVED1 0x00000001 -#define DDSVCAPS_RESERVED2 0x00000002 -#define DDSVCAPS_RESERVED3 0x00000004 -#define DDSVCAPS_RESERVED4 0x00000008 -#else -#define DDSVCAPS_ENIGMA 0x00000001 -#define DDSVCAPS_FLICKER 0x00000002 -#define DDSVCAPS_REDBLUE 0x00000004 -#define DDSVCAPS_SPLIT 0x00000008 -#endif -#define DDSVCAPS_STEREOSEQUENTIAL 0x00000010 - -/* BitDepths */ -#define DDBD_1 0x00004000 -#define DDBD_2 0x00002000 -#define DDBD_4 0x00001000 -#define DDBD_8 0x00000800 -#define DDBD_16 0x00000400 -#define DDBD_24 0x00000200 -#define DDBD_32 0x00000100 - -/* DDOVERLAYFX.dwDDFX */ -#define DDOVERFX_ARITHSTRETCHY 0x00000001 -#define DDOVERFX_MIRRORLEFTRIGHT 0x00000002 -#define DDOVERFX_MIRRORUPDOWN 0x00000004 - -/* UpdateOverlay flags */ -#define DDOVER_ALPHADEST 0x00000001 -#define DDOVER_ALPHADESTCONSTOVERRIDE 0x00000002 -#define DDOVER_ALPHADESTNEG 0x00000004 -#define DDOVER_ALPHADESTSURFACEOVERRIDE 0x00000008 -#define DDOVER_ALPHAEDGEBLEND 0x00000010 -#define DDOVER_ALPHASRC 0x00000020 -#define DDOVER_ALPHASRCCONSTOVERRIDE 0x00000040 -#define DDOVER_ALPHASRCNEG 0x00000080 -#define DDOVER_ALPHASRCSURFACEOVERRIDE 0x00000100 -#define DDOVER_HIDE 0x00000200 -#define DDOVER_KEYDEST 0x00000400 -#define DDOVER_KEYDESTOVERRIDE 0x00000800 -#define DDOVER_KEYSRC 0x00001000 -#define DDOVER_KEYSRCOVERRIDE 0x00002000 -#define DDOVER_SHOW 0x00004000 -#define DDOVER_ADDDIRTYRECT 0x00008000 -#define DDOVER_REFRESHDIRTYRECTS 0x00010000 -#define DDOVER_REFRESHALL 0x00020000 -#define DDOVER_DDFX 0x00080000 -#define DDOVER_AUTOFLIP 0x00100000 -#define DDOVER_BOB 0x00200000 -#define DDOVER_OVERRIDEBOBWEAVE 0x00400000 -#define DDOVER_INTERLEAVED 0x00800000 - -/* DDCOLORKEY.dwFlags */ -#define DDPF_ALPHAPIXELS 0x00000001 -#define DDPF_ALPHA 0x00000002 -#define DDPF_FOURCC 0x00000004 -#define DDPF_PALETTEINDEXED4 0x00000008 -#define DDPF_PALETTEINDEXEDTO8 0x00000010 -#define DDPF_PALETTEINDEXED8 0x00000020 -#define DDPF_RGB 0x00000040 -#define DDPF_COMPRESSED 0x00000080 -#define DDPF_RGBTOYUV 0x00000100 -#define DDPF_YUV 0x00000200 -#define DDPF_ZBUFFER 0x00000400 -#define DDPF_PALETTEINDEXED1 0x00000800 -#define DDPF_PALETTEINDEXED2 0x00001000 -#define DDPF_ZPIXELS 0x00002000 -#define DDPF_STENCILBUFFER 0x00004000 -#define DDPF_ALPHAPREMULT 0x00008000 -#define DDPF_LUMINANCE 0x00020000 -#define DDPF_BUMPLUMINANCE 0x00040000 -#define DDPF_BUMPDUDV 0x00080000 - -/* SetCooperativeLevel dwFlags */ -#define DDSCL_FULLSCREEN 0x00000001 -#define DDSCL_ALLOWREBOOT 0x00000002 -#define DDSCL_NOWINDOWCHANGES 0x00000004 -#define DDSCL_NORMAL 0x00000008 -#define DDSCL_EXCLUSIVE 0x00000010 -#define DDSCL_ALLOWMODEX 0x00000040 -#define DDSCL_SETFOCUSWINDOW 0x00000080 -#define DDSCL_SETDEVICEWINDOW 0x00000100 -#define DDSCL_CREATEDEVICEWINDOW 0x00000200 -#define DDSCL_MULTITHREADED 0x00000400 -#define DDSCL_FPUSETUP 0x00000800 -#define DDSCL_FPUPRESERVE 0x00001000 - - -/* DDSURFACEDESC.dwFlags */ -#define DDSD_CAPS 0x00000001 -#define DDSD_HEIGHT 0x00000002 -#define DDSD_WIDTH 0x00000004 -#define DDSD_PITCH 0x00000008 -#define DDSD_BACKBUFFERCOUNT 0x00000020 -#define DDSD_ZBUFFERBITDEPTH 0x00000040 -#define DDSD_ALPHABITDEPTH 0x00000080 -#define DDSD_LPSURFACE 0x00000800 -#define DDSD_PIXELFORMAT 0x00001000 -#define DDSD_CKDESTOVERLAY 0x00002000 -#define DDSD_CKDESTBLT 0x00004000 -#define DDSD_CKSRCOVERLAY 0x00008000 -#define DDSD_CKSRCBLT 0x00010000 -#define DDSD_MIPMAPCOUNT 0x00020000 -#define DDSD_REFRESHRATE 0x00040000 -#define DDSD_LINEARSIZE 0x00080000 -#define DDSD_TEXTURESTAGE 0x00100000 -#define DDSD_FVF 0x00200000 -#define DDSD_SRCVBHANDLE 0x00400000 -#define DDSD_ALL 0x007ff9ee - -/* EnumSurfaces flags */ -#define DDENUMSURFACES_ALL 0x00000001 -#define DDENUMSURFACES_MATCH 0x00000002 -#define DDENUMSURFACES_NOMATCH 0x00000004 -#define DDENUMSURFACES_CANBECREATED 0x00000008 -#define DDENUMSURFACES_DOESEXIST 0x00000010 - -/* SetDisplayMode flags */ -#define DDSDM_STANDARDVGAMODE 0x00000001 - -/* EnumDisplayModes flags */ -#define DDEDM_REFRESHRATES 0x00000001 -#define DDEDM_STANDARDVGAMODES 0x00000002 - -/* WaitForVerticalDisplay flags */ - -#define DDWAITVB_BLOCKBEGIN 0x00000001 -#define DDWAITVB_BLOCKBEGINEVENT 0x00000002 -#define DDWAITVB_BLOCKEND 0x00000004 - -typedef struct _DDSURFACEDESC -{ - DWORD dwSize; /* 0: size of the DDSURFACEDESC structure*/ - DWORD dwFlags; /* 4: determines what fields are valid*/ - DWORD dwHeight; /* 8: height of surface to be created*/ - DWORD dwWidth; /* C: width of input surface*/ - union { - LONG lPitch; /* 10: distance to start of next line (return value only)*/ - DWORD dwLinearSize; - } DUMMYUNIONNAME1; - DWORD dwBackBufferCount;/* 14: number of back buffers requested*/ - union { - DWORD dwMipMapCount;/* 18:number of mip-map levels requested*/ - DWORD dwZBufferBitDepth;/*18: depth of Z buffer requested*/ - DWORD dwRefreshRate;/* 18:refresh rate (used when display mode is described)*/ - } DUMMYUNIONNAME2; - DWORD dwAlphaBitDepth;/* 1C:depth of alpha buffer requested*/ - DWORD dwReserved; /* 20:reserved*/ - LPVOID lpSurface; /* 24:pointer to the associated surface memory*/ - DDCOLORKEY ddckCKDestOverlay;/* 28: CK for dest overlay use*/ - DDCOLORKEY ddckCKDestBlt; /* 30: CK for destination blt use*/ - DDCOLORKEY ddckCKSrcOverlay;/* 38: CK for source overlay use*/ - DDCOLORKEY ddckCKSrcBlt; /* 40: CK for source blt use*/ - DDPIXELFORMAT ddpfPixelFormat;/* 48: pixel format description of the surface*/ - DDSCAPS ddsCaps; /* 68: direct draw surface caps */ -} DDSURFACEDESC,*LPDDSURFACEDESC; - -typedef struct _DDSURFACEDESC2 -{ - DWORD dwSize; /* 0: size of the DDSURFACEDESC structure*/ - DWORD dwFlags; /* 4: determines what fields are valid*/ - DWORD dwHeight; /* 8: height of surface to be created*/ - DWORD dwWidth; /* C: width of input surface*/ - union { - LONG lPitch; /*10: distance to start of next line (return value only)*/ - DWORD dwLinearSize; /*10: formless late-allocated optimized surface size */ - } DUMMYUNIONNAME1; - DWORD dwBackBufferCount;/* 14: number of back buffers requested*/ - union { - DWORD dwMipMapCount;/* 18:number of mip-map levels requested*/ - DWORD dwRefreshRate;/* 18:refresh rate (used when display mode is described)*/ - DWORD dwSrcVBHandle;/* 18:source used in VB::Optimize */ - } DUMMYUNIONNAME2; - DWORD dwAlphaBitDepth;/* 1C:depth of alpha buffer requested*/ - DWORD dwReserved; /* 20:reserved*/ - LPVOID lpSurface; /* 24:pointer to the associated surface memory*/ - union { - DDCOLORKEY ddckCKDestOverlay; /* 28: CK for dest overlay use*/ - DWORD dwEmptyFaceColor; /* 28: color for empty cubemap faces */ - } DUMMYUNIONNAME3; - DDCOLORKEY ddckCKDestBlt; /* 30: CK for destination blt use*/ - DDCOLORKEY ddckCKSrcOverlay;/* 38: CK for source overlay use*/ - DDCOLORKEY ddckCKSrcBlt; /* 40: CK for source blt use*/ - - union { - DDPIXELFORMAT ddpfPixelFormat;/* 48: pixel format description of the surface*/ - DWORD dwFVF; /* 48: vertex format description of vertex buffers */ - } DUMMYUNIONNAME4; - DDSCAPS2 ddsCaps; /* 68: DDraw surface caps */ - DWORD dwTextureStage; /* 78: stage in multitexture cascade */ -} DDSURFACEDESC2,*LPDDSURFACEDESC2; - -/* DDCOLORCONTROL.dwFlags */ -#define DDCOLOR_BRIGHTNESS 0x00000001 -#define DDCOLOR_CONTRAST 0x00000002 -#define DDCOLOR_HUE 0x00000004 -#define DDCOLOR_SATURATION 0x00000008 -#define DDCOLOR_SHARPNESS 0x00000010 -#define DDCOLOR_GAMMA 0x00000020 -#define DDCOLOR_COLORENABLE 0x00000040 - -typedef struct { - DWORD dwSize; - DWORD dwFlags; - LONG lBrightness; - LONG lContrast; - LONG lHue; - LONG lSaturation; - LONG lSharpness; - LONG lGamma; - LONG lColorEnable; - DWORD dwReserved1; -} DDCOLORCONTROL,*LPDDCOLORCONTROL; - -typedef struct { - WORD red[256]; - WORD green[256]; - WORD blue[256]; -} DDGAMMARAMP,*LPDDGAMMARAMP; - -typedef BOOL CALLBACK (*LPDDENUMCALLBACKA)(GUID *, LPSTR, LPSTR, LPVOID); -typedef BOOL CALLBACK (*LPDDENUMCALLBACKW)(GUID *, LPWSTR, LPWSTR, LPVOID); -DECL_WINELIB_TYPE_AW(LPDDENUMCALLBACK) - -typedef HRESULT CALLBACK (*LPDDENUMMODESCALLBACK)(LPDDSURFACEDESC, LPVOID); -typedef HRESULT CALLBACK (*LPDDENUMMODESCALLBACK2)(LPDDSURFACEDESC2, LPVOID); -typedef HRESULT CALLBACK (*LPDDENUMSURFACESCALLBACK)(LPDIRECTDRAWSURFACE, LPDDSURFACEDESC, LPVOID); -typedef HRESULT CALLBACK (*LPDDENUMSURFACESCALLBACK2)(LPDIRECTDRAWSURFACE4, LPDDSURFACEDESC2, LPVOID); -typedef HRESULT CALLBACK (*LPDDENUMSURFACESCALLBACK7)(LPDIRECTDRAWSURFACE7, LPDDSURFACEDESC2, LPVOID); - -typedef BOOL CALLBACK (*LPDDENUMCALLBACKEXA)(GUID *, LPSTR, LPSTR, LPVOID, HMONITOR); -typedef BOOL CALLBACK (*LPDDENUMCALLBACKEXW)(GUID *, LPWSTR, LPWSTR, LPVOID, HMONITOR); -DECL_WINELIB_TYPE_AW(LPDDENUMCALLBACKEX) - -HRESULT WINAPI DirectDrawEnumerateExA( LPDDENUMCALLBACKEXA lpCallback, LPVOID lpContext, DWORD dwFlags); -HRESULT WINAPI DirectDrawEnumerateExW( LPDDENUMCALLBACKEXW lpCallback, LPVOID lpContext, DWORD dwFlags); -#define DirectDrawEnumerateEx WINELIB_NAME_AW(DirectDrawEnumerateEx) - -/* flags for DirectDrawEnumerateEx */ -#define DDENUM_ATTACHEDSECONDARYDEVICES 0x00000001 -#define DDENUM_DETACHEDSECONDARYDEVICES 0x00000002 -#define DDENUM_NONDISPLAYDEVICES 0x00000004 - -/* flags for DirectDrawCreate or IDirectDraw::Initialize */ -#define DDCREATE_HARDWAREONLY 1L -#define DDCREATE_EMULATIONONLY 2L - -typedef struct _DDBLTFX -{ - DWORD dwSize; /* size of structure */ - DWORD dwDDFX; /* FX operations */ - DWORD dwROP; /* Win32 raster operations */ - DWORD dwDDROP; /* Raster operations new for DirectDraw */ - DWORD dwRotationAngle; /* Rotation angle for blt */ - DWORD dwZBufferOpCode; /* ZBuffer compares */ - DWORD dwZBufferLow; /* Low limit of Z buffer */ - DWORD dwZBufferHigh; /* High limit of Z buffer */ - DWORD dwZBufferBaseDest; /* Destination base value */ - DWORD dwZDestConstBitDepth; /* Bit depth used to specify Z constant for destination */ - union - { - DWORD dwZDestConst; /* Constant to use as Z buffer for dest */ - LPDIRECTDRAWSURFACE lpDDSZBufferDest; /* Surface to use as Z buffer for dest */ - } DUMMYUNIONNAME1; - DWORD dwZSrcConstBitDepth; /* Bit depth used to specify Z constant for source */ - union - { - DWORD dwZSrcConst; /* Constant to use as Z buffer for src */ - LPDIRECTDRAWSURFACE lpDDSZBufferSrc; /* Surface to use as Z buffer for src */ - } DUMMYUNIONNAME2; - DWORD dwAlphaEdgeBlendBitDepth; /* Bit depth used to specify constant for alpha edge blend */ - DWORD dwAlphaEdgeBlend; /* Alpha for edge blending */ - DWORD dwReserved; - DWORD dwAlphaDestConstBitDepth; /* Bit depth used to specify alpha constant for destination */ - union - { - DWORD dwAlphaDestConst; /* Constant to use as Alpha Channel */ - LPDIRECTDRAWSURFACE lpDDSAlphaDest; /* Surface to use as Alpha Channel */ - } DUMMYUNIONNAME3; - DWORD dwAlphaSrcConstBitDepth; /* Bit depth used to specify alpha constant for source */ - union - { - DWORD dwAlphaSrcConst; /* Constant to use as Alpha Channel */ - LPDIRECTDRAWSURFACE lpDDSAlphaSrc; /* Surface to use as Alpha Channel */ - } DUMMYUNIONNAME4; - union - { - DWORD dwFillColor; /* color in RGB or Palettized */ - DWORD dwFillDepth; /* depth value for z-buffer */ - DWORD dwFillPixel; /* pixel val for RGBA or RGBZ */ - LPDIRECTDRAWSURFACE lpDDSPattern; /* Surface to use as pattern */ - } DUMMYUNIONNAME5; - DDCOLORKEY ddckDestColorkey; /* DestColorkey override */ - DDCOLORKEY ddckSrcColorkey; /* SrcColorkey override */ -} DDBLTFX,*LPDDBLTFX; - -/* dwDDFX */ -/* arithmetic stretching along y axis */ -#define DDBLTFX_ARITHSTRETCHY 0x00000001 -/* mirror on y axis */ -#define DDBLTFX_MIRRORLEFTRIGHT 0x00000002 -/* mirror on x axis */ -#define DDBLTFX_MIRRORUPDOWN 0x00000004 -/* do not tear */ -#define DDBLTFX_NOTEARING 0x00000008 -/* 180 degrees clockwise rotation */ -#define DDBLTFX_ROTATE180 0x00000010 -/* 270 degrees clockwise rotation */ -#define DDBLTFX_ROTATE270 0x00000020 -/* 90 degrees clockwise rotation */ -#define DDBLTFX_ROTATE90 0x00000040 -/* dwZBufferLow and dwZBufferHigh specify limits to the copied Z values */ -#define DDBLTFX_ZBUFFERRANGE 0x00000080 -/* add dwZBufferBaseDest to every source z value before compare */ -#define DDBLTFX_ZBUFFERBASEDEST 0x00000100 - -typedef struct _DDOVERLAYFX -{ - DWORD dwSize; /* size of structure */ - DWORD dwAlphaEdgeBlendBitDepth; /* Bit depth used to specify constant for alpha edge blend */ - DWORD dwAlphaEdgeBlend; /* Constant to use as alpha for edge blend */ - DWORD dwReserved; - DWORD dwAlphaDestConstBitDepth; /* Bit depth used to specify alpha constant for destination */ - union - { - DWORD dwAlphaDestConst; /* Constant to use as alpha channel for dest */ - LPDIRECTDRAWSURFACE lpDDSAlphaDest; /* Surface to use as alpha channel for dest */ - } DUMMYUNIONNAME1; - DWORD dwAlphaSrcConstBitDepth; /* Bit depth used to specify alpha constant for source */ - union - { - DWORD dwAlphaSrcConst; /* Constant to use as alpha channel for src */ - LPDIRECTDRAWSURFACE lpDDSAlphaSrc; /* Surface to use as alpha channel for src */ - } DUMMYUNIONNAME2; - DDCOLORKEY dckDestColorkey; /* DestColorkey override */ - DDCOLORKEY dckSrcColorkey; /* DestColorkey override */ - DWORD dwDDFX; /* Overlay FX */ - DWORD dwFlags; /* flags */ -} DDOVERLAYFX,*LPDDOVERLAYFX; - -typedef struct _DDBLTBATCH -{ - LPRECT lprDest; - LPDIRECTDRAWSURFACE lpDDSSrc; - LPRECT lprSrc; - DWORD dwFlags; - LPDDBLTFX lpDDBltFx; -} DDBLTBATCH,*LPDDBLTBATCH; - -#define MAX_DDDEVICEID_STRING 512 - -typedef struct tagDDDEVICEIDENTIFIER { - char szDriver[MAX_DDDEVICEID_STRING]; - char szDescription[MAX_DDDEVICEID_STRING]; - LARGE_INTEGER liDriverVersion; - DWORD dwVendorId; - DWORD dwDeviceId; - DWORD dwSubSysId; - DWORD dwRevision; - GUID guidDeviceIdentifier; -} DDDEVICEIDENTIFIER, * LPDDDEVICEIDENTIFIER; - -typedef struct tagDDDEVICEIDENTIFIER2 { - char szDriver[MAX_DDDEVICEID_STRING]; /* user readable driver name */ - char szDescription[MAX_DDDEVICEID_STRING]; /* user readable description */ - LARGE_INTEGER liDriverVersion; /* driver version */ - DWORD dwVendorId; /* vendor ID, zero if unknown */ - DWORD dwDeviceId; /* chipset ID, zero if unknown */ - DWORD dwSubSysId; /* board ID, zero if unknown */ - DWORD dwRevision; /* chipset version, zero if unknown */ - GUID guidDeviceIdentifier; /* unique ID for this driver/chipset combination */ - DWORD dwWHQLLevel; /* Windows Hardware Quality Lab certification level */ -} DDDEVICEIDENTIFIER2, * LPDDDEVICEIDENTIFIER2; - -/***************************************************************************** - * IDirectDrawPalette interface - */ -#undef INTERFACE -#define INTERFACE IDirectDrawPalette -DECLARE_INTERFACE_(IDirectDrawPalette,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(GetCaps)(THIS_ LPDWORD lpdwCaps) PURE; - STDMETHOD(GetEntries)(THIS_ DWORD dwFlags, DWORD dwBase, DWORD dwNumEntries, LPPALETTEENTRY lpEntries) PURE; - STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, DWORD dwFlags, LPPALETTEENTRY lpDDColorTable) PURE; - STDMETHOD(SetEntries)(THIS_ DWORD dwFlags, DWORD dwStartingEntry, DWORD dwCount, LPPALETTEENTRY lpEntries) PURE; -}; - - /*** IUnknown methods ***/ -#define IDirectDrawPalette_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) -#define IDirectDrawPalette_AddRef(p) ICOM_CALL_(AddRef,p,(p)) -#define IDirectDrawPalette_Release(p) ICOM_CALL_(Release,p,(p)) - /*** IDirectDrawPalette methods ***/ -#define IDirectDrawPalette_GetCaps(p,a) ICOM_CALL_(GetCaps,p,(p,a)) -#define IDirectDrawPalette_GetEntries(p,a,b,c,d) ICOM_CALL_(GetEntries,p,(p,a,b,c,d)) -#define IDirectDrawPalette_Initialize(p,a,b,c) ICOM_CALL_(Initialize,p,(p,a,b,c)) -#define IDirectDrawPalette_SetEntries(p,a,b,c,d) ICOM_CALL_(SetEntries,p,(p,a,b,c,d)) - - -/***************************************************************************** - * IDirectDrawClipper interface - */ -#undef INTERFACE -#define INTERFACE IDirectDrawClipper -DECLARE_INTERFACE_(IDirectDrawClipper,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(GetClipList)(THIS_ LPRECT lpRect, LPRGNDATA lpClipList, LPDWORD lpdwSize) PURE; - STDMETHOD(GetHWnd)(THIS_ HWND* lphWnd) PURE; - STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, DWORD dwFlags) PURE; - STDMETHOD(IsClipListChanged)(THIS_ BOOL* lpbChanged) PURE; - STDMETHOD(SetClipList)(THIS_ LPRGNDATA lpClipList, DWORD dwFlags) PURE; - STDMETHOD(SetHWnd)(THIS_ DWORD dwFlags, HWND hWnd) PURE; -}; - - /*** IUnknown methods ***/ -#define IDirectDrawClipper_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) -#define IDirectDrawClipper_AddRef(p) ICOM_CALL_(AddRef,p,(p)) -#define IDirectDrawClipper_Release(p) ICOM_CALL_(Release,p,(p)) - /*** IDirectDrawClipper methods ***/ -#define IDirectDrawClipper_GetClipList(p,a,b,c) ICOM_CALL_(GetClipList,p,(p,a,b,c)) -#define IDirectDrawClipper_GetHWnd(p,a) ICOM_CALL_(GetHWnd,p,(p,a)) -#define IDirectDrawClipper_Initialize(p,a,b) ICOM_CALL_(Initialize,p,(p,a,b)) -#define IDirectDrawClipper_IsClipListChanged(p,a) ICOM_CALL_(IsClipListChanged,p,(p,a)) -#define IDirectDrawClipper_SetClipList(p,a,b) ICOM_CALL_(SetClipList,p,(p,a,b)) -#define IDirectDrawClipper_SetHWnd(p,a,b) ICOM_CALL_(SetHWnd,p,(p,a,b)) - - -/***************************************************************************** - * IDirectDraw interface - */ -#undef INTERFACE -#define INTERFACE IDirectDraw -DECLARE_INTERFACE_(IDirectDraw,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(Compact)(THIS) PURE; - STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) PURE; - STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE* lplpDDPalette, IUnknown* pUnkOuter) PURE; - STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE* lplpDDSurface, IUnknown* pUnkOuter) PURE; - STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE lpDDSurface, LPDIRECTDRAWSURFACE* lplpDupDDSurface) PURE; - STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback) PURE; - STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE; - STDMETHOD(FlipToGDISurface)(THIS) PURE; - STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE; - STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE; - STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE; - STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE* lplpGDIDDSurface) PURE; - STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE; - STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE; - STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL* lpbIsInVB) PURE; - STDMETHOD(Initialize)(THIS_ GUID* lpGUID) PURE; - STDMETHOD(RestoreDisplayMode)(THIS) PURE; - STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE; - STDMETHOD(SetDisplayMode)(THIS_ DWORD, DWORD, DWORD) PURE; - STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE; -}; - - /*** IUnknown methods ***/ -#define IDirectDraw_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) -#define IDirectDraw_AddRef(p) ICOM_CALL_(AddRef,p,(p)) -#define IDirectDraw_Release(p) ICOM_CALL_(Release,p,(p)) - /*** IDirectDraw methods ***/ -#define IDirectDraw_Compact(p) ICOM_CALL_(Compact,p,(p)) -#define IDirectDraw_CreateClipper(p,a,b,c) ICOM_CALL_(CreateClipper,p,(p,a,b,c)) -#define IDirectDraw_CreatePalette(p,a,b,c,d) ICOM_CALL_(CreatePalette,p,(p,a,b,c,d)) -#define IDirectDraw_CreateSurface(p,a,b,c) ICOM_CALL_(CreateSurface,p,(p,a,b,c)) -#define IDirectDraw_DuplicateSurface(p,a,b) ICOM_CALL_(DuplicateSurface,p,(p,a,b)) -#define IDirectDraw_EnumDisplayModes(p,a,b,c,d) ICOM_CALL_(EnumDisplayModes,p,(p,a,b,c,d)) -#define IDirectDraw_EnumSurfaces(p,a,b,c,d) ICOM_CALL_(EnumSurfaces,p,(p,a,b,c,d)) -#define IDirectDraw_FlipToGDISurface(p) ICOM_CALL_(FlipToGDISurface,p,(p)) -#define IDirectDraw_GetCaps(p,a,b) ICOM_CALL_(GetCaps,p,(p,a,b)) -#define IDirectDraw_GetDisplayMode(p,a) ICOM_CALL_(GetDisplayMode,p,(p,a)) -#define IDirectDraw_GetFourCCCodes(p,a,b) ICOM_CALL_(GetFourCCCodes,p,(p,a,b)) -#define IDirectDraw_GetGDISurface(p,a) ICOM_CALL_(GetGDISurface,p,(p,a)) -#define IDirectDraw_GetMonitorFrequency(p,a) ICOM_CALL_(GetMonitorFrequency,p,(p,a)) -#define IDirectDraw_GetScanLine(p,a) ICOM_CALL_(GetScanLine,p,(p,a)) -#define IDirectDraw_GetVerticalBlankStatus(p,a) ICOM_CALL_(GetVerticalBlankStatus,p,(p,a)) -#define IDirectDraw_Initialize(p,a) ICOM_CALL_(Initialize,p,(p,a)) -#define IDirectDraw_RestoreDisplayMode(p) ICOM_CALL_(RestoreDisplayMode,p,(p)) -#define IDirectDraw_SetCooperativeLevel(p,a,b) ICOM_CALL_(SetCooperativeLevel,p,(p,a,b)) -#define IDirectDraw_SetDisplayMode(p,a,b,c) ICOM_CALL_(SetDisplayMode,p,(p,a,b,c)) -#define IDirectDraw_WaitForVerticalBlank(p,a,b) ICOM_CALL_(WaitForVerticalBlank,p,(p,a,b)) - - -/* flags for Lock() */ -#define DDLOCK_SURFACEMEMORYPTR 0x00000000 -#define DDLOCK_WAIT 0x00000001 -#define DDLOCK_EVENT 0x00000002 -#define DDLOCK_READONLY 0x00000010 -#define DDLOCK_WRITEONLY 0x00000020 -#define DDLOCK_NOSYSLOCK 0x00000800 - - -/***************************************************************************** - * IDirectDraw2 interface - */ -/* Note: IDirectDraw2 cannot derive from IDirectDraw because the number of - * arguments of SetDisplayMode has changed ! - */ -#undef INTERFACE -#define INTERFACE IDirectDraw2 -DECLARE_INTERFACE_(IDirectDraw2,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(Compact)(THIS) PURE; - STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) PURE; - STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE* lplpDDPalette, IUnknown* pUnkOuter) PURE; - STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc, LPDIRECTDRAWSURFACE2* lplpDDSurface, IUnknown* pUnkOuter) PURE; - STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE2 lpDDSurface, LPDIRECTDRAWSURFACE2* lplpDupDDSurface) PURE; - STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK lpEnumModesCallback) PURE; - STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE; - STDMETHOD(FlipToGDISurface)(THIS) PURE; - STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE; - STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE; - STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE; - STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE2* lplpGDIDDSurface) PURE; - STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE; - STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE; - STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL* lpbIsInVB) PURE; - STDMETHOD(Initialize)(THIS_ GUID* lpGUID) PURE; - STDMETHOD(RestoreDisplayMode)(THIS) PURE; - STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE; - STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE; - STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE; - - STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE; -}; - - /*** IUnknown methods ***/ -#define IDirectDraw2_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) -#define IDirectDraw2_AddRef(p) ICOM_CALL_(AddRef,p,(p)) -#define IDirectDraw2_Release(p) ICOM_CALL_(Release,p,(p)) - /*** IDirectDraw methods ***/ -#define IDirectDraw2_Compact(p) ICOM_CALL_(Compact,p,(p)) -#define IDirectDraw2_CreateClipper(p,a,b,c) ICOM_CALL_(CreateClipper,p,(p,a,b,c)) -#define IDirectDraw2_CreatePalette(p,a,b,c,d) ICOM_CALL_(CreatePalette,p,(p,a,b,c,d)) -#define IDirectDraw2_CreateSurface(p,a,b,c) ICOM_CALL_(CreateSurface,p,(p,a,b,c)) -#define IDirectDraw2_DuplicateSurface(p,a,b) ICOM_CALL_(DuplicateSurface,p,(p,a,b)) -#define IDirectDraw2_EnumDisplayModes(p,a,b,c,d) ICOM_CALL_(EnumDisplayModes,p,(p,a,b,c,d)) -#define IDirectDraw2_EnumSurfaces(p,a,b,c,d) ICOM_CALL_(EnumSurfaces,p,(p,a,b,c,d)) -#define IDirectDraw2_FlipToGDISurface(p) ICOM_CALL_(FlipToGDISurface,p,(p)) -#define IDirectDraw2_GetCaps(p,a,b) ICOM_CALL_(GetCaps,p,(p,a,b)) -#define IDirectDraw2_GetDisplayMode(p,a) ICOM_CALL_(GetDisplayMode,p,(p,a)) -#define IDirectDraw2_GetFourCCCodes(p,a,b) ICOM_CALL_(GetFourCCCodes,p,(p,a,b)) -#define IDirectDraw2_GetGDISurface(p,a) ICOM_CALL_(GetGDISurface,p,(p,a)) -#define IDirectDraw2_GetMonitorFrequency(p,a) ICOM_CALL_(GetMonitorFrequency,p,(p,a)) -#define IDirectDraw2_GetScanLine(p,a) ICOM_CALL_(GetScanLine,p,(p,a)) -#define IDirectDraw2_GetVerticalBlankStatus(p,a) ICOM_CALL_(GetVerticalBlankStatus,p,(p,a)) -#define IDirectDraw2_Initialize(p,a) ICOM_CALL_(Initialize,p,(p,a)) -#define IDirectDraw2_RestoreDisplayMode(p) ICOM_CALL_(RestoreDisplayMode,p,(p)) -#define IDirectDraw2_SetCooperativeLevel(p,a,b) ICOM_CALL_(SetCooperativeLevel,p,(p,a,b)) -#define IDirectDraw2_SetDisplayMode(p,a,b,c,d,e) ICOM_CALL_(SetDisplayMode,p,(p,a,b,c,d,e)) -#define IDirectDraw2_WaitForVerticalBlank(p,a,b) ICOM_CALL_(WaitForVerticalBlank,p,(p,a,b)) -/*** IDirectDraw2 methods ***/ -#define IDirectDraw2_GetAvailableVidMem(p,a,b,c) ICOM_CALL_(GetAvailableVidMem,p,(p,a,b,c)) - - -/***************************************************************************** - * IDirectDraw4 interface - */ -#undef INTERFACE -#define INTERFACE IDirectDraw4 -DECLARE_INTERFACE_(IDirectDraw4,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(Compact)(THIS) PURE; - STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) PURE; - STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE* lplpDDPalette, IUnknown* pUnkOuter) PURE; - STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc, LPDIRECTDRAWSURFACE4* lplpDDSurface, IUnknown* pUnkOuter) PURE; - STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE4 lpDDSurface, LPDIRECTDRAWSURFACE4* lplpDupDDSurface) PURE; - STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK2 lpEnumModesCallback) PURE; - STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK2 lpEnumSurfacesCallback) PURE; - STDMETHOD(FlipToGDISurface)(THIS) PURE; - STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE; - STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE; - STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE; - STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE4* lplpGDIDDSurface) PURE; - STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE; - STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE; - STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL* lpbIsInVB) PURE; - STDMETHOD(Initialize)(THIS_ GUID* lpGUID) PURE; - STDMETHOD(RestoreDisplayMode)(THIS) PURE; - STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE; - STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE; - STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE; - - STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS2 lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE; - - STDMETHOD(GetSurfaceFromDC)(THIS_ HDC , LPDIRECTDRAWSURFACE4* ) PURE; - STDMETHOD(RestoreAllSurfaces)(THIS) PURE; - STDMETHOD(TestCooperativeLevel)(THIS) PURE; - STDMETHOD(GetDeviceIdentifier)(THIS_ LPDDDEVICEIDENTIFIER , DWORD ) PURE; -}; - - /*** IUnknown methods ***/ -#define IDirectDraw4_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) -#define IDirectDraw4_AddRef(p) ICOM_CALL_(AddRef,p,(p)) -#define IDirectDraw4_Release(p) ICOM_CALL_(Release,p,(p)) - /*** IDirectDraw methods ***/ -#define IDirectDraw4_Compact(p) ICOM_CALL_(Compact,p,(p)) -#define IDirectDraw4_CreateClipper(p,a,b,c) ICOM_CALL_(CreateClipper,p,(p,a,b,c)) -#define IDirectDraw4_CreatePalette(p,a,b,c,d) ICOM_CALL_(CreatePalette,p,(p,a,b,c,d)) -#define IDirectDraw4_CreateSurface(p,a,b,c) ICOM_CALL_(CreateSurface,p,(p,a,b,c)) -#define IDirectDraw4_DuplicateSurface(p,a,b) ICOM_CALL_(DuplicateSurface,p,(p,a,b)) -#define IDirectDraw4_EnumDisplayModes(p,a,b,c,d) ICOM_CALL_(EnumDisplayModes,p,(p,a,b,c,d)) -#define IDirectDraw4_EnumSurfaces(p,a,b,c,d) ICOM_CALL_(EnumSurfaces,p,(p,a,b,c,d)) -#define IDirectDraw4_FlipToGDISurface(p) ICOM_CALL_(FlipToGDISurface,p,(p)) -#define IDirectDraw4_GetCaps(p,a,b) ICOM_CALL_(GetCaps,p,(p,a,b)) -#define IDirectDraw4_GetDisplayMode(p,a) ICOM_CALL_(GetDisplayMode,p,(p,a)) -#define IDirectDraw4_GetFourCCCodes(p,a,b) ICOM_CALL_(GetFourCCCodes,p,(p,a,b)) -#define IDirectDraw4_GetGDISurface(p,a) ICOM_CALL_(GetGDISurface,p,(p,a)) -#define IDirectDraw4_GetMonitorFrequency(p,a) ICOM_CALL_(GetMonitorFrequency,p,(p,a)) -#define IDirectDraw4_GetScanLine(p,a) ICOM_CALL_(GetScanLine,p,(p,a)) -#define IDirectDraw4_GetVerticalBlankStatus(p,a) ICOM_CALL_(GetVerticalBlankStatus,p,(p,a)) -#define IDirectDraw4_Initialize(p,a) ICOM_CALL_(Initialize,p,(p,a)) -#define IDirectDraw4_RestoreDisplayMode(p) ICOM_CALL_(RestoreDisplayMode,p,(p)) -#define IDirectDraw4_SetCooperativeLevel(p,a,b) ICOM_CALL_(SetCooperativeLevel,p,(p,a,b)) -#define IDirectDraw4_SetDisplayMode(p,a,b,c,d,e) ICOM_CALL_(SetDisplayMode,p,(p,a,b,c,d,e)) -#define IDirectDraw4_WaitForVerticalBlank(p,a,b) ICOM_CALL_(WaitForVerticalBlank,p,(p,a,b)) -/*** IDirectDraw2 methods ***/ -#define IDirectDraw4_GetAvailableVidMem(p,a,b,c) ICOM_CALL_(GetAvailableVidMem,p,(p,a,b,c)) -/*** IDirectDraw4 methods ***/ -#define IDirectDraw4_GetSurfaceFromDC(p,a,b) ICOM_CALL_(GetSurfaceFromDC,p,(p,a,b)) -#define IDirectDraw4_RestoreAllSurfaces(pc) ICOM_CALL_(RestoreAllSurfaces,p,(p)) -#define IDirectDraw4_TestCooperativeLevel(p) ICOM_CALL_(TestCooperativeLevel,p,(p)) -#define IDirectDraw4_GetDeviceIdentifier(p,a,b) ICOM_CALL_(GetDeviceIdentifier,p,(p,a,b)) - - -/***************************************************************************** - * IDirectDraw7 interface - */ -/* Note: IDirectDraw7 cannot derive from IDirectDraw4; it is even documented - * as not interchangeable with earlier DirectDraw interfaces. - */ -#undef INTERFACE -#define INTERFACE IDirectDraw7 -DECLARE_INTERFACE_(IDirectDraw7,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(Compact)(THIS) PURE; - STDMETHOD(CreateClipper)(THIS_ DWORD dwFlags, LPDIRECTDRAWCLIPPER* lplpDDClipper, IUnknown* pUnkOuter) PURE; - STDMETHOD(CreatePalette)(THIS_ DWORD dwFlags, LPPALETTEENTRY lpColorTable, LPDIRECTDRAWPALETTE* lplpDDPalette, IUnknown* pUnkOuter) PURE; - STDMETHOD(CreateSurface)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc, LPDIRECTDRAWSURFACE7* lplpDDSurface, IUnknown* pUnkOuter) PURE; - STDMETHOD(DuplicateSurface)(THIS_ LPDIRECTDRAWSURFACE7 lpDDSurface, LPDIRECTDRAWSURFACE7* lplpDupDDSurface) PURE; - STDMETHOD(EnumDisplayModes)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSurfaceDesc, LPVOID lpContext, LPDDENUMMODESCALLBACK2 lpEnumModesCallback) PURE; - STDMETHOD(EnumSurfaces)(THIS_ DWORD dwFlags, LPDDSURFACEDESC2 lpDDSD, LPVOID lpContext, LPDDENUMSURFACESCALLBACK7 lpEnumSurfacesCallback) PURE; - STDMETHOD(FlipToGDISurface)(THIS) PURE; - STDMETHOD(GetCaps)(THIS_ LPDDCAPS lpDDDriverCaps, LPDDCAPS lpDDHELCaps) PURE; - STDMETHOD(GetDisplayMode)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE; - STDMETHOD(GetFourCCCodes)(THIS_ LPDWORD lpNumCodes, LPDWORD lpCodes) PURE; - STDMETHOD(GetGDISurface)(THIS_ LPDIRECTDRAWSURFACE7* lplpGDIDDSurface) PURE; - STDMETHOD(GetMonitorFrequency)(THIS_ LPDWORD lpdwFrequency) PURE; - STDMETHOD(GetScanLine)(THIS_ LPDWORD lpdwScanLine) PURE; - STDMETHOD(GetVerticalBlankStatus)(THIS_ BOOL* lpbIsInVB) PURE; - STDMETHOD(Initialize)(THIS_ GUID* lpGUID) PURE; - STDMETHOD(RestoreDisplayMode)(THIS) PURE; - STDMETHOD(SetCooperativeLevel)(THIS_ HWND hWnd, DWORD dwFlags) PURE; - STDMETHOD(SetDisplayMode)(THIS_ DWORD dwWidth, DWORD dwHeight, DWORD dwBPP, DWORD dwRefreshRate, DWORD dwFlags) PURE; - STDMETHOD(WaitForVerticalBlank)(THIS_ DWORD dwFlags, HANDLE hEvent) PURE; - - STDMETHOD(GetAvailableVidMem)(THIS_ LPDDSCAPS2 lpDDCaps, LPDWORD lpdwTotal, LPDWORD lpdwFree) PURE; - - STDMETHOD(GetSurfaceFromDC)(THIS_ HDC , LPDIRECTDRAWSURFACE7* ) PURE; - STDMETHOD(RestoreAllSurfaces)(THIS) PURE; - STDMETHOD(TestCooperativeLevel)(THIS) PURE; - STDMETHOD(GetDeviceIdentifier)(THIS_ LPDDDEVICEIDENTIFIER2 , DWORD ) PURE; - - STDMETHOD(StartModeTest)(THIS_ LPSIZE , DWORD , DWORD ) PURE; - STDMETHOD(EvaluateMode)(THIS_ DWORD , DWORD * ) PURE; -}; - - /*** IUnknown methods ***/ -#define IDirectDraw7_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) -#define IDirectDraw7_AddRef(p) ICOM_CALL_(AddRef,p,(p)) -#define IDirectDraw7_Release(p) ICOM_CALL_(Release,p,(p)) - /*** IDirectDraw methods ***/ -#define IDirectDraw7_Compact(p) ICOM_CALL_(Compact,p,(p)) -#define IDirectDraw7_CreateClipper(p,a,b,c) ICOM_CALL_(CreateClipper,p,(p,a,b,c)) -#define IDirectDraw7_CreatePalette(p,a,b,c,d) ICOM_CALL_(CreatePalette,p,(p,a,b,c,d)) -#define IDirectDraw7_CreateSurface(p,a,b,c) ICOM_CALL_(CreateSurface,p,(p,a,b,c)) -#define IDirectDraw7_DuplicateSurface(p,a,b) ICOM_CALL_(DuplicateSurface,p,(p,a,b)) -#define IDirectDraw7_EnumDisplayModes(p,a,b,c,d) ICOM_CALL_(EnumDisplayModes,p,(p,a,b,c,d)) -#define IDirectDraw7_EnumSurfaces(p,a,b,c,d) ICOM_CALL_(EnumSurfaces,p,(p,a,b,c,d)) -#define IDirectDraw7_FlipToGDISurface(p) ICOM_CALL_(FlipToGDISurface,p,(p)) -#define IDirectDraw7_GetCaps(p,a,b) ICOM_CALL_(GetCaps,p,(p,a,b)) -#define IDirectDraw7_GetDisplayMode(p,a) ICOM_CALL_(GetDisplayMode,p,(p,a)) -#define IDirectDraw7_GetFourCCCodes(p,a,b) ICOM_CALL_(GetFourCCCodes,p,(p,a,b)) -#define IDirectDraw7_GetGDISurface(p,a) ICOM_CALL_(GetGDISurface,p,(p,a)) -#define IDirectDraw7_GetMonitorFrequency(p,a) ICOM_CALL_(GetMonitorFrequency,p,(p,a)) -#define IDirectDraw7_GetScanLine(p,a) ICOM_CALL_(GetScanLine,p,(p,a)) -#define IDirectDraw7_GetVerticalBlankStatus(p,a) ICOM_CALL_(GetVerticalBlankStatus,p,(p,a)) -#define IDirectDraw7_Initialize(p,a) ICOM_CALL_(Initialize,p,(p,a)) -#define IDirectDraw7_RestoreDisplayMode(p) ICOM_CALL_(RestoreDisplayMode,p,(p)) -#define IDirectDraw7_SetCooperativeLevel(p,a,b) ICOM_CALL_(SetCooperativeLevel,p,(p,a,b)) -#define IDirectDraw7_SetDisplayMode(p,a,b,c,d,e) ICOM_CALL_(SetDisplayMode,p,(p,a,b,c,d,e)) -#define IDirectDraw7_WaitForVerticalBlank(p,a,b) ICOM_CALL_(WaitForVerticalBlank,p,(p,a,b)) -/*** added in IDirectDraw2 ***/ -#define IDirectDraw7_GetAvailableVidMem(p,a,b,c) ICOM_CALL_(GetAvailableVidMem,p,(p,a,b,c)) -/*** added in IDirectDraw4 ***/ -#define IDirectDraw7_GetSurfaceFromDC(p,a,b) ICOM_CALL_(GetSurfaceFromDC,p,(p,a,b)) -#define IDirectDraw7_RestoreAllSurfaces(p) ICOM_CALL_(RestoreAllSurfaces,p,(p)) -#define IDirectDraw7_TestCooperativeLevel(p) ICOM_CALL_(TestCooperativeLevel,p,(p)) -#define IDirectDraw7_GetDeviceIdentifier(p,a,b) ICOM_CALL_(GetDeviceIdentifier,p,(p,a,b)) -/*** added in IDirectDraw 7 ***/ -#define IDirectDraw7_StartModeTest(p,a,b,c) ICOM_CALL_(StartModeTest,p,(p,a,b,c)) -#define IDirectDraw7_EvaluateMode(p,a,b) ICOM_CALL_(EvaluateMode,p,(p,a,b)) - - -/***************************************************************************** - * IDirectDrawSurface interface - */ -#undef INTERFACE -#define INTERFACE IDirectDrawSurface -DECLARE_INTERFACE_(IDirectDrawSurface,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE lpDDSAttachedSurface) PURE; - STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE; - STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE; - STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE; - STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE; - STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSAttachedSurface) PURE; - STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE; - STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE; - STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE lpDDSurfaceTargetOverride, DWORD dwFlags) PURE; - STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE* lplpDDAttachedSurface) PURE; - STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(GetCaps)(THIS_ LPDDSCAPS lpDDSCaps) PURE; - STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER* lplpDDClipper) PURE; - STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; - STDMETHOD(GetDC)(THIS_ HDC* lphDC) PURE; - STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE; - STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE* lplpDDPalette) PURE; - STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE; - STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE; - STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) PURE; - STDMETHOD(IsLost)(THIS) PURE; - STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE; - STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE; - STDMETHOD(Restore)(THIS) PURE; - STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE; - STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; - STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE; - STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE; - STDMETHOD(Unlock)(THIS_ LPVOID lpSurfaceData) PURE; - STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE; - STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE lpDDSReference) PURE; -}; - - /*** IUnknown methods ***/ -#define IDirectDrawSurface_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) -#define IDirectDrawSurface_AddRef(p) ICOM_CALL_(AddRef,p,(p)) -#define IDirectDrawSurface_Release(p) ICOM_CALL_(Release,p,(p)) - /*** IDirectDrawSurface methods ***/ -#define IDirectDrawSurface_AddAttachedSurface(p,a) ICOM_CALL_(AddAttachedSurface,p,(p,a)) -#define IDirectDrawSurface_AddOverlayDirtyRect(p,a) ICOM_CALL_(AddOverlayDirtyRect,p,(p,a)) -#define IDirectDrawSurface_Blt(p,a,b,c,d,e) ICOM_CALL_(Blt,p,(p,a,b,c,d,e)) -#define IDirectDrawSurface_BltBatch(p,a,b,c) ICOM_CALL_(BltBatch,p,(p,a,b,c)) -#define IDirectDrawSurface_BltFast(p,a,b,c,d,e) ICOM_CALL_(BltFast,p,(p,a,b,c,d,e)) -#define IDirectDrawSurface_DeleteAttachedSurface(p,a,b) ICOM_CALL_(DeleteAttachedSurface,p,(p,a,b)) -#define IDirectDrawSurface_EnumAttachedSurfaces(p,a,b) ICOM_CALL_(EnumAttachedSurfaces,p,(p,a,b)) -#define IDirectDrawSurface_EnumOverlayZOrders(p,a,b,c) ICOM_CALL_(EnumOverlayZOrders,p,(p,a,b,c)) -#define IDirectDrawSurface_Flip(p,a,b) ICOM_CALL_(Flip,p,(p,a,b)) -#define IDirectDrawSurface_GetAttachedSurface(p,a,b) ICOM_CALL_(GetAttachedSurface,p,(p,a,b)) -#define IDirectDrawSurface_GetBltStatus(p,a) ICOM_CALL_(GetBltStatus,p,(p,a)) -#define IDirectDrawSurface_GetCaps(p,a) ICOM_CALL_(GetCaps,p,(p,a)) -#define IDirectDrawSurface_GetClipper(p,a) ICOM_CALL_(GetClipper,p,(p,a)) -#define IDirectDrawSurface_GetColorKey(p,a,b) ICOM_CALL_(GetColorKey,p,(p,a,b)) -#define IDirectDrawSurface_GetDC(p,a) ICOM_CALL_(GetDC,p,(p,a)) -#define IDirectDrawSurface_GetFlipStatus(p,a) ICOM_CALL_(GetFlipStatus,p,(p,a)) -#define IDirectDrawSurface_GetOverlayPosition(p,a,b) ICOM_CALL_(GetOverlayPosition,p,(p,a,b)) -#define IDirectDrawSurface_GetPalette(p,a) ICOM_CALL_(GetPalette,p,(p,a)) -#define IDirectDrawSurface_GetPixelFormat(p,a) ICOM_CALL_(GetPixelFormat,p,(p,a)) -#define IDirectDrawSurface_GetSurfaceDesc(p,a) ICOM_CALL_(GetSurfaceDesc,p,(p,a)) -#define IDirectDrawSurface_Initialize(p,a,b) ICOM_CALL_(Initialize,p,(p,a,b)) -#define IDirectDrawSurface_IsLost(p) ICOM_CALL_(IsLost,p,(p)) -#define IDirectDrawSurface_Lock(p,a,b,c,d) ICOM_CALL_(Lock,p,(p,a,b,c,d)) -#define IDirectDrawSurface_ReleaseDC(p,a) ICOM_CALL_(ReleaseDC,p,(p,a)) -#define IDirectDrawSurface_Restore(p) ICOM_CALL_(Restore,p,(p)) -#define IDirectDrawSurface_SetClipper(p,a) ICOM_CALL_(SetClipper,p,(p,a)) -#define IDirectDrawSurface_SetColorKey(p,a,b) ICOM_CALL_(SetColorKey,p,(p,a,b)) -#define IDirectDrawSurface_SetOverlayPosition(p,a,b) ICOM_CALL_(SetOverlayPosition,p,(p,a,b)) -#define IDirectDrawSurface_SetPalette(p,a) ICOM_CALL_(SetPalette,p,(p,a)) -#define IDirectDrawSurface_Unlock(p,a) ICOM_CALL_(Unlock,p,(p,a)) -#define IDirectDrawSurface_UpdateOverlay(p,a,b,c,d,e) ICOM_CALL_(UpdateOverlay,p,(p,a,b,c,d,e)) -#define IDirectDrawSurface_UpdateOverlayDisplay(p,a) ICOM_CALL_(UpdateOverlayDisplay,p,(p,a)) -#define IDirectDrawSurface_UpdateOverlayZOrder(p,a,b) ICOM_CALL_(UpdateOverlayZOrder,p,(p,a,b)) - - -/***************************************************************************** - * IDirectDrawSurface2 interface - */ -/* Cannot inherit from IDirectDrawSurface because the LPDIRECTDRAWSURFACE parameters - * have been converted to LPDIRECTDRAWSURFACE2. - */ -#undef INTERFACE -#define INTERFACE IDirectDrawSurface2 -DECLARE_INTERFACE_(IDirectDrawSurface2,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE2 lpDDSAttachedSurface) PURE; - STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE; - STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE2 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE; - STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE; - STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE2 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE; - STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDSAttachedSurface) PURE; - STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE; - STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE; - STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE2 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE; - STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE2* lplpDDAttachedSurface) PURE; - STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(GetCaps)(THIS_ LPDDSCAPS lpDDSCaps) PURE; - STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER* lplpDDClipper) PURE; - STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; - STDMETHOD(GetDC)(THIS_ HDC* lphDC) PURE; - STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE; - STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE* lplpDDPalette) PURE; - STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE; - STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE; - STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) PURE; - STDMETHOD(IsLost)(THIS) PURE; - STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE; - STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE; - STDMETHOD(Restore)(THIS) PURE; - STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE; - STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; - STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE; - STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE; - STDMETHOD(Unlock)(THIS_ LPVOID lpSurfaceData) PURE; - STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE2 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE; - STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE2 lpDDSReference) PURE; - /* added in v2 */ - STDMETHOD(GetDDInterface)(THIS_ LPVOID* lplpDD) PURE; - STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE; -}; - - /*** IUnknown methods ***/ -#define IDirectDrawSurface2_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) -#define IDirectDrawSurface2_AddRef(p) ICOM_CALL_(AddRef,p,(p)) -#define IDirectDrawSurface2_Release(p) ICOM_CALL_(Release,p,(p)) -/*** IDirectDrawSurface methods (almost) ***/ -#define IDirectDrawSurface2_AddAttachedSurface(p,a) ICOM_CALL_(AddAttachedSurface,p,(p,a)) -#define IDirectDrawSurface2_AddOverlayDirtyRect(p,a) ICOM_CALL_(AddOverlayDirtyRect,p,(p,a)) -#define IDirectDrawSurface2_Blt(p,a,b,c,d,e) ICOM_CALL_(Blt,p,(p,a,b,c,d,e)) -#define IDirectDrawSurface2_BltBatch(p,a,b,c) ICOM_CALL_(BltBatch,p,(p,a,b,c)) -#define IDirectDrawSurface2_BltFast(p,a,b,c,d,e) ICOM_CALL_(BltFast,p,(p,a,b,c,d,e)) -#define IDirectDrawSurface2_DeleteAttachedSurface(p,a,b) ICOM_CALL_(DeleteAttachedSurface,p,(p,a,b)) -#define IDirectDrawSurface2_EnumAttachedSurfaces(p,a,b) ICOM_CALL_(EnumAttachedSurfaces,p,(p,a,b)) -#define IDirectDrawSurface2_EnumOverlayZOrders(p,a,b,c) ICOM_CALL_(EnumOverlayZOrders,p,(p,a,b,c)) -#define IDirectDrawSurface2_Flip(p,a,b) ICOM_CALL_(Flip,p,(p,a,b)) -#define IDirectDrawSurface2_GetAttachedSurface(p,a,b) ICOM_CALL_(GetAttachedSurface,p,(p,a,b)) -#define IDirectDrawSurface2_GetBltStatus(p,a) ICOM_CALL_(GetBltStatus,p,(p,a)) -#define IDirectDrawSurface2_GetCaps(p,a) ICOM_CALL_(GetCaps,p,(p,a)) -#define IDirectDrawSurface2_GetClipper(p,a) ICOM_CALL_(GetClipper,p,(p,a)) -#define IDirectDrawSurface2_GetColorKey(p,a,b) ICOM_CALL_(GetColorKey,p,(p,a,b)) -#define IDirectDrawSurface2_GetDC(p,a) ICOM_CALL_(GetDC,p,(p,a)) -#define IDirectDrawSurface2_GetFlipStatus(p,a) ICOM_CALL_(GetFlipStatus,p,(p,a)) -#define IDirectDrawSurface2_GetOverlayPosition(p,a,b) ICOM_CALL_(GetOverlayPosition,p,(p,a,b)) -#define IDirectDrawSurface2_GetPalette(p,a) ICOM_CALL_(GetPalette,p,(p,a)) -#define IDirectDrawSurface2_GetPixelFormat(p,a) ICOM_CALL_(GetPixelFormat,p,(p,a)) -#define IDirectDrawSurface2_GetSurfaceDesc(p,a) ICOM_CALL_(GetSurfaceDesc,p,(p,a)) -#define IDirectDrawSurface2_Initialize(p,a,b) ICOM_CALL_(Initialize,p,(p,a,b)) -#define IDirectDrawSurface2_IsLost(p) ICOM_CALL_(IsLost,p,(p)) -#define IDirectDrawSurface2_Lock(p,a,b,c,d) ICOM_CALL_(Lock,p,(p,a,b,c,d)) -#define IDirectDrawSurface2_ReleaseDC(p,a) ICOM_CALL_(ReleaseDC,p,(p,a)) -#define IDirectDrawSurface2_Restore(p) ICOM_CALL_(Restore,p,(p)) -#define IDirectDrawSurface2_SetClipper(p,a) ICOM_CALL_(SetClipper,p,(p,a)) -#define IDirectDrawSurface2_SetColorKey(p,a,b) ICOM_CALL_(SetColorKey,p,(p,a,b)) -#define IDirectDrawSurface2_SetOverlayPosition(p,a,b) ICOM_CALL_(SetOverlayPosition,p,(p,a,b)) -#define IDirectDrawSurface2_SetPalette(p,a) ICOM_CALL_(SetPalette,p,(p,a)) -#define IDirectDrawSurface2_Unlock(p,a) ICOM_CALL_(Unlock,p,(p,a)) -#define IDirectDrawSurface2_UpdateOverlay(p,a,b,c,d,e) ICOM_CALL_(UpdateOverlay,p,(p,a,b,c,d,e)) -#define IDirectDrawSurface2_UpdateOverlayDisplay(p,a) ICOM_CALL_(UpdateOverlayDisplay,p,(p,a)) -#define IDirectDrawSurface2_UpdateOverlayZOrder(p,a,b) ICOM_CALL_(UpdateOverlayZOrder,p,(p,a,b)) -/*** IDirectDrawSurface2 methods ***/ -#define IDirectDrawSurface2_GetDDInterface(p,a) ICOM_CALL_(GetDDInterface,p,(p,a)) -#define IDirectDrawSurface2_PageLock(p,a) ICOM_CALL_(PageLock,p,(p,a)) -#define IDirectDrawSurface2_PageUnlock(p,a) ICOM_CALL_(PageUnlock,p,(p,a)) - - -/***************************************************************************** - * IDirectDrawSurface3 interface - */ -/* Cannot inherit from IDirectDrawSurface2 because the LPDIRECTDRAWSURFACE2 parameters - * have been converted to LPDIRECTDRAWSURFACE3. - */ -#undef INTERFACE -#define INTERFACE IDirectDrawSurface3 -DECLARE_INTERFACE_(IDirectDrawSurface3,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface) PURE; - STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE; - STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE3 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE; - STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE; - STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE3 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE; - STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDSAttachedSurface) PURE; - STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE; - STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE; - STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE3 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE; - STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS lpDDSCaps, LPDIRECTDRAWSURFACE3* lplpDDAttachedSurface) PURE; - STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(GetCaps)(THIS_ LPDDSCAPS lpDDSCaps) PURE; - STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER* lplpDDClipper) PURE; - STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; - STDMETHOD(GetDC)(THIS_ HDC* lphDC) PURE; - STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE; - STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE* lplpDDPalette) PURE; - STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE; - STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE; - STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) PURE; - STDMETHOD(IsLost)(THIS) PURE; - STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE; - STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE; - STDMETHOD(Restore)(THIS) PURE; - STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE; - STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; - STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE; - STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE; - STDMETHOD(Unlock)(THIS_ LPVOID lpSurfaceData) PURE; - STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE3 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE; - STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE3 lpDDSReference) PURE; - /* added in v2 */ - STDMETHOD(GetDDInterface)(THIS_ LPVOID* lplpDD) PURE; - STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE; - /* added in v3 */ - STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSD, DWORD dwFlags) PURE; -}; - - /*** IUnknown methods ***/ -#define IDirectDrawSurface3_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) -#define IDirectDrawSurface3_AddRef(p) ICOM_CALL_(AddRef,p,(p)) -#define IDirectDrawSurface3_Release(p) ICOM_CALL_(Release,p,(p)) -/*** IDirectDrawSurface methods (almost) ***/ -#define IDirectDrawSurface3_AddAttachedSurface(p,a) ICOM_CALL_(AddAttachedSurface,p,(p,a)) -#define IDirectDrawSurface3_AddOverlayDirtyRect(p,a) ICOM_CALL_(AddOverlayDirtyRect,p,(p,a)) -#define IDirectDrawSurface3_Blt(p,a,b,c,d,e) ICOM_CALL_(Blt,p,(p,a,b,c,d,e)) -#define IDirectDrawSurface3_BltBatch(p,a,b,c) ICOM_CALL_(BltBatch,p,(p,a,b,c)) -#define IDirectDrawSurface3_BltFast(p,a,b,c,d,e) ICOM_CALL_(BltFast,p,(p,a,b,c,d,e)) -#define IDirectDrawSurface3_DeleteAttachedSurface(p,a,b) ICOM_CALL_(DeleteAttachedSurface,p,(p,a,b)) -#define IDirectDrawSurface3_EnumAttachedSurfaces(p,a,b) ICOM_CALL_(EnumAttachedSurfaces,p,(p,a,b)) -#define IDirectDrawSurface3_EnumOverlayZOrders(p,a,b,c) ICOM_CALL_(EnumOverlayZOrders,p,(p,a,b,c)) -#define IDirectDrawSurface3_Flip(p,a,b) ICOM_CALL_(Flip,p,(p,a,b)) -#define IDirectDrawSurface3_GetAttachedSurface(p,a,b) ICOM_CALL_(GetAttachedSurface,p,(p,a,b)) -#define IDirectDrawSurface3_GetBltStatus(p,a) ICOM_CALL_(GetBltStatus,p,(p,a)) -#define IDirectDrawSurface3_GetCaps(p,a) ICOM_CALL_(GetCaps,p,(p,a)) -#define IDirectDrawSurface3_GetClipper(p,a) ICOM_CALL_(GetClipper,p,(p,a)) -#define IDirectDrawSurface3_GetColorKey(p,a,b) ICOM_CALL_(GetColorKey,p,(p,a,b)) -#define IDirectDrawSurface3_GetDC(p,a) ICOM_CALL_(GetDC,p,(p,a)) -#define IDirectDrawSurface3_GetFlipStatus(p,a) ICOM_CALL_(GetFlipStatus,p,(p,a)) -#define IDirectDrawSurface3_GetOverlayPosition(p,a,b) ICOM_CALL_(GetOverlayPosition,p,(p,a,b)) -#define IDirectDrawSurface3_GetPalette(p,a) ICOM_CALL_(GetPalette,p,(p,a)) -#define IDirectDrawSurface3_GetPixelFormat(p,a) ICOM_CALL_(GetPixelFormat,p,(p,a)) -#define IDirectDrawSurface3_GetSurfaceDesc(p,a) ICOM_CALL_(GetSurfaceDesc,p,(p,a)) -#define IDirectDrawSurface3_Initialize(p,a,b) ICOM_CALL_(Initialize,p,(p,a,b)) -#define IDirectDrawSurface3_IsLost(p) ICOM_CALL_(IsLost,p,(p)) -#define IDirectDrawSurface3_Lock(p,a,b,c,d) ICOM_CALL_(Lock,p,(p,a,b,c,d)) -#define IDirectDrawSurface3_ReleaseDC(p,a) ICOM_CALL_(ReleaseDC,p,(p,a)) -#define IDirectDrawSurface3_Restore(p) ICOM_CALL_(Restore,p,(p)) -#define IDirectDrawSurface3_SetClipper(p,a) ICOM_CALL_(SetClipper,p,(p,a)) -#define IDirectDrawSurface3_SetColorKey(p,a,b) ICOM_CALL_(SetColorKey,p,(p,a,b)) -#define IDirectDrawSurface3_SetOverlayPosition(p,a,b) ICOM_CALL_(SetOverlayPosition,p,(p,a,b)) -#define IDirectDrawSurface3_SetPalette(p,a) ICOM_CALL_(SetPalette,p,(p,a)) -#define IDirectDrawSurface3_Unlock(p,a) ICOM_CALL_(Unlock,p,(p,a)) -#define IDirectDrawSurface3_UpdateOverlay(p,a,b,c,d,e) ICOM_CALL_(UpdateOverlay,p,(p,a,b,c,d,e)) -#define IDirectDrawSurface3_UpdateOverlayDisplay(p,a) ICOM_CALL_(UpdateOverlayDisplay,p,(p,a)) -#define IDirectDrawSurface3_UpdateOverlayZOrder(p,a,b) ICOM_CALL_(UpdateOverlayZOrder,p,(p,a,b)) -/*** IDirectDrawSurface2 methods ***/ -#define IDirectDrawSurface3_GetDDInterface(p,a) ICOM_CALL_(GetDDInterface,p,(p,a)) -#define IDirectDrawSurface3_PageLock(p,a) ICOM_CALL_(PageLock,p,(p,a)) -#define IDirectDrawSurface3_PageUnlock(p,a) ICOM_CALL_(PageUnlock,p,(p,a)) -/*** IDirectDrawSurface3 methods ***/ -#define IDirectDrawSurface3_SetSurfaceDesc(p,a,b) ICOM_CALL_(SetSurfaceDesc,p,(p,a,b)) - - -/***************************************************************************** - * IDirectDrawSurface4 interface - */ -/* Cannot inherit from IDirectDrawSurface2 because DDSCAPS changed to DDSCAPS2. - */ -#undef INTERFACE -#define INTERFACE IDirectDrawSurface4 -DECLARE_INTERFACE_(IDirectDrawSurface4,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface) PURE; - STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE; - STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE4 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE; - STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE; - STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE4 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE; - STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE4 lpDDSAttachedSurface) PURE; - STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpEnumSurfacesCallback) PURE; - STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK lpfnCallback) PURE; - STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE4 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE; - STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS2 lpDDSCaps, LPDIRECTDRAWSURFACE4* lplpDDAttachedSurface) PURE; - STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(GetCaps)(THIS_ LPDDSCAPS2 lpDDSCaps) PURE; - STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER* lplpDDClipper) PURE; - STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; - STDMETHOD(GetDC)(THIS_ HDC* lphDC) PURE; - STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE; - STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE* lplpDDPalette) PURE; - STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE; - STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSurfaceDesc) PURE; - STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC lpDDSurfaceDesc) PURE; - STDMETHOD(IsLost)(THIS) PURE; - STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE; - STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE; - STDMETHOD(Restore)(THIS) PURE; - STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE; - STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; - STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE; - STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE; - STDMETHOD(Unlock)(THIS_ LPRECT lpSurfaceData) PURE; - STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE4 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE; - STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE4 lpDDSReference) PURE; - /* added in v2 */ - STDMETHOD(GetDDInterface)(THIS_ LPVOID* lplpDD) PURE; - STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE; - /* added in v3 */ - STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC lpDDSD, DWORD dwFlags) PURE; - /* added in v4 */ - STDMETHOD(SetPrivateData)(THIS_ REFGUID , LPVOID , DWORD , DWORD ) PURE; - STDMETHOD(GetPrivateData)(THIS_ REFGUID , LPVOID , LPDWORD ) PURE; - STDMETHOD(FreePrivateData)(THIS_ REFGUID ) PURE; - STDMETHOD(GetUniquenessValue)(THIS_ LPDWORD ) PURE; - STDMETHOD(ChangeUniquenessValue)(THIS) PURE; -}; - - /*** IUnknown methods ***/ -#define IDirectDrawSurface4_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) -#define IDirectDrawSurface4_AddRef(p) ICOM_CALL_(AddRef,p,(p)) -#define IDirectDrawSurface4_Release(p) ICOM_CALL_(Release,p,(p)) -/*** IDirectDrawSurface (almost) methods ***/ -#define IDirectDrawSurface4_AddAttachedSurface(p,a) ICOM_CALL_(AddAttachedSurface,p,(p,a)) -#define IDirectDrawSurface4_AddOverlayDirtyRect(p,a) ICOM_CALL_(AddOverlayDirtyRect,p,(p,a)) -#define IDirectDrawSurface4_Blt(p,a,b,c,d,e) ICOM_CALL_(Blt,p,(p,a,b,c,d,e)) -#define IDirectDrawSurface4_BltBatch(p,a,b,c) ICOM_CALL_(BltBatch,p,(p,a,b,c)) -#define IDirectDrawSurface4_BltFast(p,a,b,c,d,e) ICOM_CALL_(BltFast,p,(p,a,b,c,d,e)) -#define IDirectDrawSurface4_DeleteAttachedSurface(p,a,b) ICOM_CALL_(DeleteAttachedSurface,p,(p,a,b)) -#define IDirectDrawSurface4_EnumAttachedSurfaces(p,a,b) ICOM_CALL_(EnumAttachedSurfaces,p,(p,a,b)) -#define IDirectDrawSurface4_EnumOverlayZOrders(p,a,b,c) ICOM_CALL_(EnumOverlayZOrders,p,(p,a,b,c)) -#define IDirectDrawSurface4_Flip(p,a,b) ICOM_CALL_(Flip,p,(p,a,b)) -#define IDirectDrawSurface4_GetAttachedSurface(p,a,b) ICOM_CALL_(GetAttachedSurface,p,(p,a,b)) -#define IDirectDrawSurface4_GetBltStatus(p,a) ICOM_CALL_(GetBltStatus,p,(p,a)) -#define IDirectDrawSurface4_GetCaps(p,a) ICOM_CALL_(GetCaps,p,(p,a)) -#define IDirectDrawSurface4_GetClipper(p,a) ICOM_CALL_(GetClipper,p,(p,a)) -#define IDirectDrawSurface4_GetColorKey(p,a,b) ICOM_CALL_(GetColorKey,p,(p,a,b)) -#define IDirectDrawSurface4_GetDC(p,a) ICOM_CALL_(GetDC,p,(p,a)) -#define IDirectDrawSurface4_GetFlipStatus(p,a) ICOM_CALL_(GetFlipStatus,p,(p,a)) -#define IDirectDrawSurface4_GetOverlayPosition(p,a,b) ICOM_CALL_(GetOverlayPosition,p,(p,a,b)) -#define IDirectDrawSurface4_GetPalette(p,a) ICOM_CALL_(GetPalette,p,(p,a)) -#define IDirectDrawSurface4_GetPixelFormat(p,a) ICOM_CALL_(GetPixelFormat,p,(p,a)) -#define IDirectDrawSurface4_GetSurfaceDesc(p,a) ICOM_CALL_(GetSurfaceDesc,p,(p,a)) -#define IDirectDrawSurface4_Initialize(p,a,b) ICOM_CALL_(Initialize,p,(p,a,b)) -#define IDirectDrawSurface4_IsLost(p) ICOM_CALL_(IsLost,p,(p)) -#define IDirectDrawSurface4_Lock(p,a,b,c,d) ICOM_CALL_(Lock,p,(p,a,b,c,d)) -#define IDirectDrawSurface4_ReleaseDC(p,a) ICOM_CALL_(ReleaseDC,p,(p,a)) -#define IDirectDrawSurface4_Restore(p) ICOM_CALL_(Restore,p,(p)) -#define IDirectDrawSurface4_SetClipper(p,a) ICOM_CALL_(SetClipper,p,(p,a)) -#define IDirectDrawSurface4_SetColorKey(p,a,b) ICOM_CALL_(SetColorKey,p,(p,a,b)) -#define IDirectDrawSurface4_SetOverlayPosition(p,a,b) ICOM_CALL_(SetOverlayPosition,p,(p,a,b)) -#define IDirectDrawSurface4_SetPalette(p,a) ICOM_CALL_(SetPalette,p,(p,a)) -#define IDirectDrawSurface4_Unlock(p,a) ICOM_CALL_(Unlock,p,(p,a)) -#define IDirectDrawSurface4_UpdateOverlay(p,a,b,c,d,e) ICOM_CALL_(UpdateOverlay,p,(p,a,b,c,d,e)) -#define IDirectDrawSurface4_UpdateOverlayDisplay(p,a) ICOM_CALL_(UpdateOverlayDisplay,p,(p,a)) -#define IDirectDrawSurface4_UpdateOverlayZOrder(p,a,b) ICOM_CALL_(UpdateOverlayZOrder,p,(p,a,b)) -/*** IDirectDrawSurface2 methods ***/ -#define IDirectDrawSurface4_GetDDInterface(p,a) ICOM_CALL_(GetDDInterface,p,(p,a)) -#define IDirectDrawSurface4_PageLock(p,a) ICOM_CALL_(PageLock,p,(p,a)) -#define IDirectDrawSurface4_PageUnlock(p,a) ICOM_CALL_(PageUnlock,p,(p,a)) -/*** IDirectDrawSurface3 methods ***/ -#define IDirectDrawSurface4_SetSurfaceDesc(p,a,b) ICOM_CALL_(SetSurfaceDesc,p,(p,a,b)) -/*** IDirectDrawSurface4 methods ***/ -#define IDirectDrawSurface4_SetPrivateData(p,a,b,c,d) ICOM_CALL_(SetPrivateData,p,(p,a,b,c,d)) -#define IDirectDrawSurface4_GetPrivateData(p,a,b,c) ICOM_CALL_(GetPrivateData,p,(p,a,b,c)) -#define IDirectDrawSurface4_FreePrivateData(p,a) ICOM_CALL_(FreePrivateData,p,(p,a)) -#define IDirectDrawSurface4_GetUniquenessValue(p,a) ICOM_CALL_(GetUniquenessValue,p,(p,a)) -#define IDirectDrawSurface4_ChangeUniquenessValue(p) ICOM_CALL_(ChangeUniquenessValue,p,(p)) - - -/***************************************************************************** - * IDirectDrawSurface7 interface - */ -#undef INTERFACE -#define INTERFACE IDirectDrawSurface7 -DECLARE_INTERFACE_(IDirectDrawSurface7,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(AddAttachedSurface)(THIS_ LPDIRECTDRAWSURFACE7 lpDDSAttachedSurface) PURE; - STDMETHOD(AddOverlayDirtyRect)(THIS_ LPRECT lpRect) PURE; - STDMETHOD(Blt)(THIS_ LPRECT lpDestRect, LPDIRECTDRAWSURFACE7 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwFlags, LPDDBLTFX lpDDBltFx) PURE; - STDMETHOD(BltBatch)(THIS_ LPDDBLTBATCH lpDDBltBatch, DWORD dwCount, DWORD dwFlags) PURE; - STDMETHOD(BltFast)(THIS_ DWORD dwX, DWORD dwY, LPDIRECTDRAWSURFACE7 lpDDSrcSurface, LPRECT lpSrcRect, DWORD dwTrans) PURE; - STDMETHOD(DeleteAttachedSurface)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE7 lpDDSAttachedSurface) PURE; - STDMETHOD(EnumAttachedSurfaces)(THIS_ LPVOID lpContext, LPDDENUMSURFACESCALLBACK7 lpEnumSurfacesCallback) PURE; - STDMETHOD(EnumOverlayZOrders)(THIS_ DWORD dwFlags, LPVOID lpContext, LPDDENUMSURFACESCALLBACK7 lpfnCallback) PURE; - STDMETHOD(Flip)(THIS_ LPDIRECTDRAWSURFACE7 lpDDSurfaceTargetOverride, DWORD dwFlags) PURE; - STDMETHOD(GetAttachedSurface)(THIS_ LPDDSCAPS2 lpDDSCaps, LPDIRECTDRAWSURFACE7* lplpDDAttachedSurface) PURE; - STDMETHOD(GetBltStatus)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(GetCaps)(THIS_ LPDDSCAPS2 lpDDSCaps) PURE; - STDMETHOD(GetClipper)(THIS_ LPDIRECTDRAWCLIPPER* lplpDDClipper) PURE; - STDMETHOD(GetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; - STDMETHOD(GetDC)(THIS_ HDC* lphDC) PURE; - STDMETHOD(GetFlipStatus)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(GetOverlayPosition)(THIS_ LPLONG lplX, LPLONG lplY) PURE; - STDMETHOD(GetPalette)(THIS_ LPDIRECTDRAWPALETTE* lplpDDPalette) PURE; - STDMETHOD(GetPixelFormat)(THIS_ LPDDPIXELFORMAT lpDDPixelFormat) PURE; - STDMETHOD(GetSurfaceDesc)(THIS_ LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE; - STDMETHOD(Initialize)(THIS_ LPDIRECTDRAW lpDD, LPDDSURFACEDESC2 lpDDSurfaceDesc) PURE; - STDMETHOD(IsLost)(THIS) PURE; - STDMETHOD(Lock)(THIS_ LPRECT lpDestRect, LPDDSURFACEDESC2 lpDDSurfaceDesc, DWORD dwFlags, HANDLE hEvent) PURE; - STDMETHOD(ReleaseDC)(THIS_ HDC hDC) PURE; - STDMETHOD(Restore)(THIS) PURE; - STDMETHOD(SetClipper)(THIS_ LPDIRECTDRAWCLIPPER lpDDClipper) PURE; - STDMETHOD(SetColorKey)(THIS_ DWORD dwFlags, LPDDCOLORKEY lpDDColorKey) PURE; - STDMETHOD(SetOverlayPosition)(THIS_ LONG lX, LONG lY) PURE; - STDMETHOD(SetPalette)(THIS_ LPDIRECTDRAWPALETTE lpDDPalette) PURE; - STDMETHOD(Unlock)(THIS_ LPRECT lpSurfaceData) PURE; - STDMETHOD(UpdateOverlay)(THIS_ LPRECT lpSrcRect, LPDIRECTDRAWSURFACE7 lpDDDestSurface, LPRECT lpDestRect, DWORD dwFlags, LPDDOVERLAYFX lpDDOverlayFx) PURE; - STDMETHOD(UpdateOverlayDisplay)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(UpdateOverlayZOrder)(THIS_ DWORD dwFlags, LPDIRECTDRAWSURFACE7 lpDDSReference) PURE; - /* added in v2 */ - STDMETHOD(GetDDInterface)(THIS_ LPVOID* lplpDD) PURE; - STDMETHOD(PageLock)(THIS_ DWORD dwFlags) PURE; - STDMETHOD(PageUnlock)(THIS_ DWORD dwFlags) PURE; - /* added in v3 */ - STDMETHOD(SetSurfaceDesc)(THIS_ LPDDSURFACEDESC2 lpDDSD, DWORD dwFlags) PURE; - /* added in v4 */ - STDMETHOD(SetPrivateData)(THIS_ REFGUID , LPVOID , DWORD , DWORD ) PURE; - STDMETHOD(GetPrivateData)(THIS_ REFGUID , LPVOID , LPDWORD ) PURE; - STDMETHOD(FreePrivateData)(THIS_ REFGUID ) PURE; - STDMETHOD(GetUniquenessValue)(THIS_ LPDWORD ) PURE; - STDMETHOD(ChangeUniquenessValue)(THIS) PURE; - /* added in v7 */ - STDMETHOD(SetPriority)(THIS_ DWORD prio) PURE; - STDMETHOD(GetPriority)(THIS_ LPDWORD prio) PURE; - STDMETHOD(SetLOD)(THIS_ DWORD lod) PURE; - STDMETHOD(GetLOD)(THIS_ LPDWORD lod) PURE; -}; - - /*** IUnknown methods ***/ -#define IDirectDrawSurface7_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) -#define IDirectDrawSurface7_AddRef(p) ICOM_CALL_(AddRef,p,(p)) -#define IDirectDrawSurface7_Release(p) ICOM_CALL_(Release,p,(p)) -/*** IDirectDrawSurface (almost) methods ***/ -#define IDirectDrawSurface7_AddAttachedSurface(p,a) ICOM_CALL_(AddAttachedSurface,p,(p,a)) -#define IDirectDrawSurface7_AddOverlayDirtyRect(p,a) ICOM_CALL_(AddOverlayDirtyRect,p,(p,a)) -#define IDirectDrawSurface7_Blt(p,a,b,c,d,e) ICOM_CALL_(Blt,p,(p,a,b,c,d,e)) -#define IDirectDrawSurface7_BltBatch(p,a,b,c) ICOM_CALL_(BltBatch,p,(p,a,b,c)) -#define IDirectDrawSurface7_BltFast(p,a,b,c,d,e) ICOM_CALL_(BltFast,p,(p,a,b,c,d,e)) -#define IDirectDrawSurface7_DeleteAttachedSurface(p,a,b) ICOM_CALL_(DeleteAttachedSurface,p,(p,a,b)) -#define IDirectDrawSurface7_EnumAttachedSurfaces(p,a,b) ICOM_CALL_(EnumAttachedSurfaces,p,(p,a,b)) -#define IDirectDrawSurface7_EnumOverlayZOrders(p,a,b,c) ICOM_CALL_(EnumOverlayZOrders,p,(p,a,b,c)) -#define IDirectDrawSurface7_Flip(p,a,b) ICOM_CALL_(Flip,p,(p,a,b)) -#define IDirectDrawSurface7_GetAttachedSurface(p,a,b) ICOM_CALL_(GetAttachedSurface,p,(p,a,b)) -#define IDirectDrawSurface7_GetBltStatus(p,a) ICOM_CALL_(GetBltStatus,p,(p,a)) -#define IDirectDrawSurface7_GetCaps(p,a) ICOM_CALL_(GetCaps,p,(p,a)) -#define IDirectDrawSurface7_GetClipper(p,a) ICOM_CALL_(GetClipper,p,(p,a)) -#define IDirectDrawSurface7_GetColorKey(p,a,b) ICOM_CALL_(GetColorKey,p,(p,a,b)) -#define IDirectDrawSurface7_GetDC(p,a) ICOM_CALL_(GetDC,p,(p,a)) -#define IDirectDrawSurface7_GetFlipStatus(p,a) ICOM_CALL_(GetFlipStatus,p,(p,a)) -#define IDirectDrawSurface7_GetOverlayPosition(p,a,b) ICOM_CALL_(GetOverlayPosition,p,(p,a,b)) -#define IDirectDrawSurface7_GetPalette(p,a) ICOM_CALL_(GetPalette,p,(p,a)) -#define IDirectDrawSurface7_GetPixelFormat(p,a) ICOM_CALL_(GetPixelFormat,p,(p,a)) -#define IDirectDrawSurface7_GetSurfaceDesc(p,a) ICOM_CALL_(GetSurfaceDesc,p,(p,a)) -#define IDirectDrawSurface7_Initialize(p,a,b) ICOM_CALL_(Initialize,p,(p,a,b)) -#define IDirectDrawSurface7_IsLost(p) ICOM_CALL_(IsLost,p,(p)) -#define IDirectDrawSurface7_Lock(p,a,b,c,d) ICOM_CALL_(Lock,p,(p,a,b,c,d)) -#define IDirectDrawSurface7_ReleaseDC(p,a) ICOM_CALL_(ReleaseDC,p,(p,a)) -#define IDirectDrawSurface7_Restore(p) ICOM_CALL_(Restore,p,(p)) -#define IDirectDrawSurface7_SetClipper(p,a) ICOM_CALL_(SetClipper,p,(p,a)) -#define IDirectDrawSurface7_SetColorKey(p,a,b) ICOM_CALL_(SetColorKey,p,(p,a,b)) -#define IDirectDrawSurface7_SetOverlayPosition(p,a,b) ICOM_CALL_(SetOverlayPosition,p,(p,a,b)) -#define IDirectDrawSurface7_SetPalette(p,a) ICOM_CALL_(SetPalette,p,(p,a)) -#define IDirectDrawSurface7_Unlock(p,a) ICOM_CALL_(Unlock,p,(p,a)) -#define IDirectDrawSurface7_UpdateOverlay(p,a,b,c,d,e) ICOM_CALL_(UpdateOverlay,p,(p,a,b,c,d,e)) -#define IDirectDrawSurface7_UpdateOverlayDisplay(p,a) ICOM_CALL_(UpdateOverlayDisplay,p,(p,a)) -#define IDirectDrawSurface7_UpdateOverlayZOrder(p,a,b) ICOM_CALL_(UpdateOverlayZOrder,p,(p,a,b)) -/*** IDirectDrawSurface2 methods ***/ -#define IDirectDrawSurface7_GetDDInterface(p,a) ICOM_CALL_(GetDDInterface,p,(p,a)) -#define IDirectDrawSurface7_PageLock(p,a) ICOM_CALL_(PageLock,p,(p,a)) -#define IDirectDrawSurface7_PageUnlock(p,a) ICOM_CALL_(PageUnlock,p,(p,a)) -/*** IDirectDrawSurface3 methods ***/ -#define IDirectDrawSurface7_SetSurfaceDesc(p,a,b) ICOM_CALL_(SetSurfaceDesc,p,(p,a,b)) -/*** IDirectDrawSurface4 methods ***/ -#define IDirectDrawSurface7_SetPrivateData(p,a,b,c,d) ICOM_CALL_(SetPrivateData,p,(p,a,b,c,d)) -#define IDirectDrawSurface7_GetPrivateData(p,a,b,c) ICOM_CALL_(GetPrivateData,p,(p,a,b,c)) -#define IDirectDrawSurface7_FreePrivateData(p,a) ICOM_CALL_(FreePrivateData,p,(p,a)) -#define IDirectDrawSurface7_GetUniquenessValue(p,a) ICOM_CALL_(GetUniquenessValue,p,(p,a)) -#define IDirectDrawSurface7_ChangeUniquenessValue(p) ICOM_CALL_(ChangeUniquenessValue,p,(p)) -/*** IDirectDrawSurface7 methods ***/ -#define IDirectDrawSurface7_SetPriority(p,a) ICOM_CALL_(SetPriority,p,(p,a)) -#define IDirectDrawSurface7_GetPriority(p,a) ICOM_CALL_(GetPriority,p,(p,a)) -#define IDirectDrawSurface7_SetLOD(p,a) ICOM_CALL_(SetLOD,p,(p,a)) -#define IDirectDrawSurface7_GetLOD(p,a) ICOM_CALL_(GetLOD,p,(p,a)) - -/***************************************************************************** - * IDirectDrawColorControl interface - */ -#undef INTERFACE -#define INTERFACE IDirectDrawColorControl -DECLARE_INTERFACE_(IDirectDrawColorControl,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(GetColorControls)(THIS_ LPDDCOLORCONTROL lpColorControl) PURE; - STDMETHOD(SetColorControls)(THIS_ LPDDCOLORCONTROL lpColorControl) PURE; -}; - - /*** IUnknown methods ***/ -#define IDirectDrawColorControl_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) -#define IDirectDrawColorControl_AddRef(p) ICOM_CALL_(AddRef,p,(p)) -#define IDirectDrawColorControl_Release(p) ICOM_CALL_(Release,p,(p)) - /*** IDirectDrawColorControl methods ***/ -#define IDirectDrawColorControl_GetColorControls(p,a) ICOM_CALL_(GetColorControls,p,(p,a)) -#define IDirectDrawColorControl_SetColorControls(p,a) ICOM_CALL_(SetColorControls,p,(p,a)) - -/***************************************************************************** - * IDirectDrawGammaControl interface - */ -#undef INTERFACE -#define INTERFACE IDirectDrawGammaControl -DECLARE_INTERFACE_(IDirectDrawGammaControl,IUnknown) -{ - STDMETHOD(QueryInterface)(THIS_ REFIID,LPVOID*) PURE; - STDMETHOD_(ULONG,AddRef)(THIS) PURE; - STDMETHOD_(ULONG,Release)(THIS) PURE; - STDMETHOD(GetGammaRamp)(THIS_ DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp) PURE; - STDMETHOD(SetGammaRamp)(THIS_ DWORD dwFlags, LPDDGAMMARAMP lpGammaRamp) PURE; -}; - - /*** IUnknown methods ***/ -#define IDirectDrawGammaControl_QueryInterface(p,a,b) ICOM_CALL_(QueryInterface,p,(p,a,b)) -#define IDirectDrawGammaControl_AddRef(p) ICOM_CALL_(AddRef,p,(p)) -#define IDirectDrawGammaControl_Release(p) ICOM_CALL_(Release,p,(p)) - /*** IDirectDrawGammaControl methods ***/ -#define IDirectDrawGammaControl_GetGammaRamp(p,a,b) ICOM_CALL_(GetGammaRamp,p,(p,a,b)) -#define IDirectDrawGammaControl_SetGammaRamp(p,a,b) ICOM_CALL_(SetGammaRamp,p,(p,a,b)) - - -HRESULT WINAPI DirectDrawCreate(LPGUID,LPDIRECTDRAW*,LPUNKNOWN); -HRESULT WINAPI DirectDrawCreateEx(LPGUID,LPVOID*,REFIID,LPUNKNOWN); -HRESULT WINAPI DirectDrawEnumerateA(LPDDENUMCALLBACKA,LPVOID); -HRESULT WINAPI DirectDrawEnumerateW(LPDDENUMCALLBACKW,LPVOID); -#define DirectDrawEnumerate WINELIB_NAME_AW(DirectDrawEnumerate) -HRESULT WINAPI DirectDrawCreateClipper(DWORD,LPDIRECTDRAWCLIPPER*,LPUNKNOWN); - - -#ifdef __cplusplus -} /* extern "C" */ -#endif /* defined(__cplusplus) */ - -#endif /* __XWIN_DDRAW_H */ diff --git a/xorg-server/hw/xwin/glx/gen_gl_wrappers.py b/xorg-server/hw/xwin/glx/gen_gl_wrappers.py index 127e8b21d..6bba3079e 100644 --- a/xorg-server/hw/xwin/glx/gen_gl_wrappers.py +++ b/xorg-server/hw/xwin/glx/gen_gl_wrappers.py @@ -239,10 +239,12 @@ for w in sorted(wrappers.keys()) : if wrappers[w]['category'].startswith('VERSION_1_0') or wrappers[w]['category'].startswith('VERSION_1_1') : if staticwrappers : print 'static', - print returntype + ' ' + funcname + 'Wrapper(' + arglist + ')' + print returntype + ' __stdcall ' + funcname + 'Wrapper(' + arglist + ')' print '{' + print '#ifdef _DEBUG' print ' if (glxWinDebugSettings.enable' + prefix.upper() + 'callTrace) ErrorF("'+ funcname + '\\n");' print ' glWinDirectProcCalls++;' + print '#endif' if returntype.lower() == 'void' : print ' ' + funcname + '(', else : @@ -257,7 +259,7 @@ for w in sorted(wrappers.keys()) : else: if staticwrappers : print 'static', - print returntype + ' ' + funcname + 'Wrapper(' + arglist + ')' + print returntype + ' __stdcall ' + funcname + 'Wrapper(' + arglist + ')' print '{' stringname = funcname @@ -287,11 +289,15 @@ for w in sorted(wrappers.keys()) : if returntype.lower() == 'void' : print ' RESOLVE(' + pfntypename + ', "' + stringname + '");' + print '#ifdef _DEBUG' print ' if (glxWinDebugSettings.enable' + prefix.upper() + 'callTrace) ErrorF("'+ funcname + '\\n");' + print '#endif' print ' RESOLVED_PROC(' + pfntypename + ')(', else : print ' RESOLVE_RET(' + pfntypename + ', "' + stringname + '", FALSE);' + print '#ifdef _DEBUG' print ' if (glxWinDebugSettings.enable' + prefix.upper() + 'callTrace) ErrorF("'+ funcname + '\\n");' + print '#endif' print ' return RESOLVED_PROC(' + pfntypename + ')(', if arglist != 'void' : diff --git a/xorg-server/hw/xwin/glx/gl.spec b/xorg-server/hw/xwin/glx/gl.spec new file mode 100644 index 000000000..98f364d53 --- /dev/null +++ b/xorg-server/hw/xwin/glx/gl.spec @@ -0,0 +1,26844 @@ +# gl.spec file +# DON'T REMOVE PREVIOUS LINE!!! libspec depends on it! +# +# Copyright (c) 1991-2005 Silicon Graphics, Inc. All Rights Reserved. +# Copyright (c) 2006-2009 The Khronos Group Inc. +# +# This document is licensed under the SGI Free Software B License Version +# 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + + +required-props: +# Description of a parameter +param: retval retained +# Display list flags +dlflags: notlistable handcode +# GLX implementation flags +glxflags: client-intercept client-handcode server-handcode EXT SGI ignore ARB +# Vector ('v') equivalent form of a command taking 1-4 explicit xyzw/rgba arguments +vectorequiv: * +# Category this function falls in. While there are many categories for +# early GL 1.0 functions, later functions just have a core version +# (e.g. VERSION_major_minor) or extension name for the category. +category: display-list drawing drawing-control feedback framebuf misc modeling pixel-op pixel-rw state-req xform VERSION_1_0 VERSION_1_0_DEPRECATED VERSION_1_1 VERSION_1_1_DEPRECATED VERSION_1_2 VERSION_1_2_DEPRECATED VERSION_1_3 VERSION_1_3_DEPRECATED VERSION_1_4 VERSION_1_4_DEPRECATED VERSION_1_5 VERSION_2_0 VERSION_2_1 VERSION_3_0 VERSION_3_0_DEPRECATED VERSION_3_1 VERSION_3_2 ATI_element_array ATI_envmap_bumpmap ATI_fragment_shader ATI_pn_triangles ATI_vertex_array_object ATI_vertex_streams EXT_blend_color EXT_blend_minmax EXT_convolution EXT_copy_texture EXT_histogram EXT_polygon_offset EXT_subtexture EXT_texture3D EXT_texture_object EXT_vertex_array EXT_vertex_shader SGIS_detail_texture SGIS_multisample SGIS_pixel_texture ARB_point_parameters EXT_point_parameters SGIS_point_parameters SGIS_sharpen_texture SGIS_texture4D SGIS_texture_filter4 SGIX_async SGIX_flush_raster SGIX_fragment_lighting SGIX_framezoom SGIX_igloo_interface SGIX_instruments SGIX_list_priority SGIX_pixel_texture SGIX_polynomial_ffd SGIX_reference_plane SGIX_sprite SGIX_tag_sample_buffer SGI_color_table ARB_multitexture ARB_multisample ARB_texture_compression ARB_transpose_matrix ARB_vertex_blend ARB_matrix_palette EXT_compiled_vertex_array EXT_cull_vertex EXT_index_func EXT_index_material EXT_draw_range_elements EXT_vertex_weighting INGR_blend_func_separate NV_evaluators NV_fence NV_occlusion_query NV_point_sprite NV_register_combiners NV_register_combiners2 NV_vertex_array_range NV_vertex_program NV_vertex_program1_1_dcc MESA_resize_buffers MESA_window_pos PGI_misc_hints EXT_fog_coord EXT_blend_func_separate EXT_color_subtable EXT_coordinate_frame EXT_light_texture EXT_multi_draw_arrays EXT_paletted_texture EXT_pixel_transform EXT_secondary_color EXT_texture_perturb_normal HP_image_transform IBM_multimode_draw_arrays IBM_vertex_array_lists INTEL_parallel_arrays SUNX_constant_data SUN_global_alpha SUN_mesh_array SUN_triangle_list SUN_vertex 3DFX_tbuffer EXT_multisample SGIS_fog_function SGIS_texture_color_mask ARB_window_pos EXT_stencil_two_side EXT_depth_bounds_test EXT_blend_equation_separate ARB_vertex_program ARB_fragment_program ARB_vertex_buffer_object ARB_occlusion_query ARB_shader_objects ARB_vertex_shader ARB_fragment_shader S3_s3tc ATI_draw_buffers ATI_texture_env_combine3 ATI_texture_float NV_float_buffer NV_fragment_program NV_half_float NV_pixel_data_range NV_primitive_restart NV_texture_expand_normal NV_texture_expand_normal NV_vertex_program2 APPLE_element_array APPLE_fence APPLE_vertex_array_object APPLE_vertex_array_range ATI_draw_buffers NV_fragment_program NV_half_float NV_pixel_data_range NV_primitive_restart ATI_map_object_buffer ATI_separate_stencil ATI_vertex_attrib_array_object ARB_draw_buffers ARB_texture_rectangle ARB_color_buffer_float EXT_framebuffer_object GREMEDY_string_marker EXT_stencil_clear_tag EXT_framebuffer_blit EXT_framebuffer_multisample MESAX_texture_stack EXT_timer_query EXT_gpu_program_parameters APPLE_flush_buffer_range NV_gpu_program4 NV_geometry_program4 EXT_geometry_shader4 NV_vertex_program4 EXT_gpu_shader4 EXT_draw_instanced EXT_texture_buffer_object NV_depth_buffer_float NV_framebuffer_multisample_coverage NV_parameter_buffer_object EXT_draw_buffers2 NV_transform_feedback EXT_bindable_uniform EXT_texture_integer GREMEDY_frame_terminator NV_conditional_render NV_present_video EXT_transform_feedback ARB_depth_buffer_float ARB_draw_instanced ARB_framebuffer_object ARB_framebuffer_sRGB ARB_geometry_shader4 ARB_half_float_vertex ARB_instanced_arrays ARB_map_buffer_range ARB_texture_buffer_object ARB_texture_compression_rgtc ARB_texture_rg ARB_vertex_array_object EXT_direct_state_access EXT_vertex_array_bgra EXT_texture_swizzle NV_explicit_multisample NV_transform_feedback2 ATI_meminfo AMD_performance_monitor AMD_vertex_shader_tesselator EXT_provoking_vertex ARB_uniform_buffer_object ARB_copy_buffer EXT_texture_snorm AMD_draw_buffers_blend APPLE_texture_range APPLE_float_pixels APPLE_vertex_program_evaluators APPLE_aux_depth_stencil APPLE_object_purgeable APPLE_row_bytes ARB_draw_elements_base_vertex ARB_provoking_vertex ARB_sync ARB_texture_multisample ARB_draw_buffers_blend ARB_sample_shading NV_video_capture NV_copy_image EXT_separate_shader_objects NV_parameter_buffer_object2 NV_shader_buffer_load NV_vertex_buffer_unified_memory NV_texture_barrier + +# Categories for extensions with no functions - need not be included now +# ARB_texture_env_add ARB_texture_cube_map ARB_texture_border_clamp +# ARB_shading_language_100 ARB_texture_non_power_of_two ARB_point_sprite +# ARB_half_float_pixel ARB_texture_float ARB_pixel_buffer_object EXT_abgr +# EXT_texture SGI_color_matrix SGI_texture_color_table EXT_cmyka +# EXT_packed_pixels SGIS_texture_lod EXT_rescale_normal EXT_misc_attribute +# SGIS_generate_mipmap SGIX_clipmap SGIX_shadow SGIS_texture_edge_clamp +# SGIS_texture_border_clamp EXT_blend_subtract EXT_blend_logic_op +# SGIX_async_histogram SGIX_async_pixel SGIX_interlace SGIX_pixel_tiles +# SGIX_texture_select SGIX_texture_multi_buffer SGIX_texture_scale_bias +# SGIX_depth_texture SGIX_fog_offset HP_convolution_border_modes +# SGIX_texture_add_env PGI_vertex_hints EXT_clip_volume_hint +# SGIX_ir_instrument1 SGIX_calligraphic_fragment SGIX_texture_lod_bias +# SGIX_shadow_ambient EXT_index_texture EXT_index_array_formats SGIX_ycrcb +# IBM_rasterpos_clip HP_texture_lighting WIN_phong_shading +# WIN_specular_fog SGIX_blend_alpha_minmax EXT_bgra HP_occlusion_test +# EXT_pixel_transform_color_table EXT_shared_texture_palette +# EXT_separate_specular_color EXT_texture_env REND_screen_coordinates +# EXT_texture_env_combine APPLE_specular_vector APPLE_transform_hint +# SGIX_fog_scale INGR_color_clamp INGR_interlace_read EXT_stencil_wrap +# EXT_422_pixels NV_texgen_reflection SUN_convolution_border_modes +# SUN_slice_accum EXT_texture_env_add EXT_texture_lod_bias +# EXT_texture_filter_anisotropic NV_light_max_exponent NV_fog_distance +# NV_texgen_emboss NV_blend_square NV_texture_env_combine4 +# NV_packed_depth_stencil NV_texture_compression_vtc NV_texture_rectangle +# NV_texture_shader NV_texture_shader2 NV_vertex_array_range2 +# IBM_cull_vertex SGIX_subsample SGIX_ycrcba SGIX_ycrcb_subsample +# SGIX_depth_pass_instrument 3DFX_texture_compression_FXT1 +# 3DFX_multisample SGIX_vertex_preclip SGIX_convolution_accuracy +# SGIX_resample SGIX_scalebias_hint SGIX_texture_coordinate_clamp +# EXT_shadow_funcs MESA_pack_invert MESA_ycbcr_texture EXT_packed_float +# EXT_texture_array EXT_texture_compression_latc +# EXT_texture_compression_rgtc EXT_texture_shared_exponent +# NV_fragment_program4 EXT_framebuffer_sRGB NV_geometry_shader4 +# EXT_vertex_array_bgra ARB_depth_clamp ARB_fragment_coord_conventions +# ARB_seamless_cube_map ARB_vertex_array_bgra ARB_texture_cube_map_array +# ARB_texture_gather ARB_texture_query_lod + +# Core version in which a function was introduced, or against +# which an extension can be implemented +version: 1.0 1.1 1.2 1.3 1.4 1.5 2.0 2.1 3.0 3.1 3.2 +# Core version in which a function was removed +deprecated: 3.1 +# GLX Single, Rendering, or Vendor Private opcode +glxsingle: * +glxropcode: * +glxvendorpriv: * +# WGL implementation flags (incomplete) +wglflags: client-handcode server-handcode small-data batchable +# Drivers in which this is implemented (very incomplete) +extension: future not_implemented soft WINSOFT NV10 NV20 NV50 +# Function this aliases (indistinguishable to the GL) +alias: * +# Mesa dispatch table offset (incomplete) +offset: * +# These properties are picked up from NVIDIA .spec files, we don't use them +glfflags: * +beginend: * +glxvectorequiv: * +subcategory: * +glextmask: * + +############################################################################### +# +# glxsingle, glxropcode, and other GLX allocations to vendors +# are used here, but the master registry for GLX is in +# /ogl/trunk/doc/registry/extensions.reserved +# +# XFree86 dispatch offsets: 0-645 +# 578-641 NV_vertex_program +# GLS opcodes: 0x0030-0x0269 +# +############################################################################### + +############################################################################### +# +# things to remember when adding an extension command +# +# - append new ARB and non-ARB extensions to the appropriate portion of +# the spec file, in extension number order. +# - use tabs, not spaces +# - set glxflags to "ignore" until GLX is updated to support the new command +# - add new data types to typemaps/spec2wire.map +# - add extension name in alphabetical order to category list +# - add commands within an extension in spec order +# - use existing command entries as a model (where possible) +# - when reserving new glxropcodes, update +# gfx/lib/opengl/doc/glspec/extensions.reserved to indicate this +# +############################################################################### + +# New type declarations + +passthru: #include <stddef.h> + +passthru: #ifndef GL_VERSION_2_0 +passthru: /* GL type for program/shader text */ +passthru: typedef char GLchar; +passthru: #endif +passthru: +passthru: #ifndef GL_VERSION_1_5 +passthru: /* GL types for handling large vertex buffer objects */ +passthru: typedef ptrdiff_t GLintptr; +passthru: typedef ptrdiff_t GLsizeiptr; +passthru: #endif +passthru: +passthru: #ifndef GL_ARB_vertex_buffer_object +passthru: /* GL types for handling large vertex buffer objects */ +passthru: typedef ptrdiff_t GLintptrARB; +passthru: typedef ptrdiff_t GLsizeiptrARB; +passthru: #endif +passthru: +passthru: #ifndef GL_ARB_shader_objects +passthru: /* GL types for program/shader text and shader object handles */ +passthru: typedef char GLcharARB; +passthru: typedef unsigned int GLhandleARB; +passthru: #endif +passthru: +passthru: /* GL type for "half" precision (s10e5) float data in host memory */ +passthru: #ifndef GL_ARB_half_float_pixel +passthru: typedef unsigned short GLhalfARB; +passthru: #endif +passthru: +passthru: #ifndef GL_NV_half_float +passthru: typedef unsigned short GLhalfNV; +passthru: #endif +passthru: +passthru: #ifndef GLEXT_64_TYPES_DEFINED +passthru: /* This code block is duplicated in glxext.h, so must be protected */ +passthru: #define GLEXT_64_TYPES_DEFINED +passthru: /* Define int32_t, int64_t, and uint64_t types for UST/MSC */ +passthru: /* (as used in the GL_EXT_timer_query extension). */ +passthru: #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L +passthru: #include <inttypes.h> +passthru: #elif defined(__sun__) || defined(__digital__) +passthru: #include <inttypes.h> +passthru: #if defined(__STDC__) +passthru: #if defined(__arch64__) || defined(_LP64) +passthru: typedef long int int64_t; +passthru: typedef unsigned long int uint64_t; +passthru: #else +passthru: typedef long long int int64_t; +passthru: typedef unsigned long long int uint64_t; +passthru: #endif /* __arch64__ */ +passthru: #endif /* __STDC__ */ +passthru: #elif defined( __VMS ) || defined(__sgi) +passthru: #include <inttypes.h> +passthru: #elif defined(__SCO__) || defined(__USLC__) +passthru: #include <stdint.h> +passthru: #elif defined(__UNIXOS2__) || defined(__SOL64__) +passthru: typedef long int int32_t; +passthru: typedef long long int int64_t; +passthru: typedef unsigned long long int uint64_t; +passthru: #elif defined(_WIN32) && defined(__GNUC__) +passthru: #include <stdint.h> +passthru: #elif defined(_WIN32) +passthru: typedef __int32 int32_t; +passthru: typedef __int64 int64_t; +passthru: typedef unsigned __int64 uint64_t; +passthru: #else +passthru: /* Fallback if nothing above works */ +passthru: #include <inttypes.h> +passthru: #endif +passthru: #endif +passthru: +passthru: #ifndef GL_EXT_timer_query +passthru: typedef int64_t GLint64EXT; +passthru: typedef uint64_t GLuint64EXT; +passthru: #endif +passthru: +passthru: #ifndef ARB_sync +passthru: typedef int64_t GLint64; +passthru: typedef uint64_t GLuint64; +passthru: typedef struct __GLsync *GLsync; +passthru: #endif +passthru: + +############################################################################### +############################################################################### +# +# OpenGL 1.0 commands +# +############################################################################### +############################################################################### + +############################################################################### +# +# drawing-control commands +# +############################################################################### + +CullFace(mode) + return void + param mode CullFaceMode in value + category VERSION_1_0 # old: drawing-control + version 1.0 + glxropcode 79 + offset 152 + +FrontFace(mode) + return void + param mode FrontFaceDirection in value + category VERSION_1_0 # old: drawing-control + version 1.0 + glxropcode 84 + offset 157 + +Hint(target, mode) + return void + param target HintTarget in value + param mode HintMode in value + category VERSION_1_0 # old: drawing-control + version 1.0 + glxropcode 85 + offset 158 + +LineWidth(width) + return void + param width CheckedFloat32 in value + category VERSION_1_0 # old: drawing-control + version 1.0 + glxropcode 95 + offset 168 + +PointSize(size) + return void + param size CheckedFloat32 in value + category VERSION_1_0 # old: drawing-control + version 1.0 + glxropcode 100 + offset 173 + +PolygonMode(face, mode) + return void + param face MaterialFace in value + param mode PolygonMode in value + category VERSION_1_0 # old: drawing-control + version 1.0 + glxropcode 101 + offset 174 + +Scissor(x, y, width, height) + return void + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + category VERSION_1_0 # old: drawing-control + version 1.0 + glxropcode 103 + offset 176 + +TexParameterf(target, pname, param) + return void + param target TextureTarget in value + param pname TextureParameterName in value + param param CheckedFloat32 in value + category VERSION_1_0 # old: drawing-control + version 1.0 + glxropcode 105 + wglflags small-data + offset 178 + +TexParameterfv(target, pname, params) + return void + param target TextureTarget in value + param pname TextureParameterName in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category VERSION_1_0 # old: drawing-control + version 1.0 + glxropcode 106 + wglflags small-data + offset 179 + +TexParameteri(target, pname, param) + return void + param target TextureTarget in value + param pname TextureParameterName in value + param param CheckedInt32 in value + category VERSION_1_0 # old: drawing-control + version 1.0 + glxropcode 107 + wglflags small-data + offset 180 + +TexParameteriv(target, pname, params) + return void + param target TextureTarget in value + param pname TextureParameterName in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category VERSION_1_0 # old: drawing-control + version 1.0 + glxropcode 108 + wglflags small-data + offset 181 + +TexImage1D(target, level, internalformat, width, border, format, type, pixels) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureComponentCount in value + param width SizeI in value + param border CheckedInt32 in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width)] + category VERSION_1_0 # old: drawing-control + dlflags handcode + glxflags client-handcode server-handcode + version 1.0 + glxropcode 109 + wglflags client-handcode server-handcode + offset 182 + +TexImage2D(target, level, internalformat, width, height, border, format, type, pixels) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureComponentCount in value + param width SizeI in value + param height SizeI in value + param border CheckedInt32 in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height)] + category VERSION_1_0 # old: drawing-control + dlflags handcode + glxflags client-handcode server-handcode + version 1.0 + glxropcode 110 + wglflags client-handcode server-handcode + offset 183 + +############################################################################### +# +# framebuf commands +# +############################################################################### + +DrawBuffer(mode) + return void + param mode DrawBufferMode in value + category VERSION_1_0 # old: framebuf + version 1.0 + glxropcode 126 + offset 202 + +Clear(mask) + return void + param mask ClearBufferMask in value + category VERSION_1_0 # old: framebuf + version 1.0 + glxropcode 127 + offset 203 + +ClearColor(red, green, blue, alpha) + return void + param red ClampedColorF in value + param green ClampedColorF in value + param blue ClampedColorF in value + param alpha ClampedColorF in value + category VERSION_1_0 # old: framebuf + version 1.0 + glxropcode 130 + offset 206 + +ClearStencil(s) + return void + param s StencilValue in value + category VERSION_1_0 # old: framebuf + version 1.0 + glxropcode 131 + offset 207 + +ClearDepth(depth) + return void + param depth ClampedFloat64 in value + category VERSION_1_0 # old: framebuf + version 1.0 + glxropcode 132 + offset 208 + +StencilMask(mask) + return void + param mask MaskedStencilValue in value + category VERSION_1_0 # old: framebuf + version 1.0 + glxropcode 133 + offset 209 + +ColorMask(red, green, blue, alpha) + return void + param red Boolean in value + param green Boolean in value + param blue Boolean in value + param alpha Boolean in value + category VERSION_1_0 # old: framebuf + version 1.0 + glxropcode 134 + offset 210 + +DepthMask(flag) + return void + param flag Boolean in value + category VERSION_1_0 # old: framebuf + version 1.0 + glxropcode 135 + offset 211 + +############################################################################### +# +# misc commands +# +############################################################################### + +Disable(cap) + return void + param cap EnableCap in value + category VERSION_1_0 # old: misc + version 1.0 + dlflags handcode + glxflags client-handcode client-intercept + glxropcode 138 + offset 214 + +Enable(cap) + return void + param cap EnableCap in value + category VERSION_1_0 # old: misc + version 1.0 + dlflags handcode + glxflags client-handcode client-intercept + glxropcode 139 + offset 215 + +Finish() + return void + dlflags notlistable + glxflags client-handcode server-handcode + category VERSION_1_0 # old: misc + version 1.0 + glxsingle 108 + offset 216 + +Flush() + return void + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + category VERSION_1_0 # old: misc + version 1.0 + glxsingle 142 + offset 217 + +############################################################################### +# +# pixel-op commands +# +############################################################################### + +BlendFunc(sfactor, dfactor) + return void + param sfactor BlendingFactorSrc in value + param dfactor BlendingFactorDest in value + category VERSION_1_0 # old: pixel-op + version 1.0 + glxropcode 160 + offset 241 + +LogicOp(opcode) + return void + param opcode LogicOp in value + category VERSION_1_0 # old: pixel-op + version 1.0 + glxropcode 161 + offset 242 + +StencilFunc(func, ref, mask) + return void + param func StencilFunction in value + param ref ClampedStencilValue in value + param mask MaskedStencilValue in value + category VERSION_1_0 # old: pixel-op + version 1.0 + glxropcode 162 + offset 243 + +StencilOp(fail, zfail, zpass) + return void + param fail StencilOp in value + param zfail StencilOp in value + param zpass StencilOp in value + category VERSION_1_0 # old: pixel-op + version 1.0 + glxropcode 163 + offset 244 + +DepthFunc(func) + return void + param func DepthFunction in value + category VERSION_1_0 # old: pixel-op + version 1.0 + glxropcode 164 + offset 245 + +############################################################################### +# +# pixel-rw commands +# +############################################################################### + +PixelStoref(pname, param) + return void + param pname PixelStoreParameter in value + param param CheckedFloat32 in value + dlflags notlistable + glxflags client-handcode + category VERSION_1_0 # old: pixel-rw + version 1.0 + glxsingle 109 + wglflags batchable + offset 249 + +PixelStorei(pname, param) + return void + param pname PixelStoreParameter in value + param param CheckedInt32 in value + dlflags notlistable + glxflags client-handcode + category VERSION_1_0 # old: pixel-rw + version 1.0 + glxsingle 110 + wglflags batchable + offset 250 + +ReadBuffer(mode) + return void + param mode ReadBufferMode in value + category VERSION_1_0 # old: pixel-rw + version 1.0 + glxropcode 171 + offset 254 + +ReadPixels(x, y, width, height, format, type, pixels) + return void + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + param format PixelFormat in value + param type PixelType in value + param pixels Void out array [COMPSIZE(format/type/width/height)] + category VERSION_1_0 # old: pixel-rw + dlflags notlistable + glxflags client-handcode server-handcode + version 1.0 + glxsingle 111 + wglflags client-handcode server-handcode + offset 256 + +############################################################################### +# +# state-req commands +# +############################################################################### + +GetBooleanv(pname, params) + return void + param pname GetPName in value + param params Boolean out array [COMPSIZE(pname)] + category VERSION_1_0 # old: state-req + dlflags notlistable + glxflags client-handcode + version 1.0 + glxsingle 112 + wglflags small-data + offset 258 + +GetDoublev(pname, params) + return void + param pname GetPName in value + param params Float64 out array [COMPSIZE(pname)] + category VERSION_1_0 # old: state-req + dlflags notlistable + glxflags client-handcode + version 1.0 + glxsingle 114 + wglflags small-data + offset 260 + +GetError() + return ErrorCode + category VERSION_1_0 # old: state-req + dlflags notlistable + glxflags client-handcode + version 1.0 + glxsingle 115 + offset 261 + +GetFloatv(pname, params) + return void + param pname GetPName in value + param params Float32 out array [COMPSIZE(pname)] + category VERSION_1_0 # old: state-req + dlflags notlistable + glxflags client-handcode + version 1.0 + glxsingle 116 + wglflags small-data + offset 262 + +GetIntegerv(pname, params) + return void + param pname GetPName in value + param params Int32 out array [COMPSIZE(pname)] + category VERSION_1_0 # old: state-req + dlflags notlistable + glxflags client-handcode + version 1.0 + glxsingle 117 + wglflags small-data + offset 263 + +GetString(name) + return String + param name StringName in value + category VERSION_1_0 # old: state-req + dlflags notlistable + glxflags client-handcode server-handcode + version 1.0 + glxsingle 129 + wglflags client-handcode server-handcode + offset 275 + +GetTexImage(target, level, format, type, pixels) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param format PixelFormat in value + param type PixelType in value + param pixels Void out array [COMPSIZE(target/level/format/type)] + category VERSION_1_0 # old: state-req + dlflags notlistable + glxflags client-handcode server-handcode + version 1.0 + glxsingle 135 + wglflags client-handcode server-handcode + offset 281 + +GetTexParameterfv(target, pname, params) + return void + param target TextureTarget in value + param pname GetTextureParameter in value + param params Float32 out array [COMPSIZE(pname)] + category VERSION_1_0 # old: state-req + dlflags notlistable + version 1.0 + glxsingle 136 + wglflags small-data + offset 282 + +GetTexParameteriv(target, pname, params) + return void + param target TextureTarget in value + param pname GetTextureParameter in value + param params Int32 out array [COMPSIZE(pname)] + category VERSION_1_0 # old: state-req + dlflags notlistable + version 1.0 + glxsingle 137 + wglflags small-data + offset 283 + +GetTexLevelParameterfv(target, level, pname, params) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param pname GetTextureParameter in value + param params Float32 out array [COMPSIZE(pname)] + category VERSION_1_0 # old: state-req + dlflags notlistable + version 1.0 + glxsingle 138 + wglflags small-data + offset 284 + +GetTexLevelParameteriv(target, level, pname, params) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param pname GetTextureParameter in value + param params Int32 out array [COMPSIZE(pname)] + category VERSION_1_0 # old: state-req + dlflags notlistable + version 1.0 + glxsingle 139 + wglflags small-data + offset 285 + +IsEnabled(cap) + return Boolean + param cap EnableCap in value + category VERSION_1_0 # old: state-req + dlflags notlistable + version 1.0 + glxflags client-handcode client-intercept + glxsingle 140 + offset 286 + +############################################################################### +# +# xform commands +# +############################################################################### + +DepthRange(near, far) + return void + param near ClampedFloat64 in value + param far ClampedFloat64 in value + category VERSION_1_0 # old: xform + version 1.0 + glxropcode 174 + offset 288 + +Viewport(x, y, width, height) + return void + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + category VERSION_1_0 # old: xform + version 1.0 + glxropcode 191 + offset 305 + +############################################################################### +############################################################################### +# +# OpenGL 1.0 deprecated commands +# +############################################################################### +############################################################################### + +# display-list commands + +NewList(list, mode) + return void + param list List in value + param mode ListMode in value + dlflags notlistable + category VERSION_1_0_DEPRECATED # old: display-list + version 1.0 + deprecated 3.1 + glxsingle 101 + wglflags batchable + offset 0 + +EndList() + return void + dlflags notlistable + category VERSION_1_0_DEPRECATED # old: display-list + version 1.0 + deprecated 3.1 + glxsingle 102 + wglflags batchable + offset 1 + +CallList(list) + return void + param list List in value + category VERSION_1_0_DEPRECATED # old: display-list + version 1.0 + deprecated 3.1 + glxropcode 1 + offset 2 + +CallLists(n, type, lists) + return void + param n SizeI in value + param type ListNameType in value + param lists Void in array [COMPSIZE(n/type)] + category VERSION_1_0_DEPRECATED # old: display-list + glxflags client-handcode server-handcode + version 1.0 + deprecated 3.1 + glxropcode 2 + offset 3 + +DeleteLists(list, range) + return void + param list List in value + param range SizeI in value + dlflags notlistable + category VERSION_1_0_DEPRECATED # old: display-list + version 1.0 + deprecated 3.1 + glxsingle 103 + wglflags batchable + offset 4 + +GenLists(range) + return List + param range SizeI in value + dlflags notlistable + category VERSION_1_0_DEPRECATED # old: display-list + version 1.0 + deprecated 3.1 + glxsingle 104 + offset 5 + +ListBase(base) + return void + param base List in value + category VERSION_1_0_DEPRECATED # old: display-list + version 1.0 + deprecated 3.1 + glxropcode 3 + offset 6 + +# drawing commands + +Begin(mode) + return void + param mode BeginMode in value + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 4 + offset 7 + +Bitmap(width, height, xorig, yorig, xmove, ymove, bitmap) + return void + param width SizeI in value + param height SizeI in value + param xorig CoordF in value + param yorig CoordF in value + param xmove CoordF in value + param ymove CoordF in value + param bitmap UInt8 in array [COMPSIZE(width/height)] + category VERSION_1_0_DEPRECATED # old: drawing + dlflags handcode + glxflags client-handcode server-handcode + version 1.0 + deprecated 3.1 + glxropcode 5 + wglflags client-handcode server-handcode + offset 8 + +Color3b(red, green, blue) + return void + param red ColorB in value + param green ColorB in value + param blue ColorB in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color3bv + version 1.0 + deprecated 3.1 + offset 9 + +Color3bv(v) + return void + param v ColorB in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 6 + offset 10 + +Color3d(red, green, blue) + return void + param red ColorD in value + param green ColorD in value + param blue ColorD in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color3dv + version 1.0 + deprecated 3.1 + offset 11 + +Color3dv(v) + return void + param v ColorD in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 7 + offset 12 + +Color3f(red, green, blue) + return void + param red ColorF in value + param green ColorF in value + param blue ColorF in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color3fv + version 1.0 + deprecated 3.1 + offset 13 + +Color3fv(v) + return void + param v ColorF in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 8 + offset 14 + +Color3i(red, green, blue) + return void + param red ColorI in value + param green ColorI in value + param blue ColorI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color3iv + version 1.0 + deprecated 3.1 + offset 15 + +Color3iv(v) + return void + param v ColorI in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 9 + offset 16 + +Color3s(red, green, blue) + return void + param red ColorS in value + param green ColorS in value + param blue ColorS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color3sv + version 1.0 + deprecated 3.1 + offset 17 + +Color3sv(v) + return void + param v ColorS in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 10 + offset 18 + +Color3ub(red, green, blue) + return void + param red ColorUB in value + param green ColorUB in value + param blue ColorUB in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color3ubv + version 1.0 + deprecated 3.1 + offset 19 + +Color3ubv(v) + return void + param v ColorUB in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 11 + offset 20 + +Color3ui(red, green, blue) + return void + param red ColorUI in value + param green ColorUI in value + param blue ColorUI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color3uiv + version 1.0 + deprecated 3.1 + offset 21 + +Color3uiv(v) + return void + param v ColorUI in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 12 + offset 22 + +Color3us(red, green, blue) + return void + param red ColorUS in value + param green ColorUS in value + param blue ColorUS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color3usv + version 1.0 + deprecated 3.1 + offset 23 + +Color3usv(v) + return void + param v ColorUS in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 13 + offset 24 + +Color4b(red, green, blue, alpha) + return void + param red ColorB in value + param green ColorB in value + param blue ColorB in value + param alpha ColorB in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color4bv + version 1.0 + deprecated 3.1 + offset 25 + +Color4bv(v) + return void + param v ColorB in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 14 + offset 26 + +Color4d(red, green, blue, alpha) + return void + param red ColorD in value + param green ColorD in value + param blue ColorD in value + param alpha ColorD in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color4dv + version 1.0 + deprecated 3.1 + offset 27 + +Color4dv(v) + return void + param v ColorD in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 15 + offset 28 + +Color4f(red, green, blue, alpha) + return void + param red ColorF in value + param green ColorF in value + param blue ColorF in value + param alpha ColorF in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color4fv + version 1.0 + deprecated 3.1 + offset 29 + +Color4fv(v) + return void + param v ColorF in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 16 + offset 30 + +Color4i(red, green, blue, alpha) + return void + param red ColorI in value + param green ColorI in value + param blue ColorI in value + param alpha ColorI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color4iv + version 1.0 + deprecated 3.1 + offset 31 + +Color4iv(v) + return void + param v ColorI in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 17 + offset 32 + +Color4s(red, green, blue, alpha) + return void + param red ColorS in value + param green ColorS in value + param blue ColorS in value + param alpha ColorS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color4sv + version 1.0 + deprecated 3.1 + offset 33 + +Color4sv(v) + return void + param v ColorS in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 18 + offset 34 + +Color4ub(red, green, blue, alpha) + return void + param red ColorUB in value + param green ColorUB in value + param blue ColorUB in value + param alpha ColorUB in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color4ubv + version 1.0 + deprecated 3.1 + offset 35 + +Color4ubv(v) + return void + param v ColorUB in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 19 + offset 36 + +Color4ui(red, green, blue, alpha) + return void + param red ColorUI in value + param green ColorUI in value + param blue ColorUI in value + param alpha ColorUI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color4uiv + version 1.0 + deprecated 3.1 + offset 37 + +Color4uiv(v) + return void + param v ColorUI in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 20 + offset 38 + +Color4us(red, green, blue, alpha) + return void + param red ColorUS in value + param green ColorUS in value + param blue ColorUS in value + param alpha ColorUS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Color4usv + version 1.0 + deprecated 3.1 + offset 39 + +Color4usv(v) + return void + param v ColorUS in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 21 + offset 40 + +EdgeFlag(flag) + return void + param flag Boolean in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv EdgeFlagv + version 1.0 + deprecated 3.1 + offset 41 + +EdgeFlagv(flag) + return void + param flag Boolean in array [1] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 22 + offset 42 + +End() + return void + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 23 + offset 43 + +Indexd(c) + return void + param c ColorIndexValueD in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Indexdv + version 1.0 + deprecated 3.1 + offset 44 + +Indexdv(c) + return void + param c ColorIndexValueD in array [1] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 24 + offset 45 + +Indexf(c) + return void + param c ColorIndexValueF in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Indexfv + version 1.0 + deprecated 3.1 + offset 46 + +Indexfv(c) + return void + param c ColorIndexValueF in array [1] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 25 + offset 47 + +Indexi(c) + return void + param c ColorIndexValueI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Indexiv + version 1.0 + deprecated 3.1 + offset 48 + +Indexiv(c) + return void + param c ColorIndexValueI in array [1] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 26 + offset 49 + +Indexs(c) + return void + param c ColorIndexValueS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Indexsv + version 1.0 + deprecated 3.1 + offset 50 + +Indexsv(c) + return void + param c ColorIndexValueS in array [1] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 27 + offset 51 + +Normal3b(nx, ny, nz) + return void + param nx Int8 in value + param ny Int8 in value + param nz Int8 in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Normal3bv + version 1.0 + deprecated 3.1 + offset 52 + +Normal3bv(v) + return void + param v Int8 in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 28 + offset 53 + +Normal3d(nx, ny, nz) + return void + param nx CoordD in value + param ny CoordD in value + param nz CoordD in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Normal3dv + version 1.0 + deprecated 3.1 + offset 54 + +Normal3dv(v) + return void + param v CoordD in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 29 + offset 55 + +Normal3f(nx, ny, nz) + return void + param nx CoordF in value + param ny CoordF in value + param nz CoordF in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Normal3fv + version 1.0 + deprecated 3.1 + offset 56 + +Normal3fv(v) + return void + param v CoordF in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 30 + offset 57 + +Normal3i(nx, ny, nz) + return void + param nx Int32 in value + param ny Int32 in value + param nz Int32 in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Normal3iv + version 1.0 + deprecated 3.1 + offset 58 + +Normal3iv(v) + return void + param v Int32 in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 31 + offset 59 + +Normal3s(nx, ny, nz) + return void + param nx Int16 in value + param ny Int16 in value + param nz Int16 in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Normal3sv + version 1.0 + deprecated 3.1 + offset 60 + +Normal3sv(v) + return void + param v Int16 in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 32 + offset 61 + +RasterPos2d(x, y) + return void + param x CoordD in value + param y CoordD in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv RasterPos2dv + version 1.0 + deprecated 3.1 + offset 62 + +RasterPos2dv(v) + return void + param v CoordD in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 33 + offset 63 + +RasterPos2f(x, y) + return void + param x CoordF in value + param y CoordF in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv RasterPos2fv + version 1.0 + deprecated 3.1 + offset 64 + +RasterPos2fv(v) + return void + param v CoordF in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 34 + offset 65 + +RasterPos2i(x, y) + return void + param x CoordI in value + param y CoordI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv RasterPos2iv + version 1.0 + deprecated 3.1 + offset 66 + +RasterPos2iv(v) + return void + param v CoordI in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 35 + offset 67 + +RasterPos2s(x, y) + return void + param x CoordS in value + param y CoordS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv RasterPos2sv + version 1.0 + deprecated 3.1 + offset 68 + +RasterPos2sv(v) + return void + param v CoordS in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 36 + offset 69 + +RasterPos3d(x, y, z) + return void + param x CoordD in value + param y CoordD in value + param z CoordD in value + vectorequiv RasterPos3dv + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + offset 70 + +RasterPos3dv(v) + return void + param v CoordD in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 37 + offset 71 + +RasterPos3f(x, y, z) + return void + param x CoordF in value + param y CoordF in value + param z CoordF in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv RasterPos3fv + version 1.0 + deprecated 3.1 + offset 72 + +RasterPos3fv(v) + return void + param v CoordF in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 38 + offset 73 + +RasterPos3i(x, y, z) + return void + param x CoordI in value + param y CoordI in value + param z CoordI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv RasterPos3iv + version 1.0 + deprecated 3.1 + offset 74 + +RasterPos3iv(v) + return void + param v CoordI in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 39 + offset 75 + +RasterPos3s(x, y, z) + return void + param x CoordS in value + param y CoordS in value + param z CoordS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv RasterPos3sv + version 1.0 + deprecated 3.1 + offset 76 + +RasterPos3sv(v) + return void + param v CoordS in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 40 + offset 77 + +RasterPos4d(x, y, z, w) + return void + param x CoordD in value + param y CoordD in value + param z CoordD in value + param w CoordD in value + vectorequiv RasterPos4dv + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + offset 78 + +RasterPos4dv(v) + return void + param v CoordD in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 41 + offset 79 + +RasterPos4f(x, y, z, w) + return void + param x CoordF in value + param y CoordF in value + param z CoordF in value + param w CoordF in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv RasterPos4fv + version 1.0 + deprecated 3.1 + offset 80 + +RasterPos4fv(v) + return void + param v CoordF in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 42 + offset 81 + +RasterPos4i(x, y, z, w) + return void + param x CoordI in value + param y CoordI in value + param z CoordI in value + param w CoordI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv RasterPos4iv + version 1.0 + deprecated 3.1 + offset 82 + +RasterPos4iv(v) + return void + param v CoordI in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 43 + offset 83 + +RasterPos4s(x, y, z, w) + return void + param x CoordS in value + param y CoordS in value + param z CoordS in value + param w CoordS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv RasterPos4sv + version 1.0 + deprecated 3.1 + offset 84 + +RasterPos4sv(v) + return void + param v CoordS in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 44 + offset 85 + +Rectd(x1, y1, x2, y2) + return void + param x1 CoordD in value + param y1 CoordD in value + param x2 CoordD in value + param y2 CoordD in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Rectdv + version 1.0 + deprecated 3.1 + offset 86 + +Rectdv(v1, v2) + return void + param v1 CoordD in array [2] + param v2 CoordD in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 45 + offset 87 + +Rectf(x1, y1, x2, y2) + return void + param x1 CoordF in value + param y1 CoordF in value + param x2 CoordF in value + param y2 CoordF in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Rectfv + version 1.0 + deprecated 3.1 + offset 88 + +Rectfv(v1, v2) + return void + param v1 CoordF in array [2] + param v2 CoordF in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 46 + offset 89 + +Recti(x1, y1, x2, y2) + return void + param x1 CoordI in value + param y1 CoordI in value + param x2 CoordI in value + param y2 CoordI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Rectiv + version 1.0 + deprecated 3.1 + offset 90 + +Rectiv(v1, v2) + return void + param v1 CoordI in array [2] + param v2 CoordI in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 47 + offset 91 + +Rects(x1, y1, x2, y2) + return void + param x1 CoordS in value + param y1 CoordS in value + param x2 CoordS in value + param y2 CoordS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Rectsv + version 1.0 + deprecated 3.1 + offset 92 + +Rectsv(v1, v2) + return void + param v1 CoordS in array [2] + param v2 CoordS in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 48 + offset 93 + +TexCoord1d(s) + return void + param s CoordD in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord1dv + version 1.0 + deprecated 3.1 + offset 94 + +TexCoord1dv(v) + return void + param v CoordD in array [1] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 49 + offset 95 + +TexCoord1f(s) + return void + param s CoordF in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord1fv + version 1.0 + deprecated 3.1 + offset 96 + +TexCoord1fv(v) + return void + param v CoordF in array [1] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 50 + offset 97 + +TexCoord1i(s) + return void + param s CoordI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord1iv + version 1.0 + deprecated 3.1 + offset 98 + +TexCoord1iv(v) + return void + param v CoordI in array [1] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 51 + offset 99 + +TexCoord1s(s) + return void + param s CoordS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord1sv + version 1.0 + deprecated 3.1 + offset 100 + +TexCoord1sv(v) + return void + param v CoordS in array [1] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 52 + offset 101 + +TexCoord2d(s, t) + return void + param s CoordD in value + param t CoordD in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord2dv + version 1.0 + deprecated 3.1 + offset 102 + +TexCoord2dv(v) + return void + param v CoordD in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 53 + offset 103 + +TexCoord2f(s, t) + return void + param s CoordF in value + param t CoordF in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord2fv + version 1.0 + deprecated 3.1 + offset 104 + +TexCoord2fv(v) + return void + param v CoordF in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 54 + offset 105 + +TexCoord2i(s, t) + return void + param s CoordI in value + param t CoordI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord2iv + version 1.0 + deprecated 3.1 + offset 106 + +TexCoord2iv(v) + return void + param v CoordI in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 55 + offset 107 + +TexCoord2s(s, t) + return void + param s CoordS in value + param t CoordS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord2sv + version 1.0 + deprecated 3.1 + offset 108 + +TexCoord2sv(v) + return void + param v CoordS in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 56 + offset 109 + +TexCoord3d(s, t, r) + return void + param s CoordD in value + param t CoordD in value + param r CoordD in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord3dv + version 1.0 + deprecated 3.1 + offset 110 + +TexCoord3dv(v) + return void + param v CoordD in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 57 + offset 111 + +TexCoord3f(s, t, r) + return void + param s CoordF in value + param t CoordF in value + param r CoordF in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord3fv + version 1.0 + deprecated 3.1 + offset 112 + +TexCoord3fv(v) + return void + param v CoordF in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 58 + offset 113 + +TexCoord3i(s, t, r) + return void + param s CoordI in value + param t CoordI in value + param r CoordI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord3iv + version 1.0 + deprecated 3.1 + offset 114 + +TexCoord3iv(v) + return void + param v CoordI in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 59 + offset 115 + +TexCoord3s(s, t, r) + return void + param s CoordS in value + param t CoordS in value + param r CoordS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord3sv + version 1.0 + deprecated 3.1 + offset 116 + +TexCoord3sv(v) + return void + param v CoordS in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 60 + offset 117 + +TexCoord4d(s, t, r, q) + return void + param s CoordD in value + param t CoordD in value + param r CoordD in value + param q CoordD in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord4dv + version 1.0 + deprecated 3.1 + offset 118 + +TexCoord4dv(v) + return void + param v CoordD in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 61 + offset 119 + +TexCoord4f(s, t, r, q) + return void + param s CoordF in value + param t CoordF in value + param r CoordF in value + param q CoordF in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord4fv + version 1.0 + deprecated 3.1 + offset 120 + +TexCoord4fv(v) + return void + param v CoordF in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 62 + offset 121 + +TexCoord4i(s, t, r, q) + return void + param s CoordI in value + param t CoordI in value + param r CoordI in value + param q CoordI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord4iv + version 1.0 + deprecated 3.1 + offset 122 + +TexCoord4iv(v) + return void + param v CoordI in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 63 + offset 123 + +TexCoord4s(s, t, r, q) + return void + param s CoordS in value + param t CoordS in value + param r CoordS in value + param q CoordS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv TexCoord4sv + version 1.0 + deprecated 3.1 + offset 124 + +TexCoord4sv(v) + return void + param v CoordS in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 64 + offset 125 + +Vertex2d(x, y) + return void + param x CoordD in value + param y CoordD in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Vertex2dv + version 1.0 + deprecated 3.1 + offset 126 + +Vertex2dv(v) + return void + param v CoordD in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 65 + offset 127 + +Vertex2f(x, y) + return void + param x CoordF in value + param y CoordF in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Vertex2fv + version 1.0 + deprecated 3.1 + offset 128 + +Vertex2fv(v) + return void + param v CoordF in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 66 + offset 129 + +Vertex2i(x, y) + return void + param x CoordI in value + param y CoordI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Vertex2iv + version 1.0 + deprecated 3.1 + offset 130 + +Vertex2iv(v) + return void + param v CoordI in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 67 + offset 131 + +Vertex2s(x, y) + return void + param x CoordS in value + param y CoordS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Vertex2sv + version 1.0 + deprecated 3.1 + offset 132 + +Vertex2sv(v) + return void + param v CoordS in array [2] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 68 + offset 133 + +Vertex3d(x, y, z) + return void + param x CoordD in value + param y CoordD in value + param z CoordD in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Vertex3dv + version 1.0 + deprecated 3.1 + offset 134 + +Vertex3dv(v) + return void + param v CoordD in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 69 + offset 135 + +Vertex3f(x, y, z) + return void + param x CoordF in value + param y CoordF in value + param z CoordF in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Vertex3fv + version 1.0 + deprecated 3.1 + offset 136 + +Vertex3fv(v) + return void + param v CoordF in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 70 + offset 137 + +Vertex3i(x, y, z) + return void + param x CoordI in value + param y CoordI in value + param z CoordI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Vertex3iv + version 1.0 + deprecated 3.1 + offset 138 + +Vertex3iv(v) + return void + param v CoordI in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 71 + offset 139 + +Vertex3s(x, y, z) + return void + param x CoordS in value + param y CoordS in value + param z CoordS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Vertex3sv + version 1.0 + deprecated 3.1 + offset 140 + +Vertex3sv(v) + return void + param v CoordS in array [3] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 72 + offset 141 + +Vertex4d(x, y, z, w) + return void + param x CoordD in value + param y CoordD in value + param z CoordD in value + param w CoordD in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Vertex4dv + version 1.0 + deprecated 3.1 + offset 142 + +Vertex4dv(v) + return void + param v CoordD in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 73 + offset 143 + +Vertex4f(x, y, z, w) + return void + param x CoordF in value + param y CoordF in value + param z CoordF in value + param w CoordF in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Vertex4fv + version 1.0 + deprecated 3.1 + offset 144 + +Vertex4fv(v) + return void + param v CoordF in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 74 + offset 145 + +Vertex4i(x, y, z, w) + return void + param x CoordI in value + param y CoordI in value + param z CoordI in value + param w CoordI in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Vertex4iv + version 1.0 + deprecated 3.1 + offset 146 + +Vertex4iv(v) + return void + param v CoordI in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 75 + offset 147 + +Vertex4s(x, y, z, w) + return void + param x CoordS in value + param y CoordS in value + param z CoordS in value + param w CoordS in value + category VERSION_1_0_DEPRECATED # old: drawing + vectorequiv Vertex4sv + version 1.0 + deprecated 3.1 + offset 148 + +Vertex4sv(v) + return void + param v CoordS in array [4] + category VERSION_1_0_DEPRECATED # old: drawing + version 1.0 + deprecated 3.1 + glxropcode 76 + offset 149 + +ClipPlane(plane, equation) + return void + param plane ClipPlaneName in value + param equation Float64 in array [4] + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 77 + offset 150 + +ColorMaterial(face, mode) + return void + param face MaterialFace in value + param mode ColorMaterialParameter in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 78 + offset 151 + +Fogf(pname, param) + return void + param pname FogParameter in value + param param CheckedFloat32 in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 80 + wglflags small-data + offset 153 + +Fogfv(pname, params) + return void + param pname FogParameter in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 81 + wglflags small-data + offset 154 + +Fogi(pname, param) + return void + param pname FogParameter in value + param param CheckedInt32 in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 82 + wglflags small-data + offset 155 + +Fogiv(pname, params) + return void + param pname FogParameter in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 83 + wglflags small-data + offset 156 + +Lightf(light, pname, param) + return void + param light LightName in value + param pname LightParameter in value + param param CheckedFloat32 in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 86 + wglflags small-data + offset 159 + +Lightfv(light, pname, params) + return void + param light LightName in value + param pname LightParameter in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 87 + wglflags small-data + offset 160 + +Lighti(light, pname, param) + return void + param light LightName in value + param pname LightParameter in value + param param CheckedInt32 in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 88 + wglflags small-data + offset 161 + +Lightiv(light, pname, params) + return void + param light LightName in value + param pname LightParameter in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 89 + wglflags small-data + offset 162 + +LightModelf(pname, param) + return void + param pname LightModelParameter in value + param param Float32 in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 90 + wglflags small-data + offset 163 + +LightModelfv(pname, params) + return void + param pname LightModelParameter in value + param params Float32 in array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 91 + wglflags small-data + offset 164 + +LightModeli(pname, param) + return void + param pname LightModelParameter in value + param param Int32 in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 92 + wglflags small-data + offset 165 + +LightModeliv(pname, params) + return void + param pname LightModelParameter in value + param params Int32 in array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 93 + wglflags small-data + offset 166 + +LineStipple(factor, pattern) + return void + param factor CheckedInt32 in value + param pattern LineStipple in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 94 + offset 167 + +Materialf(face, pname, param) + return void + param face MaterialFace in value + param pname MaterialParameter in value + param param CheckedFloat32 in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 96 + wglflags small-data + offset 169 + +Materialfv(face, pname, params) + return void + param face MaterialFace in value + param pname MaterialParameter in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 97 + wglflags small-data + offset 170 + +Materiali(face, pname, param) + return void + param face MaterialFace in value + param pname MaterialParameter in value + param param CheckedInt32 in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 98 + wglflags small-data + offset 171 + +Materialiv(face, pname, params) + return void + param face MaterialFace in value + param pname MaterialParameter in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 99 + wglflags small-data + offset 172 + +PolygonStipple(mask) + return void + param mask UInt8 in array [COMPSIZE()] + category VERSION_1_0_DEPRECATED # old: drawing-control + dlflags handcode + glxflags client-handcode server-handcode + version 1.0 + deprecated 3.1 + glxropcode 102 + wglflags client-handcode server-handcode + offset 175 + +ShadeModel(mode) + return void + param mode ShadingModel in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 104 + offset 177 + +TexEnvf(target, pname, param) + return void + param target TextureEnvTarget in value + param pname TextureEnvParameter in value + param param CheckedFloat32 in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 111 + wglflags small-data + offset 184 + +TexEnvfv(target, pname, params) + return void + param target TextureEnvTarget in value + param pname TextureEnvParameter in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 112 + wglflags small-data + offset 185 + +TexEnvi(target, pname, param) + return void + param target TextureEnvTarget in value + param pname TextureEnvParameter in value + param param CheckedInt32 in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 113 + wglflags small-data + offset 186 + +TexEnviv(target, pname, params) + return void + param target TextureEnvTarget in value + param pname TextureEnvParameter in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 114 + wglflags small-data + offset 187 + +TexGend(coord, pname, param) + return void + param coord TextureCoordName in value + param pname TextureGenParameter in value + param param Float64 in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 115 + wglflags small-data + offset 188 + +TexGendv(coord, pname, params) + return void + param coord TextureCoordName in value + param pname TextureGenParameter in value + param params Float64 in array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 116 + wglflags small-data + offset 189 + +TexGenf(coord, pname, param) + return void + param coord TextureCoordName in value + param pname TextureGenParameter in value + param param CheckedFloat32 in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 117 + wglflags small-data + offset 190 + +TexGenfv(coord, pname, params) + return void + param coord TextureCoordName in value + param pname TextureGenParameter in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 118 + wglflags small-data + offset 191 + +TexGeni(coord, pname, param) + return void + param coord TextureCoordName in value + param pname TextureGenParameter in value + param param CheckedInt32 in value + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 119 + wglflags small-data + offset 192 + +TexGeniv(coord, pname, params) + return void + param coord TextureCoordName in value + param pname TextureGenParameter in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: drawing-control + version 1.0 + deprecated 3.1 + glxropcode 120 + wglflags small-data + offset 193 + +# feedback commands + +FeedbackBuffer(size, type, buffer) + return void + param size SizeI in value + param type FeedbackType in value + param buffer FeedbackElement out array [size] retained + dlflags notlistable + glxflags client-handcode server-handcode + category VERSION_1_0_DEPRECATED # old: feedback + version 1.0 + deprecated 3.1 + glxsingle 105 + wglflags client-handcode server-handcode batchable + offset 194 + +SelectBuffer(size, buffer) + return void + param size SizeI in value + param buffer SelectName out array [size] retained + dlflags notlistable + glxflags client-handcode server-handcode + category VERSION_1_0_DEPRECATED # old: feedback + version 1.0 + deprecated 3.1 + glxsingle 106 + wglflags client-handcode server-handcode batchable + offset 195 + +RenderMode(mode) + return Int32 + param mode RenderingMode in value + category VERSION_1_0_DEPRECATED # old: feedback + dlflags notlistable + glxflags client-handcode server-handcode + version 1.0 + deprecated 3.1 + glxsingle 107 + wglflags client-handcode server-handcode + offset 196 + +InitNames() + return void + category VERSION_1_0_DEPRECATED # old: feedback + version 1.0 + deprecated 3.1 + glxropcode 121 + offset 197 + +LoadName(name) + return void + param name SelectName in value + category VERSION_1_0_DEPRECATED # old: feedback + version 1.0 + deprecated 3.1 + glxropcode 122 + offset 198 + +PassThrough(token) + return void + param token FeedbackElement in value + category VERSION_1_0_DEPRECATED # old: feedback + version 1.0 + deprecated 3.1 + glxropcode 123 + offset 199 + +PopName() + return void + category VERSION_1_0_DEPRECATED # old: feedback + version 1.0 + deprecated 3.1 + glxropcode 124 + offset 200 + +PushName(name) + return void + param name SelectName in value + category VERSION_1_0_DEPRECATED # old: feedback + version 1.0 + deprecated 3.1 + glxropcode 125 + offset 201 + +ClearAccum(red, green, blue, alpha) + return void + param red Float32 in value + param green Float32 in value + param blue Float32 in value + param alpha Float32 in value + category VERSION_1_0_DEPRECATED # old: framebuf + version 1.0 + deprecated 3.1 + glxropcode 128 + offset 204 + +ClearIndex(c) + return void + param c MaskedColorIndexValueF in value + category VERSION_1_0_DEPRECATED # old: framebuf + version 1.0 + deprecated 3.1 + glxropcode 129 + offset 205 + +IndexMask(mask) + return void + param mask MaskedColorIndexValueI in value + category VERSION_1_0_DEPRECATED # old: framebuf + version 1.0 + deprecated 3.1 + glxropcode 136 + offset 212 + +Accum(op, value) + return void + param op AccumOp in value + param value CoordF in value + category VERSION_1_0_DEPRECATED # old: misc + version 1.0 + deprecated 3.1 + glxropcode 137 + offset 213 + +PopAttrib() + return void + category VERSION_1_0_DEPRECATED # old: misc + version 1.0 + deprecated 3.1 + glxropcode 141 + offset 218 + +PushAttrib(mask) + return void + param mask AttribMask in value + category VERSION_1_0_DEPRECATED # old: misc + version 1.0 + deprecated 3.1 + glxropcode 142 + offset 219 + +# modeling commands + +Map1d(target, u1, u2, stride, order, points) + return void + param target MapTarget in value + param u1 CoordD in value + param u2 CoordD in value + param stride Int32 in value + param order CheckedInt32 in value + param points CoordD in array [COMPSIZE(target/stride/order)] + category VERSION_1_0_DEPRECATED # old: modeling + dlflags handcode + glxflags client-handcode server-handcode + version 1.0 + deprecated 3.1 + glxropcode 143 + wglflags client-handcode server-handcode + offset 220 + +Map1f(target, u1, u2, stride, order, points) + return void + param target MapTarget in value + param u1 CoordF in value + param u2 CoordF in value + param stride Int32 in value + param order CheckedInt32 in value + param points CoordF in array [COMPSIZE(target/stride/order)] + category VERSION_1_0_DEPRECATED # old: modeling + dlflags handcode + glxflags client-handcode server-handcode + version 1.0 + deprecated 3.1 + glxropcode 144 + wglflags client-handcode server-handcode + offset 221 + +Map2d(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points) + return void + param target MapTarget in value + param u1 CoordD in value + param u2 CoordD in value + param ustride Int32 in value + param uorder CheckedInt32 in value + param v1 CoordD in value + param v2 CoordD in value + param vstride Int32 in value + param vorder CheckedInt32 in value + param points CoordD in array [COMPSIZE(target/ustride/uorder/vstride/vorder)] + category VERSION_1_0_DEPRECATED # old: modeling + dlflags handcode + glxflags client-handcode server-handcode + version 1.0 + deprecated 3.1 + glxropcode 145 + wglflags client-handcode server-handcode + offset 222 + +Map2f(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points) + return void + param target MapTarget in value + param u1 CoordF in value + param u2 CoordF in value + param ustride Int32 in value + param uorder CheckedInt32 in value + param v1 CoordF in value + param v2 CoordF in value + param vstride Int32 in value + param vorder CheckedInt32 in value + param points CoordF in array [COMPSIZE(target/ustride/uorder/vstride/vorder)] + category VERSION_1_0_DEPRECATED # old: modeling + dlflags handcode + glxflags client-handcode server-handcode + version 1.0 + deprecated 3.1 + glxropcode 146 + wglflags client-handcode server-handcode + offset 223 + +MapGrid1d(un, u1, u2) + return void + param un Int32 in value + param u1 CoordD in value + param u2 CoordD in value + category VERSION_1_0_DEPRECATED # old: modeling + version 1.0 + deprecated 3.1 + glxropcode 147 + offset 224 + +MapGrid1f(un, u1, u2) + return void + param un Int32 in value + param u1 CoordF in value + param u2 CoordF in value + category VERSION_1_0_DEPRECATED # old: modeling + version 1.0 + deprecated 3.1 + glxropcode 148 + offset 225 + +MapGrid2d(un, u1, u2, vn, v1, v2) + return void + param un Int32 in value + param u1 CoordD in value + param u2 CoordD in value + param vn Int32 in value + param v1 CoordD in value + param v2 CoordD in value + category VERSION_1_0_DEPRECATED # old: modeling + version 1.0 + deprecated 3.1 + glxropcode 149 + offset 226 + +MapGrid2f(un, u1, u2, vn, v1, v2) + return void + param un Int32 in value + param u1 CoordF in value + param u2 CoordF in value + param vn Int32 in value + param v1 CoordF in value + param v2 CoordF in value + category VERSION_1_0_DEPRECATED # old: modeling + version 1.0 + deprecated 3.1 + glxropcode 150 + offset 227 + +EvalCoord1d(u) + return void + param u CoordD in value + category VERSION_1_0_DEPRECATED # old: modeling + vectorequiv EvalCoord1dv + version 1.0 + deprecated 3.1 + offset 228 + +EvalCoord1dv(u) + return void + param u CoordD in array [1] + category VERSION_1_0_DEPRECATED # old: modeling + version 1.0 + deprecated 3.1 + glxropcode 151 + offset 229 + +EvalCoord1f(u) + return void + param u CoordF in value + category VERSION_1_0_DEPRECATED # old: modeling + vectorequiv EvalCoord1fv + version 1.0 + deprecated 3.1 + offset 230 + +EvalCoord1fv(u) + return void + param u CoordF in array [1] + category VERSION_1_0_DEPRECATED # old: modeling + version 1.0 + deprecated 3.1 + glxropcode 152 + offset 231 + +EvalCoord2d(u, v) + return void + param u CoordD in value + param v CoordD in value + category VERSION_1_0_DEPRECATED # old: modeling + vectorequiv EvalCoord2dv + version 1.0 + deprecated 3.1 + offset 232 + +EvalCoord2dv(u) + return void + param u CoordD in array [2] + category VERSION_1_0_DEPRECATED # old: modeling + version 1.0 + deprecated 3.1 + glxropcode 153 + offset 233 + +EvalCoord2f(u, v) + return void + param u CoordF in value + param v CoordF in value + category VERSION_1_0_DEPRECATED # old: modeling + vectorequiv EvalCoord2fv + version 1.0 + deprecated 3.1 + offset 234 + +EvalCoord2fv(u) + return void + param u CoordF in array [2] + category VERSION_1_0_DEPRECATED # old: modeling + version 1.0 + deprecated 3.1 + glxropcode 154 + offset 235 + +EvalMesh1(mode, i1, i2) + return void + param mode MeshMode1 in value + param i1 CheckedInt32 in value + param i2 CheckedInt32 in value + category VERSION_1_0_DEPRECATED # old: modeling + version 1.0 + deprecated 3.1 + glxropcode 155 + offset 236 + +EvalPoint1(i) + return void + param i Int32 in value + category VERSION_1_0_DEPRECATED # old: modeling + version 1.0 + deprecated 3.1 + glxropcode 156 + offset 237 + +EvalMesh2(mode, i1, i2, j1, j2) + return void + param mode MeshMode2 in value + param i1 CheckedInt32 in value + param i2 CheckedInt32 in value + param j1 CheckedInt32 in value + param j2 CheckedInt32 in value + category VERSION_1_0_DEPRECATED # old: modeling + version 1.0 + deprecated 3.1 + glxropcode 157 + offset 238 + +EvalPoint2(i, j) + return void + param i CheckedInt32 in value + param j CheckedInt32 in value + category VERSION_1_0_DEPRECATED # old: modeling + version 1.0 + deprecated 3.1 + glxropcode 158 + offset 239 + +AlphaFunc(func, ref) + return void + param func AlphaFunction in value + param ref ClampedFloat32 in value + category VERSION_1_0_DEPRECATED # old: pixel-op + version 1.0 + deprecated 3.1 + glxropcode 159 + offset 240 + +PixelZoom(xfactor, yfactor) + return void + param xfactor Float32 in value + param yfactor Float32 in value + category VERSION_1_0_DEPRECATED # old: pixel-rw + version 1.0 + deprecated 3.1 + glxropcode 165 + offset 246 + +PixelTransferf(pname, param) + return void + param pname PixelTransferParameter in value + param param CheckedFloat32 in value + category VERSION_1_0_DEPRECATED # old: pixel-rw + version 1.0 + deprecated 3.1 + glxropcode 166 + offset 247 + +PixelTransferi(pname, param) + return void + param pname PixelTransferParameter in value + param param CheckedInt32 in value + category VERSION_1_0_DEPRECATED # old: pixel-rw + version 1.0 + deprecated 3.1 + glxropcode 167 + offset 248 + +PixelMapfv(map, mapsize, values) + return void + param map PixelMap in value + param mapsize CheckedInt32 in value + param values Float32 in array [mapsize] + category VERSION_1_0_DEPRECATED # old: pixel-rw + glxflags client-handcode + version 1.0 + deprecated 3.1 + glxropcode 168 + offset 251 + +PixelMapuiv(map, mapsize, values) + return void + param map PixelMap in value + param mapsize CheckedInt32 in value + param values UInt32 in array [mapsize] + category VERSION_1_0_DEPRECATED # old: pixel-rw + glxflags client-handcode + version 1.0 + deprecated 3.1 + glxropcode 169 + offset 252 + +PixelMapusv(map, mapsize, values) + return void + param map PixelMap in value + param mapsize CheckedInt32 in value + param values UInt16 in array [mapsize] + category VERSION_1_0_DEPRECATED # old: pixel-rw + glxflags client-handcode + version 1.0 + deprecated 3.1 + glxropcode 170 + offset 253 + +CopyPixels(x, y, width, height, type) + return void + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + param type PixelCopyType in value + category VERSION_1_0_DEPRECATED # old: pixel-rw + version 1.0 + deprecated 3.1 + glxropcode 172 + offset 255 + +DrawPixels(width, height, format, type, pixels) + return void + param width SizeI in value + param height SizeI in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height)] + category VERSION_1_0_DEPRECATED # old: pixel-rw + dlflags handcode + glxflags client-handcode server-handcode + version 1.0 + deprecated 3.1 + glxropcode 173 + wglflags client-handcode server-handcode + offset 257 + +GetClipPlane(plane, equation) + return void + param plane ClipPlaneName in value + param equation Float64 out array [4] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 113 + glxflags client-handcode server-handcode + offset 259 + +GetLightfv(light, pname, params) + return void + param light LightName in value + param pname LightParameter in value + param params Float32 out array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 118 + wglflags small-data + offset 264 + +GetLightiv(light, pname, params) + return void + param light LightName in value + param pname LightParameter in value + param params Int32 out array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 119 + wglflags small-data + offset 265 + +GetMapdv(target, query, v) + return void + param target MapTarget in value + param query GetMapQuery in value + param v Float64 out array [COMPSIZE(target/query)] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 120 + offset 266 + +GetMapfv(target, query, v) + return void + param target MapTarget in value + param query GetMapQuery in value + param v Float32 out array [COMPSIZE(target/query)] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 121 + offset 267 + +GetMapiv(target, query, v) + return void + param target MapTarget in value + param query GetMapQuery in value + param v Int32 out array [COMPSIZE(target/query)] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 122 + offset 268 + +GetMaterialfv(face, pname, params) + return void + param face MaterialFace in value + param pname MaterialParameter in value + param params Float32 out array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 123 + wglflags small-data + offset 269 + +GetMaterialiv(face, pname, params) + return void + param face MaterialFace in value + param pname MaterialParameter in value + param params Int32 out array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 124 + wglflags small-data + offset 270 + +GetPixelMapfv(map, values) + return void + param map PixelMap in value + param values Float32 out array [COMPSIZE(map)] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 125 + offset 271 + +GetPixelMapuiv(map, values) + return void + param map PixelMap in value + param values UInt32 out array [COMPSIZE(map)] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 126 + offset 272 + +GetPixelMapusv(map, values) + return void + param map PixelMap in value + param values UInt16 out array [COMPSIZE(map)] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 127 + offset 273 + +GetPolygonStipple(mask) + return void + param mask UInt8 out array [COMPSIZE()] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + glxflags client-handcode server-handcode + version 1.0 + deprecated 3.1 + glxsingle 128 + wglflags client-handcode server-handcode + offset 274 + +GetTexEnvfv(target, pname, params) + return void + param target TextureEnvTarget in value + param pname TextureEnvParameter in value + param params Float32 out array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 130 + wglflags small-data + offset 276 + +GetTexEnviv(target, pname, params) + return void + param target TextureEnvTarget in value + param pname TextureEnvParameter in value + param params Int32 out array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 131 + wglflags small-data + offset 277 + +GetTexGendv(coord, pname, params) + return void + param coord TextureCoordName in value + param pname TextureGenParameter in value + param params Float64 out array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 132 + wglflags small-data + offset 278 + +GetTexGenfv(coord, pname, params) + return void + param coord TextureCoordName in value + param pname TextureGenParameter in value + param params Float32 out array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 133 + wglflags small-data + offset 279 + +GetTexGeniv(coord, pname, params) + return void + param coord TextureCoordName in value + param pname TextureGenParameter in value + param params Int32 out array [COMPSIZE(pname)] + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 134 + wglflags small-data + offset 280 + +IsList(list) + return Boolean + param list List in value + category VERSION_1_0_DEPRECATED # old: state-req + dlflags notlistable + version 1.0 + deprecated 3.1 + glxsingle 141 + offset 287 + +Frustum(left, right, bottom, top, zNear, zFar) + return void + param left Float64 in value + param right Float64 in value + param bottom Float64 in value + param top Float64 in value + param zNear Float64 in value + param zFar Float64 in value + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 175 + offset 289 + +LoadIdentity() + return void + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 176 + offset 290 + +LoadMatrixf(m) + return void + param m Float32 in array [16] + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 177 + offset 291 + +LoadMatrixd(m) + return void + param m Float64 in array [16] + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 178 + offset 292 + +MatrixMode(mode) + return void + param mode MatrixMode in value + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 179 + offset 293 + +MultMatrixf(m) + return void + param m Float32 in array [16] + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 180 + offset 294 + +MultMatrixd(m) + return void + param m Float64 in array [16] + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 181 + offset 295 + +Ortho(left, right, bottom, top, zNear, zFar) + return void + param left Float64 in value + param right Float64 in value + param bottom Float64 in value + param top Float64 in value + param zNear Float64 in value + param zFar Float64 in value + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 182 + offset 296 + +PopMatrix() + return void + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 183 + offset 297 + +PushMatrix() + return void + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 184 + offset 298 + +Rotated(angle, x, y, z) + return void + param angle Float64 in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 185 + offset 299 + +Rotatef(angle, x, y, z) + return void + param angle Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 186 + offset 300 + +Scaled(x, y, z) + return void + param x Float64 in value + param y Float64 in value + param z Float64 in value + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 187 + offset 301 + +Scalef(x, y, z) + return void + param x Float32 in value + param y Float32 in value + param z Float32 in value + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 188 + offset 302 + +Translated(x, y, z) + return void + param x Float64 in value + param y Float64 in value + param z Float64 in value + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 189 + offset 303 + +Translatef(x, y, z) + return void + param x Float32 in value + param y Float32 in value + param z Float32 in value + category VERSION_1_0_DEPRECATED # old: xform + version 1.0 + deprecated 3.1 + glxropcode 190 + offset 304 + +############################################################################### +############################################################################### +# +# OpenGL 1.1 commands +# +############################################################################### +############################################################################### + +DrawArrays(mode, first, count) + return void + param mode BeginMode in value + param first Int32 in value + param count SizeI in value + category VERSION_1_1 + dlflags handcode + glxflags client-handcode client-intercept server-handcode + version 1.1 + glxropcode 193 + offset 310 + +DrawElements(mode, count, type, indices) + return void + param mode BeginMode in value + param count SizeI in value + param type DrawElementsType in value + param indices Void in array [COMPSIZE(count/type)] + category VERSION_1_1 + dlflags handcode + glxflags client-handcode client-intercept server-handcode + version 1.1 + offset 311 + +GetPointerv(pname, params) + return void + param pname GetPointervPName in value + param params VoidPointer out array [1] + category VERSION_1_1 + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + version 1.1 + offset 329 + +PolygonOffset(factor, units) + return void + param factor Float32 in value + param units Float32 in value + category VERSION_1_1 + version 1.1 + glxropcode 192 + offset 319 + +# Arguably TexelInternalFormat, not PixelInternalFormat +CopyTexImage1D(target, level, internalformat, x, y, width, border) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat PixelInternalFormat in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param border CheckedInt32 in value + category VERSION_1_1 + version 1.1 + glxropcode 4119 + glxflags EXT + offset 323 + +# Arguably TexelInternalFormat, not PixelInternalFormat +CopyTexImage2D(target, level, internalformat, x, y, width, height, border) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat PixelInternalFormat in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + param border CheckedInt32 in value + category VERSION_1_1 + version 1.1 + glxropcode 4120 + glxflags EXT + offset 324 + +CopyTexSubImage1D(target, level, xoffset, x, y, width) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + category VERSION_1_1 + version 1.1 + glxropcode 4121 + glxflags EXT + offset 325 + +CopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + category VERSION_1_1 + version 1.1 + glxropcode 4122 + glxflags EXT + offset 326 + +TexSubImage1D(target, level, xoffset, width, format, type, pixels) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param width SizeI in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width)] + category VERSION_1_1 + dlflags handcode + glxflags EXT client-handcode server-handcode + version 1.1 + glxropcode 4099 + offset 332 + +TexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height)] + category VERSION_1_1 + dlflags handcode + glxflags EXT client-handcode server-handcode + version 1.1 + glxropcode 4100 + offset 333 + +BindTexture(target, texture) + return void + param target TextureTarget in value + param texture Texture in value + category VERSION_1_1 + version 1.1 + glxropcode 4117 + glxflags EXT + offset 307 + +DeleteTextures(n, textures) + return void + param n SizeI in value + param textures Texture in array [n] + category VERSION_1_1 + dlflags notlistable + version 1.1 + glxsingle 144 + offset 327 + +GenTextures(n, textures) + return void + param n SizeI in value + param textures Texture out array [n] + category VERSION_1_1 + dlflags notlistable + version 1.1 + glxsingle 145 + offset 328 + +IsTexture(texture) + return Boolean + param texture Texture in value + category VERSION_1_1 + dlflags notlistable + version 1.1 + glxsingle 146 + offset 330 + +############################################################################### +############################################################################### +# +# OpenGL 1.1 deprecated commands +# +############################################################################### +############################################################################### + +ArrayElement(i) + return void + param i Int32 in value + category VERSION_1_1_DEPRECATED + dlflags handcode + glxflags client-handcode client-intercept server-handcode + version 1.1 + deprecated 3.1 + offset 306 + +ColorPointer(size, type, stride, pointer) + return void + param size Int32 in value + param type ColorPointerType in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(size/type/stride)] retained + category VERSION_1_1_DEPRECATED + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + version 1.1 + deprecated 3.1 + offset 308 + +DisableClientState(array) + return void + param array EnableCap in value + category VERSION_1_1_DEPRECATED + version 1.1 + deprecated 3.1 + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + offset 309 + +EdgeFlagPointer(stride, pointer) + return void + param stride SizeI in value + param pointer Void in array [COMPSIZE(stride)] retained + category VERSION_1_1_DEPRECATED + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + version 1.1 + deprecated 3.1 + offset 312 + +EnableClientState(array) + return void + param array EnableCap in value + category VERSION_1_1_DEPRECATED + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + version 1.1 + deprecated 3.1 + offset 313 + +IndexPointer(type, stride, pointer) + return void + param type IndexPointerType in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(type/stride)] retained + category VERSION_1_1_DEPRECATED + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + version 1.1 + deprecated 3.1 + offset 314 + +InterleavedArrays(format, stride, pointer) + return void + param format InterleavedArrayFormat in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(format/stride)] retained + category VERSION_1_1_DEPRECATED + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + version 1.1 + deprecated 3.1 + offset 317 + +NormalPointer(type, stride, pointer) + return void + param type NormalPointerType in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(type/stride)] retained + category VERSION_1_1_DEPRECATED + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + version 1.1 + deprecated 3.1 + offset 318 + +TexCoordPointer(size, type, stride, pointer) + return void + param size Int32 in value + param type TexCoordPointerType in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(size/type/stride)] retained + category VERSION_1_1_DEPRECATED + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + version 1.1 + deprecated 3.1 + offset 320 + +VertexPointer(size, type, stride, pointer) + return void + param size Int32 in value + param type VertexPointerType in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(size/type/stride)] retained + category VERSION_1_1_DEPRECATED + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + version 1.1 + deprecated 3.1 + offset 321 + +AreTexturesResident(n, textures, residences) + return Boolean + param n SizeI in value + param textures Texture in array [n] + param residences Boolean out array [n] + category VERSION_1_1_DEPRECATED + glxsingle 143 + dlflags notlistable + version 1.1 + deprecated 3.1 + offset 322 + +PrioritizeTextures(n, textures, priorities) + return void + param n SizeI in value + param textures Texture in array [n] + param priorities ClampedFloat32 in array [n] + category VERSION_1_1_DEPRECATED + version 1.1 + deprecated 3.1 + glxropcode 4118 + glxflags EXT + offset 331 + +Indexub(c) + return void + param c ColorIndexValueUB in value + category VERSION_1_1_DEPRECATED + vectorequiv Indexubv + version 1.1 + offset 315 + +Indexubv(c) + return void + param c ColorIndexValueUB in array [1] + category VERSION_1_1_DEPRECATED + version 1.1 + glxropcode 194 + offset 316 + +PopClientAttrib() + return void + category VERSION_1_1_DEPRECATED + version 1.1 + deprecated 3.1 + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + offset 334 + +PushClientAttrib(mask) + return void + param mask ClientAttribMask in value + category VERSION_1_1_DEPRECATED + version 1.1 + deprecated 3.1 + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + offset 335 + +############################################################################### +############################################################################### +# +# OpenGL 1.2 commands +# +############################################################################### +############################################################################### + +BlendColor(red, green, blue, alpha) + return void + param red ClampedColorF in value + param green ClampedColorF in value + param blue ClampedColorF in value + param alpha ClampedColorF in value + category VERSION_1_2 + glxflags EXT + version 1.2 + glxropcode 4096 + offset 336 + +BlendEquation(mode) + return void + param mode BlendEquationMode in value + category VERSION_1_2 + glxflags EXT + version 1.2 + glxropcode 4097 + offset 337 + +DrawRangeElements(mode, start, end, count, type, indices) + return void + param mode BeginMode in value + param start UInt32 in value + param end UInt32 in value + param count SizeI in value + param type DrawElementsType in value + param indices Void in array [COMPSIZE(count/type)] + category VERSION_1_2 + dlflags handcode + glxflags client-handcode client-intercept server-handcode + version 1.2 + offset 338 + +# OpenGL 1.2 (EXT_texture3D) commands + +# Arguably TexelInternalFormat, not PixelInternalFormat +TexImage3D(target, level, internalformat, width, height, depth, border, format, type, pixels) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureComponentCount in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param border CheckedInt32 in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height/depth)] + category VERSION_1_2 + dlflags handcode + glxflags client-handcode server-handcode EXT + version 1.2 + deprecated 3.1 + glxropcode 4114 + offset 371 + +TexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param zoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height/depth)] + category VERSION_1_2 + dlflags handcode + glxflags client-handcode server-handcode EXT + version 1.2 + glxropcode 4115 + offset 372 + +# OpenGL 1.2 (EXT_copy_texture) commands (specific to texture3D) + +CopyTexSubImage3D(target, level, xoffset, yoffset, zoffset, x, y, width, height) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param zoffset CheckedInt32 in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + category VERSION_1_2 + glxflags EXT + version 1.2 + glxropcode 4123 + offset 373 + +############################################################################### +############################################################################### +# +# OpenGL 1.2 deprecated commands +# +############################################################################### +############################################################################### + +# OpenGL 1.2 (SGI_color_table) commands + +ColorTable(target, internalformat, width, format, type, table) + return void + param target ColorTableTarget in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param format PixelFormat in value + param type PixelType in value + param table Void in array [COMPSIZE(format/type/width)] + category VERSION_1_2_DEPRECATED + dlflags handcode + glxflags client-handcode server-handcode EXT + version 1.2 + deprecated 3.1 + glxropcode 2053 + offset 339 + +ColorTableParameterfv(target, pname, params) + return void + param target ColorTableTarget in value + param pname ColorTableParameterPName in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category VERSION_1_2_DEPRECATED + glxflags EXT + version 1.2 + deprecated 3.1 + glxropcode 2054 + offset 340 + +ColorTableParameteriv(target, pname, params) + return void + param target ColorTableTarget in value + param pname ColorTableParameterPName in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category VERSION_1_2_DEPRECATED + glxflags EXT + version 1.2 + deprecated 3.1 + glxropcode 2055 + offset 341 + +CopyColorTable(target, internalformat, x, y, width) + return void + param target ColorTableTarget in value + param internalformat PixelInternalFormat in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + category VERSION_1_2_DEPRECATED + glxflags EXT + version 1.2 + deprecated 3.1 + glxropcode 2056 + offset 342 + +GetColorTable(target, format, type, table) + return void + param target ColorTableTarget in value + param format PixelFormat in value + param type PixelType in value + param table Void out array [COMPSIZE(target/format/type)] + category VERSION_1_2_DEPRECATED + dlflags notlistable + glxflags client-handcode server-handcode + version 1.2 + deprecated 3.1 + glxsingle 147 + offset 343 + +GetColorTableParameterfv(target, pname, params) + return void + param target ColorTableTarget in value + param pname GetColorTableParameterPName in value + param params Float32 out array [COMPSIZE(pname)] + category VERSION_1_2_DEPRECATED + dlflags notlistable + version 1.2 + deprecated 3.1 + glxsingle 148 + offset 344 + +GetColorTableParameteriv(target, pname, params) + return void + param target ColorTableTarget in value + param pname GetColorTableParameterPName in value + param params Int32 out array [COMPSIZE(pname)] + category VERSION_1_2_DEPRECATED + dlflags notlistable + version 1.2 + deprecated 3.1 + glxsingle 149 + offset 345 + +# OpenGL 1.2 (EXT_color_subtable) commands + +ColorSubTable(target, start, count, format, type, data) + return void + param target ColorTableTarget in value + param start SizeI in value + param count SizeI in value + param format PixelFormat in value + param type PixelType in value + param data Void in array [COMPSIZE(format/type/count)] + category VERSION_1_2_DEPRECATED + dlflags handcode + glxflags client-handcode server-handcode + version 1.2 + deprecated 3.1 + glxropcode 195 + offset 346 + +CopyColorSubTable(target, start, x, y, width) + return void + param target ColorTableTarget in value + param start SizeI in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + category VERSION_1_2_DEPRECATED + version 1.2 + deprecated 3.1 + glxropcode 196 + offset 347 + +# OpenGL 1.2 (EXT_convolution) commands + +ConvolutionFilter1D(target, internalformat, width, format, type, image) + return void + param target ConvolutionTarget in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param format PixelFormat in value + param type PixelType in value + param image Void in array [COMPSIZE(format/type/width)] + category VERSION_1_2_DEPRECATED + dlflags handcode + glxflags client-handcode server-handcode EXT + version 1.2 + deprecated 3.1 + glxropcode 4101 + offset 348 + +ConvolutionFilter2D(target, internalformat, width, height, format, type, image) + return void + param target ConvolutionTarget in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param height SizeI in value + param format PixelFormat in value + param type PixelType in value + param image Void in array [COMPSIZE(format/type/width/height)] + category VERSION_1_2_DEPRECATED + dlflags handcode + glxflags client-handcode server-handcode EXT + version 1.2 + deprecated 3.1 + glxropcode 4102 + offset 349 + +ConvolutionParameterf(target, pname, params) + return void + param target ConvolutionTarget in value + param pname ConvolutionParameter in value + param params CheckedFloat32 in value + category VERSION_1_2_DEPRECATED + glxflags EXT + version 1.2 + deprecated 3.1 + glxropcode 4103 + offset 350 + +ConvolutionParameterfv(target, pname, params) + return void + param target ConvolutionTarget in value + param pname ConvolutionParameter in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category VERSION_1_2_DEPRECATED + glxflags EXT + version 1.2 + deprecated 3.1 + glxropcode 4104 + offset 351 + +ConvolutionParameteri(target, pname, params) + return void + param target ConvolutionTarget in value + param pname ConvolutionParameter in value + param params CheckedInt32 in value + category VERSION_1_2_DEPRECATED + glxflags EXT + version 1.2 + deprecated 3.1 + glxropcode 4105 + offset 352 + +ConvolutionParameteriv(target, pname, params) + return void + param target ConvolutionTarget in value + param pname ConvolutionParameter in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category VERSION_1_2_DEPRECATED + glxflags EXT + version 1.2 + deprecated 3.1 + glxropcode 4106 + offset 353 + +CopyConvolutionFilter1D(target, internalformat, x, y, width) + return void + param target ConvolutionTarget in value + param internalformat PixelInternalFormat in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + category VERSION_1_2_DEPRECATED + glxflags EXT + version 1.2 + deprecated 3.1 + glxropcode 4107 + offset 354 + +CopyConvolutionFilter2D(target, internalformat, x, y, width, height) + return void + param target ConvolutionTarget in value + param internalformat PixelInternalFormat in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + category VERSION_1_2_DEPRECATED + glxflags EXT + version 1.2 + deprecated 3.1 + glxropcode 4108 + offset 355 + +GetConvolutionFilter(target, format, type, image) + return void + param target ConvolutionTarget in value + param format PixelFormat in value + param type PixelType in value + param image Void out array [COMPSIZE(target/format/type)] + category VERSION_1_2_DEPRECATED + dlflags notlistable + glxflags client-handcode server-handcode + version 1.2 + deprecated 3.1 + glxsingle 150 + offset 356 + +GetConvolutionParameterfv(target, pname, params) + return void + param target ConvolutionTarget in value + param pname GetConvolutionParameterPName in value + param params Float32 out array [COMPSIZE(pname)] + category VERSION_1_2_DEPRECATED + dlflags notlistable + version 1.2 + deprecated 3.1 + glxsingle 151 + offset 357 + +GetConvolutionParameteriv(target, pname, params) + return void + param target ConvolutionTarget in value + param pname GetConvolutionParameterPName in value + param params Int32 out array [COMPSIZE(pname)] + category VERSION_1_2_DEPRECATED + dlflags notlistable + version 1.2 + deprecated 3.1 + glxsingle 152 + offset 358 + +GetSeparableFilter(target, format, type, row, column, span) + return void + param target SeparableTarget in value + param format PixelFormat in value + param type PixelType in value + param row Void out array [COMPSIZE(target/format/type)] + param column Void out array [COMPSIZE(target/format/type)] + param span Void out array [COMPSIZE(target/format/type)] + category VERSION_1_2_DEPRECATED + dlflags notlistable + glxflags client-handcode server-handcode + version 1.2 + deprecated 3.1 + glxsingle 153 + offset 359 + +SeparableFilter2D(target, internalformat, width, height, format, type, row, column) + return void + param target SeparableTarget in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param height SizeI in value + param format PixelFormat in value + param type PixelType in value + param row Void in array [COMPSIZE(target/format/type/width)] + param column Void in array [COMPSIZE(target/format/type/height)] + category VERSION_1_2_DEPRECATED + dlflags handcode + glxflags client-handcode server-handcode EXT + version 1.2 + deprecated 3.1 + glxropcode 4109 + offset 360 + +# OpenGL 1.2 (EXT_histogram) commands + +GetHistogram(target, reset, format, type, values) + return void + param target HistogramTarget in value + param reset Boolean in value + param format PixelFormat in value + param type PixelType in value + param values Void out array [COMPSIZE(target/format/type)] + category VERSION_1_2_DEPRECATED + dlflags notlistable + glxflags client-handcode server-handcode + version 1.2 + deprecated 3.1 + glxsingle 154 + offset 361 + +GetHistogramParameterfv(target, pname, params) + return void + param target HistogramTarget in value + param pname GetHistogramParameterPName in value + param params Float32 out array [COMPSIZE(pname)] + category VERSION_1_2_DEPRECATED + dlflags notlistable + version 1.2 + deprecated 3.1 + glxsingle 155 + offset 362 + +GetHistogramParameteriv(target, pname, params) + return void + param target HistogramTarget in value + param pname GetHistogramParameterPName in value + param params Int32 out array [COMPSIZE(pname)] + category VERSION_1_2_DEPRECATED + dlflags notlistable + version 1.2 + deprecated 3.1 + glxsingle 156 + offset 363 + +GetMinmax(target, reset, format, type, values) + return void + param target MinmaxTarget in value + param reset Boolean in value + param format PixelFormat in value + param type PixelType in value + param values Void out array [COMPSIZE(target/format/type)] + category VERSION_1_2_DEPRECATED + dlflags notlistable + glxflags client-handcode server-handcode + version 1.2 + deprecated 3.1 + glxsingle 157 + offset 364 + +GetMinmaxParameterfv(target, pname, params) + return void + param target MinmaxTarget in value + param pname GetMinmaxParameterPName in value + param params Float32 out array [COMPSIZE(pname)] + category VERSION_1_2_DEPRECATED + dlflags notlistable + version 1.2 + deprecated 3.1 + glxsingle 158 + offset 365 + +GetMinmaxParameteriv(target, pname, params) + return void + param target MinmaxTarget in value + param pname GetMinmaxParameterPName in value + param params Int32 out array [COMPSIZE(pname)] + category VERSION_1_2_DEPRECATED + dlflags notlistable + version 1.2 + deprecated 3.1 + glxsingle 159 + offset 366 + +Histogram(target, width, internalformat, sink) + return void + param target HistogramTarget in value + param width SizeI in value + param internalformat PixelInternalFormat in value + param sink Boolean in value + category VERSION_1_2_DEPRECATED + dlflags handcode + glxflags EXT + version 1.2 + deprecated 3.1 + glxropcode 4110 + offset 367 + +Minmax(target, internalformat, sink) + return void + param target MinmaxTarget in value + param internalformat PixelInternalFormat in value + param sink Boolean in value + category VERSION_1_2_DEPRECATED + glxflags EXT + version 1.2 + deprecated 3.1 + glxropcode 4111 + offset 368 + +ResetHistogram(target) + return void + param target HistogramTarget in value + category VERSION_1_2_DEPRECATED + glxflags EXT + version 1.2 + deprecated 3.1 + glxropcode 4112 + offset 369 + +ResetMinmax(target) + return void + param target MinmaxTarget in value + category VERSION_1_2_DEPRECATED + glxflags EXT + version 1.2 + deprecated 3.1 + glxropcode 4113 + offset 370 + +############################################################################### +############################################################################### +# +# OpenGL 1.3 commands +# +############################################################################### +############################################################################### + +# OpenGL 1.3 (ARB_multitexture) commands + +ActiveTexture(texture) + return void + param texture TextureUnit in value + category VERSION_1_3 + glxflags ARB + version 1.3 + glxropcode 197 + offset 374 + +# OpenGL 1.3 (ARB_multisample) commands + +SampleCoverage(value, invert) + return void + param value ClampedFloat32 in value + param invert Boolean in value + category VERSION_1_3 + glxflags ARB + version 1.3 + glxropcode 229 + offset 412 + +# OpenGL 1.3 (ARB_texture_compression) commands + +# Arguably TexelInternalFormat, not PixelInternalFormat +CompressedTexImage3D(target, level, internalformat, width, height, depth, border, imageSize, data) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param border CheckedInt32 in value + param imageSize SizeI in value + param data CompressedTextureARB in array [imageSize] + category VERSION_1_3 + dlflags handcode + glxflags ARB client-handcode server-handcode + version 1.3 + glxropcode 216 + wglflags client-handcode server-handcode + offset 554 + +# Arguably TexelInternalFormat, not PixelInternalFormat +CompressedTexImage2D(target, level, internalformat, width, height, border, imageSize, data) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param height SizeI in value + param border CheckedInt32 in value + param imageSize SizeI in value + param data CompressedTextureARB in array [imageSize] + category VERSION_1_3 + dlflags handcode + glxflags ARB client-handcode server-handcode + version 1.3 + glxropcode 215 + wglflags client-handcode server-handcode + offset 555 + +# Arguably TexelInternalFormat, not PixelInternalFormat +CompressedTexImage1D(target, level, internalformat, width, border, imageSize, data) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param border CheckedInt32 in value + param imageSize SizeI in value + param data CompressedTextureARB in array [imageSize] + category VERSION_1_3 + dlflags handcode + glxflags ARB client-handcode server-handcode + version 1.3 + glxropcode 214 + wglflags client-handcode server-handcode + offset 556 + +CompressedTexSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param zoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param format PixelFormat in value + param imageSize SizeI in value + param data CompressedTextureARB in array [imageSize] + category VERSION_1_3 + dlflags handcode + glxflags ARB client-handcode server-handcode + version 1.3 + glxropcode 219 + wglflags client-handcode server-handcode + offset 557 + +CompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, imageSize, data) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param format PixelFormat in value + param imageSize SizeI in value + param data CompressedTextureARB in array [imageSize] + category VERSION_1_3 + dlflags handcode + glxflags ARB client-handcode server-handcode + version 1.3 + glxropcode 218 + wglflags client-handcode server-handcode + offset 558 + +CompressedTexSubImage1D(target, level, xoffset, width, format, imageSize, data) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param width SizeI in value + param format PixelFormat in value + param imageSize SizeI in value + param data CompressedTextureARB in array [imageSize] + category VERSION_1_3 + dlflags handcode + glxflags ARB client-handcode server-handcode + version 1.3 + glxropcode 217 + wglflags client-handcode server-handcode + offset 559 + +GetCompressedTexImage(target, level, img) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param img CompressedTextureARB out array [COMPSIZE(target/level)] + category VERSION_1_3 + dlflags notlistable + glxflags ARB client-handcode server-handcode + version 1.3 + glxsingle 160 + wglflags client-handcode server-handcode + offset 560 + +############################################################################### +############################################################################### +# +# OpenGL 1.3 deprecated commands +# +############################################################################### +############################################################################### + +ClientActiveTexture(texture) + return void + param texture TextureUnit in value + category VERSION_1_3_DEPRECATED + dlflags notlistable + glxflags ARB client-handcode client-intercept server-handcode + version 1.3 + deprecated 3.1 + offset 375 + +MultiTexCoord1d(target, s) + return void + param target TextureUnit in value + param s CoordD in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord1dv + offset 376 + +MultiTexCoord1dv(target, v) + return void + param target TextureUnit in value + param v CoordD in array [1] + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + glxropcode 198 + offset 377 + +MultiTexCoord1f(target, s) + return void + param target TextureUnit in value + param s CoordF in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord1fv + offset 378 + +MultiTexCoord1fv(target, v) + return void + param target TextureUnit in value + param v CoordF in array [1] + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + glxropcode 199 + offset 379 + +MultiTexCoord1i(target, s) + return void + param target TextureUnit in value + param s CoordI in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord1iv + offset 380 + +MultiTexCoord1iv(target, v) + return void + param target TextureUnit in value + param v CoordI in array [1] + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + glxropcode 200 + offset 381 + +MultiTexCoord1s(target, s) + return void + param target TextureUnit in value + param s CoordS in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord1sv + offset 382 + +MultiTexCoord1sv(target, v) + return void + param target TextureUnit in value + param v CoordS in array [1] + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + glxropcode 201 + offset 383 + +MultiTexCoord2d(target, s, t) + return void + param target TextureUnit in value + param s CoordD in value + param t CoordD in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord2dv + offset 384 + +MultiTexCoord2dv(target, v) + return void + param target TextureUnit in value + param v CoordD in array [2] + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + glxropcode 202 + offset 385 + +MultiTexCoord2f(target, s, t) + return void + param target TextureUnit in value + param s CoordF in value + param t CoordF in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord2fv + offset 386 + +MultiTexCoord2fv(target, v) + return void + param target TextureUnit in value + param v CoordF in array [2] + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + glxropcode 203 + offset 387 + +MultiTexCoord2i(target, s, t) + return void + param target TextureUnit in value + param s CoordI in value + param t CoordI in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord2iv + offset 388 + +MultiTexCoord2iv(target, v) + return void + param target TextureUnit in value + param v CoordI in array [2] + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + glxropcode 204 + offset 389 + +MultiTexCoord2s(target, s, t) + return void + param target TextureUnit in value + param s CoordS in value + param t CoordS in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord2sv + offset 390 + +MultiTexCoord2sv(target, v) + return void + param target TextureUnit in value + param v CoordS in array [2] + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + glxropcode 205 + offset 391 + +MultiTexCoord3d(target, s, t, r) + return void + param target TextureUnit in value + param s CoordD in value + param t CoordD in value + param r CoordD in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord3dv + offset 392 + +MultiTexCoord3dv(target, v) + return void + param target TextureUnit in value + param v CoordD in array [3] + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + glxropcode 206 + offset 393 + +MultiTexCoord3f(target, s, t, r) + return void + param target TextureUnit in value + param s CoordF in value + param t CoordF in value + param r CoordF in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord3fv + offset 394 + +MultiTexCoord3fv(target, v) + return void + param target TextureUnit in value + param v CoordF in array [3] + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + glxropcode 207 + offset 395 + +MultiTexCoord3i(target, s, t, r) + return void + param target TextureUnit in value + param s CoordI in value + param t CoordI in value + param r CoordI in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord3iv + offset 396 + +MultiTexCoord3iv(target, v) + return void + param target TextureUnit in value + param v CoordI in array [3] + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + glxropcode 208 + offset 397 + +MultiTexCoord3s(target, s, t, r) + return void + param target TextureUnit in value + param s CoordS in value + param t CoordS in value + param r CoordS in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord3sv + offset 398 + +MultiTexCoord3sv(target, v) + return void + param target TextureUnit in value + param v CoordS in array [3] + category VERSION_1_3_DEPRECATED + version 1.3 + deprecated 3.1 + glxflags ARB + glxropcode 209 + offset 399 + +MultiTexCoord4d(target, s, t, r, q) + return void + param target TextureUnit in value + param s CoordD in value + param t CoordD in value + param r CoordD in value + param q CoordD in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord4dv + offset 400 + +MultiTexCoord4dv(target, v) + return void + param target TextureUnit in value + param v CoordD in array [4] + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + glxropcode 210 + offset 401 + +MultiTexCoord4f(target, s, t, r, q) + return void + param target TextureUnit in value + param s CoordF in value + param t CoordF in value + param r CoordF in value + param q CoordF in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord4fv + offset 402 + +MultiTexCoord4fv(target, v) + return void + param target TextureUnit in value + param v CoordF in array [4] + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + glxropcode 211 + offset 403 + +MultiTexCoord4i(target, s, t, r, q) + return void + param target TextureUnit in value + param s CoordI in value + param t CoordI in value + param r CoordI in value + param q CoordI in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord4iv + offset 404 + +MultiTexCoord4iv(target, v) + return void + param target TextureUnit in value + param v CoordI in array [4] + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + glxropcode 212 + offset 405 + +MultiTexCoord4s(target, s, t, r, q) + return void + param target TextureUnit in value + param s CoordS in value + param t CoordS in value + param r CoordS in value + param q CoordS in value + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + vectorequiv MultiTexCoord4sv + offset 406 + +MultiTexCoord4sv(target, v) + return void + param target TextureUnit in value + param v CoordS in array [4] + category VERSION_1_3_DEPRECATED + glxflags ARB + version 1.3 + deprecated 3.1 + glxropcode 213 + offset 407 + +# OpenGL 1.3 (ARB_transpose_matrix) commands + +LoadTransposeMatrixf(m) + return void + param m Float32 in array [16] + category VERSION_1_3_DEPRECATED + glxflags ARB client-handcode client-intercept server-handcode + version 1.3 + deprecated 3.1 + offset 408 + +LoadTransposeMatrixd(m) + return void + param m Float64 in array [16] + category VERSION_1_3_DEPRECATED + glxflags ARB client-handcode client-intercept server-handcode + version 1.3 + deprecated 3.1 + offset 409 + +MultTransposeMatrixf(m) + return void + param m Float32 in array [16] + category VERSION_1_3_DEPRECATED + glxflags ARB client-handcode client-intercept server-handcode + version 1.3 + deprecated 3.1 + offset 410 + +MultTransposeMatrixd(m) + return void + param m Float64 in array [16] + category VERSION_1_3_DEPRECATED + glxflags ARB client-handcode client-intercept server-handcode + version 1.3 + deprecated 3.1 + offset 411 + +############################################################################### +############################################################################### +# +# OpenGL 1.4 commands +# +############################################################################### +############################################################################### + +# OpenGL 1.4 (EXT_blend_func_separate) commands + +BlendFuncSeparate(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha) + return void + param sfactorRGB BlendFuncSeparateParameterEXT in value + param dfactorRGB BlendFuncSeparateParameterEXT in value + param sfactorAlpha BlendFuncSeparateParameterEXT in value + param dfactorAlpha BlendFuncSeparateParameterEXT in value + category VERSION_1_4 + glxropcode 4134 + version 1.4 + extension + offset 537 + +# OpenGL 1.4 (EXT_multi_draw_arrays) commands + +# first and count are really 'in' +MultiDrawArrays(mode, first, count, primcount) + return void + param mode BeginMode in value + param first Int32 out array [COMPSIZE(count)] + param count SizeI out array [COMPSIZE(primcount)] + param primcount SizeI in value + category VERSION_1_4 + version 1.4 + glxropcode ? + offset 644 + +MultiDrawElements(mode, count, type, indices, primcount) + return void + param mode BeginMode in value + param count SizeI in array [COMPSIZE(primcount)] + param type DrawElementsType in value + param indices VoidPointer in array [COMPSIZE(primcount)] + param primcount SizeI in value + category VERSION_1_4 + version 1.4 + glxropcode ? + offset 645 + +# OpenGL 1.4 (ARB_point_parameters, NV_point_sprite) commands + +PointParameterf(pname, param) + return void + param pname PointParameterNameARB in value + param param CheckedFloat32 in value + category VERSION_1_4 + version 1.4 + glxropcode 2065 + extension + offset 458 + +PointParameterfv(pname, params) + return void + param pname PointParameterNameARB in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category VERSION_1_4 + version 1.4 + glxropcode 2066 + extension + offset 459 + +PointParameteri(pname, param) + return void + param pname PointParameterNameARB in value + param param Int32 in value + category VERSION_1_4 + version 1.4 + extension soft WINSOFT NV20 + glxropcode 4221 + offset 642 + +PointParameteriv(pname, params) + return void + param pname PointParameterNameARB in value + param params Int32 in array [COMPSIZE(pname)] + category VERSION_1_4 + version 1.4 + extension soft WINSOFT NV20 + glxropcode 4222re + offset 643 + +############################################################################### +############################################################################### +# +# OpenGL 1.4 deprecated commands +# +############################################################################### +############################################################################### + +# OpenGL 1.4 (EXT_fog_coord) commands + +FogCoordf(coord) + return void + param coord CoordF in value + category VERSION_1_4_DEPRECATED + vectorequiv FogCoordfv + version 1.4 + deprecated 3.1 + offset 545 + +FogCoordfv(coord) + return void + param coord CoordF in array [1] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 4124 + offset 546 + +FogCoordd(coord) + return void + param coord CoordD in value + category VERSION_1_4_DEPRECATED + vectorequiv FogCoorddv + version 1.4 + deprecated 3.1 + offset 547 + +FogCoorddv(coord) + return void + param coord CoordD in array [1] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 4125 + offset 548 + +FogCoordPointer(type, stride, pointer) + return void + param type FogPointerTypeEXT in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(type/stride)] retained + category VERSION_1_4_DEPRECATED + dlflags notlistable + version 1.4 + deprecated 3.1 + glxflags client-handcode server-handcode + offset 549 + +# OpenGL 1.4 (EXT_secondary_color) commands + +SecondaryColor3b(red, green, blue) + return void + param red ColorB in value + param green ColorB in value + param blue ColorB in value + category VERSION_1_4_DEPRECATED + vectorequiv SecondaryColor3bv + version 1.4 + deprecated 3.1 + offset 561 + +SecondaryColor3bv(v) + return void + param v ColorB in array [3] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 4126 + offset 562 + +SecondaryColor3d(red, green, blue) + return void + param red ColorD in value + param green ColorD in value + param blue ColorD in value + category VERSION_1_4_DEPRECATED + vectorequiv SecondaryColor3dv + version 1.4 + deprecated 3.1 + offset 563 + +SecondaryColor3dv(v) + return void + param v ColorD in array [3] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 4130 + offset 564 + +SecondaryColor3f(red, green, blue) + return void + param red ColorF in value + param green ColorF in value + param blue ColorF in value + category VERSION_1_4_DEPRECATED + vectorequiv SecondaryColor3fv + version 1.4 + deprecated 3.1 + offset 565 + +SecondaryColor3fv(v) + return void + param v ColorF in array [3] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 4129 + offset 566 + +SecondaryColor3i(red, green, blue) + return void + param red ColorI in value + param green ColorI in value + param blue ColorI in value + category VERSION_1_4_DEPRECATED + vectorequiv SecondaryColor3iv + version 1.4 + deprecated 3.1 + offset 567 + +SecondaryColor3iv(v) + return void + param v ColorI in array [3] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 4128 + offset 568 + +SecondaryColor3s(red, green, blue) + return void + param red ColorS in value + param green ColorS in value + param blue ColorS in value + category VERSION_1_4_DEPRECATED + vectorequiv SecondaryColor3sv + version 1.4 + deprecated 3.1 + offset 569 + +SecondaryColor3sv(v) + return void + param v ColorS in array [3] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 4127 + offset 570 + +SecondaryColor3ub(red, green, blue) + return void + param red ColorUB in value + param green ColorUB in value + param blue ColorUB in value + category VERSION_1_4_DEPRECATED + vectorequiv SecondaryColor3ubv + version 1.4 + deprecated 3.1 + offset 571 + +SecondaryColor3ubv(v) + return void + param v ColorUB in array [3] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 4131 + offset 572 + +SecondaryColor3ui(red, green, blue) + return void + param red ColorUI in value + param green ColorUI in value + param blue ColorUI in value + category VERSION_1_4_DEPRECATED + vectorequiv SecondaryColor3uiv + version 1.4 + deprecated 3.1 + offset 573 + +SecondaryColor3uiv(v) + return void + param v ColorUI in array [3] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 4133 + offset 574 + +SecondaryColor3us(red, green, blue) + return void + param red ColorUS in value + param green ColorUS in value + param blue ColorUS in value + category VERSION_1_4_DEPRECATED + vectorequiv SecondaryColor3usv + version 1.4 + deprecated 3.1 + offset 575 + +SecondaryColor3usv(v) + return void + param v ColorUS in array [3] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 4132 + offset 576 + +SecondaryColorPointer(size, type, stride, pointer) + return void + param size Int32 in value + param type ColorPointerType in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(size/type/stride)] retained + category VERSION_1_4_DEPRECATED + dlflags notlistable + glxflags client-handcode server-handcode + version 1.4 + deprecated 3.1 + extension + offset 577 + +# OpenGL 1.4 (ARB_window_pos) commands +# Note: all WindowPos* entry points use glxropcode ropcode 230, with 3 float parameters + +WindowPos2d(x, y) + return void + param x CoordD in value + param y CoordD in value + category VERSION_1_4_DEPRECATED + vectorequiv WindowPos2dv + version 1.4 + deprecated 3.1 + offset 513 + +WindowPos2dv(v) + return void + param v CoordD in array [2] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 230 + glxflags client-handcode server-handcode + offset 514 + +WindowPos2f(x, y) + return void + param x CoordF in value + param y CoordF in value + category VERSION_1_4_DEPRECATED + vectorequiv WindowPos2fv + version 1.4 + deprecated 3.1 + offset 515 + +WindowPos2fv(v) + return void + param v CoordF in array [2] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 230 + glxflags client-handcode server-handcode + offset 516 + +WindowPos2i(x, y) + return void + param x CoordI in value + param y CoordI in value + category VERSION_1_4_DEPRECATED + vectorequiv WindowPos2iv + version 1.4 + deprecated 3.1 + offset 517 + +WindowPos2iv(v) + return void + param v CoordI in array [2] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 230 + glxflags client-handcode server-handcode + offset 518 + +WindowPos2s(x, y) + return void + param x CoordS in value + param y CoordS in value + category VERSION_1_4_DEPRECATED + vectorequiv WindowPos2sv + version 1.4 + deprecated 3.1 + offset 519 + +WindowPos2sv(v) + return void + param v CoordS in array [2] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 230 + glxflags client-handcode server-handcode + offset 520 + +WindowPos3d(x, y, z) + return void + param x CoordD in value + param y CoordD in value + param z CoordD in value + vectorequiv WindowPos3dv + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + offset 521 + +WindowPos3dv(v) + return void + param v CoordD in array [3] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 230 + glxflags client-handcode server-handcode + offset 522 + +WindowPos3f(x, y, z) + return void + param x CoordF in value + param y CoordF in value + param z CoordF in value + category VERSION_1_4_DEPRECATED + vectorequiv WindowPos3fv + version 1.4 + deprecated 3.1 + offset 523 + +WindowPos3fv(v) + return void + param v CoordF in array [3] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 230 + glxflags client-handcode server-handcode + offset 524 + +WindowPos3i(x, y, z) + return void + param x CoordI in value + param y CoordI in value + param z CoordI in value + category VERSION_1_4_DEPRECATED + vectorequiv WindowPos3iv + version 1.4 + deprecated 3.1 + offset 525 + +WindowPos3iv(v) + return void + param v CoordI in array [3] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 230 + glxflags client-handcode server-handcode + offset 526 + +WindowPos3s(x, y, z) + return void + param x CoordS in value + param y CoordS in value + param z CoordS in value + category VERSION_1_4_DEPRECATED + vectorequiv WindowPos3sv + version 1.4 + deprecated 3.1 + offset 527 + +WindowPos3sv(v) + return void + param v CoordS in array [3] + category VERSION_1_4_DEPRECATED + version 1.4 + deprecated 3.1 + glxropcode 230 + glxflags client-handcode server-handcode + offset 528 + +############################################################################### +############################################################################### +# +# OpenGL 1.5 commands +# +############################################################################### +############################################################################### + +# OpenGL 1.5 (ARB_occlusion_query) commands + +GenQueries(n, ids) + return void + param n SizeI in value + param ids UInt32 out array [n] + category VERSION_1_5 + version 1.5 + extension + glxsingle 162 + glxflags ignore + offset 700 + +DeleteQueries(n, ids) + return void + param n SizeI in value + param ids UInt32 in array [n] + category VERSION_1_5 + version 1.5 + extension + glxsingle 161 + glxflags ignore + offset 701 + +IsQuery(id) + return Boolean + param id UInt32 in value + category VERSION_1_5 + version 1.5 + extension + glxsingle 163 + glxflags ignore + offset 702 + +BeginQuery(target, id) + return void + param target GLenum in value + param id UInt32 in value + category VERSION_1_5 + version 1.5 + extension + glxropcode 231 + glxflags ignore + offset 703 + +EndQuery(target) + return void + param target GLenum in value + category VERSION_1_5 + version 1.5 + extension + glxropcode 232 + glxflags ignore + offset 704 + +GetQueryiv(target, pname, params) + return void + param target GLenum in value + param pname GLenum in value + param params Int32 out array [pname] + category VERSION_1_5 + dlflags notlistable + version 1.5 + extension + glxsingle 164 + glxflags ignore + offset 705 + +GetQueryObjectiv(id, pname, params) + return void + param id UInt32 in value + param pname GLenum in value + param params Int32 out array [pname] + category VERSION_1_5 + dlflags notlistable + version 1.5 + extension + glxsingle 165 + glxflags ignore + offset 706 + +GetQueryObjectuiv(id, pname, params) + return void + param id UInt32 in value + param pname GLenum in value + param params UInt32 out array [pname] + category VERSION_1_5 + dlflags notlistable + version 1.5 + extension + glxsingle 166 + glxflags ignore + offset 707 + +# OpenGL 1.5 (ARB_vertex_buffer_object) commands + +BindBuffer(target, buffer) + return void + param target BufferTargetARB in value + param buffer UInt32 in value + category VERSION_1_5 + version 1.5 + extension + glxropcode ? + glxflags ignore + offset 688 + +DeleteBuffers(n, buffers) + return void + param n SizeI in value + param buffers ConstUInt32 in array [n] + category VERSION_1_5 + version 1.5 + extension + glxropcode ? + glxflags ignore + offset 691 + +GenBuffers(n, buffers) + return void + param n SizeI in value + param buffers UInt32 out array [n] + category VERSION_1_5 + version 1.5 + extension + glxropcode ? + glxflags ignore + offset 692 + +IsBuffer(buffer) + return Boolean + param buffer UInt32 in value + category VERSION_1_5 + version 1.5 + extension + glxropcode ? + glxflags ignore + offset 696 + +BufferData(target, size, data, usage) + return void + param target BufferTargetARB in value + param size BufferSize in value + param data ConstVoid in array [size] + param usage BufferUsageARB in value + category VERSION_1_5 + version 1.5 + extension + glxropcode ? + glxflags ignore + offset 689 + +BufferSubData(target, offset, size, data) + return void + param target BufferTargetARB in value + param offset BufferOffset in value + param size BufferSize in value + param data ConstVoid in array [size] + category VERSION_1_5 + version 1.5 + extension + glxropcode ? + glxflags ignore + offset 690 + +GetBufferSubData(target, offset, size, data) + return void + param target BufferTargetARB in value + param offset BufferOffset in value + param size BufferSize in value + param data Void out array [size] + category VERSION_1_5 + dlflags notlistable + version 1.5 + extension + glxsingle ? + glxflags ignore + offset 695 + +MapBuffer(target, access) + return VoidPointer + param target BufferTargetARB in value + param access BufferAccessARB in value + category VERSION_1_5 + version 1.5 + extension + glxropcode ? + glxflags ignore + offset 697 + +UnmapBuffer(target) + return Boolean + param target BufferTargetARB in value + category VERSION_1_5 + version 1.5 + extension + glxropcode ? + glxflags ignore + offset 698 + +GetBufferParameteriv(target, pname, params) + return void + param target BufferTargetARB in value + param pname BufferPNameARB in value + param params Int32 out array [COMPSIZE(pname)] + category VERSION_1_5 + dlflags notlistable + version 1.5 + extension + glxsingle ? + glxflags ignore + offset 693 + +GetBufferPointerv(target, pname, params) + return void + param target BufferTargetARB in value + param pname BufferPointerNameARB in value + param params VoidPointer out array [1] + category VERSION_1_5 + dlflags notlistable + version 1.5 + extension + glxsingle ? + glxflags ignore + offset 694 + +# OpenGL 1.5 (EXT_shadow_funcs) commands - none + + +############################################################################### +############################################################################### +# +# OpenGL 2.0 commands +# +############################################################################### +############################################################################### + +# OpenGL 2.0 (EXT_blend_equation_separate) commands + +BlendEquationSeparate(modeRGB, modeAlpha) + return void + param modeRGB BlendEquationModeEXT in value + param modeAlpha BlendEquationModeEXT in value + category VERSION_2_0 + version 2.0 + extension + glxropcode 4228 + +# OpenGL 2.0 (ARB_draw_buffers) commands + +DrawBuffers(n, bufs) + return void + param n SizeI in value + param bufs DrawBufferModeATI in array [n] + category VERSION_2_0 + version 2.0 + extension + glxropcode 233 + glxflags ignore + offset ? + +# OpenGL 2.0 (ARB_stencil_two_side) commands + +StencilOpSeparate(face, sfail, dpfail, dppass) + return void + param face StencilFaceDirection in value + param sfail StencilOp in value + param dpfail StencilOp in value + param dppass StencilOp in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +StencilFuncSeparate(frontfunc, backfunc, ref, mask) + return void + param frontfunc StencilFunction in value + param backfunc StencilFunction in value + param ref ClampedStencilValue in value + param mask MaskedStencilValue in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +StencilMaskSeparate(face, mask) + return void + param face StencilFaceDirection in value + param mask MaskedStencilValue in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +# OpenGL 2.0 (ARB_shader_objects / ARB_vertex_shader / ARB_fragment_shader) commands + +AttachShader(program, shader) + return void + param program UInt32 in value + param shader UInt32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +BindAttribLocation(program, index, name) + return void + param program UInt32 in value + param index UInt32 in value + param name Char in array [] + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +CompileShader(shader) + return void + param shader UInt32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +CreateProgram() + return UInt32 + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +CreateShader(type) + return UInt32 + param type GLenum in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +DeleteProgram(program) + return void + param program UInt32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +DeleteShader(shader) + return void + param shader UInt32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +DetachShader(program, shader) + return void + param program UInt32 in value + param shader UInt32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +DisableVertexAttribArray(index) + return void + param index UInt32 in value + dlflags notlistable + category VERSION_2_0 + version 2.0 + extension soft WINSOFT NV10 + glxflags ignore + offset 666 + +EnableVertexAttribArray(index) + return void + param index UInt32 in value + dlflags notlistable + category VERSION_2_0 + version 2.0 + extension soft WINSOFT NV10 + glxflags ignore + offset 665 + +GetActiveAttrib(program, index, bufSize, length, size, type, name) + return void + param program UInt32 in value + param index UInt32 in value + param bufSize SizeI in value + param length SizeI out array [1] + param size Int32 out array [1] + param type GLenum out array [1] + param name Char out array [] + category VERSION_2_0 + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetActiveUniform(program, index, bufSize, length, size, type, name) + return void + param program UInt32 in value + param index UInt32 in value + param bufSize SizeI in value + param length SizeI out array [1] + param size Int32 out array [1] + param type GLenum out array [1] + param name Char out array [] + category VERSION_2_0 + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetAttachedShaders(program, maxCount, count, obj) + return void + param program UInt32 in value + param maxCount SizeI in value + param count SizeI out array [1] + param obj UInt32 out array [count] + category VERSION_2_0 + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetAttribLocation(program, name) + return Int32 + param program UInt32 in value + param name Char in array [] + category VERSION_2_0 + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetProgramiv(program, pname, params) + return void + param program UInt32 in value + param pname GLenum in value + param params Int32 out array [pname] + category VERSION_2_0 + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetProgramInfoLog(program, bufSize, length, infoLog) + return void + param program UInt32 in value + param bufSize SizeI in value + param length SizeI out array [1] + param infoLog Char out array [length] + category VERSION_2_0 + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetShaderiv(shader, pname, params) + return void + param shader UInt32 in value + param pname GLenum in value + param params Int32 out array [pname] + category VERSION_2_0 + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetShaderInfoLog(shader, bufSize, length, infoLog) + return void + param shader UInt32 in value + param bufSize SizeI in value + param length SizeI out array [1] + param infoLog Char out array [length] + category VERSION_2_0 + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetShaderSource(shader, bufSize, length, source) + return void + param shader UInt32 in value + param bufSize SizeI in value + param length SizeI out array [1] + param source Char out array [length] + category VERSION_2_0 + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetUniformLocation(program, name) + return Int32 + param program UInt32 in value + param name Char in array [] + category VERSION_2_0 + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetUniformfv(program, location, params) + return void + param program UInt32 in value + param location Int32 in value + param params Float32 out array [location] + category VERSION_2_0 + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetUniformiv(program, location, params) + return void + param program UInt32 in value + param location Int32 in value + param params Int32 out array [location] + category VERSION_2_0 + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetVertexAttribdv(index, pname, params) + return void + param index UInt32 in value + param pname VertexAttribPropertyARB in value + param params Float64 out array [4] + dlflags notlistable + category VERSION_2_0 + version 2.0 + extension soft WINSOFT NV10 + glxvendorpriv 1301 + offset 588 + +GetVertexAttribfv(index, pname, params) + return void + param index UInt32 in value + param pname VertexAttribPropertyARB in value + param params Float32 out array [4] + dlflags notlistable + category VERSION_2_0 + version 2.0 + extension soft WINSOFT NV10 + glxvendorpriv 1302 + offset 589 + +GetVertexAttribiv(index, pname, params) + return void + param index UInt32 in value + param pname VertexAttribPropertyARB in value + param params Int32 out array [4] + dlflags notlistable + category VERSION_2_0 + version 2.0 + extension soft WINSOFT NV10 + glxvendorpriv 1303 + offset 590 + +GetVertexAttribPointerv(index, pname, pointer) + return void + param index UInt32 in value + param pname VertexAttribPointerPropertyARB in value + param pointer VoidPointer out array [1] + dlflags notlistable + category VERSION_2_0 + version 2.0 + extension soft WINSOFT NV10 + glxflags ignore + offset 591 + +IsProgram(program) + return Boolean + param program UInt32 in value + dlflags notlistable + category VERSION_2_0 + version 2.0 + extension soft WINSOFT NV10 + glxvendorpriv 1304 + offset 592 + +IsShader(shader) + return Boolean + param shader UInt32 in value + dlflags notlistable + category VERSION_2_0 + version 2.0 + extension soft WINSOFT NV10 + glxvendorpriv ? + offset ? + +LinkProgram(program) + return void + param program UInt32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +ShaderSource(shader, count, string, length) + return void + param shader UInt32 in value + param count SizeI in value + param string CharPointer in array [count] + param length Int32 in array [1] + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +UseProgram(program) + return void + param program UInt32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform1f(location, v0) + return void + param location Int32 in value + param v0 Float32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform2f(location, v0, v1) + return void + param location Int32 in value + param v0 Float32 in value + param v1 Float32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform3f(location, v0, v1, v2) + return void + param location Int32 in value + param v0 Float32 in value + param v1 Float32 in value + param v2 Float32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform4f(location, v0, v1, v2, v3) + return void + param location Int32 in value + param v0 Float32 in value + param v1 Float32 in value + param v2 Float32 in value + param v3 Float32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform1i(location, v0) + return void + param location Int32 in value + param v0 Int32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform2i(location, v0, v1) + return void + param location Int32 in value + param v0 Int32 in value + param v1 Int32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform3i(location, v0, v1, v2) + return void + param location Int32 in value + param v0 Int32 in value + param v1 Int32 in value + param v2 Int32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform4i(location, v0, v1, v2, v3) + return void + param location Int32 in value + param v0 Int32 in value + param v1 Int32 in value + param v2 Int32 in value + param v3 Int32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform1fv(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Float32 in array [count] + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform2fv(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Float32 in array [count] + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform3fv(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Float32 in array [count] + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform4fv(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Float32 in array [count] + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform1iv(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Int32 in array [count] + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform2iv(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Int32 in array [count] + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform3iv(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Int32 in array [count] + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniform4iv(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Int32 in array [count] + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +UniformMatrix2fv(location, count, transpose, value) + return void + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [count] + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +UniformMatrix3fv(location, count, transpose, value) + return void + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [count] + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +UniformMatrix4fv(location, count, transpose, value) + return void + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [count] + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +ValidateProgram(program) + return void + param program UInt32 in value + category VERSION_2_0 + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexAttrib1d(index, x) + return void + param index UInt32 in value + param x Float64 in value + category VERSION_2_0 + version 2.0 + deprecated 3.1 + vectorequiv VertexAttrib1dv + extension soft WINSOFT NV10 + glxflags ignore + offset 603 + +VertexAttrib1dv(index, v) + return void + param index UInt32 in value + param v Float64 in array [1] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxropcode 4197 + offset 604 + +VertexAttrib1f(index, x) + return void + param index UInt32 in value + param x Float32 in value + category VERSION_2_0 + version 2.0 + deprecated 3.1 + vectorequiv VertexAttrib1fv + extension soft WINSOFT NV10 + glxflags ignore + offset 605 + +VertexAttrib1fv(index, v) + return void + param index UInt32 in value + param v Float32 in array [1] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxropcode 4193 + offset 606 + +VertexAttrib1s(index, x) + return void + param index UInt32 in value + param x Int16 in value + category VERSION_2_0 + version 2.0 + deprecated 3.1 + vectorequiv VertexAttrib1sv + extension soft WINSOFT NV10 + glxflags ignore + offset 607 + +VertexAttrib1sv(index, v) + return void + param index UInt32 in value + param v Int16 in array [1] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxropcode 4189 + offset 608 + +VertexAttrib2d(index, x, y) + return void + param index UInt32 in value + param x Float64 in value + param y Float64 in value + category VERSION_2_0 + version 2.0 + deprecated 3.1 + vectorequiv VertexAttrib2dv + extension soft WINSOFT NV10 + glxflags ignore + offset 609 + +VertexAttrib2dv(index, v) + return void + param index UInt32 in value + param v Float64 in array [2] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxropcode 4198 + offset 610 + +VertexAttrib2f(index, x, y) + return void + param index UInt32 in value + param x Float32 in value + param y Float32 in value + category VERSION_2_0 + version 2.0 + deprecated 3.1 + vectorequiv VertexAttrib2fv + extension soft WINSOFT NV10 + glxflags ignore + offset 611 + +VertexAttrib2fv(index, v) + return void + param index UInt32 in value + param v Float32 in array [2] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxropcode 4194 + offset 612 + +VertexAttrib2s(index, x, y) + return void + param index UInt32 in value + param x Int16 in value + param y Int16 in value + category VERSION_2_0 + version 2.0 + deprecated 3.1 + vectorequiv VertexAttrib2sv + extension soft WINSOFT NV10 + glxflags ignore + offset 613 + +VertexAttrib2sv(index, v) + return void + param index UInt32 in value + param v Int16 in array [2] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxropcode 4190 + offset 614 + +VertexAttrib3d(index, x, y, z) + return void + param index UInt32 in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + category VERSION_2_0 + version 2.0 + deprecated 3.1 + vectorequiv VertexAttrib3dv + extension soft WINSOFT NV10 + glxflags ignore + offset 615 + +VertexAttrib3dv(index, v) + return void + param index UInt32 in value + param v Float64 in array [3] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxropcode 4199 + offset 616 + +VertexAttrib3f(index, x, y, z) + return void + param index UInt32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category VERSION_2_0 + version 2.0 + deprecated 3.1 + vectorequiv VertexAttrib3fv + extension soft WINSOFT NV10 + glxflags ignore + offset 617 + +VertexAttrib3fv(index, v) + return void + param index UInt32 in value + param v Float32 in array [3] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxropcode 4195 + offset 618 + +VertexAttrib3s(index, x, y, z) + return void + param index UInt32 in value + param x Int16 in value + param y Int16 in value + param z Int16 in value + category VERSION_2_0 + version 2.0 + deprecated 3.1 + vectorequiv VertexAttrib3sv + extension soft WINSOFT NV10 + glxflags ignore + offset 619 + +VertexAttrib3sv(index, v) + return void + param index UInt32 in value + param v Int16 in array [3] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxropcode 4191 + offset 620 + +VertexAttrib4Nbv(index, v) + return void + param index UInt32 in value + param v Int8 in array [4] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxflags ignore + offset 659 + +VertexAttrib4Niv(index, v) + return void + param index UInt32 in value + param v Int32 in array [4] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxflags ignore + offset 661 + +VertexAttrib4Nsv(index, v) + return void + param index UInt32 in value + param v Int16 in array [4] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxflags ignore + offset 660 + +VertexAttrib4Nub(index, x, y, z, w) + return void + param index UInt32 in value + param x UInt8 in value + param y UInt8 in value + param z UInt8 in value + param w UInt8 in value + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxflags ignore + offset 627 + +VertexAttrib4Nubv(index, v) + return void + param index UInt32 in value + param v UInt8 in array [4] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxflags ignore + glxropcode 4201 + offset 628 + +VertexAttrib4Nuiv(index, v) + return void + param index UInt32 in value + param v UInt32 in array [4] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxflags ignore + offset 663 + +VertexAttrib4Nusv(index, v) + return void + param index UInt32 in value + param v UInt16 in array [4] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxflags ignore + offset 662 + +VertexAttrib4bv(index, v) + return void + param index UInt32 in value + param v Int8 in array [4] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxflags ignore + offset 654 + +VertexAttrib4d(index, x, y, z, w) + return void + param index UInt32 in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + param w Float64 in value + category VERSION_2_0 + version 2.0 + deprecated 3.1 + vectorequiv VertexAttrib4dv + extension soft WINSOFT NV10 + glxflags ignore + offset 621 + +VertexAttrib4dv(index, v) + return void + param index UInt32 in value + param v Float64 in array [4] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxropcode 4200 + offset 622 + +VertexAttrib4f(index, x, y, z, w) + return void + param index UInt32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + param w Float32 in value + category VERSION_2_0 + version 2.0 + deprecated 3.1 + vectorequiv VertexAttrib4fv + extension soft WINSOFT NV10 + glxflags ignore + offset 623 + +VertexAttrib4fv(index, v) + return void + param index UInt32 in value + param v Float32 in array [4] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxropcode 4196 + offset 624 + +VertexAttrib4iv(index, v) + return void + param index UInt32 in value + param v Int32 in array [4] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxflags ignore + offset 655 + +VertexAttrib4s(index, x, y, z, w) + return void + param index UInt32 in value + param x Int16 in value + param y Int16 in value + param z Int16 in value + param w Int16 in value + category VERSION_2_0 + version 2.0 + deprecated 3.1 + vectorequiv VertexAttrib4sv + extension soft WINSOFT NV10 + glxflags ignore + offset 625 + +VertexAttrib4sv(index, v) + return void + param index UInt32 in value + param v Int16 in array [4] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxflags ignore + glxropcode 4192 + offset 626 + +VertexAttrib4ubv(index, v) + return void + param index UInt32 in value + param v UInt8 in array [4] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxflags ignore + offset 656 + +VertexAttrib4uiv(index, v) + return void + param index UInt32 in value + param v UInt32 in array [4] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxflags ignore + offset 658 + +VertexAttrib4usv(index, v) + return void + param index UInt32 in value + param v UInt16 in array [4] + category VERSION_2_0 + version 2.0 + deprecated 3.1 + extension soft WINSOFT NV10 + glxflags ignore + offset 657 + +VertexAttribPointer(index, size, type, normalized, stride, pointer) + return void + param index UInt32 in value + param size Int32 in value + param type VertexAttribPointerTypeARB in value + param normalized Boolean in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(size/type/stride)] retained + dlflags notlistable + category VERSION_2_0 + version 2.0 + extension soft WINSOFT NV10 + glxflags ignore + offset 664 + + +############################################################################### +############################################################################### +# +# OpenGL 2.1 commands +# +############################################################################### +############################################################################### + +# OpenGL 2.1 (ARB_pixel_buffer_object) commands - none + +# OpenGL 2.1 (EXT_texture_sRGB) commands - none + +# New commands in OpenGL 2.1 + +UniformMatrix2x3fv(location, count, transpose, value) + return void + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [6] + category VERSION_2_1 + version 2.1 + extension + glxropcode ? + glxflags ignore + offset ? + +UniformMatrix3x2fv(location, count, transpose, value) + return void + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [6] + category VERSION_2_1 + version 2.1 + extension + glxropcode ? + glxflags ignore + offset ? + +UniformMatrix2x4fv(location, count, transpose, value) + return void + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [8] + category VERSION_2_1 + version 2.1 + extension + glxropcode ? + glxflags ignore + offset ? + +UniformMatrix4x2fv(location, count, transpose, value) + return void + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [8] + category VERSION_2_1 + version 2.1 + extension + glxropcode ? + glxflags ignore + offset ? + +UniformMatrix3x4fv(location, count, transpose, value) + return void + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [12] + category VERSION_2_1 + version 2.1 + extension + glxropcode ? + glxflags ignore + offset ? + +UniformMatrix4x3fv(location, count, transpose, value) + return void + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [12] + category VERSION_2_1 + version 2.1 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +############################################################################### +# +# OpenGL 3.0 commands +# +############################################################################### +############################################################################### + +# OpenGL 3.0 (EXT_draw_buffers2) commands + +ColorMaski(index, r, g, b, a) + return void + param index UInt32 in value + param r Boolean in value + param g Boolean in value + param b Boolean in value + param a Boolean in value + category VERSION_3_0 + version 3.0 + extension + glxflags ignore + glfflags ignore + +GetBooleani_v(target, index, data) + return void + param target GLenum in value + param index UInt32 in value + param data Boolean out array [COMPSIZE(target)] + category VERSION_3_0 + version 3.0 + extension + dlflags notlistable + glxflags ignore + glfflags ignore + +GetIntegeri_v(target, index, data) + return void + param target GLenum in value + param index UInt32 in value + param data Int32 out array [COMPSIZE(target)] + category VERSION_3_0 + version 3.0 + extension + dlflags notlistable + glxflags ignore + glfflags ignore + +Enablei(target, index) + return void + param target GLenum in value + param index UInt32 in value + category VERSION_3_0 + version 3.0 + extension + glxflags ignore + glfflags ignore + +Disablei(target, index) + return void + param target GLenum in value + param index UInt32 in value + category VERSION_3_0 + version 3.0 + extension + glxflags ignore + glfflags ignore + +IsEnabledi(target, index) + return Boolean + param target GLenum in value + param index UInt32 in value + category VERSION_3_0 + version 3.0 + extension + dlflags notlistable + glxflags ignore + glfflags ignore + +# OpenGL 3.0 (EXT_transform_feedback) commands + +BeginTransformFeedback(primitiveMode) + return void + param primitiveMode GLenum in value + category VERSION_3_0 + version 3.0 + extension + dlflags notlistable + glxflags ignore + glfflags ignore + +EndTransformFeedback() + return void + category VERSION_3_0 + version 3.0 + extension + dlflags notlistable + glxflags ignore + glfflags ignore + +BindBufferRange(target, index, buffer, offset, size) + return void + param target GLenum in value + param index UInt32 in value + param buffer UInt32 in value + param offset BufferOffset in value + param size BufferSize in value + category VERSION_3_0 + version 3.0 + extension + dlflags notlistable + glxflags ignore + glfflags ignore + +BindBufferBase(target, index, buffer) + return void + param target GLenum in value + param index UInt32 in value + param buffer UInt32 in value + category VERSION_3_0 + version 3.0 + extension + dlflags notlistable + glxflags ignore + glfflags ignore + +TransformFeedbackVaryings(program, count, varyings, bufferMode) + return void + param program UInt32 in value + param count SizeI in value + param varyings CharPointer in array [count] + param bufferMode GLenum in value + category VERSION_3_0 + version 3.0 + extension + dlflags notlistable + glxflags ignore + glfflags ignore + +GetTransformFeedbackVarying(program, index, bufSize, length, size, type, name) + return void + param program UInt32 in value + param index UInt32 in value + param bufSize SizeI in value + param length SizeI out array [1] + param size SizeI out array [1] + param type GLenum out array [1] + param name Char out array [COMPSIZE(length)] + category VERSION_3_0 + dlflags notlistable + version 3.0 + extension + glfflags ignore + glxflags ignore + +ClampColor(target, clamp) + return void + param target ClampColorTargetARB in value + param clamp ClampColorModeARB in value + category VERSION_3_0 + version 3.0 + extension + glxropcode 234 + glxflags ignore + offset ? + +BeginConditionalRender(id, mode) + return void + param id UInt32 in value + param mode TypeEnum in value + category VERSION_3_0 + version 3.0 + glfflags ignore + glxflags ignore + +EndConditionalRender() + return void + category VERSION_3_0 + version 3.0 + glfflags ignore + glxflags ignore + +VertexAttribIPointer(index, size, type, stride, pointer) + return void + param index UInt32 in value + param size Int32 in value + param type VertexAttribEnum in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(size/type/stride)] retained + category VERSION_3_0 + version 3.0 + dlflags notlistable + extension + glfflags ignore + glxflags ignore + +GetVertexAttribIiv(index, pname, params) + return void + param index UInt32 in value + param pname VertexAttribEnum in value + param params Int32 out array [1] + category VERSION_3_0 + version 3.0 + dlflags notlistable + extension + glfflags ignore + glxflags ignore + +GetVertexAttribIuiv(index, pname, params) + return void + param index UInt32 in value + param pname VertexAttribEnum in value + param params UInt32 out array [1] + category VERSION_3_0 + version 3.0 + dlflags notlistable + extension + glfflags ignore + glxflags ignore + +# OpenGL 3.0 (NV_vertex_program4) commands + +VertexAttribI1i(index, x) + return void + param index UInt32 in value + param x Int32 in value + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + vectorequiv VertexAttribI1iv + glxvectorequiv VertexAttribI1iv + extension + glfflags ignore + glxflags ignore + +VertexAttribI2i(index, x, y) + return void + param index UInt32 in value + param x Int32 in value + param y Int32 in value + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + vectorequiv VertexAttribI2iv + glxvectorequiv VertexAttribI2iv + extension + glfflags ignore + glxflags ignore + +VertexAttribI3i(index, x, y, z) + return void + param index UInt32 in value + param x Int32 in value + param y Int32 in value + param z Int32 in value + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + vectorequiv VertexAttribI3iv + glxvectorequiv VertexAttribI3iv + extension + glfflags ignore + glxflags ignore + +VertexAttribI4i(index, x, y, z, w) + return void + param index UInt32 in value + param x Int32 in value + param y Int32 in value + param z Int32 in value + param w Int32 in value + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + vectorequiv VertexAttribI4iv + glxvectorequiv VertexAttribI4iv + extension + glfflags ignore + glxflags ignore + +VertexAttribI1ui(index, x) + return void + param index UInt32 in value + param x UInt32 in value + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + vectorequiv VertexAttribI1uiv + glxvectorequiv VertexAttribI1uiv + extension + glfflags ignore + glxflags ignore + +VertexAttribI2ui(index, x, y) + return void + param index UInt32 in value + param x UInt32 in value + param y UInt32 in value + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + vectorequiv VertexAttribI2uiv + glxvectorequiv VertexAttribI2uiv + extension + glfflags ignore + glxflags ignore + +VertexAttribI3ui(index, x, y, z) + return void + param index UInt32 in value + param x UInt32 in value + param y UInt32 in value + param z UInt32 in value + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + vectorequiv VertexAttribI3uiv + glxvectorequiv VertexAttribI3uiv + extension + glfflags ignore + glxflags ignore + +VertexAttribI4ui(index, x, y, z, w) + return void + param index UInt32 in value + param x UInt32 in value + param y UInt32 in value + param z UInt32 in value + param w UInt32 in value + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + vectorequiv VertexAttribI4uiv + glxvectorequiv VertexAttribI4uiv + extension + glfflags ignore + glxflags ignore + +VertexAttribI1iv(index, v) + return void + param index UInt32 in value + param v Int32 in array [1] + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + extension + glfflags ignore + glxflags ignore + +VertexAttribI2iv(index, v) + return void + param index UInt32 in value + param v Int32 in array [2] + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + extension + glfflags ignore + glxflags ignore + +VertexAttribI3iv(index, v) + return void + param index UInt32 in value + param v Int32 in array [3] + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + extension + glfflags ignore + glxflags ignore + +VertexAttribI4iv(index, v) + return void + param index UInt32 in value + param v Int32 in array [4] + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + extension + glfflags ignore + glxflags ignore + +VertexAttribI1uiv(index, v) + return void + param index UInt32 in value + param v UInt32 in array [1] + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + extension + glfflags ignore + glxflags ignore + +VertexAttribI2uiv(index, v) + return void + param index UInt32 in value + param v UInt32 in array [2] + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + extension + glfflags ignore + glxflags ignore + +VertexAttribI3uiv(index, v) + return void + param index UInt32 in value + param v UInt32 in array [3] + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + extension + glfflags ignore + glxflags ignore + +VertexAttribI4uiv(index, v) + return void + param index UInt32 in value + param v UInt32 in array [4] + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + extension + glfflags ignore + glxflags ignore + +VertexAttribI4bv(index, v) + return void + param index UInt32 in value + param v Int8 in array [4] + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + extension + glfflags ignore + glxflags ignore + +VertexAttribI4sv(index, v) + return void + param index UInt32 in value + param v Int16 in array [4] + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + extension + glfflags ignore + glxflags ignore + +VertexAttribI4ubv(index, v) + return void + param index UInt32 in value + param v UInt8 in array [4] + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + extension + glfflags ignore + glxflags ignore + +VertexAttribI4usv(index, v) + return void + param index UInt32 in value + param v UInt16 in array [4] + category VERSION_3_0 + version 3.0 + deprecated 3.1 + beginend allow-inside + extension + glfflags ignore + glxflags ignore + +# OpenGL 3.0 (EXT_gpu_shader4) commands + +GetUniformuiv(program, location, params) + return void + param program UInt32 in value + param location Int32 in value + param params UInt32 out array [COMPSIZE(program/location)] + category VERSION_3_0 + dlflags notlistable + version 3.0 + extension + glfflags ignore + glxflags ignore + +BindFragDataLocation(program, color, name) + return void + param program UInt32 in value + param color UInt32 in value + param name Char in array [COMPSIZE(name)] + category VERSION_3_0 + dlflags notlistable + version 3.0 + extension + glfflags ignore + glxflags ignore + +GetFragDataLocation(program, name) + return Int32 + param program UInt32 in value + param name Char in array [COMPSIZE(name)] + category VERSION_3_0 + dlflags notlistable + version 3.0 + extension + glfflags ignore + glxflags ignore + +Uniform1ui(location, v0) + return void + param location Int32 in value + param v0 UInt32 in value + category VERSION_3_0 + version 3.0 + extension + glfflags ignore + glxflags ignore + +Uniform2ui(location, v0, v1) + return void + param location Int32 in value + param v0 UInt32 in value + param v1 UInt32 in value + category VERSION_3_0 + version 3.0 + extension + glfflags ignore + glxflags ignore + +Uniform3ui(location, v0, v1, v2) + return void + param location Int32 in value + param v0 UInt32 in value + param v1 UInt32 in value + param v2 UInt32 in value + category VERSION_3_0 + version 3.0 + extension + glfflags ignore + glxflags ignore + +Uniform4ui(location, v0, v1, v2, v3) + return void + param location Int32 in value + param v0 UInt32 in value + param v1 UInt32 in value + param v2 UInt32 in value + param v3 UInt32 in value + category VERSION_3_0 + version 3.0 + extension + glfflags ignore + glxflags ignore + +Uniform1uiv(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value UInt32 in array [count] + category VERSION_3_0 + version 3.0 + extension + glfflags ignore + glxflags ignore + +Uniform2uiv(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value UInt32 in array [count*2] + category VERSION_3_0 + version 3.0 + extension + glfflags ignore + glxflags ignore + +Uniform3uiv(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value UInt32 in array [count*3] + category VERSION_3_0 + version 3.0 + extension + glfflags ignore + glxflags ignore + +Uniform4uiv(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value UInt32 in array [count*4] + category VERSION_3_0 + version 3.0 + extension + glfflags ignore + glxflags ignore + +# OpenGL 3.0 (EXT_texture_integer) commands + +TexParameterIiv(target, pname, params) + return void + param target TextureTarget in value + param pname TextureParameterName in value + param params Int32 in array [COMPSIZE(pname)] + category VERSION_3_0 + version 3.0 + extension + glfflags ignore + glxflags ignore + +TexParameterIuiv(target, pname, params) + return void + param target TextureTarget in value + param pname TextureParameterName in value + param params UInt32 in array [COMPSIZE(pname)] + category VERSION_3_0 + version 3.0 + extension + glfflags ignore + glxflags ignore + +GetTexParameterIiv(target, pname, params) + return void + param target TextureTarget in value + param pname GetTextureParameter in value + param params Int32 out array [COMPSIZE(pname)] + category VERSION_3_0 + dlflags notlistable + version 3.0 + extension + glfflags ignore + glxflags ignore + +GetTexParameterIuiv(target, pname, params) + return void + param target TextureTarget in value + param pname GetTextureParameter in value + param params UInt32 out array [COMPSIZE(pname)] + category VERSION_3_0 + dlflags notlistable + version 3.0 + extension + glfflags ignore + glxflags ignore + +# New commands in OpenGL 3.0 + +ClearBufferiv(buffer, drawbuffer, value) + return void + param buffer GLenum in value + param drawbuffer DrawBufferName in value + param value Int32 in array [COMPSIZE(buffer)] + category VERSION_3_0 + version 3.0 + extension + glfflags ignore + glxflags ignore + +ClearBufferuiv(buffer, drawbuffer, value) + return void + param buffer GLenum in value + param drawbuffer DrawBufferName in value + param value UInt32 in array [COMPSIZE(buffer)] + category VERSION_3_0 + version 3.0 + extension + glfflags ignore + glxflags ignore + +ClearBufferfv(buffer, drawbuffer, value) + return void + param buffer GLenum in value + param drawbuffer DrawBufferName in value + param value Float32 in array [COMPSIZE(buffer)] + category VERSION_3_0 + version 3.0 + extension + glfflags ignore + glxflags ignore + +ClearBufferfi(buffer, drawbuffer, depth, stencil) + return void + param buffer GLenum in value + param drawbuffer DrawBufferName in value + param depth Float32 in value + param stencil Int32 in value + category VERSION_3_0 + version 3.0 + extension + glfflags ignore + glxflags ignore + +GetStringi(name, index) + return String + param name GLenum in value + param index UInt32 in value + category VERSION_3_0 + version 3.0 + extension + dlflags notlistable + glxflags client-handcode server-handcode + glfflags ignore + glxsingle ? + +passthru: /* OpenGL 3.0 also reuses entry points from these extensions: */ +passthru: /* ARB_framebuffer_object */ +passthru: /* ARB_map_buffer_range */ +passthru: /* ARB_vertex_array_object */ + +############################################################################### +############################################################################### +# +# OpenGL 3.0 deprecated commands +# +############################################################################### +############################################################################### + +# (none - VertexAttribI* were moved back into non-deprecated) + + +############################################################################### +############################################################################### +# +# OpenGL 3.1 commands +# +############################################################################### +############################################################################### + +# New commands in OpenGL 3.1 - none + +# OpenGL 3.1 (ARB_draw_instanced) commands + +DrawArraysInstanced(mode, first, count, primcount) + return void + param mode BeginMode in value + param first Int32 in value + param count SizeI in value + param primcount SizeI in value + category VERSION_3_1 + version 3.1 + extension + dlflags notlistable + vectorequiv ArrayElement + glfflags ignore + glxflags ignore + +DrawElementsInstanced(mode, count, type, indices, primcount) + return void + param mode BeginMode in value + param count SizeI in value + param type DrawElementsType in value + param indices Void in array [COMPSIZE(count/type)] + param primcount SizeI in value + category VERSION_3_1 + version 3.1 + extension + dlflags notlistable + vectorequiv ArrayElement + glfflags ignore + glxflags ignore + +# OpenGL 3.1 (ARB_texture_buffer_object) commands + +TexBuffer(target, internalformat, buffer) + return void + param target TextureTarget in value + param internalformat GLenum in value + param buffer UInt32 in value + category VERSION_3_1 + version 3.1 + extension + glfflags ignore + glxflags ignore + +# OpenGL 3.1 (ARB_texture_rectangle) commands - none + +# OpenGL 3.1 (SNORM texture) commands - none + +# OpenGL 3.1 (NV_primitive_restart) commands +# This is *not* an alias of PrimitiveRestartIndexNV, since it sets +# server instead of client state. + +PrimitiveRestartIndex(index) + return void + param index UInt32 in value + category VERSION_3_1 + version 3.1 + extension + glxropcode ? + glxflags ignore + offset ? + +passthru: /* OpenGL 3.1 also reuses entry points from these extensions: */ +passthru: /* ARB_copy_buffer */ +passthru: /* ARB_uniform_buffer_object */ + + +############################################################################### +############################################################################### +# +# OpenGL 3.2 commands +# +############################################################################### +############################################################################### + +# New commands in OpenGL 3.2 + +GetInteger64i_v(target, index, data) + return void + param target GLenum in value + param index UInt32 in value + param data Int64 out array [COMPSIZE(target)] + category VERSION_3_2 + version 3.2 + extension + dlflags notlistable + glxflags ignore + glfflags ignore + + +GetBufferParameteri64v(target, pname, params) + return void + param target BufferTargetARB in value + param pname BufferPNameARB in value + param params Int64 out array [COMPSIZE(pname)] + category VERSION_3_2 + dlflags notlistable + version 3.2 + extension + glxsingle ? + glxflags ignore + +# OpenGL 3.2 (ARB_depth_clamp) commands - none +# OpenGL 3.2 (ARB_fragment_coord_conventions) commands - none + +# OpenGL 3.2 (ARB_geometry_shader4) commands + +ProgramParameteri(program, pname, value) + return void + param program UInt32 in value + param pname GLenum in value + param value Int32 in value + category VERSION_3_2 + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +FramebufferTexture(target, attachment, texture, level) + return void + param target GLenum in value + param attachment GLenum in value + param texture UInt32 in value + param level Int32 in value + category VERSION_3_2 + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +# FramebufferTextureLayer redeclared in ARB_framebuffer_object +# FramebufferTextureLayer(target, attachment, texture, level, layer) +# return void +# param target GLenum in value +# param attachment GLenum in value +# param texture UInt32 in value +# param level Int32 in value +# param layer Int32 in value +# category VERSION_3_2 +# version 1.2 +# extension +# glxropcode ? +# glxflags ignore +# offset ? + +FramebufferTextureFace(target, attachment, texture, level, face) + return void + param target GLenum in value + param attachment GLenum in value + param texture UInt32 in value + param level Int32 in value + param face GLenum in value + category VERSION_3_2 + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +# OpenGL 3.2 (ARB_seamless_cube_map) commands - none +# OpenGL 3.2 (ARB_vertex_array_bgra) commands - none + +passthru: /* OpenGL 3.2 also reuses entry points from these extensions: */ +passthru: /* ARB_draw_elements_base_vertex */ +passthru: /* ARB_provoking_vertex */ +passthru: /* ARB_sync */ +passthru: /* ARB_texture_multisample */ + + +############################################################################### +############################################################################### +# +# ARB extensions, in order by ARB extension number +# +############################################################################### +############################################################################### + +############################################################################### +# +# ARB Extension #1 +# ARB_multitexture commands +# +############################################################################### + +ActiveTextureARB(texture) + return void + param texture TextureUnit in value + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 197 + alias ActiveTexture + +ClientActiveTextureARB(texture) + return void + param texture TextureUnit in value + category ARB_multitexture + dlflags notlistable + glxflags ARB client-handcode client-intercept server-handcode + version 1.2 + alias ClientActiveTexture + +MultiTexCoord1dARB(target, s) + return void + param target TextureUnit in value + param s CoordD in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord1dv + +MultiTexCoord1dvARB(target, v) + return void + param target TextureUnit in value + param v CoordD in array [1] + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 198 + alias MultiTexCoord1dv + +MultiTexCoord1fARB(target, s) + return void + param target TextureUnit in value + param s CoordF in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord1fv + +MultiTexCoord1fvARB(target, v) + return void + param target TextureUnit in value + param v CoordF in array [1] + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 199 + alias MultiTexCoord1fv + +MultiTexCoord1iARB(target, s) + return void + param target TextureUnit in value + param s CoordI in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord1iv + +MultiTexCoord1ivARB(target, v) + return void + param target TextureUnit in value + param v CoordI in array [1] + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 200 + alias MultiTexCoord1iv + +MultiTexCoord1sARB(target, s) + return void + param target TextureUnit in value + param s CoordS in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord1sv + +MultiTexCoord1svARB(target, v) + return void + param target TextureUnit in value + param v CoordS in array [1] + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 201 + alias MultiTexCoord1sv + +MultiTexCoord2dARB(target, s, t) + return void + param target TextureUnit in value + param s CoordD in value + param t CoordD in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord2dv + +MultiTexCoord2dvARB(target, v) + return void + param target TextureUnit in value + param v CoordD in array [2] + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 202 + alias MultiTexCoord2dv + +MultiTexCoord2fARB(target, s, t) + return void + param target TextureUnit in value + param s CoordF in value + param t CoordF in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord2fv + +MultiTexCoord2fvARB(target, v) + return void + param target TextureUnit in value + param v CoordF in array [2] + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 203 + alias MultiTexCoord2fv + +MultiTexCoord2iARB(target, s, t) + return void + param target TextureUnit in value + param s CoordI in value + param t CoordI in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord2iv + +MultiTexCoord2ivARB(target, v) + return void + param target TextureUnit in value + param v CoordI in array [2] + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 204 + alias MultiTexCoord2iv + +MultiTexCoord2sARB(target, s, t) + return void + param target TextureUnit in value + param s CoordS in value + param t CoordS in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord2sv + +MultiTexCoord2svARB(target, v) + return void + param target TextureUnit in value + param v CoordS in array [2] + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 205 + alias MultiTexCoord2sv + +MultiTexCoord3dARB(target, s, t, r) + return void + param target TextureUnit in value + param s CoordD in value + param t CoordD in value + param r CoordD in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord3dv + +MultiTexCoord3dvARB(target, v) + return void + param target TextureUnit in value + param v CoordD in array [3] + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 206 + alias MultiTexCoord3dv + +MultiTexCoord3fARB(target, s, t, r) + return void + param target TextureUnit in value + param s CoordF in value + param t CoordF in value + param r CoordF in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord3fv + +MultiTexCoord3fvARB(target, v) + return void + param target TextureUnit in value + param v CoordF in array [3] + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 207 + alias MultiTexCoord3fv + +MultiTexCoord3iARB(target, s, t, r) + return void + param target TextureUnit in value + param s CoordI in value + param t CoordI in value + param r CoordI in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord3iv + +MultiTexCoord3ivARB(target, v) + return void + param target TextureUnit in value + param v CoordI in array [3] + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 208 + alias MultiTexCoord3iv + +MultiTexCoord3sARB(target, s, t, r) + return void + param target TextureUnit in value + param s CoordS in value + param t CoordS in value + param r CoordS in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord3sv + +MultiTexCoord3svARB(target, v) + return void + param target TextureUnit in value + param v CoordS in array [3] + category ARB_multitexture + version 1.2 + glxflags ARB + glxropcode 209 + alias MultiTexCoord3sv + +MultiTexCoord4dARB(target, s, t, r, q) + return void + param target TextureUnit in value + param s CoordD in value + param t CoordD in value + param r CoordD in value + param q CoordD in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord4dv + +MultiTexCoord4dvARB(target, v) + return void + param target TextureUnit in value + param v CoordD in array [4] + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 210 + alias MultiTexCoord4dv + +MultiTexCoord4fARB(target, s, t, r, q) + return void + param target TextureUnit in value + param s CoordF in value + param t CoordF in value + param r CoordF in value + param q CoordF in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord4fv + +MultiTexCoord4fvARB(target, v) + return void + param target TextureUnit in value + param v CoordF in array [4] + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 211 + alias MultiTexCoord4fv + +MultiTexCoord4iARB(target, s, t, r, q) + return void + param target TextureUnit in value + param s CoordI in value + param t CoordI in value + param r CoordI in value + param q CoordI in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord4iv + +MultiTexCoord4ivARB(target, v) + return void + param target TextureUnit in value + param v CoordI in array [4] + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 212 + alias MultiTexCoord4iv + +MultiTexCoord4sARB(target, s, t, r, q) + return void + param target TextureUnit in value + param s CoordS in value + param t CoordS in value + param r CoordS in value + param q CoordS in value + category ARB_multitexture + glxflags ARB + version 1.2 + vectorequiv MultiTexCoord4sv + +MultiTexCoord4svARB(target, v) + return void + param target TextureUnit in value + param v CoordS in array [4] + category ARB_multitexture + glxflags ARB + version 1.2 + glxropcode 213 + alias MultiTexCoord4sv + +################################################################################ +# +# ARB Extension #2 - GLX_ARB_get_proc_address +# +############################################################################### + +################################################################################ +# +# ARB Extension #3 +# ARB_transpose_matrix commands +# +############################################################################### + +LoadTransposeMatrixfARB(m) + return void + param m Float32 in array [16] + category ARB_transpose_matrix + glxflags ARB client-handcode client-intercept server-handcode + version 1.2 + alias LoadTransposeMatrixf + +LoadTransposeMatrixdARB(m) + return void + param m Float64 in array [16] + category ARB_transpose_matrix + glxflags ARB client-handcode client-intercept server-handcode + version 1.2 + alias LoadTransposeMatrixd + +MultTransposeMatrixfARB(m) + return void + param m Float32 in array [16] + category ARB_transpose_matrix + glxflags ARB client-handcode client-intercept server-handcode + version 1.2 + alias MultTransposeMatrixf + +MultTransposeMatrixdARB(m) + return void + param m Float64 in array [16] + category ARB_transpose_matrix + glxflags ARB client-handcode client-intercept server-handcode + version 1.2 + alias MultTransposeMatrixd + +################################################################################ +# +# ARB Extension #4 - WGL_ARB_buffer_region +# +############################################################################### + +################################################################################ +# +# ARB Extension #5 +# ARB_multisample commands +# +############################################################################### + +SampleCoverageARB(value, invert) + return void + param value ClampedFloat32 in value + param invert Boolean in value + category ARB_multisample + glxflags ARB + version 1.2 + alias SampleCoverage + +################################################################################ +# +# ARB Extension #6 +# ARB_texture_env_add commands +# +############################################################################### + +# (none) +newcategory: ARB_texture_env_add + +################################################################################ +# +# ARB Extension #7 +# ARB_texture_cube_map commands +# +############################################################################### + +# (none) +newcategory: ARB_texture_cube_map + +################################################################################ +# +# ARB Extension #8 - WGL_ARB_extensions_string +# ARB Extension #9 - WGL_ARB_pixel_format commands +# ARB Extension #10 - WGL_ARB_make_current_read commands +# ARB Extension #11 - WGL_ARB_pbuffer +# +############################################################################### + +################################################################################ +# +# ARB Extension #12 +# ARB_texture_compression commands +# +############################################################################### + +# Arguably TexelInternalFormat, not PixelInternalFormat +CompressedTexImage3DARB(target, level, internalformat, width, height, depth, border, imageSize, data) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param border CheckedInt32 in value + param imageSize SizeI in value + param data CompressedTextureARB in array [imageSize] + category ARB_texture_compression + dlflags handcode + glxflags ARB client-handcode server-handcode + version 1.2 + glxropcode 216 + alias CompressedTexImage3D + wglflags client-handcode server-handcode + +# Arguably TexelInternalFormat, not PixelInternalFormat +CompressedTexImage2DARB(target, level, internalformat, width, height, border, imageSize, data) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param height SizeI in value + param border CheckedInt32 in value + param imageSize SizeI in value + param data CompressedTextureARB in array [imageSize] + category ARB_texture_compression + dlflags handcode + glxflags ARB client-handcode server-handcode + version 1.2 + glxropcode 215 + alias CompressedTexImage2D + wglflags client-handcode server-handcode + +# Arguably TexelInternalFormat, not PixelInternalFormat +CompressedTexImage1DARB(target, level, internalformat, width, border, imageSize, data) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param border CheckedInt32 in value + param imageSize SizeI in value + param data CompressedTextureARB in array [imageSize] + category ARB_texture_compression + dlflags handcode + glxflags ARB client-handcode server-handcode + version 1.2 + glxropcode 214 + alias CompressedTexImage1D + wglflags client-handcode server-handcode + +CompressedTexSubImage3DARB(target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param zoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param format PixelFormat in value + param imageSize SizeI in value + param data CompressedTextureARB in array [imageSize] + category ARB_texture_compression + dlflags handcode + glxflags ARB client-handcode server-handcode + version 1.2 + glxropcode 219 + alias CompressedTexSubImage3D + wglflags client-handcode server-handcode + +CompressedTexSubImage2DARB(target, level, xoffset, yoffset, width, height, format, imageSize, data) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param format PixelFormat in value + param imageSize SizeI in value + param data CompressedTextureARB in array [imageSize] + category ARB_texture_compression + dlflags handcode + glxflags ARB client-handcode server-handcode + version 1.2 + glxropcode 218 + alias CompressedTexSubImage2D + wglflags client-handcode server-handcode + +CompressedTexSubImage1DARB(target, level, xoffset, width, format, imageSize, data) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param width SizeI in value + param format PixelFormat in value + param imageSize SizeI in value + param data CompressedTextureARB in array [imageSize] + category ARB_texture_compression + dlflags handcode + glxflags ARB client-handcode server-handcode + version 1.2 + glxropcode 217 + alias CompressedTexSubImage1D + wglflags client-handcode server-handcode + +GetCompressedTexImageARB(target, level, img) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param img CompressedTextureARB out array [COMPSIZE(target/level)] + category ARB_texture_compression + dlflags notlistable + glxflags ARB client-handcode server-handcode + version 1.2 + glxsingle 160 + alias GetCompressedTexImage + wglflags client-handcode server-handcode + +################################################################################ +# +# ARB Extension #13 +# ARB_texture_border_clamp commands +# +############################################################################### + +# (none) +newcategory: ARB_texture_border_clamp + +############################################################################### +# +# ARB Extension #14 +# ARB_point_parameters commands +# +############################################################################### + +PointParameterfARB(pname, param) + return void + param pname PointParameterNameARB in value + param param CheckedFloat32 in value + category ARB_point_parameters + version 1.0 + glxflags ARB + glxropcode 2065 + extension + alias PointParameterf + +PointParameterfvARB(pname, params) + return void + param pname PointParameterNameARB in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category ARB_point_parameters + version 1.0 + glxflags ARB + glxropcode 2066 + extension + alias PointParameterfv + +################################################################################ +# +# ARB Extension #15 +# ARB_vertex_blend commands +# +############################################################################### + +WeightbvARB(size, weights) + return void + param size Int32 in value + param weights Int8 in array [size] + category ARB_vertex_blend + version 1.1 + extension + glxropcode 220 + glxflags ignore + offset ? + +WeightsvARB(size, weights) + return void + param size Int32 in value + param weights Int16 in array [size] + category ARB_vertex_blend + version 1.1 + extension + glxropcode 222 + glxflags ignore + offset ? + +WeightivARB(size, weights) + return void + param size Int32 in value + param weights Int32 in array [size] + category ARB_vertex_blend + version 1.1 + extension + glxropcode 224 + glxflags ignore + offset ? + +WeightfvARB(size, weights) + return void + param size Int32 in value + param weights Float32 in array [size] + category ARB_vertex_blend + version 1.1 + extension + glxropcode 227 + glxflags ignore + offset ? + +WeightdvARB(size, weights) + return void + param size Int32 in value + param weights Float64 in array [size] + category ARB_vertex_blend + version 1.1 + extension + glxropcode 228 + glxflags ignore + offset ? + +WeightubvARB(size, weights) + return void + param size Int32 in value + param weights UInt8 in array [size] + category ARB_vertex_blend + version 1.1 + extension + glxropcode 221 + glxflags ignore + offset ? + +WeightusvARB(size, weights) + return void + param size Int32 in value + param weights UInt16 in array [size] + category ARB_vertex_blend + version 1.1 + extension + glxropcode 223 + glxflags ignore + offset ? + +WeightuivARB(size, weights) + return void + param size Int32 in value + param weights UInt32 in array [size] + category ARB_vertex_blend + version 1.1 + extension + glxropcode 225 + glxflags ignore + offset ? + +WeightPointerARB(size, type, stride, pointer) + return void + param size Int32 in value + param type WeightPointerTypeARB in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(type/stride)] retained + category ARB_vertex_blend + version 1.1 + extension + dlflags notlistable + glxflags ignore + offset ? + +VertexBlendARB(count) + return void + param count Int32 in value + category ARB_vertex_blend + version 1.1 + extension + glxropcode 226 + glxflags ignore + offset ? + +################################################################################ +# +# ARB Extension #16 +# ARB_matrix_palette commands +# +############################################################################### + +CurrentPaletteMatrixARB(index) + return void + param index Int32 in value + category ARB_matrix_palette + version 1.1 + extension + glxropcode 4329 + glxflags ignore + offset ? + +MatrixIndexubvARB(size, indices) + return void + param size Int32 in value + param indices UInt8 in array [size] + category ARB_matrix_palette + version 1.1 + extension + glxropcode 4326 + glxflags ignore + offset ? + +MatrixIndexusvARB(size, indices) + return void + param size Int32 in value + param indices UInt16 in array [size] + category ARB_matrix_palette + version 1.1 + extension + glxropcode 4327 + glxflags ignore + offset ? + +MatrixIndexuivARB(size, indices) + return void + param size Int32 in value + param indices UInt32 in array [size] + category ARB_matrix_palette + version 1.1 + extension + glxropcode 4328 + glxflags ignore + offset ? + +MatrixIndexPointerARB(size, type, stride, pointer) + return void + param size Int32 in value + param type MatrixIndexPointerTypeARB in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(type/stride)] retained + category ARB_matrix_palette + version 1.1 + extension + dlflags notlistable + glxflags ignore + offset ? + +################################################################################ +# +# ARB Extension #17 +# ARB_texture_env_combine commands +# +############################################################################### + +# (none) +newcategory: ARB_texture_env_combine + +################################################################################ +# +# ARB Extension #18 +# ARB_texture_env_crossbar commands +# +############################################################################### + +# (none) +newcategory: ARB_texture_env_crossbar + +################################################################################ +# +# ARB Extension #19 +# ARB_texture_env_dot3 commands +# +############################################################################### + +# (none) +newcategory: ARB_texture_env_dot3 + +############################################################################### +# +# ARB Extension #20 - WGL_ARB_render_texture +# +############################################################################### + +############################################################################### +# +# ARB Extension #21 +# ARB_texture_mirrored_repeat commands +# +############################################################################### + +# (none) +newcategory: ARB_texture_mirrored_repeat + +############################################################################### +# +# ARB Extension #22 +# ARB_depth_texture commands +# +############################################################################### + +# (none) +newcategory: ARB_depth_texture + +############################################################################### +# +# ARB Extension #23 +# ARB_shadow commands +# +############################################################################### + +# (none) +newcategory: ARB_shadow + +############################################################################### +# +# ARB Extension #24 +# ARB_shadow_ambient commands +# +############################################################################### + +# (none) +newcategory: ARB_shadow_ambient + +############################################################################### +# +# ARB Extension #25 +# ARB_window_pos commands +# Note: all entry points use glxropcode ropcode 230, with 3 float parameters +# +############################################################################### + +WindowPos2dARB(x, y) + return void + param x CoordD in value + param y CoordD in value + category ARB_window_pos + vectorequiv WindowPos2dvARB + version 1.0 + alias WindowPos2d + +WindowPos2dvARB(v) + return void + param v CoordD in array [2] + category ARB_window_pos + version 1.0 + glxropcode 230 + glxflags client-handcode server-handcode + alias WindowPos2dv + +WindowPos2fARB(x, y) + return void + param x CoordF in value + param y CoordF in value + category ARB_window_pos + vectorequiv WindowPos2fvARB + version 1.0 + alias WindowPos2f + +WindowPos2fvARB(v) + return void + param v CoordF in array [2] + category ARB_window_pos + version 1.0 + glxropcode 230 + glxflags client-handcode server-handcode + alias WindowPos2fv + +WindowPos2iARB(x, y) + return void + param x CoordI in value + param y CoordI in value + category ARB_window_pos + vectorequiv WindowPos2ivARB + version 1.0 + alias WindowPos2i + +WindowPos2ivARB(v) + return void + param v CoordI in array [2] + category ARB_window_pos + version 1.0 + glxropcode 230 + glxflags client-handcode server-handcode + alias WindowPos2iv + +WindowPos2sARB(x, y) + return void + param x CoordS in value + param y CoordS in value + category ARB_window_pos + vectorequiv WindowPos2svARB + version 1.0 + alias WindowPos2s + +WindowPos2svARB(v) + return void + param v CoordS in array [2] + category ARB_window_pos + version 1.0 + glxropcode 230 + glxflags client-handcode server-handcode + alias WindowPos2sv + +WindowPos3dARB(x, y, z) + return void + param x CoordD in value + param y CoordD in value + param z CoordD in value + vectorequiv WindowPos3dvARB + category ARB_window_pos + version 1.0 + alias WindowPos3d + +WindowPos3dvARB(v) + return void + param v CoordD in array [3] + category ARB_window_pos + version 1.0 + glxropcode 230 + glxflags client-handcode server-handcode + alias WindowPos3dv + +WindowPos3fARB(x, y, z) + return void + param x CoordF in value + param y CoordF in value + param z CoordF in value + category ARB_window_pos + vectorequiv WindowPos3fvARB + version 1.0 + alias WindowPos3f + +WindowPos3fvARB(v) + return void + param v CoordF in array [3] + category ARB_window_pos + version 1.0 + glxropcode 230 + glxflags client-handcode server-handcode + alias WindowPos3fv + +WindowPos3iARB(x, y, z) + return void + param x CoordI in value + param y CoordI in value + param z CoordI in value + category ARB_window_pos + vectorequiv WindowPos3ivARB + version 1.0 + alias WindowPos3i + +WindowPos3ivARB(v) + return void + param v CoordI in array [3] + category ARB_window_pos + version 1.0 + glxropcode 230 + glxflags client-handcode server-handcode + alias WindowPos3iv + +WindowPos3sARB(x, y, z) + return void + param x CoordS in value + param y CoordS in value + param z CoordS in value + category ARB_window_pos + vectorequiv WindowPos3svARB + version 1.0 + alias WindowPos3s + +WindowPos3svARB(v) + return void + param v CoordS in array [3] + category ARB_window_pos + version 1.0 + glxropcode 230 + glxflags client-handcode server-handcode + alias WindowPos3sv + +############################################################################### +# +# ARB Extension #26 +# ARB_vertex_program commands +# +############################################################################### + +VertexAttrib1dARB(index, x) + return void + param index UInt32 in value + param x Float64 in value + category ARB_vertex_program + version 1.3 + vectorequiv VertexAttrib1dvARB + extension soft WINSOFT NV10 + alias VertexAttrib1d + +VertexAttrib1dvARB(index, v) + return void + param index UInt32 in value + param v Float64 in array [1] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxropcode 4197 + alias VertexAttrib1dv + +VertexAttrib1fARB(index, x) + return void + param index UInt32 in value + param x Float32 in value + category ARB_vertex_program + version 1.3 + vectorequiv VertexAttrib1fvARB + extension soft WINSOFT NV10 + alias VertexAttrib1f + +VertexAttrib1fvARB(index, v) + return void + param index UInt32 in value + param v Float32 in array [1] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxropcode 4193 + alias VertexAttrib1fv + +VertexAttrib1sARB(index, x) + return void + param index UInt32 in value + param x Int16 in value + category ARB_vertex_program + version 1.3 + vectorequiv VertexAttrib1svARB + extension soft WINSOFT NV10 + alias VertexAttrib1s + +VertexAttrib1svARB(index, v) + return void + param index UInt32 in value + param v Int16 in array [1] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxropcode 4189 + alias VertexAttrib1sv + +VertexAttrib2dARB(index, x, y) + return void + param index UInt32 in value + param x Float64 in value + param y Float64 in value + category ARB_vertex_program + version 1.3 + vectorequiv VertexAttrib2dvARB + extension soft WINSOFT NV10 + alias VertexAttrib2d + +VertexAttrib2dvARB(index, v) + return void + param index UInt32 in value + param v Float64 in array [2] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxropcode 4198 + alias VertexAttrib2dv + +VertexAttrib2fARB(index, x, y) + return void + param index UInt32 in value + param x Float32 in value + param y Float32 in value + category ARB_vertex_program + version 1.3 + vectorequiv VertexAttrib2fvARB + extension soft WINSOFT NV10 + alias VertexAttrib2f + +VertexAttrib2fvARB(index, v) + return void + param index UInt32 in value + param v Float32 in array [2] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxropcode 4194 + alias VertexAttrib2fv + +VertexAttrib2sARB(index, x, y) + return void + param index UInt32 in value + param x Int16 in value + param y Int16 in value + category ARB_vertex_program + version 1.3 + vectorequiv VertexAttrib2svARB + extension soft WINSOFT NV10 + alias VertexAttrib2s + +VertexAttrib2svARB(index, v) + return void + param index UInt32 in value + param v Int16 in array [2] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxropcode 4190 + alias VertexAttrib2sv + +VertexAttrib3dARB(index, x, y, z) + return void + param index UInt32 in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + category ARB_vertex_program + version 1.3 + vectorequiv VertexAttrib3dvARB + extension soft WINSOFT NV10 + alias VertexAttrib3d + +VertexAttrib3dvARB(index, v) + return void + param index UInt32 in value + param v Float64 in array [3] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxropcode 4199 + alias VertexAttrib3dv + +VertexAttrib3fARB(index, x, y, z) + return void + param index UInt32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category ARB_vertex_program + version 1.3 + vectorequiv VertexAttrib3fvARB + extension soft WINSOFT NV10 + alias VertexAttrib3f + +VertexAttrib3fvARB(index, v) + return void + param index UInt32 in value + param v Float32 in array [3] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxropcode 4195 + alias VertexAttrib3fv + +VertexAttrib3sARB(index, x, y, z) + return void + param index UInt32 in value + param x Int16 in value + param y Int16 in value + param z Int16 in value + category ARB_vertex_program + version 1.3 + vectorequiv VertexAttrib3svARB + extension soft WINSOFT NV10 + alias VertexAttrib3s + +VertexAttrib3svARB(index, v) + return void + param index UInt32 in value + param v Int16 in array [3] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxropcode 4191 + alias VertexAttrib3sv + +VertexAttrib4NbvARB(index, v) + return void + param index UInt32 in value + param v Int8 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + alias VertexAttrib4Nbv + +VertexAttrib4NivARB(index, v) + return void + param index UInt32 in value + param v Int32 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + alias VertexAttrib4Niv + +VertexAttrib4NsvARB(index, v) + return void + param index UInt32 in value + param v Int16 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + alias VertexAttrib4Nsv + +VertexAttrib4NubARB(index, x, y, z, w) + return void + param index UInt32 in value + param x UInt8 in value + param y UInt8 in value + param z UInt8 in value + param w UInt8 in value + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + alias VertexAttrib4Nub + +VertexAttrib4NubvARB(index, v) + return void + param index UInt32 in value + param v UInt8 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxropcode 4201 + alias VertexAttrib4Nubv + +VertexAttrib4NuivARB(index, v) + return void + param index UInt32 in value + param v UInt32 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + alias VertexAttrib4Nuiv + +VertexAttrib4NusvARB(index, v) + return void + param index UInt32 in value + param v UInt16 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + alias VertexAttrib4Nusv + +VertexAttrib4bvARB(index, v) + return void + param index UInt32 in value + param v Int8 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + alias VertexAttrib4bv + +VertexAttrib4dARB(index, x, y, z, w) + return void + param index UInt32 in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + param w Float64 in value + category ARB_vertex_program + version 1.3 + vectorequiv VertexAttrib4dvARB + extension soft WINSOFT NV10 + alias VertexAttrib4d + +VertexAttrib4dvARB(index, v) + return void + param index UInt32 in value + param v Float64 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxropcode 4200 + alias VertexAttrib4dv + +VertexAttrib4fARB(index, x, y, z, w) + return void + param index UInt32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + param w Float32 in value + category ARB_vertex_program + version 1.3 + vectorequiv VertexAttrib4fvARB + extension soft WINSOFT NV10 + alias VertexAttrib4f + +VertexAttrib4fvARB(index, v) + return void + param index UInt32 in value + param v Float32 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxropcode 4196 + alias VertexAttrib4fv + +VertexAttrib4ivARB(index, v) + return void + param index UInt32 in value + param v Int32 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + alias VertexAttrib4iv + +VertexAttrib4sARB(index, x, y, z, w) + return void + param index UInt32 in value + param x Int16 in value + param y Int16 in value + param z Int16 in value + param w Int16 in value + category ARB_vertex_program + version 1.3 + vectorequiv VertexAttrib4svARB + extension soft WINSOFT NV10 + alias VertexAttrib4s + +VertexAttrib4svARB(index, v) + return void + param index UInt32 in value + param v Int16 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxropcode 4192 + alias VertexAttrib4sv + +VertexAttrib4ubvARB(index, v) + return void + param index UInt32 in value + param v UInt8 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + alias VertexAttrib4ubv + +VertexAttrib4uivARB(index, v) + return void + param index UInt32 in value + param v UInt32 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + alias VertexAttrib4uiv + +VertexAttrib4usvARB(index, v) + return void + param index UInt32 in value + param v UInt16 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + alias VertexAttrib4usv + +VertexAttribPointerARB(index, size, type, normalized, stride, pointer) + return void + param index UInt32 in value + param size Int32 in value + param type VertexAttribPointerTypeARB in value + param normalized Boolean in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(size/type/stride)] retained + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + alias VertexAttribPointer + +EnableVertexAttribArrayARB(index) + return void + param index UInt32 in value + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + alias EnableVertexAttribArray + +DisableVertexAttribArrayARB(index) + return void + param index UInt32 in value + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + alias DisableVertexAttribArray + +ProgramStringARB(target, format, len, string) + return void + param target ProgramTargetARB in value + param format ProgramFormatARB in value + param len SizeI in value + param string Void in array [len] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxflags ignore + offset 667 + +BindProgramARB(target, program) + return void + param target ProgramTargetARB in value + param program UInt32 in value + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxropcode 4180 + offset 579 + +DeleteProgramsARB(n, programs) + return void + param n SizeI in value + param programs UInt32 in array [n] + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxvendorpriv 1294 + offset 580 + +GenProgramsARB(n, programs) + return void + param n SizeI in value + param programs UInt32 out array [n] + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxvendorpriv 1295 + offset 582 + +ProgramEnvParameter4dARB(target, index, x, y, z, w) + return void + param target ProgramTargetARB in value + param index UInt32 in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + param w Float64 in value + category ARB_vertex_program + version 1.3 + vectorequiv ProgramEnvParameter4dvARB + extension soft WINSOFT NV10 + glxflags ignore + offset 668 + +ProgramEnvParameter4dvARB(target, index, params) + return void + param target ProgramTargetARB in value + param index UInt32 in value + param params Float64 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxflags ignore + offset 669 + +ProgramEnvParameter4fARB(target, index, x, y, z, w) + return void + param target ProgramTargetARB in value + param index UInt32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + param w Float32 in value + category ARB_vertex_program + version 1.3 + vectorequiv ProgramEnvParameter4fvARB + extension soft WINSOFT NV10 + glxflags ignore + offset 670 + +ProgramEnvParameter4fvARB(target, index, params) + return void + param target ProgramTargetARB in value + param index UInt32 in value + param params Float32 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxflags ignore + offset 671 + +ProgramLocalParameter4dARB(target, index, x, y, z, w) + return void + param target ProgramTargetARB in value + param index UInt32 in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + param w Float64 in value + category ARB_vertex_program + version 1.3 + vectorequiv ProgramLocalParameter4dvARB + extension soft WINSOFT NV10 + glxflags ignore + offset 672 + +ProgramLocalParameter4dvARB(target, index, params) + return void + param target ProgramTargetARB in value + param index UInt32 in value + param params Float64 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxflags ignore + offset 673 + +ProgramLocalParameter4fARB(target, index, x, y, z, w) + return void + param target ProgramTargetARB in value + param index UInt32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + param w Float32 in value + category ARB_vertex_program + version 1.3 + vectorequiv ProgramLocalParameter4fvARB + extension soft WINSOFT NV10 + glxflags ignore + offset 674 + +ProgramLocalParameter4fvARB(target, index, params) + return void + param target ProgramTargetARB in value + param index UInt32 in value + param params Float32 in array [4] + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxflags ignore + offset 675 + +GetProgramEnvParameterdvARB(target, index, params) + return void + param target ProgramTargetARB in value + param index UInt32 in value + param params Float64 out array [4] + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxflags ignore + offset 676 + +GetProgramEnvParameterfvARB(target, index, params) + return void + param target ProgramTargetARB in value + param index UInt32 in value + param params Float32 out array [4] + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxflags ignore + offset 677 + +GetProgramLocalParameterdvARB(target, index, params) + return void + param target ProgramTargetARB in value + param index UInt32 in value + param params Float64 out array [4] + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxflags ignore + offset 678 + +GetProgramLocalParameterfvARB(target, index, params) + return void + param target ProgramTargetARB in value + param index UInt32 in value + param params Float32 out array [4] + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxflags ignore + offset 679 + +GetProgramivARB(target, pname, params) + return void + param target ProgramTargetARB in value + param pname ProgramPropertyARB in value + param params Int32 out array [1] + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxflags ignore + offset 680 + +GetProgramStringARB(target, pname, string) + return void + param target ProgramTargetARB in value + param pname ProgramStringPropertyARB in value + param string Void out array [COMPSIZE(target,pname)] + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxflags ignore + offset 681 + +GetVertexAttribdvARB(index, pname, params) + return void + param index UInt32 in value + param pname VertexAttribPropertyARB in value + param params Float64 out array [4] + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxvendorpriv 1301 + alias GetVertexAttribdv + +GetVertexAttribfvARB(index, pname, params) + return void + param index UInt32 in value + param pname VertexAttribPropertyARB in value + param params Float32 out array [4] + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxvendorpriv 1302 + alias GetVertexAttribfv + +GetVertexAttribivARB(index, pname, params) + return void + param index UInt32 in value + param pname VertexAttribPropertyARB in value + param params Int32 out array [4] + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxvendorpriv 1303 + alias GetVertexAttribiv + +GetVertexAttribPointervARB(index, pname, pointer) + return void + param index UInt32 in value + param pname VertexAttribPointerPropertyARB in value + param pointer VoidPointer out array [1] + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxflags ignore + alias GetVertexAttribPointerv + +IsProgramARB(program) + return Boolean + param program UInt32 in value + dlflags notlistable + category ARB_vertex_program + version 1.3 + extension soft WINSOFT NV10 + glxvendorpriv 1304 + alias IsProgram + + +############################################################################### +# +# ARB Extension #27 +# ARB_fragment_program commands +# +############################################################################### + +# All ARB_fragment_program entry points are shared with ARB_vertex_program, +# and are only included in that #define block, for now. +newcategory: ARB_fragment_program +passthru: /* All ARB_fragment_program entry points are shared with ARB_vertex_program. */ + +############################################################################### +# +# ARB Extension #28 +# ARB_vertex_buffer_object commands +# +############################################################################### + +BindBufferARB(target, buffer) + return void + param target BufferTargetARB in value + param buffer UInt32 in value + category ARB_vertex_buffer_object + version 1.2 + extension + alias BindBuffer + +DeleteBuffersARB(n, buffers) + return void + param n SizeI in value + param buffers ConstUInt32 in array [n] + category ARB_vertex_buffer_object + version 1.2 + extension + alias DeleteBuffers + +GenBuffersARB(n, buffers) + return void + param n SizeI in value + param buffers UInt32 out array [n] + category ARB_vertex_buffer_object + version 1.2 + extension + alias GenBuffers + +IsBufferARB(buffer) + return Boolean + param buffer UInt32 in value + category ARB_vertex_buffer_object + version 1.2 + extension + alias IsBuffer + +BufferDataARB(target, size, data, usage) + return void + param target BufferTargetARB in value + param size BufferSizeARB in value + param data ConstVoid in array [size] + param usage BufferUsageARB in value + category ARB_vertex_buffer_object + version 1.2 + extension + alias BufferData + +BufferSubDataARB(target, offset, size, data) + return void + param target BufferTargetARB in value + param offset BufferOffsetARB in value + param size BufferSizeARB in value + param data ConstVoid in array [size] + category ARB_vertex_buffer_object + version 1.2 + extension + alias BufferSubData + +GetBufferSubDataARB(target, offset, size, data) + return void + param target BufferTargetARB in value + param offset BufferOffsetARB in value + param size BufferSizeARB in value + param data Void out array [size] + category ARB_vertex_buffer_object + dlflags notlistable + version 1.2 + extension + alias GetBufferSubData + +MapBufferARB(target, access) + return VoidPointer + param target BufferTargetARB in value + param access BufferAccessARB in value + category ARB_vertex_buffer_object + version 1.2 + extension + alias MapBuffer + +UnmapBufferARB(target) + return Boolean + param target BufferTargetARB in value + category ARB_vertex_buffer_object + version 1.2 + extension + alias UnmapBuffer + +GetBufferParameterivARB(target, pname, params) + return void + param target BufferTargetARB in value + param pname BufferPNameARB in value + param params Int32 out array [COMPSIZE(pname)] + category ARB_vertex_buffer_object + dlflags notlistable + version 1.2 + extension + alias GetBufferParameteriv + +GetBufferPointervARB(target, pname, params) + return void + param target BufferTargetARB in value + param pname BufferPointerNameARB in value + param params VoidPointer out array [1] + category ARB_vertex_buffer_object + dlflags notlistable + version 1.2 + extension + alias GetBufferPointerv + +############################################################################### +# +# ARB Extension #29 +# ARB_occlusion_query commands +# +############################################################################### + +GenQueriesARB(n, ids) + return void + param n SizeI in value + param ids UInt32 out array [n] + category ARB_occlusion_query + version 1.5 + extension + alias GenQueries + +DeleteQueriesARB(n, ids) + return void + param n SizeI in value + param ids UInt32 in array [n] + category ARB_occlusion_query + version 1.5 + extension + alias DeleteQueries + +IsQueryARB(id) + return Boolean + param id UInt32 in value + category ARB_occlusion_query + version 1.5 + extension + alias IsQuery + +BeginQueryARB(target, id) + return void + param target GLenum in value + param id UInt32 in value + category ARB_occlusion_query + version 1.5 + extension + alias BeginQuery + +EndQueryARB(target) + return void + param target GLenum in value + category ARB_occlusion_query + version 1.5 + extension + alias EndQuery + +GetQueryivARB(target, pname, params) + return void + param target GLenum in value + param pname GLenum in value + param params Int32 out array [pname] + category ARB_occlusion_query + dlflags notlistable + version 1.5 + extension + alias GetQueryiv + +GetQueryObjectivARB(id, pname, params) + return void + param id UInt32 in value + param pname GLenum in value + param params Int32 out array [pname] + category ARB_occlusion_query + dlflags notlistable + version 1.5 + extension + alias GetQueryObjectiv + +GetQueryObjectuivARB(id, pname, params) + return void + param id UInt32 in value + param pname GLenum in value + param params UInt32 out array [pname] + category ARB_occlusion_query + dlflags notlistable + version 1.5 + extension + alias GetQueryObjectuiv + +############################################################################### +# +# ARB Extension #30 +# ARB_shader_objects commands +# +############################################################################### + +DeleteObjectARB(obj) + return void + param obj handleARB in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetHandleARB(pname) + return handleARB + param pname GLenum in value + category ARB_shader_objects + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +DetachObjectARB(containerObj, attachedObj) + return void + param containerObj handleARB in value + param attachedObj handleARB in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias DetachShader + +CreateShaderObjectARB(shaderType) + return handleARB + param shaderType GLenum in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias CreateShader + +ShaderSourceARB(shaderObj, count, string, length) + return void + param shaderObj handleARB in value + param count SizeI in value + param string charPointerARB in array [count] + param length Int32 in array [1] + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias ShaderSource + +CompileShaderARB(shaderObj) + return void + param shaderObj handleARB in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias CompileShader + +CreateProgramObjectARB() + return handleARB + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias CreateProgram + +AttachObjectARB(containerObj, obj) + return void + param containerObj handleARB in value + param obj handleARB in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias AttachShader + +LinkProgramARB(programObj) + return void + param programObj handleARB in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias LinkProgram + +UseProgramObjectARB(programObj) + return void + param programObj handleARB in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias UseProgram + +ValidateProgramARB(programObj) + return void + param programObj handleARB in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias ValidateProgram + +Uniform1fARB(location, v0) + return void + param location Int32 in value + param v0 Float32 in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform1f + +Uniform2fARB(location, v0, v1) + return void + param location Int32 in value + param v0 Float32 in value + param v1 Float32 in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform2f + +Uniform3fARB(location, v0, v1, v2) + return void + param location Int32 in value + param v0 Float32 in value + param v1 Float32 in value + param v2 Float32 in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform3f + +Uniform4fARB(location, v0, v1, v2, v3) + return void + param location Int32 in value + param v0 Float32 in value + param v1 Float32 in value + param v2 Float32 in value + param v3 Float32 in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform4f + +Uniform1iARB(location, v0) + return void + param location Int32 in value + param v0 Int32 in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform1i + +Uniform2iARB(location, v0, v1) + return void + param location Int32 in value + param v0 Int32 in value + param v1 Int32 in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform2i + +Uniform3iARB(location, v0, v1, v2) + return void + param location Int32 in value + param v0 Int32 in value + param v1 Int32 in value + param v2 Int32 in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform3i + +Uniform4iARB(location, v0, v1, v2, v3) + return void + param location Int32 in value + param v0 Int32 in value + param v1 Int32 in value + param v2 Int32 in value + param v3 Int32 in value + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform4i + +Uniform1fvARB(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Float32 in array [count] + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform1fv + +Uniform2fvARB(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Float32 in array [count] + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform2fv + +Uniform3fvARB(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Float32 in array [count] + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform3fv + +Uniform4fvARB(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Float32 in array [count] + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform4fv + +Uniform1ivARB(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Int32 in array [count] + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform1iv + +Uniform2ivARB(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Int32 in array [count] + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform2iv + +Uniform3ivARB(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Int32 in array [count] + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform3iv + +Uniform4ivARB(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value Int32 in array [count] + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias Uniform4iv + +UniformMatrix2fvARB(location, count, transpose, value) + return void + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [count] + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias UniformMatrix2fv + +UniformMatrix3fvARB(location, count, transpose, value) + return void + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [count] + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias UniformMatrix3fv + +UniformMatrix4fvARB(location, count, transpose, value) + return void + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [count] + category ARB_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + alias UniformMatrix4fv + +GetObjectParameterfvARB(obj, pname, params) + return void + param obj handleARB in value + param pname GLenum in value + param params Float32 out array [pname] + category ARB_shader_objects + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetObjectParameterivARB(obj, pname, params) + return void + param obj handleARB in value + param pname GLenum in value + param params Int32 out array [pname] + category ARB_shader_objects + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetInfoLogARB(obj, maxLength, length, infoLog) + return void + param obj handleARB in value + param maxLength SizeI in value + param length SizeI out array [1] + param infoLog charARB out array [length] + category ARB_shader_objects + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetAttachedObjectsARB(containerObj, maxCount, count, obj) + return void + param containerObj handleARB in value + param maxCount SizeI in value + param count SizeI out array [1] + param obj handleARB out array [count] + category ARB_shader_objects + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + alias GetAttachedShaders + +GetUniformLocationARB(programObj, name) + return Int32 + param programObj handleARB in value + param name charARB in array [] + category ARB_shader_objects + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + alias GetUniformLocation + +GetActiveUniformARB(programObj, index, maxLength, length, size, type, name) + return void + param programObj handleARB in value + param index UInt32 in value + param maxLength SizeI in value + param length SizeI out array [1] + param size Int32 out array [1] + param type GLenum out array [1] + param name charARB out array [] + category ARB_shader_objects + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + alias GetActiveUniform + +GetUniformfvARB(programObj, location, params) + return void + param programObj handleARB in value + param location Int32 in value + param params Float32 out array [location] + category ARB_shader_objects + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + alias GetUniformfv + +GetUniformivARB(programObj, location, params) + return void + param programObj handleARB in value + param location Int32 in value + param params Int32 out array [location] + category ARB_shader_objects + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + alias GetUniformiv + +GetShaderSourceARB(obj, maxLength, length, source) + return void + param obj handleARB in value + param maxLength SizeI in value + param length SizeI out array [1] + param source charARB out array [length] + category ARB_shader_objects + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + alias GetShaderSource + + +############################################################################### +# +# ARB Extension #31 +# ARB_vertex_shader commands +# +############################################################################### + +BindAttribLocationARB(programObj, index, name) + return void + param programObj handleARB in value + param index UInt32 in value + param name charARB in array [] + category ARB_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + alias BindAttribLocation + +GetActiveAttribARB(programObj, index, maxLength, length, size, type, name) + return void + param programObj handleARB in value + param index UInt32 in value + param maxLength SizeI in value + param length SizeI out array [1] + param size Int32 out array [1] + param type GLenum out array [1] + param name charARB out array [] + category ARB_vertex_shader + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + alias GetActiveAttrib + +GetAttribLocationARB(programObj, name) + return Int32 + param programObj handleARB in value + param name charARB in array [] + category ARB_vertex_shader + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + alias GetAttribLocation + +############################################################################### +# +# ARB Extension #32 +# ARB_fragment_shader commands +# +############################################################################### + +# (none) +newcategory: ARB_fragment_shader + +############################################################################### +# +# ARB Extension #33 +# ARB_shading_language_100 commands +# +############################################################################### + +# (none) +newcategory: ARB_shading_language_100 + +############################################################################### +# +# ARB Extension #34 +# ARB_texture_non_power_of_two commands +# +############################################################################### + +# (none) +newcategory: ARB_texture_non_power_of_two + +############################################################################### +# +# ARB Extension #35 +# ARB_point_sprite commands +# +############################################################################### + +# (none) +newcategory: ARB_point_sprite + +############################################################################### +# +# ARB Extension #36 +# ARB_fragment_program_shadow commands +# +############################################################################### + +# (none) +newcategory: ARB_fragment_program_shadow + +############################################################################### +# +# ARB Extension #37 +# ARB_draw_buffers commands +# +############################################################################### + +DrawBuffersARB(n, bufs) + return void + param n SizeI in value + param bufs DrawBufferModeATI in array [n] + category ARB_draw_buffers + version 1.5 + extension + alias DrawBuffers + +############################################################################### +# +# ARB Extension #38 +# ARB_texture_rectangle commands +# +############################################################################### + +# (none) +newcategory: ARB_texture_rectangle + +############################################################################### +# +# ARB Extension #39 +# ARB_color_buffer_float commands +# +############################################################################### + +ClampColorARB(target, clamp) + return void + param target ClampColorTargetARB in value + param clamp ClampColorModeARB in value + category ARB_color_buffer_float + version 1.5 + extension + glxropcode 234 + glxflags ignore + alias ClampColor + +############################################################################### +# +# ARB Extension #40 +# ARB_half_float_pixel commands +# +############################################################################### + +# (none) +newcategory: ARB_half_float_pixel + +############################################################################### +# +# ARB Extension #41 +# ARB_texture_float commands +# +############################################################################### + +# (none) +newcategory: ARB_texture_float + +############################################################################### +# +# ARB Extension #42 +# ARB_pixel_buffer_object commands +# +############################################################################### + +# (none) +newcategory: ARB_pixel_buffer_object + +############################################################################### +# +# ARB Extension #43 +# ARB_depth_buffer_float commands (also OpenGL 3.0) +# +############################################################################### + +# (none) +newcategory: ARB_depth_buffer_float + +############################################################################### +# +# ARB Extension #44 +# ARB_draw_instanced commands +# +############################################################################### + +DrawArraysInstancedARB(mode, first, count, primcount) + return void + param mode BeginMode in value + param first Int32 in value + param count SizeI in value + param primcount SizeI in value + category ARB_draw_instanced + version 2.0 + extension soft WINSOFT + dlflags notlistable + vectorequiv ArrayElement + glfflags ignore + glxflags ignore + alias DrawArraysInstanced + +DrawElementsInstancedARB(mode, count, type, indices, primcount) + return void + param mode BeginMode in value + param count SizeI in value + param type DrawElementsType in value + param indices Void in array [COMPSIZE(count/type)] + param primcount SizeI in value + category ARB_draw_instanced + version 2.0 + extension soft WINSOFT + dlflags notlistable + vectorequiv ArrayElement + glfflags ignore + glxflags ignore + alias DrawElementsInstanced + +############################################################################### +# +# ARB Extension #45 +# ARB_framebuffer_object commands (also OpenGL 3.0) +# +############################################################################### + +# Promoted from EXT_framebuffer_object +IsRenderbuffer(renderbuffer) + return Boolean + param renderbuffer UInt32 in value + category ARB_framebuffer_object + version 3.0 + extension + glxvendorpriv 1422 + glxflags ignore + offset ? + +BindRenderbuffer(target, renderbuffer) + return void + param target RenderbufferTarget in value + param renderbuffer UInt32 in value + category ARB_framebuffer_object + version 3.0 + extension + glxropcode 4316 + glxflags ignore + offset ? + +DeleteRenderbuffers(n, renderbuffers) + return void + param n SizeI in value + param renderbuffers UInt32 in array [n] + category ARB_framebuffer_object + version 3.0 + extension + glxropcode 4317 + glxflags ignore + offset ? + +GenRenderbuffers(n, renderbuffers) + return void + param n SizeI in value + param renderbuffers UInt32 out array [n] + category ARB_framebuffer_object + version 3.0 + extension + glxvendorpriv 1423 + glxflags ignore + offset ? + +RenderbufferStorage(target, internalformat, width, height) + return void + param target RenderbufferTarget in value + param internalformat GLenum in value + param width SizeI in value + param height SizeI in value + category ARB_framebuffer_object + version 3.0 + extension + glxropcode 4318 + glxflags ignore + offset ? + +GetRenderbufferParameteriv(target, pname, params) + return void + param target RenderbufferTarget in value + param pname GLenum in value + param params Int32 out array [COMPSIZE(pname)] + category ARB_framebuffer_object + dlflags notlistable + version 3.0 + extension + glxvendorpriv 1424 + glxflags ignore + offset ? + +IsFramebuffer(framebuffer) + return Boolean + param framebuffer UInt32 in value + category ARB_framebuffer_object + version 3.0 + extension + glxvendorpriv 1425 + glxflags ignore + offset ? + +BindFramebuffer(target, framebuffer) + return void + param target FramebufferTarget in value + param framebuffer UInt32 in value + category ARB_framebuffer_object + version 3.0 + extension + glxropcode 4319 + glxflags ignore + offset ? + +DeleteFramebuffers(n, framebuffers) + return void + param n SizeI in value + param framebuffers UInt32 in array [n] + category ARB_framebuffer_object + version 3.0 + extension + glxropcode 4320 + glxflags ignore + offset ? + +GenFramebuffers(n, framebuffers) + return void + param n SizeI in value + param framebuffers UInt32 out array [n] + category ARB_framebuffer_object + version 3.0 + extension + glxvendorpriv 1426 + glxflags ignore + offset ? + +CheckFramebufferStatus(target) + return GLenum + param target FramebufferTarget in value + category ARB_framebuffer_object + version 3.0 + extension + glxvendorpriv 1427 + glxflags ignore + offset ? + +FramebufferTexture1D(target, attachment, textarget, texture, level) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param textarget GLenum in value + param texture UInt32 in value + param level Int32 in value + category ARB_framebuffer_object + version 3.0 + extension + glxropcode 4321 + glxflags ignore + offset ? + +FramebufferTexture2D(target, attachment, textarget, texture, level) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param textarget GLenum in value + param texture UInt32 in value + param level Int32 in value + category ARB_framebuffer_object + version 3.0 + extension + glxropcode 4322 + glxflags ignore + offset ? + +FramebufferTexture3D(target, attachment, textarget, texture, level, zoffset) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param textarget GLenum in value + param texture UInt32 in value + param level Int32 in value + param zoffset Int32 in value + category ARB_framebuffer_object + version 3.0 + extension + glxropcode 4323 + glxflags ignore + offset ? + +FramebufferRenderbuffer(target, attachment, renderbuffertarget, renderbuffer) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param renderbuffertarget RenderbufferTarget in value + param renderbuffer UInt32 in value + category ARB_framebuffer_object + version 3.0 + extension + glxropcode 4324 + glxflags ignore + offset ? + +GetFramebufferAttachmentParameteriv(target, attachment, pname, params) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param pname GLenum in value + param params Int32 out array [COMPSIZE(pname)] + category ARB_framebuffer_object + dlflags notlistable + version 3.0 + extension + glxvendorpriv 1428 + glxflags ignore + offset ? + +GenerateMipmap(target) + return void + param target GLenum in value + category ARB_framebuffer_object + version 3.0 + extension + glxropcode 4325 + glxflags ignore + offset ? + +# Promoted from EXT_framebuffer_blit +BlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter) + return void + param srcX0 Int32 in value + param srcY0 Int32 in value + param srcX1 Int32 in value + param srcY1 Int32 in value + param dstX0 Int32 in value + param dstY0 Int32 in value + param dstX1 Int32 in value + param dstY1 Int32 in value + param mask ClearBufferMask in value + param filter GLenum in value + category ARB_framebuffer_object + version 3.0 + glxropcode 4330 + offset ? + +# Promoted from EXT_framebuffer_multisample +RenderbufferStorageMultisample(target, samples, internalformat, width, height) + return void + param target GLenum in value + param samples SizeI in value + param internalformat GLenum in value + param width SizeI in value + param height SizeI in value + category ARB_framebuffer_object + version 3.0 + glxropcode 4331 + offset ? + +# Promoted from ARB_geometry_shader4 +FramebufferTextureLayer(target, attachment, texture, level, layer) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param texture Texture in value + param level CheckedInt32 in value + param layer CheckedInt32 in value + category ARB_framebuffer_object + version 3.0 + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + + +############################################################################### +# +# ARB Extension #46 +# ARB_framebuffer_sRGB commands (also OpenGL 3.0) +# +############################################################################### + +# (none) +newcategory: ARB_framebuffer_sRGB + +############################################################################### +# +# ARB Extension #47 +# ARB_geometry_shader4 commands +# +############################################################################### + +ProgramParameteriARB(program, pname, value) + return void + param program UInt32 in value + param pname ProgramParameterPName in value + param value Int32 in value + category ARB_geometry_shader4 + version 3.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + +FramebufferTextureARB(target, attachment, texture, level) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param texture Texture in value + param level CheckedInt32 in value + category ARB_geometry_shader4 + version 3.0 + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + +FramebufferTextureLayerARB(target, attachment, texture, level, layer) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param texture Texture in value + param level CheckedInt32 in value + param layer CheckedInt32 in value + category ARB_geometry_shader4 + version 3.0 + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + alias FramebufferTextureLayer + +FramebufferTextureFaceARB(target, attachment, texture, level, face) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param texture Texture in value + param level CheckedInt32 in value + param face TextureTarget in value + category ARB_geometry_shader4 + version 3.0 + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + +############################################################################### +# +# ARB Extension #48 +# ARB_half_float_vertex commands (also OpenGL 3.0) +# +############################################################################### + +# (none) +newcategory: ARB_half_float_vertex + +############################################################################### +# +# ARB Extension #49 +# ARB_instanced_arrays commands +# +############################################################################### + +VertexAttribDivisorARB(index, divisor) + return void + param index UInt32 in value + param divisor UInt32 in value + category ARB_instanced_arrays + version 2.0 + extension + glfflags ignore + glxflags ignore + +############################################################################### +# +# ARB Extension #50 +# ARB_map_buffer_range commands (also OpenGL 3.0) +# +############################################################################### + +MapBufferRange(target, offset, length, access) + return VoidPointer + param target BufferTargetARB in value + param offset BufferOffset in value + param length BufferSize in value + param access BufferAccessMask in value + category ARB_map_buffer_range + version 3.0 + extension + glxropcode ? + glxflags ignore + offset ? + +# Promoted from APPLE_flush_buffer_range +FlushMappedBufferRange(target, offset, length) + return void + param target BufferTargetARB in value + param offset BufferOffset in value + param length BufferSize in value + category ARB_map_buffer_range + version 3.0 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# ARB Extension #51 +# ARB_texture_buffer_object commands +# +############################################################################### + +TexBufferARB(target, internalformat, buffer) + return void + param target TextureTarget in value + param internalformat GLenum in value + param buffer UInt32 in value + category ARB_texture_buffer_object + version 3.0 + extension soft WINSOFT NV50 + glfflags ignore + alias TexBuffer + +############################################################################### +# +# ARB Extension #52 +# ARB_texture_compression_rgtc commands (also OpenGL 3.0) +# +############################################################################### + +# (none) +newcategory: ARB_texture_compression_rgtc + +############################################################################### +# +# ARB Extension #53 +# ARB_texture_rg commands (also OpenGL 3.0) +# +############################################################################### + +# (none) +newcategory: ARB_texture_rg + +############################################################################### +# +# ARB Extension #54 +# ARB_vertex_array_object commands (also OpenGL 3.0) +# +############################################################################### + +# Promoted from APPLE_vertex_array_object +BindVertexArray(array) + return void + param array UInt32 in value + category ARB_vertex_array_object + version 3.0 + extension + glxropcode ? + glxflags ignore + offset ? + +DeleteVertexArrays(n, arrays) + return void + param n SizeI in value + param arrays UInt32 in array [n] + category ARB_vertex_array_object + version 3.0 + extension + glxropcode ? + glxflags ignore + offset ? + +GenVertexArrays(n, arrays) + return void + param n SizeI in value + param arrays UInt32 out array [n] + category ARB_vertex_array_object + version 3.0 + extension + glxropcode ? + glxflags ignore + offset ? + +IsVertexArray(array) + return Boolean + param array UInt32 in value + category ARB_vertex_array_object + version 3.0 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# ARB Extension #55 - WGL_ARB_create_context +# ARB Extension #56 - GLX_ARB_create_context +# +############################################################################### + +############################################################################### +# +# ARB Extension #57 +# ARB_uniform_buffer_object commands +# +############################################################################### + +GetUniformIndices(program, uniformCount, uniformNames, uniformIndices) + return void + param program UInt32 in value + param uniformCount SizeI in value + param uniformNames CharPointer in array [COMPSIZE(uniformCount)] + param uniformIndices UInt32 out array [COMPSIZE(uniformCount)] + category ARB_uniform_buffer_object + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetActiveUniformsiv(program, uniformCount, uniformIndices, pname, params) + return void + param program UInt32 in value + param uniformCount SizeI in value + param uniformIndices UInt32 in array [COMPSIZE(uniformCount)] + param pname GLenum in value + param params Int32 out array [COMPSIZE(pname)] + category ARB_uniform_buffer_object + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetActiveUniformName(program, uniformIndex, bufSize, length, uniformName) + return void + param program UInt32 in value + param uniformIndex UInt32 in value + param bufSize SizeI in value + param length SizeI out array [1] + param uniformName Char out array [bufSize] + category ARB_uniform_buffer_object + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetUniformBlockIndex(program, uniformBlockName) + return UInt32 + param program UInt32 in value + param uniformBlockName Char in array [COMPSIZE()] + category ARB_uniform_buffer_object + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetActiveUniformBlockiv(program, uniformBlockIndex, pname, params) + return void + param program UInt32 in value + param uniformBlockIndex UInt32 in value + param pname GLenum in value + param params Int32 out array [COMPSIZE(pname)] + category ARB_uniform_buffer_object + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +GetActiveUniformBlockName(program, uniformBlockIndex, bufSize, length, uniformBlockName) + return void + param program UInt32 in value + param uniformBlockIndex UInt32 in value + param bufSize SizeI in value + param length SizeI out array [1] + param uniformBlockName Char out array [bufSize] + category ARB_uniform_buffer_object + dlflags notlistable + version 2.0 + extension + glxsingle ? + glxflags ignore + offset ? + +UniformBlockBinding(program, uniformBlockIndex, uniformBlockBinding) + return void + param program UInt32 in value + param uniformBlockIndex UInt32 in value + param uniformBlockBinding UInt32 in value + category ARB_uniform_buffer_object + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + + +############################################################################### +# +# ARB Extension #58 +# ARB_compatibility commands +# +############################################################################### + +# (none) +newcategory: ARB_compatibility + +############################################################################### +# +# ARB Extension #59 +# ARB_copy_buffer commands +# +############################################################################### + +CopyBufferSubData(readTarget, writeTarget, readOffset, writeOffset, size) + return void + param readTarget GLenum in value + param writeTarget GLenum in value + param readOffset BufferOffset in value + param writeOffset BufferOffset in value + param size BufferSize in value + category ARB_copy_buffer + version 3.0 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# ARB Extension #60 +# ARB_shader_texture_lod commands +# +############################################################################### + +# (none) +newcategory: ARB_shader_texture_lod + +############################################################################### +# +# ARB Extension #61 +# ARB_depth_clamp commands +# +############################################################################### + +# (none) +newcategory: ARB_depth_clamp + +############################################################################### +# +# ARB Extension #62 +# ARB_draw_elements_base_vertex commands +# +############################################################################### + +DrawElementsBaseVertex(mode, count, type, indices, basevertex) + return void + param mode GLenum in value + param count SizeI in value + param type DrawElementsType in value + param indices Void in array [COMPSIZE(count/type)] + param basevertex Int32 in value + category ARB_draw_elements_base_vertex + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +DrawRangeElementsBaseVertex(mode, start, end, count, type, indices, basevertex) + return void + param mode GLenum in value + param start UInt32 in value + param end UInt32 in value + param count SizeI in value + param type DrawElementsType in value + param indices Void in array [COMPSIZE(count/type)] + param basevertex Int32 in value + category ARB_draw_elements_base_vertex + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +DrawElementsInstancedBaseVertex(mode, count, type, indices, primcount, basevertex) + return void + param mode GLenum in value + param count SizeI in value + param type DrawElementsType in value + param indices Void in array [COMPSIZE(count/type)] + param primcount SizeI in value + param basevertex Int32 in value + category ARB_draw_elements_base_vertex + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +MultiDrawElementsBaseVertex(mode, count, type, indices, primcount, basevertex) + return void + param mode GLenum in value + param count SizeI in array [COMPSIZE(primcount)] + param type DrawElementsType in value + param indices VoidPointer in array [COMPSIZE(primcount)] + param primcount SizeI in value + param basevertex Int32 in array [COMPSIZE(primcount)] + category ARB_draw_elements_base_vertex + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# ARB Extension #63 +# ARB_fragment_coord_conventions commands +# +############################################################################### + +# (none) +newcategory: ARB_fragment_coord_conventions + +############################################################################### +# +# ARB Extension #64 +# ARB_provoking_vertex commands +# +############################################################################### + +ProvokingVertex(mode) + return void + param mode GLenum in value + category ARB_provoking_vertex + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# ARB Extension #65 +# ARB_seamless_cube_map commands +# +############################################################################### + +# (none) +newcategory: ARB_seamless_cube_map + +############################################################################### +# +# ARB Extension #66 +# ARB_sync commands +# +############################################################################### + +FenceSync(condition, flags) + return sync + param condition GLenum in value + param flags GLbitfield in value + category ARB_sync + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +IsSync(sync) + return Boolean + param sync sync in value + category ARB_sync + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +DeleteSync(sync) + return void + param sync sync in value + category ARB_sync + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +ClientWaitSync(sync, flags, timeout) + return GLenum + param sync sync in value + param flags GLbitfield in value + param timeout UInt64 in value + category ARB_sync + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +WaitSync(sync, flags, timeout) + return void + param sync sync in value + param flags GLbitfield in value + param timeout UInt64 in value + category ARB_sync + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetInteger64v(pname, params) + return void + param pname GLenum in value + param params Int64 out array [COMPSIZE(pname)] + category ARB_sync + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetSynciv(sync, pname, bufSize, length, values) + return void + param sync sync in value + param pname GLenum in value + param bufSize SizeI in value + param length SizeI out array [1] + param values Int32 out array [length] + category ARB_sync + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +############################################################################### +# +# ARB Extension #67 +# ARB_texture_multisample commands +# +############################################################################### + +TexImage2DMultisample(target, samples, internalformat, width, height, fixedsamplelocations) + return void + param target GLenum in value + param samples SizeI in value + param internalformat Int32 in value + param width SizeI in value + param height SizeI in value + param fixedsamplelocations Boolean in value + category ARB_texture_multisample + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +TexImage3DMultisample(target, samples, internalformat, width, height, depth, fixedsamplelocations) + return void + param target GLenum in value + param samples SizeI in value + param internalformat Int32 in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param fixedsamplelocations Boolean in value + category ARB_texture_multisample + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetMultisamplefv(pname, index, val) + return void + param pname GLenum in value + param index UInt32 in value + param val Float32 out array [COMPSIZE(pname)] + category ARB_texture_multisample + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +SampleMaski(index, mask) + return void + param index UInt32 in value + param mask GLbitfield in value + category ARB_texture_multisample + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# ARB Extension #68 +# ARB_vertex_array_bgra commands +# +############################################################################### + +# (none) +newcategory: ARB_vertex_array_bgra + +############################################################################### +# +# ARB Extension #69 +# ARB_draw_buffers_blend commands +# +############################################################################### + +BlendEquationi(buf, mode) + return void + param buf UInt32 in value + param mode GLenum in value + category ARB_draw_buffers_blend + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +BlendEquationSeparatei(buf, modeRGB, modeAlpha) + return void + param buf UInt32 in value + param modeRGB GLenum in value + param modeAlpha GLenum in value + category ARB_draw_buffers_blend + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +BlendFunci(buf, src, dst) + return void + param buf UInt32 in value + param src GLenum in value + param dst GLenum in value + category ARB_draw_buffers_blend + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +BlendFuncSeparatei(buf, srcRGB, dstRGB, srcAlpha, dstAlpha) + return void + param buf UInt32 in value + param srcRGB GLenum in value + param dstRGB GLenum in value + param srcAlpha GLenum in value + param dstAlpha GLenum in value + category ARB_draw_buffers_blend + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# ARB Extension #70 +# ARB_sample_shading commands +# +############################################################################### + +MinSampleShading(value) + return void + param value ClampedColorF in value + category ARB_sample_shading + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# ARB Extension #71 +# ARB_texture_cube_map_array commands +# +############################################################################### + +# (none) +newcategory: ARB_texture_cube_map_array + +############################################################################### +# +# ARB Extension #72 +# ARB_texture_gather commands +# +############################################################################### + +# (none) +newcategory: ARB_texture_gather + +############################################################################### +# +# ARB Extension #73 +# ARB_texture_query_lod commands +# +############################################################################### + +# (none) +newcategory: ARB_texture_query_lod + +############################################################################### +# +# ARB Extension #74 - WGL_ARB_create_context_profile +# ARB Extension #75 - GLX_ARB_create_context_profile +# +############################################################################### + + +############################################################################### +############################################################################### +# +# Non-ARB extensions, in order by registry extension number +# +############################################################################### +############################################################################### + +############################################################################### +# +# Extension #1 +# EXT_abgr commands +# +############################################################################### + +# (none) +newcategory: EXT_abgr + +############################################################################### +# +# Extension #2 +# EXT_blend_color commands +# +############################################################################### + +BlendColorEXT(red, green, blue, alpha) + return void + param red ClampedColorF in value + param green ClampedColorF in value + param blue ClampedColorF in value + param alpha ClampedColorF in value + category EXT_blend_color + version 1.0 + glxropcode 4096 + glxflags EXT + extension soft + alias BlendColor + +############################################################################### +# +# Extension #3 +# EXT_polygon_offset commands +# +############################################################################### + +PolygonOffsetEXT(factor, bias) + return void + param factor Float32 in value + param bias Float32 in value + category EXT_polygon_offset + version 1.0 + glxropcode 4098 + glxflags EXT + extension soft + offset 414 + +############################################################################### +# +# Extension #4 +# EXT_texture commands +# +############################################################################### + +# (none) +newcategory: EXT_texture + +############################################################################### +# +# Extension #5 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #6 +# EXT_texture3D commands +# +############################################################################### + +# Arguably TexelInternalFormat, not PixelInternalFormat +TexImage3DEXT(target, level, internalformat, width, height, depth, border, format, type, pixels) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param border CheckedInt32 in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height/depth)] + category EXT_texture3D + dlflags handcode + glxflags client-handcode server-handcode EXT + version 1.0 + glxropcode 4114 + extension + alias TexImage3D + +TexSubImage3DEXT(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param zoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height/depth)] + category EXT_texture3D + dlflags handcode + glxflags client-handcode server-handcode EXT + version 1.0 + glxropcode 4115 + extension + alias TexSubImage3D + +############################################################################### +# +# Extension #7 +# SGIS_texture_filter4 commands +# +############################################################################### + +GetTexFilterFuncSGIS(target, filter, weights) + return void + param target TextureTarget in value + param filter TextureFilterSGIS in value + param weights Float32 out array [COMPSIZE(target/filter)] + category SGIS_texture_filter4 + dlflags notlistable + version 1.0 + glxflags SGI + glxvendorpriv 4101 + extension + offset 415 + +TexFilterFuncSGIS(target, filter, n, weights) + return void + param target TextureTarget in value + param filter TextureFilterSGIS in value + param n SizeI in value + param weights Float32 in array [n] + category SGIS_texture_filter4 + glxflags SGI + version 1.0 + glxropcode 2064 + extension + offset 416 + +############################################################################### +# +# Extension #8 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #9 +# EXT_subtexture commands +# +############################################################################### + +TexSubImage1DEXT(target, level, xoffset, width, format, type, pixels) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param width SizeI in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width)] + category EXT_subtexture + dlflags handcode + glxflags client-handcode server-handcode EXT + version 1.0 + glxropcode 4099 + extension + alias TexSubImage1D + +TexSubImage2DEXT(target, level, xoffset, yoffset, width, height, format, type, pixels) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height)] + category EXT_subtexture + dlflags handcode + glxflags client-handcode server-handcode EXT + version 1.0 + glxropcode 4100 + extension + alias TexSubImage2D + +############################################################################### +# +# Extension #10 +# EXT_copy_texture commands +# +############################################################################### + +# Arguably TexelInternalFormat, not PixelInternalFormat +CopyTexImage1DEXT(target, level, internalformat, x, y, width, border) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat PixelInternalFormat in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param border CheckedInt32 in value + category EXT_copy_texture + version 1.0 + glxflags EXT + glxropcode 4119 + extension + alias CopyTexImage1D + +# Arguably TexelInternalFormat, not PixelInternalFormat +CopyTexImage2DEXT(target, level, internalformat, x, y, width, height, border) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat PixelInternalFormat in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + param border CheckedInt32 in value + category EXT_copy_texture + version 1.0 + glxflags EXT + glxropcode 4120 + extension + alias CopyTexImage2D + +CopyTexSubImage1DEXT(target, level, xoffset, x, y, width) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + category EXT_copy_texture + version 1.0 + glxflags EXT + glxropcode 4121 + extension + alias CopyTexSubImage1D + +CopyTexSubImage2DEXT(target, level, xoffset, yoffset, x, y, width, height) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + category EXT_copy_texture + version 1.0 + glxflags EXT + glxropcode 4122 + extension + alias CopyTexSubImage2D + +CopyTexSubImage3DEXT(target, level, xoffset, yoffset, zoffset, x, y, width, height) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param zoffset CheckedInt32 in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + category EXT_copy_texture + version 1.0 + glxflags EXT + glxropcode 4123 + extension + alias CopyTexSubImage3D + +############################################################################### +# +# Extension #11 +# EXT_histogram commands +# +############################################################################### + +GetHistogramEXT(target, reset, format, type, values) + return void + param target HistogramTargetEXT in value + param reset Boolean in value + param format PixelFormat in value + param type PixelType in value + param values Void out array [COMPSIZE(target/format/type)] + category EXT_histogram + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.0 + glxvendorpriv 5 + extension + offset 417 + +GetHistogramParameterfvEXT(target, pname, params) + return void + param target HistogramTargetEXT in value + param pname GetHistogramParameterPNameEXT in value + param params Float32 out array [COMPSIZE(pname)] + category EXT_histogram + dlflags notlistable + version 1.0 + glxvendorpriv 6 + glxflags EXT + extension + offset 418 + +GetHistogramParameterivEXT(target, pname, params) + return void + param target HistogramTargetEXT in value + param pname GetHistogramParameterPNameEXT in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_histogram + dlflags notlistable + version 1.0 + glxvendorpriv 7 + glxflags EXT + extension + offset 419 + +GetMinmaxEXT(target, reset, format, type, values) + return void + param target MinmaxTargetEXT in value + param reset Boolean in value + param format PixelFormat in value + param type PixelType in value + param values Void out array [COMPSIZE(target/format/type)] + category EXT_histogram + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.0 + glxvendorpriv 8 + extension + offset 420 + +GetMinmaxParameterfvEXT(target, pname, params) + return void + param target MinmaxTargetEXT in value + param pname GetMinmaxParameterPNameEXT in value + param params Float32 out array [COMPSIZE(pname)] + category EXT_histogram + dlflags notlistable + version 1.0 + glxvendorpriv 9 + glxflags EXT + extension + offset 421 + +GetMinmaxParameterivEXT(target, pname, params) + return void + param target MinmaxTargetEXT in value + param pname GetMinmaxParameterPNameEXT in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_histogram + dlflags notlistable + version 1.0 + glxvendorpriv 10 + glxflags EXT + extension + offset 422 + +HistogramEXT(target, width, internalformat, sink) + return void + param target HistogramTargetEXT in value + param width SizeI in value + param internalformat PixelInternalFormat in value + param sink Boolean in value + category EXT_histogram + version 1.0 + glxropcode 4110 + glxflags EXT + extension + alias Histogram + +MinmaxEXT(target, internalformat, sink) + return void + param target MinmaxTargetEXT in value + param internalformat PixelInternalFormat in value + param sink Boolean in value + category EXT_histogram + version 1.0 + glxropcode 4111 + glxflags EXT + extension + alias Minmax + +ResetHistogramEXT(target) + return void + param target HistogramTargetEXT in value + category EXT_histogram + version 1.0 + glxropcode 4112 + glxflags EXT + extension + alias ResetHistogram + +ResetMinmaxEXT(target) + return void + param target MinmaxTargetEXT in value + category EXT_histogram + version 1.0 + glxropcode 4113 + glxflags EXT + extension + alias ResetMinmax + +############################################################################### +# +# Extension #12 +# EXT_convolution commands +# +############################################################################### + +ConvolutionFilter1DEXT(target, internalformat, width, format, type, image) + return void + param target ConvolutionTargetEXT in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param format PixelFormat in value + param type PixelType in value + param image Void in array [COMPSIZE(format/type/width)] + category EXT_convolution + dlflags handcode + glxflags client-handcode server-handcode EXT + version 1.0 + glxropcode 4101 + extension + alias ConvolutionFilter1D + +ConvolutionFilter2DEXT(target, internalformat, width, height, format, type, image) + return void + param target ConvolutionTargetEXT in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param height SizeI in value + param format PixelFormat in value + param type PixelType in value + param image Void in array [COMPSIZE(format/type/width/height)] + category EXT_convolution + dlflags handcode + glxflags client-handcode server-handcode EXT + version 1.0 + glxropcode 4102 + extension + alias ConvolutionFilter2D + +ConvolutionParameterfEXT(target, pname, params) + return void + param target ConvolutionTargetEXT in value + param pname ConvolutionParameterEXT in value + param params CheckedFloat32 in value + category EXT_convolution + version 1.0 + glxropcode 4103 + glxflags EXT + extension + alias ConvolutionParameterf + +ConvolutionParameterfvEXT(target, pname, params) + return void + param target ConvolutionTargetEXT in value + param pname ConvolutionParameterEXT in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category EXT_convolution + version 1.0 + glxropcode 4104 + glxflags EXT + extension + alias ConvolutionParameterfv + +ConvolutionParameteriEXT(target, pname, params) + return void + param target ConvolutionTargetEXT in value + param pname ConvolutionParameterEXT in value + param params CheckedInt32 in value + category EXT_convolution + version 1.0 + glxropcode 4105 + glxflags EXT + extension + alias ConvolutionParameteri + +ConvolutionParameterivEXT(target, pname, params) + return void + param target ConvolutionTargetEXT in value + param pname ConvolutionParameterEXT in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category EXT_convolution + version 1.0 + glxropcode 4106 + glxflags EXT + extension + alias ConvolutionParameteriv + +CopyConvolutionFilter1DEXT(target, internalformat, x, y, width) + return void + param target ConvolutionTargetEXT in value + param internalformat PixelInternalFormat in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + category EXT_convolution + version 1.0 + glxropcode 4107 + glxflags EXT + extension + alias CopyConvolutionFilter1D + +CopyConvolutionFilter2DEXT(target, internalformat, x, y, width, height) + return void + param target ConvolutionTargetEXT in value + param internalformat PixelInternalFormat in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + category EXT_convolution + version 1.0 + glxropcode 4108 + glxflags EXT + extension + alias CopyConvolutionFilter2D + +GetConvolutionFilterEXT(target, format, type, image) + return void + param target ConvolutionTargetEXT in value + param format PixelFormat in value + param type PixelType in value + param image Void out array [COMPSIZE(target/format/type)] + category EXT_convolution + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.0 + glxvendorpriv 1 + extension + offset 423 + +GetConvolutionParameterfvEXT(target, pname, params) + return void + param target ConvolutionTargetEXT in value + param pname ConvolutionParameterEXT in value + param params Float32 out array [COMPSIZE(pname)] + category EXT_convolution + dlflags notlistable + version 1.0 + glxvendorpriv 2 + glxflags EXT + extension + offset 424 + +GetConvolutionParameterivEXT(target, pname, params) + return void + param target ConvolutionTargetEXT in value + param pname ConvolutionParameterEXT in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_convolution + dlflags notlistable + version 1.0 + glxvendorpriv 3 + glxflags EXT + extension + offset 425 + +GetSeparableFilterEXT(target, format, type, row, column, span) + return void + param target SeparableTargetEXT in value + param format PixelFormat in value + param type PixelType in value + param row Void out array [COMPSIZE(target/format/type)] + param column Void out array [COMPSIZE(target/format/type)] + param span Void out array [COMPSIZE(target/format/type)] + category EXT_convolution + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.0 + glxvendorpriv 4 + extension + offset 426 + +SeparableFilter2DEXT(target, internalformat, width, height, format, type, row, column) + return void + param target SeparableTargetEXT in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param height SizeI in value + param format PixelFormat in value + param type PixelType in value + param row Void in array [COMPSIZE(target/format/type/width)] + param column Void in array [COMPSIZE(target/format/type/height)] + category EXT_convolution + dlflags handcode + glxflags client-handcode server-handcode EXT + version 1.0 + glxropcode 4109 + extension + alias SeparableFilter2D + +############################################################################### +# +# Extension #13 +# SGI_color_matrix commands +# +############################################################################### + +# (none) +newcategory: SGI_color_matrix + +############################################################################### +# +# Extension #14 +# SGI_color_table commands +# +############################################################################### + +ColorTableSGI(target, internalformat, width, format, type, table) + return void + param target ColorTableTargetSGI in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param format PixelFormat in value + param type PixelType in value + param table Void in array [COMPSIZE(format/type/width)] + category SGI_color_table + dlflags handcode + glxflags client-handcode server-handcode SGI + version 1.0 + glxropcode 2053 + extension + alias ColorTable + +ColorTableParameterfvSGI(target, pname, params) + return void + param target ColorTableTargetSGI in value + param pname ColorTableParameterPNameSGI in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category SGI_color_table + version 1.0 + glxropcode 2054 + glxflags SGI + extension + alias ColorTableParameterfv + +ColorTableParameterivSGI(target, pname, params) + return void + param target ColorTableTargetSGI in value + param pname ColorTableParameterPNameSGI in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category SGI_color_table + version 1.0 + glxropcode 2055 + glxflags SGI + extension + alias ColorTableParameteriv + +CopyColorTableSGI(target, internalformat, x, y, width) + return void + param target ColorTableTargetSGI in value + param internalformat PixelInternalFormat in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + category SGI_color_table + version 1.0 + glxropcode 2056 + glxflags SGI + extension + alias CopyColorTable + +GetColorTableSGI(target, format, type, table) + return void + param target ColorTableTargetSGI in value + param format PixelFormat in value + param type PixelType in value + param table Void out array [COMPSIZE(target/format/type)] + category SGI_color_table + dlflags notlistable + glxflags client-handcode server-handcode SGI + version 1.0 + glxvendorpriv 4098 + extension + offset 427 + +GetColorTableParameterfvSGI(target, pname, params) + return void + param target ColorTableTargetSGI in value + param pname GetColorTableParameterPNameSGI in value + param params Float32 out array [COMPSIZE(pname)] + category SGI_color_table + dlflags notlistable + version 1.0 + glxflags SGI + glxvendorpriv 4099 + extension + offset 428 + +GetColorTableParameterivSGI(target, pname, params) + return void + param target ColorTableTargetSGI in value + param pname GetColorTableParameterPNameSGI in value + param params Int32 out array [COMPSIZE(pname)] + category SGI_color_table + dlflags notlistable + version 1.0 + glxflags SGI + glxvendorpriv 4100 + extension + offset 429 + +############################################################################### +# +# Extension #15 +# SGIX_pixel_texture commands +# +############################################################################### + +PixelTexGenSGIX(mode) + return void + param mode PixelTexGenModeSGIX in value + category SGIX_pixel_texture + version 1.0 + glxflags SGI + glxropcode 2059 + extension + offset 430 + +############################################################################### +# +# Extension #15 (variant) +# SGIS_pixel_texture commands +# Both SGIS and SGIX forms have extension #15! +# +############################################################################### + +PixelTexGenParameteriSGIS(pname, param) + return void + param pname PixelTexGenParameterNameSGIS in value + param param CheckedInt32 in value + category SGIS_pixel_texture + version 1.0 + extension + glxropcode ? + glxflags ignore + offset 431 + +PixelTexGenParameterivSGIS(pname, params) + return void + param pname PixelTexGenParameterNameSGIS in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category SGIS_pixel_texture + version 1.0 + extension + glxropcode ? + glxflags ignore + offset 432 + +PixelTexGenParameterfSGIS(pname, param) + return void + param pname PixelTexGenParameterNameSGIS in value + param param CheckedFloat32 in value + category SGIS_pixel_texture + version 1.0 + extension + glxropcode ? + glxflags ignore + offset 433 + +PixelTexGenParameterfvSGIS(pname, params) + return void + param pname PixelTexGenParameterNameSGIS in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category SGIS_pixel_texture + version 1.0 + extension + glxropcode ? + glxflags ignore + offset 434 + +GetPixelTexGenParameterivSGIS(pname, params) + return void + param pname PixelTexGenParameterNameSGIS in value + param params CheckedInt32 out array [COMPSIZE(pname)] + dlflags notlistable + category SGIS_pixel_texture + version 1.0 + extension + glxvendorpriv ? + glxflags ignore + offset 435 + +GetPixelTexGenParameterfvSGIS(pname, params) + return void + param pname PixelTexGenParameterNameSGIS in value + param params CheckedFloat32 out array [COMPSIZE(pname)] + dlflags notlistable + category SGIS_pixel_texture + version 1.0 + extension + glxvendorpriv ? + glxflags ignore + offset 436 + +############################################################################### +# +# Extension #16 +# SGIS_texture4D commands +# +############################################################################### + +TexImage4DSGIS(target, level, internalformat, width, height, depth, size4d, border, format, type, pixels) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param size4d SizeI in value + param border CheckedInt32 in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height/depth/size4d)] + category SGIS_texture4D + dlflags handcode + glxflags client-handcode server-handcode SGI + version 1.0 + glxropcode 2057 + extension + offset 437 + +TexSubImage4DSGIS(target, level, xoffset, yoffset, zoffset, woffset, width, height, depth, size4d, format, type, pixels) + return void + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param zoffset CheckedInt32 in value + param woffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param size4d SizeI in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height/depth/size4d)] + category SGIS_texture4D + dlflags handcode + glxflags client-handcode server-handcode SGI + version 1.0 + glxropcode 2058 + extension + offset 438 + +############################################################################### +# +# Extension #17 +# SGI_texture_color_table commands +# +############################################################################### + +# (none) +newcategory: SGI_texture_color_table + +############################################################################### +# +# Extension #18 +# EXT_cmyka commands +# +############################################################################### + +# (none) +newcategory: EXT_cmyka + +############################################################################### +# +# Extension #19 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #20 +# EXT_texture_object commands +# +############################################################################### + +AreTexturesResidentEXT(n, textures, residences) + return Boolean + param n SizeI in value + param textures Texture in array [n] + param residences Boolean out array [n] + category EXT_texture_object + glxflags EXT + glxvendorpriv 11 + dlflags notlistable + version 1.0 + extension + offset 439 + +BindTextureEXT(target, texture) + return void + param target TextureTarget in value + param texture Texture in value + category EXT_texture_object + version 1.0 + glxflags EXT + glxropcode 4117 + extension + alias BindTexture + +DeleteTexturesEXT(n, textures) + return void + param n SizeI in value + param textures Texture in array [n] + category EXT_texture_object + dlflags notlistable + version 1.0 + glxflags EXT + glxvendorpriv 12 + extension + offset 561 + +GenTexturesEXT(n, textures) + return void + param n SizeI in value + param textures Texture out array [n] + category EXT_texture_object + dlflags notlistable + version 1.0 + glxflags EXT + glxvendorpriv 13 + extension + offset 440 + +IsTextureEXT(texture) + return Boolean + param texture Texture in value + category EXT_texture_object + dlflags notlistable + version 1.0 + glxflags EXT + glxvendorpriv 14 + extension + offset 441 + +PrioritizeTexturesEXT(n, textures, priorities) + return void + param n SizeI in value + param textures Texture in array [n] + param priorities ClampedFloat32 in array [n] + category EXT_texture_object + glxflags EXT + version 1.0 + glxropcode 4118 + extension + alias PrioritizeTextures + +############################################################################### +# +# Extension #21 +# SGIS_detail_texture commands +# +############################################################################### + +DetailTexFuncSGIS(target, n, points) + return void + param target TextureTarget in value + param n SizeI in value + param points Float32 in array [n*2] + category SGIS_detail_texture + glxflags SGI + version 1.0 + glxropcode 2051 + extension + offset 442 + +GetDetailTexFuncSGIS(target, points) + return void + param target TextureTarget in value + param points Float32 out array [COMPSIZE(target)] + category SGIS_detail_texture + dlflags notlistable + version 1.0 + glxflags SGI + glxvendorpriv 4096 + extension + offset 443 + +############################################################################### +# +# Extension #22 +# SGIS_sharpen_texture commands +# +############################################################################### + +SharpenTexFuncSGIS(target, n, points) + return void + param target TextureTarget in value + param n SizeI in value + param points Float32 in array [n*2] + category SGIS_sharpen_texture + glxflags SGI + version 1.0 + glxropcode 2052 + extension + offset 444 + +GetSharpenTexFuncSGIS(target, points) + return void + param target TextureTarget in value + param points Float32 out array [COMPSIZE(target)] + category SGIS_sharpen_texture + dlflags notlistable + version 1.0 + glxflags SGI + glxvendorpriv 4097 + extension + offset 445 + +############################################################################### +# +# EXT_packed_pixels commands +# Extension #23 +# +############################################################################### + +# (none) +newcategory: EXT_packed_pixels + +############################################################################### +# +# Extension #24 +# SGIS_texture_lod commands +# +############################################################################### + +# (none) +newcategory: SGIS_texture_lod + +############################################################################### +# +# Extension #25 +# SGIS_multisample commands +# +############################################################################### + +SampleMaskSGIS(value, invert) + return void + param value ClampedFloat32 in value + param invert Boolean in value + category SGIS_multisample + version 1.1 + glxropcode 2048 + glxflags SGI + extension + alias SampleMaskEXT + +SamplePatternSGIS(pattern) + return void + param pattern SamplePatternSGIS in value + category SGIS_multisample + version 1.0 + glxropcode 2049 + glxflags SGI + extension + alias SamplePatternEXT + +############################################################################### +# +# Extension #26 - no specification? +# +############################################################################### + +############################################################################### +# +# Extension #27 +# EXT_rescale_normal commands +# +############################################################################### + +# (none) +newcategory: EXT_rescale_normal + +############################################################################### +# +# Extension #28 - GLX_EXT_visual_info +# Extension #29 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #30 +# EXT_vertex_array commands +# +############################################################################### + +ArrayElementEXT(i) + return void + param i Int32 in value + category EXT_vertex_array + dlflags handcode + glxflags client-handcode server-handcode EXT + version 1.0 + extension + alias ArrayElement + +ColorPointerEXT(size, type, stride, count, pointer) + return void + param size Int32 in value + param type ColorPointerType in value + param stride SizeI in value + param count SizeI in value + param pointer Void in array [COMPSIZE(size/type/stride/count)] retained + category EXT_vertex_array + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.0 + extension + offset 448 + +DrawArraysEXT(mode, first, count) + return void + param mode BeginMode in value + param first Int32 in value + param count SizeI in value + category EXT_vertex_array + dlflags handcode + glxflags client-handcode server-handcode EXT + version 1.0 + glxropcode 4116 + extension + alias DrawArrays + +EdgeFlagPointerEXT(stride, count, pointer) + return void + param stride SizeI in value + param count SizeI in value + param pointer Boolean in array [COMPSIZE(stride/count)] retained + category EXT_vertex_array + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.0 + extension + offset 449 + +GetPointervEXT(pname, params) + return void + param pname GetPointervPName in value + param params VoidPointer out array [1] + category EXT_vertex_array + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.0 + extension + alias GetPointerv + +IndexPointerEXT(type, stride, count, pointer) + return void + param type IndexPointerType in value + param stride SizeI in value + param count SizeI in value + param pointer Void in array [COMPSIZE(type/stride/count)] retained + category EXT_vertex_array + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.0 + extension + offset 450 + +NormalPointerEXT(type, stride, count, pointer) + return void + param type NormalPointerType in value + param stride SizeI in value + param count SizeI in value + param pointer Void in array [COMPSIZE(type/stride/count)] retained + category EXT_vertex_array + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.0 + extension + offset 451 + +TexCoordPointerEXT(size, type, stride, count, pointer) + return void + param size Int32 in value + param type TexCoordPointerType in value + param stride SizeI in value + param count SizeI in value + param pointer Void in array [COMPSIZE(size/type/stride/count)] retained + category EXT_vertex_array + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.0 + extension + offset 452 + +VertexPointerEXT(size, type, stride, count, pointer) + return void + param size Int32 in value + param type VertexPointerType in value + param stride SizeI in value + param count SizeI in value + param pointer Void in array [COMPSIZE(size/type/stride/count)] retained + category EXT_vertex_array + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.0 + extension + offset 453 + +############################################################################### +# +# Extension #31 +# EXT_misc_attribute commands +# +############################################################################### + +# (none) +newcategory: EXT_misc_attribute + +############################################################################### +# +# Extension #32 +# SGIS_generate_mipmap commands +# +############################################################################### + +# (none) +newcategory: SGIS_generate_mipmap + +############################################################################### +# +# Extension #33 +# SGIX_clipmap commands +# +############################################################################### + +# (none) +newcategory: SGIX_clipmap + +############################################################################### +# +# Extension #34 +# SGIX_shadow commands +# +############################################################################### + +# (none) +newcategory: SGIX_shadow + +############################################################################### +# +# Extension #35 +# SGIS_texture_edge_clamp commands +# +############################################################################### + +# (none) +newcategory: SGIS_texture_edge_clamp + +############################################################################### +# +# Extension #36 +# SGIS_texture_border_clamp commands +# +############################################################################### + +# (none) +newcategory: SGIS_texture_border_clamp + +############################################################################### +# +# Extension #37 +# EXT_blend_minmax commands +# +############################################################################### + +BlendEquationEXT(mode) + return void + param mode BlendEquationModeEXT in value + category EXT_blend_minmax + version 1.0 + glxropcode 4097 + glxflags EXT + extension soft + alias BlendEquation + +############################################################################### +# +# Extension #38 +# EXT_blend_subtract commands +# +############################################################################### + +# (none) +newcategory: EXT_blend_subtract + +############################################################################### +# +# Extension #39 +# EXT_blend_logic_op commands +# +############################################################################### + +# (none) +newcategory: EXT_blend_logic_op + +############################################################################### +# +# Extension #40 - GLX_SGI_swap_control +# Extension #41 - GLX_SGI_video_sync +# Extension #42 - GLX_SGI_make_current_read +# Extension #43 - GLX_SGIX_video_source +# Extension #44 - GLX_EXT_visual_rating +# +############################################################################### + +############################################################################### +# +# Extension #45 +# SGIX_interlace commands +# +############################################################################### + +# (none) +newcategory: SGIX_interlace + +############################################################################### +# +# Extension #46 +# SGIX_pixel_tiles commands +# +############################################################################### + +# (none) +newcategory: SGIX_pixel_tiles + +############################################################################### +# +# Extension #47 - GLX_EXT_import_context +# Extension #48 - skipped +# Extension #49 - GLX_SGIX_fbconfig +# Extension #50 - GLX_SGIX_pbuffer +# +############################################################################### + +############################################################################### +# +# Extension #51 +# SGIX_texture_select commands +# +############################################################################### + +# (none) +newcategory: SGIX_texture_select + +############################################################################### +# +# Extension #52 +# SGIX_sprite commands +# +############################################################################### + +SpriteParameterfSGIX(pname, param) + return void + param pname SpriteParameterNameSGIX in value + param param CheckedFloat32 in value + category SGIX_sprite + version 1.0 + glxflags SGI + glxropcode 2060 + extension + offset 454 + +SpriteParameterfvSGIX(pname, params) + return void + param pname SpriteParameterNameSGIX in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category SGIX_sprite + version 1.0 + glxflags SGI + glxropcode 2061 + extension + offset 455 + +SpriteParameteriSGIX(pname, param) + return void + param pname SpriteParameterNameSGIX in value + param param CheckedInt32 in value + category SGIX_sprite + version 1.0 + glxflags SGI + glxropcode 2062 + extension + offset 456 + +SpriteParameterivSGIX(pname, params) + return void + param pname SpriteParameterNameSGIX in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category SGIX_sprite + version 1.0 + glxflags SGI + glxropcode 2063 + extension + offset 457 + +############################################################################### +# +# Extension #53 +# SGIX_texture_multi_buffer commands +# +############################################################################### + +# (none) +newcategory: SGIX_texture_multi_buffer + +############################################################################### +# +# Extension #54 +# EXT_point_parameters / SGIS_point_parameters commands +# +############################################################################### + +PointParameterfEXT(pname, param) + return void + param pname PointParameterNameARB in value + param param CheckedFloat32 in value + category EXT_point_parameters + version 1.0 + glxflags SGI + extension + alias PointParameterfARB + +PointParameterfvEXT(pname, params) + return void + param pname PointParameterNameARB in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category EXT_point_parameters + version 1.0 + glxflags SGI + extension + alias PointParameterfvARB + +PointParameterfSGIS(pname, param) + return void + param pname PointParameterNameARB in value + param param CheckedFloat32 in value + category SGIS_point_parameters + version 1.0 + glxflags SGI + extension + alias PointParameterfARB + +PointParameterfvSGIS(pname, params) + return void + param pname PointParameterNameARB in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category SGIS_point_parameters + version 1.0 + glxflags SGI + extension + alias PointParameterfvARB + +############################################################################### +# +# Extension #55 +# SGIX_instruments commands +# +############################################################################### + +GetInstrumentsSGIX() + return Int32 + dlflags notlistable + category SGIX_instruments + version 1.0 + glxflags SGI + glxvendorpriv 4102 + extension + offset 460 + +InstrumentsBufferSGIX(size, buffer) + return void + param size SizeI in value + param buffer Int32 out array [size] retained + dlflags notlistable + category SGIX_instruments + version 1.0 + glxflags SGI + glxvendorpriv 4103 + extension + offset 461 + +PollInstrumentsSGIX(marker_p) + return Int32 + param marker_p Int32 out array [1] + dlflags notlistable + category SGIX_instruments + version 1.0 + glxflags SGI + glxvendorpriv 4104 + extension + offset 462 + +ReadInstrumentsSGIX(marker) + return void + param marker Int32 in value + category SGIX_instruments + version 1.0 + glxflags SGI + glxropcode 2077 + extension + offset 463 + +StartInstrumentsSGIX() + return void + category SGIX_instruments + version 1.0 + glxflags SGI + glxropcode 2069 + extension + offset 464 + +StopInstrumentsSGIX(marker) + return void + param marker Int32 in value + category SGIX_instruments + version 1.0 + glxflags SGI + glxropcode 2070 + extension + offset 465 + +############################################################################### +# +# Extension #56 +# SGIX_texture_scale_bias commands +# +############################################################################### + +# (none) +newcategory: SGIX_texture_scale_bias + +############################################################################### +# +# Extension #57 +# SGIX_framezoom commands +# +############################################################################### + +FrameZoomSGIX(factor) + return void + param factor CheckedInt32 in value + category SGIX_framezoom + version 1.0 + glxflags SGI + glxropcode 2072 + extension + offset 466 + +############################################################################### +# +# Extension #58 +# SGIX_tag_sample_buffer commands +# +############################################################################### + +TagSampleBufferSGIX() + return void + category SGIX_tag_sample_buffer + version 1.0 + glxropcode 2050 + glxflags SGI + extension + offset 467 + +############################################################################### +# +# Extension #59 +# SGIX_polynomial_ffd commands +# +############################################################################### + +DeformationMap3dSGIX(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, w1, w2, wstride, worder, points) + return void + param target FfdTargetSGIX in value + param u1 CoordD in value + param u2 CoordD in value + param ustride Int32 in value + param uorder CheckedInt32 in value + param v1 CoordD in value + param v2 CoordD in value + param vstride Int32 in value + param vorder CheckedInt32 in value + param w1 CoordD in value + param w2 CoordD in value + param wstride Int32 in value + param worder CheckedInt32 in value + param points CoordD in array [COMPSIZE(target/ustride/uorder/vstride/vorder/wstride/worder)] + dlflags handcode + category SGIX_polynomial_ffd + version 1.0 + glxflags SGI ignore + glxropcode 2073 + extension + offset ? + +DeformationMap3fSGIX(target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, w1, w2, wstride, worder, points) + return void + param target FfdTargetSGIX in value + param u1 CoordF in value + param u2 CoordF in value + param ustride Int32 in value + param uorder CheckedInt32 in value + param v1 CoordF in value + param v2 CoordF in value + param vstride Int32 in value + param vorder CheckedInt32 in value + param w1 CoordF in value + param w2 CoordF in value + param wstride Int32 in value + param worder CheckedInt32 in value + param points CoordF in array [COMPSIZE(target/ustride/uorder/vstride/vorder/wstride/worder)] + category SGIX_polynomial_ffd + dlflags handcode + version 1.0 + glxflags SGI ignore + glxropcode 2074 + extension + offset ? + +DeformSGIX(mask) + return void + param mask FfdMaskSGIX in value + category SGIX_polynomial_ffd + version 1.0 + glxflags SGI ignore + glxropcode 2075 + extension + offset ? + +LoadIdentityDeformationMapSGIX(mask) + return void + param mask FfdMaskSGIX in value + category SGIX_polynomial_ffd + version 1.0 + glxflags SGI ignore + glxropcode 2076 + extension + offset ? + +############################################################################### +# +# Extension #60 +# SGIX_reference_plane commands +# +############################################################################### + +ReferencePlaneSGIX(equation) + return void + param equation Float64 in array [4] + category SGIX_reference_plane + version 1.0 + glxflags SGI + glxropcode 2071 + extension + offset 468 + +############################################################################### +# +# Extension #61 +# SGIX_flush_raster commands +# +############################################################################### + +FlushRasterSGIX() + return void + category SGIX_flush_raster + version 1.0 + dlflags notlistable + glxflags SGI + glxvendorpriv 4105 + extension + offset 469 + +############################################################################### +# +# Extension #62 - GLX_SGIX_cushion +# +############################################################################### + +############################################################################### +# +# Extension #63 +# SGIX_depth_texture commands +# +############################################################################### + +# (none) +newcategory: SGIX_depth_texture + +############################################################################### +# +# Extension #64 +# SGIS_fog_function commands +# +############################################################################### + +FogFuncSGIS(n, points) + return void + param n SizeI in value + param points Float32 in array [n*2] + category SGIS_fog_function + version 1.1 + glxflags SGI + glxropcode 2067 + extension + offset + +# Need to insert GLX information +GetFogFuncSGIS(points) + return void + param points Float32 out array [COMPSIZE()] + category SGIS_fog_function + version 1.1 + dlflags notlistable + glxflags ignore + extension + offset + +############################################################################### +# +# Extension #65 +# SGIX_fog_offset commands +# +############################################################################### + +# (none) +newcategory: SGIX_fog_offset + +############################################################################### +# +# Extension #66 +# HP_image_transform commands +# +############################################################################### + +ImageTransformParameteriHP(target, pname, param) + return void + param target ImageTransformTargetHP in value + param pname ImageTransformPNameHP in value + param param Int32 in value + category HP_image_transform + version 1.1 + glxropcode ? + offset ? + +ImageTransformParameterfHP(target, pname, param) + return void + param target ImageTransformTargetHP in value + param pname ImageTransformPNameHP in value + param param Float32 in value + category HP_image_transform + version 1.1 + glxropcode ? + offset ? + +ImageTransformParameterivHP(target, pname, params) + return void + param target ImageTransformTargetHP in value + param pname ImageTransformPNameHP in value + param params Int32 in array [COMPSIZE(pname)] + category HP_image_transform + version 1.1 + glxropcode ? + offset ? + +ImageTransformParameterfvHP(target, pname, params) + return void + param target ImageTransformTargetHP in value + param pname ImageTransformPNameHP in value + param params Float32 in array [COMPSIZE(pname)] + category HP_image_transform + version 1.1 + glxropcode ? + offset ? + +GetImageTransformParameterivHP(target, pname, params) + return void + param target ImageTransformTargetHP in value + param pname ImageTransformPNameHP in value + param params Int32 out array [COMPSIZE(pname)] + dlflags notlistable + category HP_image_transform + version 1.1 + glxropcode ? + offset ? + +GetImageTransformParameterfvHP(target, pname, params) + return void + param target ImageTransformTargetHP in value + param pname ImageTransformPNameHP in value + param params Float32 out array [COMPSIZE(pname)] + category HP_image_transform + version 1.1 + glxropcode ? + offset ? + +############################################################################### +# +# Extension #67 +# HP_convolution_border_modes commands +# +############################################################################### + +# (none) +newcategory: HP_convolution_border_modes + +############################################################################### +# +# Extension #68 +# INGR_palette_buffer commands +# +############################################################################### + +#@ (Intergraph hasn't provided a spec) + +############################################################################### +# +# Extension #69 +# SGIX_texture_add_env commands +# +############################################################################### + +# (none) +newcategory: SGIX_texture_add_env + +############################################################################### +# +# Extension #70 - skipped +# Extension #71 - skipped +# Extension #72 - skipped +# Extension #73 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #74 +# EXT_color_subtable commands +# +# This was probably never actually shipped as an EXT - just written up as a +# reference for OpenGL 1.2 ARB_imaging. +# +############################################################################### + +ColorSubTableEXT(target, start, count, format, type, data) + return void + param target ColorTableTarget in value + param start SizeI in value + param count SizeI in value + param format PixelFormat in value + param type PixelType in value + param data Void in array [COMPSIZE(format/type/count)] + category EXT_color_subtable + version 1.2 + alias ColorSubTable + +CopyColorSubTableEXT(target, start, x, y, width) + return void + param target ColorTableTarget in value + param start SizeI in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + category EXT_color_subtable + version 1.2 + alias CopyColorSubTable + +############################################################################### +# +# Extension #75 - GLU_EXT_object_space_tess +# +############################################################################### + +############################################################################### +# +# Extension #76 +# PGI_vertex_hints commands +# +############################################################################### + +# (none) +newcategory: PGI_vertex_hints + +############################################################################### +# +# Extension #77 +# PGI_misc_hints commands +# +############################################################################### + +HintPGI(target, mode) + return void + param target HintTargetPGI in value + param mode Int32 in value + category PGI_misc_hints + version 1.1 + offset 544 + +############################################################################### +# +# Extension #78 +# EXT_paletted_texture commands +# +############################################################################### + +ColorTableEXT(target, internalFormat, width, format, type, table) + return void + param target ColorTableTarget in value + param internalFormat PixelInternalFormat in value + param width SizeI in value + param format PixelFormat in value + param type PixelType in value + param table Void in array [COMPSIZE(format/type/width)] + category EXT_paletted_texture + version 1.1 + alias ColorTable + +GetColorTableEXT(target, format, type, data) + return void + param target ColorTableTarget in value + param format PixelFormat in value + param type PixelType in value + param data Void out array [COMPSIZE(target/format/type)] + category EXT_paletted_texture + version 1.1 + offset 550 + +GetColorTableParameterivEXT(target, pname, params) + return void + param target ColorTableTarget in value + param pname GetColorTableParameterPName in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_paletted_texture + version 1.1 + offset 551 + +GetColorTableParameterfvEXT(target, pname, params) + return void + param target ColorTableTarget in value + param pname GetColorTableParameterPName in value + param params Float32 out array [COMPSIZE(pname)] + category EXT_paletted_texture + version 1.1 + offset 552 + +############################################################################### +# +# Extension #79 +# EXT_clip_volume_hint commands +# +############################################################################### + +# (none) +newcategory: EXT_clip_volume_hint + +############################################################################### +# +# Extension #80 +# SGIX_list_priority commands +# +############################################################################### + +# @@@ Needs vendorpriv opcodes assigned +GetListParameterfvSGIX(list, pname, params) + return void + param list List in value + param pname ListParameterName in value + param params CheckedFloat32 out array [COMPSIZE(pname)] + dlflags notlistable + glxflags ignore + category SGIX_list_priority + version 1.0 + glxvendorpriv ? + extension + offset 470 + +# @@@ Needs vendorpriv opcodes assigned +GetListParameterivSGIX(list, pname, params) + return void + param list List in value + param pname ListParameterName in value + param params CheckedInt32 out array [COMPSIZE(pname)] + dlflags notlistable + glxflags ignore + category SGIX_list_priority + version 1.0 + glxvendorpriv ? + extension + offset 471 + +ListParameterfSGIX(list, pname, param) + return void + param list List in value + param pname ListParameterName in value + param param CheckedFloat32 in value + dlflags notlistable + glxflags ignore + category SGIX_list_priority + version 1.0 + glxropcode 2078 + extension + offset 472 + +ListParameterfvSGIX(list, pname, params) + return void + param list List in value + param pname ListParameterName in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + dlflags notlistable + glxflags ignore + category SGIX_list_priority + version 1.0 + glxropcode 2079 + extension + offset 473 + +ListParameteriSGIX(list, pname, param) + return void + param list List in value + param pname ListParameterName in value + param param CheckedInt32 in value + dlflags notlistable + glxflags ignore + category SGIX_list_priority + version 1.0 + glxropcode 2080 + extension + offset 474 + +ListParameterivSGIX(list, pname, params) + return void + param list List in value + param pname ListParameterName in value + param params CheckedInt32 in array [COMPSIZE(pname)] + dlflags notlistable + glxflags ignore + category SGIX_list_priority + version 1.0 + glxropcode 2081 + extension + offset 475 + +############################################################################### +# +# Extension #81 +# SGIX_ir_instrument1 commands +# +############################################################################### + +# (none) +newcategory: SGIX_ir_instrument1 + +############################################################################### +# +# Extension #82 +# SGIX_calligraphic_fragment commands +# +############################################################################### + +# (none) +newcategory: SGIX_calligraphic_fragment + +############################################################################### +# +# Extension #83 - GLX_SGIX_video_resize +# +############################################################################### + +############################################################################### +# +# Extension #84 +# SGIX_texture_lod_bias commands +# +############################################################################### + +# (none) +newcategory: SGIX_texture_lod_bias + +############################################################################### +# +# Extension #85 - skipped +# Extension #86 - GLX_SGIX_dmbuffer +# Extension #87 - skipped +# Extension #88 - skipped +# Extension #89 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #90 +# SGIX_shadow_ambient commands +# +############################################################################### + +# (none) +newcategory: SGIX_shadow_ambient + +############################################################################### +# +# Extension #91 - GLX_SGIX_swap_group +# Extension #92 - GLX_SGIX_swap_barrier +# +############################################################################### + +############################################################################### +# +# Extension #93 +# EXT_index_texture commands +# +############################################################################### + +# (none) +newcategory: EXT_index_texture + +############################################################################### +# +# Extension #94 +# EXT_index_material commands +# +############################################################################### + +IndexMaterialEXT(face, mode) + return void + param face MaterialFace in value + param mode IndexMaterialParameterEXT in value + category EXT_index_material + version 1.1 + extension soft + glxflags ignore + offset 538 + +############################################################################### +# +# Extension #95 +# EXT_index_func commands +# +############################################################################### + +IndexFuncEXT(func, ref) + return void + param func IndexFunctionEXT in value + param ref ClampedFloat32 in value + category EXT_index_func + version 1.1 + extension soft + glxflags ignore + offset 539 + +############################################################################### +# +# Extension #96 +# EXT_index_array_formats commands +# +############################################################################### + +# (none) +newcategory: EXT_index_array_formats + +############################################################################### +# +# Extension #97 +# EXT_compiled_vertex_array commands +# +############################################################################### + +LockArraysEXT(first, count) + return void + param first Int32 in value + param count SizeI in value + category EXT_compiled_vertex_array + version 1.1 + dlflags notlistable + extension soft + glxflags ignore + offset 540 + +UnlockArraysEXT() + return void + category EXT_compiled_vertex_array + version 1.1 + dlflags notlistable + extension soft + glxflags ignore + offset 541 + +############################################################################### +# +# Extension #98 +# EXT_cull_vertex commands +# +############################################################################### + +CullParameterdvEXT(pname, params) + return void + param pname CullParameterEXT in value + param params Float64 out array [4] + category EXT_cull_vertex + version 1.1 + dlflags notlistable + extension soft + glxflags ignore + offset 542 + +CullParameterfvEXT(pname, params) + return void + param pname CullParameterEXT in value + param params Float32 out array [4] + category EXT_cull_vertex + version 1.1 + dlflags notlistable + extension soft + glxflags ignore + offset 543 + +############################################################################### +# +# Extension #99 - skipped +# Extension #100 - GLU_EXT_nurbs_tessellator +# +############################################################################### + +############################################################################### +# +# Extension #101 +# SGIX_ycrcb commands +# +############################################################################### + +# (none) +newcategory: SGIX_ycrcb + +############################################################################### +# +# Extension #102 +# SGIX_fragment_lighting commands +# +############################################################################### + +FragmentColorMaterialSGIX(face, mode) + return void + param face MaterialFace in value + param mode MaterialParameter in value + category SGIX_fragment_lighting + glxflags ignore + version 1.0 + extension + offset 476 + +FragmentLightfSGIX(light, pname, param) + return void + param light FragmentLightNameSGIX in value + param pname FragmentLightParameterSGIX in value + param param CheckedFloat32 in value + category SGIX_fragment_lighting + glxflags ignore + version 1.0 + extension + offset 477 + +FragmentLightfvSGIX(light, pname, params) + return void + param light FragmentLightNameSGIX in value + param pname FragmentLightParameterSGIX in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category SGIX_fragment_lighting + glxflags ignore + version 1.0 + extension + offset 478 + +FragmentLightiSGIX(light, pname, param) + return void + param light FragmentLightNameSGIX in value + param pname FragmentLightParameterSGIX in value + param param CheckedInt32 in value + category SGIX_fragment_lighting + glxflags ignore + version 1.0 + extension + offset 479 + +FragmentLightivSGIX(light, pname, params) + return void + param light FragmentLightNameSGIX in value + param pname FragmentLightParameterSGIX in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category SGIX_fragment_lighting + glxflags ignore + version 1.0 + extension + offset 480 + +FragmentLightModelfSGIX(pname, param) + return void + param pname FragmentLightModelParameterSGIX in value + param param CheckedFloat32 in value + category SGIX_fragment_lighting + glxflags ignore + version 1.0 + extension + offset 481 + +FragmentLightModelfvSGIX(pname, params) + return void + param pname FragmentLightModelParameterSGIX in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category SGIX_fragment_lighting + glxflags ignore + version 1.0 + extension + offset 482 + +FragmentLightModeliSGIX(pname, param) + return void + param pname FragmentLightModelParameterSGIX in value + param param CheckedInt32 in value + category SGIX_fragment_lighting + glxflags ignore + version 1.0 + extension + offset 483 + +FragmentLightModelivSGIX(pname, params) + return void + param pname FragmentLightModelParameterSGIX in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category SGIX_fragment_lighting + glxflags ignore + version 1.0 + extension + offset 484 + +FragmentMaterialfSGIX(face, pname, param) + return void + param face MaterialFace in value + param pname MaterialParameter in value + param param CheckedFloat32 in value + category SGIX_fragment_lighting + glxflags ignore + version 1.0 + extension + offset 485 + +FragmentMaterialfvSGIX(face, pname, params) + return void + param face MaterialFace in value + param pname MaterialParameter in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category SGIX_fragment_lighting + glxflags ignore + version 1.0 + extension + offset 486 + +FragmentMaterialiSGIX(face, pname, param) + return void + param face MaterialFace in value + param pname MaterialParameter in value + param param CheckedInt32 in value + category SGIX_fragment_lighting + glxflags ignore + version 1.0 + extension + offset 487 + +FragmentMaterialivSGIX(face, pname, params) + return void + param face MaterialFace in value + param pname MaterialParameter in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category SGIX_fragment_lighting + glxflags ignore + version 1.0 + extension + offset 488 + +GetFragmentLightfvSGIX(light, pname, params) + return void + param light FragmentLightNameSGIX in value + param pname FragmentLightParameterSGIX in value + param params Float32 out array [COMPSIZE(pname)] + category SGIX_fragment_lighting + dlflags notlistable + glxflags ignore + version 1.0 + extension + offset 489 + +GetFragmentLightivSGIX(light, pname, params) + return void + param light FragmentLightNameSGIX in value + param pname FragmentLightParameterSGIX in value + param params Int32 out array [COMPSIZE(pname)] + category SGIX_fragment_lighting + dlflags notlistable + glxflags ignore + version 1.0 + extension + offset 490 + +GetFragmentMaterialfvSGIX(face, pname, params) + return void + param face MaterialFace in value + param pname MaterialParameter in value + param params Float32 out array [COMPSIZE(pname)] + category SGIX_fragment_lighting + dlflags notlistable + glxflags ignore + version 1.0 + extension + offset 491 + +GetFragmentMaterialivSGIX(face, pname, params) + return void + param face MaterialFace in value + param pname MaterialParameter in value + param params Int32 out array [COMPSIZE(pname)] + category SGIX_fragment_lighting + dlflags notlistable + glxflags ignore + version 1.0 + extension + offset 492 + +LightEnviSGIX(pname, param) + return void + param pname LightEnvParameterSGIX in value + param param CheckedInt32 in value + category SGIX_fragment_lighting + glxflags ignore + version 1.0 + extension + offset 493 + +############################################################################### +# +# Extension #103 - skipped +# Extension #104 - skipped +# Extension #105 - skipped +# Extension #106 - skipped +# Extension #107 - skipped +# Extension #108 - skipped +# Extension #109 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #110 +# IBM_rasterpos_clip commands +# +############################################################################### + +# (none) +newcategory: IBM_rasterpos_clip + +############################################################################### +# +# Extension #111 +# HP_texture_lighting commands +# +############################################################################### + +# (none) +newcategory: HP_texture_lighting + +############################################################################### +# +# Extension #112 +# EXT_draw_range_elements commands +# +############################################################################### + +# Spec entries to be written +DrawRangeElementsEXT(mode, start, end, count, type, indices) + return void + param mode BeginMode in value + param start UInt32 in value + param end UInt32 in value + param count SizeI in value + param type DrawElementsType in value + param indices Void in array [COMPSIZE(count/type)] + category EXT_draw_range_elements + dlflags handcode + glxflags client-handcode client-intercept server-handcode + version 1.1 + alias DrawRangeElements + +############################################################################### +# +# Extension #113 +# WIN_phong_shading commands +# +############################################################################### + +# (none) +newcategory: WIN_phong_shading + +############################################################################### +# +# Extension #114 +# WIN_specular_fog commands +# +############################################################################### + +# (none) +newcategory: WIN_specular_fog + +############################################################################### +# +# Extension #115 - skipped +# Extension #116 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #117 +# EXT_light_texture commands +# +############################################################################### + +# Spec entries to be written +ApplyTextureEXT(mode) + return void + param mode LightTextureModeEXT in value + category EXT_light_texture + version 1.1 + glxropcode ? + offset ? + +TextureLightEXT(pname) + return void + param pname LightTexturePNameEXT in value + category EXT_light_texture + version 1.1 + glxropcode ? + offset ? + +TextureMaterialEXT(face, mode) + return void + param face MaterialFace in value + param mode MaterialParameter in value + category EXT_light_texture + version 1.1 + glxropcode ? + offset ? + +############################################################################### +# +# Extension #118 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #119 +# SGIX_blend_alpha_minmax commands +# +############################################################################### + +# (none) +newcategory: SGIX_blend_alpha_minmax + +############################################################################### +# +# Extension #120 - skipped +# Extension #121 - skipped +# Extension #122 - skipped +# Extension #123 - skipped +# Extension #124 - skipped +# Extension #125 - skipped +# Extension #126 - skipped +# Extension #127 - skipped +# Extension #128 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #129 +# EXT_bgra commands +# +############################################################################### + +# (none) +newcategory: EXT_bgra + +############################################################################### +# +# Extension #130 - skipped +# Extension #131 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #132 +# SGIX_async commands +# +############################################################################### + +AsyncMarkerSGIX(marker) + return void + param marker UInt32 in value + category SGIX_async + version 1.0 + glxflags ignore + extension + offset ? + +FinishAsyncSGIX(markerp) + return Int32 + param markerp UInt32 out array [1] + category SGIX_async + version 1.0 + dlflags notlistable + glxflags ignore + extension + offset ? + +PollAsyncSGIX(markerp) + return Int32 + param markerp UInt32 out array [1] + category SGIX_async + version 1.0 + dlflags notlistable + glxflags ignore + extension + offset ? + +GenAsyncMarkersSGIX(range) + return UInt32 + param range SizeI in value + category SGIX_async + version 1.0 + dlflags notlistable + glxflags ignore + extension + offset ? + +DeleteAsyncMarkersSGIX(marker, range) + return void + param marker UInt32 in value + param range SizeI in value + category SGIX_async + version 1.0 + dlflags notlistable + glxflags ignore + extension + offset ? + +IsAsyncMarkerSGIX(marker) + return Boolean + param marker UInt32 in value + category SGIX_async + version 1.0 + dlflags notlistable + glxflags ignore + extension + offset ? + +############################################################################### +# +# Extension #133 +# SGIX_async_pixel commands +# +############################################################################### + +# (none) +newcategory: SGIX_async_pixel + +############################################################################### +# +# Extension #134 +# SGIX_async_histogram commands +# +############################################################################### + +# (none) +newcategory: SGIX_async_histogram + +############################################################################### +# +# Extension #135 - skipped (INTEL_texture_scissor was never implemented) +# +############################################################################### + +############################################################################### +# +# Extension #136 +# INTEL_parallel_arrays commands +# +############################################################################### + +VertexPointervINTEL(size, type, pointer) + return void + param size Int32 in value + param type VertexPointerType in value + param pointer VoidPointer in array [4] retained + category INTEL_parallel_arrays + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.1 + offset ? + +NormalPointervINTEL(type, pointer) + return void + param type NormalPointerType in value + param pointer VoidPointer in array [4] retained + category INTEL_parallel_arrays + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.1 + offset ? + +ColorPointervINTEL(size, type, pointer) + return void + param size Int32 in value + param type VertexPointerType in value + param pointer VoidPointer in array [4] retained + category INTEL_parallel_arrays + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.1 + offset ? + +TexCoordPointervINTEL(size, type, pointer) + return void + param size Int32 in value + param type VertexPointerType in value + param pointer VoidPointer in array [4] retained + category INTEL_parallel_arrays + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.1 + offset ? + + +############################################################################### +# +# Extension #137 +# HP_occlusion_test commands +# +############################################################################### + +# (none) +newcategory: HP_occlusion_test + +############################################################################### +# +# Extension #138 +# EXT_pixel_transform commands +# +############################################################################### + +PixelTransformParameteriEXT(target, pname, param) + return void + param target PixelTransformTargetEXT in value + param pname PixelTransformPNameEXT in value + param param Int32 in value + category EXT_pixel_transform + version 1.1 + glxropcode ? + offset ? + +PixelTransformParameterfEXT(target, pname, param) + return void + param target PixelTransformTargetEXT in value + param pname PixelTransformPNameEXT in value + param param Float32 in value + category EXT_pixel_transform + version 1.1 + glxropcode ? + offset ? + +PixelTransformParameterivEXT(target, pname, params) + return void + param target PixelTransformTargetEXT in value + param pname PixelTransformPNameEXT in value + param params Int32 in array [1] + category EXT_pixel_transform + version 1.1 + glxropcode ? + offset ? + +PixelTransformParameterfvEXT(target, pname, params) + return void + param target PixelTransformTargetEXT in value + param pname PixelTransformPNameEXT in value + param params Float32 in array [1] + category EXT_pixel_transform + version 1.1 + glxropcode ? + offset ? + +############################################################################### +# +# Extension #139 +# EXT_pixel_transform_color_table commands +# +############################################################################### + +# (none) +newcategory: EXT_pixel_transform_color_table + +############################################################################### +# +# Extension #140 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #141 +# EXT_shared_texture_palette commands +# +############################################################################### + +# (none) +newcategory: EXT_shared_texture_palette + +############################################################################### +# +# Extension #142 - GLX_SGIS_blended_overlay +# Extension #143 - GLX_SGIS_shared_multisample +# +############################################################################### + +############################################################################### +# +# Extension #144 +# EXT_separate_specular_color commands +# +############################################################################### + +# (none) +newcategory: EXT_separate_specular_color + +############################################################################### +# +# Extension #145 +# EXT_secondary_color commands +# +############################################################################### + +SecondaryColor3bEXT(red, green, blue) + return void + param red ColorB in value + param green ColorB in value + param blue ColorB in value + category EXT_secondary_color + vectorequiv SecondaryColor3bvEXT + version 1.1 + alias SecondaryColor3b + +SecondaryColor3bvEXT(v) + return void + param v ColorB in array [3] + category EXT_secondary_color + version 1.1 + glxropcode 4126 + alias SecondaryColor3bv + +SecondaryColor3dEXT(red, green, blue) + return void + param red ColorD in value + param green ColorD in value + param blue ColorD in value + category EXT_secondary_color + vectorequiv SecondaryColor3dvEXT + version 1.1 + alias SecondaryColor3d + +SecondaryColor3dvEXT(v) + return void + param v ColorD in array [3] + category EXT_secondary_color + version 1.1 + glxropcode 4130 + alias SecondaryColor3dv + +SecondaryColor3fEXT(red, green, blue) + return void + param red ColorF in value + param green ColorF in value + param blue ColorF in value + category EXT_secondary_color + vectorequiv SecondaryColor3fvEXT + version 1.1 + alias SecondaryColor3f + +SecondaryColor3fvEXT(v) + return void + param v ColorF in array [3] + category EXT_secondary_color + version 1.1 + glxropcode 4129 + alias SecondaryColor3fv + +SecondaryColor3iEXT(red, green, blue) + return void + param red ColorI in value + param green ColorI in value + param blue ColorI in value + category EXT_secondary_color + vectorequiv SecondaryColor3ivEXT + version 1.1 + alias SecondaryColor3i + +SecondaryColor3ivEXT(v) + return void + param v ColorI in array [3] + category EXT_secondary_color + version 1.1 + glxropcode 4128 + offset 568 + alias SecondaryColor3iv + +SecondaryColor3sEXT(red, green, blue) + return void + param red ColorS in value + param green ColorS in value + param blue ColorS in value + category EXT_secondary_color + vectorequiv SecondaryColor3svEXT + version 1.1 + alias SecondaryColor3s + +SecondaryColor3svEXT(v) + return void + param v ColorS in array [3] + category EXT_secondary_color + version 1.1 + glxropcode 4127 + alias SecondaryColor3sv + +SecondaryColor3ubEXT(red, green, blue) + return void + param red ColorUB in value + param green ColorUB in value + param blue ColorUB in value + category EXT_secondary_color + vectorequiv SecondaryColor3ubvEXT + version 1.1 + alias SecondaryColor3ub + +SecondaryColor3ubvEXT(v) + return void + param v ColorUB in array [3] + category EXT_secondary_color + version 1.1 + glxropcode 4131 + alias SecondaryColor3ubv + +SecondaryColor3uiEXT(red, green, blue) + return void + param red ColorUI in value + param green ColorUI in value + param blue ColorUI in value + category EXT_secondary_color + vectorequiv SecondaryColor3uivEXT + version 1.1 + alias SecondaryColor3ui + +SecondaryColor3uivEXT(v) + return void + param v ColorUI in array [3] + category EXT_secondary_color + version 1.1 + glxropcode 4133 + alias SecondaryColor3uiv + +SecondaryColor3usEXT(red, green, blue) + return void + param red ColorUS in value + param green ColorUS in value + param blue ColorUS in value + category EXT_secondary_color + vectorequiv SecondaryColor3usvEXT + version 1.1 + alias SecondaryColor3us + +SecondaryColor3usvEXT(v) + return void + param v ColorUS in array [3] + category EXT_secondary_color + version 1.1 + glxropcode 4132 + alias SecondaryColor3usv + +SecondaryColorPointerEXT(size, type, stride, pointer) + return void + param size Int32 in value + param type ColorPointerType in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(size/type/stride)] retained + category EXT_secondary_color + dlflags notlistable + glxflags client-handcode server-handcode EXT + version 1.1 + extension + alias SecondaryColorPointer + +############################################################################### +# +# Extension #146 +# EXT_texture_env commands +# +############################################################################### + +# Dead extension - never implemented (removed from registry!) +# (none) +# newcategory: EXT_texture_env + +############################################################################### +# +# Extension #147 +# EXT_texture_perturb_normal commands +# +############################################################################### + +TextureNormalEXT(mode) + return void + param mode TextureNormalModeEXT in value + category EXT_texture_perturb_normal + version 1.1 + glxropcode ? + offset ? + +############################################################################### +# +# Extension #148 +# EXT_multi_draw_arrays commands +# +############################################################################### + +# first and count are really 'in' +MultiDrawArraysEXT(mode, first, count, primcount) + return void + param mode BeginMode in value + param first Int32 out array [COMPSIZE(primcount)] + param count SizeI out array [COMPSIZE(primcount)] + param primcount SizeI in value + category EXT_multi_draw_arrays + version 1.1 + glxropcode ? + alias MultiDrawArrays + +MultiDrawElementsEXT(mode, count, type, indices, primcount) + return void + param mode BeginMode in value + param count SizeI in array [COMPSIZE(primcount)] + param type DrawElementsType in value + param indices VoidPointer in array [COMPSIZE(primcount)] + param primcount SizeI in value + category EXT_multi_draw_arrays + version 1.1 + glxropcode ? + alias MultiDrawElements + +############################################################################### +# +# Extension #149 +# EXT_fog_coord commands +# +############################################################################### + +FogCoordfEXT(coord) + return void + param coord CoordF in value + category EXT_fog_coord + vectorequiv FogCoordfvEXT + version 1.1 + alias FogCoordf + +FogCoordfvEXT(coord) + return void + param coord CoordF in array [1] + category EXT_fog_coord + version 1.1 + glxropcode 4124 + alias FogCoordfv + +FogCoorddEXT(coord) + return void + param coord CoordD in value + category EXT_fog_coord + vectorequiv FogCoorddvEXT + version 1.1 + alias FogCoordd + +FogCoorddvEXT(coord) + return void + param coord CoordD in array [1] + category EXT_fog_coord + version 1.1 + glxropcode 4125 + alias FogCoorddv + +FogCoordPointerEXT(type, stride, pointer) + return void + param type FogPointerTypeEXT in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(type/stride)] retained + category EXT_fog_coord + dlflags notlistable + version 1.1 + glxflags client-handcode server-handcode EXT + alias FogCoordPointer + +############################################################################### +# +# Extension #150 - skipped +# Extension #151 - skipped +# Extension #152 - skipped +# Extension #153 - skipped +# Extension #154 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #155 +# REND_screen_coordinates commands +# +############################################################################### + +# (none) +newcategory: REND_screen_coordinates + +############################################################################### +# +# Extension #156 +# EXT_coordinate_frame commands +# +############################################################################### + +Tangent3bEXT(tx, ty, tz) + return void + param tx Int8 in value + param ty Int8 in value + param tz Int8 in value + category EXT_coordinate_frame + vectorequiv Tangent3bvEXT + version 1.1 + offset ? + +Tangent3bvEXT(v) + return void + param v Int8 in array [3] + category EXT_coordinate_frame + version 1.1 + glxropcode ? + offset ? + +Tangent3dEXT(tx, ty, tz) + return void + param tx CoordD in value + param ty CoordD in value + param tz CoordD in value + category EXT_coordinate_frame + vectorequiv Tangent3dvEXT + version 1.1 + offset ? + +Tangent3dvEXT(v) + return void + param v CoordD in array [3] + category EXT_coordinate_frame + version 1.1 + glxropcode ? + offset ? + +Tangent3fEXT(tx, ty, tz) + return void + param tx CoordF in value + param ty CoordF in value + param tz CoordF in value + category EXT_coordinate_frame + vectorequiv Tangent3fvEXT + version 1.1 + offset ? + +Tangent3fvEXT(v) + return void + param v CoordF in array [3] + category EXT_coordinate_frame + version 1.1 + glxropcode ? + offset ? + +Tangent3iEXT(tx, ty, tz) + return void + param tx Int32 in value + param ty Int32 in value + param tz Int32 in value + category EXT_coordinate_frame + vectorequiv Tangent3ivEXT + version 1.1 + offset ? + +Tangent3ivEXT(v) + return void + param v Int32 in array [3] + category EXT_coordinate_frame + version 1.1 + glxropcode ? + offset ? + +Tangent3sEXT(tx, ty, tz) + return void + param tx Int16 in value + param ty Int16 in value + param tz Int16 in value + category EXT_coordinate_frame + vectorequiv Tangent3svEXT + version 1.1 + offset ? + +Tangent3svEXT(v) + return void + param v Int16 in array [3] + category EXT_coordinate_frame + version 1.1 + glxropcode ? + offset ? + +Binormal3bEXT(bx, by, bz) + return void + param bx Int8 in value + param by Int8 in value + param bz Int8 in value + category EXT_coordinate_frame + vectorequiv Binormal3bvEXT + version 1.1 + offset ? + +Binormal3bvEXT(v) + return void + param v Int8 in array [3] + category EXT_coordinate_frame + version 1.1 + glxropcode ? + offset ? + +Binormal3dEXT(bx, by, bz) + return void + param bx CoordD in value + param by CoordD in value + param bz CoordD in value + category EXT_coordinate_frame + vectorequiv Binormal3dvEXT + version 1.1 + offset ? + +Binormal3dvEXT(v) + return void + param v CoordD in array [3] + category EXT_coordinate_frame + version 1.1 + glxropcode ? + offset ? + +Binormal3fEXT(bx, by, bz) + return void + param bx CoordF in value + param by CoordF in value + param bz CoordF in value + category EXT_coordinate_frame + vectorequiv Binormal3fvEXT + version 1.1 + offset ? + +Binormal3fvEXT(v) + return void + param v CoordF in array [3] + category EXT_coordinate_frame + version 1.1 + glxropcode ? + offset ? + +Binormal3iEXT(bx, by, bz) + return void + param bx Int32 in value + param by Int32 in value + param bz Int32 in value + category EXT_coordinate_frame + vectorequiv Binormal3ivEXT + version 1.1 + offset ? + +Binormal3ivEXT(v) + return void + param v Int32 in array [3] + category EXT_coordinate_frame + version 1.1 + glxropcode ? + offset ? + +Binormal3sEXT(bx, by, bz) + return void + param bx Int16 in value + param by Int16 in value + param bz Int16 in value + category EXT_coordinate_frame + vectorequiv Binormal3svEXT + version 1.1 + offset ? + +Binormal3svEXT(v) + return void + param v Int16 in array [3] + category EXT_coordinate_frame + version 1.1 + glxropcode ? + offset ? + +TangentPointerEXT(type, stride, pointer) + return void + param type TangentPointerTypeEXT in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(type/stride)] retained + category EXT_coordinate_frame + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + version 1.1 + offset ? + +BinormalPointerEXT(type, stride, pointer) + return void + param type BinormalPointerTypeEXT in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(type/stride)] retained + category EXT_coordinate_frame + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + version 1.1 + offset ? + +############################################################################### +# +# Extension #157 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #158 +# EXT_texture_env_combine commands +# +############################################################################### + +# (none) +newcategory: EXT_texture_env_combine + +############################################################################### +# +# Extension #159 +# APPLE_specular_vector commands +# +############################################################################### + +# (none) +newcategory: APPLE_specular_vector + +############################################################################### +# +# Extension #160 +# APPLE_transform_hint commands +# +############################################################################### + +# (none) +newcategory: APPLE_transform_hint + +############################################################################### +# +# Extension #161 +# SGIX_fog_scale commands +# +############################################################################### + +# (none) +newcategory: SGIX_fog_scale + +############################################################################### +# +# Extension #162 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #163 +# SUNX_constant_data commands +# +############################################################################### + +FinishTextureSUNX() + return void + category SUNX_constant_data + version 1.1 + glxropcode ? + offset ? + +############################################################################### +# +# Extension #164 +# SUN_global_alpha commands +# +############################################################################### + +GlobalAlphaFactorbSUN(factor) + return void + param factor Int8 in value + category SUN_global_alpha + version 1.1 + glxropcode ? + offset ? + +GlobalAlphaFactorsSUN(factor) + return void + param factor Int16 in value + category SUN_global_alpha + version 1.1 + glxropcode ? + offset ? + +GlobalAlphaFactoriSUN(factor) + return void + param factor Int32 in value + category SUN_global_alpha + version 1.1 + glxropcode ? + offset ? + +GlobalAlphaFactorfSUN(factor) + return void + param factor Float32 in value + category SUN_global_alpha + version 1.1 + glxropcode ? + offset ? + +GlobalAlphaFactordSUN(factor) + return void + param factor Float64 in value + category SUN_global_alpha + version 1.1 + glxropcode ? + offset ? + +GlobalAlphaFactorubSUN(factor) + return void + param factor UInt8 in value + category SUN_global_alpha + version 1.1 + glxropcode ? + offset ? + +GlobalAlphaFactorusSUN(factor) + return void + param factor UInt16 in value + category SUN_global_alpha + version 1.1 + glxropcode ? + offset ? + +GlobalAlphaFactoruiSUN(factor) + return void + param factor UInt32 in value + category SUN_global_alpha + version 1.1 + glxropcode ? + offset ? + +############################################################################### +# +# Extension #165 +# SUN_triangle_list commands +# +############################################################################### + +ReplacementCodeuiSUN(code) + return void + param code UInt32 in value + category SUN_triangle_list + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeusSUN(code) + return void + param code UInt16 in value + category SUN_triangle_list + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeubSUN(code) + return void + param code UInt8 in value + category SUN_triangle_list + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuivSUN(code) + return void + param code UInt32 in array [COMPSIZE()] + category SUN_triangle_list + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeusvSUN(code) + return void + param code UInt16 in array [COMPSIZE()] + category SUN_triangle_list + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeubvSUN(code) + return void + param code UInt8 in array [COMPSIZE()] + category SUN_triangle_list + version 1.1 + glxropcode ? + offset ? + +ReplacementCodePointerSUN(type, stride, pointer) + return void + param type ReplacementCodeTypeSUN in value + param stride SizeI in value + param pointer VoidPointer in array [COMPSIZE(type/stride)] retained + category SUN_triangle_list + version 1.1 + glxropcode ? + offset ? + +############################################################################### +# +# Extension #166 +# SUN_vertex commands +# +############################################################################### + +Color4ubVertex2fSUN(r, g, b, a, x, y) + return void + param r UInt8 in value + param g UInt8 in value + param b UInt8 in value + param a UInt8 in value + param x Float32 in value + param y Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +Color4ubVertex2fvSUN(c, v) + return void + param c UInt8 in array [4] + param v Float32 in array [2] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +Color4ubVertex3fSUN(r, g, b, a, x, y, z) + return void + param r UInt8 in value + param g UInt8 in value + param b UInt8 in value + param a UInt8 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +Color4ubVertex3fvSUN(c, v) + return void + param c UInt8 in array [4] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +Color3fVertex3fSUN(r, g, b, x, y, z) + return void + param r Float32 in value + param g Float32 in value + param b Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +Color3fVertex3fvSUN(c, v) + return void + param c Float32 in array [3] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +Normal3fVertex3fSUN(nx, ny, nz, x, y, z) + return void + param nx Float32 in value + param ny Float32 in value + param nz Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +Normal3fVertex3fvSUN(n, v) + return void + param n Float32 in array [3] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +Color4fNormal3fVertex3fSUN(r, g, b, a, nx, ny, nz, x, y, z) + return void + param r Float32 in value + param g Float32 in value + param b Float32 in value + param a Float32 in value + param nx Float32 in value + param ny Float32 in value + param nz Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +Color4fNormal3fVertex3fvSUN(c, n, v) + return void + param c Float32 in array [4] + param n Float32 in array [3] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +TexCoord2fVertex3fSUN(s, t, x, y, z) + return void + param s Float32 in value + param t Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +TexCoord2fVertex3fvSUN(tc, v) + return void + param tc Float32 in array [2] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +TexCoord4fVertex4fSUN(s, t, p, q, x, y, z, w) + return void + param s Float32 in value + param t Float32 in value + param p Float32 in value + param q Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + param w Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +TexCoord4fVertex4fvSUN(tc, v) + return void + param tc Float32 in array [4] + param v Float32 in array [4] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +TexCoord2fColor4ubVertex3fSUN(s, t, r, g, b, a, x, y, z) + return void + param s Float32 in value + param t Float32 in value + param r UInt8 in value + param g UInt8 in value + param b UInt8 in value + param a UInt8 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +TexCoord2fColor4ubVertex3fvSUN(tc, c, v) + return void + param tc Float32 in array [2] + param c UInt8 in array [4] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +TexCoord2fColor3fVertex3fSUN(s, t, r, g, b, x, y, z) + return void + param s Float32 in value + param t Float32 in value + param r Float32 in value + param g Float32 in value + param b Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +TexCoord2fColor3fVertex3fvSUN(tc, c, v) + return void + param tc Float32 in array [2] + param c Float32 in array [3] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +TexCoord2fNormal3fVertex3fSUN(s, t, nx, ny, nz, x, y, z) + return void + param s Float32 in value + param t Float32 in value + param nx Float32 in value + param ny Float32 in value + param nz Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +TexCoord2fNormal3fVertex3fvSUN(tc, n, v) + return void + param tc Float32 in array [2] + param n Float32 in array [3] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +TexCoord2fColor4fNormal3fVertex3fSUN(s, t, r, g, b, a, nx, ny, nz, x, y, z) + return void + param s Float32 in value + param t Float32 in value + param r Float32 in value + param g Float32 in value + param b Float32 in value + param a Float32 in value + param nx Float32 in value + param ny Float32 in value + param nz Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +TexCoord2fColor4fNormal3fVertex3fvSUN(tc, c, n, v) + return void + param tc Float32 in array [2] + param c Float32 in array [4] + param n Float32 in array [3] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +TexCoord4fColor4fNormal3fVertex4fSUN(s, t, p, q, r, g, b, a, nx, ny, nz, x, y, z, w) + return void + param s Float32 in value + param t Float32 in value + param p Float32 in value + param q Float32 in value + param r Float32 in value + param g Float32 in value + param b Float32 in value + param a Float32 in value + param nx Float32 in value + param ny Float32 in value + param nz Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + param w Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +TexCoord4fColor4fNormal3fVertex4fvSUN(tc, c, n, v) + return void + param tc Float32 in array [4] + param c Float32 in array [4] + param n Float32 in array [3] + param v Float32 in array [4] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiVertex3fSUN(rc, x, y, z) + return void + param rc ReplacementCodeSUN in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiVertex3fvSUN(rc, v) + return void + param rc ReplacementCodeSUN in array [1] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiColor4ubVertex3fSUN(rc, r, g, b, a, x, y, z) + return void + param rc ReplacementCodeSUN in value + param r UInt8 in value + param g UInt8 in value + param b UInt8 in value + param a UInt8 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiColor4ubVertex3fvSUN(rc, c, v) + return void + param rc ReplacementCodeSUN in array [1] + param c UInt8 in array [4] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiColor3fVertex3fSUN(rc, r, g, b, x, y, z) + return void + param rc ReplacementCodeSUN in value + param r Float32 in value + param g Float32 in value + param b Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiColor3fVertex3fvSUN(rc, c, v) + return void + param rc ReplacementCodeSUN in array [1] + param c Float32 in array [3] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiNormal3fVertex3fSUN(rc, nx, ny, nz, x, y, z) + return void + param rc ReplacementCodeSUN in value + param nx Float32 in value + param ny Float32 in value + param nz Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiNormal3fVertex3fvSUN(rc, n, v) + return void + param rc ReplacementCodeSUN in array [1] + param n Float32 in array [3] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiColor4fNormal3fVertex3fSUN(rc, r, g, b, a, nx, ny, nz, x, y, z) + return void + param rc ReplacementCodeSUN in value + param r Float32 in value + param g Float32 in value + param b Float32 in value + param a Float32 in value + param nx Float32 in value + param ny Float32 in value + param nz Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiColor4fNormal3fVertex3fvSUN(rc, c, n, v) + return void + param rc ReplacementCodeSUN in array [1] + param c Float32 in array [4] + param n Float32 in array [3] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiTexCoord2fVertex3fSUN(rc, s, t, x, y, z) + return void + param rc ReplacementCodeSUN in value + param s Float32 in value + param t Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiTexCoord2fVertex3fvSUN(rc, tc, v) + return void + param rc ReplacementCodeSUN in array [1] + param tc Float32 in array [2] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiTexCoord2fNormal3fVertex3fSUN(rc, s, t, nx, ny, nz, x, y, z) + return void + param rc ReplacementCodeSUN in value + param s Float32 in value + param t Float32 in value + param nx Float32 in value + param ny Float32 in value + param nz Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiTexCoord2fNormal3fVertex3fvSUN(rc, tc, n, v) + return void + param rc ReplacementCodeSUN in array [1] + param tc Float32 in array [2] + param n Float32 in array [3] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fSUN(rc, s, t, r, g, b, a, nx, ny, nz, x, y, z) + return void + param rc ReplacementCodeSUN in value + param s Float32 in value + param t Float32 in value + param r Float32 in value + param g Float32 in value + param b Float32 in value + param a Float32 in value + param nx Float32 in value + param ny Float32 in value + param nz Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +ReplacementCodeuiTexCoord2fColor4fNormal3fVertex3fvSUN(rc, tc, c, n, v) + return void + param rc ReplacementCodeSUN in array [1] + param tc Float32 in array [2] + param c Float32 in array [4] + param n Float32 in array [3] + param v Float32 in array [3] + category SUN_vertex + version 1.1 + glxropcode ? + offset ? + +############################################################################### +# +# Extension #167 - WGL_EXT_display_color_table +# Extension #168 - WGL_EXT_extensions_string +# Extension #169 - WGL_EXT_make_current_read +# Extension #170 - WGL_EXT_pixel_format +# Extension #171 - WGL_EXT_pbuffer +# Extension #172 - WGL_EXT_swap_control +# +############################################################################### + +############################################################################### +# +# Extension #173 +# EXT_blend_func_separate commands (also INGR_blend_func_separate) +# +############################################################################### + +BlendFuncSeparateEXT(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha) + return void + param sfactorRGB BlendFuncSeparateParameterEXT in value + param dfactorRGB BlendFuncSeparateParameterEXT in value + param sfactorAlpha BlendFuncSeparateParameterEXT in value + param dfactorAlpha BlendFuncSeparateParameterEXT in value + category EXT_blend_func_separate + glxropcode 4134 + version 1.0 + extension + alias BlendFuncSeparate + +BlendFuncSeparateINGR(sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha) + return void + param sfactorRGB BlendFuncSeparateParameterEXT in value + param dfactorRGB BlendFuncSeparateParameterEXT in value + param sfactorAlpha BlendFuncSeparateParameterEXT in value + param dfactorAlpha BlendFuncSeparateParameterEXT in value + category INGR_blend_func_separate + glxropcode 4134 + version 1.0 + extension + alias BlendFuncSeparateEXT + +############################################################################### +# +# Extension #174 +# INGR_color_clamp commands +# +############################################################################### + +# (none) +newcategory: INGR_color_clamp + +############################################################################### +# +# Extension #175 +# INGR_interlace_read commands +# +############################################################################### + +# (none) +newcategory: INGR_interlace_read + +############################################################################### +# +# Extension #176 +# EXT_stencil_wrap commands +# +############################################################################### + +# (none) +newcategory: EXT_stencil_wrap + +############################################################################### +# +# Extension #177 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #178 +# EXT_422_pixels commands +# +############################################################################### + +# (none) +newcategory: EXT_422_pixels + +############################################################################### +# +# Extension #179 +# NV_texgen_reflection commands +# +############################################################################### + +# (none) +newcategory: NV_texgen_reflection + +############################################################################### +# +# Extension #??? +# @ EXT_texture_cube_map commands +# +############################################################################### + +# (none) + +############################################################################### +# +# Extension #180 - skipped +# Extension #181 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #182 +# SUN_convolution_border_modes commands +# +############################################################################### + +# (none) +newcategory: SUN_convolution_border_modes + +############################################################################### +# +# Extension #183 - GLX_SUN_get_transparent_index +# Extension #184 - skipped +# +############################################################################### + +############################################################################### +# +# Extension #185 +# EXT_texture_env_add commands +# +############################################################################### + +# (none) +newcategory: EXT_texture_env_add + +############################################################################### +# +# Extension #186 +# EXT_texture_lod_bias commands +# +############################################################################### + +# (none) +newcategory: EXT_texture_lod_bias + +############################################################################### +# +# Extension #187 +# EXT_texture_filter_anisotropic commands +# +############################################################################### + +# (none) +newcategory: EXT_texture_filter_anisotropic + +############################################################################### +# +# Extension #188 +# EXT_vertex_weighting commands +# +############################################################################### + +# GLX stuff to be written +VertexWeightfEXT(weight) + return void + param weight Float32 in value + category EXT_vertex_weighting + vectorequiv VertexWeightfvEXT + version 1.1 + extension soft WINSOFT NV10 + glxflags ignore + offset 494 + +VertexWeightfvEXT(weight) + return void + param weight Float32 in array [1] + category EXT_vertex_weighting + version 1.1 + extension soft WINSOFT NV10 + glxropcode 4135 + glxflags ignore + offset 495 + +VertexWeightPointerEXT(size, type, stride, pointer) + return void + param size SizeI in value + param type VertexWeightPointerTypeEXT in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(type/stride)] retained + category EXT_vertex_weighting + version 1.1 + extension soft WINSOFT NV10 + dlflags notlistable + glxflags ignore + offset 496 + +############################################################################### +# +# Extension #189 +# NV_light_max_exponent commands +# +############################################################################### + +# (none) +newcategory: NV_light_max_exponent + +############################################################################### +# +# Extension #190 +# NV_vertex_array_range commands +# +############################################################################### + +FlushVertexArrayRangeNV() + return void + category NV_vertex_array_range + version 1.1 + extension soft WINSOFT NV10 + dlflags notlistable + glxflags client-handcode server-handcode ignore + offset 497 + +VertexArrayRangeNV(length, pointer) + return void + param length SizeI in value + param pointer Void in array [COMPSIZE(length)] retained + category NV_vertex_array_range + version 1.1 + extension soft WINSOFT NV10 + dlflags notlistable + glxflags client-handcode server-handcode ignore + offset 498 + +############################################################################### +# +# Extension #191 +# NV_register_combiners commands +# +############################################################################### + +CombinerParameterfvNV(pname, params) + return void + param pname CombinerParameterNV in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category NV_register_combiners + version 1.1 + extension soft WINSOFT NV10 + glxropcode 4137 + glxflags ignore + offset 499 + +CombinerParameterfNV(pname, param) + return void + param pname CombinerParameterNV in value + param param Float32 in value + category NV_register_combiners + version 1.1 + extension soft WINSOFT NV10 + glxropcode 4136 + glxflags ignore + offset 500 + +CombinerParameterivNV(pname, params) + return void + param pname CombinerParameterNV in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category NV_register_combiners + version 1.1 + extension soft WINSOFT NV10 + glxropcode 4139 + glxflags ignore + offset 501 + +CombinerParameteriNV(pname, param) + return void + param pname CombinerParameterNV in value + param param Int32 in value + category NV_register_combiners + version 1.1 + extension soft WINSOFT NV10 + glxropcode 4138 + glxflags ignore + offset 502 + +CombinerInputNV(stage, portion, variable, input, mapping, componentUsage) + return void + param stage CombinerStageNV in value + param portion CombinerPortionNV in value + param variable CombinerVariableNV in value + param input CombinerRegisterNV in value + param mapping CombinerMappingNV in value + param componentUsage CombinerComponentUsageNV in value + category NV_register_combiners + version 1.1 + extension soft WINSOFT NV10 + glxropcode 4140 + glxflags ignore + offset 503 + +CombinerOutputNV(stage, portion, abOutput, cdOutput, sumOutput, scale, bias, abDotProduct, cdDotProduct, muxSum) + return void + param stage CombinerStageNV in value + param portion CombinerPortionNV in value + param abOutput CombinerRegisterNV in value + param cdOutput CombinerRegisterNV in value + param sumOutput CombinerRegisterNV in value + param scale CombinerScaleNV in value + param bias CombinerBiasNV in value + param abDotProduct Boolean in value + param cdDotProduct Boolean in value + param muxSum Boolean in value + category NV_register_combiners + version 1.1 + extension soft WINSOFT NV10 + glxropcode 4141 + glxflags ignore + offset 504 + +FinalCombinerInputNV(variable, input, mapping, componentUsage) + return void + param variable CombinerVariableNV in value + param input CombinerRegisterNV in value + param mapping CombinerMappingNV in value + param componentUsage CombinerComponentUsageNV in value + category NV_register_combiners + version 1.1 + extension soft WINSOFT NV10 + glxropcode 4142 + glxflags ignore + offset 505 + +GetCombinerInputParameterfvNV(stage, portion, variable, pname, params) + return void + param stage CombinerStageNV in value + param portion CombinerPortionNV in value + param variable CombinerVariableNV in value + param pname CombinerParameterNV in value + param params Float32 out array [COMPSIZE(pname)] + dlflags notlistable + category NV_register_combiners + version 1.1 + extension soft WINSOFT NV10 + glxvendorpriv 1270 + glxflags ignore + offset 506 + +GetCombinerInputParameterivNV(stage, portion, variable, pname, params) + return void + param stage CombinerStageNV in value + param portion CombinerPortionNV in value + param variable CombinerVariableNV in value + param pname CombinerParameterNV in value + param params Int32 out array [COMPSIZE(pname)] + dlflags notlistable + category NV_register_combiners + version 1.1 + extension soft WINSOFT NV10 + glxvendorpriv 1271 + glxflags ignore + offset 507 + +GetCombinerOutputParameterfvNV(stage, portion, pname, params) + return void + param stage CombinerStageNV in value + param portion CombinerPortionNV in value + param pname CombinerParameterNV in value + param params Float32 out array [COMPSIZE(pname)] + dlflags notlistable + category NV_register_combiners + version 1.1 + extension soft WINSOFT NV10 + glxvendorpriv 1272 + glxflags ignore + offset 508 + +GetCombinerOutputParameterivNV(stage, portion, pname, params) + return void + param stage CombinerStageNV in value + param portion CombinerPortionNV in value + param pname CombinerParameterNV in value + param params Int32 out array [COMPSIZE(pname)] + dlflags notlistable + category NV_register_combiners + version 1.1 + extension soft WINSOFT NV10 + glxvendorpriv 1273 + glxflags ignore + offset 509 + +GetFinalCombinerInputParameterfvNV(variable, pname, params) + return void + param variable CombinerVariableNV in value + param pname CombinerParameterNV in value + param params Float32 out array [COMPSIZE(pname)] + dlflags notlistable + category NV_register_combiners + version 1.1 + extension soft WINSOFT NV10 + glxvendorpriv 1274 + glxflags ignore + offset 510 + +GetFinalCombinerInputParameterivNV(variable, pname, params) + return void + param variable CombinerVariableNV in value + param pname CombinerParameterNV in value + param params Int32 out array [COMPSIZE(pname)] + dlflags notlistable + category NV_register_combiners + version 1.1 + extension soft WINSOFT NV10 + glxvendorpriv 1275 + glxflags ignore + offset 511 + +############################################################################### +# +# Extension #192 +# NV_fog_distance commands +# +############################################################################### + +# (none) +newcategory: NV_fog_distance + +############################################################################### +# +# Extension #193 +# NV_texgen_emboss commands +# +############################################################################### + +# (none) +newcategory: NV_texgen_emboss + +############################################################################### +# +# Extension #194 +# NV_blend_square commands +# +############################################################################### + +# (none) +newcategory: NV_blend_square + +############################################################################### +# +# Extension #195 +# NV_texture_env_combine4 commands +# +############################################################################### + +# (none) +newcategory: NV_texture_env_combine4 + +############################################################################### +# +# Extension #196 +# MESA_resize_buffers commands +# +############################################################################### + +ResizeBuffersMESA() + return void + category MESA_resize_buffers + version 1.0 + glxropcode ? + offset 512 + +############################################################################### +# +# Extension #197 +# MESA_window_pos commands +# +# Note that the 2- and 3-component versions are now aliases of ARB +# entry points. +# +############################################################################### + +WindowPos2dMESA(x, y) + return void + param x CoordD in value + param y CoordD in value + category MESA_window_pos + vectorequiv WindowPos2dvMESA + version 1.0 + alias WindowPos2dARB + +WindowPos2dvMESA(v) + return void + param v CoordD in array [2] + category MESA_window_pos + version 1.0 + glxropcode ? + alias WindowPos2dvARB + +WindowPos2fMESA(x, y) + return void + param x CoordF in value + param y CoordF in value + category MESA_window_pos + vectorequiv WindowPos2fvMESA + version 1.0 + alias WindowPos2fARB + +WindowPos2fvMESA(v) + return void + param v CoordF in array [2] + category MESA_window_pos + version 1.0 + glxropcode ? + alias WindowPos2fvARB + +WindowPos2iMESA(x, y) + return void + param x CoordI in value + param y CoordI in value + category MESA_window_pos + vectorequiv WindowPos2ivMESA + version 1.0 + alias WindowPos2iARB + +WindowPos2ivMESA(v) + return void + param v CoordI in array [2] + category MESA_window_pos + version 1.0 + glxropcode ? + alias WindowPos2ivARB + +WindowPos2sMESA(x, y) + return void + param x CoordS in value + param y CoordS in value + category MESA_window_pos + vectorequiv WindowPos2svMESA + version 1.0 + alias WindowPos2sARB + +WindowPos2svMESA(v) + return void + param v CoordS in array [2] + category MESA_window_pos + version 1.0 + glxropcode ? + alias WindowPos2svARB + +WindowPos3dMESA(x, y, z) + return void + param x CoordD in value + param y CoordD in value + param z CoordD in value + vectorequiv WindowPos3dvMESA + category MESA_window_pos + version 1.0 + alias WindowPos3dARB + +WindowPos3dvMESA(v) + return void + param v CoordD in array [3] + category MESA_window_pos + version 1.0 + glxropcode ? + alias WindowPos3dvARB + +WindowPos3fMESA(x, y, z) + return void + param x CoordF in value + param y CoordF in value + param z CoordF in value + category MESA_window_pos + vectorequiv WindowPos3fvMESA + version 1.0 + alias WindowPos3fARB + +WindowPos3fvMESA(v) + return void + param v CoordF in array [3] + category MESA_window_pos + version 1.0 + glxropcode ? + alias WindowPos3fvARB + +WindowPos3iMESA(x, y, z) + return void + param x CoordI in value + param y CoordI in value + param z CoordI in value + category MESA_window_pos + vectorequiv WindowPos3ivMESA + version 1.0 + alias WindowPos3iARB + +WindowPos3ivMESA(v) + return void + param v CoordI in array [3] + category MESA_window_pos + version 1.0 + glxropcode ? + alias WindowPos3ivARB + +WindowPos3sMESA(x, y, z) + return void + param x CoordS in value + param y CoordS in value + param z CoordS in value + category MESA_window_pos + vectorequiv WindowPos3svMESA + version 1.0 + alias WindowPos3sARB + +WindowPos3svMESA(v) + return void + param v CoordS in array [3] + category MESA_window_pos + version 1.0 + glxropcode ? + alias WindowPos3svARB + +WindowPos4dMESA(x, y, z, w) + return void + param x CoordD in value + param y CoordD in value + param z CoordD in value + param w CoordD in value + vectorequiv WindowPos4dvMESA + category MESA_window_pos + version 1.0 + offset 529 + +WindowPos4dvMESA(v) + return void + param v CoordD in array [4] + category MESA_window_pos + version 1.0 + glxropcode ? + offset 530 + +WindowPos4fMESA(x, y, z, w) + return void + param x CoordF in value + param y CoordF in value + param z CoordF in value + param w CoordF in value + category MESA_window_pos + vectorequiv WindowPos4fvMESA + version 1.0 + offset 531 + +WindowPos4fvMESA(v) + return void + param v CoordF in array [4] + category MESA_window_pos + version 1.0 + glxropcode ? + offset 532 + +WindowPos4iMESA(x, y, z, w) + return void + param x CoordI in value + param y CoordI in value + param z CoordI in value + param w CoordI in value + category MESA_window_pos + vectorequiv WindowPos4ivMESA + version 1.0 + offset 533 + +WindowPos4ivMESA(v) + return void + param v CoordI in array [4] + category MESA_window_pos + version 1.0 + glxropcode ? + offset 534 + +WindowPos4sMESA(x, y, z, w) + return void + param x CoordS in value + param y CoordS in value + param z CoordS in value + param w CoordS in value + category MESA_window_pos + vectorequiv WindowPos4svMESA + version 1.0 + offset 535 + +WindowPos4svMESA(v) + return void + param v CoordS in array [4] + category MESA_window_pos + version 1.0 + glxropcode ? + offset 536 + +############################################################################### +# +# Extension #198 +# EXT_texture_compression_s3tc commands +# +############################################################################### + +#@@ (none yet) + +############################################################################### +# +# Extension #199 +# IBM_cull_vertex commands +# +############################################################################### + +# (none) +newcategory: IBM_cull_vertex + +############################################################################### +# +# Extension #200 +# IBM_multimode_draw_arrays commands +# +############################################################################### + +MultiModeDrawArraysIBM(mode, first, count, primcount, modestride) + return void + param mode BeginMode in array [COMPSIZE(primcount)] + param first Int32 in array [COMPSIZE(primcount)] + param count SizeI in array [COMPSIZE(primcount)] + param primcount SizeI in value + param modestride Int32 in value + category IBM_multimode_draw_arrays + version 1.1 + glxropcode ? + offset 708 + + +MultiModeDrawElementsIBM(mode, count, type, indices, primcount, modestride) + return void + param mode BeginMode in array [COMPSIZE(primcount)] + param count SizeI in array [COMPSIZE(primcount)] + param type DrawElementsType in value + param indices ConstVoidPointer in array [COMPSIZE(primcount)] + param primcount SizeI in value + param modestride Int32 in value + category IBM_multimode_draw_arrays + version 1.1 + glxropcode ? + offset 709 + +############################################################################### +# +# Extension #201 +# IBM_vertex_array_lists commands +# +############################################################################### + +ColorPointerListIBM(size, type, stride, pointer, ptrstride) + return void + param size Int32 in value + param type ColorPointerType in value + param stride Int32 in value + param pointer VoidPointer in array [COMPSIZE(size/type/stride)] retained + param ptrstride Int32 in value + category IBM_vertex_array_lists + version 1.1 + glxropcode ? + offset ? + +SecondaryColorPointerListIBM(size, type, stride, pointer, ptrstride) + return void + param size Int32 in value + param type SecondaryColorPointerTypeIBM in value + param stride Int32 in value + param pointer VoidPointer in array [COMPSIZE(size/type/stride)] retained + param ptrstride Int32 in value + category IBM_vertex_array_lists + version 1.1 + glxropcode ? + offset ? + +EdgeFlagPointerListIBM(stride, pointer, ptrstride) + return void + param stride Int32 in value + param pointer BooleanPointer in array [COMPSIZE(stride)] retained + param ptrstride Int32 in value + category IBM_vertex_array_lists + version 1.1 + glxropcode ? + offset ? + +FogCoordPointerListIBM(type, stride, pointer, ptrstride) + return void + param type FogPointerTypeIBM in value + param stride Int32 in value + param pointer VoidPointer in array [COMPSIZE(type/stride)] retained + param ptrstride Int32 in value + category IBM_vertex_array_lists + version 1.1 + glxropcode ? + offset ? + +IndexPointerListIBM(type, stride, pointer, ptrstride) + return void + param type IndexPointerType in value + param stride Int32 in value + param pointer VoidPointer in array [COMPSIZE(type/stride)] retained + param ptrstride Int32 in value + category IBM_vertex_array_lists + version 1.1 + glxropcode ? + offset ? + +NormalPointerListIBM(type, stride, pointer, ptrstride) + return void + param type NormalPointerType in value + param stride Int32 in value + param pointer VoidPointer in array [COMPSIZE(type/stride)] retained + param ptrstride Int32 in value + category IBM_vertex_array_lists + version 1.1 + glxropcode ? + offset ? + +TexCoordPointerListIBM(size, type, stride, pointer, ptrstride) + return void + param size Int32 in value + param type TexCoordPointerType in value + param stride Int32 in value + param pointer VoidPointer in array [COMPSIZE(size/type/stride)] retained + param ptrstride Int32 in value + category IBM_vertex_array_lists + version 1.1 + glxropcode ? + offset ? + +VertexPointerListIBM(size, type, stride, pointer, ptrstride) + return void + param size Int32 in value + param type VertexPointerType in value + param stride Int32 in value + param pointer VoidPointer in array [COMPSIZE(size/type/stride)] retained + param ptrstride Int32 in value + category IBM_vertex_array_lists + version 1.1 + glxropcode ? + offset ? + +############################################################################### +# +# Extension #202 +# SGIX_subsample commands +# +############################################################################### + +# (none) +newcategory: SGIX_subsample + +############################################################################### +# +# Extension #203 +# SGIX_ycrcba commands +# +############################################################################### + +# (none) +newcategory: SGIX_ycrcba + +############################################################################### +# +# Extension #204 +# SGIX_ycrcb_subsample commands +# +############################################################################### + +# (none) +newcategory: SGIX_ycrcb_subsample + +############################################################################### +# +# Extension #205 +# SGIX_depth_pass_instrument commands +# +############################################################################### + +# (none) +newcategory: SGIX_depth_pass_instrument + +############################################################################### +# +# Extension #206 +# 3DFX_texture_compression_FXT1 commands +# +############################################################################### + +# (none) +newcategory: 3DFX_texture_compression_FXT1 + +############################################################################### +# +# Extension #207 +# 3DFX_multisample commands +# +############################################################################### + +# (none) +newcategory: 3DFX_multisample + +############################################################################### +# +# Extension #208 +# 3DFX_tbuffer commands +# +############################################################################### + +TbufferMask3DFX(mask) + return void + param mask UInt32 in value + category 3DFX_tbuffer + version 1.2 + glxropcode ? + offset 553 + +############################################################################### +# +# Extension #209 +# EXT_multisample commands +# +############################################################################### + +SampleMaskEXT(value, invert) + return void + param value ClampedFloat32 in value + param invert Boolean in value + category EXT_multisample + version 1.0 + glxropcode ? + extension + offset 446 + +SamplePatternEXT(pattern) + return void + param pattern SamplePatternEXT in value + category EXT_multisample + version 1.0 + glxropcode ? + glxflags + extension + offset 447 + +############################################################################### +# +# Extension #210 +# SGIX_vertex_preclip commands +# +############################################################################### + +# (none) +newcategory: SGIX_vertex_preclip + +############################################################################### +# +# Extension #211 +# SGIX_convolution_accuracy commands +# +############################################################################### + +# (none) +newcategory: SGIX_convolution_accuracy + +############################################################################### +# +# Extension #212 +# SGIX_resample commands +# +############################################################################### + +# (none) +newcategory: SGIX_resample + +############################################################################### +# +# Extension #213 +# SGIS_point_line_texgen commands +# +############################################################################### + +# (none) +newcategory: SGIS_point_line_texgen + +############################################################################### +# +# Extension #214 +# SGIS_texture_color_mask commands +# +############################################################################### + +TextureColorMaskSGIS(red, green, blue, alpha) + return void + param red Boolean in value + param green Boolean in value + param blue Boolean in value + param alpha Boolean in value + category SGIS_texture_color_mask + version 1.1 + glxropcode 2082 + extension + offset ? + +############################################################################### +# +# Extension #215 - GLX_MESA_copy_sub_buffer +# Extension #216 - GLX_MESA_pixmap_colormap +# Extension #217 - GLX_MESA_release_buffers +# Extension #218 - GLX_MESA_set_3dfx_mode +# +############################################################################### + +############################################################################### +# +# Extension #219 +# SGIX_igloo_interface commands +# +############################################################################### + +IglooInterfaceSGIX(pname, params) + return void + dlflags notlistable + param pname IglooFunctionSelectSGIX in value + param params IglooParameterSGIX in array [COMPSIZE(pname)] + category SGIX_igloo_interface + version 1.0 + glxflags SGI ignore + extension + glxropcode 200 + offset ? + +############################################################################### +# +# Extension #220 +# EXT_texture_env_dot3 commands +# +############################################################################### + +# (none) +newcategory: EXT_texture_env_dot3 + +############################################################################### +# +# Extension #221 +# ATI_texture_mirror_once commands +# +############################################################################### +# (none) +newcategory: ATI_texture_mirror_once + +############################################################################### +# +# Extension #222 +# NV_fence commands +# +############################################################################### + +DeleteFencesNV(n, fences) + return void + param n SizeI in value + param fences FenceNV in array [n] + category NV_fence + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxvendorpriv 1276 + glxflags ignore + offset 647 + +GenFencesNV(n, fences) + return void + param n SizeI in value + param fences FenceNV out array [n] + category NV_fence + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxvendorpriv 1277 + glxflags ignore + offset 648 + +IsFenceNV(fence) + return Boolean + param fence FenceNV in value + category NV_fence + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxvendorpriv 1278 + glxflags ignore + offset 649 + +TestFenceNV(fence) + return Boolean + param fence FenceNV in value + category NV_fence + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxvendorpriv 1279 + glxflags ignore + offset 650 + +GetFenceivNV(fence, pname, params) + return void + param fence FenceNV in value + param pname FenceParameterNameNV in value + param params Int32 out array [COMPSIZE(pname)] + category NV_fence + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxvendorpriv 1280 + glxflags ignore + offset 651 + +FinishFenceNV(fence) + return void + param fence FenceNV in value + category NV_fence + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxvendorpriv 1312 + glxflags ignore + offset 652 + +SetFenceNV(fence, condition) + return void + param fence FenceNV in value + param condition FenceConditionNV in value + category NV_fence + version 1.2 + extension soft WINSOFT NV10 + glxflags ignore + offset 653 + +############################################################################### +# +# Extension #225 +# NV_evaluators commands +# +############################################################################### + +MapControlPointsNV(target, index, type, ustride, vstride, uorder, vorder, packed, points) + return void + param target EvalTargetNV in value + param index UInt32 in value + param type MapTypeNV in value + param ustride SizeI in value + param vstride SizeI in value + param uorder CheckedInt32 in value + param vorder CheckedInt32 in value + param packed Boolean in value + param points Void in array [COMPSIZE(target/uorder/vorder)] + category NV_evaluators + dlflags handcode + version 1.1 + extension soft WINSOFT NV10 + glxflags ignore + offset ? + +MapParameterivNV(target, pname, params) + return void + param target EvalTargetNV in value + param pname MapParameterNV in value + param params CheckedInt32 in array [COMPSIZE(target/pname)] + category NV_evaluators + version 1.1 + extension soft WINSOFT NV10 + glxflags ignore + offset ? + +MapParameterfvNV(target, pname, params) + return void + param target EvalTargetNV in value + param pname MapParameterNV in value + param params CheckedFloat32 in array [COMPSIZE(target/pname)] + category NV_evaluators + version 1.1 + extension soft WINSOFT NV10 + glxflags ignore + offset ? + +GetMapControlPointsNV(target, index, type, ustride, vstride, packed, points) + return void + param target EvalTargetNV in value + param index UInt32 in value + param type MapTypeNV in value + param ustride SizeI in value + param vstride SizeI in value + param packed Boolean in value + param points Void out array [COMPSIZE(target)] + category NV_evaluators + dlflags notlistable + version 1.1 + extension soft WINSOFT NV10 + glxflags ignore + offset ? + +GetMapParameterivNV(target, pname, params) + return void + param target EvalTargetNV in value + param pname MapParameterNV in value + param params Int32 out array [COMPSIZE(target/pname)] + category NV_evaluators + dlflags notlistable + version 1.1 + extension soft WINSOFT NV10 + glxflags ignore + offset ? + +GetMapParameterfvNV(target, pname, params) + return void + param target EvalTargetNV in value + param pname MapParameterNV in value + param params Float32 out array [COMPSIZE(target/pname)] + category NV_evaluators + dlflags notlistable + version 1.1 + extension soft WINSOFT NV10 + glxflags ignore + offset ? + +GetMapAttribParameterivNV(target, index, pname, params) + return void + param target EvalTargetNV in value + param index UInt32 in value + param pname MapAttribParameterNV in value + param params Int32 out array [COMPSIZE(pname)] + category NV_evaluators + dlflags notlistable + version 1.1 + extension soft WINSOFT NV10 + glxflags ignore + offset ? + +GetMapAttribParameterfvNV(target, index, pname, params) + return void + param target EvalTargetNV in value + param index UInt32 in value + param pname MapAttribParameterNV in value + param params Float32 out array [COMPSIZE(pname)] + category NV_evaluators + dlflags notlistable + version 1.1 + extension soft WINSOFT NV10 + glxflags ignore + offset ? + +EvalMapsNV(target, mode) + return void + param target EvalTargetNV in value + param mode EvalMapsModeNV in value + category NV_evaluators + version 1.1 + extension soft WINSOFT NV10 + glxflags ignore + offset ? + +############################################################################### +# +# Extension #226 +# NV_packed_depth_stencil commands +# +############################################################################### + +# (none) +newcategory: NV_packed_depth_stencil + +############################################################################### +# +# Extension #227 +# NV_register_combiners2 commands +# +############################################################################### + +CombinerStageParameterfvNV(stage, pname, params) + return void + param stage CombinerStageNV in value + param pname CombinerParameterNV in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category NV_register_combiners2 + version 1.1 + extension + glxflags ignore + offset ? + +GetCombinerStageParameterfvNV(stage, pname, params) + return void + param stage CombinerStageNV in value + param pname CombinerParameterNV in value + param params Float32 out array [COMPSIZE(pname)] + dlflags notlistable + category NV_register_combiners2 + version 1.1 + extension + glxflags ignore + offset ? + +############################################################################### +# +# Extension #228 +# NV_texture_compression_vtc commands +# +############################################################################### + +# (none) +newcategory: NV_texture_compression_vtc + +############################################################################### +# +# Extension #229 +# NV_texture_rectangle commands +# +############################################################################### + +# (none) +newcategory: NV_texture_rectangle + +############################################################################### +# +# Extension #230 +# NV_texture_shader commands +# +############################################################################### + +# (none) +newcategory: NV_texture_shader + +############################################################################### +# +# Extension #231 +# NV_texture_shader2 commands +# +############################################################################### + +# (none) +newcategory: NV_texture_shader2 + +############################################################################### +# +# Extension #232 +# NV_vertex_array_range2 commands +# +############################################################################### + +# (none) +newcategory: NV_vertex_array_range2 + +############################################################################### +# +# Extension #233 +# NV_vertex_program commands +# +############################################################################### + +AreProgramsResidentNV(n, programs, residences) + return Boolean + param n SizeI in value + param programs UInt32 in array [n] + param residences Boolean out array [n] + category NV_vertex_program + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxflags ignore + glxvendorpriv 1293 + offset 578 + +BindProgramNV(target, id) + return void + param target VertexAttribEnumNV in value + param id UInt32 in value + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4180 + alias BindProgramARB + +DeleteProgramsNV(n, programs) + return void + param n SizeI in value + param programs UInt32 in array [n] + category NV_vertex_program + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxvendorpriv 1294 + alias DeleteProgramsARB + +ExecuteProgramNV(target, id, params) + return void + param target VertexAttribEnumNV in value + param id UInt32 in value + param params Float32 in array [4] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxflags ignore + glxropcode 4181 + offset 581 + +GenProgramsNV(n, programs) + return void + param n SizeI in value + param programs UInt32 out array [n] + category NV_vertex_program + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxvendorpriv 1295 + alias GenProgramsARB + +GetProgramParameterdvNV(target, index, pname, params) + return void + param target VertexAttribEnumNV in value + param index UInt32 in value + param pname VertexAttribEnumNV in value + param params Float64 out array [4] + category NV_vertex_program + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxflags ignore + glxvendorpriv 1297 + offset 583 + +GetProgramParameterfvNV(target, index, pname, params) + return void + param target VertexAttribEnumNV in value + param index UInt32 in value + param pname VertexAttribEnumNV in value + param params Float32 out array [4] + category NV_vertex_program + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxflags ignore + glxvendorpriv 1296 + offset 584 + +# GetProgramParameterSigneddvNV(target, index, pname, params) +# return void +# param target VertexAttribEnumNV in value +# param index Int32 in value +# param pname VertexAttribEnumNV in value +# param params Float64 out array [4] +# category NV_vertex_program1_1_dcc +# dlflags notlistable +# version 1.2 +# extension soft WINSOFT NV20 +# glxflags ignore +# offset ? +# +# GetProgramParameterSignedfvNV(target, index, pname, params) +# return void +# param target VertexAttribEnumNV in value +# param index Int32 in value +# param pname VertexAttribEnumNV in value +# param params Float32 out array [4] +# category NV_vertex_program1_1_dcc +# dlflags notlistable +# version 1.2 +# extension soft WINSOFT NV20 +# glxflags ignore +# offset ? + +GetProgramivNV(id, pname, params) + return void + param id UInt32 in value + param pname VertexAttribEnumNV in value + param params Int32 out array [4] + category NV_vertex_program + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxflags ignore + glxvendorpriv 1298 + offset 585 + +GetProgramStringNV(id, pname, program) + return void + param id UInt32 in value + param pname VertexAttribEnumNV in value + param program ProgramCharacterNV out array [COMPSIZE(id/pname)] + category NV_vertex_program + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxflags ignore + glxvendorpriv 1299 + offset 586 + +GetTrackMatrixivNV(target, address, pname, params) + return void + param target VertexAttribEnumNV in value + param address UInt32 in value + param pname VertexAttribEnumNV in value + param params Int32 out array [1] + category NV_vertex_program + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxflags ignore + glxvendorpriv 1300 + offset 587 + +GetVertexAttribdvNV(index, pname, params) + return void + param index UInt32 in value + param pname VertexAttribEnumNV in value + param params Float64 out array [1] + category NV_vertex_program + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxvendorpriv 1301 + alias GetVertexAttribdv + +GetVertexAttribfvNV(index, pname, params) + return void + param index UInt32 in value + param pname VertexAttribEnumNV in value + param params Float32 out array [1] + category NV_vertex_program + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxvendorpriv 1302 + alias GetVertexAttribfv + +GetVertexAttribivNV(index, pname, params) + return void + param index UInt32 in value + param pname VertexAttribEnumNV in value + param params Int32 out array [1] + category NV_vertex_program + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxvendorpriv 1303 + alias GetVertexAttribiv + +GetVertexAttribPointervNV(index, pname, pointer) + return void + param index UInt32 in value + param pname VertexAttribEnumNV in value + param pointer VoidPointer out array [1] + category NV_vertex_program + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxflags ignore + alias GetVertexAttribPointerv + +IsProgramNV(id) + return Boolean + param id UInt32 in value + category NV_vertex_program + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxvendorpriv 1304 + alias IsProgram + +LoadProgramNV(target, id, len, program) + return void + param target VertexAttribEnumNV in value + param id UInt32 in value + param len SizeI in value + param program UInt8 in array [len] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4183 + offset 593 + +ProgramParameter4dNV(target, index, x, y, z, w) + return void + param target VertexAttribEnumNV in value + param index UInt32 in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + param w Float64 in value + category NV_vertex_program + version 1.2 + vectorequiv ProgramParameter4dvNV + extension soft WINSOFT NV10 + offset 594 + +ProgramParameter4dvNV(target, index, v) + return void + param target VertexAttribEnumNV in value + param index UInt32 in value + param v Float64 in array [4] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4185 + offset 595 + +ProgramParameter4fNV(target, index, x, y, z, w) + return void + param target VertexAttribEnumNV in value + param index UInt32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + param w Float32 in value + category NV_vertex_program + version 1.2 + vectorequiv ProgramParameter4fvNV + extension soft WINSOFT NV10 + offset 596 + +ProgramParameter4fvNV(target, index, v) + return void + param target VertexAttribEnumNV in value + param index UInt32 in value + param v Float32 in array [4] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4184 + offset 597 + +#??? 'count' was SizeI in the latest NVIDIA gl.spec, but UInt32 in the +#??? extension specification in the registry. +ProgramParameters4dvNV(target, index, count, v) + return void + param target VertexAttribEnumNV in value + param index UInt32 in value + param count UInt32 in value + param v Float64 in array [count*4] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4187 + offset 598 + +#??? 'count' was SizeI in the latest NVIDIA gl.spec, but UInt32 in the +#??? extension specification in the registry. +ProgramParameters4fvNV(target, index, count, v) + return void + param target VertexAttribEnumNV in value + param index UInt32 in value + param count UInt32 in value + param v Float32 in array [count*4] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4186 + offset 599 + +# ProgramParameterSigned4dNV(target, index, x, y, z, w) +# return void +# param target VertexAttribEnumNV in value +# param index Int32 in value +# param x Float64 in value +# param y Float64 in value +# param z Float64 in value +# param w Float64 in value +# category NV_vertex_program1_1_dcc +# version 1.2 +# vectorequiv ProgramParameterSigned4dvNV +# extension soft WINSOFT NV20 +# offset ? +# +# ProgramParameterSigned4dvNV(target, index, v) +# return void +# param target VertexAttribEnumNV in value +# param index Int32 in value +# param v Float64 in array [4] +# category NV_vertex_program1_1_dcc +# version 1.2 +# extension soft WINSOFT NV20 +# glxflags ignore +# offset ? +# +# ProgramParameterSigned4fNV(target, index, x, y, z, w) +# return void +# param target VertexAttribEnumNV in value +# param index Int32 in value +# param x Float32 in value +# param y Float32 in value +# param z Float32 in value +# param w Float32 in value +# category NV_vertex_program1_1_dcc +# version 1.2 +# vectorequiv ProgramParameterSigned4fvNV +# extension soft WINSOFT NV20 +# offset ? +# +# ProgramParameterSigned4fvNV(target, index, v) +# return void +# param target VertexAttribEnumNV in value +# param index Int32 in value +# param v Float32 in array [4] +# category NV_vertex_program1_1_dcc +# version 1.2 +# extension soft WINSOFT NV20 +# glxflags ignore +# offset ? +# +# ProgramParametersSigned4dvNV(target, index, count, v) +# return void +# param target VertexAttribEnumNV in value +# param index Int32 in value +# param count SizeI in value +# param v Float64 in array [count*4] +# category NV_vertex_program1_1_dcc +# version 1.2 +# extension soft WINSOFT NV20 +# glxflags ignore +# offset ? +# +# ProgramParametersSigned4fvNV(target, index, count, v) +# return void +# param target VertexAttribEnumNV in value +# param index Int32 in value +# param count SizeI in value +# param v Float32 in array [count*4] +# category NV_vertex_program1_1_dcc +# version 1.2 +# extension soft WINSOFT NV20 +# glxflags ignore +# offset ? + +RequestResidentProgramsNV(n, programs) + return void + param n SizeI in value + param programs UInt32 in array [n] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4182 + offset 600 + +TrackMatrixNV(target, address, matrix, transform) + return void + param target VertexAttribEnumNV in value + param address UInt32 in value + param matrix VertexAttribEnumNV in value + param transform VertexAttribEnumNV in value + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4188 + offset 601 + +VertexAttribPointerNV(index, fsize, type, stride, pointer) + return void + param index UInt32 in value + param fsize Int32 in value + param type VertexAttribEnumNV in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(fsize/type/stride)] retained + category NV_vertex_program + dlflags notlistable + version 1.2 + extension soft WINSOFT NV10 + glxflags ignore + offset 602 + +VertexAttrib1dNV(index, x) + return void + param index UInt32 in value + param x Float64 in value + category NV_vertex_program + version 1.2 + vectorequiv VertexAttrib1dvNV + extension soft WINSOFT NV10 + alias VertexAttrib1d + +VertexAttrib1dvNV(index, v) + return void + param index UInt32 in value + param v Float64 in array [1] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4197 + alias VertexAttrib1dv + +VertexAttrib1fNV(index, x) + return void + param index UInt32 in value + param x Float32 in value + category NV_vertex_program + version 1.2 + vectorequiv VertexAttrib1fvNV + extension soft WINSOFT NV10 + alias VertexAttrib1f + +VertexAttrib1fvNV(index, v) + return void + param index UInt32 in value + param v Float32 in array [1] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4193 + alias VertexAttrib1fv + +VertexAttrib1sNV(index, x) + return void + param index UInt32 in value + param x Int16 in value + category NV_vertex_program + version 1.2 + vectorequiv VertexAttrib1svNV + extension soft WINSOFT NV10 + alias VertexAttrib1s + +VertexAttrib1svNV(index, v) + return void + param index UInt32 in value + param v Int16 in array [1] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4189 + alias VertexAttrib1sv + +VertexAttrib2dNV(index, x, y) + return void + param index UInt32 in value + param x Float64 in value + param y Float64 in value + category NV_vertex_program + version 1.2 + vectorequiv VertexAttrib2dvNV + extension soft WINSOFT NV10 + alias VertexAttrib2d + +VertexAttrib2dvNV(index, v) + return void + param index UInt32 in value + param v Float64 in array [2] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4198 + alias VertexAttrib2dv + +VertexAttrib2fNV(index, x, y) + return void + param index UInt32 in value + param x Float32 in value + param y Float32 in value + category NV_vertex_program + version 1.2 + vectorequiv VertexAttrib2fvNV + extension soft WINSOFT NV10 + alias VertexAttrib2f + +VertexAttrib2fvNV(index, v) + return void + param index UInt32 in value + param v Float32 in array [2] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4194 + alias VertexAttrib2fv + +VertexAttrib2sNV(index, x, y) + return void + param index UInt32 in value + param x Int16 in value + param y Int16 in value + category NV_vertex_program + version 1.2 + vectorequiv VertexAttrib2svNV + extension soft WINSOFT NV10 + alias VertexAttrib2s + +VertexAttrib2svNV(index, v) + return void + param index UInt32 in value + param v Int16 in array [2] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4190 + alias VertexAttrib2sv + +VertexAttrib3dNV(index, x, y, z) + return void + param index UInt32 in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + category NV_vertex_program + version 1.2 + vectorequiv VertexAttrib3dvNV + extension soft WINSOFT NV10 + alias VertexAttrib3d + +VertexAttrib3dvNV(index, v) + return void + param index UInt32 in value + param v Float64 in array [3] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4199 + alias VertexAttrib3dv + +VertexAttrib3fNV(index, x, y, z) + return void + param index UInt32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category NV_vertex_program + version 1.2 + vectorequiv VertexAttrib3fvNV + extension soft WINSOFT NV10 + alias VertexAttrib3f + +VertexAttrib3fvNV(index, v) + return void + param index UInt32 in value + param v Float32 in array [3] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4195 + alias VertexAttrib3fv + +VertexAttrib3sNV(index, x, y, z) + return void + param index UInt32 in value + param x Int16 in value + param y Int16 in value + param z Int16 in value + category NV_vertex_program + version 1.2 + vectorequiv VertexAttrib3svNV + extension soft WINSOFT NV10 + alias VertexAttrib3s + +VertexAttrib3svNV(index, v) + return void + param index UInt32 in value + param v Int16 in array [3] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4191 + alias VertexAttrib3sv + +VertexAttrib4dNV(index, x, y, z, w) + return void + param index UInt32 in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + param w Float64 in value + category NV_vertex_program + version 1.2 + vectorequiv VertexAttrib4dvNV + extension soft WINSOFT NV10 + alias VertexAttrib4d + +VertexAttrib4dvNV(index, v) + return void + param index UInt32 in value + param v Float64 in array [4] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4200 + alias VertexAttrib4dv + +VertexAttrib4fNV(index, x, y, z, w) + return void + param index UInt32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + param w Float32 in value + category NV_vertex_program + version 1.2 + vectorequiv VertexAttrib4fvNV + extension soft WINSOFT NV10 + alias VertexAttrib4f + +VertexAttrib4fvNV(index, v) + return void + param index UInt32 in value + param v Float32 in array [4] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4196 + alias VertexAttrib4fv + +VertexAttrib4sNV(index, x, y, z, w) + return void + param index UInt32 in value + param x Int16 in value + param y Int16 in value + param z Int16 in value + param w Int16 in value + category NV_vertex_program + version 1.2 + vectorequiv VertexAttrib4svNV + extension soft WINSOFT NV10 + alias VertexAttrib4s + +VertexAttrib4svNV(index, v) + return void + param index UInt32 in value + param v Int16 in array [4] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4192 + alias VertexAttrib4sv + +VertexAttrib4ubNV(index, x, y, z, w) + return void + param index UInt32 in value + param x ColorUB in value + param y ColorUB in value + param z ColorUB in value + param w ColorUB in value + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + vectorequiv VertexAttrib4ubvNV + alias VertexAttrib4Nub + +VertexAttrib4ubvNV(index, v) + return void + param index UInt32 in value + param v ColorUB in array [4] + category NV_vertex_program + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4201 + alias VertexAttrib4Nubv + +VertexAttribs1dvNV(index, count, v) + return void + param index UInt32 in value + param count SizeI in value + param v Float64 in array [count] + category NV_vertex_program + dlflags handcode + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4210 + offset 629 + +VertexAttribs1fvNV(index, count, v) + return void + param index UInt32 in value + param count SizeI in value + param v Float32 in array [count] + category NV_vertex_program + dlflags handcode + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4206 + offset 630 + +VertexAttribs1svNV(index, count, v) + return void + param index UInt32 in value + param count SizeI in value + param v Int16 in array [count] + category NV_vertex_program + dlflags handcode + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4202 + offset 631 + +VertexAttribs2dvNV(index, count, v) + return void + param index UInt32 in value + param count SizeI in value + param v Float64 in array [count*2] + category NV_vertex_program + dlflags handcode + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4211 + offset 632 + +VertexAttribs2fvNV(index, count, v) + return void + param index UInt32 in value + param count SizeI in value + param v Float32 in array [count*2] + category NV_vertex_program + dlflags handcode + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4207 + offset 633 + +VertexAttribs2svNV(index, count, v) + return void + param index UInt32 in value + param count SizeI in value + param v Int16 in array [count*2] + category NV_vertex_program + dlflags handcode + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4203 + offset 634 + +VertexAttribs3dvNV(index, count, v) + return void + param index UInt32 in value + param count SizeI in value + param v Float64 in array [count*3] + category NV_vertex_program + dlflags handcode + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4212 + offset 635 + +VertexAttribs3fvNV(index, count, v) + return void + param index UInt32 in value + param count SizeI in value + param v Float32 in array [count*3] + category NV_vertex_program + dlflags handcode + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4208 + offset 636 + +VertexAttribs3svNV(index, count, v) + return void + param index UInt32 in value + param count SizeI in value + param v Int16 in array [count*3] + category NV_vertex_program + dlflags handcode + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4204 + offset 637 + +VertexAttribs4dvNV(index, count, v) + return void + param index UInt32 in value + param count SizeI in value + param v Float64 in array [count*4] + category NV_vertex_program + dlflags handcode + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4213 + offset 638 + +VertexAttribs4fvNV(index, count, v) + return void + param index UInt32 in value + param count SizeI in value + param v Float32 in array [count*4] + category NV_vertex_program + dlflags handcode + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4209 + offset 639 + +VertexAttribs4svNV(index, count, v) + return void + param index UInt32 in value + param count SizeI in value + param v Int16 in array [count*4] + category NV_vertex_program + dlflags handcode + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4205 + offset 640 + +VertexAttribs4ubvNV(index, count, v) + return void + param index UInt32 in value + param count SizeI in value + param v ColorUB in array [count*4] + category NV_vertex_program + dlflags handcode + version 1.2 + extension soft WINSOFT NV10 + glxropcode 4214 + offset 641 + + +############################################################################### +# +# Extension #234 - GLX_SGIX_visual_select_group +# +############################################################################### + +############################################################################### +# +# Extension #235 +# SGIX_texture_coordinate_clamp commands +# +############################################################################### + +# (none) +newcategory: SGIX_texture_coordinate_clamp + +############################################################################### +# +# Extension #236 +# SGIX_scalebias_hint commands +# +############################################################################### + +# (none) +newcategory: SGIX_scalebias_hint + +############################################################################### +# +# Extension #237 - GLX_OML_swap_method commands +# Extension #238 - GLX_OML_sync_control commands +# +############################################################################### + +############################################################################### +# +# Extension #239 +# OML_interlace commands +# +############################################################################### + +# (none) +newcategory: OML_interlace + +############################################################################### +# +# Extension #240 +# OML_subsample commands +# +############################################################################### + +# (none) +newcategory: OML_subsample + +############################################################################### +# +# Extension #241 +# OML_resample commands +# +############################################################################### + +# (none) +newcategory: OML_resample + +############################################################################### +# +# Extension #242 - WGL_OML_sync_control commands +# +############################################################################### + +############################################################################### +# +# Extension #243 +# NV_copy_depth_to_color commands +# +############################################################################### + +# (none) +newcategory: NV_copy_depth_to_color + +############################################################################### +# +# Extension #244 +# ATI_envmap_bumpmap commands +# +############################################################################### + +TexBumpParameterivATI(pname, param) + return void + param pname TexBumpParameterATI in value + param param Int32 in array [COMPSIZE(pname)] + category ATI_envmap_bumpmap + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +TexBumpParameterfvATI(pname, param) + return void + param pname TexBumpParameterATI in value + param param Float32 in array [COMPSIZE(pname)] + category ATI_envmap_bumpmap + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetTexBumpParameterivATI(pname, param) + return void + param pname GetTexBumpParameterATI in value + param param Int32 out array [COMPSIZE(pname)] + category ATI_envmap_bumpmap + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetTexBumpParameterfvATI(pname, param) + return void + param pname GetTexBumpParameterATI in value + param param Float32 out array [COMPSIZE(pname)] + category ATI_envmap_bumpmap + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #245 +# ATI_fragment_shader commands +# +############################################################################### + +GenFragmentShadersATI(range) + return UInt32 + param range UInt32 in value + category ATI_fragment_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +BindFragmentShaderATI(id) + return void + param id UInt32 in value + category ATI_fragment_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +DeleteFragmentShaderATI(id) + return void + param id UInt32 in value + category ATI_fragment_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +BeginFragmentShaderATI() + return void + category ATI_fragment_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +EndFragmentShaderATI() + return void + category ATI_fragment_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +PassTexCoordATI(dst, coord, swizzle) + return void + param dst UInt32 in value + param coord UInt32 in value + param swizzle SwizzleOpATI in value + category ATI_fragment_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +SampleMapATI(dst, interp, swizzle) + return void + param dst UInt32 in value + param interp UInt32 in value + param swizzle SwizzleOpATI in value + category ATI_fragment_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +ColorFragmentOp1ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod) + return void + param op FragmentOpATI in value + param dst UInt32 in value + param dstMask UInt32 in value + param dstMod UInt32 in value + param arg1 UInt32 in value + param arg1Rep UInt32 in value + param arg1Mod UInt32 in value + category ATI_fragment_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +ColorFragmentOp2ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod) + return void + param op FragmentOpATI in value + param dst UInt32 in value + param dstMask UInt32 in value + param dstMod UInt32 in value + param arg1 UInt32 in value + param arg1Rep UInt32 in value + param arg1Mod UInt32 in value + param arg2 UInt32 in value + param arg2Rep UInt32 in value + param arg2Mod UInt32 in value + category ATI_fragment_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +ColorFragmentOp3ATI(op, dst, dstMask, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, arg3Rep, arg3Mod) + return void + param op FragmentOpATI in value + param dst UInt32 in value + param dstMask UInt32 in value + param dstMod UInt32 in value + param arg1 UInt32 in value + param arg1Rep UInt32 in value + param arg1Mod UInt32 in value + param arg2 UInt32 in value + param arg2Rep UInt32 in value + param arg2Mod UInt32 in value + param arg3 UInt32 in value + param arg3Rep UInt32 in value + param arg3Mod UInt32 in value + category ATI_fragment_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +AlphaFragmentOp1ATI(op, dst, dstMod, arg1, arg1Rep, arg1Mod) + return void + param op FragmentOpATI in value + param dst UInt32 in value + param dstMod UInt32 in value + param arg1 UInt32 in value + param arg1Rep UInt32 in value + param arg1Mod UInt32 in value + category ATI_fragment_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +AlphaFragmentOp2ATI(op, dst, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod) + return void + param op FragmentOpATI in value + param dst UInt32 in value + param dstMod UInt32 in value + param arg1 UInt32 in value + param arg1Rep UInt32 in value + param arg1Mod UInt32 in value + param arg2 UInt32 in value + param arg2Rep UInt32 in value + param arg2Mod UInt32 in value + category ATI_fragment_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +AlphaFragmentOp3ATI(op, dst, dstMod, arg1, arg1Rep, arg1Mod, arg2, arg2Rep, arg2Mod, arg3, arg3Rep, arg3Mod) + return void + param op FragmentOpATI in value + param dst UInt32 in value + param dstMod UInt32 in value + param arg1 UInt32 in value + param arg1Rep UInt32 in value + param arg1Mod UInt32 in value + param arg2 UInt32 in value + param arg2Rep UInt32 in value + param arg2Mod UInt32 in value + param arg3 UInt32 in value + param arg3Rep UInt32 in value + param arg3Mod UInt32 in value + category ATI_fragment_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +SetFragmentShaderConstantATI(dst, value) + return void + param dst UInt32 in value + param value ConstFloat32 in array [4] + category ATI_fragment_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #246 +# ATI_pn_triangles commands +# +############################################################################### + +PNTrianglesiATI(pname, param) + return void + param pname PNTrianglesPNameATI in value + param param Int32 in value + category ATI_pn_triangles + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +PNTrianglesfATI(pname, param) + return void + param pname PNTrianglesPNameATI in value + param param Float32 in value + category ATI_pn_triangles + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #247 +# ATI_vertex_array_object commands +# +############################################################################### + +NewObjectBufferATI(size, pointer, usage) + return UInt32 + param size SizeI in value + param pointer ConstVoid in array [size] + param usage ArrayObjectUsageATI in value + category ATI_vertex_array_object + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +IsObjectBufferATI(buffer) + return Boolean + param buffer UInt32 in value + category ATI_vertex_array_object + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +UpdateObjectBufferATI(buffer, offset, size, pointer, preserve) + return void + param buffer UInt32 in value + param offset UInt32 in value + param size SizeI in value + param pointer ConstVoid in array [size] + param preserve PreserveModeATI in value + category ATI_vertex_array_object + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetObjectBufferfvATI(buffer, pname, params) + return void + param buffer UInt32 in value + param pname ArrayObjectPNameATI in value + param params Float32 out array [1] + category ATI_vertex_array_object + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetObjectBufferivATI(buffer, pname, params) + return void + param buffer UInt32 in value + param pname ArrayObjectPNameATI in value + param params Int32 out array [1] + category ATI_vertex_array_object + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +FreeObjectBufferATI(buffer) + return void + param buffer UInt32 in value + category ATI_vertex_array_object + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +ArrayObjectATI(array, size, type, stride, buffer, offset) + return void + param array EnableCap in value + param size Int32 in value + param type ScalarType in value + param stride SizeI in value + param buffer UInt32 in value + param offset UInt32 in value + category ATI_vertex_array_object + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetArrayObjectfvATI(array, pname, params) + return void + param array EnableCap in value + param pname ArrayObjectPNameATI in value + param params Float32 out array [1] + category ATI_vertex_array_object + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetArrayObjectivATI(array, pname, params) + return void + param array EnableCap in value + param pname ArrayObjectPNameATI in value + param params Int32 out array [1] + category ATI_vertex_array_object + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +VariantArrayObjectATI(id, type, stride, buffer, offset) + return void + param id UInt32 in value + param type ScalarType in value + param stride SizeI in value + param buffer UInt32 in value + param offset UInt32 in value + category ATI_vertex_array_object + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetVariantArrayObjectfvATI(id, pname, params) + return void + param id UInt32 in value + param pname ArrayObjectPNameATI in value + param params Float32 out array [1] + category ATI_vertex_array_object + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetVariantArrayObjectivATI(id, pname, params) + return void + param id UInt32 in value + param pname ArrayObjectPNameATI in value + param params Int32 out array [1] + category ATI_vertex_array_object + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #248 +# EXT_vertex_shader commands +# +############################################################################### + +BeginVertexShaderEXT() + return void + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +EndVertexShaderEXT() + return void + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +BindVertexShaderEXT(id) + return void + param id UInt32 in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GenVertexShadersEXT(range) + return UInt32 + param range UInt32 in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +DeleteVertexShaderEXT(id) + return void + param id UInt32 in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +ShaderOp1EXT(op, res, arg1) + return void + param op VertexShaderOpEXT in value + param res UInt32 in value + param arg1 UInt32 in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +ShaderOp2EXT(op, res, arg1, arg2) + return void + param op VertexShaderOpEXT in value + param res UInt32 in value + param arg1 UInt32 in value + param arg2 UInt32 in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +ShaderOp3EXT(op, res, arg1, arg2, arg3) + return void + param op VertexShaderOpEXT in value + param res UInt32 in value + param arg1 UInt32 in value + param arg2 UInt32 in value + param arg3 UInt32 in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +SwizzleEXT(res, in, outX, outY, outZ, outW) + return void + param res UInt32 in value + param in UInt32 in value + param outX VertexShaderCoordOutEXT in value + param outY VertexShaderCoordOutEXT in value + param outZ VertexShaderCoordOutEXT in value + param outW VertexShaderCoordOutEXT in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +WriteMaskEXT(res, in, outX, outY, outZ, outW) + return void + param res UInt32 in value + param in UInt32 in value + param outX VertexShaderWriteMaskEXT in value + param outY VertexShaderWriteMaskEXT in value + param outZ VertexShaderWriteMaskEXT in value + param outW VertexShaderWriteMaskEXT in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +InsertComponentEXT(res, src, num) + return void + param res UInt32 in value + param src UInt32 in value + param num UInt32 in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +ExtractComponentEXT(res, src, num) + return void + param res UInt32 in value + param src UInt32 in value + param num UInt32 in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GenSymbolsEXT(datatype, storagetype, range, components) + return UInt32 + param datatype DataTypeEXT in value + param storagetype VertexShaderStorageTypeEXT in value + param range ParameterRangeEXT in value + param components UInt32 in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +SetInvariantEXT(id, type, addr) + return void + param id UInt32 in value + param type ScalarType in value + param addr Void in array [COMPSIZE(id/type)] + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +SetLocalConstantEXT(id, type, addr) + return void + param id UInt32 in value + param type ScalarType in value + param addr Void in array [COMPSIZE(id/type)] + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VariantbvEXT(id, addr) + return void + param id UInt32 in value + param addr Int8 in array [COMPSIZE(id)] + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VariantsvEXT(id, addr) + return void + param id UInt32 in value + param addr Int16 in array [COMPSIZE(id)] + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VariantivEXT(id, addr) + return void + param id UInt32 in value + param addr Int32 in array [COMPSIZE(id)] + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VariantfvEXT(id, addr) + return void + param id UInt32 in value + param addr Float32 in array [COMPSIZE(id)] + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VariantdvEXT(id, addr) + return void + param id UInt32 in value + param addr Float64 in array [COMPSIZE(id)] + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VariantubvEXT(id, addr) + return void + param id UInt32 in value + param addr UInt8 in array [COMPSIZE(id)] + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VariantusvEXT(id, addr) + return void + param id UInt32 in value + param addr UInt16 in array [COMPSIZE(id)] + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VariantuivEXT(id, addr) + return void + param id UInt32 in value + param addr UInt32 in array [COMPSIZE(id)] + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VariantPointerEXT(id, type, stride, addr) + return void + param id UInt32 in value + param type ScalarType in value + param stride UInt32 in value + param addr Void in array [COMPSIZE(id/type/stride)] + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +EnableVariantClientStateEXT(id) + return void + param id UInt32 in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +DisableVariantClientStateEXT(id) + return void + param id UInt32 in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +BindLightParameterEXT(light, value) + return UInt32 + param light LightName in value + param value LightParameter in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +BindMaterialParameterEXT(face, value) + return UInt32 + param face MaterialFace in value + param value MaterialParameter in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +BindTexGenParameterEXT(unit, coord, value) + return UInt32 + param unit TextureUnit in value + param coord TextureCoordName in value + param value TextureGenParameter in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +BindTextureUnitParameterEXT(unit, value) + return UInt32 + param unit TextureUnit in value + param value VertexShaderTextureUnitParameter in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +BindParameterEXT(value) + return UInt32 + param value VertexShaderParameterEXT in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +IsVariantEnabledEXT(id, cap) + return Boolean + param id UInt32 in value + param cap VariantCapEXT in value + category EXT_vertex_shader + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetVariantBooleanvEXT(id, value, data) + return void + param id UInt32 in value + param value GetVariantValueEXT in value + param data Boolean out array [COMPSIZE(id)] + category EXT_vertex_shader + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetVariantIntegervEXT(id, value, data) + return void + param id UInt32 in value + param value GetVariantValueEXT in value + param data Int32 out array [COMPSIZE(id)] + category EXT_vertex_shader + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetVariantFloatvEXT(id, value, data) + return void + param id UInt32 in value + param value GetVariantValueEXT in value + param data Float32 out array [COMPSIZE(id)] + category EXT_vertex_shader + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetVariantPointervEXT(id, value, data) + return void + param id UInt32 in value + param value GetVariantValueEXT in value + param data VoidPointer out array [COMPSIZE(id)] + category EXT_vertex_shader + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetInvariantBooleanvEXT(id, value, data) + return void + param id UInt32 in value + param value GetVariantValueEXT in value + param data Boolean out array [COMPSIZE(id)] + category EXT_vertex_shader + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetInvariantIntegervEXT(id, value, data) + return void + param id UInt32 in value + param value GetVariantValueEXT in value + param data Int32 out array [COMPSIZE(id)] + category EXT_vertex_shader + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetInvariantFloatvEXT(id, value, data) + return void + param id UInt32 in value + param value GetVariantValueEXT in value + param data Float32 out array [COMPSIZE(id)] + category EXT_vertex_shader + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetLocalConstantBooleanvEXT(id, value, data) + return void + param id UInt32 in value + param value GetVariantValueEXT in value + param data Boolean out array [COMPSIZE(id)] + category EXT_vertex_shader + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetLocalConstantIntegervEXT(id, value, data) + return void + param id UInt32 in value + param value GetVariantValueEXT in value + param data Int32 out array [COMPSIZE(id)] + category EXT_vertex_shader + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetLocalConstantFloatvEXT(id, value, data) + return void + param id UInt32 in value + param value GetVariantValueEXT in value + param data Float32 out array [COMPSIZE(id)] + category EXT_vertex_shader + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #249 +# ATI_vertex_streams commands +# +############################################################################### + +VertexStream1sATI(stream, x) + return void + param stream VertexStreamATI in value + param x Int16 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream1svATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Int16 in array [1] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream1iATI(stream, x) + return void + param stream VertexStreamATI in value + param x Int32 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream1ivATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Int32 in array [1] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream1fATI(stream, x) + return void + param stream VertexStreamATI in value + param x Float32 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream1fvATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Float32 in array [1] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream1dATI(stream, x) + return void + param stream VertexStreamATI in value + param x Float64 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream1dvATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Float64 in array [1] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream2sATI(stream, x, y) + return void + param stream VertexStreamATI in value + param x Int16 in value + param y Int16 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream2svATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Int16 in array [2] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream2iATI(stream, x, y) + return void + param stream VertexStreamATI in value + param x Int32 in value + param y Int32 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream2ivATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Int32 in array [2] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream2fATI(stream, x, y) + return void + param stream VertexStreamATI in value + param x Float32 in value + param y Float32 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream2fvATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Float32 in array [2] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream2dATI(stream, x, y) + return void + param stream VertexStreamATI in value + param x Float64 in value + param y Float64 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream2dvATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Float64 in array [2] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream3sATI(stream, x, y, z) + return void + param stream VertexStreamATI in value + param x Int16 in value + param y Int16 in value + param z Int16 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream3svATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Int16 in array [3] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream3iATI(stream, x, y, z) + return void + param stream VertexStreamATI in value + param x Int32 in value + param y Int32 in value + param z Int32 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream3ivATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Int32 in array [3] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream3fATI(stream, x, y, z) + return void + param stream VertexStreamATI in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream3fvATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Float32 in array [3] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream3dATI(stream, x, y, z) + return void + param stream VertexStreamATI in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream3dvATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Float64 in array [3] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream4sATI(stream, x, y, z, w) + return void + param stream VertexStreamATI in value + param x Int16 in value + param y Int16 in value + param z Int16 in value + param w Int16 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream4svATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Int16 in array [4] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream4iATI(stream, x, y, z, w) + return void + param stream VertexStreamATI in value + param x Int32 in value + param y Int32 in value + param z Int32 in value + param w Int32 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream4ivATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Int32 in array [4] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream4fATI(stream, x, y, z, w) + return void + param stream VertexStreamATI in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + param w Float32 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream4fvATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Float32 in array [4] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream4dATI(stream, x, y, z, w) + return void + param stream VertexStreamATI in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + param w Float64 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexStream4dvATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Float64 in array [4] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +NormalStream3bATI(stream, nx, ny, nz) + return void + param stream VertexStreamATI in value + param nx Int8 in value + param ny Int8 in value + param nz Int8 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +NormalStream3bvATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Int8 in array [3] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +NormalStream3sATI(stream, nx, ny, nz) + return void + param stream VertexStreamATI in value + param nx Int16 in value + param ny Int16 in value + param nz Int16 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +NormalStream3svATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Int16 in array [3] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +NormalStream3iATI(stream, nx, ny, nz) + return void + param stream VertexStreamATI in value + param nx Int32 in value + param ny Int32 in value + param nz Int32 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +NormalStream3ivATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Int32 in array [3] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +NormalStream3fATI(stream, nx, ny, nz) + return void + param stream VertexStreamATI in value + param nx Float32 in value + param ny Float32 in value + param nz Float32 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +NormalStream3fvATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Float32 in array [3] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +NormalStream3dATI(stream, nx, ny, nz) + return void + param stream VertexStreamATI in value + param nx Float64 in value + param ny Float64 in value + param nz Float64 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +NormalStream3dvATI(stream, coords) + return void + param stream VertexStreamATI in value + param coords Float64 in array [3] + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +ClientActiveVertexStreamATI(stream) + return void + param stream VertexStreamATI in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexBlendEnviATI(pname, param) + return void + param pname VertexStreamATI in value + param param Int32 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexBlendEnvfATI(pname, param) + return void + param pname VertexStreamATI in value + param param Float32 in value + category ATI_vertex_streams + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #250 - WGL_I3D_digital_video_control +# Extension #251 - WGL_I3D_gamma +# Extension #252 - WGL_I3D_genlock +# Extension #253 - WGL_I3D_image_buffer +# Extension #254 - WGL_I3D_swap_frame_lock +# Extension #255 - WGL_I3D_swap_frame_usage +# +############################################################################### + +############################################################################### +# +# Extension #256 +# ATI_element_array commands +# +############################################################################### + +ElementPointerATI(type, pointer) + return void + param type ElementPointerTypeATI in value + param pointer Void in array [COMPSIZE(type)] retained + category ATI_element_array + dlflags notlistable + glxflags client-handcode client-intercept server-handcode + version 1.2 + offset ? + +DrawElementArrayATI(mode, count) + return void + param mode BeginMode in value + param count SizeI in value + category ATI_element_array + dlflags handcode + glxflags client-handcode client-intercept server-handcode + version 1.2 + offset ? + +DrawRangeElementArrayATI(mode, start, end, count) + return void + param mode BeginMode in value + param start UInt32 in value + param end UInt32 in value + param count SizeI in value + category ATI_element_array + dlflags handcode + glxflags client-handcode client-intercept server-handcode + version 1.2 + offset ? + +############################################################################### +# +# Extension #257 +# SUN_mesh_array commands +# +############################################################################### + +DrawMeshArraysSUN(mode, first, count, width) + return void + param mode BeginMode in value + param first Int32 in value + param count SizeI in value + param width SizeI in value + category SUN_mesh_array + dlflags handcode + glxflags client-handcode client-intercept server-handcode + version 1.1 + glxropcode ? + offset ? + +############################################################################### +# +# Extension #258 +# SUN_slice_accum commands +# +############################################################################### + +# (none) +newcategory: SUN_slice_accum + +############################################################################### +# +# Extension #259 +# NV_multisample_filter_hint commands +# +############################################################################### + +# (none) +newcategory: NV_multisample_filter_hint + +############################################################################### +# +# Extension #260 +# NV_depth_clamp commands +# +############################################################################### + +# (none) +newcategory: NV_depth_clamp + +############################################################################### +# +# Extension #261 +# NV_occlusion_query commands +# +############################################################################### + +GenOcclusionQueriesNV(n, ids) + return void + param n SizeI in value + param ids UInt32 out array [n] + dlflags notlistable + category NV_occlusion_query + version 1.2 + extension soft WINSOFT NV20 + glxflags ignore + +DeleteOcclusionQueriesNV(n, ids) + return void + param n SizeI in value + param ids UInt32 in array [n] + dlflags notlistable + category NV_occlusion_query + version 1.2 + extension soft WINSOFT NV20 + glxflags ignore + +IsOcclusionQueryNV(id) + return Boolean + param id UInt32 in value + dlflags notlistable + category NV_occlusion_query + version 1.2 + extension soft WINSOFT NV20 + glxflags ignore + +BeginOcclusionQueryNV(id) + return void + param id UInt32 in value + category NV_occlusion_query + version 1.2 + extension soft WINSOFT NV20 + glxflags ignore + +EndOcclusionQueryNV() + return void + category NV_occlusion_query + version 1.2 + extension soft WINSOFT NV20 + glxflags ignore + +GetOcclusionQueryivNV(id, pname, params) + return void + param id UInt32 in value + param pname OcclusionQueryParameterNameNV in value + param params Int32 out array [COMPSIZE(pname)] + dlflags notlistable + category NV_occlusion_query + version 1.2 + extension soft WINSOFT NV20 + glxflags ignore + +GetOcclusionQueryuivNV(id, pname, params) + return void + param id UInt32 in value + param pname OcclusionQueryParameterNameNV in value + param params UInt32 out array [COMPSIZE(pname)] + dlflags notlistable + category NV_occlusion_query + version 1.2 + extension soft WINSOFT NV20 + glxflags ignore + +############################################################################### +# +# Extension #262 +# NV_point_sprite commands +# +############################################################################### + +PointParameteriNV(pname, param) + return void + param pname PointParameterNameARB in value + param param Int32 in value + category NV_point_sprite + version 1.2 + extension soft WINSOFT NV20 + glxropcode 4221 + alias PointParameteri + +PointParameterivNV(pname, params) + return void + param pname PointParameterNameARB in value + param params Int32 in array [COMPSIZE(pname)] + category NV_point_sprite + version 1.2 + extension soft WINSOFT NV20 + glxropcode 4222 + alias PointParameteriv + +############################################################################### +# +# Extension #263 - WGL_NV_render_depth_texture +# Extension #264 - WGL_NV_render_texture_rectangle +# +############################################################################### + +############################################################################### +# +# Extension #265 +# NV_texture_shader3 commands +# +############################################################################### + +# (none) +newcategory: NV_texture_shader3 + +############################################################################### +# +# Extension #266 +# NV_vertex_program1_1 commands +# +############################################################################### + +# (none) +newcategory: NV_vertex_program1_1 + +############################################################################### +# +# Extension #267 +# EXT_shadow_funcs commands +# +############################################################################### + +# (none) +newcategory: EXT_shadow_funcs + +############################################################################### +# +# Extension #268 +# EXT_stencil_two_side commands +# +############################################################################### + +ActiveStencilFaceEXT(face) + return void + param face StencilFaceDirection in value + category EXT_stencil_two_side + version 1.3 + glxropcode 4220 + offset 646 + +############################################################################### +# +# Extension #269 +# ATI_text_fragment_shader commands +# +############################################################################### + +# Uses ARB_vertex_program entry points +newcategory: ATI_text_fragment_shader + +############################################################################### +# +# Extension #270 +# APPLE_client_storage commands +# +############################################################################### + +# (none) +newcategory: APPLE_client_storage + +############################################################################### +# +# Extension #271 +# APPLE_element_array commands +# +############################################################################### + +# @@ Need to verify/add GLX protocol + +# @@@ like #256 ATI_element_array +ElementPointerAPPLE(type, pointer) + return void + param type ElementPointerTypeATI in value + param pointer Void in array [type] + category APPLE_element_array + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +DrawElementArrayAPPLE(mode, first, count) + return void + param mode BeginMode in value + param first Int32 in value + param count SizeI in value + category APPLE_element_array + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +DrawRangeElementArrayAPPLE(mode, start, end, first, count) + return void + param mode BeginMode in value + param start UInt32 in value + param end UInt32 in value + param first Int32 in value + param count SizeI in value + category APPLE_element_array + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +MultiDrawElementArrayAPPLE(mode, first, count, primcount) + return void + param mode BeginMode in value + param first Int32 in array [primcount] + param count SizeI in array [primcount] + param primcount SizeI in value + category APPLE_element_array + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +MultiDrawRangeElementArrayAPPLE(mode, start, end, first, count, primcount) + return void + param mode BeginMode in value + param start UInt32 in value + param end UInt32 in value + param first Int32 in array [primcount] + param count SizeI in array [primcount] + param primcount SizeI in value + category APPLE_element_array + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #272 +# APPLE_fence commands +# +############################################################################### + +# @@ Need to verify/add GLX protocol + +# @@@ like #222 NV_fence +GenFencesAPPLE(n, fences) + return void + param n SizeI in value + param fences FenceNV out array [n] + category APPLE_fence + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +DeleteFencesAPPLE(n, fences) + return void + param n SizeI in value + param fences FenceNV in array [n] + category APPLE_fence + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +SetFenceAPPLE(fence) + return void + param fence FenceNV in value + category APPLE_fence + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +IsFenceAPPLE(fence) + return Boolean + param fence FenceNV in value + category APPLE_fence + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +TestFenceAPPLE(fence) + return Boolean + param fence FenceNV in value + category APPLE_fence + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +FinishFenceAPPLE(fence) + return void + param fence FenceNV in value + category APPLE_fence + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +TestObjectAPPLE(object, name) + return Boolean + param object ObjectTypeAPPLE in value + param name UInt32 in value + category APPLE_fence + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +FinishObjectAPPLE(object, name) + return void + param object ObjectTypeAPPLE in value + param name Int32 in value + category APPLE_fence + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #273 +# APPLE_vertex_array_object commands +# +############################################################################### + +BindVertexArrayAPPLE(array) + return void + param array UInt32 in value + category APPLE_vertex_array_object + version 1.2 + extension + glxropcode ? + glxflags ignore + alias BindVertexArray + +DeleteVertexArraysAPPLE(n, arrays) + return void + param n SizeI in value + param arrays UInt32 in array [n] + category APPLE_vertex_array_object + version 1.2 + extension + glxropcode ? + glxflags ignore + alias DeleteVertexArrays + +GenVertexArraysAPPLE(n, arrays) + return void + param n SizeI in value + param arrays UInt32 out array [n] + category APPLE_vertex_array_object + version 1.2 + extension + glxropcode ? + glxflags ignore + alias GenVertexArray + +IsVertexArrayAPPLE(array) + return Boolean + param array UInt32 in value + category APPLE_vertex_array_object + version 1.2 + extension + glxropcode ? + glxflags ignore + alias IsVertexArray + +############################################################################### +# +# Extension #274 +# APPLE_vertex_array_range commands +# +############################################################################### + +# @@ Need to verify/add GLX protocol + +# @@@ like #190 NV_vertex_array_range, +VertexArrayRangeAPPLE(length, pointer) + return void + param length SizeI in value + param pointer Void out array [length] + category APPLE_vertex_array_range + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +FlushVertexArrayRangeAPPLE(length, pointer) + return void + param length SizeI in value + param pointer Void out array [length] + category APPLE_vertex_array_range + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexArrayParameteriAPPLE(pname, param) + return void + param pname VertexArrayPNameAPPLE in value + param param Int32 in value + category APPLE_vertex_array_range + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #275 +# APPLE_ycbcr_422 commands +# +############################################################################### + +# (none) +newcategory: APPLE_ycbcr_422 + +############################################################################### +# +# Extension #276 +# S3_s3tc commands +# +############################################################################### + +# (none) +newcategory: S3_s3tc + +############################################################################### +# +# Extension #277 +# ATI_draw_buffers commands +# +############################################################################### + +DrawBuffersATI(n, bufs) + return void + param n SizeI in value + param bufs DrawBufferModeATI in array [n] + category ATI_draw_buffers + version 1.2 + extension + glxropcode 233 + alias DrawBuffers + +############################################################################### +# +# Extension #278 - WGL_ATI_pixel_format_float +# +############################################################################### +newcategory: ATI_pixel_format_float +passthru: /* This is really a WGL extension, but defines some associated GL enums. +passthru: * ATI does not export "GL_ATI_pixel_format_float" in the GL_EXTENSIONS string. +passthru: */ + +############################################################################### +# +# Extension #279 +# ATI_texture_env_combine3 commands +# +############################################################################### + +# (none) +newcategory: ATI_texture_env_combine3 + +############################################################################### +# +# Extension #280 +# ATI_texture_float commands +# +############################################################################### + +# (none) +newcategory: ATI_texture_float + +############################################################################### +# +# Extension #281 (also WGL_NV_float_buffer) +# NV_float_buffer commands +# +############################################################################### + +# (none) +newcategory: NV_float_buffer + +############################################################################### +# +# Extension #282 +# NV_fragment_program commands +# +############################################################################### + +# @@ Need to verify/add GLX protocol + +# Some NV_fragment_program entry points are shared with ARB_vertex_program, +# and are only included in that #define block, for now. +newcategory: NV_fragment_program +passthru: /* Some NV_fragment_program entry points are shared with ARB_vertex_program. */ + +ProgramNamedParameter4fNV(id, len, name, x, y, z, w) + return void + param id UInt32 in value + param len SizeI in value + param name UInt8 in array [1] + param x Float32 in value + param y Float32 in value + param z Float32 in value + param w Float32 in value + category NV_fragment_program + version 1.2 + extension + glxropcode ? + glxflags ignore + offset 682 + +ProgramNamedParameter4dNV(id, len, name, x, y, z, w) + return void + param id UInt32 in value + param len SizeI in value + param name UInt8 in array [1] + param x Float64 in value + param y Float64 in value + param z Float64 in value + param w Float64 in value + category NV_fragment_program + version 1.2 + extension + glxropcode ? + glxflags ignore + offset 683 + +ProgramNamedParameter4fvNV(id, len, name, v) + return void + param id UInt32 in value + param len SizeI in value + param name UInt8 in array [1] + param v Float32 in array [4] + category NV_fragment_program + version 1.2 + extension + glxropcode ? + glxflags ignore + offset 684 + +ProgramNamedParameter4dvNV(id, len, name, v) + return void + param id UInt32 in value + param len SizeI in value + param name UInt8 in array [1] + param v Float64 in array [4] + category NV_fragment_program + version 1.2 + extension + glxropcode ? + glxflags ignore + offset 685 + +GetProgramNamedParameterfvNV(id, len, name, params) + return void + param id UInt32 in value + param len SizeI in value + param name UInt8 in array [1] + param params Float32 out array [4] + category NV_fragment_program + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset 686 + +GetProgramNamedParameterdvNV(id, len, name, params) + return void + param id UInt32 in value + param len SizeI in value + param name UInt8 in array [1] + param params Float64 out array [4] + category NV_fragment_program + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset 687 + +############################################################################### +# +# Extension #283 +# NV_half_float commands +# +############################################################################### + +# @@ Need to verify/add GLX protocol + +Vertex2hNV(x, y) + return void + param x Half16NV in value + param y Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +Vertex2hvNV(v) + return void + param v Half16NV in array [2] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +Vertex3hNV(x, y, z) + return void + param x Half16NV in value + param y Half16NV in value + param z Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +Vertex3hvNV(v) + return void + param v Half16NV in array [3] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +Vertex4hNV(x, y, z, w) + return void + param x Half16NV in value + param y Half16NV in value + param z Half16NV in value + param w Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +Vertex4hvNV(v) + return void + param v Half16NV in array [4] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +Normal3hNV(nx, ny, nz) + return void + param nx Half16NV in value + param ny Half16NV in value + param nz Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +Normal3hvNV(v) + return void + param v Half16NV in array [3] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +Color3hNV(red, green, blue) + return void + param red Half16NV in value + param green Half16NV in value + param blue Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +Color3hvNV(v) + return void + param v Half16NV in array [3] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +Color4hNV(red, green, blue, alpha) + return void + param red Half16NV in value + param green Half16NV in value + param blue Half16NV in value + param alpha Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +Color4hvNV(v) + return void + param v Half16NV in array [4] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +TexCoord1hNV(s) + return void + param s Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +TexCoord1hvNV(v) + return void + param v Half16NV in array [1] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +TexCoord2hNV(s, t) + return void + param s Half16NV in value + param t Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +TexCoord2hvNV(v) + return void + param v Half16NV in array [2] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +TexCoord3hNV(s, t, r) + return void + param s Half16NV in value + param t Half16NV in value + param r Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +TexCoord3hvNV(v) + return void + param v Half16NV in array [3] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +TexCoord4hNV(s, t, r, q) + return void + param s Half16NV in value + param t Half16NV in value + param r Half16NV in value + param q Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +TexCoord4hvNV(v) + return void + param v Half16NV in array [4] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +MultiTexCoord1hNV(target, s) + return void + param target TextureUnit in value + param s Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +MultiTexCoord1hvNV(target, v) + return void + param target TextureUnit in value + param v Half16NV in array [1] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +MultiTexCoord2hNV(target, s, t) + return void + param target TextureUnit in value + param s Half16NV in value + param t Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +MultiTexCoord2hvNV(target, v) + return void + param target TextureUnit in value + param v Half16NV in array [2] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +MultiTexCoord3hNV(target, s, t, r) + return void + param target TextureUnit in value + param s Half16NV in value + param t Half16NV in value + param r Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +MultiTexCoord3hvNV(target, v) + return void + param target TextureUnit in value + param v Half16NV in array [3] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +MultiTexCoord4hNV(target, s, t, r, q) + return void + param target TextureUnit in value + param s Half16NV in value + param t Half16NV in value + param r Half16NV in value + param q Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +MultiTexCoord4hvNV(target, v) + return void + param target TextureUnit in value + param v Half16NV in array [4] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +FogCoordhNV(fog) + return void + param fog Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +FogCoordhvNV(fog) + return void + param fog Half16NV in array [1] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +SecondaryColor3hNV(red, green, blue) + return void + param red Half16NV in value + param green Half16NV in value + param blue Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +SecondaryColor3hvNV(v) + return void + param v Half16NV in array [3] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexWeighthNV(weight) + return void + param weight Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexWeighthvNV(weight) + return void + param weight Half16NV in array [1] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexAttrib1hNV(index, x) + return void + param index UInt32 in value + param x Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexAttrib1hvNV(index, v) + return void + param index UInt32 in value + param v Half16NV in array [1] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexAttrib2hNV(index, x, y) + return void + param index UInt32 in value + param x Half16NV in value + param y Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexAttrib2hvNV(index, v) + return void + param index UInt32 in value + param v Half16NV in array [2] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexAttrib3hNV(index, x, y, z) + return void + param index UInt32 in value + param x Half16NV in value + param y Half16NV in value + param z Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexAttrib3hvNV(index, v) + return void + param index UInt32 in value + param v Half16NV in array [3] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexAttrib4hNV(index, x, y, z, w) + return void + param index UInt32 in value + param x Half16NV in value + param y Half16NV in value + param z Half16NV in value + param w Half16NV in value + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexAttrib4hvNV(index, v) + return void + param index UInt32 in value + param v Half16NV in array [4] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexAttribs1hvNV(index, n, v) + return void + param index UInt32 in value + param n SizeI in value + param v Half16NV in array [n] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexAttribs2hvNV(index, n, v) + return void + param index UInt32 in value + param n SizeI in value + param v Half16NV in array [n] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexAttribs3hvNV(index, n, v) + return void + param index UInt32 in value + param n SizeI in value + param v Half16NV in array [n] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexAttribs4hvNV(index, n, v) + return void + param index UInt32 in value + param n SizeI in value + param v Half16NV in array [n] + category NV_half_float + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #284 +# NV_pixel_data_range commands +# +############################################################################### + +# @@ Need to verify/add GLX protocol + +PixelDataRangeNV(target, length, pointer) + return void + param target PixelDataRangeTargetNV in value + param length SizeI in value + param pointer Void out array [length] + category NV_pixel_data_range + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +FlushPixelDataRangeNV(target) + return void + param target PixelDataRangeTargetNV in value + category NV_pixel_data_range + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #285 +# NV_primitive_restart commands +# +############################################################################### + +# @@ Need to verify/add GLX protocol + +PrimitiveRestartNV() + return void + category NV_primitive_restart + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +PrimitiveRestartIndexNV(index) + return void + param index UInt32 in value + category NV_primitive_restart + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + + +############################################################################### +# +# Extension #286 +# NV_texture_expand_normal commands +# +############################################################################### + +# (none) +newcategory: NV_texture_expand_normal + +############################################################################### +# +# Extension #287 +# NV_vertex_program2 commands +# +############################################################################### + +# (none) +newcategory: NV_vertex_program2 + +############################################################################### +# +# Extension #288 +# ATI_map_object_buffer commands +# +############################################################################### + +# @@ Need to verify/add GLX protocol + +MapObjectBufferATI(buffer) + return VoidPointer + param buffer UInt32 in value + category ATI_map_object_buffer + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +UnmapObjectBufferATI(buffer) + return void + param buffer UInt32 in value + category ATI_map_object_buffer + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #289 +# ATI_separate_stencil commands +# +############################################################################### + +# @@ Need to verify/add GLX protocol + +StencilOpSeparateATI(face, sfail, dpfail, dppass) + return void + param face StencilFaceDirection in value + param sfail StencilOp in value + param dpfail StencilOp in value + param dppass StencilOp in value + category ATI_separate_stencil + version 1.2 + extension + glxropcode ? + glxflags ignore + alias StencilOpSeparate + +StencilFuncSeparateATI(frontfunc, backfunc, ref, mask) + return void + param frontfunc StencilFunction in value + param backfunc StencilFunction in value + param ref ClampedStencilValue in value + param mask MaskedStencilValue in value + category ATI_separate_stencil + version 1.2 + extension + glxropcode ? + glxflags ignore + alias StencilFuncSeparate + +############################################################################### +# +# Extension #290 +# ATI_vertex_attrib_array_object commands +# +############################################################################### + +# @@ Need to verify/add GLX protocol + +VertexAttribArrayObjectATI(index, size, type, normalized, stride, buffer, offset) + return void + param index UInt32 in value + param size Int32 in value + param type VertexAttribPointerTypeARB in value + param normalized Boolean in value + param stride SizeI in value + param buffer UInt32 in value + param offset UInt32 in value + category ATI_vertex_attrib_array_object + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetVertexAttribArrayObjectfvATI(index, pname, params) + return void + param index UInt32 in value + param pname ArrayObjectPNameATI in value + param params Float32 out array [pname] + category ATI_vertex_attrib_array_object + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetVertexAttribArrayObjectivATI(index, pname, params) + return void + param index UInt32 in value + param pname ArrayObjectPNameATI in value + param params Int32 out array [pname] + category ATI_vertex_attrib_array_object + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #291 - OpenGL ES only, not in glext.h +# OES_byte_coordinates commands +# +############################################################################### + +# void Vertex{234}bOES(T coords) +# void Vertex{234}bvOES(T *coords) +# void TexCoord{1234}bOES(T coords) +# void TexCoord{1234}bvOES(T *coords) +# void MultiTexCoord{1234}bOES(enum texture, T coords) +# void MultiTexCoord{1234}bvOES(enum texture, T *coords) +# All are handcode - mapped to non-byte GLX protocol on client side + +# newcategory: OES_byte_coordinates + +############################################################################### +# +# Extension #292 - OpenGL ES only, not in glext.h +# OES_fixed_point commands +# +############################################################################### + +# Too many to list in just a comment - see spec in the extension registry +# All are handcode - mapped to non-byte GLX protocol on client side + +# newcategory: OES_fixed_point + +############################################################################### +# +# Extension #293 - OpenGL ES only, not in glext.h +# OES_single_precision commands +# +############################################################################### + +# void DepthRangefOES(clampf n, clampf f) +# void FrustumfOES(float l, float r, float b, float t, float n, float f) +# void OrthofOES(float l, float r, float b, float t, float n, float f) +# void ClipPlanefOES(enum plane, const float* equation) +# void glClearDepthfOES(clampd depth) +# GLX ropcodes 4308-4312 (not respectively, see extension spec) +# void GetClipPlanefOES(enum plane, float* equation) +# GLX vendor private 1421 + +# newcategory: OES_single_precision + +############################################################################### +# +# Extension #294 - OpenGL ES only, not in glext.h +# OES_compressed_paletted_texture commands +# +############################################################################### + +# (none) +# newcategory: OES_compressed_paletted_texture + +############################################################################### +# +# Extension #295 - This is an OpenGL ES extension, but also implemented in Mesa +# OES_read_format commands +# +############################################################################### + +# (none) +newcategory: OES_read_format + +############################################################################### +# +# Extension #296 - OpenGL ES only, not in glext.h +# OES_query_matrix commands +# +############################################################################### + +# bitfield queryMatrixxOES(fixed mantissa[16], int exponent[16]) +# All are handcode - mapped to non-byte GLX protocol on client side + +# newcategory: OES_query_matrix + +############################################################################### +# +# Extension #297 +# EXT_depth_bounds_test commands +# +############################################################################### + +DepthBoundsEXT(zmin, zmax) + return void + param zmin ClampedFloat64 in value + param zmax ClampedFloat64 in value + category EXT_depth_bounds_test + version 1.2 + extension + glxropcode 4229 + offset 699 + +############################################################################### +# +# Extension #298 +# EXT_texture_mirror_clamp commands +# +############################################################################### + +# (none) +newcategory: EXT_texture_mirror_clamp + +############################################################################### +# +# Extension #299 +# EXT_blend_equation_separate commands +# +############################################################################### + +BlendEquationSeparateEXT(modeRGB, modeAlpha) + return void + param modeRGB BlendEquationModeEXT in value + param modeAlpha BlendEquationModeEXT in value + category EXT_blend_equation_separate + version 1.2 + extension + glxropcode 4228 + alias BlendEquationSeparate + +############################################################################### +# +# Extension #300 +# MESA_pack_invert commands +# +############################################################################### + +# (none) +newcategory: MESA_pack_invert + +############################################################################### +# +# Extension #301 +# MESA_ycbcr_texture commands +# +############################################################################### + +# (none) +newcategory: MESA_ycbcr_texture + +############################################################################### +# +# Extension #301 +# MESA_ycbcr_texture commands +# +############################################################################### + +# (none) +newcategory: MESA_ycbcr_texture + +############################################################################### +# +# Extension #302 +# EXT_pixel_buffer_object commands +# +############################################################################### + +# (none) +newcategory: EXT_pixel_buffer_object + +############################################################################### +# +# Extension #303 +# NV_fragment_program_option commands +# +############################################################################### + +# (none) +newcategory: NV_fragment_program_option + +############################################################################### +# +# Extension #304 +# NV_fragment_program2 commands +# +############################################################################### + +# (none) +newcategory: NV_fragment_program2 + +############################################################################### +# +# Extension #305 +# NV_vertex_program2_option commands +# +############################################################################### + +# (none) +newcategory: NV_vertex_program2_option + +############################################################################### +# +# Extension #306 +# NV_vertex_program3 commands +# +############################################################################### + +# (none) +newcategory: NV_vertex_program3 + +############################################################################### +# +# Extension #307 - GLX_SGIX_hyperpipe commands +# Extension #308 - GLX_MESA_agp_offset commands +# Extension #309 - GL_EXT_texture_compression_dxt1 (OpenGL ES only, subset of _st3c version) +# +############################################################################### + +############################################################################### +# +# Extension #310 +# EXT_framebuffer_object commands +# +############################################################################### + +IsRenderbufferEXT(renderbuffer) + return Boolean + param renderbuffer UInt32 in value + category EXT_framebuffer_object + version 1.2 + extension + glxvendorpriv 1422 + glxflags ignore + alias IsRenderbuffer + +BindRenderbufferEXT(target, renderbuffer) + return void + param target RenderbufferTarget in value + param renderbuffer UInt32 in value + category EXT_framebuffer_object + version 1.2 + extension + glxropcode 4316 + glxflags ignore + alias BindRenderbuffer + +DeleteRenderbuffersEXT(n, renderbuffers) + return void + param n SizeI in value + param renderbuffers UInt32 in array [n] + category EXT_framebuffer_object + version 1.2 + extension + glxropcode 4317 + glxflags ignore + alias DeleteRenderbuffers + +GenRenderbuffersEXT(n, renderbuffers) + return void + param n SizeI in value + param renderbuffers UInt32 out array [n] + category EXT_framebuffer_object + version 1.2 + extension + glxvendorpriv 1423 + glxflags ignore + alias GenRenderbuffers + +RenderbufferStorageEXT(target, internalformat, width, height) + return void + param target RenderbufferTarget in value + param internalformat GLenum in value + param width SizeI in value + param height SizeI in value + category EXT_framebuffer_object + version 1.2 + extension + glxropcode 4318 + glxflags ignore + alias RenderbufferStorage + +GetRenderbufferParameterivEXT(target, pname, params) + return void + param target RenderbufferTarget in value + param pname GLenum in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_framebuffer_object + dlflags notlistable + version 1.2 + extension + glxvendorpriv 1424 + glxflags ignore + alias GetRenderbufferParameteriv + +IsFramebufferEXT(framebuffer) + return Boolean + param framebuffer UInt32 in value + category EXT_framebuffer_object + version 1.2 + extension + glxvendorpriv 1425 + glxflags ignore + alias IsFramebuffer + +BindFramebufferEXT(target, framebuffer) + return void + param target FramebufferTarget in value + param framebuffer UInt32 in value + category EXT_framebuffer_object + version 1.2 + extension + glxropcode 4319 + glxflags ignore + alias BindFramebuffer + +DeleteFramebuffersEXT(n, framebuffers) + return void + param n SizeI in value + param framebuffers UInt32 in array [n] + category EXT_framebuffer_object + version 1.2 + extension + glxropcode 4320 + glxflags ignore + alias DeleteFramebuffers + +GenFramebuffersEXT(n, framebuffers) + return void + param n SizeI in value + param framebuffers UInt32 out array [n] + category EXT_framebuffer_object + version 1.2 + extension + glxvendorpriv 1426 + glxflags ignore + alias GenFramebuffers + +CheckFramebufferStatusEXT(target) + return GLenum + param target FramebufferTarget in value + category EXT_framebuffer_object + version 1.2 + extension + glxvendorpriv 1427 + glxflags ignore + alias CheckFramebufferStatus + +FramebufferTexture1DEXT(target, attachment, textarget, texture, level) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param textarget GLenum in value + param texture UInt32 in value + param level Int32 in value + category EXT_framebuffer_object + version 1.2 + extension + glxropcode 4321 + glxflags ignore + alias FramebufferTexture1D + +FramebufferTexture2DEXT(target, attachment, textarget, texture, level) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param textarget GLenum in value + param texture UInt32 in value + param level Int32 in value + category EXT_framebuffer_object + version 1.2 + extension + glxropcode 4322 + glxflags ignore + alias FramebufferTexture2D + +FramebufferTexture3DEXT(target, attachment, textarget, texture, level, zoffset) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param textarget GLenum in value + param texture UInt32 in value + param level Int32 in value + param zoffset Int32 in value + category EXT_framebuffer_object + version 1.2 + extension + glxropcode 4323 + glxflags ignore + alias FramebufferTexture3D + +FramebufferRenderbufferEXT(target, attachment, renderbuffertarget, renderbuffer) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param renderbuffertarget RenderbufferTarget in value + param renderbuffer UInt32 in value + category EXT_framebuffer_object + version 1.2 + extension + glxropcode 4324 + glxflags ignore + alias FramebufferRenderbuffer + +GetFramebufferAttachmentParameterivEXT(target, attachment, pname, params) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param pname GLenum in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_framebuffer_object + dlflags notlistable + version 1.2 + extension + glxvendorpriv 1428 + glxflags ignore + alias GetFramebufferAttachmentParameteriv + +GenerateMipmapEXT(target) + return void + param target GLenum in value + category EXT_framebuffer_object + version 1.2 + extension + glxropcode 4325 + glxflags ignore + alias GenerateMipmap + + +############################################################################### +# +# Extension #311 +# GREMEDY_string_marker commands +# +############################################################################### + +StringMarkerGREMEDY(len, string) + return void + param len SizeI in value + param string Void in array [len] + category GREMEDY_string_marker + version 1.0 + extension + glxflags ignore + offset ? + +############################################################################### +# +# Extension #312 +# EXT_packed_depth_stencil commands +# +############################################################################### + +# (none) +newcategory: EXT_packed_depth_stencil + +############################################################################### +# +# Extension #313 - WGL_3DL_stereo_control +# +############################################################################### + +############################################################################### +# +# Extension #314 +# EXT_stencil_clear_tag commands +# +############################################################################### + +StencilClearTagEXT(stencilTagBits, stencilClearTag) + return void + param stencilTagBits SizeI in value + param stencilClearTag UInt32 in value + category EXT_stencil_clear_tag + version 1.5 + extension + glxropcode 4223 + glxflags ignore + offset ? + +############################################################################### +# +# Extension #315 +# EXT_texture_sRGB commands +# +############################################################################### + +# (none) +newcategory: EXT_texture_sRGB + +############################################################################### +# +# Extension #316 +# EXT_framebuffer_blit commands +# +############################################################################### + +BlitFramebufferEXT(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter) + return void + param srcX0 Int32 in value + param srcY0 Int32 in value + param srcX1 Int32 in value + param srcY1 Int32 in value + param dstX0 Int32 in value + param dstY0 Int32 in value + param dstX1 Int32 in value + param dstY1 Int32 in value + param mask ClearBufferMask in value + param filter GLenum in value + category EXT_framebuffer_blit + version 1.5 + glxropcode 4330 + alias BlitFramebuffer + +############################################################################### +# +# Extension #317 +# EXT_framebuffer_multisample commands +# +############################################################################### + +RenderbufferStorageMultisampleEXT(target, samples, internalformat, width, height) + return void + param target GLenum in value + param samples SizeI in value + param internalformat GLenum in value + param width SizeI in value + param height SizeI in value + category EXT_framebuffer_multisample + version 1.5 + glxropcode 4331 + alias RenderbufferStorageMultisample + +############################################################################### +# +# Extension #318 +# MESAX_texture_stack commands +# +############################################################################### + +# (none) +newcategory: MESAX_texture_stack + +############################################################################### +# +# Extension #319 +# EXT_timer_query commands +# +############################################################################### + +GetQueryObjecti64vEXT(id, pname, params) + return void + param id UInt32 in value + param pname GLenum in value + param params Int64EXT out array [pname] + category EXT_timer_query + dlflags notlistable + version 1.5 + glxvendorpriv 1328 + glxflags ignore + offset ? + +GetQueryObjectui64vEXT(id, pname, params) + return void + param id UInt32 in value + param pname GLenum in value + param params UInt64EXT out array [pname] + category EXT_timer_query + dlflags notlistable + version 1.5 + glxvendorpriv 1329 + glxflags ignore + offset ? + +############################################################################### +# +# Extension #320 +# EXT_gpu_program_parameters commands +# +############################################################################### + +ProgramEnvParameters4fvEXT(target, index, count, params) + return void + param target ProgramTargetARB in value + param index UInt32 in value + param count SizeI in value + param params Float32 in array [count*4] + category EXT_gpu_program_parameters + version 1.2 + glxropcode 4281 + offset ? + +ProgramLocalParameters4fvEXT(target, index, count, params) + return void + param target ProgramTargetARB in value + param index UInt32 in value + param count SizeI in value + param params Float32 in array [count*4] + category EXT_gpu_program_parameters + version 1.2 + glxropcode 4282 + offset ? + +############################################################################### +# +# Extension #321 +# APPLE_flush_buffer_range commands +# +############################################################################### + +BufferParameteriAPPLE(target, pname, param) + return void + param target GLenum in value + param pname GLenum in value + param param Int32 in value + category APPLE_flush_buffer_range + version 1.5 + extension + glxropcode ? + glxflags ignore + offset ? + +FlushMappedBufferRangeAPPLE(target, offset, size) + return void + param target GLenum in value + param offset BufferOffset in value + param size BufferSize in value + category APPLE_flush_buffer_range + version 1.5 + extension + glxropcode ? + glxflags ignore + alias FlushMappedBufferRange + +############################################################################### +# +# Extension #322 +# NV_gpu_program4 commands +# +############################################################################### + +ProgramLocalParameterI4iNV(target, index, x, y, z, w) + return void + param target ProgramTarget in value + param index UInt32 in value + param x Int32 in value + param y Int32 in value + param z Int32 in value + param w Int32 in value + category NV_gpu_program4 + version 1.3 + vectorequiv ProgramLocalParameterI4ivNV + glxvectorequiv ProgramLocalParameterI4ivNV + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +ProgramLocalParameterI4ivNV(target, index, params) + return void + param target ProgramTarget in value + param index UInt32 in value + param params Int32 in array [4] + category NV_gpu_program4 + version 1.3 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +ProgramLocalParametersI4ivNV(target, index, count, params) + return void + param target ProgramTarget in value + param index UInt32 in value + param count SizeI in value + param params Int32 in array [count*4] + category NV_gpu_program4 + version 1.3 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +ProgramLocalParameterI4uiNV(target, index, x, y, z, w) + return void + param target ProgramTarget in value + param index UInt32 in value + param x UInt32 in value + param y UInt32 in value + param z UInt32 in value + param w UInt32 in value + category NV_gpu_program4 + version 1.3 + vectorequiv ProgramLocalParameterI4uivNV + glxvectorequiv ProgramLocalParameterI4uivNV + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +ProgramLocalParameterI4uivNV(target, index, params) + return void + param target ProgramTarget in value + param index UInt32 in value + param params UInt32 in array [4] + category NV_gpu_program4 + version 1.3 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +ProgramLocalParametersI4uivNV(target, index, count, params) + return void + param target ProgramTarget in value + param index UInt32 in value + param count SizeI in value + param params UInt32 in array [count*4] + category NV_gpu_program4 + version 1.3 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +ProgramEnvParameterI4iNV(target, index, x, y, z, w) + return void + param target ProgramTarget in value + param index UInt32 in value + param x Int32 in value + param y Int32 in value + param z Int32 in value + param w Int32 in value + category NV_gpu_program4 + version 1.3 + vectorequiv ProgramEnvParameterI4ivNV + glxvectorequiv ProgramEnvParameterI4ivNV + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +ProgramEnvParameterI4ivNV(target, index, params) + return void + param target ProgramTarget in value + param index UInt32 in value + param params Int32 in array [4] + category NV_gpu_program4 + version 1.3 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +ProgramEnvParametersI4ivNV(target, index, count, params) + return void + param target ProgramTarget in value + param index UInt32 in value + param count SizeI in value + param params Int32 in array [count*4] + category NV_gpu_program4 + version 1.3 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +ProgramEnvParameterI4uiNV(target, index, x, y, z, w) + return void + param target ProgramTarget in value + param index UInt32 in value + param x UInt32 in value + param y UInt32 in value + param z UInt32 in value + param w UInt32 in value + category NV_gpu_program4 + version 1.3 + vectorequiv ProgramEnvParameterI4uivNV + glxvectorequiv ProgramEnvParameterI4uivNV + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +ProgramEnvParameterI4uivNV(target, index, params) + return void + param target ProgramTarget in value + param index UInt32 in value + param params UInt32 in array [4] + category NV_gpu_program4 + version 1.3 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +ProgramEnvParametersI4uivNV(target, index, count, params) + return void + param target ProgramTarget in value + param index UInt32 in value + param count SizeI in value + param params UInt32 in array [count*4] + category NV_gpu_program4 + version 1.3 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +GetProgramLocalParameterIivNV(target, index, params) + return void + param target ProgramTarget in value + param index UInt32 in value + param params Int32 out array [4] + dlflags notlistable + category NV_gpu_program4 + version 1.3 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +GetProgramLocalParameterIuivNV(target, index, params) + return void + param target ProgramTarget in value + param index UInt32 in value + param params UInt32 out array [4] + dlflags notlistable + category NV_gpu_program4 + version 1.3 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +GetProgramEnvParameterIivNV(target, index, params) + return void + param target ProgramTarget in value + param index UInt32 in value + param params Int32 out array [4] + dlflags notlistable + category NV_gpu_program4 + version 1.3 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +GetProgramEnvParameterIuivNV(target, index, params) + return void + param target ProgramTarget in value + param index UInt32 in value + param params UInt32 out array [4] + dlflags notlistable + category NV_gpu_program4 + version 1.3 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +############################################################################### +# +# Extension #323 +# NV_geometry_program4 commands +# +############################################################################### + +ProgramVertexLimitNV(target, limit) + return void + param target ProgramTarget in value + param limit Int32 in value + category NV_geometry_program4 + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + +FramebufferTextureEXT(target, attachment, texture, level) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param texture Texture in value + param level CheckedInt32 in value + category NV_geometry_program4 + version 2.0 + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + alias FramebufferTextureARB + +FramebufferTextureLayerEXT(target, attachment, texture, level, layer) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param texture Texture in value + param level CheckedInt32 in value + param layer CheckedInt32 in value + category NV_geometry_program4 + version 2.0 + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + alias FramebufferTextureLayer + +FramebufferTextureFaceEXT(target, attachment, texture, level, face) + return void + param target FramebufferTarget in value + param attachment FramebufferAttachment in value + param texture Texture in value + param level CheckedInt32 in value + param face TextureTarget in value + category NV_geometry_program4 + version 2.0 + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + alias FramebufferTextureFaceARB + +############################################################################### +# +# Extension #324 +# EXT_geometry_shader4 commands +# +############################################################################### + +ProgramParameteriEXT(program, pname, value) + return void + param program UInt32 in value + param pname ProgramParameterPName in value + param value Int32 in value + category EXT_geometry_shader4 + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + alias ProgramParameteriARB + +############################################################################### +# +# Extension #325 +# NV_vertex_program4 commands +# +############################################################################### + +VertexAttribI1iEXT(index, x) + return void + param index UInt32 in value + param x Int32 in value + category NV_vertex_program4 + beginend allow-inside + vectorequiv VertexAttribI1ivEXT + glxvectorequiv VertexAttribI1ivEXT + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI1i + +VertexAttribI2iEXT(index, x, y) + return void + param index UInt32 in value + param x Int32 in value + param y Int32 in value + category NV_vertex_program4 + beginend allow-inside + vectorequiv VertexAttribI2ivEXT + glxvectorequiv VertexAttribI2ivEXT + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI2i + +VertexAttribI3iEXT(index, x, y, z) + return void + param index UInt32 in value + param x Int32 in value + param y Int32 in value + param z Int32 in value + category NV_vertex_program4 + beginend allow-inside + vectorequiv VertexAttribI3ivEXT + glxvectorequiv VertexAttribI3ivEXT + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI3i + +VertexAttribI4iEXT(index, x, y, z, w) + return void + param index UInt32 in value + param x Int32 in value + param y Int32 in value + param z Int32 in value + param w Int32 in value + category NV_vertex_program4 + beginend allow-inside + vectorequiv VertexAttribI4ivEXT + glxvectorequiv VertexAttribI4ivEXT + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI4i + +VertexAttribI1uiEXT(index, x) + return void + param index UInt32 in value + param x UInt32 in value + category NV_vertex_program4 + beginend allow-inside + vectorequiv VertexAttribI1uivEXT + glxvectorequiv VertexAttribI1uivEXT + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI1ui + +VertexAttribI2uiEXT(index, x, y) + return void + param index UInt32 in value + param x UInt32 in value + param y UInt32 in value + category NV_vertex_program4 + beginend allow-inside + vectorequiv VertexAttribI2uivEXT + glxvectorequiv VertexAttribI2uivEXT + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI2ui + +VertexAttribI3uiEXT(index, x, y, z) + return void + param index UInt32 in value + param x UInt32 in value + param y UInt32 in value + param z UInt32 in value + category NV_vertex_program4 + beginend allow-inside + vectorequiv VertexAttribI3uivEXT + glxvectorequiv VertexAttribI3uivEXT + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI3ui + +VertexAttribI4uiEXT(index, x, y, z, w) + return void + param index UInt32 in value + param x UInt32 in value + param y UInt32 in value + param z UInt32 in value + param w UInt32 in value + category NV_vertex_program4 + beginend allow-inside + vectorequiv VertexAttribI4uivEXT + glxvectorequiv VertexAttribI4uivEXT + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI4ui + +VertexAttribI1ivEXT(index, v) + return void + param index UInt32 in value + param v Int32 in array [1] + category NV_vertex_program4 + beginend allow-inside + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI1iv + +VertexAttribI2ivEXT(index, v) + return void + param index UInt32 in value + param v Int32 in array [2] + category NV_vertex_program4 + beginend allow-inside + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI2iv + +VertexAttribI3ivEXT(index, v) + return void + param index UInt32 in value + param v Int32 in array [3] + category NV_vertex_program4 + beginend allow-inside + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI3iv + +VertexAttribI4ivEXT(index, v) + return void + param index UInt32 in value + param v Int32 in array [4] + category NV_vertex_program4 + beginend allow-inside + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI4iv + +VertexAttribI1uivEXT(index, v) + return void + param index UInt32 in value + param v UInt32 in array [1] + category NV_vertex_program4 + beginend allow-inside + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI1uiv + +VertexAttribI2uivEXT(index, v) + return void + param index UInt32 in value + param v UInt32 in array [2] + category NV_vertex_program4 + beginend allow-inside + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI2uiv + +VertexAttribI3uivEXT(index, v) + return void + param index UInt32 in value + param v UInt32 in array [3] + category NV_vertex_program4 + beginend allow-inside + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI3uiv + +VertexAttribI4uivEXT(index, v) + return void + param index UInt32 in value + param v UInt32 in array [4] + category NV_vertex_program4 + beginend allow-inside + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI4uiv + +VertexAttribI4bvEXT(index, v) + return void + param index UInt32 in value + param v Int8 in array [4] + category NV_vertex_program4 + beginend allow-inside + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI4bv + +VertexAttribI4svEXT(index, v) + return void + param index UInt32 in value + param v Int16 in array [4] + category NV_vertex_program4 + beginend allow-inside + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI4sv + +VertexAttribI4ubvEXT(index, v) + return void + param index UInt32 in value + param v UInt8 in array [4] + category NV_vertex_program4 + beginend allow-inside + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI4ubv + +VertexAttribI4usvEXT(index, v) + return void + param index UInt32 in value + param v UInt16 in array [4] + category NV_vertex_program4 + beginend allow-inside + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribI4usv + +VertexAttribIPointerEXT(index, size, type, stride, pointer) + return void + param index UInt32 in value + param size Int32 in value + param type VertexAttribEnum in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(size/type/stride)] retained + category NV_vertex_program4 + dlflags notlistable + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias VertexAttribIPointer + +GetVertexAttribIivEXT(index, pname, params) + return void + param index UInt32 in value + param pname VertexAttribEnum in value + param params Int32 out array [1] + category NV_vertex_program4 + dlflags notlistable + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias GetVertexAttribIiv + +GetVertexAttribIuivEXT(index, pname, params) + return void + param index UInt32 in value + param pname VertexAttribEnum in value + param params UInt32 out array [1] + category NV_vertex_program4 + dlflags notlistable + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + alias GetVertexAttribIuiv + +############################################################################### +# +# Extension #326 +# EXT_gpu_shader4 commands +# +############################################################################### + +GetUniformuivEXT(program, location, params) + return void + param program UInt32 in value + param location Int32 in value + param params UInt32 out array [COMPSIZE(program/location)] + category EXT_gpu_shader4 + dlflags notlistable + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + alias GetUniformuiv + +BindFragDataLocationEXT(program, color, name) + return void + param program UInt32 in value + param color UInt32 in value + param name Char in array [COMPSIZE(name)] + category EXT_gpu_shader4 + dlflags notlistable + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + alias BindFragDataLocation + +GetFragDataLocationEXT(program, name) + return Int32 + param program UInt32 in value + param name Char in array [COMPSIZE(name)] + category EXT_gpu_shader4 + dlflags notlistable + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + alias GetFragDataLocation + +Uniform1uiEXT(location, v0) + return void + param location Int32 in value + param v0 UInt32 in value + category EXT_gpu_shader4 + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + alias Uniform1ui + +Uniform2uiEXT(location, v0, v1) + return void + param location Int32 in value + param v0 UInt32 in value + param v1 UInt32 in value + category EXT_gpu_shader4 + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + alias Uniform2ui + +Uniform3uiEXT(location, v0, v1, v2) + return void + param location Int32 in value + param v0 UInt32 in value + param v1 UInt32 in value + param v2 UInt32 in value + category EXT_gpu_shader4 + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + alias Uniform3ui + +Uniform4uiEXT(location, v0, v1, v2, v3) + return void + param location Int32 in value + param v0 UInt32 in value + param v1 UInt32 in value + param v2 UInt32 in value + param v3 UInt32 in value + category EXT_gpu_shader4 + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + alias Uniform4ui + +Uniform1uivEXT(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value UInt32 in array [count] + category EXT_gpu_shader4 + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + alias Uniform1uiv + +Uniform2uivEXT(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value UInt32 in array [count*2] + category EXT_gpu_shader4 + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + alias Uniform2uiv + +Uniform3uivEXT(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value UInt32 in array [count*3] + category EXT_gpu_shader4 + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + alias Uniform3uiv + +Uniform4uivEXT(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value UInt32 in array [count*4] + category EXT_gpu_shader4 + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + alias Uniform4uiv + +############################################################################### +# +# Extension #327 +# EXT_draw_instanced commands +# +############################################################################### + +DrawArraysInstancedEXT(mode, start, count, primcount) + return void + param mode BeginMode in value + param start Int32 in value + param count SizeI in value + param primcount SizeI in value + category EXT_draw_instanced + version 2.0 + extension soft WINSOFT + dlflags notlistable + vectorequiv ArrayElement + glfflags ignore + glxflags ignore + alias DrawArraysInstancedARB + +DrawElementsInstancedEXT(mode, count, type, indices, primcount) + return void + param mode BeginMode in value + param count SizeI in value + param type DrawElementsType in value + param indices Void in array [COMPSIZE(count/type)] + param primcount SizeI in value + category EXT_draw_instanced + version 2.0 + extension soft WINSOFT + dlflags notlistable + vectorequiv ArrayElement + glfflags ignore + glxflags ignore + alias DrawElementsInstancedARB + +############################################################################### +# +# Extension #328 +# EXT_packed_float commands +# +############################################################################### + +# (none) +newcategory: EXT_packed_float + +############################################################################### +# +# Extension #329 +# EXT_texture_array commands +# +############################################################################### + +# (none) +newcategory: EXT_texture_array + +############################################################################### +# +# Extension #330 +# EXT_texture_buffer_object commands +# +############################################################################### + +TexBufferEXT(target, internalformat, buffer) + return void + param target TextureTarget in value + param internalformat GLenum in value + param buffer UInt32 in value + category EXT_texture_buffer_object + version 2.0 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + alias TexBufferARB + +############################################################################### +# +# Extension #331 +# EXT_texture_compression_latc commands +# +############################################################################### + +# (none) +newcategory: EXT_texture_compression_latc + +############################################################################### +# +# Extension #332 +# EXT_texture_compression_rgtc commands +# +############################################################################### + +# (none) +newcategory: EXT_texture_compression_rgtc + +############################################################################### +# +# Extension #333 +# EXT_texture_shared_exponent commands +# +############################################################################### + +# (none) +newcategory: EXT_texture_shared_exponent + +############################################################################### +# +# Extension #334 +# NV_depth_buffer_float commands +# +############################################################################### + +DepthRangedNV(zNear, zFar) + return void + param zNear Float64 in value + param zFar Float64 in value + category NV_depth_buffer_float + extension soft WINSOFT NV50 + version 2.0 + glfflags ignore + glxflags ignore + +ClearDepthdNV(depth) + return void + param depth Float64 in value + category NV_depth_buffer_float + extension soft WINSOFT NV50 + version 2.0 + glfflags ignore + glxflags ignore + +DepthBoundsdNV(zmin, zmax) + return void + param zmin Float64 in value + param zmax Float64 in value + category NV_depth_buffer_float + extension soft WINSOFT NV50 + version 2.0 + glfflags ignore + glxflags ignore + +############################################################################### +# +# Extension #335 +# NV_fragment_program4 commands +# +############################################################################### + +# (none) +newcategory: NV_fragment_program4 + +############################################################################### +# +# Extension #336 +# NV_framebuffer_multisample_coverage commands +# +############################################################################### + +RenderbufferStorageMultisampleCoverageNV(target, coverageSamples, colorSamples, internalformat, width, height) + return void + param target RenderbufferTarget in value + param coverageSamples SizeI in value + param colorSamples SizeI in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param height SizeI in value + category NV_framebuffer_multisample_coverage + version 1.5 + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + +############################################################################### +# +# Extension #337 +# EXT_framebuffer_sRGB commands +# +############################################################################### + +# (none) +newcategory: EXT_framebuffer_sRGB + +############################################################################### +# +# Extension #338 +# NV_geometry_shader4 commands +# +############################################################################### + +# (none) +newcategory: NV_geometry_shader4 + +############################################################################### +# +# Extension #339 +# NV_parameter_buffer_object commands +# +############################################################################### + +ProgramBufferParametersfvNV(target, buffer, index, count, params) + return void + param target ProgramTarget in value + param buffer UInt32 in value + param index UInt32 in value + param count SizeI in value + param params Float32 in array [count] + category NV_parameter_buffer_object + version 1.2 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +ProgramBufferParametersIivNV(target, buffer, index, count, params) + return void + param target ProgramTarget in value + param buffer UInt32 in value + param index UInt32 in value + param count SizeI in value + param params Int32 in array [count] + category NV_parameter_buffer_object + version 1.2 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +ProgramBufferParametersIuivNV(target, buffer, index, count, params) + return void + param target ProgramTarget in value + param buffer UInt32 in value + param index UInt32 in value + param count SizeI in value + param params UInt32 in array [count] + category NV_parameter_buffer_object + version 1.2 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +############################################################################### +# +# Extension #340 +# EXT_draw_buffers2 commands +# +############################################################################### + +ColorMaskIndexedEXT(index, r, g, b, a) + return void + param index UInt32 in value + param r Boolean in value + param g Boolean in value + param b Boolean in value + param a Boolean in value + category EXT_draw_buffers2 + version 2.0 + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias ColorMaski + +GetBooleanIndexedvEXT(target, index, data) + return void + param target GLenum in value + param index UInt32 in value + param data Boolean out array [COMPSIZE(target)] + category EXT_draw_buffers2 + version 2.0 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias GetBooleani_v + +GetIntegerIndexedvEXT(target, index, data) + return void + param target GLenum in value + param index UInt32 in value + param data Int32 out array [COMPSIZE(target)] + category EXT_draw_buffers2 + version 2.0 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias GetIntegeri_v + +EnableIndexedEXT(target, index) + return void + param target GLenum in value + param index UInt32 in value + category EXT_draw_buffers2 + version 2.0 + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias Enablei + +DisableIndexedEXT(target, index) + return void + param target GLenum in value + param index UInt32 in value + category EXT_draw_buffers2 + version 2.0 + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias Disablei + +IsEnabledIndexedEXT(target, index) + return Boolean + param target GLenum in value + param index UInt32 in value + category EXT_draw_buffers2 + version 2.0 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias IsEnabledi + +############################################################################### +# +# Extension #341 +# NV_transform_feedback commands +# +############################################################################### + +BeginTransformFeedbackNV(primitiveMode) + return void + param primitiveMode GLenum in value + category NV_transform_feedback + version 1.5 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias BeginTransformFeedback + +EndTransformFeedbackNV() + return void + category NV_transform_feedback + version 1.5 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias EndTransformFeedback + +TransformFeedbackAttribsNV(count, attribs, bufferMode) + return void + param count UInt32 in value + param attribs Int32 in array [COMPSIZE(count)] + param bufferMode GLenum in value + category NV_transform_feedback + version 1.5 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + +BindBufferRangeNV(target, index, buffer, offset, size) + return void + param target GLenum in value + param index UInt32 in value + param buffer UInt32 in value + param offset BufferOffset in value + param size BufferSize in value + category NV_transform_feedback + version 1.5 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias BindBufferRange + +BindBufferOffsetNV(target, index, buffer, offset) + return void + param target GLenum in value + param index UInt32 in value + param buffer UInt32 in value + param offset BufferOffset in value + category NV_transform_feedback + version 1.5 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias BindBufferOffsetEXT + +BindBufferBaseNV(target, index, buffer) + return void + param target GLenum in value + param index UInt32 in value + param buffer UInt32 in value + category NV_transform_feedback + version 1.5 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias BindBufferBase + +TransformFeedbackVaryingsNV(program, count, varyings, bufferMode) + return void + param program UInt32 in value + param count SizeI in value + param varyings CharPointer in array [count] + param bufferMode GLenum in value + category NV_transform_feedback + version 1.5 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias TransformFeedbackVaryings + +ActiveVaryingNV(program, name) + return void + param program UInt32 in value + param name Char in array [COMPSIZE(name)] + category NV_transform_feedback + version 1.5 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + +GetVaryingLocationNV(program, name) + return Int32 + param program UInt32 in value + param name Char in array [COMPSIZE(name)] + category NV_transform_feedback + dlflags notlistable + version 1.5 + glfflags ignore + glxflags ignore + extension soft WINSOFT + +GetActiveVaryingNV(program, index, bufSize, length, size, type, name) + return void + param program UInt32 in value + param index UInt32 in value + param bufSize SizeI in value + param length SizeI out array [1] + param size SizeI out array [1] + param type GLenum out array [1] + param name Char out array [COMPSIZE(program/index/bufSize)] + category NV_transform_feedback + dlflags notlistable + version 1.5 + extension soft WINSOFT + glfflags ignore + glxflags ignore + +GetTransformFeedbackVaryingNV(program, index, location) + return void + param program UInt32 in value + param index UInt32 in value + param location Int32 out array [1] + category NV_transform_feedback + dlflags notlistable + version 1.5 + extension soft WINSOFT + glfflags ignore + glxflags ignore + alias GetTransformFeedbackVarying + +############################################################################### +# +# Extension #342 +# EXT_bindable_uniform commands +# +############################################################################### + +UniformBufferEXT(program, location, buffer) + return void + param program UInt32 in value + param location Int32 in value + param buffer UInt32 in value + category EXT_bindable_uniform + version 2.0 + extension soft WINSOFT + glxflags ignore + glfflags ignore + +GetUniformBufferSizeEXT(program, location) + return Int32 + param program UInt32 in value + param location Int32 in value + category EXT_bindable_uniform + dlflags notlistable + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + +GetUniformOffsetEXT(program, location) + return BufferOffset + param program UInt32 in value + param location Int32 in value + category EXT_bindable_uniform + dlflags notlistable + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + +############################################################################### +# +# Extension #343 +# EXT_texture_integer extension commands +# +############################################################################### + +TexParameterIivEXT(target, pname, params) + return void + param target TextureTarget in value + param pname TextureParameterName in value + param params Int32 in array [COMPSIZE(pname)] + category EXT_texture_integer + version 2.0 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + alias TexParameterIiv + +TexParameterIuivEXT(target, pname, params) + return void + param target TextureTarget in value + param pname TextureParameterName in value + param params UInt32 in array [COMPSIZE(pname)] + category EXT_texture_integer + version 2.0 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + alias TexParameterIuiv + +GetTexParameterIivEXT(target, pname, params) + return void + param target TextureTarget in value + param pname GetTextureParameter in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_texture_integer + dlflags notlistable + version 1.0 + version 2.0 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + alias GetTexParameterIiv + +GetTexParameterIuivEXT(target, pname, params) + return void + param target TextureTarget in value + param pname GetTextureParameter in value + param params UInt32 out array [COMPSIZE(pname)] + category EXT_texture_integer + dlflags notlistable + version 1.0 + version 2.0 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + alias GetTexParameterIuiv + +ClearColorIiEXT(red, green, blue, alpha) + return void + param red Int32 in value + param green Int32 in value + param blue Int32 in value + param alpha Int32 in value + category EXT_texture_integer + version 2.0 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +ClearColorIuiEXT(red, green, blue, alpha) + return void + param red UInt32 in value + param green UInt32 in value + param blue UInt32 in value + param alpha UInt32 in value + category EXT_texture_integer + version 2.0 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + +############################################################################### +# +# Extension #344 - GLX_EXT_texture_from_pixmap +# +############################################################################### + +############################################################################### +# +# Extension #345 +# GREMEDY_frame_terminator commands +# +############################################################################### + +FrameTerminatorGREMEDY() + return void + category GREMEDY_frame_terminator + version 1.0 + extension + glxflags ignore + offset ? + +############################################################################### +# +# Extension #346 +# NV_conditional_render commands +# +############################################################################### + +BeginConditionalRenderNV(id, mode) + return void + param id UInt32 in value + param mode TypeEnum in value + category NV_conditional_render + glfflags ignore + glxflags ignore + alias BeginConditionalRender + +EndConditionalRenderNV() + return void + category NV_conditional_render + glfflags ignore + glxflags ignore + alias EndConditionalRender + +############################################################################### +# +# Extension #347 +# NV_present_video commands +# +############################################################################### + +# TBD +# void PresentFrameKeyedNV(uint video_slot, uint64EXT minPresentTime, +# uint beginPresentTimeId, uint +# presentDurationId, enum type, enum target0, +# uint fill0, uint key0, enum target1, uint +# fill1, uint key1); +# +# void PresentFrameDualFillNV(uint video_slot, uint64EXT +# minPresentTime, uint beginPresentTimeId, +# uint presentDurationId, enum type, enum +# target0, uint fill0, enum target1, uint +# fill1, enum target2, uint fill2, enum +# target3, uint fill3); +# +# void GetVideoivNV(uint video_slot, enum pname, int *params); +# void GetVideouivNV(uint video_slot, enum pname, uint *params); +# void GetVideoi64vNV(uint video_slot, enum pname, int64EXT *params); +# void GetVideoui64vNV(uint video_slot, enum pname, uint64EXT *params); +# void VideoParameterivNV(uint video_slot, enum pname, const int *params); + +PresentFrameKeyedNV(video_slot, minPresentTime, beginPresentTimeId, presentDurationId, type, target0, fill0, key0, target1, fill1, key1) + return void + param video_slot UInt32 in value + param minPresentTime UInt64EXT in value + param beginPresentTimeId UInt32 in value + param presentDurationId UInt32 in value + param type GLenum in value + param target0 GLenum in value + param fill0 UInt32 in value + param key0 UInt32 in value + param target1 GLenum in value + param fill1 UInt32 in value + param key1 UInt32 in value + category NV_present_video + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +PresentFrameDualFillNV(video_slot, minPresentTime, beginPresentTimeId, presentDurationId, type, target0, fill0, target1, fill1, target2, fill2, target3, fill3) + return void + param video_slot UInt32 in value + param minPresentTime UInt64EXT in value + param beginPresentTimeId UInt32 in value + param presentDurationId UInt32 in value + param type GLenum in value + param target0 GLenum in value + param fill0 UInt32 in value + param target1 GLenum in value + param fill1 UInt32 in value + param target2 GLenum in value + param fill2 UInt32 in value + param target3 GLenum in value + param fill3 UInt32 in value + category NV_present_video + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetVideoivNV(video_slot, pname, params) + return void + param video_slot UInt32 in value + param pname GLenum in value + param params Int32 out array [COMPSIZE(pname)] + category NV_present_video + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetVideouivNV(video_slot, pname, params) + return void + param video_slot UInt32 in value + param pname GLenum in value + param params UInt32 out array [COMPSIZE(pname)] + category NV_present_video + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetVideoi64vNV(video_slot, pname, params) + return void + param video_slot UInt32 in value + param pname GLenum in value + param params Int64EXT out array [COMPSIZE(pname)] + category NV_present_video + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetVideoui64vNV(video_slot, pname, params) + return void + param video_slot UInt32 in value + param pname GLenum in value + param params UInt64EXT out array [COMPSIZE(pname)] + category NV_present_video + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #348 - GLX_NV_video_out +# Extension #349 - WGL_NV_video_out +# Extension #350 - GLX_NV_swap_group +# Extension #351 - WGL_NV_swap_group +# +############################################################################### + +############################################################################### +# +# Extension #352 +# EXT_transform_feedback commands +# +############################################################################### + +# From EXT_draw_buffers2: GetBooleanIndexedvEXT / GetIntegerIndexedvEXT + +BeginTransformFeedbackEXT(primitiveMode) + return void + param primitiveMode GLenum in value + category EXT_transform_feedback + version 2.0 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias BeginTransformFeedback + +EndTransformFeedbackEXT() + return void + category EXT_transform_feedback + version 2.0 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias EndTransformFeedback + +BindBufferRangeEXT(target, index, buffer, offset, size) + return void + param target GLenum in value + param index UInt32 in value + param buffer UInt32 in value + param offset BufferOffset in value + param size BufferSize in value + category EXT_transform_feedback + version 2.0 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias BindBufferRange + +# Not promoted to the OpenGL 3.0 core +BindBufferOffsetEXT(target, index, buffer, offset) + return void + param target GLenum in value + param index UInt32 in value + param buffer UInt32 in value + param offset BufferOffset in value + category EXT_transform_feedback + version 2.0 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + +BindBufferBaseEXT(target, index, buffer) + return void + param target GLenum in value + param index UInt32 in value + param buffer UInt32 in value + category EXT_transform_feedback + version 2.0 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias BindBufferBase + +TransformFeedbackVaryingsEXT(program, count, varyings, bufferMode) + return void + param program UInt32 in value + param count SizeI in value + param varyings CharPointer in array [count] + param bufferMode GLenum in value + category EXT_transform_feedback + version 2.0 + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + alias TransformFeedbackVaryings + +GetTransformFeedbackVaryingEXT(program, index, bufSize, length, size, type, name) + return void + param program UInt32 in value + param index UInt32 in value + param bufSize SizeI in value + param length SizeI out array [1] + param size SizeI out array [1] + param type GLenum out array [1] + param name Char out array [COMPSIZE(length)] + category EXT_transform_feedback + dlflags notlistable + version 2.0 + extension soft WINSOFT + glfflags ignore + glxflags ignore + alias GetTransformFeedbackVarying + +############################################################################### +# +# Extension #353 +# EXT_direct_state_access commands +# +############################################################################### + +# New 1.1 client commands + +ClientAttribDefaultEXT(mask) + return void + param mask ClientAttribMask in value + category EXT_direct_state_access + extension soft WINSOFT + dlflags notlistable + glxflags ignore ### client-handcode client-intercept server-handcode + +PushClientAttribDefaultEXT(mask) + return void + param mask ClientAttribMask in value + category EXT_direct_state_access + extension soft WINSOFT + dlflags notlistable + glxflags ignore ### client-handcode client-intercept server-handcode + +# New 1.0 matrix commands + +MatrixLoadfEXT(mode, m) + return void + param mode MatrixMode in value + param m Float32 in array [16] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixLoaddEXT(mode, m) + return void + param mode MatrixMode in value + param m Float64 in array [16] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixMultfEXT(mode, m) + return void + param mode MatrixMode in value + param m Float32 in array [16] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixMultdEXT(mode, m) + return void + param mode MatrixMode in value + param m Float64 in array [16] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixLoadIdentityEXT(mode) + return void + param mode MatrixMode in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixRotatefEXT(mode, angle, x, y, z) + return void + param mode MatrixMode in value + param angle Float32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixRotatedEXT(mode, angle, x, y, z) + return void + param mode MatrixMode in value + param angle Float64 in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixScalefEXT(mode, x, y, z) + return void + param mode MatrixMode in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixScaledEXT(mode, x, y, z) + return void + param mode MatrixMode in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixTranslatefEXT(mode, x, y, z) + return void + param mode MatrixMode in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixTranslatedEXT(mode, x, y, z) + return void + param mode MatrixMode in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixFrustumEXT(mode, left, right, bottom, top, zNear, zFar) + return void + param mode MatrixMode in value + param left Float64 in value + param right Float64 in value + param bottom Float64 in value + param top Float64 in value + param zNear Float64 in value + param zFar Float64 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixOrthoEXT(mode, left, right, bottom, top, zNear, zFar) + return void + param mode MatrixMode in value + param left Float64 in value + param right Float64 in value + param bottom Float64 in value + param top Float64 in value + param zNear Float64 in value + param zFar Float64 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixPopEXT(mode) + return void + param mode MatrixMode in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixPushEXT(mode) + return void + param mode MatrixMode in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +# New 1.3 matrix transpose commands + +MatrixLoadTransposefEXT(mode, m) + return void + param mode MatrixMode in value + param m Float32 in array [16] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixLoadTransposedEXT(mode, m) + return void + param mode MatrixMode in value + param m Float64 in array [16] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixMultTransposefEXT(mode, m) + return void + param mode MatrixMode in value + param m Float32 in array [16] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MatrixMultTransposedEXT(mode, m) + return void + param mode MatrixMode in value + param m Float64 in array [16] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +# New 1.1 texture object commands + +TextureParameterfEXT(texture, target, pname, param) + return void + param texture Texture in value + param target TextureTarget in value + param pname TextureParameterName in value + param param CheckedFloat32 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + vectorequiv TextureParameterfvEXT + +TextureParameterfvEXT(texture, target, pname, params) + return void + param texture Texture in value + param target TextureTarget in value + param pname TextureParameterName in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +TextureParameteriEXT(texture, target, pname, param) + return void + param texture Texture in value + param target TextureTarget in value + param pname TextureParameterName in value + param param CheckedInt32 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + vectorequiv TextureParameterivEXT + +TextureParameterivEXT(texture, target, pname, params) + return void + param texture Texture in value + param target TextureTarget in value + param pname TextureParameterName in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +TextureImage1DEXT(texture, target, level, internalformat, width, border, format, type, pixels) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param width SizeI in value + param border CheckedInt32 in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width)] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + extension soft WINSOFT + glfflags capture-handcode decode-handcode pixel-unpack + +TextureImage2DEXT(texture, target, level, internalformat, width, height, border, format, type, pixels) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param width SizeI in value + param height SizeI in value + param border CheckedInt32 in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height)] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + extension soft WINSOFT + glfflags capture-handcode decode-handcode pixel-unpack + +TextureSubImage1DEXT(texture, target, level, xoffset, width, format, type, pixels) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param width SizeI in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width)] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### EXT client-handcode server-handcode + glxflags ignore + extension soft WINSOFT + glfflags ignore + +TextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, type, pixels) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height)] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### EXT client-handcode server-handcode + extension soft WINSOFT + glfflags ignore + +CopyTextureImage1DEXT(texture, target, level, internalformat, x, y, width, border) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param border CheckedInt32 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore ### EXT + +CopyTextureImage2DEXT(texture, target, level, internalformat, x, y, width, height, border) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + param border CheckedInt32 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore ### EXT + +CopyTextureSubImage1DEXT(texture, target, level, xoffset, x, y, width) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore ### EXT + +CopyTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, x, y, width, height) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore ### EXT + +# New 1.1 texture object queries + +GetTextureImageEXT(texture, target, level, format, type, pixels) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param format PixelFormat in value + param type PixelType in value + param pixels Void out array [COMPSIZE(target/level/format/type)] + category EXT_direct_state_access + dlflags notlistable + glxflags ignore ### client-handcode server-handcode + extension soft WINSOFT + glfflags capture-execute capture-handcode decode-handcode pixel-pack + +GetTextureParameterfvEXT(texture, target, pname, params) + return void + param texture Texture in value + param target TextureTarget in value + param pname GetTextureParameter in value + param params Float32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + +GetTextureParameterivEXT(texture, target, pname, params) + return void + param texture Texture in value + param target TextureTarget in value + param pname GetTextureParameter in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + +GetTextureLevelParameterfvEXT(texture, target, level, pname, params) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param pname GetTextureParameter in value + param params Float32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + +GetTextureLevelParameterivEXT(texture, target, level, pname, params) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param pname GetTextureParameter in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + +# New 1.2 3D texture object commands + +TextureImage3DEXT(texture, target, level, internalformat, width, height, depth, border, format, type, pixels) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param border CheckedInt32 in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height/depth)] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode EXT + extension soft WINSOFT + glfflags ignore + +TextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param zoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height/depth)] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode EXT + extension soft WINSOFT + glfflags ignore + +CopyTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, x, y, width, height) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param zoffset CheckedInt32 in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + category EXT_direct_state_access + glxflags ignore ### EXT + extension soft WINSOFT + glfflags ignore + +# New 1.1 multitexture commands + +MultiTexParameterfEXT(texunit, target, pname, param) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param pname TextureParameterName in value + param param CheckedFloat32 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + vectorequiv MultiTexParameterfvEXT + +MultiTexParameterfvEXT(texunit, target, pname, params) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param pname TextureParameterName in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MultiTexParameteriEXT(texunit, target, pname, param) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param pname TextureParameterName in value + param param CheckedInt32 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + vectorequiv MultiTexParameterivEXT + +MultiTexParameterivEXT(texunit, target, pname, params) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param pname TextureParameterName in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags ignore + +MultiTexImage1DEXT(texunit, target, level, internalformat, width, border, format, type, pixels) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param width SizeI in value + param border CheckedInt32 in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width)] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + extension soft WINSOFT + glfflags capture-handcode decode-handcode pixel-unpack + +MultiTexImage2DEXT(texunit, target, level, internalformat, width, height, border, format, type, pixels) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param width SizeI in value + param height SizeI in value + param border CheckedInt32 in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height)] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + extension soft WINSOFT + glfflags capture-handcode decode-handcode pixel-unpack + +MultiTexSubImage1DEXT(texunit, target, level, xoffset, width, format, type, pixels) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param width SizeI in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width)] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### EXT client-handcode server-handcode + extension soft WINSOFT + glfflags ignore + +MultiTexSubImage2DEXT(texunit, target, level, xoffset, yoffset, width, height, format, type, pixels) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height)] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### EXT client-handcode server-handcode + extension soft WINSOFT + glfflags ignore + +CopyMultiTexImage1DEXT(texunit, target, level, internalformat, x, y, width, border) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param border CheckedInt32 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore ### EXT + +CopyMultiTexImage2DEXT(texunit, target, level, internalformat, x, y, width, height, border) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + param border CheckedInt32 in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore ### EXT + +CopyMultiTexSubImage1DEXT(texunit, target, level, xoffset, x, y, width) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore ### EXT + +CopyMultiTexSubImage2DEXT(texunit, target, level, xoffset, yoffset, x, y, width, height) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore ### EXT + +# New 1.1 multitexture queries + +GetMultiTexImageEXT(texunit, target, level, format, type, pixels) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param format PixelFormat in value + param type PixelType in value + param pixels Void out array [COMPSIZE(target/level/format/type)] + category EXT_direct_state_access + dlflags notlistable + glxflags ignore ### client-handcode server-handcode + extension soft WINSOFT + glfflags capture-execute capture-handcode decode-handcode pixel-pack + +GetMultiTexParameterfvEXT(texunit, target, pname, params) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param pname GetTextureParameter in value + param params Float32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + +GetMultiTexParameterivEXT(texunit, target, pname, params) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param pname GetTextureParameter in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + +GetMultiTexLevelParameterfvEXT(texunit, target, level, pname, params) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param pname GetTextureParameter in value + param params Float32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + +GetMultiTexLevelParameterivEXT(texunit, target, level, pname, params) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param pname GetTextureParameter in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + +# New 1.2 3D multitexture commands + +MultiTexImage3DEXT(texunit, target, level, internalformat, width, height, depth, border, format, type, pixels) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param border CheckedInt32 in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height/depth)] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode EXT + extension soft WINSOFT + glfflags ignore + +MultiTexSubImage3DEXT(texunit, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param zoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param format PixelFormat in value + param type PixelType in value + param pixels Void in array [COMPSIZE(format/type/width/height/depth)] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode EXT + extension soft WINSOFT + glfflags ignore + +CopyMultiTexSubImage3DEXT(texunit, target, level, xoffset, yoffset, zoffset, x, y, width, height) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param zoffset CheckedInt32 in value + param x WinCoord in value + param y WinCoord in value + param width SizeI in value + param height SizeI in value + category EXT_direct_state_access + glxflags ignore ### EXT + extension soft WINSOFT + glfflags ignore + +# New 1.2.1 multitexture texture commands + +BindMultiTextureEXT(texunit, target, texture) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param texture Texture in value + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore ### EXT + +EnableClientStateIndexedEXT(array, index) + return void + param array EnableCap in value + param index UInt32 in value + category EXT_direct_state_access + dlflags notlistable + glxflags ignore ### client-handcode client-intercept server-handcode + extension soft WINSOFT + +DisableClientStateIndexedEXT(array, index) + return void + param array EnableCap in value + param index UInt32 in value + category EXT_direct_state_access + extension soft WINSOFT + dlflags notlistable + glxflags ignore ### client-handcode client-intercept server-handcode + +MultiTexCoordPointerEXT(texunit, size, type, stride, pointer) + return void + param texunit TextureUnit in value + param size Int32 in value + param type TexCoordPointerType in value + param stride SizeI in value + param pointer Void in array [COMPSIZE(size/type/stride)] retained + category EXT_direct_state_access + dlflags notlistable + glxflags ignore ### client-handcode client-intercept server-handcode + extension soft WINSOFT + glfflags ignore + +MultiTexEnvfEXT(texunit, target, pname, param) + return void + param texunit TextureUnit in value + param target TextureEnvTarget in value + param pname TextureEnvParameter in value + param param CheckedFloat32 in value + category EXT_direct_state_access + extension soft WINSOFT + vectorequiv MultiTexEnvfvEXT + glxflags ignore + glfflags gl-enum + +MultiTexEnvfvEXT(texunit, target, pname, params) + return void + param texunit TextureUnit in value + param target TextureEnvTarget in value + param pname TextureEnvParameter in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags gl-enum + +MultiTexEnviEXT(texunit, target, pname, param) + return void + param texunit TextureUnit in value + param target TextureEnvTarget in value + param pname TextureEnvParameter in value + param param CheckedInt32 in value + category EXT_direct_state_access + extension soft WINSOFT + vectorequiv MultiTexEnvivEXT + glxflags ignore + glfflags gl-enum + +MultiTexEnvivEXT(texunit, target, pname, params) + return void + param texunit TextureUnit in value + param target TextureEnvTarget in value + param pname TextureEnvParameter in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags gl-enum + +MultiTexGendEXT(texunit, coord, pname, param) + return void + param texunit TextureUnit in value + param coord TextureCoordName in value + param pname TextureGenParameter in value + param param Float64 in value + category EXT_direct_state_access + extension soft WINSOFT + vectorequiv MultiTexGendvEXT + glxflags ignore + glfflags gl-enum + +MultiTexGendvEXT(texunit, coord, pname, params) + return void + param texunit TextureUnit in value + param coord TextureCoordName in value + param pname TextureGenParameter in value + param params Float64 in array [COMPSIZE(pname)] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags gl-enum + +MultiTexGenfEXT(texunit, coord, pname, param) + return void + param texunit TextureUnit in value + param coord TextureCoordName in value + param pname TextureGenParameter in value + param param CheckedFloat32 in value + category EXT_direct_state_access + extension soft WINSOFT + vectorequiv MultiTexGenfvEXT + glxflags ignore + glfflags gl-enum + +MultiTexGenfvEXT(texunit, coord, pname, params) + return void + param texunit TextureUnit in value + param coord TextureCoordName in value + param pname TextureGenParameter in value + param params CheckedFloat32 in array [COMPSIZE(pname)] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags gl-enum + +MultiTexGeniEXT(texunit, coord, pname, param) + return void + param texunit TextureUnit in value + param coord TextureCoordName in value + param pname TextureGenParameter in value + param param CheckedInt32 in value + category EXT_direct_state_access + extension soft WINSOFT + vectorequiv MultiTexGenivEXT + glxflags ignore + glfflags gl-enum + +MultiTexGenivEXT(texunit, coord, pname, params) + return void + param texunit TextureUnit in value + param coord TextureCoordName in value + param pname TextureGenParameter in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category EXT_direct_state_access + extension soft WINSOFT + glxflags ignore + glfflags gl-enum + +# New 1.2.1 multitexture texture queries + +GetMultiTexEnvfvEXT(texunit, target, pname, params) + return void + param texunit TextureUnit in value + param target TextureEnvTarget in value + param pname TextureEnvParameter in value + param params Float32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + +GetMultiTexEnvivEXT(texunit, target, pname, params) + return void + param texunit TextureUnit in value + param target TextureEnvTarget in value + param pname TextureEnvParameter in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + +GetMultiTexGendvEXT(texunit, coord, pname, params) + return void + param texunit TextureUnit in value + param coord TextureCoordName in value + param pname TextureGenParameter in value + param params Float64 out array [COMPSIZE(pname)] + category EXT_direct_state_access + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + +GetMultiTexGenfvEXT(texunit, coord, pname, params) + return void + param texunit TextureUnit in value + param coord TextureCoordName in value + param pname TextureGenParameter in value + param params Float32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + +GetMultiTexGenivEXT(texunit, coord, pname, params) + return void + param texunit TextureUnit in value + param coord TextureCoordName in value + param pname TextureGenParameter in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + +# From EXT_draw_buffers2 +# EnableIndexedEXT +# DisableIndexedEXT +# IsEnabledIndexedEXT + +GetFloatIndexedvEXT(target, index, data) + return void + param target TypeEnum in value + param index UInt32 in value + param data Float32 out array [COMPSIZE(target)] + category EXT_direct_state_access + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + +GetDoubleIndexedvEXT(target, index, data) + return void + param target TypeEnum in value + param index UInt32 in value + param data Float64 out array [COMPSIZE(target)] + category EXT_direct_state_access + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + +GetPointerIndexedvEXT(target, index, data) + return void + param target TypeEnum in value + param index UInt32 in value + param data VoidPointer out array [COMPSIZE(target)] + category EXT_direct_state_access + dlflags notlistable + glxflags ignore + glfflags ignore + extension soft WINSOFT + +# New compressed texture commands + +CompressedTextureImage3DEXT(texture, target, level, internalformat, width, height, depth, border, imageSize, bits) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param border CheckedInt32 in value + param imageSize SizeI in value + param bits Void in array [imageSize] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + glfflags ignore + extension soft WINSOFT + +CompressedTextureImage2DEXT(texture, target, level, internalformat, width, height, border, imageSize, bits) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param width SizeI in value + param height SizeI in value + param border CheckedInt32 in value + param imageSize SizeI in value + param bits Void in array [imageSize] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + glfflags ignore + extension soft WINSOFT + +CompressedTextureImage1DEXT(texture, target, level, internalformat, width, border, imageSize, bits) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param width SizeI in value + param border CheckedInt32 in value + param imageSize SizeI in value + param bits Void in array [imageSize] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + glfflags ignore + extension soft WINSOFT + +CompressedTextureSubImage3DEXT(texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param zoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param format PixelFormat in value + param imageSize SizeI in value + param bits Void in array [imageSize] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + glfflags ignore + extension soft WINSOFT + +CompressedTextureSubImage2DEXT(texture, target, level, xoffset, yoffset, width, height, format, imageSize, bits) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param format PixelFormat in value + param imageSize SizeI in value + param bits Void in array [imageSize] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + glfflags ignore + extension soft WINSOFT + +CompressedTextureSubImage1DEXT(texture, target, level, xoffset, width, format, imageSize, bits) + return void + param texture Texture in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param width SizeI in value + param format PixelFormat in value + param imageSize SizeI in value + param bits Void in array [imageSize] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + glfflags ignore + extension soft WINSOFT + +# New compressed texture query + +GetCompressedTextureImageEXT(texture, target, lod, img) + return void + param texture Texture in value + param target TextureTarget in value + param lod CheckedInt32 in value + param img Void out array [COMPSIZE(target/lod)] + category EXT_direct_state_access + dlflags notlistable + glxflags ignore ### server-handcode + extension soft WINSOFT + +# New compressed multitexture commands + +CompressedMultiTexImage3DEXT(texunit, target, level, internalformat, width, height, depth, border, imageSize, bits) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param border CheckedInt32 in value + param imageSize SizeI in value + param bits Void in array [imageSize] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + glfflags ignore + extension soft WINSOFT + +CompressedMultiTexImage2DEXT(texunit, target, level, internalformat, width, height, border, imageSize, bits) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param width SizeI in value + param height SizeI in value + param border CheckedInt32 in value + param imageSize SizeI in value + param bits Void in array [imageSize] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + glfflags ignore + extension soft WINSOFT + +CompressedMultiTexImage1DEXT(texunit, target, level, internalformat, width, border, imageSize, bits) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param internalformat TextureInternalFormat in value + param width SizeI in value + param border CheckedInt32 in value + param imageSize SizeI in value + param bits Void in array [imageSize] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + glfflags ignore + extension soft WINSOFT + +CompressedMultiTexSubImage3DEXT(texunit, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, bits) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param zoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + param format PixelFormat in value + param imageSize SizeI in value + param bits Void in array [imageSize] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + glfflags ignore + extension soft WINSOFT + +CompressedMultiTexSubImage2DEXT(texunit, target, level, xoffset, yoffset, width, height, format, imageSize, bits) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param yoffset CheckedInt32 in value + param width SizeI in value + param height SizeI in value + param format PixelFormat in value + param imageSize SizeI in value + param bits Void in array [imageSize] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + glfflags ignore + extension soft WINSOFT + +CompressedMultiTexSubImage1DEXT(texunit, target, level, xoffset, width, format, imageSize, bits) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param level CheckedInt32 in value + param xoffset CheckedInt32 in value + param width SizeI in value + param format PixelFormat in value + param imageSize SizeI in value + param bits Void in array [imageSize] + category EXT_direct_state_access + dlflags handcode + glxflags ignore ### client-handcode server-handcode + glfflags ignore + extension soft WINSOFT + +# New compressed multitexture query + +GetCompressedMultiTexImageEXT(texunit, target, lod, img) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param lod CheckedInt32 in value + param img Void out array [COMPSIZE(target/lod)] + category EXT_direct_state_access + dlflags notlistable + glxflags ignore ### server-handcode + extension soft WINSOFT + +# New ARB assembly program named commands + +NamedProgramStringEXT(program, target, format, len, string) + return void + param program UInt32 in value + param target ProgramTarget in value + param format ProgramFormat in value + param len SizeI in value + param string Void in array [len] + category EXT_direct_state_access + subcategory ARB_vertex_program + extension soft WINSOFT + glfflags ignore + glxflags ignore ### client-handcode server-handcode EXT + glextmask GL_MASK_ARB_vertex_program|GL_MASK_ARB_fragment_program + +NamedProgramLocalParameter4dEXT(program, target, index, x, y, z, w) + return void + param program UInt32 in value + param target ProgramTarget in value + param index UInt32 in value + param x Float64 in value + param y Float64 in value + param z Float64 in value + param w Float64 in value + category EXT_direct_state_access + subcategory ARB_vertex_program + vectorequiv NamedProgramLocalParameter4dvEXT + glxvectorequiv NamedProgramLocalParameter4dvEXT + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore ### EXT + glextmask GL_MASK_ARB_vertex_program|GL_MASK_ARB_fragment_program + +NamedProgramLocalParameter4dvEXT(program, target, index, params) + return void + param program UInt32 in value + param target ProgramTarget in value + param index UInt32 in value + param params Float64 in array [4] + category EXT_direct_state_access + subcategory ARB_vertex_program + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore ### EXT + glextmask GL_MASK_ARB_vertex_program|GL_MASK_ARB_fragment_program + +NamedProgramLocalParameter4fEXT(program, target, index, x, y, z, w) + return void + param program UInt32 in value + param target ProgramTarget in value + param index UInt32 in value + param x Float32 in value + param y Float32 in value + param z Float32 in value + param w Float32 in value + category EXT_direct_state_access + subcategory ARB_vertex_program + vectorequiv NamedProgramLocalParameter4fvEXT + glxvectorequiv NamedProgramLocalParameter4fvEXT + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore ### EXT + glextmask GL_MASK_ARB_vertex_program|GL_MASK_ARB_fragment_program + +NamedProgramLocalParameter4fvEXT(program, target, index, params) + return void + param program UInt32 in value + param target ProgramTarget in value + param index UInt32 in value + param params Float32 in array [4] + category EXT_direct_state_access + subcategory ARB_vertex_program + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore ### EXT + glextmask GL_MASK_ARB_vertex_program|GL_MASK_ARB_fragment_program + +# New ARB assembly program named queries + +GetNamedProgramLocalParameterdvEXT(program, target, index, params) + return void + param program UInt32 in value + param target ProgramTarget in value + param index UInt32 in value + param params Float64 out array [4] + dlflags notlistable + category EXT_direct_state_access + subcategory ARB_vertex_program + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore ### client-handcode server-handcode EXT + glextmask GL_MASK_ARB_vertex_program|GL_MASK_ARB_fragment_program + +GetNamedProgramLocalParameterfvEXT(program, target, index, params) + return void + param program UInt32 in value + param target ProgramTarget in value + param index UInt32 in value + param params Float32 out array [4] + dlflags notlistable + category EXT_direct_state_access + subcategory ARB_vertex_program + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore ### client-handcode server-handcode EXT + glextmask GL_MASK_ARB_vertex_program|GL_MASK_ARB_fragment_program + +GetNamedProgramivEXT(program, target, pname, params) + return void + param program UInt32 in value + param target ProgramTarget in value + param pname ProgramProperty in value + param params Int32 out array [1] + dlflags notlistable + category EXT_direct_state_access + subcategory ARB_vertex_program + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore ### client-handcode server-handcode EXT + glextmask GL_MASK_ARB_vertex_program|GL_MASK_ARB_fragment_program + +GetNamedProgramStringEXT(program, target, pname, string) + return void + param program UInt32 in value + param target ProgramTarget in value + param pname ProgramStringProperty in value + param string Void out array [COMPSIZE(program,pname)] + dlflags notlistable + category EXT_direct_state_access + subcategory ARB_vertex_program + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore ### client-handcode server-handcode EXT + glextmask GL_MASK_ARB_vertex_program|GL_MASK_ARB_fragment_program + +# New EXT_gpu_program_parameters command + +NamedProgramLocalParameters4fvEXT(program, target, index, count, params) + return void + param program UInt32 in value + param target ProgramTarget in value + param index UInt32 in value + param count SizeI in value + param params Float32 in array [count*4] + category EXT_direct_state_access + subcategory EXT_gpu_program_parameters + extension soft WINSOFT NV10 + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_gpu_program_parameters + +# New NV_gpu_program4 commands + +NamedProgramLocalParameterI4iEXT(program, target, index, x, y, z, w) + return void + param program UInt32 in value + param target ProgramTarget in value + param index UInt32 in value + param x Int32 in value + param y Int32 in value + param z Int32 in value + param w Int32 in value + category EXT_direct_state_access + subcategory NV_gpu_program4 + vectorequiv NamedProgramLocalParameterI4ivEXT + glxvectorequiv NamedProgramLocalParameterI4ivEXT + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + glextmask GL_MASK_NV_gpu_program4 + +NamedProgramLocalParameterI4ivEXT(program, target, index, params) + return void + param program UInt32 in value + param target ProgramTarget in value + param index UInt32 in value + param params Int32 in array [4] + category EXT_direct_state_access + subcategory NV_gpu_program4 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + glextmask GL_MASK_NV_gpu_program4 + +NamedProgramLocalParametersI4ivEXT(program, target, index, count, params) + return void + param program UInt32 in value + param target ProgramTarget in value + param index UInt32 in value + param count SizeI in value + param params Int32 in array [count*4] + category EXT_direct_state_access + subcategory NV_gpu_program4 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + glextmask GL_MASK_NV_gpu_program4 + +NamedProgramLocalParameterI4uiEXT(program, target, index, x, y, z, w) + return void + param program UInt32 in value + param target ProgramTarget in value + param index UInt32 in value + param x UInt32 in value + param y UInt32 in value + param z UInt32 in value + param w UInt32 in value + category EXT_direct_state_access + subcategory NV_gpu_program4 + vectorequiv NamedProgramLocalParameterI4uivEXT + glxvectorequiv NamedProgramLocalParameterI4uivEXT + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + glextmask GL_MASK_NV_gpu_program4 + +NamedProgramLocalParameterI4uivEXT(program, target, index, params) + return void + param program UInt32 in value + param target ProgramTarget in value + param index UInt32 in value + param params UInt32 in array [4] + category EXT_direct_state_access + subcategory NV_gpu_program4 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + glextmask GL_MASK_NV_gpu_program4 + +NamedProgramLocalParametersI4uivEXT(program, target, index, count, params) + return void + param program UInt32 in value + param target ProgramTarget in value + param index UInt32 in value + param count SizeI in value + param params UInt32 in array [count*4] + category EXT_direct_state_access + subcategory NV_gpu_program4 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + glextmask GL_MASK_NV_gpu_program4 + +GetNamedProgramLocalParameterIivEXT(program, target, index, params) + return void + param program UInt32 in value + param target ProgramTarget in value + param index UInt32 in value + param params Int32 out array [4] + dlflags notlistable + category EXT_direct_state_access + subcategory NV_gpu_program4 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + glextmask GL_MASK_NV_gpu_program4 + +GetNamedProgramLocalParameterIuivEXT(program, target, index, params) + return void + param program UInt32 in value + param target ProgramTarget in value + param index UInt32 in value + param params UInt32 out array [4] + dlflags notlistable + category EXT_direct_state_access + subcategory NV_gpu_program4 + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + glextmask GL_MASK_NV_gpu_program4 + +# New EXT_texture_integer texture object commands + +TextureParameterIivEXT(texture, target, pname, params) + return void + param texture Texture in value + param target TextureTarget in value + param pname TextureParameterName in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category EXT_direct_state_access + subcategory EXT_texture_integer + extension soft WINSOFT + glxflags ignore + glfflags ignore + glextmask GL_MASK_EXT_texture_integer + +TextureParameterIuivEXT(texture, target, pname, params) + return void + param texture Texture in value + param target TextureTarget in value + param pname TextureParameterName in value + param params UInt32 in array [COMPSIZE(pname)] + category EXT_direct_state_access + subcategory EXT_texture_integer + extension soft WINSOFT + glxflags ignore + glfflags ignore + glextmask GL_MASK_EXT_texture_integer + +# New EXT_texture_integer texture object queries + +GetTextureParameterIivEXT(texture, target, pname, params) + return void + param texture Texture in value + param target TextureTarget in value + param pname GetTextureParameter in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + subcategory EXT_texture_integer + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + glextmask GL_MASK_EXT_texture_integer + +GetTextureParameterIuivEXT(texture, target, pname, params) + return void + param texture Texture in value + param target TextureTarget in value + param pname GetTextureParameter in value + param params UInt32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + subcategory EXT_texture_integer + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + glextmask GL_MASK_EXT_texture_integer + +# New EXT_texture_integer multitexture commands + +MultiTexParameterIivEXT(texunit, target, pname, params) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param pname TextureParameterName in value + param params CheckedInt32 in array [COMPSIZE(pname)] + category EXT_direct_state_access + subcategory EXT_texture_integer + extension soft WINSOFT + glxflags ignore + glfflags ignore + glextmask GL_MASK_EXT_texture_integer + +MultiTexParameterIuivEXT(texunit, target, pname, params) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param pname TextureParameterName in value + param params UInt32 in array [COMPSIZE(pname)] + category EXT_direct_state_access + subcategory EXT_texture_integer + extension soft WINSOFT + glxflags ignore + glfflags ignore + glextmask GL_MASK_EXT_texture_integer + +# New EXT_texture_integer multitexture queries + +GetMultiTexParameterIivEXT(texunit, target, pname, params) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param pname GetTextureParameter in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + subcategory EXT_texture_integer + dlflags notlistable + extension soft WINSOFT + glfflags capture-execute gl-enum + glxflags ignore + glextmask GL_MASK_EXT_texture_integer + +GetMultiTexParameterIuivEXT(texunit, target, pname, params) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param pname GetTextureParameter in value + param params UInt32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + subcategory EXT_texture_integer + dlflags notlistable + extension soft WINSOFT + glfflags capture-execute gl-enum + glxflags ignore + glextmask GL_MASK_EXT_texture_integer + +# New GLSL 2.0 uniform commands + +ProgramUniform1fEXT(program, location, v0) + return void + param program UInt32 in value + param location Int32 in value + param v0 Float32 in value + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform2fEXT(program, location, v0, v1) + return void + param program UInt32 in value + param location Int32 in value + param v0 Float32 in value + param v1 Float32 in value + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform3fEXT(program, location, v0, v1, v2) + return void + param program UInt32 in value + param location Int32 in value + param v0 Float32 in value + param v1 Float32 in value + param v2 Float32 in value + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform4fEXT(program, location, v0, v1, v2, v3) + return void + param program UInt32 in value + param location Int32 in value + param v0 Float32 in value + param v1 Float32 in value + param v2 Float32 in value + param v3 Float32 in value + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform1iEXT(program, location, v0) + return void + param program UInt32 in value + param location Int32 in value + param v0 Int32 in value + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform2iEXT(program, location, v0, v1) + return void + param program UInt32 in value + param location Int32 in value + param v0 Int32 in value + param v1 Int32 in value + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform3iEXT(program, location, v0, v1, v2) + return void + param program UInt32 in value + param location Int32 in value + param v0 Int32 in value + param v1 Int32 in value + param v2 Int32 in value + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform4iEXT(program, location, v0, v1, v2, v3) + return void + param program UInt32 in value + param location Int32 in value + param v0 Int32 in value + param v1 Int32 in value + param v2 Int32 in value + param v3 Int32 in value + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform1fvEXT(program, location, count, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param value Float32 in array [count] + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform2fvEXT(program, location, count, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param value Float32 in array [count*2] + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform3fvEXT(program, location, count, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param value Float32 in array [count*3] + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform4fvEXT(program, location, count, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param value Float32 in array [count*4] + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform1ivEXT(program, location, count, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param value Int32 in array [count] + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform2ivEXT(program, location, count, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param value Int32 in array [count*2] + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform3ivEXT(program, location, count, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param value Int32 in array [count*3] + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform4ivEXT(program, location, count, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param value Int32 in array [count*4] + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniformMatrix2fvEXT(program, location, count, transpose, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [count*4] + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniformMatrix3fvEXT(program, location, count, transpose, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [count*9] + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniformMatrix4fvEXT(program, location, count, transpose, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [count*16] + category EXT_direct_state_access + subcategory VERSION_2_0 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +# New GLSL 2.1 uniform commands + +ProgramUniformMatrix2x3fvEXT(program, location, count, transpose, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [count*6] + category EXT_direct_state_access + subcategory VERSION_2_1 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniformMatrix3x2fvEXT(program, location, count, transpose, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [count*6] + category EXT_direct_state_access + subcategory VERSION_2_1 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniformMatrix2x4fvEXT(program, location, count, transpose, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [count*8] + category EXT_direct_state_access + subcategory VERSION_2_1 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniformMatrix4x2fvEXT(program, location, count, transpose, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [count*8] + category EXT_direct_state_access + subcategory VERSION_2_1 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniformMatrix3x4fvEXT(program, location, count, transpose, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [count*12] + category EXT_direct_state_access + subcategory VERSION_2_1 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniformMatrix4x3fvEXT(program, location, count, transpose, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param transpose Boolean in value + param value Float32 in array [count*12] + category EXT_direct_state_access + subcategory VERSION_2_1 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +# New EXT_gpu_shader4 commands + +ProgramUniform1uiEXT(program, location, v0) + return void + param program UInt32 in value + param location Int32 in value + param v0 UInt32 in value + category EXT_direct_state_access + subcategory EXT_gpu_shader4 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform2uiEXT(program, location, v0, v1) + return void + param program UInt32 in value + param location Int32 in value + param v0 UInt32 in value + param v1 UInt32 in value + category EXT_direct_state_access + subcategory EXT_gpu_shader4 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform3uiEXT(program, location, v0, v1, v2) + return void + param program UInt32 in value + param location Int32 in value + param v0 UInt32 in value + param v1 UInt32 in value + param v2 UInt32 in value + category EXT_direct_state_access + subcategory EXT_gpu_shader4 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform4uiEXT(program, location, v0, v1, v2, v3) + return void + param program UInt32 in value + param location Int32 in value + param v0 UInt32 in value + param v1 UInt32 in value + param v2 UInt32 in value + param v3 UInt32 in value + category EXT_direct_state_access + subcategory EXT_gpu_shader4 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform1uivEXT(program, location, count, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param value UInt32 in array [count] + category EXT_direct_state_access + subcategory EXT_gpu_shader4 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform2uivEXT(program, location, count, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param value UInt32 in array [count*2] + category EXT_direct_state_access + subcategory EXT_gpu_shader4 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform3uivEXT(program, location, count, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param value UInt32 in array [count*3] + category EXT_direct_state_access + subcategory EXT_gpu_shader4 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +ProgramUniform4uivEXT(program, location, count, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param value UInt32 in array [count*4] + category EXT_direct_state_access + subcategory EXT_gpu_shader4 + glfflags ignore + glxflags ignore + extension soft WINSOFT + glextmask GL_MASK_OpenGL_2_0 + +# New named buffer commands + +NamedBufferDataEXT(buffer, size, data, usage) + return void + param buffer UInt32 in value + param size Sizeiptr in value + param data Void in array [COMPSIZE(size)] + param usage VertexBufferObjectUsage in value + category EXT_direct_state_access + extension soft WINSOFT + dlflags notlistable + glxflags ignore + glfflags ignore + +NamedBufferSubDataEXT(buffer, offset, size, data) + return void + param buffer UInt32 in value + param offset Intptr in value + param size Sizeiptr in value + param data Void in array [COMPSIZE(size)] + category EXT_direct_state_access + extension soft WINSOFT + dlflags notlistable + glxflags ignore + glfflags ignore + +MapNamedBufferEXT(buffer, access) + return VoidPointer + param buffer UInt32 in value + param access VertexBufferObjectAccess in value + category EXT_direct_state_access + extension soft WINSOFT + dlflags notlistable + glxflags ignore + glfflags ignore + +UnmapNamedBufferEXT(buffer) + return Boolean + param buffer UInt32 in value + category EXT_direct_state_access + extension soft WINSOFT + dlflags notlistable + glxflags ignore + glfflags ignore + +# New named buffer queries + +GetNamedBufferParameterivEXT(buffer, pname, params) + return void + param buffer UInt32 in value + param pname VertexBufferObjectParameter in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + extension soft WINSOFT + dlflags notlistable + glxflags ignore + glfflags ignore + +GetNamedBufferPointervEXT(buffer, pname, params) + return void + param buffer UInt32 in value + param pname VertexBufferObjectParameter in value + param params VoidPointer out array [COMPSIZE(pname)] + category EXT_direct_state_access + extension soft WINSOFT + dlflags notlistable + glxflags ignore + glfflags ignore + +GetNamedBufferSubDataEXT(buffer, offset, size, data) + return void + param buffer UInt32 in value + param offset Intptr in value + param size Sizeiptr in value + param data Void out array [COMPSIZE(size)] + category EXT_direct_state_access + extension soft WINSOFT + dlflags notlistable + glxflags ignore + glfflags ignore + +# New named texture buffer texture object command + +TextureBufferEXT(texture, target, internalformat, buffer) + return void + param texture Texture in value + param target TextureTarget in value + param internalformat TypeEnum in value + param buffer UInt32 in value + category EXT_direct_state_access + subcategory EXT_texture_buffer_object + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_texture_buffer_object + dlflags notlistable + +# New named texture buffer multitexture command + +MultiTexBufferEXT(texunit, target, internalformat, buffer) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param internalformat TypeEnum in value + param buffer UInt32 in value + category EXT_direct_state_access + subcategory EXT_texture_buffer_object + extension soft WINSOFT NV50 + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_texture_buffer_object + dlflags notlistable + +# New named frame buffer object commands + +NamedRenderbufferStorageEXT(renderbuffer, internalformat, width, height) + return void + param renderbuffer Renderbuffer in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param height SizeI in value + category EXT_direct_state_access + subcategory EXT_framebuffer_object + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_framebuffer_object + +GetNamedRenderbufferParameterivEXT(renderbuffer, pname, params) + return void + param renderbuffer Renderbuffer in value + param pname RenderbufferParameterName in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + subcategory EXT_framebuffer_object + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_framebuffer_object + +CheckNamedFramebufferStatusEXT(framebuffer, target) + return FramebufferStatus + param framebuffer Framebuffer in value + param target FramebufferTarget in value + category EXT_direct_state_access + subcategory EXT_framebuffer_object + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_framebuffer_object + +NamedFramebufferTexture1DEXT(framebuffer, attachment, textarget, texture, level) + return void + param framebuffer Framebuffer in value + param attachment FramebufferAttachment in value + param textarget TextureTarget in value + param texture Texture in value + param level CheckedInt32 in value + category EXT_direct_state_access + subcategory EXT_framebuffer_object + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_framebuffer_object + +NamedFramebufferTexture2DEXT(framebuffer, attachment, textarget, texture, level) + return void + param framebuffer Framebuffer in value + param attachment FramebufferAttachment in value + param textarget TextureTarget in value + param texture Texture in value + param level CheckedInt32 in value + category EXT_direct_state_access + subcategory EXT_framebuffer_object + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_framebuffer_object + +NamedFramebufferTexture3DEXT(framebuffer, attachment, textarget, texture, level, zoffset) + return void + param framebuffer Framebuffer in value + param attachment FramebufferAttachment in value + param textarget TextureTarget in value + param texture Texture in value + param level CheckedInt32 in value + param zoffset CheckedInt32 in value + category EXT_direct_state_access + subcategory EXT_framebuffer_object + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_framebuffer_object + +NamedFramebufferRenderbufferEXT(framebuffer, attachment, renderbuffertarget, renderbuffer) + return void + param framebuffer Framebuffer in value + param attachment FramebufferAttachment in value + param renderbuffertarget RenderbufferTarget in value + param renderbuffer Renderbuffer in value + category EXT_direct_state_access + subcategory EXT_framebuffer_object + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_framebuffer_object + +GetNamedFramebufferAttachmentParameterivEXT(framebuffer, attachment, pname, params) + return void + param framebuffer Framebuffer in value + param attachment FramebufferAttachment in value + param pname FramebufferAttachmentParameterName in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + subcategory EXT_framebuffer_object + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_framebuffer_object + +GenerateTextureMipmapEXT(texture, target) + return void + param texture Texture in value + param target TextureTarget in value + category EXT_direct_state_access + subcategory EXT_framebuffer_object + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_framebuffer_object + +GenerateMultiTexMipmapEXT(texunit, target) + return void + param texunit TextureUnit in value + param target TextureTarget in value + category EXT_direct_state_access + subcategory EXT_framebuffer_object + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_framebuffer_object + +FramebufferDrawBufferEXT(framebuffer, mode) + return void + param framebuffer Framebuffer in value + param mode DrawBufferMode in value + category EXT_direct_state_access + subcategory EXT_framebuffer_object + extension soft WINSOFT + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_framebuffer_object + +FramebufferDrawBuffersEXT(framebuffer, n, bufs) + return void + param framebuffer Framebuffer in value + param n SizeI in value + param bufs DrawBufferMode in array [n] + category EXT_direct_state_access + subcategory EXT_framebuffer_object + extension soft WINSOFT + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_framebuffer_object + +FramebufferReadBufferEXT(framebuffer, mode) + return void + param framebuffer Framebuffer in value + param mode ReadBufferMode in value + category EXT_direct_state_access + subcategory EXT_framebuffer_object + extension soft WINSOFT + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_framebuffer_object + +GetFramebufferParameterivEXT(framebuffer, pname, params) + return void + param framebuffer Framebuffer in value + param pname GetFramebufferParameter in value + param params Int32 out array [COMPSIZE(pname)] + category EXT_direct_state_access + subcategory EXT_framebuffer_object + dlflags notlistable + extension soft WINSOFT + glxflags ignore + glfflags capture-execute gl-enum + +# New named framebuffer multisample object commands + +NamedRenderbufferStorageMultisampleEXT(renderbuffer, samples, internalformat, width, height) + return void + param renderbuffer Renderbuffer in value + param samples SizeI in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param height SizeI in value + category EXT_direct_state_access + subcategory EXT_framebuffer_multisample + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_EXT_framebuffer_multisample + +# New named framebuffer multisample coverage object commands + +NamedRenderbufferStorageMultisampleCoverageEXT(renderbuffer, coverageSamples, colorSamples, internalformat, width, height) + return void + param renderbuffer Renderbuffer in value + param coverageSamples SizeI in value + param colorSamples SizeI in value + param internalformat PixelInternalFormat in value + param width SizeI in value + param height SizeI in value + category EXT_direct_state_access + subcategory NV_framebuffer_multisample_coverage + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_NV_framebuffer_multisample_coverage + +# New named geometry program/shader frame buffer object commands + +NamedFramebufferTextureEXT(framebuffer, attachment, texture, level) + return void + param framebuffer Framebuffer in value + param attachment FramebufferAttachment in value + param texture Texture in value + param level CheckedInt32 in value + category EXT_direct_state_access + subcategory NV_gpu_program4 + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_NV_gpu_program4 + +NamedFramebufferTextureLayerEXT(framebuffer, attachment, texture, level, layer) + return void + param framebuffer Framebuffer in value + param attachment FramebufferAttachment in value + param texture Texture in value + param level CheckedInt32 in value + param layer CheckedInt32 in value + category EXT_direct_state_access + subcategory NV_gpu_program4 + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_NV_gpu_program4 + +NamedFramebufferTextureFaceEXT(framebuffer, attachment, texture, level, face) + return void + param framebuffer Framebuffer in value + param attachment FramebufferAttachment in value + param texture Texture in value + param level CheckedInt32 in value + param face TextureTarget in value + category EXT_direct_state_access + subcategory NV_gpu_program4 + extension soft WINSOFT + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_NV_gpu_program4 + +# New explicit multisample query and commands + +TextureRenderbufferEXT(texture, target, renderbuffer) + return void + param texture Texture in value + param target TextureTarget in value + param renderbuffer UInt32 in value + category EXT_direct_state_access + subcategory NV_explicit_multisample + extension soft WINSOFT NV50 + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_NV_explicit_multisample + +MultiTexRenderbufferEXT(texunit, target, renderbuffer) + return void + param texunit TextureUnit in value + param target TextureTarget in value + param renderbuffer UInt32 in value + category EXT_direct_state_access + subcategory NV_explicit_multisample + extension soft WINSOFT NV50 + dlflags notlistable + glfflags ignore + glxflags ignore + glextmask GL_MASK_NV_explicit_multisample + +############################################################################### +# +# Extension #354 +# EXT_vertex_array_bgra commands +# +############################################################################### + +# (none) +newcategory: EXT_vertex_array_bgra + +############################################################################### +# +# Extension #355 - WGL_NV_gpu_affinity +# +############################################################################### + +############################################################################### +# +# Extension #356 +# EXT_texture_swizzle commands +# +############################################################################### + +# (none) +newcategory: EXT_texture_swizzle + +############################################################################### +# +# Extension #357 +# NV_explicit_multisample commands +# +############################################################################### + +# From EXT_draw_buffers2: GetBooleanIndexedvEXT / GetIntegerIndexedvEXT + +GetMultisamplefvNV(pname, index, val) + return void + param pname GetMultisamplePNameNV in value + param index UInt32 in value + param val Float32 out array [2] + category NV_explicit_multisample + dlflags notlistable + glfflags ignore + glxflags ignore + +SampleMaskIndexedNV(index, mask) + return void + param index UInt32 in value + param mask SampleMaskNV in value + category NV_explicit_multisample + glfflags ignore + glxflags ignore + +TexRenderbufferNV(target, renderbuffer) + return void + param target TextureTarget in value + param renderbuffer UInt32 in value + category NV_explicit_multisample + dlflags notlistable + glfflags ignore + glxflags ignore + +############################################################################### +# +# Extension #358 +# NV_transform_feedback2 commands +# +############################################################################### + +BindTransformFeedbackNV(target, id) + return void + param target BufferTargetARB in value + param id UInt32 in value + category NV_transform_feedback2 + glfflags ignore + glxflags ignore + +DeleteTransformFeedbacksNV(n, ids) + return void + param n SizeI in value + param ids UInt32 in array [n] + category NV_transform_feedback2 + dlflags notlistable + glfflags ignore + glxflags ignore + +GenTransformFeedbacksNV(n, ids) + return void + param n SizeI in value + param ids UInt32 out array [n] + category NV_transform_feedback2 + dlflags notlistable + glfflags ignore + glxflags ignore + +IsTransformFeedbackNV(id) + return Boolean + param id UInt32 in value + category NV_transform_feedback2 + dlflags notlistable + glfflags ignore + glxflags ignore + +PauseTransformFeedbackNV() + return void + category NV_transform_feedback2 + glfflags ignore + glxflags ignore + +ResumeTransformFeedbackNV() + return void + category NV_transform_feedback2 + glfflags ignore + glxflags ignore + +DrawTransformFeedbackNV(mode, id) + return void + param mode GLenum in value + param id UInt32 in value + category NV_transform_feedback2 + glfflags ignore + glxflags ignore + +############################################################################### +# +# Extension #359 +# ATI_meminfo commands +# +############################################################################### + +# (none) +newcategory: ATI_meminfo + +############################################################################### +# +# Extension #360 +# AMD_performance_monitor commands +# +############################################################################### + +GetPerfMonitorGroupsAMD(numGroups, groupsSize, groups) + return void + param numGroups Int32 out array [1] + param groupsSize SizeI in value + param groups UInt32 out array [groupsSize] + category AMD_performance_monitor + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetPerfMonitorCountersAMD(group, numCounters, maxActiveCounters, counterSize, counters) + return void + param group UInt32 in value + param numCounters Int32 out array [1] + param maxActiveCounters Int32 out array [1] + param counterSize SizeI in value + param counters UInt32 out array [counterSize] + category AMD_performance_monitor + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetPerfMonitorGroupStringAMD(group, bufSize, length, groupString) + return void + param group UInt32 in value + param bufSize SizeI in value + param length SizeI out array [1] + param groupString Char out array [bufSize] + category AMD_performance_monitor + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetPerfMonitorCounterStringAMD(group, counter, bufSize, length, counterString) + return void + param group UInt32 in value + param counter UInt32 in value + param bufSize SizeI in value + param length SizeI out array [1] + param counterString Char out array [bufSize] + category AMD_performance_monitor + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetPerfMonitorCounterInfoAMD(group, counter, pname, data) + return void + param group UInt32 in value + param counter UInt32 in value + param pname GLenum in value + param data void out array [COMPSIZE(pname)] + category AMD_performance_monitor + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GenPerfMonitorsAMD(n, monitors) + return void + param n SizeI in value + param monitors UInt32 out array [n] + category AMD_performance_monitor + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +# 'monitors' is actually in, not out, but extension spec doesn't use const +DeletePerfMonitorsAMD(n, monitors) + return void + param n SizeI in value + param monitors UInt32 out array [n] + category AMD_performance_monitor + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +# 'counterList' is actually in, not out, but extension spec doesn't use const +SelectPerfMonitorCountersAMD(monitor, enable, group, numCounters, counterList) + return void + param monitor UInt32 in value + param enable Boolean in value + param group UInt32 in value + param numCounters Int32 in value + param counterList UInt32 out array [numCounters] + category AMD_performance_monitor + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +BeginPerfMonitorAMD(monitor) + return void + param monitor UInt32 in value + category AMD_performance_monitor + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +EndPerfMonitorAMD(monitor) + return void + param monitor UInt32 in value + category AMD_performance_monitor + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetPerfMonitorCounterDataAMD(monitor, pname, dataSize, data, bytesWritten) + return void + param monitor UInt32 in value + param pname GLenum in value + param dataSize SizeI in value + param data UInt32 out array [dataSize] + param bytesWritten Int32 out array [1] + category AMD_performance_monitor + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #361 - WGL_AMD_gpu_association +# +############################################################################### + +############################################################################### +# +# Extension #362 +# AMD_texture_texture4 commands +# +############################################################################### + +# (none) +newcategory: AMD_texture_texture4 + +############################################################################### +# +# Extension #363 +# AMD_vertex_shader_tesselator commands +# +############################################################################### + +TessellationFactorAMD(factor) + return void + param factor Float32 in value + category AMD_vertex_shader_tesselator + version 2.0 + glxsingle ? + glxflags ignore + offset ? + +TessellationModeAMD(mode) + return void + param mode GLenum in value + category AMD_vertex_shader_tesselator + version 2.0 + glxsingle ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #364 +# EXT_provoking_vertex commands +# +############################################################################### + +ProvokingVertexEXT(mode) + return void + param mode GLenum in value + category EXT_provoking_vertex + version 2.1 + glxsingle ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #365 +# EXT_texture_snorm commands +# +############################################################################### + +# (none) +newcategory: EXT_texture_snorm + +############################################################################### +# +# Extension #366 +# AMD_draw_buffers_blend commands +# +############################################################################### + +# void BlendFuncIndexedAMD(uint buf, enum src, enum dst) +# void BlendFuncSeparateIndexedAMD(uint buf, enum srcRGB, enum dstRGB, enum srcAlpha, enum dstAlpha) +# void BlendEquationIndexedAMD(uint buf, enum mode) +# void BlendEquationSeparateIndexedAMD(uint buf, enum modeRGB, enum modeAlpha) + +BlendFuncIndexedAMD(buf, src, dst) + return void + param buf UInt32 in value + param src GLenum in value + param dst GLenum in value + category AMD_draw_buffers_blend + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +BlendFuncSeparateIndexedAMD(buf, srcRGB, dstRGB, srcAlpha, dstAlpha) + return void + param buf UInt32 in value + param srcRGB GLenum in value + param dstRGB GLenum in value + param srcAlpha GLenum in value + param dstAlpha GLenum in value + category AMD_draw_buffers_blend + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +BlendEquationIndexedAMD(buf, mode) + return void + param buf UInt32 in value + param mode GLenum in value + category AMD_draw_buffers_blend + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +BlendEquationSeparateIndexedAMD(buf, modeRGB, modeAlpha) + return void + param buf UInt32 in value + param modeRGB GLenum in value + param modeAlpha GLenum in value + category AMD_draw_buffers_blend + version 2.0 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #367 +# APPLE_texture_range commands +# +############################################################################### + +TextureRangeAPPLE(target, length, pointer) + return void + param target GLenum in value + param length SizeI in value + param pointer Void in array [length] + category APPLE_texture_range + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetTexParameterPointervAPPLE(target, pname, params) + return void + param target GLenum in value + param pname GLenum in value + param params VoidPointer out array [1] + category APPLE_texture_range + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #368 +# APPLE_float_pixels commands +# +############################################################################### + +# (none) +newcategory: APPLE_float_pixels + +############################################################################### +# +# Extension #369 +# APPLE_vertex_program_evaluators commands +# +############################################################################### + +EnableVertexAttribAPPLE(index, pname) + return void + param index UInt32 in value + param pname GLenum in value + category APPLE_vertex_program_evaluators + version 1.5 + extension + glxropcode ? + glxflags ignore + offset ? + +DisableVertexAttribAPPLE(index, pname) + return void + param index UInt32 in value + param pname GLenum in value + category APPLE_vertex_program_evaluators + version 1.5 + extension + glxropcode ? + glxflags ignore + offset ? + +IsVertexAttribEnabledAPPLE(index, pname) + return Boolean + param index UInt32 in value + param pname GLenum in value + category APPLE_vertex_program_evaluators + version 1.5 + extension + glxropcode ? + glxflags ignore + offset ? + +MapVertexAttrib1dAPPLE(index, size, u1, u2, stride, order, points) + return void + param index UInt32 in value + param size UInt32 in value + param u1 CoordD in value + param u2 CoordD in value + param stride Int32 in value + param order CheckedInt32 in value + param points CoordD in array [COMPSIZE(size/stride/order)] + category APPLE_vertex_program_evaluators + version 1.5 + extension + glxropcode ? + glxflags ignore + offset ? + +MapVertexAttrib1fAPPLE(index, size, u1, u2, stride, order, points) + return void + param index UInt32 in value + param size UInt32 in value + param u1 CoordF in value + param u2 CoordF in value + param stride Int32 in value + param order CheckedInt32 in value + param points CoordF in array [COMPSIZE(size/stride/order)] + category APPLE_vertex_program_evaluators + version 1.5 + extension + glxropcode ? + glxflags ignore + offset ? + +MapVertexAttrib2dAPPLE(index, size, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points) + return void + param index UInt32 in value + param size UInt32 in value + param u1 CoordD in value + param u2 CoordD in value + param ustride Int32 in value + param uorder CheckedInt32 in value + param v1 CoordD in value + param v2 CoordD in value + param vstride Int32 in value + param vorder CheckedInt32 in value + param points CoordD in array [COMPSIZE(size/ustride/uorder/vstride/vorder)] + category APPLE_vertex_program_evaluators + version 1.5 + extension + glxropcode ? + glxflags ignore + offset ? + +MapVertexAttrib2fAPPLE(index, size, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points) + return void + param index UInt32 in value + param size UInt32 in value + param u1 CoordF in value + param u2 CoordF in value + param ustride Int32 in value + param uorder CheckedInt32 in value + param v1 CoordF in value + param v2 CoordF in value + param vstride Int32 in value + param vorder CheckedInt32 in value + param points CoordF in array [COMPSIZE(size/ustride/uorder/vstride/vorder)] + category APPLE_vertex_program_evaluators + version 1.5 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #370 +# APPLE_aux_depth_stencil commands +# +############################################################################### + +# (none) +newcategory: APPLE_aux_depth_stencil + +############################################################################### +# +# Extension #371 +# APPLE_object_purgeable commands +# +############################################################################### + +ObjectPurgeableAPPLE(objectType, name, option) + return GLenum + param objectType GLenum in value + param name UInt32 in value + param option GLenum in value + category APPLE_object_purgeable + version 1.5 + extension + glxropcode ? + glxflags ignore + offset ? + +ObjectUnpurgeableAPPLE(objectType, name, option) + return GLenum + param objectType GLenum in value + param name UInt32 in value + param option GLenum in value + category APPLE_object_purgeable + version 1.5 + extension + glxropcode ? + glxflags ignore + offset ? + +GetObjectParameterivAPPLE(objectType, name, pname, params) + return void + param objectType GLenum in value + param name UInt32 in value + param pname GLenum in value + param params Int32 out array [COMPSIZE(pname)] + category APPLE_object_purgeable + dlflags notlistable + version 1.5 + extension + glxsingle ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #372 +# APPLE_row_bytes commands +# +############################################################################### + +# (none) +newcategory: APPLE_row_bytes + +############################################################################### +# +# Extension #373 +# APPLE_rgb_422 commands +# +############################################################################### + +# (none) +newcategory: APPLE_rgb_422 + +############################################################################### +# +# Extension #374 +# NV_video_capture commands +# +############################################################################### + +BeginVideoCaptureNV(video_capture_slot) + return void + param video_capture_slot UInt32 in value + category NV_video_capture + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +BindVideoCaptureStreamBufferNV(video_capture_slot, stream, frame_region, offset) + return void + param video_capture_slot UInt32 in value + param stream UInt32 in value + param frame_region GLenum in value + param offset BufferOffsetARB in value + category NV_video_capture + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +BindVideoCaptureStreamTextureNV(video_capture_slot, stream, frame_region, target, texture) + return void + param video_capture_slot UInt32 in value + param stream UInt32 in value + param frame_region GLenum in value + param target GLenum in value + param texture UInt32 in value + category NV_video_capture + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +EndVideoCaptureNV(video_capture_slot) + return void + param video_capture_slot UInt32 in value + category NV_video_capture + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetVideoCaptureivNV(video_capture_slot, pname, params) + return void + param video_capture_slot UInt32 in value + param pname GLenum in value + param params Int32 out array [COMPSIZE(pname)] + category NV_video_capture + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetVideoCaptureStreamivNV(video_capture_slot, stream, pname, params) + return void + param video_capture_slot UInt32 in value + param stream UInt32 in value + param pname GLenum in value + param params Int32 out array [COMPSIZE(pname)] + category NV_video_capture + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetVideoCaptureStreamfvNV(video_capture_slot, stream, pname, params) + return void + param video_capture_slot UInt32 in value + param stream UInt32 in value + param pname GLenum in value + param params Float32 out array [COMPSIZE(pname)] + category NV_video_capture + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetVideoCaptureStreamdvNV(video_capture_slot, stream, pname, params) + return void + param video_capture_slot UInt32 in value + param stream UInt32 in value + param pname GLenum in value + param params Float64 out array [COMPSIZE(pname)] + category NV_video_capture + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +VideoCaptureNV(video_capture_slot, sequence_num, capture_time) + return GLenum + param video_capture_slot UInt32 in value + param sequence_num UInt32 out reference + param capture_time UInt64EXT out reference + category NV_video_capture + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VideoCaptureStreamParameterivNV(video_capture_slot, stream, pname, params) + return void + param video_capture_slot UInt32 in value + param stream UInt32 in value + param pname GLenum in value + param params Int32 in array [COMPSIZE(pname)] + category NV_video_capture + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VideoCaptureStreamParameterfvNV(video_capture_slot, stream, pname, params) + return void + param video_capture_slot UInt32 in value + param stream UInt32 in value + param pname GLenum in value + param params Float32 in array [COMPSIZE(pname)] + category NV_video_capture + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VideoCaptureStreamParameterdvNV(video_capture_slot, stream, pname, params) + return void + param video_capture_slot UInt32 in value + param stream UInt32 in value + param pname GLenum in value + param params Float64 in array [COMPSIZE(pname)] + category NV_video_capture + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #375 - GLX_EXT_swap_control +# +############################################################################### + +############################################################################### +# +# Extension #376 - also GLX_NV_copy_image, WGL_NV_copy_image +# NV_copy_image commands +# +############################################################################### + +CopyImageSubDataNV(srcName, srcTarget, srcLevel, srcX, srcY, srcZ, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, width, height, depth) + return void + param srcName UInt32 in value + param srcTarget GLenum in value + param srcLevel Int32 in value + param srcX Int32 in value + param srcY Int32 in value + param srcZ Int32 in value + param dstName UInt32 in value + param dstTarget GLenum in value + param dstLevel Int32 in value + param dstX Int32 in value + param dstY Int32 in value + param dstZ Int32 in value + param width SizeI in value + param height SizeI in value + param depth SizeI in value + category NV_copy_image + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #377 +# EXT_separate_shader_objects commands +# +############################################################################### + +UseShaderProgramEXT(type, program) + return void + param type GLenum in value + param program UInt32 in value + category EXT_separate_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +ActiveProgramEXT(program) + return void + param program UInt32 in value + category EXT_separate_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +CreateShaderProgramEXT(type, string) + return UInt32 + param type GLenum in value + param string Char in array [] + category EXT_separate_shader_objects + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #378 +# NV_parameter_buffer_object2 commands +# +############################################################################### + +newcategory: NV_parameter_buffer_object2 + +############################################################################### +# +# Extension #379 +# NV_shader_buffer_load commands +# +############################################################################### + +MakeBufferResidentNV(target, access) + return void + param target GLenum in value + param access GLenum in value + category NV_shader_buffer_load + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +MakeBufferNonResidentNV(target) + return void + param target GLenum in value + category NV_shader_buffer_load + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +IsBufferResidentNV(target) + return Boolean + param target GLenum in value + category NV_shader_buffer_load + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +NamedMakeBufferResidentNV(buffer, access) + return void + param buffer UInt32 in value + param access GLenum in value + category NV_shader_buffer_load + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +NamedMakeBufferNonResidentNV(buffer) + return void + param buffer UInt32 in value + category NV_shader_buffer_load + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +IsNamedBufferResidentNV(buffer) + return Boolean + param buffer UInt32 in value + category NV_shader_buffer_load + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetBufferParameterui64vNV(target, pname, params) + return void + param target GLenum in value + param pname GLenum in value + param params UInt64EXT out array [COMPSIZE(pname)] + category NV_shader_buffer_load + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetNamedBufferParameterui64vNV(buffer, pname, params) + return void + param buffer UInt32 in value + param pname GLenum in value + param params UInt64EXT out array [COMPSIZE(pname)] + category NV_shader_buffer_load + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +GetIntegerui64vNV(value, result) + return void + param value GLenum in value + param result UInt64EXT out array [COMPSIZE(value)] + category NV_shader_buffer_load + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +Uniformui64NV(location, value) + return void + param location Int32 in value + param value UInt64EXT in value + category NV_shader_buffer_load + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +Uniformui64vNV(location, count, value) + return void + param location Int32 in value + param count SizeI in value + param value UInt64EXT in array [count] + category NV_shader_buffer_load + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetUniformui64vNV(program, location, params) + return void + param program UInt32 in value + param location Int32 in value + param params UInt64EXT out array [COMPSIZE(program/location)] + category NV_shader_buffer_load + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +ProgramUniformui64NV(program, location, value) + return void + param program UInt32 in value + param location Int32 in value + param value UInt64EXT in value + category NV_shader_buffer_load + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +ProgramUniformui64vNV(program, location, count, value) + return void + param program UInt32 in value + param location Int32 in value + param count SizeI in value + param value UInt64EXT in array [count] + category NV_shader_buffer_load + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #380 +# NV_vertex_buffer_unified_memory commands +# +############################################################################### + +BufferAddressRangeNV(pname, index, address, length) + return void + param pname GLenum in value + param index UInt32 in value + param address UInt64EXT in value + param length BufferSize in value + category NV_vertex_buffer_unified_memory + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexFormatNV(size, type, stride) + return void + param size Int32 in value + param type GLenum in value + param stride SizeI in value + category NV_vertex_buffer_unified_memory + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +NormalFormatNV(type, stride) + return void + param type GLenum in value + param stride SizeI in value + category NV_vertex_buffer_unified_memory + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +ColorFormatNV(size, type, stride) + return void + param size Int32 in value + param type GLenum in value + param stride SizeI in value + category NV_vertex_buffer_unified_memory + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +IndexFormatNV(type, stride) + return void + param type GLenum in value + param stride SizeI in value + category NV_vertex_buffer_unified_memory + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +TexCoordFormatNV(size, type, stride) + return void + param size Int32 in value + param type GLenum in value + param stride SizeI in value + category NV_vertex_buffer_unified_memory + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +EdgeFlagFormatNV(stride) + return void + param stride SizeI in value + category NV_vertex_buffer_unified_memory + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +SecondaryColorFormatNV(size, type, stride) + return void + param size Int32 in value + param type GLenum in value + param stride SizeI in value + category NV_vertex_buffer_unified_memory + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +FogCoordFormatNV(type, stride) + return void + param type GLenum in value + param stride SizeI in value + category NV_vertex_buffer_unified_memory + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexAttribFormatNV(index, size, type, normalized, stride) + return void + param index UInt32 in value + param size Int32 in value + param type GLenum in value + param normalized Boolean in value + param stride SizeI in value + category NV_vertex_buffer_unified_memory + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +VertexAttribIFormatNV(index, size, type, stride) + return void + param index UInt32 in value + param size Int32 in value + param type GLenum in value + param stride SizeI in value + category NV_vertex_buffer_unified_memory + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + +GetIntegerui64i_vNV(value, index, result) + return void + param value GLenum in value + param index UInt32 in value + param result UInt64EXT out array [COMPSIZE(value)] + category NV_vertex_buffer_unified_memory + dlflags notlistable + version 1.2 + extension + glxsingle ? + glxflags ignore + offset ? + +############################################################################### +# +# Extension #381 +# NV_texture_barrier commands +# +############################################################################### + +TextureBarrierNV() + return void + category NV_texture_barrier + version 1.2 + extension + glxropcode ? + glxflags ignore + offset ? + diff --git a/xorg-server/hw/xwin/glx/gl.tm b/xorg-server/hw/xwin/glx/gl.tm new file mode 100644 index 000000000..fb4f8515c --- /dev/null +++ b/xorg-server/hw/xwin/glx/gl.tm @@ -0,0 +1,322 @@ +AccumOp,*,*, GLenum,*,* +AlphaFunction,*,*, GLenum,*,* +AttribMask,*,*, GLbitfield,*,* +BeginMode,*,*, GLenum,*,* +BinormalPointerTypeEXT,*,*, GLenum,*,* +BlendEquationMode,*,*, GLenum,*,* +BlendEquationModeEXT,*,*, GLenum,*,* +BlendFuncSeparateParameterEXT,*,*, GLenum,*,* +BlendingFactorDest,*,*, GLenum,*,* +BlendingFactorSrc,*,*, GLenum,*,* +Boolean,*,*, GLboolean,*,* +BooleanPointer,*,*, GLboolean*,*,* +Char,*,*, GLchar,*,* +CharPointer,*,*, GLchar*,*,* +CheckedFloat32,*,*, GLfloat,*,* +CheckedInt32,*,*, GLint,*,* +ClampColorTargetARB,*,*, GLenum,*,* +ClampColorModeARB,*,*, GLenum,*,* +ClampedColorF,*,*, GLclampf,*,* +ClampedFloat32,*,*, GLclampf,*,* +ClampedFloat64,*,*, GLclampd,*,* +ClampedStencilValue,*,*, GLint,*,* +ClearBufferMask,*,*, GLbitfield,*,* +ClientAttribMask,*,*, GLbitfield,*,* +ClipPlaneName,*,*, GLenum,*,* +ColorB,*,*, GLbyte,*,* +ColorD,*,*, GLdouble,*,* +ColorF,*,*, GLfloat,*,* +ColorI,*,*, GLint,*,* +ColorIndexValueD,*,*, GLdouble,*,* +ColorIndexValueF,*,*, GLfloat,*,* +ColorIndexValueI,*,*, GLint,*,* +ColorIndexValueS,*,*, GLshort,*,* +ColorIndexValueUB,*,*, GLubyte,*,* +ColorMaterialParameter,*,*, GLenum,*,* +ColorPointerType,*,*, GLenum,*,* +ColorS,*,*, GLshort,*,* +ColorTableParameterPName,*,*, GLenum,*,* +ColorTableParameterPNameSGI,*,*, GLenum,*,* +ColorTableTarget,*,*, GLenum,*,* +ColorTableTargetSGI,*,*, GLenum,*,* +ColorUB,*,*, GLubyte,*,* +ColorUI,*,*, GLuint,*,* +ColorUS,*,*, GLushort,*,* +CombinerBiasNV,*,*, GLenum,*,* +CombinerComponentUsageNV,*,*, GLenum,*,* +CombinerMappingNV,*,*, GLenum,*,* +CombinerParameterNV,*,*, GLenum,*,* +CombinerPortionNV,*,*, GLenum,*,* +CombinerRegisterNV,*,*, GLenum,*,* +CombinerScaleNV,*,*, GLenum,*,* +CombinerStageNV,*,*, GLenum,*,* +CombinerVariableNV,*,*, GLenum,*,* +CompressedTextureARB,*,*, GLvoid,*,* +ControlPointNV,*,*, GLvoid,*,* +ControlPointTypeNV,*,*, GLenum,*,* +ConvolutionParameter,*,*, GLenum,*,* +ConvolutionParameterEXT,*,*, GLenum,*,* +ConvolutionTarget,*,*, GLenum,*,* +ConvolutionTargetEXT,*,*, GLenum,*,* +CoordD,*,*, GLdouble,*,* +CoordF,*,*, GLfloat,*,* +CoordI,*,*, GLint,*,* +CoordS,*,*, GLshort,*,* +CullFaceMode,*,*, GLenum,*,* +CullParameterEXT,*,*, GLenum,*,* +DepthFunction,*,*, GLenum,*,* +DrawBufferMode,*,*, GLenum,*,* +DrawBufferName,*,*, GLint,*,* +DrawElementsType,*,*, GLenum,*,* +ElementPointerTypeATI,*,*, GLenum,*,* +EnableCap,*,*, GLenum,*,* +ErrorCode,*,*, GLenum,*,* +EvalMapsModeNV,*,*, GLenum,*,* +EvalTargetNV,*,*, GLenum,*,* +FeedbackElement,*,*, GLfloat,*,* +FeedbackType,*,*, GLenum,*,* +FenceNV,*,*, GLuint,*,* +FenceConditionNV,*,*, GLenum,*,* +FenceParameterNameNV,*,*, GLenum,*,* +FfdMaskSGIX,*,*, GLbitfield,*,* +FfdTargetSGIX,*,*, GLenum,*,* +Float32,*,*, GLfloat,*,* +Float32Pointer,*,*, GLfloat*,*,* +Float64,*,*, GLdouble,*,* +Float64Pointer,*,*, GLdouble*,*,* +FogParameter,*,*, GLenum,*,* +FogPointerTypeEXT,*,*, GLenum,*,* +FogPointerTypeIBM,*,*, GLenum,*,* +FragmentLightModelParameterSGIX,*,*,GLenum,*,* +FragmentLightNameSGIX,*,*, GLenum,*,* +FragmentLightParameterSGIX,*,*, GLenum,*,* +FramebufferAttachment,*,*, GLenum,*,* +FramebufferTarget,*,*, GLenum,*,* +FrontFaceDirection,*,*, GLenum,*,* +FunctionPointer,*,*, _GLfuncptr,*,* +GetColorTableParameterPName,*,*, GLenum,*,* +GetColorTableParameterPNameSGI,*,*, GLenum,*,* +GetConvolutionParameterPName,*,*, GLenum,*,* +GetHistogramParameterPName,*,*, GLenum,*,* +GetHistogramParameterPNameEXT,*,*, GLenum,*,* +GetMapQuery,*,*, GLenum,*,* +GetMinmaxParameterPName,*,*, GLenum,*,* +GetMinmaxParameterPNameEXT,*,*, GLenum,*,* +GetPName,*,*, GLenum,*,* +GetPointervPName,*,*, GLenum,*,* +GetTextureParameter,*,*, GLenum,*,* +HintMode,*,*, GLenum,*,* +HintTarget,*,*, GLenum,*,* +HintTargetPGI,*,*, GLenum,*,* +HistogramTarget,*,*, GLenum,*,* +HistogramTargetEXT,*,*, GLenum,*,* +IglooFunctionSelectSGIX,*,*, GLenum,*,* +IglooParameterSGIX,*,*, GLvoid,*,* +ImageTransformPNameHP,*,*, GLenum,*,* +ImageTransformTargetHP,*,*, GLenum,*,* +IndexFunctionEXT,*,*, GLenum,*,* +IndexMaterialParameterEXT,*,*, GLenum,*,* +IndexPointerType,*,*, GLenum,*,* +Int16,*,*, GLshort,*,* +Int32,*,*, GLint,*,* +Int8,*,*, GLbyte,*,* +InterleavedArrayFormat,*,*, GLenum,*,* +LightEnvParameterSGIX,*,*, GLenum,*,* +LightModelParameter,*,*, GLenum,*,* +LightName,*,*, GLenum,*,* +LightParameter,*,*, GLenum,*,* +LightTextureModeEXT,*,*, GLenum,*,* +LightTexturePNameEXT,*,*, GLenum,*,* +LineStipple,*,*, GLushort,*,* +List,*,*, GLuint,*,* +ListMode,*,*, GLenum,*,* +ListNameType,*,*, GLenum,*,* +ListParameterName,*,*, GLenum,*,* +LogicOp,*,*, GLenum,*,* +MapAttribParameterNV,*,*, GLenum,*,* +MapParameterNV,*,*, GLenum,*,* +MapTarget,*,*, GLenum,*,* +MapTargetNV,*,*, GLenum,*,* +MapTypeNV,*,*, GLenum,*,* +MaskedColorIndexValueF,*,*, GLfloat,*,* +MaskedColorIndexValueI,*,*, GLuint,*,* +MaskedStencilValue,*,*, GLuint,*,* +MaterialFace,*,*, GLenum,*,* +MaterialParameter,*,*, GLenum,*,* +MatrixIndexPointerTypeARB,*,*, GLenum,*,* +MatrixMode,*,*, GLenum,*,* +MatrixTransformNV,*,*, GLenum,*,* +MeshMode1,*,*, GLenum,*,* +MeshMode2,*,*, GLenum,*,* +MinmaxTarget,*,*, GLenum,*,* +MinmaxTargetEXT,*,*, GLenum,*,* +NormalPointerType,*,*, GLenum,*,* +NurbsCallback,*,*, GLenum,*,* +NurbsObj,*,*, GLUnurbs*,*,* +NurbsProperty,*,*, GLenum,*,* +NurbsTrim,*,*, GLenum,*,* +OcclusionQueryParameterNameNV,*,*, GLenum,*,* +PixelCopyType,*,*, GLenum,*,* +PixelFormat,*,*, GLenum,*,* +PixelInternalFormat,*,*, GLenum,*,* +PixelMap,*,*, GLenum,*,* +PixelStoreParameter,*,*, GLenum,*,* +PixelTexGenModeSGIX,*,*, GLenum,*,* +PixelTexGenParameterNameSGIS,*,*, GLenum,*,* +PixelTransferParameter,*,*, GLenum,*,* +PixelTransformPNameEXT,*,*, GLenum,*,* +PixelTransformTargetEXT,*,*, GLenum,*,* +PixelType,*,*, GLenum,*,* +PointParameterNameARB,*,*, GLenum,*,* +PolygonMode,*,*, GLenum,*,* +ProgramNV,*,*, GLuint,*,* +ProgramCharacterNV,*,*, GLubyte,*,* +ProgramParameterNV,*,*, GLenum,*,* +ProgramParameterPName,*,*, GLenum,*,* +QuadricCallback,*,*, GLenum,*,* +QuadricDrawStyle,*,*, GLenum,*,* +QuadricNormal,*,*, GLenum,*,* +QuadricObj,*,*, GLUquadric*,*,* +QuadricOrientation,*,*, GLenum,*,* +ReadBufferMode,*,*, GLenum,*,* +RenderbufferTarget,*,*, GLenum,*,* +RenderingMode,*,*, GLenum,*,* +ReplacementCodeSUN,*,*, GLuint,*,* +ReplacementCodeTypeSUN,*,*, GLenum,*,* +SamplePassARB,*,*, GLenum,*,* +SamplePatternEXT,*,*, GLenum,*,* +SamplePatternSGIS,*,*, GLenum,*,* +SecondaryColorPointerTypeIBM,*,*, GLenum,*,* +SelectName,*,*, GLuint,*,* +SeparableTarget,*,*, GLenum,*,* +SeparableTargetEXT,*,*, GLenum,*,* +ShadingModel,*,*, GLenum,*,* +SizeI,*,*, GLsizei,*,* +SpriteParameterNameSGIX,*,*, GLenum,*,* +StencilFunction,*,*, GLenum,*,* +StencilFaceDirection,*,*, GLenum,*,* +StencilOp,*,*, GLenum,*,* +StencilValue,*,*, GLint,*,* +String,*,*, const GLubyte *,*,* +StringName,*,*, GLenum,*,* +TangentPointerTypeEXT,*,*, GLenum,*,* +TessCallback,*,*, GLenum,*,* +TessContour,*,*, GLenum,*,* +TessProperty,*,*, GLenum,*,* +TesselatorObj,*,*, GLUtesselator*,*,* +TexCoordPointerType,*,*, GLenum,*,* +Texture,*,*, GLuint,*,* +TextureComponentCount,*,*, GLint,*,* +TextureCoordName,*,*, GLenum,*,* +TextureEnvParameter,*,*, GLenum,*,* +TextureEnvTarget,*,*, GLenum,*,* +TextureFilterSGIS,*,*, GLenum,*,* +TextureGenParameter,*,*, GLenum,*,* +TextureNormalModeEXT,*,*, GLenum,*,* +TextureParameterName,*,*, GLenum,*,* +TextureTarget,*,*, GLenum,*,* +TextureUnit,*,*, GLenum,*,* +UInt16,*,*, GLushort,*,* +UInt32,*,*, GLuint,*,* +UInt8,*,*, GLubyte,*,* +VertexAttribEnum,*,*, GLenum,*,* +VertexAttribEnumNV,*,*, GLenum,*,* +VertexAttribPointerTypeNV,*,*, GLenum,*,* +VertexPointerType,*,*, GLenum,*,* +VertexWeightPointerTypeEXT,*,*, GLenum,*,* +Void,*,*, GLvoid,*,* +VoidPointer,*,*, GLvoid*,*,* +ConstVoidPointer,*,*, GLvoid* const,*,* +WeightPointerTypeARB,*,*, GLenum,*,* +WinCoord,*,*, GLint,*,* +void,*,*, *,*,* +ArrayObjectPNameATI,*,*, GLenum,*,* +ArrayObjectUsageATI,*,*, GLenum,*,*, +ConstFloat32,*,*, GLfloat,*,* +ConstInt32,*,*, GLint,*,* +ConstUInt32,*,*, GLuint,*,* +ConstVoid,*,*, GLvoid,*,* +DataTypeEXT,*,*, GLenum,*,* +FragmentOpATI,*,*, GLenum,*,* +GetTexBumpParameterATI,*,*, GLenum,*,* +GetVariantValueEXT,*,*, GLenum,*,* +ParameterRangeEXT,*,*, GLenum,*,* +PreserveModeATI,*,*, GLenum,*,* +ProgramFormatARB,*,*, GLenum,*,* +ProgramTargetARB,*,*, GLenum,*,* +ProgramTarget,*,*, GLenum,*,* +ProgramPropertyARB,*,*, GLenum,*,* +ProgramStringPropertyARB,*,*, GLenum,*,* +ScalarType,*,*, GLenum,*,* +SwizzleOpATI,*,*, GLenum,*,* +TexBumpParameterATI,*,*, GLenum,*,* +VariantCapEXT,*,*, GLenum,*,* +VertexAttribPointerPropertyARB,*,*, GLenum,*,* +VertexAttribPointerTypeARB,*,*, GLenum,*,* +VertexAttribPropertyARB,*,*, GLenum,*,* +VertexShaderCoordOutEXT,*,*, GLenum,*,* +VertexShaderOpEXT,*,*, GLenum,*,* +VertexShaderParameterEXT,*,*, GLenum,*,* +VertexShaderStorageTypeEXT,*,*, GLenum,*,* +VertexShaderTextureUnitParameter,*,*, GLenum,*,* +VertexShaderWriteMaskEXT,*,*, GLenum,*,* +VertexStreamATI,*,*, GLenum,*,* +PNTrianglesPNameATI,*,*, GLenum,*,* +# ARB_vertex_buffer_object types and core equivalents for new types +BufferOffset,*,*, GLintptr,*,* +BufferSize,*,*, GLsizeiptr,*,* +BufferAccessARB,*,*, GLenum,*,* +BufferOffsetARB,*,*, GLintptrARB,*,* +BufferPNameARB,*,*, GLenum,*,* +BufferPointerNameARB,*,*, GLenum,*,* +BufferSizeARB,*,*, GLsizeiptrARB,*,* +BufferTargetARB,*,*, GLenum,*,* +BufferUsageARB,*,*, GLenum,*,* +# APPLE_fence +ObjectTypeAPPLE,*,*, GLenum,*,* +# APPLE_vertex_array_range +VertexArrayPNameAPPLE,*,*, GLenum,*,* +# ATI_draw_buffers +DrawBufferModeATI,*,*, GLenum,*,* +# NV_half +Half16NV,*,*, GLhalfNV,*,* +# NV_pixel_data_range +PixelDataRangeTargetNV,*,*, GLenum,*,* +# Generic types for as-yet-unspecified enums +TypeEnum,*,*, GLenum,*,* +GLbitfield,*,*, GLbitfield,*,* +GLenum,*,*, GLenum,*,* +Int64,*,*, GLint64,*,* +UInt64,*,*, GLuint64,*,* +# Object handle & data pointers +handleARB,*,*, GLhandleARB,*,* +charARB,*,*, GLcharARB,*,* +charPointerARB,*,*, GLcharARB*,*,* +sync,*,*, GLsync,*,*, +# EXT_timer_query +Int64EXT,*,*, GLint64EXT,*,* +UInt64EXT,*,*, GLuint64EXT,*,* +# EXT_direct_state_access +FramebufferAttachment,*,*, GLenum,*,* +FramebufferAttachmentParameterName,*,*, GLenum,*,* +Framebuffer,*,*, GLuint,*,* +FramebufferStatus,*,*, GLenum,*,* +FramebufferTarget,*,*, GLenum,*,* +GetFramebufferParameter,*,*, GLenum,*,* +Intptr,*,*, GLintptr,*,* +ProgramFormat,*,*, GLenum,*,* +ProgramProperty,*,*, GLenum,*,* +ProgramStringProperty,*,*, GLenum,*,* +ProgramTarget,*,*, GLenum,*,* +Renderbuffer,*,*, GLuint,*,* +RenderbufferParameterName,*,*, GLenum,*,* +Sizeiptr,*,*, GLsizeiptr,*,* +TextureInternalFormat,*,*, GLenum,*,* +VertexBufferObjectAccess,*,*, GLenum,*,* +VertexBufferObjectParameter,*,*, GLenum,*,* +VertexBufferObjectUsage,*,*, GLenum,*,* +# ARB_map_buffer_range +BufferAccessMask,*,*, GLbitfield,*,* +# NV_explicit_multisample +GetMultisamplePNameNV,*,*, GLenum,*,* +SampleMaskNV,*,*, GLbitfield,*,* diff --git a/xorg-server/hw/xwin/glx/glwindows.h b/xorg-server/hw/xwin/glx/glwindows.h index cc3f2e6ee..72278df30 100644 --- a/xorg-server/hw/xwin/glx/glwindows.h +++ b/xorg-server/hw/xwin/glx/glwindows.h @@ -49,9 +49,15 @@ const GLubyte* glGetStringWrapperNonstatic(GLenum name); void glAddSwapHintRectWINWrapperNonstatic(GLint x, GLint y, GLsizei width, GLsizei height); void glWinSetupDispatchTable(void); -#if 1 +#ifdef _DEBUG +#ifdef _MSC_VER +#define GLWIN_TRACE_MSG(msg, ...) if (glxWinDebugSettings.enableTrace) ErrorF(msg " [%s:%d]\n" , __VA_ARGS__ , __FUNCTION__, __LINE__ ) +#define GLWIN_DEBUG_MSG(msg, ...) if (glxWinDebugSettings.enableDebug) ErrorF(msg " [%s:%d]\n" , __VA_ARGS__ , __FUNCTION__, __LINE__ ) +#else #define GLWIN_TRACE_MSG(msg, args...) if (glxWinDebugSettings.enableTrace) ErrorF(msg " [%s:%d]\n" , ##args , __FUNCTION__, __LINE__ ) #define GLWIN_DEBUG_MSG(msg, args...) if (glxWinDebugSettings.enableDebug) ErrorF(msg " [%s:%d]\n" , ##args , __FUNCTION__, __LINE__ ) +#endif + #else #define GLWIN_TRACE_MSG(a, ...) #define GLWIN_DEBUG_MSG(a, ...) diff --git a/xorg-server/hw/xwin/glx/glwrap.c b/xorg-server/hw/xwin/glx/glwrap.c index fdb2c4aa6..75065726f 100644 --- a/xorg-server/hw/xwin/glx/glwrap.c +++ b/xorg-server/hw/xwin/glx/glwrap.c @@ -44,7 +44,9 @@ #include <glx/glapi.h> #include <glx/dispatch.h> #include <glwindows.h> +#include <winmsg.h> +#ifdef _DEBUG static unsigned int glWinIndirectProcCalls = 0; static unsigned int glWinDirectProcCalls = 0; @@ -66,6 +68,7 @@ glWinCallDelta(void) glWinIndirectProcCallsLast = glWinIndirectProcCalls; } } +#endif static PROC glWinResolveHelper(PROC *cache, char *symbol) @@ -78,12 +81,12 @@ glWinResolveHelper(PROC *cache, char *symbol) proc = wglGetProcAddress(symbol); if (proc == NULL) { - ErrorF("glwrap: Can't resolve \"%s\"\n", symbol); + winDebug("glwrap: Can't resolve \"%s\"\n", symbol); (*cache) = (PROC)-1; } else { - ErrorF("glwrap: Resolved \"%s\"\n", symbol); + winDebug("glwrap: Resolved \"%s\"\n", symbol); (*cache) = proc; } } @@ -101,14 +104,20 @@ glWinResolveHelper(PROC *cache, char *symbol) return proc; } +#ifdef _DEBUG +#define INCPROCCALLS glWinIndirectProcCalls++; +#else +#define INCPROCCALLS +#endif + #define RESOLVE_RET(proctype, symbol, retval) \ static PROC cache = NULL; \ - __stdcall proctype proc = (proctype)glWinResolveHelper(&cache, symbol); \ + proctype proc = (proctype)glWinResolveHelper(&cache, symbol); \ if (proc == NULL) { \ __glXErrorCallBack(0); \ return retval; \ } \ - glWinIndirectProcCalls++; + INCPROCCALLS #define RESOLVE(proctype, symbol) RESOLVE_RET(proctype, symbol,) diff --git a/xorg-server/hw/xwin/glx/indirect.c b/xorg-server/hw/xwin/glx/indirect.c index ba995c007..70b257c12 100644 --- a/xorg-server/hw/xwin/glx/indirect.c +++ b/xorg-server/hw/xwin/glx/indirect.c @@ -1,2213 +1,2394 @@ -/* - * File: indirect.c - * Purpose: A GLX implementation that uses Windows OpenGL library - * - * Authors: Alexander Gottwald - * Jon TURNEY - * - * Copyright (c) Jon TURNEY 2009 - * Copyright (c) Alexander Gottwald 2004 - * - * Portions of this file are copied from GL/apple/indirect.c, - * which contains the following copyright: - * - * Copyright (c) 2007, 2008, 2009 Apple Inc. - * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved. - * Copyright (c) 2002 Greg Parker. All Rights Reserved. - * - * Portions of this file are copied from Mesa's xf86glx.c, - * which contains the following copyright: - * - * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. - * 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 ABOVE LISTED COPYRIGHT HOLDER(S) 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. - */ - -/* - TODO: - - hook up remaining unimplemented extensions - - research what guarantees glXWaitX, glXWaitGL are supposed to offer, and implement then - using GdiFlush and/or glFinish - - pbuffer clobbering: we don't get async notification, but can we arrange to emit the - event when we notice it's been clobbered? at the very least, check if it's been clobbered - before using it? - - are the __GLXConfig * we get handed back ones we are made (so we can extend the structure - with privates?) Or are they created inside the GLX core as well? -*/ - -/* - MSDN clarifications: - - It says SetPixelFormat()'s PIXELFORMATDESCRIPTOR pointer argument has no effect - except on metafiles, this seems to mean that as it's ok to supply NULL if the DC - is not for a metafile - - wglMakeCurrent ignores the hdc if hglrc is NULL, so wglMakeCurrent(NULL, NULL) - is used to make no context current - -*/ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif - -#include "glwindows.h" -#include <glx/glxserver.h> -#include <glx/glxutil.h> -#include <glx/extension_string.h> -#include <GL/internal/glcore.h> -#include <GL/glxtokens.h> - -#include <winpriv.h> -#include <wgl_ext_api.h> - -#define NUM_ELEMENTS(x) (sizeof(x)/ sizeof(x[1])) - -/* ---------------------------------------------------------------------- */ -/* - * structure definitions - */ - -typedef struct __GLXWinContext __GLXWinContext; -typedef struct __GLXWinDrawable __GLXWinDrawable; -typedef struct __GLXWinScreen glxWinScreen; -typedef struct __GLXWinConfig GLXWinConfig; - -struct __GLXWinContext { - __GLXcontext base; - HGLRC ctx; /* Windows GL Context */ - __GLXWinContext *shareContext; /* Context with which we will share display lists and textures */ - HWND hwnd; /* For detecting when HWND has changed */ -}; - -struct __GLXWinDrawable -{ - __GLXdrawable base; - __GLXWinContext *drawContext; - __GLXWinContext *readContext; - - /* If this drawable is GLX_DRAWABLE_PBUFFER */ - HPBUFFERARB hPbuffer; - - /* If this drawable is GLX_DRAWABLE_PIXMAP */ - HDC dibDC; - HBITMAP hDIB; - HBITMAP hOldDIB; /* original DIB for DC */ - void *pOldBits; /* original pBits for this drawable's pixmap */ -}; - -struct __GLXWinScreen -{ - __GLXscreen base; - - /* Supported GLX extensions */ - unsigned char glx_enable_bits[__GLX_EXT_BYTES]; - - Bool has_WGL_ARB_multisample; - Bool has_WGL_ARB_pixel_format; - Bool has_WGL_ARB_pbuffer; - Bool has_WGL_ARB_render_texture; - - /* wrapped screen functions */ - RealizeWindowProcPtr RealizeWindow; - UnrealizeWindowProcPtr UnrealizeWindow; - CopyWindowProcPtr CopyWindow; -}; - -struct __GLXWinConfig -{ - __GLXconfig base; - int pixelFormatIndex; -}; - -/* ---------------------------------------------------------------------- */ -/* - * Various debug helpers - */ - -#define GLWIN_DEBUG_HWND(hwnd) \ - if (glxWinDebugSettings.dumpHWND) { \ - char buffer[1024]; \ - if (GetWindowText(hwnd, buffer, sizeof(buffer))==0) *buffer=0; \ - GLWIN_DEBUG_MSG("Got HWND %p for window '%s'", hwnd, buffer); \ - } - -glxWinDebugSettingsRec glxWinDebugSettings = { 0, 0, 0, 0, 0, 0}; - -static void glxWinInitDebugSettings(void) -{ - char *envptr; - - envptr = getenv("GLWIN_ENABLE_DEBUG"); - if (envptr != NULL) - glxWinDebugSettings.enableDebug = (atoi(envptr) == 1); - - envptr = getenv("GLWIN_ENABLE_TRACE"); - if (envptr != NULL) - glxWinDebugSettings.enableTrace = (atoi(envptr) == 1); - - envptr = getenv("GLWIN_DUMP_PFD"); - if (envptr != NULL) - glxWinDebugSettings.dumpPFD = (atoi(envptr) == 1); - - envptr = getenv("GLWIN_DUMP_HWND"); - if (envptr != NULL) - glxWinDebugSettings.dumpHWND = (atoi(envptr) == 1); - - envptr = getenv("GLWIN_DUMP_DC"); - if (envptr != NULL) - glxWinDebugSettings.dumpDC = (atoi(envptr) == 1); - - envptr = getenv("GLWIN_ENABLE_GLCALL_TRACE"); - if (envptr != NULL) - glxWinDebugSettings.enableGLcallTrace = (atoi(envptr) == 1); - - envptr = getenv("GLWIN_ENABLE_WGLCALL_TRACE"); - if (envptr != NULL) - glxWinDebugSettings.enableWGLcallTrace = (atoi(envptr) == 1); - - envptr = getenv("GLWIN_DEBUG_ALL"); - if (envptr != NULL) - { - glxWinDebugSettings.enableDebug = 1; - glxWinDebugSettings.enableTrace = 1; - glxWinDebugSettings.dumpPFD = 1; - glxWinDebugSettings.dumpHWND = 1; - glxWinDebugSettings.dumpDC = 1; - glxWinDebugSettings.enableGLcallTrace = 1; - glxWinDebugSettings.enableWGLcallTrace = 1; - } -} - -static -const char *glxWinErrorMessage(void) -{ - static char errorbuffer[1024]; - - if (!FormatMessage( - FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError(), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &errorbuffer, - sizeof(errorbuffer), - NULL )) - { - snprintf(errorbuffer, sizeof(errorbuffer), "Unknown error in FormatMessage: %08x!", (unsigned)GetLastError()); - } - - if (errorbuffer[strlen(errorbuffer)-1] == '\n') - errorbuffer[strlen(errorbuffer)-1] = 0; - - return errorbuffer; -} - -static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd); - -#define DUMP_PFD_FLAG(flag) \ - if (pfd->dwFlags & flag) { \ - ErrorF("%s%s", pipesym, #flag); \ - pipesym = " | "; \ - } - -static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd) -{ - const char *pipesym = ""; /* will be set after first flag dump */ - ErrorF("PIXELFORMATDESCRIPTOR:\n"); - ErrorF("nSize = %u\n", pfd->nSize); - ErrorF("nVersion = %u\n", pfd->nVersion); - ErrorF("dwFlags = %lu = {", pfd->dwFlags); - DUMP_PFD_FLAG(PFD_DOUBLEBUFFER); - DUMP_PFD_FLAG(PFD_STEREO); - DUMP_PFD_FLAG(PFD_DRAW_TO_WINDOW); - DUMP_PFD_FLAG(PFD_DRAW_TO_BITMAP); - DUMP_PFD_FLAG(PFD_SUPPORT_GDI); - DUMP_PFD_FLAG(PFD_SUPPORT_OPENGL); - DUMP_PFD_FLAG(PFD_GENERIC_FORMAT); - DUMP_PFD_FLAG(PFD_NEED_PALETTE); - DUMP_PFD_FLAG(PFD_NEED_SYSTEM_PALETTE); - DUMP_PFD_FLAG(PFD_SWAP_EXCHANGE); - DUMP_PFD_FLAG(PFD_SWAP_COPY); - DUMP_PFD_FLAG(PFD_SWAP_LAYER_BUFFERS); - DUMP_PFD_FLAG(PFD_GENERIC_ACCELERATED); - DUMP_PFD_FLAG(PFD_DEPTH_DONTCARE); - DUMP_PFD_FLAG(PFD_DOUBLEBUFFER_DONTCARE); - DUMP_PFD_FLAG(PFD_STEREO_DONTCARE); - ErrorF("}\n"); - - ErrorF("iPixelType = %hu = %s\n", pfd->iPixelType, - (pfd->iPixelType == PFD_TYPE_RGBA ? "PFD_TYPE_RGBA" : "PFD_TYPE_COLORINDEX")); - ErrorF("cColorBits = %hhu\n", pfd->cColorBits); - ErrorF("cRedBits = %hhu\n", pfd->cRedBits); - ErrorF("cRedShift = %hhu\n", pfd->cRedShift); - ErrorF("cGreenBits = %hhu\n", pfd->cGreenBits); - ErrorF("cGreenShift = %hhu\n", pfd->cGreenShift); - ErrorF("cBlueBits = %hhu\n", pfd->cBlueBits); - ErrorF("cBlueShift = %hhu\n", pfd->cBlueShift); - ErrorF("cAlphaBits = %hhu\n", pfd->cAlphaBits); - ErrorF("cAlphaShift = %hhu\n", pfd->cAlphaShift); - ErrorF("cAccumBits = %hhu\n", pfd->cAccumBits); - ErrorF("cAccumRedBits = %hhu\n", pfd->cAccumRedBits); - ErrorF("cAccumGreenBits = %hhu\n", pfd->cAccumGreenBits); - ErrorF("cAccumBlueBits = %hhu\n", pfd->cAccumBlueBits); - ErrorF("cAccumAlphaBits = %hhu\n", pfd->cAccumAlphaBits); - ErrorF("cDepthBits = %hhu\n", pfd->cDepthBits); - ErrorF("cStencilBits = %hhu\n", pfd->cStencilBits); - ErrorF("cAuxBuffers = %hhu\n", pfd->cAuxBuffers); - ErrorF("iLayerType = %hhu\n", pfd->iLayerType); - ErrorF("bReserved = %hhu\n", pfd->bReserved); - ErrorF("dwLayerMask = %lu\n", pfd->dwLayerMask); - ErrorF("dwVisibleMask = %lu\n", pfd->dwVisibleMask); - ErrorF("dwDamageMask = %lu\n", pfd->dwDamageMask); - ErrorF("\n"); -} - -static const char * -visual_class_name(int cls) -{ - switch (cls) { - case GLX_STATIC_COLOR: - return "StaticColor"; - case GLX_PSEUDO_COLOR: - return "PseudoColor"; - case GLX_STATIC_GRAY: - return "StaticGray"; - case GLX_GRAY_SCALE: - return "GrayScale"; - case GLX_TRUE_COLOR: - return "TrueColor"; - case GLX_DIRECT_COLOR: - return "DirectColor"; - default: - return "-none-"; - } -} - -static const char * -swap_method_name(int mthd) -{ - switch (mthd) - { - case GLX_SWAP_EXCHANGE_OML: - return "xchg"; - case GLX_SWAP_COPY_OML: - return "copy"; - case GLX_SWAP_UNDEFINED_OML: - return " "; - default: - return "????"; - } -} - -static void -fbConfigsDump(unsigned int n, __GLXconfig *c) -{ - ErrorF("%d fbConfigs\n", n); - ErrorF("pxf vis fb render Ste aux accum MS drawable Group/\n"); - ErrorF("idx ID ID VisualType Depth Lvl RGB CI DB Swap reo R G B A Z S buf AR AG AB AA bufs num W P Pb Float Trans Caveat\n"); - ErrorF("-----------------------------------------------------------------------------------------------------------------------------\n"); - - while (c != NULL) - { - unsigned int i = ((GLXWinConfig *)c)->pixelFormatIndex; - - ErrorF("%3d %2x %2x " - "%-11s" - " %3d %3d %s %s %s %s %s " - "%2d %2d %2d %2d " - "%2d %2d " - "%2d " - "%2d %2d %2d %2d" - " %2d %2d" - " %s %s %s " - " %s " - " %s " - " %d %s" - "\n", - i, c->visualID, c->fbconfigID, - visual_class_name(c->visualType), - c->rgbBits ? c->rgbBits : c->indexBits, - c->level, - (c->renderType & GLX_RGBA_BIT) ? "y" : ".", - (c->renderType & GLX_COLOR_INDEX_BIT) ? "y" : ".", - c->doubleBufferMode ? "y" : ".", - swap_method_name(c->swapMethod), - c->stereoMode ? "y" : ".", - c->redBits, c->greenBits, c->blueBits, c->alphaBits, - c->depthBits, c->stencilBits, - c->numAuxBuffers, - c->accumRedBits, c->accumGreenBits, c->accumBlueBits, c->accumAlphaBits, - c->sampleBuffers, c->samples, - (c->drawableType & GLX_WINDOW_BIT) ? "y" : ".", - (c->drawableType & GLX_PIXMAP_BIT) ? "y" : ".", - (c->drawableType & GLX_PBUFFER_BIT) ? "y" : ".", - ".", - (c->transparentPixel != GLX_NONE_EXT) ? "y" : ".", - c->visualSelectGroup, (c->visualRating == GLX_SLOW_VISUAL_EXT) ? "*" : " "); - - c = c->next; - } -} - -/* ---------------------------------------------------------------------- */ -/* - * Forward declarations - */ - -static __GLXscreen *glxWinScreenProbe(ScreenPtr pScreen); -static __GLXcontext *glxWinCreateContext(__GLXscreen *screen, - __GLXconfig *modes, - __GLXcontext *baseShareContext); -static __GLXdrawable *glxWinCreateDrawable(__GLXscreen *screen, - DrawablePtr pDraw, - int type, - XID drawId, - __GLXconfig *conf); - -static Bool glxWinRealizeWindow(WindowPtr pWin); -static Bool glxWinUnrealizeWindow(WindowPtr pWin); -static void glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc); - -static HDC glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HDC *hdc, HWND *hwnd); -static void glxWinReleaseDC(HWND hwnd, HDC hdc, __GLXWinDrawable *draw); - -static void glxWinCreateConfigs(HDC dc, glxWinScreen *screen); -static void glxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen); -static int fbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int drawableTypeOverride); -static int fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig *mode, int drawableTypeOverride, glxWinScreen *winScreen); - -/* ---------------------------------------------------------------------- */ -/* - * The GLX provider - */ - -__GLXprovider __glXWGLProvider = { - glxWinScreenProbe, - "Win32 native WGL", - NULL -}; - -void -glxWinPushNativeProvider(void) -{ - GlxPushProvider(&__glXWGLProvider); -} - -/* ---------------------------------------------------------------------- */ -/* - * Screen functions - */ - -static void -glxWinScreenDestroy(__GLXscreen *screen) -{ - GLWIN_DEBUG_MSG("glxWinScreenDestroy(%p)", screen); - __glXScreenDestroy(screen); - xfree(screen); -} - -static int -glxWinScreenSwapInterval(__GLXdrawable *drawable, int interval) -{ - BOOL ret = wglSwapIntervalEXTWrapper(interval); - if (!ret) - { - ErrorF("wglSwapIntervalEXT interval %d failed:%s\n", interval, glxWinErrorMessage()); - } - return ret; -} - -/* This is called by GlxExtensionInit() asking the GLX provider if it can handle the screen... */ -static __GLXscreen * -glxWinScreenProbe(ScreenPtr pScreen) -{ - glxWinScreen *screen; - const char *gl_extensions; - const char *wgl_extensions; - HWND hwnd; - HDC hdc; - HGLRC hglrc; - - GLWIN_DEBUG_MSG("glxWinScreenProbe"); - - glxWinInitDebugSettings(); - - if (pScreen == NULL) - return NULL; - - if (!winCheckScreenAiglxIsSupported(pScreen)) - { - LogMessage(X_ERROR,"AIGLX: No native OpenGL in modes with a root window\n"); - return NULL; - } - - screen = xcalloc(1, sizeof(glxWinScreen)); - - if (NULL == screen) - return NULL; - - /* Wrap RealizeWindow, UnrealizeWindow and CopyWindow on this screen */ - screen->RealizeWindow = pScreen->RealizeWindow; - pScreen->RealizeWindow = glxWinRealizeWindow; - screen->UnrealizeWindow = pScreen->UnrealizeWindow; - pScreen->UnrealizeWindow = glxWinUnrealizeWindow; - screen->CopyWindow = pScreen->CopyWindow; - pScreen->CopyWindow = glxWinCopyWindow; - - /* Dump out some useful information about the native renderer */ - - // create window class -#define WIN_GL_TEST_WINDOW_CLASS "XWinGLTest" - { - static wATOM glTestWndClass = 0; - if (glTestWndClass == 0) - { - WNDCLASSEX wc; - wc.cbSize = sizeof(WNDCLASSEX); - wc.style = CS_HREDRAW | CS_VREDRAW; - wc.lpfnWndProc = DefWindowProc; - wc.cbClsExtra = 0; - wc.cbWndExtra = 0; - wc.hInstance = GetModuleHandle(NULL); - wc.hIcon = 0; - wc.hCursor = 0; - wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); - wc.lpszMenuName = NULL; - wc.lpszClassName = WIN_GL_TEST_WINDOW_CLASS; - wc.hIconSm = 0; - RegisterClassEx (&wc); - } - } - - // create an invisible window for a scratch DC - hwnd = CreateWindowExA(0, - WIN_GL_TEST_WINDOW_CLASS, - "XWin GL Renderer Capabilities Test Window", - 0, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL); - if (hwnd == NULL) - LogMessage(X_ERROR,"AIGLX: Couldn't create a window for render capabilities testing\n"); - - hdc = GetDC(hwnd); - - // we must set a pixel format before we can create a context, just use the first one... - SetPixelFormat(hdc, 1, NULL); - hglrc = wglCreateContext(hdc); - wglMakeCurrent(hdc, hglrc); - - // initialize wgl extension proc pointers (don't call them before here...) - // (but we need to have a current context for them to be resolvable) - wglResolveExtensionProcs(); - - ErrorF("GL_VERSION: %s\n", glGetStringWrapperNonstatic(GL_VERSION)); - ErrorF("GL_VENDOR: %s\n", glGetStringWrapperNonstatic(GL_VENDOR)); - ErrorF("GL_RENDERER: %s\n", glGetStringWrapperNonstatic(GL_RENDERER)); - gl_extensions = (const char *)glGetStringWrapperNonstatic(GL_EXTENSIONS); - ErrorF("GL_EXTENSIONS: %s\n", gl_extensions); - wgl_extensions = wglGetExtensionsStringARBWrapper(hdc); - ErrorF("WGL_EXTENSIONS:%s\n", wgl_extensions); - - // Can you see the problem here? The extensions string is DC specific - // Different DCs for windows on a multimonitor system driven by multiple cards - // might have completely different capabilities. Of course, good luck getting - // those screens to be accelerated in XP and earlier... - - { - // testing facility to not use any WGL extensions - char *envptr = getenv("GLWIN_NO_WGL_EXTENSIONS"); - if ((envptr != NULL) && (atoi(envptr) != 0)) - { - ErrorF("GLWIN_NO_WGL_EXTENSIONS is set, ignoring WGL_EXTENSIONS\n"); - wgl_extensions = ""; - } - } - - { - Bool glx_sgi_make_current_read = FALSE; - - // - // Based on the WGL extensions available, enable various GLX extensions - // XXX: make this table-driven ? - // - memset(screen->glx_enable_bits, 0, __GLX_EXT_BYTES); - - __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_info"); - __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_rating"); - __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_import_context"); - __glXEnableExtension(screen->glx_enable_bits, "GLX_OML_swap_method"); - __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_fbconfig"); - - if (strstr(wgl_extensions, "WGL_ARB_make_current_read")) - { - __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_make_current_read"); - LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n"); - glx_sgi_make_current_read = TRUE; - } - - if (strstr(gl_extensions, "GL_WIN_swap_hint")) - { - __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer"); - LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n"); - } - - if (strstr(wgl_extensions, "WGL_EXT_swap_control")) - { - __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_swap_control"); - __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_swap_control"); - LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n"); - } - -/* // Hmm? screen->texOffset */ -/* if (strstr(wgl_extensions, "WGL_ARB_render_texture")) */ -/* { */ -/* __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_texture_from_pixmap"); */ -/* LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n"); */ -/* screen->has_WGL_ARB_render_texture = TRUE; */ -/* } */ - - if (strstr(wgl_extensions, "WGL_ARB_pbuffer")) - { - __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_pbuffer"); - LogMessage(X_INFO, "AIGLX: enabled GLX_SGIX_pbuffer\n"); - screen->has_WGL_ARB_pbuffer = TRUE; - } - - if (strstr(wgl_extensions, "WGL_ARB_multisample")) - { - __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_multisample"); - __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIS_multisample"); - LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_multisample and GLX_SGIS_multisample\n"); - screen->has_WGL_ARB_multisample = TRUE; - } - - screen->base.destroy = glxWinScreenDestroy; - screen->base.createContext = glxWinCreateContext; - screen->base.createDrawable = glxWinCreateDrawable; - screen->base.swapInterval = glxWinScreenSwapInterval; - screen->base.hyperpipeFuncs = NULL; - screen->base.swapBarrierFuncs = NULL; - screen->base.pScreen = pScreen; - - if (strstr(wgl_extensions, "WGL_ARB_pixel_format")) - { - glxWinCreateConfigsExt(hdc, screen); - screen->has_WGL_ARB_pixel_format = TRUE; - } - else - { - glxWinCreateConfigs(hdc, screen); - screen->has_WGL_ARB_pixel_format = FALSE; - } - // Initializes screen->base.fbconfigs and screen->base.numFBConfigs - - /* These will be set by __glXScreenInit */ - screen->base.visuals = NULL; - screen->base.numVisuals = 0; - - __glXScreenInit(&screen->base, pScreen); - - // dump out fbConfigs now fbConfigIds and visualIDs have been assigned - fbConfigsDump(screen->base.numFBConfigs, screen->base.fbconfigs); - - // Override the GL extensions string set by __glXScreenInit() - screen->base.GLextensions = xstrdup(gl_extensions); - - // Generate the GLX extensions string (overrides that set by __glXScreenInit()) - { - unsigned int buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL); - if (buffer_size > 0) - { - if (screen->base.GLXextensions != NULL) - { - xfree(screen->base.GLXextensions); - } - - screen->base.GLXextensions = xnfalloc(buffer_size); - __glXGetExtensionString(screen->glx_enable_bits, screen->base.GLXextensions); - } - } - - // - // Override the GLX version (__glXScreenInit() sets it to "1.2") - // if we have all the needed extensionsto operate as a higher version - // - // SGIX_fbconfig && SGIX_pbuffer && SGI_make_current_read -> 1.3 - // ARB_multisample -> 1.4 - // - if (screen->has_WGL_ARB_pbuffer && glx_sgi_make_current_read) - { - xfree(screen->base.GLXversion); - - if (screen->has_WGL_ARB_multisample) - { - screen->base.GLXversion = xstrdup("1.4"); - /* - XXX: this just controls the version string returned to glXQueryServerString() - there is currently no way to control the version number the server returns to - glXQueryVersion()... - */ - } - else - { - screen->base.GLXversion = xstrdup("1.3"); - } - LogMessage(X_INFO, "AIGLX: Set GLX version to %s\n", screen->base.GLXversion); - } - } - - wglMakeCurrent(NULL, NULL); - wglDeleteContext(hglrc); - ReleaseDC(hwnd, hdc); - DestroyWindow(hwnd); - - return &screen->base; -} - -/* ---------------------------------------------------------------------- */ -/* - * Window functions - */ - -static Bool -glxWinRealizeWindow(WindowPtr pWin) -{ - Bool result; - ScreenPtr pScreen = pWin->drawable.pScreen; - glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen); - - GLWIN_DEBUG_MSG("glxWinRealizeWindow"); - - /* Allow the window to be created (RootlessRealizeWindow is inside our wrap) */ - pScreen->RealizeWindow = screenPriv->RealizeWindow; - result = pScreen->RealizeWindow(pWin); - pScreen->RealizeWindow = glxWinRealizeWindow; - - return result; -} - - -static void -glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) -{ - __GLXWinDrawable *pGlxDraw; - ScreenPtr pScreen = pWindow->drawable.pScreen; - glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen); - - GLWIN_TRACE_MSG("glxWinCopyWindow pWindow %p", pWindow); - - dixLookupResourceByType((pointer) &pGlxDraw, pWindow->drawable.id, __glXDrawableRes, - NullClient, DixUnknownAccess); - - - /* - Discard any CopyWindow requests if a GL drawing context is pointing at the window - - For regions which are being drawn by GL, the shadow framebuffer doesn't have the - correct bits, so we wish to avoid shadow framebuffer damage occuring, which will - cause those incorrect bits to be transferred to the display.... - */ - if (pGlxDraw && pGlxDraw->drawContext) - { - GLWIN_DEBUG_MSG("glxWinCopyWindow: discarding"); - return; - } - - GLWIN_DEBUG_MSG("glxWinCopyWindow - passing to hw layer"); - - pScreen->CopyWindow = screenPriv->CopyWindow; - pScreen->CopyWindow(pWindow, ptOldOrg, prgnSrc); - pScreen->CopyWindow = glxWinCopyWindow; -} - -static Bool -glxWinUnrealizeWindow(WindowPtr pWin) -{ - Bool result; - ScreenPtr pScreen = pWin->drawable.pScreen; - glxWinScreen *screenPriv = (glxWinScreen *)glxGetScreen(pScreen); - - GLWIN_DEBUG_MSG("glxWinUnrealizeWindow"); - - pScreen->UnrealizeWindow = screenPriv->UnrealizeWindow; - result = pScreen->UnrealizeWindow(pWin); - pScreen->UnrealizeWindow = glxWinUnrealizeWindow; - - return result; -} - -/* ---------------------------------------------------------------------- */ -/* - * Drawable functions - */ - -static GLboolean -glxWinDrawableSwapBuffers(__GLXdrawable *base) -{ - HDC dc; - HWND hwnd; - BOOL ret; - __GLXWinDrawable *draw = (__GLXWinDrawable *)base; - - /* Swap buffers on the last active context for drawing on the drawable */ - if (draw->drawContext == NULL) - { - GLWIN_TRACE_MSG("glxWinSwapBuffers - no context for drawable"); - return GL_FALSE; - } - - GLWIN_TRACE_MSG("glxWinSwapBuffers on drawable %p, last context %p (native ctx %p)", base, draw->drawContext, draw->drawContext->ctx); - - /* - draw->drawContext->base.drawPriv will not be set if the context is not current anymore, - but if it is, it should point to this drawable.... - */ - assert((draw->drawContext->base.drawPriv == NULL) || (draw->drawContext->base.drawPriv == base)); - - dc = glxWinMakeDC(draw->drawContext, draw, &dc, &hwnd); - if (dc == NULL) - return GL_FALSE; - - ret = wglSwapLayerBuffers(dc, WGL_SWAP_MAIN_PLANE); - - glxWinReleaseDC(hwnd, dc, draw); - - if (!ret) - { - ErrorF("wglSwapBuffers failed: %s\n", glxWinErrorMessage()); - return GL_FALSE; - } - - return GL_TRUE; -} - -static void -glxWinDrawableCopySubBuffer(__GLXdrawable *drawable, - int x, int y, int w, int h) -{ - glAddSwapHintRectWINWrapperNonstatic(x, y, w, h); - glxWinDrawableSwapBuffers(drawable); -} - -static void -glxWinDrawableDestroy(__GLXdrawable *base) -{ - __GLXWinDrawable *glxPriv = (__GLXWinDrawable *)base; - - if (glxPriv->drawContext && (__glXLastContext == &((glxPriv->drawContext)->base))) - { - // if this context is current and has unflushed commands, say we have flushed them - // (don't actually flush them, the window is going away anyhow, and an implict flush occurs - // on the next context change) - // (GLX core considers it an error when we try to select a new current context if the old one - // has unflushed commands, but the window has disappeared..) - __GLX_NOTE_FLUSHED_CMDS(__glXLastContext); - __glXLastContext = NULL; - } - - if (glxPriv->hPbuffer) - if (!wglDestroyPbufferARBWrapper(glxPriv->hPbuffer)) - { - ErrorF("wglDestroyPbufferARB failed: %s\n", glxWinErrorMessage()); - } - - if (glxPriv->dibDC) - { - // restore the default DIB - SelectObject(glxPriv->dibDC, glxPriv->hOldDIB); - - if (!DeleteDC(glxPriv->dibDC)) - { - ErrorF("DeleteDC failed: %s\n", glxWinErrorMessage()); - } - } - - if (glxPriv->hDIB) - { - if (!DeleteObject(glxPriv->hDIB)) - { - ErrorF("DeleteObject failed: %s\n", glxWinErrorMessage()); - } - - ((PixmapPtr)glxPriv->base.pDraw)->devPrivate.ptr = glxPriv->pOldBits; - } - - GLWIN_DEBUG_MSG("glxWinDestroyDrawable"); - xfree(glxPriv); -} - -static __GLXdrawable * -glxWinCreateDrawable(__GLXscreen *screen, - DrawablePtr pDraw, - int type, - XID drawId, - __GLXconfig *conf) -{ - __GLXWinDrawable *glxPriv; - - glxPriv = xalloc(sizeof *glxPriv); - - if (glxPriv == NULL) - return NULL; - - memset(glxPriv, 0, sizeof *glxPriv); - - if(!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, drawId, conf)) { - xfree(glxPriv); - return NULL; - } - - glxPriv->base.destroy = glxWinDrawableDestroy; - glxPriv->base.swapBuffers = glxWinDrawableSwapBuffers; - glxPriv->base.copySubBuffer = glxWinDrawableCopySubBuffer; - // glxPriv->base.waitX what are these for? - // glxPriv->base.waitGL - - GLWIN_DEBUG_MSG("glxWinCreateDrawable %p", glxPriv); - - return &glxPriv->base; -} - -/* ---------------------------------------------------------------------- */ -/* - * Texture functions - */ - -static -int glxWinBindTexImage(__GLXcontext *baseContext, - int buffer, - __GLXdrawable *pixmap) -{ - ErrorF("glxWinBindTexImage: not implemented\n"); - return FALSE; -} - -static -int glxWinReleaseTexImage(__GLXcontext *baseContext, - int buffer, - __GLXdrawable *pixmap) -{ - ErrorF(" glxWinReleaseTexImage: not implemented\n"); - return FALSE; -} - -/* ---------------------------------------------------------------------- */ -/* - * Lazy update context implementation - * - * WGL contexts are created for a specific HDC, so we cannot create the WGL - * context in glxWinCreateContext(), we must defer creation until the context - * is actually used on a specifc drawable which is connected to a native window, - * pbuffer or DIB - * - * The WGL context may be used on other, compatible HDCs, so we don't need to - * recreate it for every new native window - * - * XXX: I wonder why we can't create the WGL context on the screen HDC ? - * Basically we assume all HDCs are compatible at the moment: if they are not - * we are in a muddle, there was some code in the old implementation to attempt - * to transparently migrate a context to a new DC by copying state and sharing - * lists with the old one... - */ - -static void -glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawableTypeOverride) -{ - __GLXscreen *screen = gc->base.pGlxScreen; - glxWinScreen *winScreen = (glxWinScreen *)screen; - - __GLXconfig *config = gc->base.config; - GLXWinConfig *winConfig = (GLXWinConfig *)config; - - GLWIN_DEBUG_MSG("glxWinSetPixelFormat: pixelFormatIndex %d", winConfig->pixelFormatIndex); - - /* - Normally, we can just use the the pixelFormatIndex corresponding - to the fbconfig which has been specified by the client - */ - - if (!((bppOverride && (bppOverride != (config->redBits + config->greenBits + config->blueBits) )) - || ((config->drawableType & drawableTypeOverride) == 0))) - { - if (!SetPixelFormat(hdc, winConfig->pixelFormatIndex, NULL)) - { - ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); - return; - } - - return; - } - - /* - However, in certain special cases this pixel format will be incompatible with the - use we are going to put it to, so we need to re-evaluate the pixel format to use: - - 1) When PFD_DRAW_TO_BITMAP is set, ChoosePixelFormat() always returns a format with - the cColorBits we asked for, so we need to ensure it matches the bpp of the bitmap - - 2) Applications may assume that visuals selected with glXChooseVisual() work with - pixmap drawables (there is no attribute to explicitly query for pixmap drawable - support as there is for glXChooseFBConfig()) - (it's arguable this is an error in the application, but we try to make it work) - - pixmap rendering is always slow for us, so we don't want to choose those visuals - by default, but if the actual drawable type we're trying to select the context - on (drawableTypeOverride) isn't supported by the selected fbConfig, reconsider - and see if we can find a suitable one... - */ - ErrorF("glxWinSetPixelFormat: having second thoughts: cColorbits %d, bppOveride %d; config->drawableType %d, drawableTypeOverride %d\n", - (config->redBits + config->greenBits + config->blueBits), bppOverride, config->drawableType, drawableTypeOverride); - - if (!winScreen->has_WGL_ARB_pixel_format) - { - PIXELFORMATDESCRIPTOR pfd; - int pixelFormat; - - /* convert fbConfig to PFD */ - if (fbConfigToPixelFormat(gc->base.config, &pfd, drawableTypeOverride)) - { - ErrorF("glxWinSetPixelFormat: fbConfigToPixelFormat failed\n"); - return; - } - - if (glxWinDebugSettings.dumpPFD) - pfdOut(&pfd); - - if (bppOverride) - { - GLWIN_DEBUG_MSG("glxWinSetPixelFormat: Forcing bpp from %d to %d\n", pfd.cColorBits, bppOverride); - pfd.cColorBits = bppOverride; - } - - pixelFormat = ChoosePixelFormat(hdc, &pfd); - if (pixelFormat == 0) - { - ErrorF("ChoosePixelFormat error: %s\n", glxWinErrorMessage()); - return; - } - - GLWIN_DEBUG_MSG("ChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat); - ErrorF("ChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex); - - if (!SetPixelFormat(hdc, pixelFormat, &pfd)) - { - ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); - return; - } - } - else - { - int pixelFormat = fbConfigToPixelFormatIndex(hdc, gc->base.config, drawableTypeOverride, winScreen); - if (pixelFormat == 0) - { - ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage()); - return; - } - - GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat); - ErrorF("wglChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex); - - if (!SetPixelFormat(hdc, pixelFormat, NULL)) - { - ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage()); - return; - } - } -} - -static HDC -glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HDC *hdc, HWND *hwnd) -{ - *hdc = NULL; - *hwnd = NULL; - - if (draw == NULL) - { - GLWIN_TRACE_MSG("No drawable for context %p (native ctx %p)", gc, gc->ctx); - return NULL; - } - - switch (draw->base.type) - { - case GLX_DRAWABLE_WINDOW: - { - winWindowInfoRec winInfo; - WindowPtr pWin; - - pWin = (WindowPtr) draw->base.pDraw; - if (pWin == NULL) - { - GLWIN_TRACE_MSG("for drawable %p, no WindowPtr", pWin); - return NULL; - } - - winGetWindowInfo(pWin, &winInfo); - *hwnd = winInfo.hwnd; - - if (winInfo.hwnd == NULL) - { - ErrorF("No HWND error: %s\n", glxWinErrorMessage()); - return NULL; - } - - *hdc = GetDC(winInfo.hwnd); - - if (*hdc == NULL) - ErrorF("GetDC error: %s\n", glxWinErrorMessage()); - - /* Check if the hwnd has changed... */ - if (winInfo.hwnd != gc->hwnd) - { - if (glxWinDebugSettings.enableTrace) - GLWIN_DEBUG_HWND(winInfo.hwnd); - - GLWIN_TRACE_MSG("for context %p (native ctx %p), hWnd changed from %p to %p", gc, gc->ctx, gc->hwnd, winInfo.hwnd); - gc->hwnd = winInfo.hwnd; - - /* We must select a pixelformat, but SetPixelFormat can only be called once for a window... */ - glxWinSetPixelFormat(gc, *hdc, 0, GLX_WINDOW_BIT); - } - } - break; - - case GLX_DRAWABLE_PBUFFER: - { - *hdc = wglGetPbufferDCARBWrapper(draw->hPbuffer); - - if (*hdc == NULL) - ErrorF("GetDC (pbuffer) error: %s\n", glxWinErrorMessage()); - } - break; - - case GLX_DRAWABLE_PIXMAP: - { - *hdc = draw->dibDC; - } - break; - - default: - { - ErrorF("glxWinMakeDC: tried to makeDC for unhandled drawable type %d\n", draw->base.type); - } - } - - if (glxWinDebugSettings.dumpDC) - GLWIN_DEBUG_MSG("Got HDC %p", *hdc); - - return *hdc; -} - -static void -glxWinReleaseDC(HWND hwnd, HDC hdc,__GLXWinDrawable *draw) -{ - switch (draw->base.type) - { - case GLX_DRAWABLE_WINDOW: - { - ReleaseDC(hwnd, hdc); - } - break; - - case GLX_DRAWABLE_PBUFFER: - { - if (!wglReleasePbufferDCARBWrapper(draw->hPbuffer, hdc)) - { - ErrorF("wglReleasePbufferDCARB error: %s\n", glxWinErrorMessage()); - } - } - break; - - case GLX_DRAWABLE_PIXMAP: - { - // don't release DC, the memory DC lives as long as the bitmap - - // We must ensure that all GDI drawing into the bitmap has completed - // in case we subsequently access the bits from it - GdiFlush(); - } - break; - - default: - { - ErrorF("glxWinReleaseDC: tried to releaseDC for unhandled drawable type %d\n", draw->base.type); - } - } -} - -static void -glxWinDeferredCreateContext(__GLXWinContext *gc, __GLXWinDrawable *draw) -{ - HDC dc; - HWND hwnd; - GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attach context %p to drawable %p", gc, draw); - - switch (draw->base.type) - { - case GLX_DRAWABLE_WINDOW: - { - winWindowInfoRec winInfo; - WindowPtr pWin = (WindowPtr) draw->base.pDraw; - - if (!(gc->base.config->drawableType & GLX_WINDOW_BIT)) - { - ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_WINDOW_BIT to a GLX_DRAWABLE_WINDOW drawable\n"); - } - - if (pWin == NULL) - { - GLWIN_DEBUG_MSG("Deferring until X window is created"); - return; - } - - GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: pWin %p", pWin); - - winGetWindowInfo(pWin, &winInfo); - if (winInfo.hwnd == NULL) - { - GLWIN_DEBUG_MSG("Deferring until native window is created"); - return; - } - } - break; - - case GLX_DRAWABLE_PBUFFER: - { - if (draw->hPbuffer == NULL) - { - // XXX: which DC are supposed to use??? - HDC screenDC = GetDC(NULL); - - if (!(gc->base.config->drawableType & GLX_PBUFFER_BIT)) - { - ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PBUFFER_BIT to a GLX_DRAWABLE_PBUFFER drawable\n"); - } - - __GLXscreen *screen = gc->base.pGlxScreen; - glxWinScreen *winScreen = (glxWinScreen *)screen; - - int pixelFormat = fbConfigToPixelFormatIndex(screenDC, gc->base.config, GLX_DRAWABLE_PBUFFER, winScreen); - if (pixelFormat == 0) - { - ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage()); - return; - } - - draw->hPbuffer = wglCreatePbufferARBWrapper(screenDC, pixelFormat, draw->base.pDraw->width, draw->base.pDraw->height, NULL); - ReleaseDC(NULL, screenDC); - - if (draw->hPbuffer == NULL) - { - ErrorF("wglCreatePbufferARBWrapper error: %s\n", glxWinErrorMessage()); - return; - } - - GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: pBuffer %p created for drawable %p", draw->hPbuffer, draw); - } - } - break; - - case GLX_DRAWABLE_PIXMAP: - { - if (draw->dibDC == NULL) - { - BITMAPINFOHEADER bmpHeader = { sizeof(bmpHeader), - draw->base.pDraw->width, draw->base.pDraw->height, - 1, draw->base.pDraw->bitsPerPixel, - BI_RGB}; - void *pBits; - - if (!(gc->base.config->drawableType & GLX_PIXMAP_BIT)) - { - ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PIXMAP_BIT to a GLX_DRAWABLE_PIXMAP drawable\n"); - } - - draw->dibDC = CreateCompatibleDC(NULL); - if (draw->dibDC == NULL) - { - ErrorF("CreateCompatibleDC error: %s\n", glxWinErrorMessage()); - return; - } - - draw->hDIB = CreateDIBSection(draw->dibDC, (BITMAPINFO *)&bmpHeader, DIB_RGB_COLORS, &pBits, 0, 0); - if (draw->dibDC == NULL) - { - ErrorF("CreateDIBSection error: %s\n", glxWinErrorMessage()); - return; - } - - // XXX: CreateDIBSection insists on allocating the bitmap memory for us, so we're going to - // need some jiggery pokery to point the underlying X Drawable's bitmap at the same set of bits - // so that they can be read with XGetImage as well as glReadPixels, assuming the formats are - // even compatible ... - draw->pOldBits = ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr; - ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr = pBits; - - // Select the DIB into the DC - draw->hOldDIB = SelectObject(draw->dibDC, draw->hDIB); - if (!draw->hOldDIB) - { - ErrorF("SelectObject error: %s\n", glxWinErrorMessage()); - } - - // Set the pixel format of the bitmap - glxWinSetPixelFormat(gc, draw->dibDC, draw->base.pDraw->bitsPerPixel, GLX_PIXMAP_BIT); - - GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: DIB bitmap %p created for drawable %p", draw->hDIB, draw); - } - } - break; - - default: - { - ErrorF("glxWinDeferredCreateContext: tried to attach unhandled drawable type %d\n", draw->base.type); - return; - } - } - - dc = glxWinMakeDC(gc, draw, &dc, &hwnd); - gc->ctx = wglCreateContext(dc); - glxWinReleaseDC(hwnd, dc, draw); - - if (gc->ctx == NULL) - { - ErrorF("wglCreateContext error: %s\n", glxWinErrorMessage()); - return; - } - - GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attached context %p to native context %p drawable %p", gc, gc->ctx, draw); - - // if the native context was created successfully, shareLists if needed - if (gc->ctx && gc->shareContext) - { - GLWIN_DEBUG_MSG("glxWinCreateContextReal shareLists with context %p (native ctx %p)", gc->shareContext, gc->shareContext->ctx); - - if (!wglShareLists(gc->shareContext->ctx, gc->ctx)) - { - ErrorF("wglShareLists error: %s\n", glxWinErrorMessage()); - } - } -} - -/* ---------------------------------------------------------------------- */ -/* - * Context functions - */ - - -/* Context manipulation routines should return TRUE on success, FALSE on failure */ -static int -glxWinContextMakeCurrent(__GLXcontext *base) -{ - __GLXWinContext *gc = (__GLXWinContext *)base; - BOOL ret; - HDC drawDC; - HDC readDC = NULL; - __GLXdrawable *drawPriv; - __GLXdrawable *readPriv; - HWND hwnd; - - GLWIN_TRACE_MSG("glxWinContextMakeCurrent context %p (native ctx %p)", gc, gc->ctx); - glWinCallDelta(); - - /* Keep a note of the last active context in the drawable */ - drawPriv = gc->base.drawPriv; - ((__GLXWinDrawable *)drawPriv)->drawContext = gc; - - if (gc->ctx == NULL) - { - glxWinDeferredCreateContext(gc, (__GLXWinDrawable *)drawPriv); - } - - if (gc->ctx == NULL) - { - ErrorF("glxWinContextMakeCurrent: Native context is NULL\n"); - return FALSE; - } - - drawDC = glxWinMakeDC(gc, (__GLXWinDrawable *)drawPriv, &drawDC, &hwnd); - if (drawDC == NULL) - { - ErrorF("glxWinMakeDC failed for drawDC\n"); - return FALSE; - } - - if ((gc->base.readPriv != NULL) && (gc->base.readPriv != gc->base.drawPriv)) - { - // XXX: should only occur with WGL_ARB_make_current_read - /* - If there is a separate read drawable, create a separate read DC, and - use the wglMakeContextCurrent extension to make the context current drawing - to one DC and reading from the other - */ - readPriv = gc->base.readPriv; - readDC = glxWinMakeDC(gc, (__GLXWinDrawable *)readPriv, &readDC, &hwnd); - if (readDC == NULL) - { - ErrorF("glxWinMakeDC failed for readDC\n"); - glxWinReleaseDC(hwnd, drawDC, (__GLXWinDrawable *)readPriv); - return FALSE; - } - - ret = wglMakeContextCurrentARBWrapper(drawDC, readDC, gc->ctx); - if (!ret) - { - ErrorF("wglMakeContextCurrent error: %s\n", glxWinErrorMessage()); - } - } - else - { - /* Otherwise, just use wglMakeCurrent */ - ret = wglMakeCurrent(drawDC, gc->ctx); - if (!ret) - { - ErrorF("wglMakeCurrent error: %s\n", glxWinErrorMessage()); - } - } - - // apparently make current could fail if the context is current in a different thread, - // but that shouldn't be able to happen in the current server... - - glxWinReleaseDC(hwnd, drawDC, (__GLXWinDrawable *)drawPriv); - if (readDC) - glxWinReleaseDC(hwnd, drawDC, (__GLXWinDrawable *)readPriv); - - return ret; -} - -static int -glxWinContextLoseCurrent(__GLXcontext *base) -{ - BOOL ret; - __GLXWinContext *gc = (__GLXWinContext *)base; - - GLWIN_TRACE_MSG("glxWinContextLoseCurrent context %p (native ctx %p)", gc, gc->ctx); - glWinCallDelta(); - - ret = wglMakeCurrent(NULL, NULL); /* We don't need a DC when setting no current context */ - if (!ret) - ErrorF("glxWinContextLoseCurrent error: %s\n", glxWinErrorMessage()); - - __glXLastContext = NULL; /* Mesa does this; why? */ - // __glXFlushContextCache() - - return TRUE; -} - -static int -glxWinContextCopy(__GLXcontext *dst_base, __GLXcontext *src_base, unsigned long mask) -{ - __GLXWinContext *dst = (__GLXWinContext *)dst_base; - __GLXWinContext *src = (__GLXWinContext *)src_base; - BOOL ret; - - GLWIN_DEBUG_MSG("glxWinContextCopy"); - - ret = wglCopyContext(src->ctx, dst->ctx, mask); - if (!ret) - { - ErrorF("wglCopyContext error: %s\n", glxWinErrorMessage()); - } - - return ret; -} - -static int -glxWinContextForceCurrent(__GLXcontext *base) -{ - /* wglMakeCurrent always flushes the previous context, so this is equivalent to glxWinContextMakeCurrent */ - return glxWinContextMakeCurrent(base); -} - -static void -glxWinContextDestroy(__GLXcontext *base) -{ - __GLXWinContext *gc = (__GLXWinContext *)base; - - if (gc != NULL) - { - GLWIN_DEBUG_MSG("GLXcontext %p destroyed (native ctx %p)", base, gc->ctx); - - if (gc->ctx) - { - /* It's bad style to delete the context while it's still current */ - if (wglGetCurrentContext() == gc->ctx) - { - wglMakeCurrent(NULL, NULL); - } - - BOOL ret = wglDeleteContext(gc->ctx); - if (!ret) - ErrorF("wglDeleteContext error: %s\n", glxWinErrorMessage()); - gc->ctx = NULL; - } - - xfree(gc); - } -} - -static __GLXcontext * -glxWinCreateContext(__GLXscreen *screen, - __GLXconfig *modes, - __GLXcontext *baseShareContext) -{ - __GLXWinContext *context; - __GLXWinContext *shareContext = (__GLXWinContext *)baseShareContext; - - static __GLXtextureFromPixmap glxWinTextureFromPixmap = - { - glxWinBindTexImage, - glxWinReleaseTexImage - }; - - context = (__GLXWinContext *)xcalloc(1, sizeof(__GLXWinContext)); - - if (!context) - return NULL; - - memset(context, 0, sizeof *context); - context->base.destroy = glxWinContextDestroy; - context->base.makeCurrent = glxWinContextMakeCurrent; - context->base.loseCurrent = glxWinContextLoseCurrent; - context->base.copy = glxWinContextCopy; - context->base.forceCurrent = glxWinContextForceCurrent; - context->base.textureFromPixmap = &glxWinTextureFromPixmap; - context->base.config = modes; - context->base.pGlxScreen = screen; - - // actual native GL context creation is deferred until attach() - context->ctx = NULL; - context->shareContext = shareContext; - - glWinSetupDispatchTable(); - - GLWIN_DEBUG_MSG("GLXcontext %p created", context); - - return &(context->base); -} - -/* ---------------------------------------------------------------------- */ -/* - * Utility functions - */ - -static int -fbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int drawableTypeOverride) -{ - PIXELFORMATDESCRIPTOR pfd = { - sizeof(PIXELFORMATDESCRIPTOR), /* size of this pfd */ - 1, /* version number */ - PFD_SUPPORT_OPENGL, /* support OpenGL */ - PFD_TYPE_RGBA, /* RGBA type */ - 24, /* 24-bit color depth */ - 0, 0, 0, 0, 0, 0, /* color bits ignored */ - 0, /* no alpha buffer */ - 0, /* shift bit ignored */ - 0, /* no accumulation buffer */ - 0, 0, 0, 0, /* accum bits ignored */ - 32, /* 32-bit z-buffer */ - 0, /* no stencil buffer */ - 0, /* no auxiliary buffer */ - PFD_MAIN_PLANE, /* main layer */ - 0, /* reserved */ - 0, 0, 0 /* layer masks ignored */ - }; - - if ((mode->drawableType | drawableTypeOverride) & GLX_WINDOW_BIT) - pfd.dwFlags |= PFD_DRAW_TO_WINDOW; /* support window */ - - if ((mode->drawableType | drawableTypeOverride) & GLX_PIXMAP_BIT) - pfd.dwFlags |= (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI); /* supports software rendering to bitmap */ - - if (mode->stereoMode) { - pfd.dwFlags |= PFD_STEREO; - } - if (mode->doubleBufferMode) { - pfd.dwFlags |= PFD_DOUBLEBUFFER; - } - - pfd.iPixelType = PFD_TYPE_RGBA; - pfd.cColorBits = mode->redBits + mode->greenBits + mode->blueBits; - pfd.cRedBits = mode->redBits; - pfd.cRedShift = 0; /* FIXME */ - pfd.cGreenBits = mode->greenBits; - pfd.cGreenShift = 0; /* FIXME */ - pfd.cBlueBits = mode->blueBits; - pfd.cBlueShift = 0; /* FIXME */ - pfd.cAlphaBits = mode->alphaBits; - pfd.cAlphaShift = 0; /* FIXME */ - - pfd.cAccumBits = mode->accumRedBits + mode->accumGreenBits + mode->accumBlueBits + mode->accumAlphaBits; - pfd.cAccumRedBits = mode->accumRedBits; - pfd.cAccumGreenBits = mode->accumGreenBits; - pfd.cAccumBlueBits = mode->accumBlueBits; - pfd.cAccumAlphaBits = mode->accumAlphaBits; - - pfd.cDepthBits = mode->depthBits; - pfd.cStencilBits = mode->stencilBits; - pfd.cAuxBuffers = mode->numAuxBuffers; - - /* mode->level ? */ - /* mode->pixmapMode ? */ - - *pfdret = pfd; - - return 0; -} - -#define SET_ATTR_VALUE(attr, value) { attribList[i++] = attr; attribList[i++] = value; assert(i < NUM_ELEMENTS(attribList)); } - -static int -fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig *mode, int drawableTypeOverride, glxWinScreen *winScreen) -{ - UINT numFormats; - unsigned int i = 0; - - /* convert fbConfig to attr-value list */ - int attribList[60]; - - SET_ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, TRUE); - SET_ATTR_VALUE(WGL_PIXEL_TYPE_ARB, (mode->visualType == GLX_TRUE_COLOR) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB); - SET_ATTR_VALUE(WGL_COLOR_BITS_ARB, (mode->visualType == GLX_TRUE_COLOR) ? mode->rgbBits : mode->indexBits); - SET_ATTR_VALUE(WGL_RED_BITS_ARB, mode->redBits); - SET_ATTR_VALUE(WGL_GREEN_BITS_ARB, mode->greenBits); - SET_ATTR_VALUE(WGL_BLUE_BITS_ARB, mode->blueBits); - SET_ATTR_VALUE(WGL_ALPHA_BITS_ARB, mode->alphaBits); - SET_ATTR_VALUE(WGL_ACCUM_RED_BITS_ARB, mode->accumRedBits); - SET_ATTR_VALUE(WGL_ACCUM_GREEN_BITS_ARB, mode->accumGreenBits); - SET_ATTR_VALUE(WGL_ACCUM_BLUE_BITS_ARB, mode->accumBlueBits); - SET_ATTR_VALUE(WGL_ACCUM_ALPHA_BITS_ARB, mode->accumAlphaBits); - SET_ATTR_VALUE(WGL_DEPTH_BITS_ARB, mode->depthBits); - SET_ATTR_VALUE(WGL_STENCIL_BITS_ARB, mode->stencilBits); - SET_ATTR_VALUE(WGL_AUX_BUFFERS_ARB, mode->numAuxBuffers); - - if (mode->doubleBufferMode) - SET_ATTR_VALUE(WGL_DOUBLE_BUFFER_ARB, TRUE); - - if (mode->stereoMode) - SET_ATTR_VALUE(WGL_STEREO_ARB, TRUE); - - // Some attributes are only added to the list if the value requested is not 'don't care', as exactly matching that is daft.. - if (mode->swapMethod == GLX_SWAP_EXCHANGE_OML) - SET_ATTR_VALUE(WGL_SWAP_METHOD_ARB, WGL_SWAP_EXCHANGE_ARB); - - if (mode->swapMethod == GLX_SWAP_COPY_OML) - SET_ATTR_VALUE(WGL_SWAP_COPY_ARB, TRUE); - - // XXX: this should probably be the other way around, but that messes up drawableTypeOverride - if (mode->visualRating == GLX_SLOW_VISUAL_EXT) - SET_ATTR_VALUE(WGL_ACCELERATION_ARB, WGL_NO_ACCELERATION_ARB); - - // must support all the drawable types the mode supports - if ((mode->drawableType | drawableTypeOverride) & GLX_WINDOW_BIT) - SET_ATTR_VALUE(WGL_DRAW_TO_WINDOW_ARB,TRUE); - - // XXX: this is a horrible hacky heuristic, in fact this whole drawableTypeOverride thing is a bad idea - // try to avoid asking for formats which don't exist (by not asking for all when adjusting the config to include the drawableTypeOverride) - if (drawableTypeOverride == GLX_WINDOW_BIT) - { - if (mode->drawableType & GLX_PIXMAP_BIT) - SET_ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, TRUE); - - if (mode->drawableType & GLX_PBUFFER_BIT) - if (winScreen->has_WGL_ARB_pbuffer) - SET_ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, TRUE); - } - else - { - if (drawableTypeOverride & GLX_PIXMAP_BIT) - SET_ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, TRUE); - - if (drawableTypeOverride & GLX_PBUFFER_BIT) - if (winScreen->has_WGL_ARB_pbuffer) - SET_ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, TRUE); - } - - SET_ATTR_VALUE(0, 0); // terminator - - /* choose the first match */ - { - int pixelFormatIndex; - - if (!wglChoosePixelFormatARBWrapper(hdc, attribList, NULL, 1, &pixelFormatIndex, &numFormats)) - { - ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage()); - } - else - { - if (numFormats > 0) - { - GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d)", pixelFormatIndex); - return pixelFormatIndex; - } - else - ErrorF("wglChoosePixelFormat couldn't decide\n"); - } - } - - return 0; -} - -/* ---------------------------------------------------------------------- */ - -#define BITS_AND_SHIFT_TO_MASK(bits,mask) (((1<<(bits))-1) << (mask)) - -// -// Create the GLXconfigs using DescribePixelFormat() -// -static void -glxWinCreateConfigs(HDC hdc, glxWinScreen *screen) -{ - GLXWinConfig *c, *result, *prev = NULL; - int numConfigs = 0; - int i = 0; - int n = 0; - PIXELFORMATDESCRIPTOR pfd; - - GLWIN_DEBUG_MSG("glxWinCreateConfigs"); - - screen->base.numFBConfigs = 0; - screen->base.fbconfigs = NULL; - - // get the number of pixelformats - numConfigs = DescribePixelFormat(hdc, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL); - GLWIN_DEBUG_MSG("DescribePixelFormat says %d possible pixel formats", numConfigs); - - /* alloc */ - result = xalloc(sizeof(GLXWinConfig) * numConfigs); - - if (NULL == result) - { - return; - } - - memset(result, 0, sizeof(GLXWinConfig) * numConfigs); - n = 0; - - /* fill in configs */ - for (i = 0; i < numConfigs; i++) - { - int rc; - - c = &(result[i]); - c->base.next = NULL; - c->pixelFormatIndex = i+1; - - rc = DescribePixelFormat(hdc, i+1, sizeof(PIXELFORMATDESCRIPTOR), &pfd); - - if (!rc) - { - ErrorF("DescribePixelFormat failed for index %d, error %s\n", i+1, glxWinErrorMessage()); - break; - } - - if (glxWinDebugSettings.dumpPFD) - pfdOut(&pfd); - - if (!(pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP)) || !(pfd.dwFlags & PFD_SUPPORT_OPENGL)) - { - GLWIN_DEBUG_MSG("pixelFormat %d has unsuitable flags 0x%08lx, skipping", i+1, pfd.dwFlags); - continue; - } - - c->base.doubleBufferMode = (pfd.dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE; - c->base.stereoMode = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE; - - c->base.redBits = pfd.cRedBits; - c->base.greenBits = pfd.cGreenBits; - c->base.blueBits = pfd.cBlueBits; - c->base.alphaBits = pfd.cAlphaBits; - - c->base.redMask = BITS_AND_SHIFT_TO_MASK(pfd.cRedBits, pfd.cRedShift); - c->base.greenMask = BITS_AND_SHIFT_TO_MASK(pfd.cGreenBits, pfd.cGreenShift); - c->base.blueMask = BITS_AND_SHIFT_TO_MASK(pfd.cBlueBits, pfd.cBlueShift); - c->base.alphaMask = BITS_AND_SHIFT_TO_MASK(pfd.cAlphaBits, pfd.cAlphaShift); - - c->base.rgbBits = pfd.cColorBits; - - if (pfd.iPixelType == PFD_TYPE_COLORINDEX) - { - c->base.indexBits = pfd.cColorBits; - } - else - { - c->base.indexBits = 0; - } - - c->base.accumRedBits = pfd.cAccumRedBits; - c->base.accumGreenBits = pfd.cAccumGreenBits; - c->base.accumBlueBits = pfd.cAccumBlueBits; - c->base.accumAlphaBits = pfd.cAccumAlphaBits; - // pfd.cAccumBits; - - c->base.depthBits = pfd.cDepthBits; - c->base.stencilBits = pfd.cStencilBits; - c->base.numAuxBuffers = pfd.cAuxBuffers; - - // pfd.iLayerType; // ignored - c->base.level = 0; - // pfd.dwLayerMask; // ignored - // pfd.dwDamageMask; // ignored - - c->base.pixmapMode = 0; - c->base.visualID = -1; // will be set by __glXScreenInit() - - /* EXT_visual_rating / GLX 1.2 */ - if (pfd.dwFlags & PFD_GENERIC_FORMAT) - { - c->base.visualRating = GLX_SLOW_VISUAL_EXT; - } - else - { - // PFD_GENERIC_ACCELERATED is not considered, so this may be MCD or ICD acclerated... - c->base.visualRating = GLX_NONE_EXT; - } - - /* EXT_visual_info / GLX 1.2 */ - if (pfd.iPixelType == PFD_TYPE_COLORINDEX) - { - c->base.visualType = GLX_STATIC_COLOR; - } - else - { - c->base.visualType = GLX_TRUE_COLOR; - } - - // pfd.dwVisibleMask; ??? - c->base.transparentPixel = GLX_NONE; - c->base.transparentRed = GLX_NONE; - c->base.transparentGreen = GLX_NONE; - c->base.transparentBlue = GLX_NONE; - c->base.transparentAlpha = GLX_NONE; - c->base.transparentIndex = GLX_NONE; - - /* ARB_multisample / SGIS_multisample */ - c->base.sampleBuffers = 0; - c->base.samples = 0; - - /* SGIX_fbconfig / GLX 1.3 */ - c->base.drawableType = (((pfd.dwFlags & PFD_DRAW_TO_WINDOW) ? GLX_WINDOW_BIT : 0) - | ((pfd.dwFlags & PFD_DRAW_TO_BITMAP) ? GLX_PIXMAP_BIT : 0)); - c->base.renderType = GLX_RGBA_BIT; - c->base.xRenderable = GL_TRUE; - c->base.fbconfigID = -1; // will be set by __glXScreenInit() - - /* SGIX_pbuffer / GLX 1.3 */ - // XXX: How can we find these values out ??? - c->base.maxPbufferWidth = -1; - c->base.maxPbufferHeight = -1; - c->base.maxPbufferPixels = -1; - c->base.optimalPbufferWidth = 0; // there is no optimal value - c->base.optimalPbufferHeight = 0; - - /* SGIX_visual_select_group */ - // arrange for visuals with the best acceleration to be preferred in selection - switch (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED)) - { - case 0: - c->base.visualSelectGroup = 2; - break; - - case PFD_GENERIC_ACCELERATED: - c->base.visualSelectGroup = 1; - break; - - case PFD_GENERIC_FORMAT: - c->base.visualSelectGroup = 0; - break; - - default: - ; - // "can't happen" - } - - /* OML_swap_method */ - if (pfd.dwFlags & PFD_SWAP_EXCHANGE) - c->base.swapMethod = GLX_SWAP_EXCHANGE_OML; - else if (pfd.dwFlags & PFD_SWAP_COPY) - c->base.swapMethod = GLX_SWAP_COPY_OML; - else - c->base.swapMethod = GLX_SWAP_UNDEFINED_OML; - - /* EXT_import_context */ - c->base.screen = screen->base.pScreen->myNum; - - /* EXT_texture_from_pixmap */ - c->base.bindToTextureRgb = -1; - c->base.bindToTextureRgba = -1; - c->base.bindToMipmapTexture = -1; - c->base.bindToTextureTargets = -1; - c->base.yInverted = -1; - - n++; - - // update previous config to point to this config - if (prev) - prev->base.next = &(c->base); - - prev = c; - } - - GLWIN_DEBUG_MSG("found %d pixelFormats suitable for conversion to fbConfigs", n); - - screen->base.numFBConfigs = n; - screen->base.fbconfigs = &(result->base); -} - -// helper function to access an attribute value from an attribute value array by attribute -static -int getAttrValue(const int attrs[], int values[], unsigned int num, int attr, int fallback) -{ - unsigned int i; - for (i = 0; i < num; i++) - { - if (attrs[i] == attr) - { - GLWIN_TRACE_MSG("getAttrValue attr 0x%x, value %d", attr, values[i]); - return values[i]; - } - } - - ErrorF("getAttrValue failed to find attr 0x%x, using default value %d\n", attr, fallback); - return fallback; -} - -// -// Create the GLXconfigs using wglGetPixelFormatAttribfvARB() extension -// -static void -glxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen) -{ - GLXWinConfig *c, *result, *prev = NULL; - int i = 0; - int n = 0; - - const int attr = WGL_NUMBER_PIXEL_FORMATS_ARB; - int numConfigs; - - int attrs[50]; - unsigned int num_attrs = 0; - - GLWIN_DEBUG_MSG("glxWinCreateConfigsExt"); - - screen->base.numFBConfigs = 0; - screen->base.fbconfigs = NULL; - - if (!wglGetPixelFormatAttribivARBWrapper(hdc, 0, 0, 1, &attr, &numConfigs)) - { - ErrorF("wglGetPixelFormatAttribivARB failed for WGL_NUMBER_PIXEL_FORMATS_ARB: %s\n", glxWinErrorMessage()); - return; - } - - GLWIN_DEBUG_MSG("wglGetPixelFormatAttribivARB says %d possible pixel formats", numConfigs); - - /* alloc */ - result = xalloc(sizeof(GLXWinConfig) * numConfigs); - - if (NULL == result) - { - return; - } - - memset(result, 0, sizeof(GLXWinConfig) * numConfigs); - n = 0; - -#define ADD_ATTR(a) { attrs[num_attrs++] = a; assert(num_attrs < NUM_ELEMENTS(attrs)); } - - ADD_ATTR(WGL_DRAW_TO_WINDOW_ARB); - ADD_ATTR(WGL_DRAW_TO_BITMAP_ARB); - ADD_ATTR(WGL_ACCELERATION_ARB); - ADD_ATTR(WGL_SWAP_LAYER_BUFFERS_ARB); - ADD_ATTR(WGL_NUMBER_OVERLAYS_ARB); - ADD_ATTR(WGL_NUMBER_UNDERLAYS_ARB); - ADD_ATTR(WGL_TRANSPARENT_ARB); - ADD_ATTR(WGL_TRANSPARENT_RED_VALUE_ARB); - ADD_ATTR(WGL_TRANSPARENT_GREEN_VALUE_ARB); - ADD_ATTR(WGL_TRANSPARENT_GREEN_VALUE_ARB); - ADD_ATTR(WGL_TRANSPARENT_ALPHA_VALUE_ARB); - ADD_ATTR(WGL_SUPPORT_OPENGL_ARB); - ADD_ATTR(WGL_DOUBLE_BUFFER_ARB); - ADD_ATTR(WGL_STEREO_ARB); - ADD_ATTR(WGL_PIXEL_TYPE_ARB); - ADD_ATTR(WGL_COLOR_BITS_ARB); - ADD_ATTR(WGL_RED_BITS_ARB); - ADD_ATTR(WGL_RED_SHIFT_ARB); - ADD_ATTR(WGL_GREEN_BITS_ARB); - ADD_ATTR(WGL_GREEN_SHIFT_ARB); - ADD_ATTR(WGL_BLUE_BITS_ARB); - ADD_ATTR(WGL_BLUE_SHIFT_ARB); - ADD_ATTR(WGL_ALPHA_BITS_ARB); - ADD_ATTR(WGL_ALPHA_SHIFT_ARB); - ADD_ATTR(WGL_ACCUM_RED_BITS_ARB); - ADD_ATTR(WGL_ACCUM_GREEN_BITS_ARB); - ADD_ATTR(WGL_ACCUM_BLUE_BITS_ARB); - ADD_ATTR(WGL_ACCUM_ALPHA_BITS_ARB); - ADD_ATTR(WGL_DEPTH_BITS_ARB); - ADD_ATTR(WGL_STENCIL_BITS_ARB); - ADD_ATTR(WGL_AUX_BUFFERS_ARB); - ADD_ATTR(WGL_SWAP_METHOD_ARB); - - if (screen->has_WGL_ARB_multisample) - { - // we may not query these attrs if WGL_ARB_multisample is not offered - ADD_ATTR(WGL_SAMPLE_BUFFERS_ARB); - ADD_ATTR(WGL_SAMPLES_ARB); - } - - if (screen->has_WGL_ARB_render_texture) - { - // we may not query these attrs if WGL_ARB_render_texture is not offered - ADD_ATTR(WGL_BIND_TO_TEXTURE_RGB_ARB); - ADD_ATTR(WGL_BIND_TO_TEXTURE_RGBA_ARB); - } - - if (screen->has_WGL_ARB_pbuffer) - { - // we may not query these attrs if WGL_ARB_pbuffer is not offered - ADD_ATTR(WGL_DRAW_TO_PBUFFER_ARB); - ADD_ATTR(WGL_MAX_PBUFFER_PIXELS_ARB); - ADD_ATTR(WGL_MAX_PBUFFER_WIDTH_ARB); - ADD_ATTR(WGL_MAX_PBUFFER_HEIGHT_ARB); - } - - /* fill in configs */ - for (i = 0; i < numConfigs; i++) - { - c = &(result[i]); - c->base.next = NULL; - c->pixelFormatIndex = i+1; - - int values[num_attrs]; - - if (!wglGetPixelFormatAttribivARBWrapper(hdc, i+1, 0, num_attrs, attrs, values)) - { - ErrorF("wglGetPixelFormatAttribivARB failed for index %d, error %s\n", i+1, glxWinErrorMessage()); - break; - } - -#define ATTR_VALUE(a, d) getAttrValue(attrs, values, num_attrs, (a), (d)) - - if (!ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, 0)) - { - GLWIN_DEBUG_MSG("pixelFormat %d isn't WGL_SUPPORT_OPENGL_ARB, skipping", i+1); - continue; - } - - c->base.doubleBufferMode = ATTR_VALUE(WGL_DOUBLE_BUFFER_ARB, 0) ? GL_TRUE : GL_FALSE; - c->base.stereoMode = ATTR_VALUE(WGL_STEREO_ARB, 0) ? GL_TRUE : GL_FALSE; - - c->base.redBits = ATTR_VALUE(WGL_RED_BITS_ARB, 0); - c->base.greenBits = ATTR_VALUE(WGL_GREEN_BITS_ARB, 0); - c->base.blueBits = ATTR_VALUE(WGL_BLUE_BITS_ARB, 0); - c->base.alphaBits = ATTR_VALUE(WGL_ALPHA_BITS_ARB, 0); - - c->base.redMask = BITS_AND_SHIFT_TO_MASK(c->base.redBits, ATTR_VALUE(WGL_RED_SHIFT_ARB, 0)); - c->base.greenMask = BITS_AND_SHIFT_TO_MASK(c->base.greenBits, ATTR_VALUE(WGL_GREEN_SHIFT_ARB, 0)); - c->base.blueMask = BITS_AND_SHIFT_TO_MASK(c->base.blueBits, ATTR_VALUE(WGL_BLUE_SHIFT_ARB, 0)); - c->base.alphaMask = BITS_AND_SHIFT_TO_MASK(c->base.alphaBits, ATTR_VALUE(WGL_ALPHA_SHIFT_ARB, 0)); - - switch (ATTR_VALUE(WGL_PIXEL_TYPE_ARB, 0)) - { - case WGL_TYPE_COLORINDEX_ARB: - c->base.indexBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0); - c->base.rgbBits = 0; - c->base.visualType = GLX_STATIC_COLOR; - break; - - case WGL_TYPE_RGBA_FLOAT_ARB: - GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_RGBA_FLOAT_ARB, skipping", i+1); - continue; - - case WGL_TYPE_RGBA_ARB: - c->base.indexBits = 0; - c->base.rgbBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0); - c->base.visualType = GLX_TRUE_COLOR; - break; - - default: - ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_PIXEL_TYPE_ARB\n", ATTR_VALUE(WGL_PIXEL_TYPE_ARB, 0)); - continue; - } - - c->base.accumRedBits = ATTR_VALUE(WGL_ACCUM_RED_BITS_ARB, 0); - c->base.accumGreenBits = ATTR_VALUE(WGL_ACCUM_GREEN_BITS_ARB, 0); - c->base.accumBlueBits = ATTR_VALUE(WGL_ACCUM_BLUE_BITS_ARB, 0); - c->base.accumAlphaBits = ATTR_VALUE(WGL_ACCUM_ALPHA_BITS_ARB, 0); - - c->base.depthBits = ATTR_VALUE(WGL_DEPTH_BITS_ARB, 0); - c->base.stencilBits = ATTR_VALUE(WGL_STENCIL_BITS_ARB, 0); - c->base.numAuxBuffers = ATTR_VALUE(WGL_AUX_BUFFERS_ARB, 0); - - { - int layers = ATTR_VALUE(WGL_NUMBER_OVERLAYS_ARB,0) + ATTR_VALUE(WGL_NUMBER_UNDERLAYS_ARB, 0); - - if (layers > 0) - { - ErrorF("pixelFormat %d: has %d overlay, %d underlays which aren't currently handled", i, ATTR_VALUE(WGL_NUMBER_OVERLAYS_ARB,0), ATTR_VALUE(WGL_NUMBER_UNDERLAYS_ARB, 0)); - // XXX: need to iterate over layers? - } - } - c->base.level = 0; - - c->base.pixmapMode = 0; // ??? - c->base.visualID = -1; // will be set by __glXScreenInit() - - /* EXT_visual_rating / GLX 1.2 */ - switch (ATTR_VALUE(WGL_ACCELERATION_ARB, 0)) - { - default: - ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_ACCELERATION_ARB\n", ATTR_VALUE(WGL_ACCELERATION_ARB, 0)); - - case WGL_NO_ACCELERATION_ARB: - c->base.visualRating = GLX_SLOW_VISUAL_EXT; - break; - - case WGL_GENERIC_ACCELERATION_ARB: - case WGL_FULL_ACCELERATION_ARB: - c->base.visualRating = GLX_NONE_EXT; - break; - } - - /* EXT_visual_info / GLX 1.2 */ - // c->base.visualType is set above - if (ATTR_VALUE(WGL_TRANSPARENT_ARB, 0)) - { - c->base.transparentPixel = (c->base.visualType == GLX_TRUE_COLOR) ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT; - c->base.transparentRed = ATTR_VALUE(WGL_TRANSPARENT_RED_VALUE_ARB, 0); - c->base.transparentGreen = ATTR_VALUE(WGL_TRANSPARENT_GREEN_VALUE_ARB, 0); - c->base.transparentBlue = ATTR_VALUE(WGL_TRANSPARENT_BLUE_VALUE_ARB, 0); - c->base.transparentAlpha = ATTR_VALUE(WGL_TRANSPARENT_ALPHA_VALUE_ARB, 0); - c->base.transparentIndex = ATTR_VALUE(WGL_TRANSPARENT_INDEX_VALUE_ARB, 0); - } - else - { - c->base.transparentPixel = GLX_NONE_EXT; - c->base.transparentRed = GLX_NONE; - c->base.transparentGreen = GLX_NONE; - c->base.transparentBlue = GLX_NONE; - c->base.transparentAlpha = GLX_NONE; - c->base.transparentIndex = GLX_NONE; - } - - /* ARB_multisample / SGIS_multisample */ - if (screen->has_WGL_ARB_multisample) - { - c->base.sampleBuffers = ATTR_VALUE(WGL_SAMPLE_BUFFERS_ARB, 0); - c->base.samples = ATTR_VALUE(WGL_SAMPLES_ARB, 0); - } - else - { - c->base.sampleBuffers = 0; - c->base.samples = 0; - } - - /* SGIX_fbconfig / GLX 1.3 */ - c->base.drawableType = ((ATTR_VALUE(WGL_DRAW_TO_WINDOW_ARB, 0) ? GLX_WINDOW_BIT : 0) - | (ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, 0) ? GLX_PIXMAP_BIT : 0) - | (ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, 0) ? GLX_PBUFFER_BIT : 0)); - c->base.renderType = GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT; // Hmmm ??? - c->base.xRenderable = GL_TRUE; - c->base.fbconfigID = -1; // will be set by __glXScreenInit() - - /* SGIX_pbuffer / GLX 1.3 */ - if (screen->has_WGL_ARB_pbuffer) - { - c->base.maxPbufferWidth = ATTR_VALUE(WGL_MAX_PBUFFER_WIDTH_ARB, -1); - c->base.maxPbufferHeight = ATTR_VALUE(WGL_MAX_PBUFFER_HEIGHT_ARB, -1); - c->base.maxPbufferPixels = ATTR_VALUE(WGL_MAX_PBUFFER_PIXELS_ARB, -1); - } - else - { - c->base.maxPbufferWidth = -1; - c->base.maxPbufferHeight = -1; - c->base.maxPbufferPixels = -1; - } - c->base.optimalPbufferWidth = 0; // there is no optimal value - c->base.optimalPbufferHeight = 0; - - /* SGIX_visual_select_group */ - // arrange for visuals with the best acceleration to be preferred in selection - switch (ATTR_VALUE(WGL_ACCELERATION_ARB, 0)) - { - case WGL_FULL_ACCELERATION_ARB: - c->base.visualSelectGroup = 2; - break; - - case WGL_GENERIC_ACCELERATION_ARB: - c->base.visualSelectGroup = 1; - break; - - default: - case WGL_NO_ACCELERATION_ARB: - c->base.visualSelectGroup = 0; - break; - } - - /* OML_swap_method */ - switch (ATTR_VALUE(WGL_SWAP_METHOD_ARB, 0)) - { - case WGL_SWAP_EXCHANGE_ARB: - c->base.swapMethod = GLX_SWAP_EXCHANGE_OML; - break; - - case WGL_SWAP_COPY_ARB: - c->base.swapMethod = GLX_SWAP_COPY_OML; - break; - - default: - ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_SWAP_METHOD_ARB\n", ATTR_VALUE(WGL_SWAP_METHOD_ARB, 0)); - - case WGL_SWAP_UNDEFINED_ARB: - c->base.swapMethod = GLX_SWAP_UNDEFINED_OML; - } - - /* EXT_import_context */ - c->base.screen = screen->base.pScreen->myNum; - - /* EXT_texture_from_pixmap */ - /* - Mesa's DRI configs always have bindToTextureRgb/Rgba TRUE (see driCreateConfigs(), so setting - bindToTextureRgb/bindToTextureRgba to FALSE means that swrast can't find any fbConfigs to use, - so setting these to 0, even if we know bindToTexture isn't available, isn't a good idea... - */ - if (screen->has_WGL_ARB_render_texture) - { - c->base.bindToTextureRgb = ATTR_VALUE(WGL_BIND_TO_TEXTURE_RGB_ARB, -1); - c->base.bindToTextureRgba = ATTR_VALUE(WGL_BIND_TO_TEXTURE_RGBA_ARB, -1); - } - else - { - c->base.bindToTextureRgb = -1; - c->base.bindToTextureRgba = -1; - } - c->base.bindToMipmapTexture = -1; - c->base.bindToTextureTargets = GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT | GLX_TEXTURE_RECTANGLE_BIT_EXT; - c->base.yInverted = -1; - - n++; - - // update previous config to point to this config - if (prev) - prev->base.next = &(c->base); - - prev = c; - } - - screen->base.numFBConfigs = n; - screen->base.fbconfigs = &(result->base); -} +/*
+ * File: indirect.c
+ * Purpose: A GLX implementation that uses Windows OpenGL library
+ *
+ * Authors: Alexander Gottwald
+ * Jon TURNEY
+ *
+ * Copyright (c) Jon TURNEY 2009
+ * Copyright (c) Alexander Gottwald 2004
+ *
+ * Portions of this file are copied from GL/apple/indirect.c,
+ * which contains the following copyright:
+ *
+ * Copyright (c) 2007, 2008, 2009 Apple Inc.
+ * Copyright (c) 2004 Torrey T. Lyons. All Rights Reserved.
+ * Copyright (c) 2002 Greg Parker. All Rights Reserved.
+ *
+ * Portions of this file are copied from Mesa's xf86glx.c,
+ * which contains the following copyright:
+ *
+ * Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
+ * 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 ABOVE LISTED COPYRIGHT HOLDER(S) 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.
+ */
+
+/*
+ TODO:
+ - hook up remaining unimplemented extensions
+ - research what guarantees glXWaitX, glXWaitGL are supposed to offer, and implement then
+ using GdiFlush and/or glFinish
+ - pbuffer clobbering: we don't get async notification, but can we arrange to emit the
+ event when we notice it's been clobbered? at the very least, check if it's been clobbered
+ before using it?
+ - are the __GLXConfig * we get handed back ones we are made (so we can extend the structure
+ with privates?) Or are they created inside the GLX core as well?
+*/
+
+/*
+ MSDN clarifications:
+
+ It says SetPixelFormat()'s PIXELFORMATDESCRIPTOR pointer argument has no effect
+ except on metafiles, this seems to mean that as it's ok to supply NULL if the DC
+ is not for a metafile
+
+ wglMakeCurrent ignores the hdc if hglrc is NULL, so wglMakeCurrent(NULL, NULL)
+ is used to make no context current
+
+*/
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+
+#include "glwindows.h"
+#include <glx/glxserver.h>
+#include <glx/glxutil.h>
+#include <glx/extension_string.h>
+#include <GL/internal/glcore.h>
+#include <GL/glxtokens.h>
+
+#include <winpriv.h>
+#include <wgl_ext_api.h>
+#include "win.h"
+#include <winmsg.h>
+
+extern Bool g_fXdmcpEnabled;
+extern Bool g_fNativeGl;
+
+#define NUM_ELEMENTS(x) (sizeof(x)/ sizeof(x[1]))
+
+/* ---------------------------------------------------------------------- */
+/*
+ * structure definitions
+ */
+
+typedef struct __GLXWinContext __GLXWinContext;
+typedef struct __GLXWinDrawable __GLXWinDrawable;
+typedef struct __GLXWinScreen glxWinScreen;
+typedef struct __GLXWinConfig GLXWinConfig;
+
+struct __GLXWinContext {
+ __GLXcontext base;
+ HGLRC ctx; /* Windows GL Context */
+ HDC hDC; /* Windows device context */
+ HDC hreadDC; /* Windows device read context */
+ __GLXWinContext *shareContext; /* Context with which we will share display lists and textures */
+ HWND hwnd; /* For detecting when HWND has changed */
+ HWND hreadwnd;
+};
+
+struct __GLXWinDrawable
+{
+ __GLXdrawable base;
+ __GLXWinContext *drawContext;
+
+ /* If this drawable is GLX_DRAWABLE_PBUFFER */
+ HPBUFFERARB hPbuffer;
+
+ /* If this drawable is GLX_DRAWABLE_PIXMAP */
+ HDC dibDC;
+ HBITMAP hDIB;
+ HBITMAP hOldDIB; /* original DIB for DC */
+ void *pOldBits; /* original pBits for this drawable's pixmap */
+};
+
+struct __GLXWinScreen
+{
+ __GLXscreen base;
+
+ /* Supported GLX extensions */
+ unsigned char glx_enable_bits[__GLX_EXT_BYTES];
+
+ Bool has_WGL_ARB_multisample;
+ Bool has_WGL_ARB_pixel_format;
+ Bool has_WGL_ARB_pbuffer;
+ Bool has_WGL_ARB_render_texture;
+
+ /* wrapped screen functions */
+ RealizeWindowProcPtr RealizeWindow;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ DestroyWindowProcPtr DestroyWindow;
+ CopyWindowProcPtr CopyWindow;
+ PositionWindowProcPtr PositionWindow;
+};
+
+struct __GLXWinConfig
+{
+ __GLXconfig base;
+ int pixelFormatIndex;
+};
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Various debug helpers
+ */
+
+#ifdef _DEBUG
+void GLWIN_DEBUG_HWND(HWND hwnd)
+{
+ if (glxWinDebugSettings.dumpHWND)
+ {
+ char buffer[1024];
+ RECT Rect;
+ HDC hDc=GetDC(hwnd);
+
+ if (GetWindowText(hwnd, buffer, sizeof(buffer))==0) *buffer=0;
+ GetWindowRect(hwnd,&Rect);
+
+ GLWIN_DEBUG_MSG("Got HWND %p (hdc %p) for window '%s' (%d,%d,%d,%d)", hwnd, hDc, buffer, Rect.left, Rect.top, Rect.right, Rect.bottom);
+ ReleaseDC(hwnd,hDc);
+ }
+}
+
+void GLWIN_HDC_DEBUG_MSG(const char *Message, HDC hDc, HWND hwnd)
+{
+ char buffer[1024];
+ RECT Rect;
+
+ if (GetWindowText(hwnd, buffer, sizeof(buffer))==0) *buffer=0;
+ GetWindowRect(hwnd,&Rect);
+
+ GLWIN_DEBUG_MSG("Got HDC %p (hwnd %p) for window '%s' (%d,%d,%d,%d)", hDc, hwnd, buffer, Rect.left, Rect.top, Rect.right, Rect.bottom);
+
+}
+
+glxWinDebugSettingsRec glxWinDebugSettings = { 0, 0, 0, 0, 0, 0};
+
+static void glxWinInitDebugSettings(void)
+{
+ char *envptr;
+
+ envptr = getenv("GLWIN_ENABLE_DEBUG");
+ if (envptr != NULL)
+ glxWinDebugSettings.enableDebug = (atoi(envptr) == 1);
+
+ envptr = getenv("GLWIN_ENABLE_TRACE");
+ if (envptr != NULL)
+ glxWinDebugSettings.enableTrace = (atoi(envptr) == 1);
+
+ envptr = getenv("GLWIN_DUMP_PFD");
+ if (envptr != NULL)
+ glxWinDebugSettings.dumpPFD = (atoi(envptr) == 1);
+
+ envptr = getenv("GLWIN_DUMP_HWND");
+ if (envptr != NULL)
+ glxWinDebugSettings.dumpHWND = (atoi(envptr) == 1);
+
+ envptr = getenv("GLWIN_DUMP_DC");
+ if (envptr != NULL)
+ glxWinDebugSettings.dumpDC = (atoi(envptr) == 1);
+
+ envptr = getenv("GLWIN_ENABLE_GLCALL_TRACE");
+ if (envptr != NULL)
+ glxWinDebugSettings.enableGLcallTrace = (atoi(envptr) == 1);
+
+ envptr = getenv("GLWIN_ENABLE_WGLCALL_TRACE");
+ if (envptr != NULL)
+ glxWinDebugSettings.enableWGLcallTrace = (atoi(envptr) == 1);
+
+ envptr = getenv("GLWIN_DEBUG_ALL");
+ if (envptr != NULL)
+ {
+ glxWinDebugSettings.enableDebug = 1;
+ glxWinDebugSettings.enableTrace = 1;
+ glxWinDebugSettings.dumpPFD = 1;
+ glxWinDebugSettings.dumpHWND = 1;
+ glxWinDebugSettings.dumpDC = 1;
+ glxWinDebugSettings.enableGLcallTrace = 1;
+ glxWinDebugSettings.enableWGLcallTrace = 1;
+ }
+}
+#endif
+
+static
+const char *glxWinErrorMessage(void)
+{
+ static char errorbuffer[1024];
+ DWORD Error=GetLastError();
+ int offset;
+
+ sprintf(errorbuffer, "%p ",Error);
+ offset=strlen(errorbuffer);
+
+ if (!FormatMessage(
+ FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+ NULL,
+ Error,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &errorbuffer[offset],
+ sizeof(errorbuffer),
+ NULL ))
+ {
+ snprintf(errorbuffer, sizeof(errorbuffer), "Unknown error in FormatMessage: %08x!", (unsigned)GetLastError());
+ }
+
+ if (errorbuffer[strlen(errorbuffer)-1] == '\n')
+ errorbuffer[strlen(errorbuffer)-1] = 0;
+
+ return errorbuffer;
+}
+
+static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd);
+
+#ifdef _DEBUG
+
+#define DUMP_PFD_FLAG(flag) \
+ if (pfd->dwFlags & flag) { \
+ ErrorF("%s%s", pipesym, #flag); \
+ pipesym = " | "; \
+ }
+
+static void pfdOut(const PIXELFORMATDESCRIPTOR *pfd)
+{
+ const char *pipesym = ""; /* will be set after first flag dump */
+ ErrorF("PIXELFORMATDESCRIPTOR:\n");
+ ErrorF("nSize = %u\n", pfd->nSize);
+ ErrorF("nVersion = %u\n", pfd->nVersion);
+ ErrorF("dwFlags = %lu = {", pfd->dwFlags);
+ DUMP_PFD_FLAG(PFD_DOUBLEBUFFER);
+ DUMP_PFD_FLAG(PFD_STEREO);
+ DUMP_PFD_FLAG(PFD_DRAW_TO_WINDOW);
+ DUMP_PFD_FLAG(PFD_DRAW_TO_BITMAP);
+ DUMP_PFD_FLAG(PFD_SUPPORT_GDI);
+ DUMP_PFD_FLAG(PFD_SUPPORT_OPENGL);
+ DUMP_PFD_FLAG(PFD_GENERIC_FORMAT);
+ DUMP_PFD_FLAG(PFD_NEED_PALETTE);
+ DUMP_PFD_FLAG(PFD_NEED_SYSTEM_PALETTE);
+ DUMP_PFD_FLAG(PFD_SWAP_EXCHANGE);
+ DUMP_PFD_FLAG(PFD_SWAP_COPY);
+ DUMP_PFD_FLAG(PFD_SWAP_LAYER_BUFFERS);
+ DUMP_PFD_FLAG(PFD_GENERIC_ACCELERATED);
+ DUMP_PFD_FLAG(PFD_DEPTH_DONTCARE);
+ DUMP_PFD_FLAG(PFD_DOUBLEBUFFER_DONTCARE);
+ DUMP_PFD_FLAG(PFD_STEREO_DONTCARE);
+ ErrorF("}\n");
+
+ ErrorF("iPixelType = %hu = %s\n", pfd->iPixelType,
+ (pfd->iPixelType == PFD_TYPE_RGBA ? "PFD_TYPE_RGBA" : "PFD_TYPE_COLORINDEX"));
+ ErrorF("cColorBits = %hhu\n", pfd->cColorBits);
+ ErrorF("cRedBits = %hhu\n", pfd->cRedBits);
+ ErrorF("cRedShift = %hhu\n", pfd->cRedShift);
+ ErrorF("cGreenBits = %hhu\n", pfd->cGreenBits);
+ ErrorF("cGreenShift = %hhu\n", pfd->cGreenShift);
+ ErrorF("cBlueBits = %hhu\n", pfd->cBlueBits);
+ ErrorF("cBlueShift = %hhu\n", pfd->cBlueShift);
+ ErrorF("cAlphaBits = %hhu\n", pfd->cAlphaBits);
+ ErrorF("cAlphaShift = %hhu\n", pfd->cAlphaShift);
+ ErrorF("cAccumBits = %hhu\n", pfd->cAccumBits);
+ ErrorF("cAccumRedBits = %hhu\n", pfd->cAccumRedBits);
+ ErrorF("cAccumGreenBits = %hhu\n", pfd->cAccumGreenBits);
+ ErrorF("cAccumBlueBits = %hhu\n", pfd->cAccumBlueBits);
+ ErrorF("cAccumAlphaBits = %hhu\n", pfd->cAccumAlphaBits);
+ ErrorF("cDepthBits = %hhu\n", pfd->cDepthBits);
+ ErrorF("cStencilBits = %hhu\n", pfd->cStencilBits);
+ ErrorF("cAuxBuffers = %hhu\n", pfd->cAuxBuffers);
+ ErrorF("iLayerType = %hhu\n", pfd->iLayerType);
+ ErrorF("bReserved = %hhu\n", pfd->bReserved);
+ ErrorF("dwLayerMask = %lu\n", pfd->dwLayerMask);
+ ErrorF("dwVisibleMask = %lu\n", pfd->dwVisibleMask);
+ ErrorF("dwDamageMask = %lu\n", pfd->dwDamageMask);
+ ErrorF("\n");
+}
+
+static const char *
+visual_class_name(int cls)
+{
+ switch (cls) {
+ case GLX_STATIC_COLOR:
+ return "StaticColor";
+ case GLX_PSEUDO_COLOR:
+ return "PseudoColor";
+ case GLX_STATIC_GRAY:
+ return "StaticGray";
+ case GLX_GRAY_SCALE:
+ return "GrayScale";
+ case GLX_TRUE_COLOR:
+ return "TrueColor";
+ case GLX_DIRECT_COLOR:
+ return "DirectColor";
+ default:
+ return "-none-";
+ }
+}
+
+static const char *
+swap_method_name(int mthd)
+{
+ switch (mthd)
+ {
+ case GLX_SWAP_EXCHANGE_OML:
+ return "xchg";
+ case GLX_SWAP_COPY_OML:
+ return "copy";
+ case GLX_SWAP_UNDEFINED_OML:
+ return " ";
+ default:
+ return "????";
+ }
+}
+
+static void
+fbConfigsDump(unsigned int n, __GLXconfig *c)
+{
+ ErrorF("%d fbConfigs\n", n);
+ ErrorF("pxf vis fb render Ste aux accum MS drawable Group/\n");
+ ErrorF("idx ID ID VisualType Depth Lvl RGB CI DB Swap reo R G B A Z S buf AR AG AB AA bufs num W P Pb Float Trans Caveat\n");
+ ErrorF("-----------------------------------------------------------------------------------------------------------------------------\n");
+
+ while (c != NULL)
+ {
+ unsigned int i = ((GLXWinConfig *)c)->pixelFormatIndex;
+
+ ErrorF("%3d %2x %2x "
+ "%-11s"
+ " %3d %3d %s %s %s %s %s "
+ "%2d %2d %2d %2d "
+ "%2d %2d "
+ "%2d "
+ "%2d %2d %2d %2d"
+ " %2d %2d"
+ " %s %s %s "
+ " %s "
+ " %s "
+ " %d %s"
+ "\n",
+ i, c->visualID, c->fbconfigID,
+ visual_class_name(c->visualType),
+ c->rgbBits ? c->rgbBits : c->indexBits,
+ c->level,
+ (c->renderType & GLX_RGBA_BIT) ? "y" : ".",
+ (c->renderType & GLX_COLOR_INDEX_BIT) ? "y" : ".",
+ c->doubleBufferMode ? "y" : ".",
+ swap_method_name(c->swapMethod),
+ c->stereoMode ? "y" : ".",
+ c->redBits, c->greenBits, c->blueBits, c->alphaBits,
+ c->depthBits, c->stencilBits,
+ c->numAuxBuffers,
+ c->accumRedBits, c->accumGreenBits, c->accumBlueBits, c->accumAlphaBits,
+ c->sampleBuffers, c->samples,
+ (c->drawableType & GLX_WINDOW_BIT) ? "y" : ".",
+ (c->drawableType & GLX_PIXMAP_BIT) ? "y" : ".",
+ (c->drawableType & GLX_PBUFFER_BIT) ? "y" : ".",
+ ".",
+ (c->transparentPixel != GLX_NONE_EXT) ? "y" : ".",
+ c->visualSelectGroup, (c->visualRating == GLX_SLOW_VISUAL_EXT) ? "*" : " ");
+
+ c = c->next;
+ }
+}
+#endif
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Forward declarations
+ */
+
+static __GLXscreen *glxWinScreenProbe(ScreenPtr pScreen);
+static __GLXcontext *glxWinCreateContext(__GLXscreen *screen,
+ __GLXconfig *modes,
+ __GLXcontext *baseShareContext);
+static __GLXdrawable *glxWinCreateDrawable(__GLXscreen *screen,
+ DrawablePtr pDraw,
+ int type,
+ XID drawId,
+ __GLXconfig *conf);
+
+static Bool glxWinRealizeWindow(WindowPtr pWin);
+static Bool glxWinUnrealizeWindow(WindowPtr pWin);
+static Bool glxWinDestroyWindow(WindowPtr pWin);
+static void glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc);
+static Bool glxWinPositionWindow(WindowPtr pWindow, int x, int y);
+
+static HDC glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HWND *hwnd);
+static void glxWinReleaseDC(HWND hwnd, HDC hdc, __GLXWinDrawable *draw);
+
+static void glxWinCreateConfigs(HDC dc, glxWinScreen *screen);
+static void glxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen);
+static int fbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int drawableTypeOverride);
+static int fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig *mode, int drawableTypeOverride, glxWinScreen *winScreen);
+
+/* ---------------------------------------------------------------------- */
+/*
+ * The GLX provider
+ */
+
+__GLXprovider __glXWGLProvider = {
+ glxWinScreenProbe,
+ "Win32 native WGL",
+ NULL
+};
+
+void
+glxWinPushNativeProvider(void)
+{
+ if (g_fNativeGl)
+ GlxPushProvider(&__glXWGLProvider);
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Screen functions
+ */
+
+static void
+glxWinScreenDestroy(__GLXscreen *screen)
+{
+ GLWIN_DEBUG_MSG("glxWinScreenDestroy(%p)", screen);
+ __glXScreenDestroy(screen);
+ xfree(screen);
+}
+
+static int
+glxWinScreenSwapInterval(__GLXdrawable *drawable, int interval)
+{
+ BOOL ret = wglSwapIntervalEXTWrapper(interval);
+ if (!ret)
+ {
+ ErrorF("wglSwapIntervalEXT interval %d failed:%s\n", interval, glxWinErrorMessage());
+ }
+ return ret;
+}
+
+static LRESULT CALLBACK GlxWindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+{
+ if (uMsg== WM_NCHITTEST)
+ {
+ return HTTRANSPARENT;
+ }
+ else
+ return DefWindowProc(hwnd, uMsg, wParam, lParam);
+}
+
+/* This is called by GlxExtensionInit() asking the GLX provider if it can handle the screen... */
+static __GLXscreen *
+glxWinScreenProbe(ScreenPtr pScreen)
+{
+ glxWinScreen *screen;
+ const char *gl_extensions;
+ const char *wgl_extensions;
+ HWND hwnd;
+ HDC hdc;
+ HGLRC hglrc;
+
+ GLWIN_DEBUG_MSG("glxWinScreenProbe");
+
+#ifdef _DEBUG
+ glxWinInitDebugSettings();
+#endif
+
+ if (pScreen == NULL)
+ return NULL;
+
+ if (!winCheckScreenAiglxIsSupported(pScreen))
+ {
+ LogMessage(X_ERROR,"AIGLX: No native OpenGL in modes with a root window\n");
+ return NULL;
+ }
+
+ screen = xcalloc(1, sizeof(glxWinScreen));
+
+ if (NULL == screen)
+ return NULL;
+
+ /* Wrap RealizeWindow, UnrealizeWindow and CopyWindow on this screen */
+ screen->RealizeWindow = pScreen->RealizeWindow;
+ pScreen->RealizeWindow = glxWinRealizeWindow;
+ screen->UnrealizeWindow = pScreen->UnrealizeWindow;
+ pScreen->UnrealizeWindow = glxWinUnrealizeWindow;
+ screen->CopyWindow = pScreen->CopyWindow;
+ pScreen->CopyWindow = glxWinCopyWindow;
+ screen->PositionWindow = pScreen->PositionWindow;
+ pScreen->PositionWindow = glxWinPositionWindow;
+ screen->DestroyWindow = pScreen->DestroyWindow;
+ pScreen->DestroyWindow = glxWinDestroyWindow;
+
+ /* Dump out some useful information about the native renderer */
+
+ // create window class
+ {
+ static wATOM glTestWndClass = 0;
+ if (glTestWndClass == 0)
+ {
+ WNDCLASSEX wc;
+ glTestWndClass=1;
+ wc.cbSize = sizeof(WNDCLASSEX);
+ wc.style = CS_OWNDC ;
+ wc.lpfnWndProc = GlxWindowProc;
+ wc.cbClsExtra = 0;
+ wc.cbWndExtra = 0;
+ wc.hInstance = GetModuleHandle(NULL);
+ wc.hIcon = 0;
+ wc.hCursor = 0;
+ wc.hbrBackground = 0;
+ wc.lpszMenuName = NULL;
+ wc.lpszClassName = WIN_GL_WINDOW_CLASS;
+ wc.hIconSm = 0;
+ RegisterClassEx (&wc);
+ }
+ }
+
+ // create an invisible window for a scratch DC
+ hwnd = CreateWindowExA(0,
+ WIN_GL_WINDOW_CLASS,
+ "XWin GL Renderer Capabilities Test Window",
+ 0, 0, 0, 0, 0, NULL, NULL, GetModuleHandle(NULL), NULL);
+ if (hwnd == NULL)
+ LogMessage(X_ERROR,"AIGLX: Couldn't create a window for render capabilities testing\n");
+
+ hdc = GetDC(hwnd);
+
+ // we must set a pixel format before we can create a context, just use the first one...
+ SetPixelFormat(hdc, 1, NULL);
+ hglrc = wglCreateContext(hdc);
+ wglMakeCurrent(hdc, hglrc);
+
+ // initialize wgl extension proc pointers (don't call them before here...)
+ // (but we need to have a current context for them to be resolvable)
+ wglResolveExtensionProcs();
+
+ winDebug("GL_VERSION: %s\n", glGetStringWrapperNonstatic(GL_VERSION));
+ winDebug("GL_VENDOR: %s\n", glGetStringWrapperNonstatic(GL_VENDOR));
+ winDebug("GL_RENDERER: %s\n", glGetStringWrapperNonstatic(GL_RENDERER));
+ gl_extensions = (const char *)glGetStringWrapperNonstatic(GL_EXTENSIONS);
+ winDebug("GL_EXTENSIONS: %s\n", gl_extensions);
+ wgl_extensions = wglGetExtensionsStringARBWrapper(hdc);
+ if (!wgl_extensions)
+ wgl_extensions="";
+ winDebug("WGL_EXTENSIONS:%s\n", wgl_extensions);
+
+ // Can you see the problem here? The extensions string is DC specific
+ // Different DCs for windows on a multimonitor system driven by multiple cards
+ // might have completely different capabilities. Of course, good luck getting
+ // those screens to be accelerated in XP and earlier...
+
+ {
+ // testing facility to not use any WGL extensions
+ char *envptr = getenv("GLWIN_NO_WGL_EXTENSIONS");
+ if ((envptr != NULL) && (atoi(envptr) != 0))
+ {
+ ErrorF("GLWIN_NO_WGL_EXTENSIONS is set, ignoring WGL_EXTENSIONS\n");
+ wgl_extensions = "";
+ }
+ }
+
+ {
+ Bool glx_sgi_make_current_read = FALSE;
+
+ //
+ // Based on the WGL extensions available, enable various GLX extensions
+ // XXX: make this table-driven ?
+ //
+ memset(screen->glx_enable_bits, 0, __GLX_EXT_BYTES);
+
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_info");
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_visual_rating");
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_import_context");
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_OML_swap_method");
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_fbconfig");
+
+ if (strstr(wgl_extensions, "WGL_ARB_make_current_read"))
+ {
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_make_current_read");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_make_current_read\n");
+ glx_sgi_make_current_read = TRUE;
+ }
+
+ if (strstr(gl_extensions, "GL_WIN_swap_hint"))
+ {
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_copy_sub_buffer");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_MESA_copy_sub_buffer\n");
+ }
+
+ if (strstr(wgl_extensions, "WGL_EXT_swap_control"))
+ {
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_SGI_swap_control");
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_MESA_swap_control");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_SGI_swap_control and GLX_MESA_swap_control\n");
+ }
+
+/* // Hmm? screen->texOffset */
+/* if (strstr(wgl_extensions, "WGL_ARB_render_texture")) */
+/* { */
+/* __glXEnableExtension(screen->glx_enable_bits, "GLX_EXT_texture_from_pixmap"); */
+/* LogMessage(X_INFO, "AIGLX: GLX_EXT_texture_from_pixmap backed by buffer objects\n"); */
+/* screen->has_WGL_ARB_render_texture = TRUE; */
+/* } */
+
+ if (strstr(wgl_extensions, "WGL_ARB_pbuffer"))
+ {
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIX_pbuffer");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_SGIX_pbuffer\n");
+ screen->has_WGL_ARB_pbuffer = TRUE;
+ }
+
+ if (strstr(wgl_extensions, "WGL_ARB_multisample"))
+ {
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_ARB_multisample");
+ __glXEnableExtension(screen->glx_enable_bits, "GLX_SGIS_multisample");
+ LogMessage(X_INFO, "AIGLX: enabled GLX_ARB_multisample and GLX_SGIS_multisample\n");
+ screen->has_WGL_ARB_multisample = TRUE;
+ }
+
+ screen->base.destroy = glxWinScreenDestroy;
+ screen->base.createContext = glxWinCreateContext;
+ screen->base.createDrawable = glxWinCreateDrawable;
+ screen->base.swapInterval = glxWinScreenSwapInterval;
+ screen->base.hyperpipeFuncs = NULL;
+ screen->base.swapBarrierFuncs = NULL;
+ screen->base.pScreen = pScreen;
+
+ if (strstr(wgl_extensions, "WGL_ARB_pixel_format"))
+ {
+ glxWinCreateConfigsExt(hdc, screen);
+ screen->has_WGL_ARB_pixel_format = TRUE;
+ }
+ else
+ {
+ glxWinCreateConfigs(hdc, screen);
+ screen->has_WGL_ARB_pixel_format = FALSE;
+ }
+ // Initializes screen->base.fbconfigs and screen->base.numFBConfigs
+
+ /* These will be set by __glXScreenInit */
+ screen->base.visuals = NULL;
+ screen->base.numVisuals = 0;
+
+ __glXScreenInit(&screen->base, pScreen);
+
+#ifdef _DEBUG
+ // dump out fbConfigs now fbConfigIds and visualIDs have been assigned
+ fbConfigsDump(screen->base.numFBConfigs, screen->base.fbconfigs);
+#endif
+
+ // Override the GL extensions string set by __glXScreenInit()
+ screen->base.GLextensions = xstrdup(gl_extensions);
+
+ // Generate the GLX extensions string (overrides that set by __glXScreenInit())
+ {
+ unsigned int buffer_size = __glXGetExtensionString(screen->glx_enable_bits, NULL);
+ if (buffer_size > 0)
+ {
+ if (screen->base.GLXextensions != NULL)
+ {
+ xfree(screen->base.GLXextensions);
+ }
+
+ screen->base.GLXextensions = xnfalloc(buffer_size);
+ __glXGetExtensionString(screen->glx_enable_bits, screen->base.GLXextensions);
+ }
+ }
+
+ //
+ // Override the GLX version (__glXScreenInit() sets it to "1.2")
+ // if we have all the needed extensionsto operate as a higher version
+ //
+ // SGIX_fbconfig && SGIX_pbuffer && SGI_make_current_read -> 1.3
+ // ARB_multisample -> 1.4
+ //
+ if (screen->has_WGL_ARB_pbuffer && glx_sgi_make_current_read)
+ {
+ xfree(screen->base.GLXversion);
+
+ if (screen->has_WGL_ARB_multisample)
+ {
+ screen->base.GLXversion = xstrdup("1.4");
+ screen->base.GLXminor=4;
+ /*
+ XXX: this just controls the version string returned to glXQueryServerString()
+ there is currently no way to control the version number the server returns to
+ glXQueryVersion()...
+ */
+ }
+ else
+ {
+ screen->base.GLXversion = xstrdup("1.3");
+ screen->base.GLXminor=3;
+ }
+ LogMessage(X_INFO, "AIGLX: Set GLX version to %s\n", screen->base.GLXversion);
+ }
+ }
+
+ wglMakeCurrent(NULL, NULL);
+ wglDeleteContext(hglrc);
+ ReleaseDC(hwnd, hdc);
+ DestroyWindow(hwnd);
+
+ return &screen->base;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Window functions
+ */
+
+static Bool
+glxWinRealizeWindow(WindowPtr pWin)
+{
+ Bool result;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen);
+ winWindowPriv(pWin);
+
+ GLWIN_DEBUG_MSG("glxWinRealizeWindow");
+
+ /* Allow the window to be created (RootlessRealizeWindow is inside our wrap) */
+ pScreen->RealizeWindow = screenPriv->RealizeWindow;
+ result = pScreen->RealizeWindow(pWin);
+ pScreen->RealizeWindow = glxWinRealizeWindow;
+
+ // Check if ze need to move the window\n
+ if (pWinPriv->GlCtxWnd && pWinPriv->hWnd)
+ {
+ ShowWindow(pWinPriv->hWnd,SW_SHOW);
+ }
+ return result;
+}
+
+
+static void
+glxWinCopyWindow(WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc)
+{
+ __GLXWinDrawable *pGlxDraw;
+ ScreenPtr pScreen = pWindow->drawable.pScreen;
+ glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen);
+
+ GLWIN_TRACE_MSG("glxWinCopyWindow pWindow %p", pWindow);
+
+ dixLookupResourceByType((pointer) &pGlxDraw, pWindow->drawable.id, __glXDrawableRes,
+ NullClient, DixUnknownAccess);
+
+
+ /*
+ Discard any CopyWindow requests if a GL drawing context is pointing at the window
+
+ For regions which are being drawn by GL, the shadow framebuffer doesn't have the
+ correct bits, so we wish to avoid shadow framebuffer damage occuring, which will
+ cause those incorrect bits to be transferred to the display....
+ */
+ if (pGlxDraw && pGlxDraw->drawContext)
+ {
+ GLWIN_DEBUG_MSG("glxWinCopyWindow: discarding");
+ return;
+ }
+
+ GLWIN_DEBUG_MSG("glxWinCopyWindow - passing to hw layer");
+
+ pScreen->CopyWindow = screenPriv->CopyWindow;
+ pScreen->CopyWindow(pWindow, ptOldOrg, prgnSrc);
+ pScreen->CopyWindow = glxWinCopyWindow;
+
+}
+
+static Bool
+glxWinPositionWindow(WindowPtr pWin, int x, int y)
+{
+ Bool result;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ glxWinScreen *screenPriv = (glxWinScreen *) glxGetScreen(pScreen);
+ winWindowPriv(pWin);
+
+ pScreen->PositionWindow = screenPriv->PositionWindow;
+ result = pScreen->PositionWindow(pWin, x, y);
+ pScreen->PositionWindow = glxWinPositionWindow;
+
+ if (pWinPriv->GlCtxWnd && pWinPriv->hWnd)
+ {
+ MoveWindow(pWinPriv->hWnd,
+ pWin->drawable.x,
+ pWin->drawable.y,
+ pWin->drawable.width,
+ pWin->drawable.height,
+ FALSE);
+ }
+ return result;
+}
+
+
+static Bool
+glxWinUnrealizeWindow(WindowPtr pWin)
+{
+ Bool result;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ glxWinScreen *screenPriv = (glxWinScreen *)glxGetScreen(pScreen);
+ winWindowPriv(pWin);
+
+ GLWIN_DEBUG_MSG("glxWinUnrealizeWindow");
+
+ pScreen->UnrealizeWindow = screenPriv->UnrealizeWindow;
+ result = pScreen->UnrealizeWindow(pWin);
+ pScreen->UnrealizeWindow = glxWinUnrealizeWindow;
+
+ if (pWinPriv->GlCtxWnd && pWinPriv->hWnd)
+ ShowWindow(pWinPriv->hWnd,SW_HIDE);
+
+ return result;
+}
+
+static Bool
+glxWinDestroyWindow(WindowPtr pWin)
+{
+ Bool result;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ glxWinScreen *screenPriv = (glxWinScreen *)glxGetScreen(pScreen);
+ winWindowPriv(pWin);
+
+ GLWIN_DEBUG_MSG("glxWinDestroyWindow");
+
+ if (pWinPriv->GlCtxWnd && pWinPriv->hWnd)
+ {
+ __GLXWinDrawable *pGlxDraw;
+
+ dixLookupResourceByType((pointer) &pGlxDraw, pWin->drawable.id, __glXDrawableRes, NullClient, DixUnknownAccess);
+
+ if (pGlxDraw && pGlxDraw->drawContext)
+ {
+ if (pGlxDraw->drawContext->hwnd!=pWinPriv->hWnd)
+ ErrorF("Wrong assumption\n");
+ glxWinReleaseDC(pGlxDraw->drawContext->hwnd, pGlxDraw->drawContext->hDC, pGlxDraw);
+ pGlxDraw->drawContext->hDC=NULL;
+ pGlxDraw->drawContext->hwnd=NULL;
+ }
+ DestroyWindow(pWinPriv->hWnd);
+ pWinPriv->hWnd=NULL;
+ pWinPriv->GlCtxWnd=0;
+ }
+
+ pScreen->DestroyWindow = screenPriv->DestroyWindow;
+ result = pScreen->DestroyWindow(pWin);
+ pScreen->DestroyWindow = glxWinDestroyWindow;
+
+ return result;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Drawable functions
+ */
+
+static GLboolean
+glxWinDrawableSwapBuffers(ClientPtr client, __GLXdrawable *base)
+{
+ BOOL ret;
+ __GLXWinDrawable *draw = (__GLXWinDrawable *)base;
+
+ /* Swap buffers on the last active context for drawing on the drawable */
+ if (draw->drawContext == NULL)
+ {
+ GLWIN_TRACE_MSG("glxWinSwapBuffers - no context for drawable");
+ return GL_FALSE;
+ }
+
+ GLWIN_TRACE_MSG("glxWinSwapBuffers on drawable %p, last context %p (native ctx %p)", base, draw->drawContext, draw->drawContext->ctx);
+
+ /*
+ draw->drawContext->base.drawPriv will not be set if the context is not current anymore,
+ but if it is, it should point to this drawable....
+ */
+ assert((draw->drawContext->base.drawPriv == NULL) || (draw->drawContext->base.drawPriv == base));
+
+ ret = SwapBuffers(draw->drawContext->hDC);
+
+ if (!ret)
+ {
+ ErrorF("wglSwapBuffers failed: %s\n", glxWinErrorMessage());
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+static void
+glxWinDrawableCopySubBuffer(__GLXdrawable *drawable,
+ int x, int y, int w, int h)
+{
+ glAddSwapHintRectWINWrapperNonstatic(x, y, w, h);
+ glxWinDrawableSwapBuffers(NULL,drawable);
+}
+
+static void
+glxWinDrawableDestroy(__GLXdrawable *base)
+{
+ __GLXWinDrawable *glxPriv = (__GLXWinDrawable *)base;
+
+ if (glxPriv->drawContext && (__glXLastContext == &((glxPriv->drawContext)->base)))
+ {
+ // if this context is current and has unflushed commands, say we have flushed them
+ // (don't actually flush them, the window is going away anyhow, and an implict flush occurs
+ // on the next context change)
+ // (GLX core considers it an error when we try to select a new current context if the old one
+ // has unflushed commands, but the window has disappeared..)
+ __GLX_NOTE_FLUSHED_CMDS(__glXLastContext);
+ __glXLastContext = NULL;
+ }
+
+ if (glxPriv->hPbuffer)
+ if (!wglDestroyPbufferARBWrapper(glxPriv->hPbuffer))
+ {
+ ErrorF("wglDestroyPbufferARB failed: %s\n", glxWinErrorMessage());
+ }
+
+ if (glxPriv->dibDC)
+ {
+ // restore the default DIB
+ SelectObject(glxPriv->dibDC, glxPriv->hOldDIB);
+
+ if (!DeleteDC(glxPriv->dibDC))
+ {
+ ErrorF("DeleteDC failed: %s\n", glxWinErrorMessage());
+ }
+ }
+
+ if (glxPriv->hDIB)
+ {
+ if (!DeleteObject(glxPriv->hDIB))
+ {
+ ErrorF("DeleteObject failed: %s\n", glxWinErrorMessage());
+ }
+
+ ((PixmapPtr)glxPriv->base.pDraw)->devPrivate.ptr = glxPriv->pOldBits;
+ }
+
+ GLWIN_DEBUG_MSG("glxWinDestroyDrawable");
+ xfree(glxPriv);
+}
+
+static __GLXdrawable *
+glxWinCreateDrawable(__GLXscreen *screen,
+ DrawablePtr pDraw,
+ int type,
+ XID drawId,
+ __GLXconfig *conf)
+{
+ __GLXWinDrawable *glxPriv;
+
+ glxPriv = xcalloc(1,sizeof(*glxPriv));
+
+ if (glxPriv == NULL)
+ return NULL;
+
+ if(!__glXDrawableInit(&glxPriv->base, screen, pDraw, type, drawId, conf)) {
+ xfree(glxPriv);
+ return NULL;
+ }
+
+ glxPriv->base.destroy = glxWinDrawableDestroy;
+ glxPriv->base.swapBuffers = glxWinDrawableSwapBuffers;
+ glxPriv->base.copySubBuffer = glxWinDrawableCopySubBuffer;
+ // glxPriv->base.waitX what are these for?
+ // glxPriv->base.waitGL
+
+ GLWIN_DEBUG_MSG("glxWinCreateDrawable %p", glxPriv);
+
+ return &glxPriv->base;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Texture functions
+ */
+
+static
+int glxWinBindTexImage(__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *pixmap)
+{
+ ErrorF("glxWinBindTexImage: not implemented\n");
+ return FALSE;
+}
+
+static
+int glxWinReleaseTexImage(__GLXcontext *baseContext,
+ int buffer,
+ __GLXdrawable *pixmap)
+{
+ ErrorF(" glxWinReleaseTexImage: not implemented\n");
+ return FALSE;
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Lazy update context implementation
+ *
+ * WGL contexts are created for a specific HDC, so we cannot create the WGL
+ * context in glxWinCreateContext(), we must defer creation until the context
+ * is actually used on a specifc drawable which is connected to a native window,
+ * pbuffer or DIB
+ *
+ * The WGL context may be used on other, compatible HDCs, so we don't need to
+ * recreate it for every new native window
+ *
+ * XXX: I wonder why we can't create the WGL context on the screen HDC ?
+ * Basically we assume all HDCs are compatible at the moment: if they are not
+ * we are in a muddle, there was some code in the old implementation to attempt
+ * to transparently migrate a context to a new DC by copying state and sharing
+ * lists with the old one...
+ */
+
+static void
+glxWinSetPixelFormat(__GLXWinContext *gc, HDC hdc, int bppOverride, int drawableTypeOverride)
+{
+ __GLXscreen *screen = gc->base.pGlxScreen;
+ glxWinScreen *winScreen = (glxWinScreen *)screen;
+
+ __GLXconfig *config = gc->base.config;
+ GLXWinConfig *winConfig = (GLXWinConfig *)config;
+
+ GLWIN_DEBUG_MSG("glxWinSetPixelFormat: pixelFormatIndex %d", winConfig->pixelFormatIndex);
+
+ /*
+ Normally, we can just use the the pixelFormatIndex corresponding
+ to the fbconfig which has been specified by the client
+ */
+
+ if (!((bppOverride && (bppOverride != (config->redBits + config->greenBits + config->blueBits) ))
+ || ((config->drawableType & drawableTypeOverride) == 0)))
+ {
+ if (!SetPixelFormat(hdc, winConfig->pixelFormatIndex, NULL))
+ {
+ ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ return;
+ }
+
+ /*
+ However, in certain special cases this pixel format will be incompatible with the
+ use we are going to put it to, so we need to re-evaluate the pixel format to use:
+
+ 1) When PFD_DRAW_TO_BITMAP is set, ChoosePixelFormat() always returns a format with
+ the cColorBits we asked for, so we need to ensure it matches the bpp of the bitmap
+
+ 2) Applications may assume that visuals selected with glXChooseVisual() work with
+ pixmap drawables (there is no attribute to explicitly query for pixmap drawable
+ support as there is for glXChooseFBConfig())
+ (it's arguable this is an error in the application, but we try to make it work)
+
+ pixmap rendering is always slow for us, so we don't want to choose those visuals
+ by default, but if the actual drawable type we're trying to select the context
+ on (drawableTypeOverride) isn't supported by the selected fbConfig, reconsider
+ and see if we can find a suitable one...
+ */
+ ErrorF("glxWinSetPixelFormat: having second thoughts: cColorbits %d, bppOveride %d; config->drawableType %d, drawableTypeOverride %d\n",
+ (config->redBits + config->greenBits + config->blueBits), bppOverride, config->drawableType, drawableTypeOverride);
+
+ if (!winScreen->has_WGL_ARB_pixel_format)
+ {
+ PIXELFORMATDESCRIPTOR pfd;
+ int pixelFormat;
+
+ /* convert fbConfig to PFD */
+ if (fbConfigToPixelFormat(gc->base.config, &pfd, drawableTypeOverride))
+ {
+ ErrorF("glxWinSetPixelFormat: fbConfigToPixelFormat failed\n");
+ return;
+ }
+
+#ifdef _DEBUG
+ if (glxWinDebugSettings.dumpPFD)
+ pfdOut(&pfd);
+#endif
+
+ if (bppOverride)
+ {
+ GLWIN_DEBUG_MSG("glxWinSetPixelFormat: Forcing bpp from %d to %d\n", pfd.cColorBits, bppOverride);
+ pfd.cColorBits = bppOverride;
+ }
+
+ pixelFormat = ChoosePixelFormat(hdc, &pfd);
+ if (pixelFormat == 0)
+ {
+ ErrorF("ChoosePixelFormat error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ GLWIN_DEBUG_MSG("ChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat);
+ ErrorF("ChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex);
+
+ if (!SetPixelFormat(hdc, pixelFormat, &pfd))
+ {
+ ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
+ return;
+ }
+ }
+ else
+ {
+ int pixelFormat = fbConfigToPixelFormatIndex(hdc, gc->base.config, drawableTypeOverride, winScreen);
+ if (pixelFormat == 0)
+ {
+ ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d", pixelFormat);
+ ErrorF("wglChoosePixelFormat: chose pixelFormatIndex %d (rather than %d as originally planned)\n", pixelFormat, winConfig->pixelFormatIndex);
+
+ if (!SetPixelFormat(hdc, pixelFormat, NULL))
+ {
+ ErrorF("SetPixelFormat error: %s\n", glxWinErrorMessage());
+ return;
+ }
+ }
+}
+
+static HDC
+glxWinMakeDC(__GLXWinContext *gc, __GLXWinDrawable *draw, HWND *hwnd)
+{
+ HDC hdc = NULL;
+ *hwnd = NULL;
+
+ if (draw == NULL)
+ {
+ GLWIN_TRACE_MSG("No drawable for context %p (native ctx %p)", gc, gc->ctx);
+ return NULL;
+ }
+
+ switch (draw->base.type)
+ {
+ case GLX_DRAWABLE_WINDOW:
+ {
+ winWindowInfoRec winInfo;
+ WindowPtr pWin;
+
+ pWin = (WindowPtr) draw->base.pDraw;
+ if (pWin == NULL)
+ {
+ GLWIN_TRACE_MSG("for drawable %p, no WindowPtr", pWin);
+ return NULL;
+ }
+
+ winGetWindowInfo(pWin, &winInfo);
+ *hwnd = winInfo.hwnd;
+
+ if (winInfo.hwnd == NULL)
+ {
+ ErrorF("No HWND error: %s\n", glxWinErrorMessage());
+ return NULL;
+ }
+
+ hdc = GetDC(winInfo.hwnd);
+
+ if (hdc == NULL)
+ ErrorF("GetDC error: %s: hwnd %x, gc %p, gc->ctx %p ,gc->hwnd %p\n", glxWinErrorMessage(), winInfo.hwnd, gc, gc->ctx, gc->hwnd);
+
+ if (gc->hDC)
+ {
+ glxWinReleaseDC(gc->hwnd, gc->hDC, draw);
+ gc->hDC=NULL;
+ }
+#ifdef _DEBUG
+ if (glxWinDebugSettings.enableTrace)
+ GLWIN_DEBUG_HWND(winInfo.hwnd);
+
+ GLWIN_TRACE_MSG("for context %p (native ctx %p), hWnd changed from %p to %p", gc, gc->ctx, gc->hwnd, winInfo.hwnd);
+#endif
+ gc->hwnd = winInfo.hwnd;
+
+ /* Check if we need to set the pixelformat */
+ {
+ winWindowPriv(pWin);
+ if (!pWinPriv->PixelFormatSet)
+ {
+ pWinPriv->PixelFormatSet=TRUE;
+ /* We must select a pixelformat, but SetPixelFormat can only be called once for a window... */
+ glxWinSetPixelFormat(gc, hdc, 0, GLX_WINDOW_BIT);
+ }
+ }
+ }
+ break;
+
+ case GLX_DRAWABLE_PBUFFER:
+ {
+ hdc = wglGetPbufferDCARBWrapper(draw->hPbuffer);
+
+ if (hdc == NULL)
+ ErrorF("GetDC (pbuffer) error: %s\n", glxWinErrorMessage());
+ }
+ break;
+
+ case GLX_DRAWABLE_PIXMAP:
+ {
+ hdc = draw->dibDC;
+#ifdef _DEBUG
+ if (glxWinDebugSettings.dumpDC)
+ GLWIN_DEBUG_MSG("Got PIXMAP HDC %p for window %p", hdc, *hwnd);
+#endif
+ }
+ break;
+
+ default:
+ {
+ ErrorF("glxWinMakeDC: tried to makeDC for unhandled drawable type %d\n", draw->base.type);
+ }
+ }
+
+#ifdef _DEBUG
+ if (glxWinDebugSettings.dumpDC)
+ GLWIN_HDC_DEBUG_MSG("Got HDC %p for window %p", hdc, *hwnd);
+#endif
+
+ return hdc;
+}
+
+static void
+glxWinReleaseDC(HWND hwnd, HDC hdc,__GLXWinDrawable *draw)
+{
+ switch (draw->base.type)
+ {
+ case GLX_DRAWABLE_WINDOW:
+ {
+ ReleaseDC(hwnd, hdc);
+ }
+ break;
+
+ case GLX_DRAWABLE_PBUFFER:
+ {
+ if (!wglReleasePbufferDCARBWrapper(draw->hPbuffer, hdc))
+ {
+ ErrorF("wglReleasePbufferDCARB error: %s\n", glxWinErrorMessage());
+ }
+ }
+ break;
+
+ case GLX_DRAWABLE_PIXMAP:
+ {
+ // don't release DC, the memory DC lives as long as the bitmap
+
+ // We must ensure that all GDI drawing into the bitmap has completed
+ // in case we subsequently access the bits from it
+ GdiFlush();
+ }
+ break;
+
+ default:
+ {
+ ErrorF("glxWinReleaseDC: tried to releaseDC for unhandled drawable type %d\n", draw->base.type);
+ }
+ }
+}
+
+static void
+glxWinDeferredCreateContext(__GLXWinContext *gc, __GLXWinDrawable *draw)
+{
+ HWND hwnd;
+ GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attach context %p to drawable %p", gc, draw);
+
+ switch (draw->base.type)
+ {
+ case GLX_DRAWABLE_WINDOW:
+ {
+ winWindowInfoRec winInfo;
+ WindowPtr pWin = (WindowPtr) draw->base.pDraw;
+
+ if (!(gc->base.config->drawableType & GLX_WINDOW_BIT))
+ {
+ ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_WINDOW_BIT to a GLX_DRAWABLE_WINDOW drawable\n");
+ }
+
+ if (pWin == NULL)
+ {
+ GLWIN_DEBUG_MSG("Deferring until X window is created");
+ return;
+ }
+
+ GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: pWin %p", pWin);
+
+ winGetWindowInfo(pWin, &winInfo);
+ if (winInfo.hwnd == NULL)
+ {
+ GLWIN_DEBUG_MSG("Deferring until native window is created");
+ return;
+ }
+ }
+ break;
+
+ case GLX_DRAWABLE_PBUFFER:
+ {
+ if (draw->hPbuffer == NULL)
+ {
+ __GLXscreen *screen;
+ glxWinScreen *winScreen;
+ int pixelFormat;
+ // XXX: which DC are supposed to use???
+ HDC screenDC = GetDC(NULL);
+
+ if (!(gc->base.config->drawableType & GLX_PBUFFER_BIT))
+ {
+ ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PBUFFER_BIT to a GLX_DRAWABLE_PBUFFER drawable\n");
+ }
+
+ screen = gc->base.pGlxScreen;
+ winScreen = (glxWinScreen *)screen;
+
+ pixelFormat = fbConfigToPixelFormatIndex(screenDC, gc->base.config, GLX_DRAWABLE_PBUFFER, winScreen);
+ if (pixelFormat == 0)
+ {
+ ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ draw->hPbuffer = wglCreatePbufferARBWrapper(screenDC, pixelFormat, draw->base.pDraw->width, draw->base.pDraw->height, NULL);
+ ReleaseDC(NULL, screenDC);
+
+ if (draw->hPbuffer == NULL)
+ {
+ ErrorF("wglCreatePbufferARBWrapper error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: pBuffer %p created for drawable %p", draw->hPbuffer, draw);
+ }
+ }
+ break;
+
+ case GLX_DRAWABLE_PIXMAP:
+ {
+ if (draw->dibDC == NULL)
+ {
+ BITMAPINFOHEADER bmpHeader;
+ void *pBits;
+
+ ZeroMemory(&bmpHeader,sizeof(bmpHeader));
+ bmpHeader.biSize=sizeof(bmpHeader);
+ bmpHeader.biWidth=draw->base.pDraw->width;
+ bmpHeader.biHeight=draw->base.pDraw->height;
+ bmpHeader.biPlanes=1;
+ bmpHeader.biBitCount=draw->base.pDraw->bitsPerPixel;
+ bmpHeader.biCompression=BI_RGB;
+
+ if (!(gc->base.config->drawableType & GLX_PIXMAP_BIT))
+ {
+ ErrorF("glxWinDeferredCreateContext: tried to attach a context whose fbConfig doesn't have drawableType GLX_PIXMAP_BIT to a GLX_DRAWABLE_PIXMAP drawable\n");
+ }
+
+ draw->dibDC = CreateCompatibleDC(NULL);
+ if (draw->dibDC == NULL)
+ {
+ ErrorF("CreateCompatibleDC error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ draw->hDIB = CreateDIBSection(draw->dibDC, (BITMAPINFO *)&bmpHeader, DIB_RGB_COLORS, &pBits, 0, 0);
+ if (draw->dibDC == NULL)
+ {
+ ErrorF("CreateDIBSection error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ // XXX: CreateDIBSection insists on allocating the bitmap memory for us, so we're going to
+ // need some jiggery pokery to point the underlying X Drawable's bitmap at the same set of bits
+ // so that they can be read with XGetImage as well as glReadPixels, assuming the formats are
+ // even compatible ...
+ draw->pOldBits = ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr;
+ ((PixmapPtr)draw->base.pDraw)->devPrivate.ptr = pBits;
+
+ // Select the DIB into the DC
+ draw->hOldDIB = SelectObject(draw->dibDC, draw->hDIB);
+ if (!draw->hOldDIB)
+ {
+ ErrorF("SelectObject error: %s\n", glxWinErrorMessage());
+ }
+
+ // Set the pixel format of the bitmap
+ glxWinSetPixelFormat(gc, draw->dibDC, draw->base.pDraw->bitsPerPixel, GLX_PIXMAP_BIT);
+
+ GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: DIB bitmap %p created for drawable %p", draw->hDIB, draw);
+ }
+ }
+ break;
+
+ default:
+ {
+ ErrorF("glxWinDeferredCreateContext: tried to attach unhandled drawable type %d\n", draw->base.type);
+ return;
+ }
+ }
+
+ gc->hDC = glxWinMakeDC(gc, draw, &hwnd);
+ gc->ctx = wglCreateContext(gc->hDC);
+
+ if (gc->ctx == NULL)
+ {
+ glxWinReleaseDC(hwnd, gc->hDC, draw);
+ gc->hDC=0;
+
+ ErrorF("wglCreateContext error: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ GLWIN_DEBUG_MSG("glxWinDeferredCreateContext: attached context %p to native context %p drawable %p", gc, gc->ctx, draw);
+
+ // if the native context was created successfully, shareLists if needed
+ if (gc->ctx && gc->shareContext)
+ {
+ GLWIN_DEBUG_MSG("glxWinCreateContextReal shareLists with context %p (native ctx %p)", gc->shareContext, gc->shareContext->ctx);
+
+ if (!wglShareLists(gc->shareContext->ctx, gc->ctx))
+ {
+ ErrorF("wglShareLists error: %s\n", glxWinErrorMessage());
+ }
+ }
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Context functions
+ */
+
+
+/* Context manipulation routines should return TRUE on success, FALSE on failure */
+static int
+glxWinContextMakeCurrent(__GLXcontext *base)
+{
+ __GLXWinContext *gc = (__GLXWinContext *)base;
+ BOOL ret;
+ __GLXWinDrawable *drawPriv;
+
+#ifdef _DEBUG
+ GLWIN_TRACE_MSG("glxWinContextMakeCurrent context %p (native ctx %p)", gc, gc->ctx);
+ glWinCallDelta();
+#endif
+
+ /* Keep a note of the last active context in the drawable */
+ drawPriv = (__GLXWinDrawable *)gc->base.drawPriv;
+ drawPriv->drawContext = gc;
+
+ if (gc->ctx == NULL)
+ {
+ glxWinDeferredCreateContext(gc, drawPriv);
+ }
+
+ if (gc->ctx == NULL)
+ {
+ ErrorF("glxWinContextMakeCurrent: Native context is NULL\n");
+ return FALSE;
+ }
+
+ if ((gc->base.readPriv != NULL) && (gc->base.readPriv != gc->base.drawPriv))
+ {
+ // XXX: should only occur with WGL_ARB_make_current_read
+ /*
+ If there is a separate read drawable, create a separate read DC, and
+ use the wglMakeContextCurrent extension to make the context current drawing
+ to one DC and reading from the other
+ */
+ gc->hreadDC = glxWinMakeDC(gc, (__GLXWinDrawable *)gc->base.readPriv, &gc->hreadwnd);
+ if (gc->hreadDC == NULL)
+ {
+ ErrorF("glxWinMakeDC failed for readDC\n");
+ return FALSE;
+ }
+
+ ret = wglMakeContextCurrentARBWrapper(gc->hDC, gc->hreadDC, gc->ctx);
+ if (!ret)
+ {
+ ErrorF("wglMakeContextCurrentARBWrapper error: %s\n", glxWinErrorMessage());
+ }
+ }
+ else
+ {
+ /* Otherwise, just use wglMakeCurrent */
+ if (!gc->hDC)
+ {
+ /* It probably has been release by loseCurrent, so create it again */
+ gc->hDC = glxWinMakeDC(gc, drawPriv, &gc->hwnd);
+ }
+ ret = wglMakeCurrent(gc->hDC, gc->ctx);
+ if (!ret)
+ {
+ DWORD ErrorCode=GetLastError();
+ ErrorF("wglMakeCurrent error: %x dc %p ctx %p\n", ErrorCode,gc->hDC,gc->ctx);
+ if (!ErrorCode)
+ {
+ ErrorF("Error code was 0, assuming no error.\n");
+ ret=TRUE;
+ }
+ }
+ }
+
+ // apparently make current could fail if the context is current in a different thread,
+ // but that shouldn't be able to happen in the current server...
+
+ return ret;
+}
+
+static int
+glxWinContextLoseCurrent(__GLXcontext *base)
+{
+ BOOL ret=TRUE;
+ __GLXWinContext *gc = (__GLXWinContext *)base;
+
+#ifdef _DEBUG
+ GLWIN_TRACE_MSG("glxWinContextLoseCurrent context %p (native ctx %p)", gc, gc->ctx);
+ glWinCallDelta();
+#endif
+
+
+ if (wglGetCurrentContext()==gc->ctx)
+ {
+ /* Only do this when we are sure we are currently the active, otherwise we are deactivating the wrong one (this is happening!!!) */
+ ret = wglMakeCurrent(NULL, NULL);
+ if (!ret)
+ ErrorF("glxWinContextLoseCurrent error: %s\n", glxWinErrorMessage());
+ }
+ else
+ {
+ return FALSE;
+ }
+
+ /* Since drawPriv is going to be set to zero in the context, we have to release the DC to */
+ if (gc->hDC && gc->base.drawPriv) glxWinReleaseDC(gc->hwnd, gc->hDC, (__GLXWinDrawable *)gc->base.drawPriv);
+ if (gc->hreadDC && gc->base.readPriv) glxWinReleaseDC(gc->hreadwnd, gc->hreadDC, (__GLXWinDrawable *)gc->base.readPriv);
+ gc->hDC=NULL;
+ gc->hreadDC=NULL;
+
+ base->isCurrent=FALSE; /* It looks like glx is not doing this */
+
+ return ret;
+}
+
+static int
+glxWinContextCopy(__GLXcontext *dst_base, __GLXcontext *src_base, unsigned long mask)
+{
+ __GLXWinContext *dst = (__GLXWinContext *)dst_base;
+ __GLXWinContext *src = (__GLXWinContext *)src_base;
+ BOOL ret;
+
+ GLWIN_DEBUG_MSG("glxWinContextCopy");
+
+ ret = wglCopyContext(src->ctx, dst->ctx, mask);
+ if (!ret)
+ {
+ ErrorF("wglCopyContext error: %s\n", glxWinErrorMessage());
+ }
+
+ return ret;
+}
+
+static int
+glxWinContextForceCurrent(__GLXcontext *base)
+{
+ /* wglMakeCurrent always flushes the previous context, so this is equivalent to glxWinContextMakeCurrent */
+ return glxWinContextMakeCurrent(base);
+}
+
+static void
+glxWinContextDestroy(__GLXcontext *base)
+{
+ __GLXWinContext *gc = (__GLXWinContext *)base;
+
+ if (gc != NULL)
+ {
+ GLWIN_DEBUG_MSG("GLXcontext %p destroyed (native ctx %p)", base, gc->ctx);
+
+ if (gc->ctx)
+ {
+ BOOL ret;
+ /* It's bad style to delete the context while it's still current */
+ if (wglGetCurrentContext() == gc->ctx)
+ {
+ wglMakeCurrent(NULL, NULL);
+ }
+
+ ret = wglDeleteContext(gc->ctx);
+ if (!ret)
+ ErrorF("wglDeleteContext error: %s\n", glxWinErrorMessage());
+ if (gc->base.drawPriv && gc->hDC) glxWinReleaseDC(gc->hwnd, gc->hDC, (__GLXWinDrawable *)gc->base.drawPriv);
+ if (gc->base.readPriv && gc->hreadDC) glxWinReleaseDC(gc->hreadwnd, gc->hreadDC, (__GLXWinDrawable *)gc->base.readPriv);
+ gc->hDC=NULL;
+ gc->hreadDC=NULL;
+ gc->ctx = NULL;
+ }
+
+ xfree(gc);
+ }
+}
+
+static __GLXcontext *
+glxWinCreateContext(__GLXscreen *screen,
+ __GLXconfig *modes,
+ __GLXcontext *baseShareContext)
+{
+ __GLXWinContext *context;
+ __GLXWinContext *shareContext = (__GLXWinContext *)baseShareContext;
+
+ static __GLXtextureFromPixmap glxWinTextureFromPixmap =
+ {
+ glxWinBindTexImage,
+ glxWinReleaseTexImage
+ };
+
+ context = (__GLXWinContext *)xcalloc(1, sizeof(__GLXWinContext));
+
+ if (!context)
+ return NULL;
+
+ memset(context, 0, sizeof *context);
+ context->base.destroy = glxWinContextDestroy;
+ context->base.makeCurrent = glxWinContextMakeCurrent;
+ context->base.loseCurrent = glxWinContextLoseCurrent;
+ context->base.copy = glxWinContextCopy;
+ context->base.forceCurrent = glxWinContextForceCurrent;
+ context->base.textureFromPixmap = &glxWinTextureFromPixmap;
+ context->base.config = modes;
+ context->base.pGlxScreen = screen;
+
+ // actual native GL context creation is deferred until attach()
+ //context->ctx = NULL; already done with memset
+ context->shareContext = shareContext;
+
+ glWinSetupDispatchTable();
+
+ GLWIN_DEBUG_MSG("GLXcontext %p created", context);
+
+ return &(context->base);
+}
+
+/* ---------------------------------------------------------------------- */
+/*
+ * Utility functions
+ */
+
+static int
+fbConfigToPixelFormat(__GLXconfig *mode, PIXELFORMATDESCRIPTOR *pfdret, int drawableTypeOverride)
+{
+ PIXELFORMATDESCRIPTOR pfd = {
+ sizeof(PIXELFORMATDESCRIPTOR), /* size of this pfd */
+ 1, /* version number */
+ PFD_SUPPORT_OPENGL, /* support OpenGL */
+ PFD_TYPE_RGBA, /* RGBA type */
+ 24, /* 24-bit color depth */
+ 0, 0, 0, 0, 0, 0, /* color bits ignored */
+ 0, /* no alpha buffer */
+ 0, /* shift bit ignored */
+ 0, /* no accumulation buffer */
+ 0, 0, 0, 0, /* accum bits ignored */
+ 32, /* 32-bit z-buffer */
+ 0, /* no stencil buffer */
+ 0, /* no auxiliary buffer */
+ PFD_MAIN_PLANE, /* main layer */
+ 0, /* reserved */
+ 0, 0, 0 /* layer masks ignored */
+ };
+
+ if ((mode->drawableType | drawableTypeOverride) & GLX_WINDOW_BIT)
+ pfd.dwFlags |= PFD_DRAW_TO_WINDOW; /* support window */
+
+ if ((mode->drawableType | drawableTypeOverride) & GLX_PIXMAP_BIT)
+ pfd.dwFlags |= (PFD_DRAW_TO_BITMAP | PFD_SUPPORT_GDI); /* supports software rendering to bitmap */
+
+ if (mode->stereoMode) {
+ pfd.dwFlags |= PFD_STEREO;
+ }
+ if (mode->doubleBufferMode) {
+ pfd.dwFlags |= PFD_DOUBLEBUFFER;
+ }
+
+ pfd.iPixelType = PFD_TYPE_RGBA;
+ pfd.cColorBits = mode->redBits + mode->greenBits + mode->blueBits;
+ pfd.cRedBits = mode->redBits;
+ pfd.cRedShift = 0; /* FIXME */
+ pfd.cGreenBits = mode->greenBits;
+ pfd.cGreenShift = 0; /* FIXME */
+ pfd.cBlueBits = mode->blueBits;
+ pfd.cBlueShift = 0; /* FIXME */
+ pfd.cAlphaBits = mode->alphaBits;
+ pfd.cAlphaShift = 0; /* FIXME */
+
+ pfd.cAccumBits = mode->accumRedBits + mode->accumGreenBits + mode->accumBlueBits + mode->accumAlphaBits;
+ pfd.cAccumRedBits = mode->accumRedBits;
+ pfd.cAccumGreenBits = mode->accumGreenBits;
+ pfd.cAccumBlueBits = mode->accumBlueBits;
+ pfd.cAccumAlphaBits = mode->accumAlphaBits;
+
+ pfd.cDepthBits = mode->depthBits;
+ pfd.cStencilBits = mode->stencilBits;
+ pfd.cAuxBuffers = mode->numAuxBuffers;
+
+ /* mode->level ? */
+ /* mode->pixmapMode ? */
+
+ *pfdret = pfd;
+
+ return 0;
+}
+
+#define SET_ATTR_VALUE(attr, value) { attribList[i++] = attr; attribList[i++] = value; assert(i < NUM_ELEMENTS(attribList)); }
+
+static int
+fbConfigToPixelFormatIndex(HDC hdc, __GLXconfig *mode, int drawableTypeOverride, glxWinScreen *winScreen)
+{
+ UINT numFormats;
+ unsigned int i = 0;
+
+ /* convert fbConfig to attr-value list */
+ int attribList[60];
+
+ SET_ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, TRUE);
+ SET_ATTR_VALUE(WGL_PIXEL_TYPE_ARB, (mode->visualType == GLX_TRUE_COLOR) ? WGL_TYPE_RGBA_ARB : WGL_TYPE_COLORINDEX_ARB);
+ SET_ATTR_VALUE(WGL_COLOR_BITS_ARB, (mode->visualType == GLX_TRUE_COLOR) ? mode->rgbBits : mode->indexBits);
+ SET_ATTR_VALUE(WGL_RED_BITS_ARB, mode->redBits);
+ SET_ATTR_VALUE(WGL_GREEN_BITS_ARB, mode->greenBits);
+ SET_ATTR_VALUE(WGL_BLUE_BITS_ARB, mode->blueBits);
+ SET_ATTR_VALUE(WGL_ALPHA_BITS_ARB, mode->alphaBits);
+ SET_ATTR_VALUE(WGL_ACCUM_RED_BITS_ARB, mode->accumRedBits);
+ SET_ATTR_VALUE(WGL_ACCUM_GREEN_BITS_ARB, mode->accumGreenBits);
+ SET_ATTR_VALUE(WGL_ACCUM_BLUE_BITS_ARB, mode->accumBlueBits);
+ SET_ATTR_VALUE(WGL_ACCUM_ALPHA_BITS_ARB, mode->accumAlphaBits);
+ SET_ATTR_VALUE(WGL_DEPTH_BITS_ARB, mode->depthBits);
+ SET_ATTR_VALUE(WGL_STENCIL_BITS_ARB, mode->stencilBits);
+ SET_ATTR_VALUE(WGL_AUX_BUFFERS_ARB, mode->numAuxBuffers);
+
+ if (mode->doubleBufferMode)
+ SET_ATTR_VALUE(WGL_DOUBLE_BUFFER_ARB, TRUE);
+
+ if (mode->stereoMode)
+ SET_ATTR_VALUE(WGL_STEREO_ARB, TRUE);
+
+ // Some attributes are only added to the list if the value requested is not 'don't care', as exactly matching that is daft..
+ if (mode->swapMethod == GLX_SWAP_EXCHANGE_OML)
+ SET_ATTR_VALUE(WGL_SWAP_METHOD_ARB, WGL_SWAP_EXCHANGE_ARB);
+
+ if (mode->swapMethod == GLX_SWAP_COPY_OML)
+ SET_ATTR_VALUE(WGL_SWAP_COPY_ARB, TRUE);
+
+ // XXX: this should probably be the other way around, but that messes up drawableTypeOverride
+ if (mode->visualRating == GLX_SLOW_VISUAL_EXT)
+ SET_ATTR_VALUE(WGL_ACCELERATION_ARB, WGL_NO_ACCELERATION_ARB);
+
+ // must support all the drawable types the mode supports
+ if ((mode->drawableType | drawableTypeOverride) & GLX_WINDOW_BIT)
+ SET_ATTR_VALUE(WGL_DRAW_TO_WINDOW_ARB,TRUE);
+
+ // XXX: this is a horrible hacky heuristic, in fact this whole drawableTypeOverride thing is a bad idea
+ // try to avoid asking for formats which don't exist (by not asking for all when adjusting the config to include the drawableTypeOverride)
+ if (drawableTypeOverride == GLX_WINDOW_BIT)
+ {
+ if (mode->drawableType & GLX_PIXMAP_BIT)
+ SET_ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, TRUE);
+
+ if (mode->drawableType & GLX_PBUFFER_BIT)
+ if (winScreen->has_WGL_ARB_pbuffer)
+ SET_ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, TRUE);
+ }
+ else
+ {
+ if (drawableTypeOverride & GLX_PIXMAP_BIT)
+ SET_ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, TRUE);
+
+ if (drawableTypeOverride & GLX_PBUFFER_BIT)
+ if (winScreen->has_WGL_ARB_pbuffer)
+ SET_ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, TRUE);
+ }
+
+ SET_ATTR_VALUE(0, 0); // terminator
+
+ /* choose the first match */
+ {
+ int pixelFormatIndex;
+
+ if (!wglChoosePixelFormatARBWrapper(hdc, attribList, NULL, 1, &pixelFormatIndex, &numFormats))
+ {
+ ErrorF("wglChoosePixelFormat error: %s\n", glxWinErrorMessage());
+ }
+ else
+ {
+ if (numFormats > 0)
+ {
+ GLWIN_DEBUG_MSG("wglChoosePixelFormat: chose pixelFormatIndex %d)", pixelFormatIndex);
+ return pixelFormatIndex;
+ }
+ else
+ ErrorF("wglChoosePixelFormat couldn't decide\n");
+ }
+ }
+
+ return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+#define BITS_AND_SHIFT_TO_MASK(bits,mask) (((1<<(bits))-1) << (mask))
+
+//
+// Create the GLXconfigs using DescribePixelFormat()
+//
+static void
+glxWinCreateConfigs(HDC hdc, glxWinScreen *screen)
+{
+ GLXWinConfig *c, *result, *prev = NULL;
+ int numConfigs = 0;
+ int i = 0;
+ int n = 0;
+ PIXELFORMATDESCRIPTOR pfd;
+
+ GLWIN_DEBUG_MSG("glxWinCreateConfigs");
+
+ screen->base.numFBConfigs = 0;
+ screen->base.fbconfigs = NULL;
+
+ // get the number of pixelformats
+ numConfigs = DescribePixelFormat(hdc, 1, sizeof(PIXELFORMATDESCRIPTOR), NULL);
+ GLWIN_DEBUG_MSG("DescribePixelFormat says %d possible pixel formats", numConfigs);
+
+ /* alloc */
+ result = xalloc(sizeof(GLXWinConfig) * numConfigs);
+
+ if (NULL == result)
+ {
+ return;
+ }
+
+ memset(result, 0, sizeof(GLXWinConfig) * numConfigs);
+ n = 0;
+
+ /* fill in configs */
+ for (i = 0; i < numConfigs; i++)
+ {
+ int rc;
+
+ c = &(result[i]);
+ c->base.next = NULL;
+ c->pixelFormatIndex = i+1;
+
+ rc = DescribePixelFormat(hdc, i+1, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
+
+ if (!rc)
+ {
+ ErrorF("DescribePixelFormat failed for index %d, error %s\n", i+1, glxWinErrorMessage());
+ break;
+ }
+
+#ifdef _DEBUG
+ if (glxWinDebugSettings.dumpPFD)
+ pfdOut(&pfd);
+#endif
+
+ if (!(pfd.dwFlags & (PFD_DRAW_TO_WINDOW | PFD_DRAW_TO_BITMAP)) || !(pfd.dwFlags & PFD_SUPPORT_OPENGL))
+ {
+ GLWIN_DEBUG_MSG("pixelFormat %d has unsuitable flags 0x%08lx, skipping", i+1, pfd.dwFlags);
+ continue;
+ }
+
+ c->base.doubleBufferMode = (pfd.dwFlags & PFD_DOUBLEBUFFER) ? GL_TRUE : GL_FALSE;
+ c->base.stereoMode = (pfd.dwFlags & PFD_STEREO) ? GL_TRUE : GL_FALSE;
+
+ c->base.redBits = pfd.cRedBits;
+ c->base.greenBits = pfd.cGreenBits;
+ c->base.blueBits = pfd.cBlueBits;
+ c->base.alphaBits = pfd.cAlphaBits;
+
+ c->base.redMask = BITS_AND_SHIFT_TO_MASK(pfd.cRedBits, pfd.cRedShift);
+ c->base.greenMask = BITS_AND_SHIFT_TO_MASK(pfd.cGreenBits, pfd.cGreenShift);
+ c->base.blueMask = BITS_AND_SHIFT_TO_MASK(pfd.cBlueBits, pfd.cBlueShift);
+ c->base.alphaMask = BITS_AND_SHIFT_TO_MASK(pfd.cAlphaBits, pfd.cAlphaShift);
+
+ c->base.rgbBits = pfd.cColorBits;
+
+ if (pfd.iPixelType == PFD_TYPE_COLORINDEX)
+ {
+ c->base.indexBits = pfd.cColorBits;
+ }
+ else
+ {
+ c->base.indexBits = 0;
+ }
+
+ c->base.accumRedBits = pfd.cAccumRedBits;
+ c->base.accumGreenBits = pfd.cAccumGreenBits;
+ c->base.accumBlueBits = pfd.cAccumBlueBits;
+ c->base.accumAlphaBits = pfd.cAccumAlphaBits;
+ // pfd.cAccumBits;
+
+ c->base.depthBits = pfd.cDepthBits;
+ c->base.stencilBits = pfd.cStencilBits;
+ c->base.numAuxBuffers = pfd.cAuxBuffers;
+
+ // pfd.iLayerType; // ignored
+ c->base.level = 0;
+ // pfd.dwLayerMask; // ignored
+ // pfd.dwDamageMask; // ignored
+
+ c->base.pixmapMode = 0;
+ c->base.visualID = -1; // will be set by __glXScreenInit()
+
+ /* EXT_visual_rating / GLX 1.2 */
+ if (pfd.dwFlags & PFD_GENERIC_FORMAT)
+ {
+ c->base.visualRating = GLX_SLOW_VISUAL_EXT;
+ }
+ else
+ {
+ // PFD_GENERIC_ACCELERATED is not considered, so this may be MCD or ICD acclerated...
+ c->base.visualRating = GLX_NONE_EXT;
+ }
+
+ /* EXT_visual_info / GLX 1.2 */
+ if (pfd.iPixelType == PFD_TYPE_COLORINDEX)
+ {
+ c->base.visualType = GLX_STATIC_COLOR;
+ }
+ else
+ {
+ c->base.visualType = GLX_TRUE_COLOR;
+ }
+
+ // pfd.dwVisibleMask; ???
+ c->base.transparentPixel = GLX_NONE;
+ c->base.transparentRed = GLX_NONE;
+ c->base.transparentGreen = GLX_NONE;
+ c->base.transparentBlue = GLX_NONE;
+ c->base.transparentAlpha = GLX_NONE;
+ c->base.transparentIndex = GLX_NONE;
+
+ /* ARB_multisample / SGIS_multisample */
+ c->base.sampleBuffers = 0;
+ c->base.samples = 0;
+
+ /* SGIX_fbconfig / GLX 1.3 */
+ c->base.drawableType = (((pfd.dwFlags & PFD_DRAW_TO_WINDOW) ? GLX_WINDOW_BIT : 0)
+ | ((pfd.dwFlags & PFD_DRAW_TO_BITMAP) ? GLX_PIXMAP_BIT : 0));
+ c->base.renderType = GLX_RGBA_BIT;
+ c->base.xRenderable = GL_TRUE;
+ c->base.fbconfigID = -1; // will be set by __glXScreenInit()
+
+ /* SGIX_pbuffer / GLX 1.3 */
+ // XXX: How can we find these values out ???
+ c->base.maxPbufferWidth = -1;
+ c->base.maxPbufferHeight = -1;
+ c->base.maxPbufferPixels = -1;
+ c->base.optimalPbufferWidth = 0; // there is no optimal value
+ c->base.optimalPbufferHeight = 0;
+
+ /* SGIX_visual_select_group */
+ // arrange for visuals with the best acceleration to be preferred in selection
+ switch (pfd.dwFlags & (PFD_GENERIC_FORMAT | PFD_GENERIC_ACCELERATED))
+ {
+ case 0:
+ c->base.visualSelectGroup = 2;
+ break;
+
+ case PFD_GENERIC_ACCELERATED:
+ c->base.visualSelectGroup = 1;
+ break;
+
+ case PFD_GENERIC_FORMAT:
+ c->base.visualSelectGroup = 0;
+ break;
+
+ default:
+ ;
+ // "can't happen"
+ }
+
+ /* OML_swap_method */
+ if (pfd.dwFlags & PFD_SWAP_EXCHANGE)
+ c->base.swapMethod = GLX_SWAP_EXCHANGE_OML;
+ else if (pfd.dwFlags & PFD_SWAP_COPY)
+ c->base.swapMethod = GLX_SWAP_COPY_OML;
+ else
+ c->base.swapMethod = GLX_SWAP_UNDEFINED_OML;
+
+ /* EXT_import_context */
+ c->base.screen = screen->base.pScreen->myNum;
+
+ /* EXT_texture_from_pixmap */
+ c->base.bindToTextureRgb = -1;
+ c->base.bindToTextureRgba = -1;
+ c->base.bindToMipmapTexture = -1;
+ c->base.bindToTextureTargets = -1;
+ c->base.yInverted = -1;
+
+ n++;
+
+ // update previous config to point to this config
+ if (prev)
+ prev->base.next = &(c->base);
+
+ prev = c;
+ }
+
+ GLWIN_DEBUG_MSG("found %d pixelFormats suitable for conversion to fbConfigs", n);
+
+ screen->base.numFBConfigs = n;
+ screen->base.fbconfigs = &(result->base);
+}
+
+// helper function to access an attribute value from an attribute value array by attribute
+static
+int getAttrValue(const int attrs[], int values[], unsigned int num, int attr, int fallback)
+{
+ unsigned int i;
+ for (i = 0; i < num; i++)
+ {
+ if (attrs[i] == attr)
+ {
+ GLWIN_TRACE_MSG("getAttrValue attr 0x%x, value %d", attr, values[i]);
+ return values[i];
+ }
+ }
+
+ ErrorF("getAttrValue failed to find attr 0x%x, using default value %d\n", attr, fallback);
+ return fallback;
+}
+
+//
+// Create the GLXconfigs using wglGetPixelFormatAttribfvARB() extension
+//
+static void
+glxWinCreateConfigsExt(HDC hdc, glxWinScreen *screen)
+{
+ GLXWinConfig *c, *result, *prev = NULL;
+ int i = 0;
+ int n = 0;
+
+ const int attr = WGL_NUMBER_PIXEL_FORMATS_ARB;
+ int numConfigs;
+
+ int attrs[50];
+ unsigned int num_attrs = 0;
+
+ GLWIN_DEBUG_MSG("glxWinCreateConfigsExt");
+
+ screen->base.numFBConfigs = 0;
+ screen->base.fbconfigs = NULL;
+
+ if (!wglGetPixelFormatAttribivARBWrapper(hdc, 0, 0, 1, &attr, &numConfigs))
+ {
+ ErrorF("wglGetPixelFormatAttribivARB failed for WGL_NUMBER_PIXEL_FORMATS_ARB: %s\n", glxWinErrorMessage());
+ return;
+ }
+
+ GLWIN_DEBUG_MSG("wglGetPixelFormatAttribivARB says %d possible pixel formats", numConfigs);
+
+ /* alloc */
+ result = xalloc(sizeof(GLXWinConfig) * numConfigs);
+
+ if (NULL == result)
+ {
+ return;
+ }
+
+ memset(result, 0, sizeof(GLXWinConfig) * numConfigs);
+ n = 0;
+
+#define ADD_ATTR(a) { attrs[num_attrs++] = a; assert(num_attrs < NUM_ELEMENTS(attrs)); }
+
+ ADD_ATTR(WGL_DRAW_TO_WINDOW_ARB);
+ ADD_ATTR(WGL_DRAW_TO_BITMAP_ARB);
+ ADD_ATTR(WGL_ACCELERATION_ARB);
+ ADD_ATTR(WGL_SWAP_LAYER_BUFFERS_ARB);
+ ADD_ATTR(WGL_NUMBER_OVERLAYS_ARB);
+ ADD_ATTR(WGL_NUMBER_UNDERLAYS_ARB);
+ ADD_ATTR(WGL_TRANSPARENT_ARB);
+ ADD_ATTR(WGL_TRANSPARENT_RED_VALUE_ARB);
+ ADD_ATTR(WGL_TRANSPARENT_GREEN_VALUE_ARB);
+ ADD_ATTR(WGL_TRANSPARENT_GREEN_VALUE_ARB);
+ ADD_ATTR(WGL_TRANSPARENT_ALPHA_VALUE_ARB);
+ ADD_ATTR(WGL_SUPPORT_OPENGL_ARB);
+ ADD_ATTR(WGL_DOUBLE_BUFFER_ARB);
+ ADD_ATTR(WGL_STEREO_ARB);
+ ADD_ATTR(WGL_PIXEL_TYPE_ARB);
+ ADD_ATTR(WGL_COLOR_BITS_ARB);
+ ADD_ATTR(WGL_RED_BITS_ARB);
+ ADD_ATTR(WGL_RED_SHIFT_ARB);
+ ADD_ATTR(WGL_GREEN_BITS_ARB);
+ ADD_ATTR(WGL_GREEN_SHIFT_ARB);
+ ADD_ATTR(WGL_BLUE_BITS_ARB);
+ ADD_ATTR(WGL_BLUE_SHIFT_ARB);
+ ADD_ATTR(WGL_ALPHA_BITS_ARB);
+ ADD_ATTR(WGL_ALPHA_SHIFT_ARB);
+ ADD_ATTR(WGL_ACCUM_RED_BITS_ARB);
+ ADD_ATTR(WGL_ACCUM_GREEN_BITS_ARB);
+ ADD_ATTR(WGL_ACCUM_BLUE_BITS_ARB);
+ ADD_ATTR(WGL_ACCUM_ALPHA_BITS_ARB);
+ ADD_ATTR(WGL_DEPTH_BITS_ARB);
+ ADD_ATTR(WGL_STENCIL_BITS_ARB);
+ ADD_ATTR(WGL_AUX_BUFFERS_ARB);
+ ADD_ATTR(WGL_SWAP_METHOD_ARB);
+
+ if (screen->has_WGL_ARB_multisample)
+ {
+ // we may not query these attrs if WGL_ARB_multisample is not offered
+ ADD_ATTR(WGL_SAMPLE_BUFFERS_ARB);
+ ADD_ATTR(WGL_SAMPLES_ARB);
+ }
+
+ if (screen->has_WGL_ARB_render_texture)
+ {
+ // we may not query these attrs if WGL_ARB_render_texture is not offered
+ ADD_ATTR(WGL_BIND_TO_TEXTURE_RGB_ARB);
+ ADD_ATTR(WGL_BIND_TO_TEXTURE_RGBA_ARB);
+ }
+
+ if (screen->has_WGL_ARB_pbuffer)
+ {
+ // we may not query these attrs if WGL_ARB_pbuffer is not offered
+ ADD_ATTR(WGL_DRAW_TO_PBUFFER_ARB);
+ ADD_ATTR(WGL_MAX_PBUFFER_PIXELS_ARB);
+ ADD_ATTR(WGL_MAX_PBUFFER_WIDTH_ARB);
+ ADD_ATTR(WGL_MAX_PBUFFER_HEIGHT_ARB);
+ }
+
+ /* fill in configs */
+ for (i = 0; i < numConfigs; i++)
+ {
+ int sizevalues=num_attrs*sizeof(int);
+ int *values=(int*)_alloca(sizevalues);
+
+ memset(values,0,sizevalues);
+
+ c = &(result[i]);
+ c->base.next = NULL;
+ c->pixelFormatIndex = i+1;
+
+ if (!wglGetPixelFormatAttribivARBWrapper(hdc, i+1, 0, num_attrs, attrs, values))
+ {
+ ErrorF("wglGetPixelFormatAttribivARB failed for index %d, error %s\n", i+1, glxWinErrorMessage());
+ break;
+ }
+
+#define ATTR_VALUE(a, d) getAttrValue(attrs, values, num_attrs, (a), (d))
+
+ if (!ATTR_VALUE(WGL_SUPPORT_OPENGL_ARB, 0))
+ {
+ GLWIN_DEBUG_MSG("pixelFormat %d isn't WGL_SUPPORT_OPENGL_ARB, skipping", i+1);
+ continue;
+ }
+
+ c->base.doubleBufferMode = ATTR_VALUE(WGL_DOUBLE_BUFFER_ARB, 0) ? GL_TRUE : GL_FALSE;
+ c->base.stereoMode = ATTR_VALUE(WGL_STEREO_ARB, 0) ? GL_TRUE : GL_FALSE;
+
+ c->base.redBits = ATTR_VALUE(WGL_RED_BITS_ARB, 0);
+ c->base.greenBits = ATTR_VALUE(WGL_GREEN_BITS_ARB, 0);
+ c->base.blueBits = ATTR_VALUE(WGL_BLUE_BITS_ARB, 0);
+ c->base.alphaBits = ATTR_VALUE(WGL_ALPHA_BITS_ARB, 0);
+
+ c->base.redMask = BITS_AND_SHIFT_TO_MASK(c->base.redBits, ATTR_VALUE(WGL_RED_SHIFT_ARB, 0));
+ c->base.greenMask = BITS_AND_SHIFT_TO_MASK(c->base.greenBits, ATTR_VALUE(WGL_GREEN_SHIFT_ARB, 0));
+ c->base.blueMask = BITS_AND_SHIFT_TO_MASK(c->base.blueBits, ATTR_VALUE(WGL_BLUE_SHIFT_ARB, 0));
+ c->base.alphaMask = BITS_AND_SHIFT_TO_MASK(c->base.alphaBits, ATTR_VALUE(WGL_ALPHA_SHIFT_ARB, 0));
+
+ switch (ATTR_VALUE(WGL_PIXEL_TYPE_ARB, 0))
+ {
+ case WGL_TYPE_COLORINDEX_ARB:
+ c->base.indexBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0);
+ c->base.rgbBits = 0;
+ c->base.visualType = GLX_STATIC_COLOR;
+ break;
+
+ case WGL_TYPE_RGBA_FLOAT_ARB:
+ GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_RGBA_FLOAT_ARB, skipping", i+1);
+ continue;
+
+ case WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT:
+ GLWIN_DEBUG_MSG("pixelFormat %d is WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT, skipping", i+1);
+ continue;
+
+ case WGL_TYPE_RGBA_ARB:
+ c->base.indexBits = 0;
+ c->base.rgbBits = ATTR_VALUE(WGL_COLOR_BITS_ARB, 0);
+ c->base.visualType = GLX_TRUE_COLOR;
+ break;
+
+ default:
+ ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_PIXEL_TYPE_ARB\n", ATTR_VALUE(WGL_PIXEL_TYPE_ARB, 0));
+ continue;
+ }
+
+ c->base.accumRedBits = ATTR_VALUE(WGL_ACCUM_RED_BITS_ARB, 0);
+ c->base.accumGreenBits = ATTR_VALUE(WGL_ACCUM_GREEN_BITS_ARB, 0);
+ c->base.accumBlueBits = ATTR_VALUE(WGL_ACCUM_BLUE_BITS_ARB, 0);
+ c->base.accumAlphaBits = ATTR_VALUE(WGL_ACCUM_ALPHA_BITS_ARB, 0);
+
+ c->base.depthBits = ATTR_VALUE(WGL_DEPTH_BITS_ARB, 0);
+ c->base.stencilBits = ATTR_VALUE(WGL_STENCIL_BITS_ARB, 0);
+ c->base.numAuxBuffers = ATTR_VALUE(WGL_AUX_BUFFERS_ARB, 0);
+
+ {
+ int layers = ATTR_VALUE(WGL_NUMBER_OVERLAYS_ARB,0) + ATTR_VALUE(WGL_NUMBER_UNDERLAYS_ARB, 0);
+
+ if (layers > 0)
+ {
+ ErrorF("pixelFormat %d: has %d overlay, %d underlays which aren't currently handled", i, ATTR_VALUE(WGL_NUMBER_OVERLAYS_ARB,0), ATTR_VALUE(WGL_NUMBER_UNDERLAYS_ARB, 0));
+ // XXX: need to iterate over layers?
+ }
+ }
+ c->base.level = 0;
+
+ c->base.pixmapMode = 0; // ???
+ c->base.visualID = -1; // will be set by __glXScreenInit()
+
+ /* EXT_visual_rating / GLX 1.2 */
+ switch (ATTR_VALUE(WGL_ACCELERATION_ARB, 0))
+ {
+ default:
+ ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_ACCELERATION_ARB\n", ATTR_VALUE(WGL_ACCELERATION_ARB, 0));
+
+ case WGL_NO_ACCELERATION_ARB:
+ c->base.visualRating = GLX_SLOW_VISUAL_EXT;
+ break;
+
+ case WGL_GENERIC_ACCELERATION_ARB:
+ case WGL_FULL_ACCELERATION_ARB:
+ c->base.visualRating = GLX_NONE_EXT;
+ break;
+ }
+
+ /* EXT_visual_info / GLX 1.2 */
+ // c->base.visualType is set above
+ if (ATTR_VALUE(WGL_TRANSPARENT_ARB, 0))
+ {
+ c->base.transparentPixel = (c->base.visualType == GLX_TRUE_COLOR) ? GLX_TRANSPARENT_RGB_EXT : GLX_TRANSPARENT_INDEX_EXT;
+ c->base.transparentRed = ATTR_VALUE(WGL_TRANSPARENT_RED_VALUE_ARB, 0);
+ c->base.transparentGreen = ATTR_VALUE(WGL_TRANSPARENT_GREEN_VALUE_ARB, 0);
+ c->base.transparentBlue = ATTR_VALUE(WGL_TRANSPARENT_BLUE_VALUE_ARB, 0);
+ c->base.transparentAlpha = ATTR_VALUE(WGL_TRANSPARENT_ALPHA_VALUE_ARB, 0);
+ c->base.transparentIndex = ATTR_VALUE(WGL_TRANSPARENT_INDEX_VALUE_ARB, 0);
+ }
+ else
+ {
+ c->base.transparentPixel = GLX_NONE_EXT;
+ c->base.transparentRed = GLX_NONE;
+ c->base.transparentGreen = GLX_NONE;
+ c->base.transparentBlue = GLX_NONE;
+ c->base.transparentAlpha = GLX_NONE;
+ c->base.transparentIndex = GLX_NONE;
+ }
+
+ /* ARB_multisample / SGIS_multisample */
+ if (screen->has_WGL_ARB_multisample)
+ {
+ c->base.sampleBuffers = ATTR_VALUE(WGL_SAMPLE_BUFFERS_ARB, 0);
+ c->base.samples = ATTR_VALUE(WGL_SAMPLES_ARB, 0);
+ }
+ else
+ {
+ c->base.sampleBuffers = 0;
+ c->base.samples = 0;
+ }
+
+ /* SGIX_fbconfig / GLX 1.3 */
+ c->base.drawableType = ((ATTR_VALUE(WGL_DRAW_TO_WINDOW_ARB, 0) ? GLX_WINDOW_BIT : 0)
+ | (ATTR_VALUE(WGL_DRAW_TO_BITMAP_ARB, 0) ? GLX_PIXMAP_BIT : 0)
+ | (ATTR_VALUE(WGL_DRAW_TO_PBUFFER_ARB, 0) ? GLX_PBUFFER_BIT : 0));
+ c->base.renderType = GLX_RGBA_BIT | GLX_COLOR_INDEX_BIT; // Hmmm ???
+ c->base.xRenderable = GL_TRUE;
+ c->base.fbconfigID = -1; // will be set by __glXScreenInit()
+
+ /* SGIX_pbuffer / GLX 1.3 */
+ if (screen->has_WGL_ARB_pbuffer)
+ {
+ c->base.maxPbufferWidth = ATTR_VALUE(WGL_MAX_PBUFFER_WIDTH_ARB, -1);
+ c->base.maxPbufferHeight = ATTR_VALUE(WGL_MAX_PBUFFER_HEIGHT_ARB, -1);
+ c->base.maxPbufferPixels = ATTR_VALUE(WGL_MAX_PBUFFER_PIXELS_ARB, -1);
+ }
+ else
+ {
+ c->base.maxPbufferWidth = -1;
+ c->base.maxPbufferHeight = -1;
+ c->base.maxPbufferPixels = -1;
+ }
+ c->base.optimalPbufferWidth = 0; // there is no optimal value
+ c->base.optimalPbufferHeight = 0;
+
+ /* SGIX_visual_select_group */
+ // arrange for visuals with the best acceleration to be preferred in selection
+ switch (ATTR_VALUE(WGL_ACCELERATION_ARB, 0))
+ {
+ case WGL_FULL_ACCELERATION_ARB:
+ c->base.visualSelectGroup = 2;
+ break;
+
+ case WGL_GENERIC_ACCELERATION_ARB:
+ c->base.visualSelectGroup = 1;
+ break;
+
+ default:
+ case WGL_NO_ACCELERATION_ARB:
+ c->base.visualSelectGroup = 0;
+ break;
+ }
+
+ /* OML_swap_method */
+ switch (ATTR_VALUE(WGL_SWAP_METHOD_ARB, 0))
+ {
+ case WGL_SWAP_EXCHANGE_ARB:
+ c->base.swapMethod = GLX_SWAP_EXCHANGE_OML;
+ break;
+
+ case WGL_SWAP_COPY_ARB:
+ c->base.swapMethod = GLX_SWAP_COPY_OML;
+ break;
+
+ default:
+ ErrorF("wglGetPixelFormatAttribivARB returned unknown value 0x%x for WGL_SWAP_METHOD_ARB\n", ATTR_VALUE(WGL_SWAP_METHOD_ARB, 0));
+
+ case WGL_SWAP_UNDEFINED_ARB:
+ c->base.swapMethod = GLX_SWAP_UNDEFINED_OML;
+ }
+
+ /* EXT_import_context */
+ c->base.screen = screen->base.pScreen->myNum;
+
+ /* EXT_texture_from_pixmap */
+ /*
+ Mesa's DRI configs always have bindToTextureRgb/Rgba TRUE (see driCreateConfigs(), so setting
+ bindToTextureRgb/bindToTextureRgba to FALSE means that swrast can't find any fbConfigs to use,
+ so setting these to 0, even if we know bindToTexture isn't available, isn't a good idea...
+ */
+ if (screen->has_WGL_ARB_render_texture)
+ {
+ c->base.bindToTextureRgb = ATTR_VALUE(WGL_BIND_TO_TEXTURE_RGB_ARB, -1);
+ c->base.bindToTextureRgba = ATTR_VALUE(WGL_BIND_TO_TEXTURE_RGBA_ARB, -1);
+ }
+ else
+ {
+ c->base.bindToTextureRgb = -1;
+ c->base.bindToTextureRgba = -1;
+ }
+ c->base.bindToMipmapTexture = -1;
+ c->base.bindToTextureTargets = GLX_TEXTURE_1D_BIT_EXT | GLX_TEXTURE_2D_BIT_EXT | GLX_TEXTURE_RECTANGLE_BIT_EXT;
+ c->base.yInverted = -1;
+
+ n++;
+
+ // update previous config to point to this config
+ if (prev)
+ prev->base.next = &(c->base);
+
+ prev = c;
+ }
+
+ screen->base.numFBConfigs = n;
+ screen->base.fbconfigs = &(result->base);
+}
diff --git a/xorg-server/hw/xwin/glx/makefile b/xorg-server/hw/xwin/glx/makefile new file mode 100644 index 000000000..5cd2e89f9 --- /dev/null +++ b/xorg-server/hw/xwin/glx/makefile @@ -0,0 +1,43 @@ +LIBRARY=libwinglx + +INCLUDES += ..\..\..\glx .. ..\..\.. +DEFINES += GLAPIENTRY=__stdcall + +DEFINES += XWIN_CLIPBOARD +DEFINES += XWIN_MULTIWINDOW +DEFINES += XWIN_NATIVEGDI +DEFINES += XWIN_RANDR RELOCATE_PROJECTROOT +INCLUDES += ..\..\..\miext\rootless +DEFINES += HAVE_XWIN_CONFIG_H BUILD_DATE=0-0-0000 PTW32_STATIC_LIB + +CSRCS = \ + winpriv.c \ + glwrap.c \ + indirect.c \ + wgl_ext_api.c + +glwrap.c: generated_gl_wrappers.c +wgl_ext_api.c: generated_wgl_wrappers.c wglext.h +wgl_ext_api.h: wglext.h +indirect.c: wgl_ext_api.h + +SPEC_FILES = gl.spec gl.tm wglext.spec wgl.tm + +.PHONY: getspecfiles + +getspecfiles: + wget http://www.opengl.org/registry/api/gl.spec + wget http://www.opengl.org/registry/api/gl.tm + wget http://www.opengl.org/registry/api/wglext.spec + wget http://www.opengl.org/registry/api/wgl.tm + wget http://www.opengl.org/registry/api/wglext.h + +generated_gl_wrappers.c: gen_gl_wrappers.py gl.spec gl.tm + gen_gl_wrappers --spec=gl.spec --typemap=gl.tm --dispatch-header=../../../glx/dispatch.h --staticwrappers >generated_gl_wrappers.c + +generated_wgl_wrappers.c: gen_gl_wrappers.py wglext.spec wgl.tm + gen_gl_wrappers --spec=wglext.spec --typemap=wgl.tm --prefix=wgl --preresolve >generated_wgl_wrappers.c + + +BUILT_SOURCES = generated_gl_wrappers.c generated_wgl_wrappers.c + diff --git a/xorg-server/hw/xwin/glx/wgl.tm b/xorg-server/hw/xwin/glx/wgl.tm new file mode 100644 index 000000000..baceced55 --- /dev/null +++ b/xorg-server/hw/xwin/glx/wgl.tm @@ -0,0 +1,36 @@ +BOOL,*,*, BOOL,*,* +DWORD,*,*, DWORD,*,* +FLOAT,*,*, FLOAT,*,* +GLbitfield,*,*, GLbitfield,*,* +GLboolean,*,*, GLboolean,*,* +GLenum,*,*, GLenum,*,* +GLfloat,*,*, GLfloat,*,* +GLint,*,*, GLint,*,* +GLsizei,*,*, GLsizei,*,* +GLuint,*,*, GLuint,*,* +GLushort,*,*, GLushort,*,* +HANDLE,*,*, HANDLE,*,* +HDC,*,*, HDC,*,* +HGLRC,*,*, HGLRC,*,* +HGPUNV,*,*, HGPUNV,*,* +HPBUFFERARB,*,*, HPBUFFERARB,*,* +HPBUFFEREXT,*,*, HPBUFFEREXT,*,* +HPVIDEODEV,*,*, HPVIDEODEV,*,* +HPGPUNV,*,*, HPGPUNV,*,* +HVIDEOINPUTDEVICENV,*,*, HVIDEOINPUTDEVICENV,*,* +HVIDEOOUTPUTDEVICENV,*,*, HVIDEOOUTPUTDEVICENV,*,* +INT,*,*, INT,*,* +INT32,*,*, INT32,*,* +INT64,*,*, INT64,*,* +LPVOID,*,*, LPVOID,*,* +PGPU_DEVICE,*,*, PGPU_DEVICE,*,* +String,*,*, const char *,*,* +UINT,*,*, UINT,*,* +USHORT,*,*, USHORT,*,* +VOID,*,*, VOID,*,* +VoidPointer,*,*, void*,*,* +float,*,*, float,*,* +int,*,*, int,*,* +uint,*,*, unsigned int,*,* +ulong,*,*, unsigned long,*,* +void,*,*, *,*,* diff --git a/xorg-server/hw/xwin/glx/wgl_ext_api.c b/xorg-server/hw/xwin/glx/wgl_ext_api.c index ffe10884d..3aa6cbcce 100644 --- a/xorg-server/hw/xwin/glx/wgl_ext_api.c +++ b/xorg-server/hw/xwin/glx/wgl_ext_api.c @@ -42,12 +42,17 @@ #define RESOLVE_DECL(type) \ static type type##proc = NULL; +#ifdef _DEBUG #define PRERESOLVE(type, symbol) \ type##proc = (type)wglGetProcAddress(symbol); \ if (type##proc == NULL) \ ErrorF("wglwrap: Can't resolve \"%s\"\n", symbol); \ else \ ErrorF("wglwrap: Resolved \"%s\"\n", symbol); +#else +#define PRERESOLVE(type, symbol) \ + type##proc = (type)wglGetProcAddress(symbol); +#endif #define RESOLVE_RET(type, symbol, retval) \ if (type##proc == NULL) { \ diff --git a/xorg-server/hw/xwin/glx/wgl_ext_api.h b/xorg-server/hw/xwin/glx/wgl_ext_api.h index e4462ac5c..3c46d1d30 100644 --- a/xorg-server/hw/xwin/glx/wgl_ext_api.h +++ b/xorg-server/hw/xwin/glx/wgl_ext_api.h @@ -38,50 +38,50 @@ void wglResolveExtensionProcs(void); XXX: should be automatically generated as well */ -const char *wglGetExtensionsStringARBWrapper(HDC hdc); -BOOL wglMakeContextCurrentARBWrapper(HDC hDrawDC, HDC hReadDC, HGLRC hglrc); -HDC wglGetCurrentReadDCARBWrapper(VOID); +const char * __stdcall wglGetExtensionsStringARBWrapper(HDC hdc); +BOOL __stdcall wglMakeContextCurrentARBWrapper(HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +HDC __stdcall wglGetCurrentReadDCARBWrapper(VOID); -BOOL wglGetPixelFormatAttribivARBWrapper(HDC hdc, +BOOL __stdcall wglGetPixelFormatAttribivARBWrapper(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); -BOOL wglGetPixelFormatAttribfvARBWrapper(HDC hdc, +BOOL __stdcall wglGetPixelFormatAttribfvARBWrapper(HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); -BOOL wglChoosePixelFormatARBWrapper(HDC hdc, +BOOL __stdcall wglChoosePixelFormatARBWrapper(HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); -HPBUFFERARB wglCreatePbufferARBWrapper(HDC hDC, +HPBUFFERARB __stdcall wglCreatePbufferARBWrapper(HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); -HDC wglGetPbufferDCARBWrapper(HPBUFFERARB hPbuffer); +HDC __stdcall wglGetPbufferDCARBWrapper(HPBUFFERARB hPbuffer); -int wglReleasePbufferDCARBWrapper(HPBUFFERARB hPbuffer, +int __stdcall wglReleasePbufferDCARBWrapper(HPBUFFERARB hPbuffer, HDC hDC); -BOOL wglDestroyPbufferARBWrapper(HPBUFFERARB hPbuffer); +BOOL __stdcall wglDestroyPbufferARBWrapper(HPBUFFERARB hPbuffer); -BOOL wglQueryPbufferARBWrapper(HPBUFFERARB hPbuffer, +BOOL __stdcall wglQueryPbufferARBWrapper(HPBUFFERARB hPbuffer, int iAttribute, int *piValue); -BOOL wglSwapIntervalEXTWrapper(int interval); +BOOL __stdcall wglSwapIntervalEXTWrapper(int interval); -int wglGetSwapIntervalEXTWrapper(void); +int __stdcall wglGetSwapIntervalEXTWrapper(void); #endif /* wgl_ext_api_h */ diff --git a/xorg-server/hw/xwin/glx/wglext.h b/xorg-server/hw/xwin/glx/wglext.h new file mode 100644 index 000000000..df96fbebb --- /dev/null +++ b/xorg-server/hw/xwin/glx/wglext.h @@ -0,0 +1,869 @@ +#ifndef __wglext_h_ +#define __wglext_h_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Copyright (c) 2007-2009 The Khronos Group Inc. +** +** Permission is hereby granted, free of charge, to any person obtaining a +** copy of this software and/or associated documentation files (the +** "Materials"), to deal in the Materials without restriction, including +** without limitation the rights to use, copy, modify, merge, publish, +** distribute, sublicense, and/or sell copies of the Materials, and to +** permit persons to whom the Materials are 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 Materials. +** +** THE MATERIALS ARE 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 +** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS. +*/ + +/* Function declaration macros - to move into glplatform.h */ + +#if defined(_WIN32) && !defined(APIENTRY) && !defined(__CYGWIN__) && !defined(__SCITECH_SNAP__) +#define WIN32_LEAN_AND_MEAN 1 +#include <windows.h> +#endif + +#ifndef APIENTRY +#define APIENTRY +#endif +#ifndef APIENTRYP +#define APIENTRYP APIENTRY * +#endif +#ifndef GLAPI +#define GLAPI extern +#endif + +/*************************************************************/ + +/* Header file version number */ +/* wglext.h last updated 2009/09/16 */ +/* Current version at http://www.opengl.org/registry/ */ +#define WGL_WGLEXT_VERSION 17 + +#ifndef WGL_ARB_buffer_region +#define WGL_FRONT_COLOR_BUFFER_BIT_ARB 0x00000001 +#define WGL_BACK_COLOR_BUFFER_BIT_ARB 0x00000002 +#define WGL_DEPTH_BUFFER_BIT_ARB 0x00000004 +#define WGL_STENCIL_BUFFER_BIT_ARB 0x00000008 +#endif + +#ifndef WGL_ARB_multisample +#define WGL_SAMPLE_BUFFERS_ARB 0x2041 +#define WGL_SAMPLES_ARB 0x2042 +#endif + +#ifndef WGL_ARB_extensions_string +#endif + +#ifndef WGL_ARB_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_ARB 0x2000 +#define WGL_DRAW_TO_WINDOW_ARB 0x2001 +#define WGL_DRAW_TO_BITMAP_ARB 0x2002 +#define WGL_ACCELERATION_ARB 0x2003 +#define WGL_NEED_PALETTE_ARB 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_ARB 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006 +#define WGL_SWAP_METHOD_ARB 0x2007 +#define WGL_NUMBER_OVERLAYS_ARB 0x2008 +#define WGL_NUMBER_UNDERLAYS_ARB 0x2009 +#define WGL_TRANSPARENT_ARB 0x200A +#define WGL_TRANSPARENT_RED_VALUE_ARB 0x2037 +#define WGL_TRANSPARENT_GREEN_VALUE_ARB 0x2038 +#define WGL_TRANSPARENT_BLUE_VALUE_ARB 0x2039 +#define WGL_TRANSPARENT_ALPHA_VALUE_ARB 0x203A +#define WGL_TRANSPARENT_INDEX_VALUE_ARB 0x203B +#define WGL_SHARE_DEPTH_ARB 0x200C +#define WGL_SHARE_STENCIL_ARB 0x200D +#define WGL_SHARE_ACCUM_ARB 0x200E +#define WGL_SUPPORT_GDI_ARB 0x200F +#define WGL_SUPPORT_OPENGL_ARB 0x2010 +#define WGL_DOUBLE_BUFFER_ARB 0x2011 +#define WGL_STEREO_ARB 0x2012 +#define WGL_PIXEL_TYPE_ARB 0x2013 +#define WGL_COLOR_BITS_ARB 0x2014 +#define WGL_RED_BITS_ARB 0x2015 +#define WGL_RED_SHIFT_ARB 0x2016 +#define WGL_GREEN_BITS_ARB 0x2017 +#define WGL_GREEN_SHIFT_ARB 0x2018 +#define WGL_BLUE_BITS_ARB 0x2019 +#define WGL_BLUE_SHIFT_ARB 0x201A +#define WGL_ALPHA_BITS_ARB 0x201B +#define WGL_ALPHA_SHIFT_ARB 0x201C +#define WGL_ACCUM_BITS_ARB 0x201D +#define WGL_ACCUM_RED_BITS_ARB 0x201E +#define WGL_ACCUM_GREEN_BITS_ARB 0x201F +#define WGL_ACCUM_BLUE_BITS_ARB 0x2020 +#define WGL_ACCUM_ALPHA_BITS_ARB 0x2021 +#define WGL_DEPTH_BITS_ARB 0x2022 +#define WGL_STENCIL_BITS_ARB 0x2023 +#define WGL_AUX_BUFFERS_ARB 0x2024 +#define WGL_NO_ACCELERATION_ARB 0x2025 +#define WGL_GENERIC_ACCELERATION_ARB 0x2026 +#define WGL_FULL_ACCELERATION_ARB 0x2027 +#define WGL_SWAP_EXCHANGE_ARB 0x2028 +#define WGL_SWAP_COPY_ARB 0x2029 +#define WGL_SWAP_UNDEFINED_ARB 0x202A +#define WGL_TYPE_RGBA_ARB 0x202B +#define WGL_TYPE_COLORINDEX_ARB 0x202C +#endif + +#ifndef WGL_ARB_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_ARB 0x2043 +#define ERROR_INCOMPATIBLE_DEVICE_CONTEXTS_ARB 0x2054 +#endif + +#ifndef WGL_ARB_pbuffer +#define WGL_DRAW_TO_PBUFFER_ARB 0x202D +#define WGL_MAX_PBUFFER_PIXELS_ARB 0x202E +#define WGL_MAX_PBUFFER_WIDTH_ARB 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_ARB 0x2030 +#define WGL_PBUFFER_LARGEST_ARB 0x2033 +#define WGL_PBUFFER_WIDTH_ARB 0x2034 +#define WGL_PBUFFER_HEIGHT_ARB 0x2035 +#define WGL_PBUFFER_LOST_ARB 0x2036 +#endif + +#ifndef WGL_ARB_render_texture +#define WGL_BIND_TO_TEXTURE_RGB_ARB 0x2070 +#define WGL_BIND_TO_TEXTURE_RGBA_ARB 0x2071 +#define WGL_TEXTURE_FORMAT_ARB 0x2072 +#define WGL_TEXTURE_TARGET_ARB 0x2073 +#define WGL_MIPMAP_TEXTURE_ARB 0x2074 +#define WGL_TEXTURE_RGB_ARB 0x2075 +#define WGL_TEXTURE_RGBA_ARB 0x2076 +#define WGL_NO_TEXTURE_ARB 0x2077 +#define WGL_TEXTURE_CUBE_MAP_ARB 0x2078 +#define WGL_TEXTURE_1D_ARB 0x2079 +#define WGL_TEXTURE_2D_ARB 0x207A +#define WGL_MIPMAP_LEVEL_ARB 0x207B +#define WGL_CUBE_MAP_FACE_ARB 0x207C +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB 0x207D +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_X_ARB 0x207E +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Y_ARB 0x207F +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Y_ARB 0x2080 +#define WGL_TEXTURE_CUBE_MAP_POSITIVE_Z_ARB 0x2081 +#define WGL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB 0x2082 +#define WGL_FRONT_LEFT_ARB 0x2083 +#define WGL_FRONT_RIGHT_ARB 0x2084 +#define WGL_BACK_LEFT_ARB 0x2085 +#define WGL_BACK_RIGHT_ARB 0x2086 +#define WGL_AUX0_ARB 0x2087 +#define WGL_AUX1_ARB 0x2088 +#define WGL_AUX2_ARB 0x2089 +#define WGL_AUX3_ARB 0x208A +#define WGL_AUX4_ARB 0x208B +#define WGL_AUX5_ARB 0x208C +#define WGL_AUX6_ARB 0x208D +#define WGL_AUX7_ARB 0x208E +#define WGL_AUX8_ARB 0x208F +#define WGL_AUX9_ARB 0x2090 +#endif + +#ifndef WGL_ARB_pixel_format_float +#define WGL_TYPE_RGBA_FLOAT_ARB 0x21A0 +#endif + +#ifndef WGL_ARB_create_context +#define WGL_CONTEXT_DEBUG_BIT_ARB 0x00000001 +#define WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB 0x00000002 +#define WGL_CONTEXT_MAJOR_VERSION_ARB 0x2091 +#define WGL_CONTEXT_MINOR_VERSION_ARB 0x2092 +#define WGL_CONTEXT_LAYER_PLANE_ARB 0x2093 +#define WGL_CONTEXT_FLAGS_ARB 0x2094 +#define ERROR_INVALID_VERSION_ARB 0x2095 +#endif + +#ifndef WGL_ARB_create_context_profile +#define WGL_CONTEXT_PROFILE_MASK_ARB 0x9126 +#define WGL_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001 +#define WGL_CONTEXT_COMPATIBILITY_PROFILE_BIT_ARB 0x00000002 +#define ERROR_INVALID_PROFILE_ARB 0x2096 +#endif + +#ifndef WGL_EXT_make_current_read +#define ERROR_INVALID_PIXEL_TYPE_EXT 0x2043 +#endif + +#ifndef WGL_EXT_pixel_format +#define WGL_NUMBER_PIXEL_FORMATS_EXT 0x2000 +#define WGL_DRAW_TO_WINDOW_EXT 0x2001 +#define WGL_DRAW_TO_BITMAP_EXT 0x2002 +#define WGL_ACCELERATION_EXT 0x2003 +#define WGL_NEED_PALETTE_EXT 0x2004 +#define WGL_NEED_SYSTEM_PALETTE_EXT 0x2005 +#define WGL_SWAP_LAYER_BUFFERS_EXT 0x2006 +#define WGL_SWAP_METHOD_EXT 0x2007 +#define WGL_NUMBER_OVERLAYS_EXT 0x2008 +#define WGL_NUMBER_UNDERLAYS_EXT 0x2009 +#define WGL_TRANSPARENT_EXT 0x200A +#define WGL_TRANSPARENT_VALUE_EXT 0x200B +#define WGL_SHARE_DEPTH_EXT 0x200C +#define WGL_SHARE_STENCIL_EXT 0x200D +#define WGL_SHARE_ACCUM_EXT 0x200E +#define WGL_SUPPORT_GDI_EXT 0x200F +#define WGL_SUPPORT_OPENGL_EXT 0x2010 +#define WGL_DOUBLE_BUFFER_EXT 0x2011 +#define WGL_STEREO_EXT 0x2012 +#define WGL_PIXEL_TYPE_EXT 0x2013 +#define WGL_COLOR_BITS_EXT 0x2014 +#define WGL_RED_BITS_EXT 0x2015 +#define WGL_RED_SHIFT_EXT 0x2016 +#define WGL_GREEN_BITS_EXT 0x2017 +#define WGL_GREEN_SHIFT_EXT 0x2018 +#define WGL_BLUE_BITS_EXT 0x2019 +#define WGL_BLUE_SHIFT_EXT 0x201A +#define WGL_ALPHA_BITS_EXT 0x201B +#define WGL_ALPHA_SHIFT_EXT 0x201C +#define WGL_ACCUM_BITS_EXT 0x201D +#define WGL_ACCUM_RED_BITS_EXT 0x201E +#define WGL_ACCUM_GREEN_BITS_EXT 0x201F +#define WGL_ACCUM_BLUE_BITS_EXT 0x2020 +#define WGL_ACCUM_ALPHA_BITS_EXT 0x2021 +#define WGL_DEPTH_BITS_EXT 0x2022 +#define WGL_STENCIL_BITS_EXT 0x2023 +#define WGL_AUX_BUFFERS_EXT 0x2024 +#define WGL_NO_ACCELERATION_EXT 0x2025 +#define WGL_GENERIC_ACCELERATION_EXT 0x2026 +#define WGL_FULL_ACCELERATION_EXT 0x2027 +#define WGL_SWAP_EXCHANGE_EXT 0x2028 +#define WGL_SWAP_COPY_EXT 0x2029 +#define WGL_SWAP_UNDEFINED_EXT 0x202A +#define WGL_TYPE_RGBA_EXT 0x202B +#define WGL_TYPE_COLORINDEX_EXT 0x202C +#endif + +#ifndef WGL_EXT_pbuffer +#define WGL_DRAW_TO_PBUFFER_EXT 0x202D +#define WGL_MAX_PBUFFER_PIXELS_EXT 0x202E +#define WGL_MAX_PBUFFER_WIDTH_EXT 0x202F +#define WGL_MAX_PBUFFER_HEIGHT_EXT 0x2030 +#define WGL_OPTIMAL_PBUFFER_WIDTH_EXT 0x2031 +#define WGL_OPTIMAL_PBUFFER_HEIGHT_EXT 0x2032 +#define WGL_PBUFFER_LARGEST_EXT 0x2033 +#define WGL_PBUFFER_WIDTH_EXT 0x2034 +#define WGL_PBUFFER_HEIGHT_EXT 0x2035 +#endif + +#ifndef WGL_EXT_depth_float +#define WGL_DEPTH_FLOAT_EXT 0x2040 +#endif + +#ifndef WGL_3DFX_multisample +#define WGL_SAMPLE_BUFFERS_3DFX 0x2060 +#define WGL_SAMPLES_3DFX 0x2061 +#endif + +#ifndef WGL_EXT_multisample +#define WGL_SAMPLE_BUFFERS_EXT 0x2041 +#define WGL_SAMPLES_EXT 0x2042 +#endif + +#ifndef WGL_I3D_digital_video_control +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_FRAMEBUFFER_I3D 0x2050 +#define WGL_DIGITAL_VIDEO_CURSOR_ALPHA_VALUE_I3D 0x2051 +#define WGL_DIGITAL_VIDEO_CURSOR_INCLUDED_I3D 0x2052 +#define WGL_DIGITAL_VIDEO_GAMMA_CORRECTED_I3D 0x2053 +#endif + +#ifndef WGL_I3D_gamma +#define WGL_GAMMA_TABLE_SIZE_I3D 0x204E +#define WGL_GAMMA_EXCLUDE_DESKTOP_I3D 0x204F +#endif + +#ifndef WGL_I3D_genlock +#define WGL_GENLOCK_SOURCE_MULTIVIEW_I3D 0x2044 +#define WGL_GENLOCK_SOURCE_EXTENAL_SYNC_I3D 0x2045 +#define WGL_GENLOCK_SOURCE_EXTENAL_FIELD_I3D 0x2046 +#define WGL_GENLOCK_SOURCE_EXTENAL_TTL_I3D 0x2047 +#define WGL_GENLOCK_SOURCE_DIGITAL_SYNC_I3D 0x2048 +#define WGL_GENLOCK_SOURCE_DIGITAL_FIELD_I3D 0x2049 +#define WGL_GENLOCK_SOURCE_EDGE_FALLING_I3D 0x204A +#define WGL_GENLOCK_SOURCE_EDGE_RISING_I3D 0x204B +#define WGL_GENLOCK_SOURCE_EDGE_BOTH_I3D 0x204C +#endif + +#ifndef WGL_I3D_image_buffer +#define WGL_IMAGE_BUFFER_MIN_ACCESS_I3D 0x00000001 +#define WGL_IMAGE_BUFFER_LOCK_I3D 0x00000002 +#endif + +#ifndef WGL_I3D_swap_frame_lock +#endif + +#ifndef WGL_NV_render_depth_texture +#define WGL_BIND_TO_TEXTURE_DEPTH_NV 0x20A3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_DEPTH_NV 0x20A4 +#define WGL_DEPTH_TEXTURE_FORMAT_NV 0x20A5 +#define WGL_TEXTURE_DEPTH_COMPONENT_NV 0x20A6 +#define WGL_DEPTH_COMPONENT_NV 0x20A7 +#endif + +#ifndef WGL_NV_render_texture_rectangle +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGB_NV 0x20A0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_RGBA_NV 0x20A1 +#define WGL_TEXTURE_RECTANGLE_NV 0x20A2 +#endif + +#ifndef WGL_ATI_pixel_format_float +#define WGL_TYPE_RGBA_FLOAT_ATI 0x21A0 +#endif + +#ifndef WGL_NV_float_buffer +#define WGL_FLOAT_COMPONENTS_NV 0x20B0 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_R_NV 0x20B1 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RG_NV 0x20B2 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGB_NV 0x20B3 +#define WGL_BIND_TO_TEXTURE_RECTANGLE_FLOAT_RGBA_NV 0x20B4 +#define WGL_TEXTURE_FLOAT_R_NV 0x20B5 +#define WGL_TEXTURE_FLOAT_RG_NV 0x20B6 +#define WGL_TEXTURE_FLOAT_RGB_NV 0x20B7 +#define WGL_TEXTURE_FLOAT_RGBA_NV 0x20B8 +#endif + +#ifndef WGL_3DL_stereo_control +#define WGL_STEREO_EMITTER_ENABLE_3DL 0x2055 +#define WGL_STEREO_EMITTER_DISABLE_3DL 0x2056 +#define WGL_STEREO_POLARITY_NORMAL_3DL 0x2057 +#define WGL_STEREO_POLARITY_INVERT_3DL 0x2058 +#endif + +#ifndef WGL_EXT_pixel_format_packed_float +#define WGL_TYPE_RGBA_UNSIGNED_FLOAT_EXT 0x20A8 +#endif + +#ifndef WGL_EXT_framebuffer_sRGB +#define WGL_FRAMEBUFFER_SRGB_CAPABLE_EXT 0x20A9 +#endif + +#ifndef WGL_NV_present_video +#define WGL_NUM_VIDEO_SLOTS_NV 0x20F0 +#endif + +#ifndef WGL_NV_video_out +#define WGL_BIND_TO_VIDEO_RGB_NV 0x20C0 +#define WGL_BIND_TO_VIDEO_RGBA_NV 0x20C1 +#define WGL_BIND_TO_VIDEO_RGB_AND_DEPTH_NV 0x20C2 +#define WGL_VIDEO_OUT_COLOR_NV 0x20C3 +#define WGL_VIDEO_OUT_ALPHA_NV 0x20C4 +#define WGL_VIDEO_OUT_DEPTH_NV 0x20C5 +#define WGL_VIDEO_OUT_COLOR_AND_ALPHA_NV 0x20C6 +#define WGL_VIDEO_OUT_COLOR_AND_DEPTH_NV 0x20C7 +#define WGL_VIDEO_OUT_FRAME 0x20C8 +#define WGL_VIDEO_OUT_FIELD_1 0x20C9 +#define WGL_VIDEO_OUT_FIELD_2 0x20CA +#define WGL_VIDEO_OUT_STACKED_FIELDS_1_2 0x20CB +#define WGL_VIDEO_OUT_STACKED_FIELDS_2_1 0x20CC +#endif + +#ifndef WGL_NV_swap_group +#endif + +#ifndef WGL_NV_gpu_affinity +#define WGL_ERROR_INCOMPATIBLE_AFFINITY_MASKS_NV 0x20D0 +#define WGL_ERROR_MISSING_AFFINITY_MASK_NV 0x20D1 +#endif + +#ifndef WGL_AMD_gpu_association +#define WGL_GPU_VENDOR_AMD 0x1F00 +#define WGL_GPU_RENDERER_STRING_AMD 0x1F01 +#define WGL_GPU_OPENGL_VERSION_STRING_AMD 0x1F02 +#define WGL_GPU_FASTEST_TARGET_GPUS_AMD 0x21A2 +#define WGL_GPU_RAM_AMD 0x21A3 +#define WGL_GPU_CLOCK_AMD 0x21A4 +#define WGL_GPU_NUM_PIPES_AMD 0x21A5 +#define WGL_GPU_NUM_SIMD_AMD 0x21A6 +#define WGL_GPU_NUM_RB_AMD 0x21A7 +#define WGL_GPU_NUM_SPI_AMD 0x21A8 +#endif + +#ifndef NV_video_capture +#define WGL_UNIQUE_ID_NV 0x20CE +#define WGL_NUM_VIDEO_CAPTURE_SLOTS_NV 0x20CF +#endif + +#ifndef NV_copy_image +#endif + + +/*************************************************************/ + +#ifndef WGL_ARB_pbuffer +DECLARE_HANDLE(HPBUFFERARB); +#endif +#ifndef WGL_EXT_pbuffer +DECLARE_HANDLE(HPBUFFEREXT); +#endif +#ifndef WGL_NV_present_video +DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); +#endif +#ifndef WGL_NV_video_output +DECLARE_HANDLE(HPVIDEODEV); +#endif +#ifndef WGL_NV_gpu_affinity +DECLARE_HANDLE(HPGPUNV); +DECLARE_HANDLE(HGPUNV); + +typedef struct _GPU_DEVICE { + DWORD cb; + CHAR DeviceName[32]; + CHAR DeviceString[128]; + DWORD Flags; + RECT rcVirtualScreen; +} GPU_DEVICE, *PGPU_DEVICE; +#endif +#ifndef WGL_NV_video_capture +DECLARE_HANDLE(HVIDEOINPUTDEVICENV); +#endif + +#ifndef WGL_ARB_buffer_region +#define WGL_ARB_buffer_region 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HANDLE WINAPI wglCreateBufferRegionARB (HDC, int, UINT); +extern VOID WINAPI wglDeleteBufferRegionARB (HANDLE); +extern BOOL WINAPI wglSaveBufferRegionARB (HANDLE, int, int, int, int); +extern BOOL WINAPI wglRestoreBufferRegionARB (HANDLE, int, int, int, int, int, int); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HANDLE (WINAPI * PFNWGLCREATEBUFFERREGIONARBPROC) (HDC hDC, int iLayerPlane, UINT uType); +typedef VOID (WINAPI * PFNWGLDELETEBUFFERREGIONARBPROC) (HANDLE hRegion); +typedef BOOL (WINAPI * PFNWGLSAVEBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height); +typedef BOOL (WINAPI * PFNWGLRESTOREBUFFERREGIONARBPROC) (HANDLE hRegion, int x, int y, int width, int height, int xSrc, int ySrc); +#endif + +#ifndef WGL_ARB_multisample +#define WGL_ARB_multisample 1 +#endif + +#ifndef WGL_ARB_extensions_string +#define WGL_ARB_extensions_string 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern const char * WINAPI wglGetExtensionsStringARB (HDC); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGARBPROC) (HDC hdc); +#endif + +#ifndef WGL_ARB_pixel_format +#define WGL_ARB_pixel_format 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC, int, int, UINT, const int *, int *); +extern BOOL WINAPI wglGetPixelFormatAttribfvARB (HDC, int, int, UINT, const int *, FLOAT *); +extern BOOL WINAPI wglChoosePixelFormatARB (HDC, const int *, const FLOAT *, UINT, int *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATARBPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif + +#ifndef WGL_ARB_make_current_read +#define WGL_ARB_make_current_read 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglMakeContextCurrentARB (HDC, HDC, HGLRC); +extern HDC WINAPI wglGetCurrentReadDCARB (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTARBPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCARBPROC) (void); +#endif + +#ifndef WGL_ARB_pbuffer +#define WGL_ARB_pbuffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HPBUFFERARB WINAPI wglCreatePbufferARB (HDC, int, int, int, const int *); +extern HDC WINAPI wglGetPbufferDCARB (HPBUFFERARB); +extern int WINAPI wglReleasePbufferDCARB (HPBUFFERARB, HDC); +extern BOOL WINAPI wglDestroyPbufferARB (HPBUFFERARB); +extern BOOL WINAPI wglQueryPbufferARB (HPBUFFERARB, int, int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HPBUFFERARB (WINAPI * PFNWGLCREATEPBUFFERARBPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCARBPROC) (HPBUFFERARB hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFERARBPROC) (HPBUFFERARB hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFERARBPROC) (HPBUFFERARB hPbuffer, int iAttribute, int *piValue); +#endif + +#ifndef WGL_ARB_render_texture +#define WGL_ARB_render_texture 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglBindTexImageARB (HPBUFFERARB, int); +extern BOOL WINAPI wglReleaseTexImageARB (HPBUFFERARB, int); +extern BOOL WINAPI wglSetPbufferAttribARB (HPBUFFERARB, const int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLBINDTEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASETEXIMAGEARBPROC) (HPBUFFERARB hPbuffer, int iBuffer); +typedef BOOL (WINAPI * PFNWGLSETPBUFFERATTRIBARBPROC) (HPBUFFERARB hPbuffer, const int *piAttribList); +#endif + +#ifndef WGL_ARB_pixel_format_float +#define WGL_ARB_pixel_format_float 1 +#endif + +#ifndef WGL_ARB_create_context +#define WGL_ARB_create_context 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HGLRC WINAPI wglCreateContextAttribsARB (HDC, HGLRC, const int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HGLRC (WINAPI * PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC hDC, HGLRC hShareContext, const int *attribList); +#endif + +#ifndef WGL_ARB_create_context_profile +#define WGL_ARB_create_context_profile 1 +#endif + +#ifndef WGL_EXT_display_color_table +#define WGL_EXT_display_color_table 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern GLboolean WINAPI wglCreateDisplayColorTableEXT (GLushort); +extern GLboolean WINAPI wglLoadDisplayColorTableEXT (const GLushort *, GLuint); +extern GLboolean WINAPI wglBindDisplayColorTableEXT (GLushort); +extern VOID WINAPI wglDestroyDisplayColorTableEXT (GLushort); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef GLboolean (WINAPI * PFNWGLCREATEDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef GLboolean (WINAPI * PFNWGLLOADDISPLAYCOLORTABLEEXTPROC) (const GLushort *table, GLuint length); +typedef GLboolean (WINAPI * PFNWGLBINDDISPLAYCOLORTABLEEXTPROC) (GLushort id); +typedef VOID (WINAPI * PFNWGLDESTROYDISPLAYCOLORTABLEEXTPROC) (GLushort id); +#endif + +#ifndef WGL_EXT_extensions_string +#define WGL_EXT_extensions_string 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern const char * WINAPI wglGetExtensionsStringEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef const char * (WINAPI * PFNWGLGETEXTENSIONSSTRINGEXTPROC) (void); +#endif + +#ifndef WGL_EXT_make_current_read +#define WGL_EXT_make_current_read 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglMakeContextCurrentEXT (HDC, HDC, HGLRC); +extern HDC WINAPI wglGetCurrentReadDCEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLMAKECONTEXTCURRENTEXTPROC) (HDC hDrawDC, HDC hReadDC, HGLRC hglrc); +typedef HDC (WINAPI * PFNWGLGETCURRENTREADDCEXTPROC) (void); +#endif + +#ifndef WGL_EXT_pbuffer +#define WGL_EXT_pbuffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern HPBUFFEREXT WINAPI wglCreatePbufferEXT (HDC, int, int, int, const int *); +extern HDC WINAPI wglGetPbufferDCEXT (HPBUFFEREXT); +extern int WINAPI wglReleasePbufferDCEXT (HPBUFFEREXT, HDC); +extern BOOL WINAPI wglDestroyPbufferEXT (HPBUFFEREXT); +extern BOOL WINAPI wglQueryPbufferEXT (HPBUFFEREXT, int, int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef HPBUFFEREXT (WINAPI * PFNWGLCREATEPBUFFEREXTPROC) (HDC hDC, int iPixelFormat, int iWidth, int iHeight, const int *piAttribList); +typedef HDC (WINAPI * PFNWGLGETPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer); +typedef int (WINAPI * PFNWGLRELEASEPBUFFERDCEXTPROC) (HPBUFFEREXT hPbuffer, HDC hDC); +typedef BOOL (WINAPI * PFNWGLDESTROYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer); +typedef BOOL (WINAPI * PFNWGLQUERYPBUFFEREXTPROC) (HPBUFFEREXT hPbuffer, int iAttribute, int *piValue); +#endif + +#ifndef WGL_EXT_pixel_format +#define WGL_EXT_pixel_format 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetPixelFormatAttribivEXT (HDC, int, int, UINT, int *, int *); +extern BOOL WINAPI wglGetPixelFormatAttribfvEXT (HDC, int, int, UINT, int *, FLOAT *); +extern BOOL WINAPI wglChoosePixelFormatEXT (HDC, const int *, const FLOAT *, UINT, int *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, int *piValues); +typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBFVEXTPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, int *piAttributes, FLOAT *pfValues); +typedef BOOL (WINAPI * PFNWGLCHOOSEPIXELFORMATEXTPROC) (HDC hdc, const int *piAttribIList, const FLOAT *pfAttribFList, UINT nMaxFormats, int *piFormats, UINT *nNumFormats); +#endif + +#ifndef WGL_EXT_swap_control +#define WGL_EXT_swap_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglSwapIntervalEXT (int); +extern int WINAPI wglGetSwapIntervalEXT (void); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLSWAPINTERVALEXTPROC) (int interval); +typedef int (WINAPI * PFNWGLGETSWAPINTERVALEXTPROC) (void); +#endif + +#ifndef WGL_EXT_depth_float +#define WGL_EXT_depth_float 1 +#endif + +#ifndef WGL_NV_vertex_array_range +#define WGL_NV_vertex_array_range 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern void* WINAPI wglAllocateMemoryNV (GLsizei, GLfloat, GLfloat, GLfloat); +extern void WINAPI wglFreeMemoryNV (void *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef void* (WINAPI * PFNWGLALLOCATEMEMORYNVPROC) (GLsizei size, GLfloat readfreq, GLfloat writefreq, GLfloat priority); +typedef void (WINAPI * PFNWGLFREEMEMORYNVPROC) (void *pointer); +#endif + +#ifndef WGL_3DFX_multisample +#define WGL_3DFX_multisample 1 +#endif + +#ifndef WGL_EXT_multisample +#define WGL_EXT_multisample 1 +#endif + +#ifndef WGL_OML_sync_control +#define WGL_OML_sync_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetSyncValuesOML (HDC, INT64 *, INT64 *, INT64 *); +extern BOOL WINAPI wglGetMscRateOML (HDC, INT32 *, INT32 *); +extern INT64 WINAPI wglSwapBuffersMscOML (HDC, INT64, INT64, INT64); +extern INT64 WINAPI wglSwapLayerBuffersMscOML (HDC, int, INT64, INT64, INT64); +extern BOOL WINAPI wglWaitForMscOML (HDC, INT64, INT64, INT64, INT64 *, INT64 *, INT64 *); +extern BOOL WINAPI wglWaitForSbcOML (HDC, INT64, INT64 *, INT64 *, INT64 *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETSYNCVALUESOMLPROC) (HDC hdc, INT64 *ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLGETMSCRATEOMLPROC) (HDC hdc, INT32 *numerator, INT32 *denominator); +typedef INT64 (WINAPI * PFNWGLSWAPBUFFERSMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef INT64 (WINAPI * PFNWGLSWAPLAYERBUFFERSMSCOMLPROC) (HDC hdc, int fuPlanes, INT64 target_msc, INT64 divisor, INT64 remainder); +typedef BOOL (WINAPI * PFNWGLWAITFORMSCOMLPROC) (HDC hdc, INT64 target_msc, INT64 divisor, INT64 remainder, INT64 *ust, INT64 *msc, INT64 *sbc); +typedef BOOL (WINAPI * PFNWGLWAITFORSBCOMLPROC) (HDC hdc, INT64 target_sbc, INT64 *ust, INT64 *msc, INT64 *sbc); +#endif + +#ifndef WGL_I3D_digital_video_control +#define WGL_I3D_digital_video_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetDigitalVideoParametersI3D (HDC, int, int *); +extern BOOL WINAPI wglSetDigitalVideoParametersI3D (HDC, int, const int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLSETDIGITALVIDEOPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); +#endif + +#ifndef WGL_I3D_gamma +#define WGL_I3D_gamma 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetGammaTableParametersI3D (HDC, int, int *); +extern BOOL WINAPI wglSetGammaTableParametersI3D (HDC, int, const int *); +extern BOOL WINAPI wglGetGammaTableI3D (HDC, int, USHORT *, USHORT *, USHORT *); +extern BOOL WINAPI wglSetGammaTableI3D (HDC, int, const USHORT *, const USHORT *, const USHORT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEPARAMETERSI3DPROC) (HDC hDC, int iAttribute, const int *piValue); +typedef BOOL (WINAPI * PFNWGLGETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, USHORT *puRed, USHORT *puGreen, USHORT *puBlue); +typedef BOOL (WINAPI * PFNWGLSETGAMMATABLEI3DPROC) (HDC hDC, int iEntries, const USHORT *puRed, const USHORT *puGreen, const USHORT *puBlue); +#endif + +#ifndef WGL_I3D_genlock +#define WGL_I3D_genlock 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglEnableGenlockI3D (HDC); +extern BOOL WINAPI wglDisableGenlockI3D (HDC); +extern BOOL WINAPI wglIsEnabledGenlockI3D (HDC, BOOL *); +extern BOOL WINAPI wglGenlockSourceI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSourceI3D (HDC, UINT *); +extern BOOL WINAPI wglGenlockSourceEdgeI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSourceEdgeI3D (HDC, UINT *); +extern BOOL WINAPI wglGenlockSampleRateI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSampleRateI3D (HDC, UINT *); +extern BOOL WINAPI wglGenlockSourceDelayI3D (HDC, UINT); +extern BOOL WINAPI wglGetGenlockSourceDelayI3D (HDC, UINT *); +extern BOOL WINAPI wglQueryGenlockMaxSourceDelayI3D (HDC, UINT *, UINT *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLENABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLDISABLEGENLOCKI3DPROC) (HDC hDC); +typedef BOOL (WINAPI * PFNWGLISENABLEDGENLOCKI3DPROC) (HDC hDC, BOOL *pFlag); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEI3DPROC) (HDC hDC, UINT uSource); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEI3DPROC) (HDC hDC, UINT *uSource); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT uEdge); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEEDGEI3DPROC) (HDC hDC, UINT *uEdge); +typedef BOOL (WINAPI * PFNWGLGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT uRate); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSAMPLERATEI3DPROC) (HDC hDC, UINT *uRate); +typedef BOOL (WINAPI * PFNWGLGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT uDelay); +typedef BOOL (WINAPI * PFNWGLGETGENLOCKSOURCEDELAYI3DPROC) (HDC hDC, UINT *uDelay); +typedef BOOL (WINAPI * PFNWGLQUERYGENLOCKMAXSOURCEDELAYI3DPROC) (HDC hDC, UINT *uMaxLineDelay, UINT *uMaxPixelDelay); +#endif + +#ifndef WGL_I3D_image_buffer +#define WGL_I3D_image_buffer 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern LPVOID WINAPI wglCreateImageBufferI3D (HDC, DWORD, UINT); +extern BOOL WINAPI wglDestroyImageBufferI3D (HDC, LPVOID); +extern BOOL WINAPI wglAssociateImageBufferEventsI3D (HDC, const HANDLE *, const LPVOID *, const DWORD *, UINT); +extern BOOL WINAPI wglReleaseImageBufferEventsI3D (HDC, const LPVOID *, UINT); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef LPVOID (WINAPI * PFNWGLCREATEIMAGEBUFFERI3DPROC) (HDC hDC, DWORD dwSize, UINT uFlags); +typedef BOOL (WINAPI * PFNWGLDESTROYIMAGEBUFFERI3DPROC) (HDC hDC, LPVOID pAddress); +typedef BOOL (WINAPI * PFNWGLASSOCIATEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const HANDLE *pEvent, const LPVOID *pAddress, const DWORD *pSize, UINT count); +typedef BOOL (WINAPI * PFNWGLRELEASEIMAGEBUFFEREVENTSI3DPROC) (HDC hDC, const LPVOID *pAddress, UINT count); +#endif + +#ifndef WGL_I3D_swap_frame_lock +#define WGL_I3D_swap_frame_lock 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglEnableFrameLockI3D (void); +extern BOOL WINAPI wglDisableFrameLockI3D (void); +extern BOOL WINAPI wglIsEnabledFrameLockI3D (BOOL *); +extern BOOL WINAPI wglQueryFrameLockMasterI3D (BOOL *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLENABLEFRAMELOCKI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLDISABLEFRAMELOCKI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLISENABLEDFRAMELOCKI3DPROC) (BOOL *pFlag); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMELOCKMASTERI3DPROC) (BOOL *pFlag); +#endif + +#ifndef WGL_I3D_swap_frame_usage +#define WGL_I3D_swap_frame_usage 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetFrameUsageI3D (float *); +extern BOOL WINAPI wglBeginFrameTrackingI3D (void); +extern BOOL WINAPI wglEndFrameTrackingI3D (void); +extern BOOL WINAPI wglQueryFrameTrackingI3D (DWORD *, DWORD *, float *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETFRAMEUSAGEI3DPROC) (float *pUsage); +typedef BOOL (WINAPI * PFNWGLBEGINFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLENDFRAMETRACKINGI3DPROC) (void); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMETRACKINGI3DPROC) (DWORD *pFrameCount, DWORD *pMissedFrames, float *pLastMissedUsage); +#endif + +#ifndef WGL_ATI_pixel_format_float +#define WGL_ATI_pixel_format_float 1 +#endif + +#ifndef WGL_NV_float_buffer +#define WGL_NV_float_buffer 1 +#endif + +#ifndef WGL_3DL_stereo_control +#define WGL_3DL_stereo_control 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglSetStereoEmitterState3DL (HDC, UINT); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLSETSTEREOEMITTERSTATE3DLPROC) (HDC hDC, UINT uState); +#endif + +#ifndef WGL_EXT_pixel_format_packed_float +#define WGL_EXT_pixel_format_packed_float 1 +#endif + +#ifndef WGL_EXT_framebuffer_sRGB +#define WGL_EXT_framebuffer_sRGB 1 +#endif + +#ifndef WGL_NV_present_video +#define WGL_NV_present_video 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern int WINAPI wglEnumerateVideoDevicesNV (HDC, HVIDEOOUTPUTDEVICENV *); +extern BOOL WINAPI wglBindVideoDeviceNV (HDC, unsigned int, HVIDEOOUTPUTDEVICENV, const int *); +extern BOOL WINAPI wglQueryCurrentContextNV (int, int *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef int (WINAPI * PFNWGLENUMERATEVIDEODEVICESNVPROC) (HDC hDC, HVIDEOOUTPUTDEVICENV *phDeviceList); +typedef BOOL (WINAPI * PFNWGLBINDVIDEODEVICENVPROC) (HDC hDC, unsigned int uVideoSlot, HVIDEOOUTPUTDEVICENV hVideoDevice, const int *piAttribList); +typedef BOOL (WINAPI * PFNWGLQUERYCURRENTCONTEXTNVPROC) (int iAttribute, int *piValue); +#endif + +#ifndef WGL_NV_video_output +#define WGL_NV_video_output 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglGetVideoDeviceNV (HDC, int, HPVIDEODEV *); +extern BOOL WINAPI wglReleaseVideoDeviceNV (HPVIDEODEV); +extern BOOL WINAPI wglBindVideoImageNV (HPVIDEODEV, HPBUFFERARB, int); +extern BOOL WINAPI wglReleaseVideoImageNV (HPBUFFERARB, int); +extern BOOL WINAPI wglSendPbufferToVideoNV (HPBUFFERARB, int, unsigned long *, BOOL); +extern BOOL WINAPI wglGetVideoInfoNV (HPVIDEODEV, unsigned long *, unsigned long *); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLGETVIDEODEVICENVPROC) (HDC hDC, int numDevices, HPVIDEODEV *hVideoDevice); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEODEVICENVPROC) (HPVIDEODEV hVideoDevice); +typedef BOOL (WINAPI * PFNWGLBINDVIDEOIMAGENVPROC) (HPVIDEODEV hVideoDevice, HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOIMAGENVPROC) (HPBUFFERARB hPbuffer, int iVideoBuffer); +typedef BOOL (WINAPI * PFNWGLSENDPBUFFERTOVIDEONVPROC) (HPBUFFERARB hPbuffer, int iBufferType, unsigned long *pulCounterPbuffer, BOOL bBlock); +typedef BOOL (WINAPI * PFNWGLGETVIDEOINFONVPROC) (HPVIDEODEV hpVideoDevice, unsigned long *pulCounterOutputPbuffer, unsigned long *pulCounterOutputVideo); +#endif + +#ifndef WGL_NV_swap_group +#define WGL_NV_swap_group 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglJoinSwapGroupNV (HDC, GLuint); +extern BOOL WINAPI wglBindSwapBarrierNV (GLuint, GLuint); +extern BOOL WINAPI wglQuerySwapGroupNV (HDC, GLuint *, GLuint *); +extern BOOL WINAPI wglQueryMaxSwapGroupsNV (HDC, GLuint *, GLuint *); +extern BOOL WINAPI wglQueryFrameCountNV (HDC, GLuint *); +extern BOOL WINAPI wglResetFrameCountNV (HDC); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLJOINSWAPGROUPNVPROC) (HDC hDC, GLuint group); +typedef BOOL (WINAPI * PFNWGLBINDSWAPBARRIERNVPROC) (GLuint group, GLuint barrier); +typedef BOOL (WINAPI * PFNWGLQUERYSWAPGROUPNVPROC) (HDC hDC, GLuint *group, GLuint *barrier); +typedef BOOL (WINAPI * PFNWGLQUERYMAXSWAPGROUPSNVPROC) (HDC hDC, GLuint *maxGroups, GLuint *maxBarriers); +typedef BOOL (WINAPI * PFNWGLQUERYFRAMECOUNTNVPROC) (HDC hDC, GLuint *count); +typedef BOOL (WINAPI * PFNWGLRESETFRAMECOUNTNVPROC) (HDC hDC); +#endif + +#ifndef WGL_NV_gpu_affinity +#define WGL_NV_gpu_affinity 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglEnumGpusNV (UINT, HGPUNV *); +extern BOOL WINAPI wglEnumGpuDevicesNV (HGPUNV, UINT, PGPU_DEVICE); +extern HDC WINAPI wglCreateAffinityDCNV (const HGPUNV *); +extern BOOL WINAPI wglEnumGpusFromAffinityDCNV (HDC, UINT, HGPUNV *); +extern BOOL WINAPI wglDeleteDCNV (HDC); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLENUMGPUSNVPROC) (UINT iGpuIndex, HGPUNV *phGpu); +typedef BOOL (WINAPI * PFNWGLENUMGPUDEVICESNVPROC) (HGPUNV hGpu, UINT iDeviceIndex, PGPU_DEVICE lpGpuDevice); +typedef HDC (WINAPI * PFNWGLCREATEAFFINITYDCNVPROC) (const HGPUNV *phGpuList); +typedef BOOL (WINAPI * PFNWGLENUMGPUSFROMAFFINITYDCNVPROC) (HDC hAffinityDC, UINT iGpuIndex, HGPUNV *hGpu); +typedef BOOL (WINAPI * PFNWGLDELETEDCNVPROC) (HDC hdc); +#endif + +#ifndef WGL_AMD_gpu_association +#define WGL_AMD_gpu_association 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern UINT WINAPI wglGetGPUIDsAMD (UINT, UINT *); +extern INT WINAPI wglGetGPUInfoAMD (UINT, int, GLenum, UINT, void *); +extern UINT WINAPI wglGetContextGPUIDAMD (HGLRC); +extern HGLRC WINAPI wglCreateAssociatedContextAMD (UINT); +extern HGLRC WINAPI wglCreateAssociatedContextAttribsAMD (UINT, HGLRC, const int *); +extern BOOL WINAPI wglDeleteAssociatedContextAMD (HGLRC); +extern BOOL WINAPI wglMakeAssociatedContextCurrentAMD (HGLRC); +extern HGLRC WINAPI wglGetCurrentAssociatedContextAMD (void); +extern VOID WINAPI wglBlitContextFramebufferAMD (HGLRC, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLint, GLbitfield, GLenum); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef UINT (WINAPI * PFNWGLGETGPUIDSAMDPROC) (UINT maxCount, UINT *ids); +typedef INT (WINAPI * PFNWGLGETGPUINFOAMDPROC) (UINT id, int property, GLenum dataType, UINT size, void *data); +typedef UINT (WINAPI * PFNWGLGETCONTEXTGPUIDAMDPROC) (HGLRC hglrc); +typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTAMDPROC) (UINT id); +typedef HGLRC (WINAPI * PFNWGLCREATEASSOCIATEDCONTEXTATTRIBSAMDPROC) (UINT id, HGLRC hShareContext, const int *attribList); +typedef BOOL (WINAPI * PFNWGLDELETEASSOCIATEDCONTEXTAMDPROC) (HGLRC hglrc); +typedef BOOL (WINAPI * PFNWGLMAKEASSOCIATEDCONTEXTCURRENTAMDPROC) (HGLRC hglrc); +typedef HGLRC (WINAPI * PFNWGLGETCURRENTASSOCIATEDCONTEXTAMDPROC) (void); +typedef VOID (WINAPI * PFNWGLBLITCONTEXTFRAMEBUFFERAMDPROC) (HGLRC dstCtx, GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter); +#endif + +#ifndef WGL_NV_video_capture +#define WGL_NV_video_capture 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglBindVideoCaptureDeviceNV (UINT, HVIDEOINPUTDEVICENV); +extern UINT WINAPI wglEnumerateVideoCaptureDevicesNV (HDC, HVIDEOINPUTDEVICENV *); +extern BOOL WINAPI wglLockVideoCaptureDeviceNV (HDC, HVIDEOINPUTDEVICENV); +extern BOOL WINAPI wglQueryVideoCaptureDeviceNV (HDC, HVIDEOINPUTDEVICENV, int, int *); +extern BOOL WINAPI wglReleaseVideoCaptureDeviceNV (HDC, HVIDEOINPUTDEVICENV); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLBINDVIDEOCAPTUREDEVICENVPROC) (UINT uVideoSlot, HVIDEOINPUTDEVICENV hDevice); +typedef UINT (WINAPI * PFNWGLENUMERATEVIDEOCAPTUREDEVICESNVPROC) (HDC hDc, HVIDEOINPUTDEVICENV *phDeviceList); +typedef BOOL (WINAPI * PFNWGLLOCKVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); +typedef BOOL (WINAPI * PFNWGLQUERYVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice, int iAttribute, int *piValue); +typedef BOOL (WINAPI * PFNWGLRELEASEVIDEOCAPTUREDEVICENVPROC) (HDC hDc, HVIDEOINPUTDEVICENV hDevice); +#endif + +#ifndef WGL_NV_copy_image +#define WGL_NV_copy_image 1 +#ifdef WGL_WGLEXT_PROTOTYPES +extern BOOL WINAPI wglCopyImageSubDataNV (HGLRC, GLuint, GLenum, GLint, GLint, GLint, GLint, HGLRC, GLuint, GLenum, GLint, GLint, GLint, GLint, GLsizei, GLsizei, GLsizei); +#endif /* WGL_WGLEXT_PROTOTYPES */ +typedef BOOL (WINAPI * PFNWGLCOPYIMAGESUBDATANVPROC) (HGLRC hSrcRC, GLuint srcName, GLenum srcTarget, GLint srcLevel, GLint srcX, GLint srcY, GLint srcZ, HGLRC hDstRC, GLuint dstName, GLenum dstTarget, GLint dstLevel, GLint dstX, GLint dstY, GLint dstZ, GLsizei width, GLsizei height, GLsizei depth); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/xorg-server/hw/xwin/glx/wglext.spec b/xorg-server/hw/xwin/glx/wglext.spec new file mode 100644 index 000000000..d282f786c --- /dev/null +++ b/xorg-server/hw/xwin/glx/wglext.spec @@ -0,0 +1,1093 @@ +# wglext.spec file +# DON'T REMOVE PREVIOUS LINE!!! libspec depends on it! +# +# Copyright (C) 1991-2002 Silicon Graphics, Inc. All Rights Reserved. +# +# This document is licensed under the SGI Free Software B License Version +# 2.0. For details, see http://oss.sgi.com/projects/FreeB/ . + +required-props: +param: retval retained +category: wgl ARB_buffer_region ARB_extensions_string ARB_pixel_format ARB_make_current_read ARB_pbuffer ARB_render_texture ARB_pixel_format_float EXT_display_color_table EXT_extensions_string EXT_make_current_read EXT_pbuffer EXT_pixel_format EXT_swap_control OML_sync_control I3D_digital_video_control I3D_gamma I3D_genlock I3D_image_buffer I3D_swap_frame_lock I3D_swap_frame_usage NV_vertex_array_range 3DL_stereo_control NV_swap_group NV_video_output NV_present_video ARB_create_context NV_gpu_affinity AMD_gpu_association NV_video_capture NV_copy_image +# required-props in wgl.spec (which is not used for anything): +# dlflags: notlistable handcode +# wglflags: client-handcode server-handcode non-dispatch + +# +# Boilerplate to define types used by some extensions. This is done +# up front, since it involves some complexities in protecting +# the declarations whether or not the -protect flag is given to +# the generator scripts. +# + +passthru: #ifndef WGL_ARB_pbuffer +passthru: DECLARE_HANDLE(HPBUFFERARB); +passthru: #endif +passthru: #ifndef WGL_EXT_pbuffer +passthru: DECLARE_HANDLE(HPBUFFEREXT); +passthru: #endif +passthru: #ifndef WGL_NV_present_video +passthru: DECLARE_HANDLE(HVIDEOOUTPUTDEVICENV); +passthru: #endif +passthru: #ifndef WGL_NV_video_output +passthru: DECLARE_HANDLE(HPVIDEODEV); +passthru: #endif +passthru: #ifndef WGL_NV_gpu_affinity +passthru: DECLARE_HANDLE(HPGPUNV); +passthru: DECLARE_HANDLE(HGPUNV); +passthru: +passthru: typedef struct _GPU_DEVICE { +passthru: DWORD cb; +passthru: CHAR DeviceName[32]; +passthru: CHAR DeviceString[128]; +passthru: DWORD Flags; +passthru: RECT rcVirtualScreen; +passthru: } GPU_DEVICE, *PGPU_DEVICE; +passthru: #endif +passthru: #ifndef WGL_NV_video_capture +passthru: DECLARE_HANDLE(HVIDEOINPUTDEVICENV); +passthru: #endif +passthru: + + +############################################################################### +# +# ARB Extension #4 +# ARB_buffer_region commands +# +############################################################################### + +CreateBufferRegionARB(hDC, iLayerPlane, uType) + return HANDLE + param hDC HDC in value + param iLayerPlane int in value + param uType UINT in value + category ARB_buffer_region + +DeleteBufferRegionARB(hRegion) + return VOID + param hRegion HANDLE in value + category ARB_buffer_region + +SaveBufferRegionARB(hRegion, x, y, width, height) + return BOOL + param hRegion HANDLE in value + param x int in value + param y int in value + param width int in value + param height int in value + category ARB_buffer_region + +RestoreBufferRegionARB(hRegion, x, y, width, height, xSrc, ySrc) + return BOOL + param hRegion HANDLE in value + param x int in value + param y int in value + param width int in value + param height int in value + param xSrc int in value + param ySrc int in value + category ARB_buffer_region + +############################################################################### +# +# ARB Extension #5 +# ARB_multisample commands +# +############################################################################### + +# (none) +newcategory: ARB_multisample + +############################################################################### +# +# ARB Extension #8 +# ARB_extensions_string commands +# +############################################################################### + +GetExtensionsStringARB(hdc) + return String + param hdc HDC in value + category ARB_extensions_string + +############################################################################### +# +# ARB Extension #9 +# ARB_pixel_format commands +# +############################################################################### + +GetPixelFormatAttribivARB(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues) + return BOOL + param hdc HDC in value + param iPixelFormat int in value + param iLayerPlane int in value + param nAttributes UINT in value + param piAttributes int in array [nAttributes] + param piValues int out array [nAttributes] + category ARB_pixel_format + +GetPixelFormatAttribfvARB(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues) + return BOOL + param hdc HDC in value + param iPixelFormat int in value + param iLayerPlane int in value + param nAttributes UINT in value + param piAttributes int in array [nAttributes] + param pfValues FLOAT out array [nAttributes] + category ARB_pixel_format + +ChoosePixelFormatARB(hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats) + return BOOL + param hdc HDC in value + param piAttribIList int in array [COMPSIZE()] + param pfAttribFList FLOAT in array [COMPSIZE()] + param nMaxFormats UINT in value + param piFormats int out array [COMPSIZE(nNumFormats)] + param nNumFormats UINT out reference + category ARB_pixel_format + +############################################################################### +# +# ARB Extension #10 +# ARB_make_current_read commands +# +############################################################################### + +MakeContextCurrentARB(hDrawDC, hReadDC, hglrc) + return BOOL + param hDrawDC HDC in value + param hReadDC HDC in value + param hglrc HGLRC in value + category ARB_make_current_read + +GetCurrentReadDCARB() + return HDC + category ARB_make_current_read + +############################################################################### +# +# ARB Extension #11 +# ARB_pbuffer commands +# +############################################################################### + +CreatePbufferARB(hDC, iPixelFormat, iWidth, iHeight, piAttribList) + return HPBUFFERARB + param hDC HDC in value + param iPixelFormat int in value + param iWidth int in value + param iHeight int in value + param piAttribList int in array [COMPSIZE()] + category ARB_pbuffer + +GetPbufferDCARB(hPbuffer) + return HDC + param hPbuffer HPBUFFERARB in value + category ARB_pbuffer + +ReleasePbufferDCARB(hPbuffer, hDC) + return int + param hPbuffer HPBUFFERARB in value + param hDC HDC in value + category ARB_pbuffer + +DestroyPbufferARB(hPbuffer) + return BOOL + param hPbuffer HPBUFFERARB in value + category ARB_pbuffer + +QueryPbufferARB(hPbuffer, iAttribute, piValue) + return BOOL + param hPbuffer HPBUFFERARB in value + param iAttribute int in value + param piValue int out reference + category ARB_pbuffer + +############################################################################### +# +# ARB Extension #20 +# ARB_render_texture commands +# +############################################################################### + +BindTexImageARB(hPbuffer, iBuffer) + return BOOL + param hPbuffer HPBUFFERARB in value + param iBuffer int in value + category ARB_render_texture + +ReleaseTexImageARB(hPbuffer, iBuffer) + return BOOL + param hPbuffer HPBUFFERARB in value + param iBuffer int in value + category ARB_render_texture + +SetPbufferAttribARB(hPbuffer, piAttribList) + return BOOL + param hPbuffer HPBUFFERARB in value + param piAttribList int in array [COMPSIZE()] + category ARB_render_texture + +############################################################################### +# +# ARB Extension #39 +# ARB_pixel_format_float commands +# +############################################################################### + +# (none) +newcategory: ARB_pixel_format_float + +############################################################################### +# +# ARB Extension #55 +# ARB_create_context commands +# +############################################################################### + +CreateContextAttribsARB(hDC, hShareContext, attribList) + return HGLRC + param hDC HDC in value + param hShareContext HGLRC in value + param attribList int in array [COMPSIZE()] + category ARB_create_context + +############################################################################### +# +# ARB Extension #74 +# ARB_create_context_profile commands +# +############################################################################### + +# (none) +newcategory: ARB_create_context_profile + + +############################################################################### +# +# Extension #167 +# EXT_display_color_table commands +# +############################################################################### + +CreateDisplayColorTableEXT(id) + return GLboolean + param id GLushort in value + category EXT_display_color_table + +LoadDisplayColorTableEXT(table, length) + return GLboolean + param table GLushort in array [length] + param length GLuint in value + category EXT_display_color_table + +BindDisplayColorTableEXT(id) + return GLboolean + param id GLushort in value + category EXT_display_color_table + +DestroyDisplayColorTableEXT(id) + return VOID + param id GLushort in value + category EXT_display_color_table + +############################################################################### +# +# Extension #168 +# EXT_extensions_string commands +# +############################################################################### + +GetExtensionsStringEXT() + return String + category EXT_extensions_string + +############################################################################### +# +# Extension #169 +# EXT_make_current_read commands +# +############################################################################### + +MakeContextCurrentEXT(hDrawDC, hReadDC, hglrc) + return BOOL + param hDrawDC HDC in value + param hReadDC HDC in value + param hglrc HGLRC in value + category EXT_make_current_read + +GetCurrentReadDCEXT() + return HDC + category EXT_make_current_read + +############################################################################### +# +# Extension #171 +# EXT_pbuffer commands +# +############################################################################### + +CreatePbufferEXT(hDC, iPixelFormat, iWidth, iHeight, piAttribList) + return HPBUFFEREXT + param hDC HDC in value + param iPixelFormat int in value + param iWidth int in value + param iHeight int in value + param piAttribList int in array [COMPSIZE()] + category EXT_pbuffer + +GetPbufferDCEXT(hPbuffer) + return HDC + param hPbuffer HPBUFFEREXT in value + category EXT_pbuffer + +ReleasePbufferDCEXT(hPbuffer, hDC) + return int + param hPbuffer HPBUFFEREXT in value + param hDC HDC in value + category EXT_pbuffer + +DestroyPbufferEXT(hPbuffer) + return BOOL + param hPbuffer HPBUFFEREXT in value + category EXT_pbuffer + +QueryPbufferEXT(hPbuffer, iAttribute, piValue) + return BOOL + param hPbuffer HPBUFFEREXT in value + param iAttribute int in value + param piValue int out reference + category EXT_pbuffer + +############################################################################### +# +# Extension #170 +# EXT_pixel_format commands +# +############################################################################### + +GetPixelFormatAttribivEXT(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, piValues) + return BOOL + param hdc HDC in value + param iPixelFormat int in value + param iLayerPlane int in value + param nAttributes UINT in value + param piAttributes int out array [nAttributes] + param piValues int out array [nAttributes] + category EXT_pixel_format + +GetPixelFormatAttribfvEXT(hdc, iPixelFormat, iLayerPlane, nAttributes, piAttributes, pfValues) + return BOOL + param hdc HDC in value + param iPixelFormat int in value + param iLayerPlane int in value + param nAttributes UINT in value + param piAttributes int out array [nAttributes] + param pfValues FLOAT out array [nAttributes] + category EXT_pixel_format + +ChoosePixelFormatEXT(hdc, piAttribIList, pfAttribFList, nMaxFormats, piFormats, nNumFormats) + return BOOL + param hdc HDC in value + param piAttribIList int in array [COMPSIZE()] + param pfAttribFList FLOAT in array [COMPSIZE()] + param nMaxFormats UINT in value + param piFormats int out array [COMPSIZE(nNumFormats)] + param nNumFormats UINT out reference + category EXT_pixel_format + +############################################################################### +# +# Extension #172 +# EXT_swap_control commands +# +############################################################################### + +SwapIntervalEXT(interval) + return BOOL + param interval int in value + category EXT_swap_control + +GetSwapIntervalEXT() + return int + category EXT_swap_control + +############################################################################### +# +# Extension #177 +# EXT_depth_float commands +# +############################################################################### + +# (none) +newcategory: EXT_depth_float + +############################################################################### +# +# Extension #190 +# NV_vertex_array_range commands +# +############################################################################### + +AllocateMemoryNV(size, readfreq, writefreq, priority) + return VoidPointer + param size GLsizei in value + param readfreq GLfloat in value + param writefreq GLfloat in value + param priority GLfloat in value + category NV_vertex_array_range + +FreeMemoryNV(pointer) + return void + param pointer void out array [1] + category NV_vertex_array_range + +############################################################################### +# +# Extension #207 +# 3DFX_multisample commands +# +############################################################################### + +# (none) +newcategory: 3DFX_multisample + +############################################################################### +# +# Extension #209 +# EXT_multisample commands +# +############################################################################### + +# (none) +newcategory: EXT_multisample + +############################################################################### +# +# Extension #242 +# OML_sync_control commands +# +############################################################################### + +GetSyncValuesOML(hdc, ust, msc, sbc) + return BOOL + param hdc HDC in value + param ust INT64 out array [1] + param msc INT64 out array [1] + param sbc INT64 out array [1] + category OML_sync_control + +GetMscRateOML(hdc, numerator, denominator) + return BOOL + param hdc HDC in value + param numerator INT32 out array [1] + param denominator INT32 out array [1] + category OML_sync_control + +SwapBuffersMscOML(hdc, target_msc, divisor, remainder) + return INT64 + param hdc HDC in value + param target_msc INT64 in value + param divisor INT64 in value + param remainder INT64 in value + category OML_sync_control + +SwapLayerBuffersMscOML(hdc, fuPlanes, target_msc, divisor, remainder) + return INT64 + param hdc HDC in value + param fuPlanes int in value + param target_msc INT64 in value + param divisor INT64 in value + param remainder INT64 in value + category OML_sync_control + +WaitForMscOML(hdc, target_msc, divisor, remainder , ust, msc, sbc) + return BOOL + param hdc HDC in value + param target_msc INT64 in value + param divisor INT64 in value + param remainder INT64 in value + param ust INT64 out array [1] + param msc INT64 out array [1] + param sbc INT64 out array [1] + category OML_sync_control + +WaitForSbcOML(hdc, target_sbc, ust, msc, sbc) + return BOOL + param hdc HDC in value + param target_sbc INT64 in value + param ust INT64 out array [1] + param msc INT64 out array [1] + param sbc INT64 out array [1] + category OML_sync_control + +############################################################################### +# +# Extension #250 +# I3D_digital_video_control commands +# +############################################################################### + +GetDigitalVideoParametersI3D(hDC, iAttribute, piValue) + return BOOL + param hDC HDC in value + param iAttribute int in value + param piValue int out array [COMPSIZE(iAttribute)] + category I3D_digital_video_control + +SetDigitalVideoParametersI3D(hDC, iAttribute, piValue) + return BOOL + param hDC HDC in value + param iAttribute int in value + param piValue int in array [COMPSIZE(iAttribute)] + category I3D_digital_video_control + +############################################################################### +# +# Extension #251 +# I3D_gamma commands +# +############################################################################### + +GetGammaTableParametersI3D(hDC, iAttribute, piValue) + return BOOL + param hDC HDC in value + param iAttribute int in value + param piValue int out array [COMPSIZE(iAttribute)] + category I3D_gamma + +SetGammaTableParametersI3D(hDC, iAttribute, piValue) + return BOOL + param hDC HDC in value + param iAttribute int in value + param piValue int in array [COMPSIZE(iAttribute)] + category I3D_gamma + +GetGammaTableI3D(hDC, iEntries, puRed, puGreen, puBlue) + return BOOL + param hDC HDC in value + param iEntries int in value + param puRed USHORT out array [iEntries] + param puGreen USHORT out array [iEntries] + param puBlue USHORT out array [iEntries] + category I3D_gamma + +SetGammaTableI3D(hDC, iEntries, puRed, puGreen, puBlue) + return BOOL + param hDC HDC in value + param iEntries int in value + param puRed USHORT in array [iEntries] + param puGreen USHORT in array [iEntries] + param puBlue USHORT in array [iEntries] + category I3D_gamma + +############################################################################### +# +# Extension #252 +# I3D_genlock commands +# +############################################################################### + +EnableGenlockI3D(hDC) + return BOOL + param hDC HDC in value + category I3D_genlock + +DisableGenlockI3D(hDC) + return BOOL + param hDC HDC in value + category I3D_genlock + +IsEnabledGenlockI3D(hDC, pFlag) + return BOOL + param hDC HDC in value + param pFlag BOOL out reference + category I3D_genlock + +GenlockSourceI3D(hDC, uSource) + return BOOL + param hDC HDC in value + param uSource UINT in value + category I3D_genlock + +GetGenlockSourceI3D(hDC, uSource) + return BOOL + param hDC HDC in value + param uSource UINT out reference + category I3D_genlock + +GenlockSourceEdgeI3D(hDC, uEdge) + return BOOL + param hDC HDC in value + param uEdge UINT in value + category I3D_genlock + +GetGenlockSourceEdgeI3D(hDC, uEdge) + return BOOL + param hDC HDC in value + param uEdge UINT out reference + category I3D_genlock + +GenlockSampleRateI3D(hDC, uRate) + return BOOL + param hDC HDC in value + param uRate UINT in value + category I3D_genlock + +GetGenlockSampleRateI3D(hDC, uRate) + return BOOL + param hDC HDC in value + param uRate UINT out reference + category I3D_genlock + +GenlockSourceDelayI3D(hDC, uDelay) + return BOOL + param hDC HDC in value + param uDelay UINT in value + category I3D_genlock + +GetGenlockSourceDelayI3D(hDC, uDelay) + return BOOL + param hDC HDC in value + param uDelay UINT out reference + category I3D_genlock + +QueryGenlockMaxSourceDelayI3D(hDC, uMaxLineDelay, uMaxPixelDelay) + return BOOL + param hDC HDC in value + param uMaxLineDelay UINT out reference + param uMaxPixelDelay UINT out reference + category I3D_genlock + +############################################################################### +# +# Extension #253 +# I3D_image_buffer commands +# +############################################################################### + +CreateImageBufferI3D(hDC, dwSize, uFlags) + return LPVOID + param hDC HDC in value + param dwSize DWORD in value + param uFlags UINT in value + category I3D_image_buffer + +DestroyImageBufferI3D(hDC, pAddress) + return BOOL + param hDC HDC in value + param pAddress LPVOID in value + category I3D_image_buffer + +AssociateImageBufferEventsI3D(hDC, pEvent, pAddress, pSize, count) + return BOOL + param hDC HDC in value + param pEvent HANDLE in array [count] + param pAddress LPVOID in array [count] + param pSize DWORD in array [count] + param count UINT in value + category I3D_image_buffer + +ReleaseImageBufferEventsI3D(hDC, pAddress, count) + return BOOL + param hDC HDC in value + param pAddress LPVOID in array [count] + param count UINT in value + category I3D_image_buffer + +############################################################################### +# +# Extension #254 +# I3D_swap_frame_lock commands +# +############################################################################### + +EnableFrameLockI3D() + return BOOL + category I3D_swap_frame_lock + +DisableFrameLockI3D() + return BOOL + category I3D_swap_frame_lock + +IsEnabledFrameLockI3D(pFlag) + return BOOL + param pFlag BOOL out reference + category I3D_swap_frame_lock + +QueryFrameLockMasterI3D(pFlag) + return BOOL + param pFlag BOOL out reference + category I3D_swap_frame_lock + +############################################################################### +# +# Extension #255 +# I3D_swap_frame_usage commands +# +############################################################################### + +GetFrameUsageI3D(pUsage) + return BOOL + param pUsage float out reference + category I3D_swap_frame_usage + +BeginFrameTrackingI3D() + return BOOL + category I3D_swap_frame_usage + +EndFrameTrackingI3D() + return BOOL + category I3D_swap_frame_usage + +QueryFrameTrackingI3D(pFrameCount, pMissedFrames, pLastMissedUsage) + return BOOL + param pFrameCount DWORD out reference + param pMissedFrames DWORD out reference + param pLastMissedUsage float out reference + category I3D_swap_frame_usage + +############################################################################### +# +# Extension #278 +# ATI_pixel_format_float commands +# +############################################################################### + +# (none) +newcategory: ATI_pixel_format_float + +############################################################################### +# +# Extension #281 +# NV_float_buffer commands +# +############################################################################### + +# (none) +newcategory: NV_float_buffer + +############################################################################### +# +# Extension #313 +# 3DL_stereo_control commands +# +############################################################################### + +SetStereoEmitterState3DL(hDC, uState) + return BOOL + param hDC HDC in value + param uState UINT in value + category 3DL_stereo_control + +############################################################################### +# +# Extension #328 +# EXT_pixel_format_packed_float commands +# +############################################################################### + +# (none) +newcategory: EXT_pixel_format_packed_float + +############################################################################### +# +# Extension #337 +# EXT_framebuffer_sRGB commands +# +############################################################################### + +# (none) +newcategory: EXT_framebuffer_sRGB + +############################################################################### +# +# Extension #347 +# NV_present_video commands +# +############################################################################### + +EnumerateVideoDevicesNV(hDC, phDeviceList) + return int + param hDC HDC in value + param phDeviceList HVIDEOOUTPUTDEVICENV out array + category NV_present_video + +BindVideoDeviceNV(hDC, uVideoSlot, hVideoDevice, piAttribList) + return BOOL + param hDC HDC in value + param uVideoSlot uint in value + param hVideoDevice HVIDEOOUTPUTDEVICENV in value + param piAttribList int in array [COMPSIZE()] + category NV_present_video + +QueryCurrentContextNV(iAttribute, piValue) + return BOOL + param iAttribute int in value + param piValue int out array [COMPSIZE()] + category NV_present_video + +############################################################################### +# +# Extension #349 +# NV_video_output commands +# +############################################################################### + +GetVideoDeviceNV(hDC, numDevices, hVideoDevice) + return BOOL + param hDC HDC in value + param numDevices int in value + param hVideoDevice HPVIDEODEV out reference + category NV_video_output + +ReleaseVideoDeviceNV(hVideoDevice) + return BOOL + param hVideoDevice HPVIDEODEV in value + category NV_video_output + +BindVideoImageNV(hVideoDevice, hPbuffer, iVideoBuffer) + return BOOL + param hVideoDevice HPVIDEODEV in value + param hPbuffer HPBUFFERARB in value + param iVideoBuffer int in value + category NV_video_output + +ReleaseVideoImageNV(hPbuffer, iVideoBuffer) + return BOOL + param hPbuffer HPBUFFERARB in value + param iVideoBuffer int in value + category NV_video_output + +SendPbufferToVideoNV(hPbuffer, iBufferType, pulCounterPbuffer, bBlock) + return BOOL + param hPbuffer HPBUFFERARB in value + param iBufferType int in value + param pulCounterPbuffer ulong out reference + param bBlock BOOL in value + category NV_video_output + +GetVideoInfoNV(hpVideoDevice, pulCounterOutputPbuffer, pulCounterOutputVideo) + return BOOL + param hpVideoDevice HPVIDEODEV in value + param pulCounterOutputPbuffer ulong out reference + param pulCounterOutputVideo ulong out reference + category NV_video_output + +############################################################################### +# +# Extension #351 +# NV_swap_group commands +# +############################################################################### + +JoinSwapGroupNV(hDC, group) + return BOOL + param hDC HDC in value + param group GLuint in value + category NV_swap_group + +BindSwapBarrierNV(group, barrier) + return BOOL + param group GLuint in value + param barrier GLuint in value + category NV_swap_group + +QuerySwapGroupNV(hDC, group, barrier) + return BOOL + param hDC HDC in value + param group GLuint out reference + param barrier GLuint out reference + category NV_swap_group + +QueryMaxSwapGroupsNV(hDC, maxGroups, maxBarriers) + return BOOL + param hDC HDC in value + param maxGroups GLuint out reference + param maxBarriers GLuint out reference + category NV_swap_group + +QueryFrameCountNV(hDC, count) + return BOOL + param hDC HDC in value + param count GLuint out reference + category NV_swap_group + +ResetFrameCountNV(hDC) + return BOOL + param hDC HDC in value + category NV_swap_group + +############################################################################### +# +# Extension #355 +# NV_gpu_affinity commands +# +############################################################################### + +EnumGpusNV(iGpuIndex, phGpu) + return BOOL + param iGpuIndex UINT in value + param phGpu HGPUNV out reference + category NV_gpu_affinity + +EnumGpuDevicesNV(hGpu, iDeviceIndex, lpGpuDevice) + return BOOL + param hGpu HGPUNV in value + param iDeviceIndex UINT in value + param lpGpuDevice PGPU_DEVICE in value + category NV_gpu_affinity + +CreateAffinityDCNV(phGpuList) + return HDC + param phGpuList HGPUNV in array [COMPSIZE()] + category NV_gpu_affinity + +EnumGpusFromAffinityDCNV(hAffinityDC, iGpuIndex, hGpu) + return BOOL + param hAffinityDC HDC in value + param iGpuIndex UINT in value + param hGpu HGPUNV out reference + category NV_gpu_affinity + +DeleteDCNV(hdc) + return BOOL + param hdc HDC in value + category NV_gpu_affinity + +############################################################################### +# +# Extension #361 +# AMD_gpu_association commands +# +############################################################################### + +GetGPUIDsAMD(maxCount, ids) + return UINT + param maxCount UINT in value + param ids UINT out array [maxCount] + category AMD_gpu_association + +GetGPUInfoAMD(id, property, dataType, size, data) + return INT + param id UINT in value + param property int in value + param dataType GLenum in value + param size UINT in value + param data void out array [COMPSIZE(dataType,size)] + category AMD_gpu_association + +GetContextGPUIDAMD(hglrc) + return UINT + param hglrc HGLRC in value + category AMD_gpu_association + +CreateAssociatedContextAMD(id) + return HGLRC + param id UINT in value + category AMD_gpu_association + +CreateAssociatedContextAttribsAMD(id, hShareContext, attribList) + return HGLRC + param id UINT in value + param hShareContext HGLRC in value + param attribList int in array [COMPSIZE()] + category AMD_gpu_association + +DeleteAssociatedContextAMD(hglrc) + return BOOL + param hglrc HGLRC in value + category AMD_gpu_association + +MakeAssociatedContextCurrentAMD(hglrc) + return BOOL + param hglrc HGLRC in value + category AMD_gpu_association + +GetCurrentAssociatedContextAMD() + return HGLRC + category AMD_gpu_association + +BlitContextFramebufferAMD(dstCtx, srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter) + return VOID + param dstCtx HGLRC in value + param srcX0 GLint in value + param srcY0 GLint in value + param srcX1 GLint in value + param srcY1 GLint in value + param dstX0 GLint in value + param dstY0 GLint in value + param dstX1 GLint in value + param dstY1 GLint in value + param mask GLbitfield in value + param filter GLenum in value + category AMD_gpu_association + +############################################################################### +# +# Extension #374 +# NV_video_capture commands +# +############################################################################### + +BindVideoCaptureDeviceNV(uVideoSlot, hDevice) + return BOOL + param uVideoSlot UINT in value + param hDevice HVIDEOINPUTDEVICENV in value + category NV_video_capture + +EnumerateVideoCaptureDevicesNV(hDc, phDeviceList) + return UINT + param hDc HDC in value + param phDeviceList HVIDEOINPUTDEVICENV out reference + category NV_video_capture + +LockVideoCaptureDeviceNV(hDc, hDevice) + return BOOL + param hDc HDC in value + param hDevice HVIDEOINPUTDEVICENV in value + category NV_video_capture + +QueryVideoCaptureDeviceNV(hDc, hDevice, iAttribute, piValue) + return BOOL + param hDc HDC in value + param hDevice HVIDEOINPUTDEVICENV in value + param iAttribute int in value + param piValue int out reference + category NV_video_capture + +ReleaseVideoCaptureDeviceNV(hDc, hDevice) + return BOOL + param hDc HDC in value + param hDevice HVIDEOINPUTDEVICENV in value + category NV_video_capture + +############################################################################### +# +# Extension #376 +# WGL_NV_copy_image commands +# +############################################################################### + +CopyImageSubDataNV(hSrcRC, srcName, srcTarget, srcLevel, srcX, srcY, srcZ, hDstRC, dstName, dstTarget, dstLevel, dstX, dstY, dstZ, width, height, depth) + return BOOL + param hSrcRC HGLRC in value + param srcName GLuint in value + param srcTarget GLenum in value + param srcLevel GLint in value + param srcX GLint in value + param srcY GLint in value + param srcZ GLint in value + param hDstRC HGLRC in value + param dstName GLuint in value + param dstTarget GLenum in value + param dstLevel GLint in value + param dstX GLint in value + param dstY GLint in value + param dstZ GLint in value + param width GLsizei in value + param height GLsizei in value + param depth GLsizei in value + category NV_copy_image diff --git a/xorg-server/hw/xwin/glx/winpriv.c b/xorg-server/hw/xwin/glx/winpriv.c index 3260ca95c..671d81a5b 100644 --- a/xorg-server/hw/xwin/glx/winpriv.c +++ b/xorg-server/hw/xwin/glx/winpriv.c @@ -11,6 +11,8 @@ #include "winpriv.h" #include "winwindow.h" +extern Bool g_fXdmcpEnabled; + void winCreateWindowsWindow (WindowPtr pWin); /** @@ -28,18 +30,31 @@ void winGetWindowInfo(WindowPtr pWin, winWindowInfoPtr pWinInfo) /* a real window was requested */ if (pWin != NULL) { + /* Initialize the size information */ + RECT rect = { + pWin->drawable.x, + pWin->drawable.y, + pWin->drawable.x + pWin->drawable.width, + pWin->drawable.y + pWin->drawable.height + }, rect_extends; /* Get the window and screen privates */ ScreenPtr pScreen = pWin->drawable.pScreen; winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen); winScreenInfoPtr pScreenInfo = NULL; - if (pWinScreen == NULL) + rect_extends = rect; + OffsetRect(&rect_extends, -pWin->drawable.x, -pWin->drawable.y); + + if (pWinScreen == NULL) { ErrorF("winGetWindowInfo: screen has no privates\n"); return; } pWinInfo->hwnd = pWinScreen->hwndScreen; + pWinInfo->hrgn = NULL; + pWinInfo->rect = rect; + pScreenInfo = pWinScreen->pScreenInfo; #ifdef XWIN_MULTIWINDOW @@ -59,15 +74,85 @@ void winGetWindowInfo(WindowPtr pWin, winWindowInfoPtr pWinInfo) winCreateWindowsWindow(pWin); ErrorF("winGetWindowInfo: forcing window to exist...\n"); } - if (pWinPriv->hWnd != NULL) - { - /* copy window handle */ + { + /* copy size and window handle */ + pWinInfo->rect = rect_extends; pWinInfo->hwnd = pWinPriv->hWnd; - } + /* Copy window region */ + if (pWinPriv->hRgn) + { + if (!pWinInfo->hrgn) + { + pWinInfo->hrgn = CreateRectRgn(0,0,0,0); + } + CombineRgn(pWinInfo->hrgn, pWinPriv->hRgn, pWinPriv->hRgn, + RGN_COPY); + } + else if (pWinInfo->hrgn) + { + DeleteObject(pWinInfo->hrgn); + pWinInfo->hrgn=NULL; + } + + } + return; } + else if (g_fXdmcpEnabled) + { + winWindowPriv(pWin); + + if (pWinPriv == NULL) + { + ErrorF("winGetWindowInfo: window has no privates\n"); + return; + } + if (pWinPriv->hWnd == NULL) + { + if (!((pWin->drawable.x==0) && + (pWin->drawable.y==0) && + (pWin->drawable.width==pScreen->width) && + (pWin->drawable.height==pScreen->height) + ) + ) + { + int ExtraClass=(pWin->realized)?WS_VISIBLE:0; + pWinPriv->hWnd=CreateWindowExA(WS_EX_TRANSPARENT, + WIN_GL_WINDOW_CLASS, + "", + WS_CHILD |WS_CLIPSIBLINGS | WS_CLIPCHILDREN | ExtraClass, + pWin->drawable.x, + pWin->drawable.y, + pWin->drawable.width, + pWin->drawable.height, + pWinScreen->hwndScreen, + NULL, + GetModuleHandle(NULL), + NULL); + pWinPriv->GlCtxWnd=TRUE; + /* copy size and window handle */ + pWinInfo->hwnd = pWinPriv->hWnd; + } + else + { + pWinInfo->hwnd = pWinScreen->hwndScreen; + } + pWinInfo->rect = rect_extends; + if (pWinInfo->hrgn) + { + DeleteObject(pWinInfo->hrgn); + pWinInfo->hrgn = NULL; + } + } + else + { + pWinInfo->rect = rect_extends; + pWinInfo->hwnd = pWinPriv->hWnd; + pWinInfo->hrgn = NULL; + } + } #endif #ifdef XWIN_MULTIWINDOWEXTWM /* check for multiwindow external wm mode */ @@ -83,7 +168,8 @@ void winGetWindowInfo(WindowPtr pWin, winWindowInfoPtr pWinInfo) if (pRLWinPriv->hWnd != NULL) { - /* copy window handle */ + /* copy size and window handle */ + pWinInfo->rect = rect_extends; pWinInfo->hwnd = pRLWinPriv->hWnd; } return; @@ -92,18 +178,21 @@ void winGetWindowInfo(WindowPtr pWin, winWindowInfoPtr pWinInfo) } else { + RECT rect = {0, 0, 0, 0}; ScreenPtr pScreen = g_ScreenInfo[0].pScreen; winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen); pWinInfo->hwnd = NULL; - + pWinInfo->hrgn = NULL; + pWinInfo->rect = rect; + if (pWinScreen == NULL) { ErrorF("winGetWindowInfo: screen has no privates\n"); return; } - ErrorF("winGetWindowInfo: returning root window\n"); + winDebug("winGetWindowInfo: returning root window\n"); pWinInfo->hwnd = pWinScreen->hwndScreen; } @@ -126,5 +215,8 @@ winCheckScreenAiglxIsSupported(ScreenPtr pScreen) return TRUE; #endif + if (g_fXdmcpEnabled) + return TRUE; + return FALSE; } diff --git a/xorg-server/hw/xwin/glx/winpriv.h b/xorg-server/hw/xwin/glx/winpriv.h index 9cb2981ad..b3a2c606b 100644 --- a/xorg-server/hw/xwin/glx/winpriv.h +++ b/xorg-server/hw/xwin/glx/winpriv.h @@ -7,9 +7,13 @@ #include <X11/Xwindows.h> #include <windowstr.h> +#define WIN_GL_WINDOW_CLASS "XWinGLTest" + typedef struct { HWND hwnd; + HRGN hrgn; + RECT rect; } winWindowInfoRec, *winWindowInfoPtr; void winGetWindowInfo(WindowPtr pWin, winWindowInfoPtr pWinInfo); diff --git a/xorg-server/hw/xwin/makefile b/xorg-server/hw/xwin/makefile new file mode 100644 index 000000000..ef0b32291 --- /dev/null +++ b/xorg-server/hw/xwin/makefile @@ -0,0 +1,113 @@ +LIBRARY = libXWin + +SRCS_CLIPBOARD = \ + winclipboardinit.c \ + winclipboardtextconv.c \ + winclipboardthread.c \ + winclipboardunicode.c \ + winclipboardwndproc.c \ + winclipboardwrappers.c \ + winclipboardxevents.c + +DEFINES += XWIN_CLIPBOARD + +SRCS_MULTIWINDOW = \ + winmultiwindowshape.c \ + winmultiwindowwindow.c \ + winmultiwindowwm.c \ + winmultiwindowwndproc.c + +DEFINES += XWIN_MULTIWINDOW + +#SRCS_MULTIWINDOWEXTWM = \ +# winwin32rootless.c \ +# winwin32rootlesswindow.c \ +# winwin32rootlesswndproc.c \ +# winwindowswm.c +#DEFINES += XWIN_MULTIWINDOWEXTWM + +SRCS_NATIVEGDI = \ + winclip.c \ + winfillsp.c \ + winfont.c \ + wingc.c \ + wingetsp.c \ + winnativegdi.c \ + winpixmap.c \ + winpolyline.c \ + winrop.c \ + winsetsp.c +DEFINES += XWIN_NATIVEGDI + + +SRCS_RANDR = \ + winrandr.c +DEFINES += XWIN_RANDR RELOCATE_PROJECTROOT + +CSRCS = InitInput.c \ + InitOutput.c \ + winallpriv.c \ + winauth.c \ + winblock.c \ + wincmap.c \ + winconfig.c \ + wincreatewnd.c \ + wincursor.c \ + windialogs.c \ + winengine.c \ + winerror.c \ + winglobals.c \ + winkeybd.c \ + winkeyhook.c \ + winmisc.c \ + winmouse.c \ + winmsg.c \ + winmultiwindowclass.c \ + winmultiwindowicons.c \ + winprefs.c \ + winprocarg.c \ + winregistry.c \ + winscrinit.c \ + winshaddd.c \ + winshadddnl.c \ + winshadgdi.c \ + wintrayicon.c \ + winvalargs.c \ + winwakeup.c \ + winwindow.c \ + winprefslex.c \ + winprefsyacc.c \ + winwndproc.c \ + windisplay.c \ + $(SRCS_RANDR) \ + $(SRCS_CLIPBOARD) \ + $(SRCS_MULTIWINDOW) \ + $(SRCS_MULTIWINDOWEXTWM) \ + $(SRCS_NATIVEGDI) + + +DEFINES += YY_NO_UNISTD_H + +# XWin.rc \ +# $(top_srcdir)/Xext/dpmsstubs.c \ +# $(top_srcdir)/Xi/stubs.c \ +# $(top_srcdir)/mi/miinitext.c \ +# $(top_srcdir)/fb/fbcmap_mi.c \ +# $(SRCS_PRIMARYFB) \ +# $(SRCS_XV) + +INCLUDES += ..\..\miext\rootless + +#.rc.o: + +# $(WINDRES) --use-temp-file -i $< --input-format=rc -o $@ -O coff -I $(top_builddir)/include -DPROJECT_NAME=\"$(VENDOR_NAME_SHORT)\" -DPROJECT_VERSION=\"$(PACKAGE_VERSION)\" -DBUILD_DATE=\"$(BUILD_DATE)\" + +DEFINES += HAVE_XWIN_CONFIG_H BUILD_DATE=0-0-0000 PTW32_STATIC_LIB + +#CSRCS=winkeybd.c + +winprefslex.c: winprefslex.l winprefsyacc.h + flex -i -o$@ $< + +winprefsyacc.c winprefsyacc.h: winprefsyacc.y + bison -d -owinprefsyacc.c $< diff --git a/xorg-server/hw/xwin/win.h b/xorg-server/hw/xwin/win.h index 9ab8ed976..90c498f81 100644 --- a/xorg-server/hw/xwin/win.h +++ b/xorg-server/hw/xwin/win.h @@ -1,1460 +1,1436 @@ -/* - *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: Dakshinamurthy Karra - * Suhaib M Siddiqi - * Peter Busch - * Harold L Hunt II - * Kensuke Matsuzaki - */ - -#ifndef _WIN_H_ -#define _WIN_H_ - -#ifndef NO -#define NO 0 -#endif -#ifndef YES -#define YES 1 -#endif - -/* Turn debug messages on or off */ -#ifndef CYGDEBUG -#define CYGDEBUG NO -#endif - -/* WM_XBUTTON Messages. They should go into w32api. */ -#ifndef WM_XBUTTONDOWN -# define WM_XBUTTONDOWN 523 -#endif -#ifndef WM_XBUTTONUP -# define WM_XBUTTONUP 524 -#endif -#ifndef WM_XBUTTONDBLCLK -# define WM_XBUTTONDBLCLK 525 -#endif - - -#define WIN_DEFAULT_BPP 0 -#define WIN_DEFAULT_WHITEPIXEL 255 -#define WIN_DEFAULT_BLACKPIXEL 0 -#define WIN_DEFAULT_LINEBIAS 0 -#define WIN_DEFAULT_E3B_TIME 50 /* milliseconds */ -#define WIN_DEFAULT_DPI 75 -#define WIN_DEFAULT_REFRESH 0 -#define WIN_DEFAULT_WIN_KILL TRUE -#define WIN_DEFAULT_UNIX_KILL FALSE -#define WIN_DEFAULT_CLIP_UPDATES_NBOXES 0 -#ifdef XWIN_EMULATEPSEUDO -#define WIN_DEFAULT_EMULATE_PSEUDO FALSE -#endif -#define WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH FALSE - -#define WIN_DIB_MAXIMUM_SIZE 0x08000000 /* 16 MB on Windows 95, 98, Me */ -#define WIN_DIB_MAXIMUM_SIZE_MB (WIN_DIB_MAXIMUM_SIZE / 8 / 1024 / 1024) - -/* - * Windows only supports 256 color palettes - */ -#define WIN_NUM_PALETTE_ENTRIES 256 - -/* - * Number of times to call Restore in an attempt to restore the primary surface - */ -#define WIN_REGAIN_SURFACE_RETRIES 1 - -/* - * Build a supported display depths mask by shifting one to the left - * by the number of bits in the supported depth. - */ -#define WIN_SUPPORTED_BPPS ( (1 << (32 - 1)) | (1 << (24 - 1)) \ - | (1 << (16 - 1)) | (1 << (15 - 1)) \ - | (1 << ( 8 - 1))) -#define WIN_CHECK_DEPTH YES - -/* - * Timer IDs for WM_TIMER - */ -#define WIN_E3B_TIMER_ID 1 -#define WIN_POLLING_MOUSE_TIMER_ID 2 - -#define MOUSE_POLLING_INTERVAL 50 - -#define WIN_E3B_OFF -1 -#define WIN_FD_INVALID -1 - -#define WIN_SERVER_NONE 0x0L /* 0 */ -#define WIN_SERVER_SHADOW_GDI 0x1L /* 1 */ -#define WIN_SERVER_SHADOW_DD 0x2L /* 2 */ -#define WIN_SERVER_SHADOW_DDNL 0x4L /* 4 */ -#ifdef XWIN_PRIMARYFB -#define WIN_SERVER_PRIMARY_DD 0x8L /* 8 */ -#endif -#ifdef XWIN_NATIVEGDI -# define WIN_SERVER_NATIVE_GDI 0x10L /* 16 */ -#endif - -#define AltMapIndex Mod1MapIndex -#define NumLockMapIndex Mod2MapIndex -#define AltLangMapIndex Mod3MapIndex -#define KanaMapIndex Mod4MapIndex -#define ScrollLockMapIndex Mod5MapIndex - -#define WIN_MOD_LALT 0x00000001 -#define WIN_MOD_RALT 0x00000002 -#define WIN_MOD_LCONTROL 0x00000004 -#define WIN_MOD_RCONTROL 0x00000008 - -#define WIN_24BPP_MASK_RED 0x00FF0000 -#define WIN_24BPP_MASK_GREEN 0x0000FF00 -#define WIN_24BPP_MASK_BLUE 0x000000FF - -#define WIN_MAX_KEYS_PER_KEY 4 - -#include <sys/types.h> -#include <sys/stat.h> -#include <stdio.h> - -#include <errno.h> -#if defined(XWIN_MULTIWINDOWEXTWM) || defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) -#define HANDLE void * -#include <pthread.h> -#undef HANDLE -#endif - -#ifdef HAS_MMAP -#include <sys/mman.h> -#ifndef MAP_FILE -#define MAP_FILE 0 -#endif /* MAP_FILE */ -#endif /* HAS_MMAP */ - -#include <X11/X.h> -#include <X11/Xproto.h> -#include <X11/Xos.h> -#include <X11/Xprotostr.h> -#include "scrnintstr.h" -#include "pixmapstr.h" -#include "pixmap.h" -#include "region.h" -#include "gcstruct.h" -#include "colormap.h" -#include "colormapst.h" -#include "miscstruct.h" -#include "servermd.h" -#include "windowstr.h" -#include "mi.h" -#include "micmap.h" -#include "mifillarc.h" -#include "mifpoly.h" -#include "mibstore.h" -#include "input.h" -#include "mipointer.h" -#include "X11/keysym.h" -#include "mibstore.h" -#include "micoord.h" -#include "dix.h" -#include "miline.h" -#include "shadow.h" -#include "fb.h" -#include "rootless.h" - -#ifdef RENDER -#include "mipict.h" -#include "picturestr.h" -#endif - -#ifdef RANDR -#include "randrstr.h" -#endif - -/* - * Windows headers - */ -#include "winms.h" -#include "./winresource.h" - - -/* - * Define Windows constants - */ - -#define WM_TRAYICON (WM_USER + 1000) -#define WM_INIT_SYS_MENU (WM_USER + 1001) -#define WM_GIVEUP (WM_USER + 1002) - - -/* Local includes */ -#include "winwindow.h" -#include "winmsg.h" - - -/* - * Debugging macros - */ - -#if CYGDEBUG -#define DEBUG_MSG(str,...) \ -if (fDebugProcMsg) \ -{ \ - char *pszTemp; \ - int iLength; \ - pszTemp = Xprintf (str, ##__VA_ARGS__); \ - MessageBox (NULL, pszTemp, szFunctionName, MB_OK); \ - xfree (pszTemp); \ -} -#else -#define DEBUG_MSG(str,...) -#endif - -#if CYGDEBUG -#define DEBUG_FN_NAME(str) PTSTR szFunctionName = str -#else -#define DEBUG_FN_NAME(str) -#endif - -#if CYGDEBUG || YES -#define DEBUGVARS BOOL fDebugProcMsg = FALSE -#else -#define DEBUGVARS -#endif - -#if CYGDEBUG || YES -#define DEBUGPROC_MSG fDebugProcMsg = TRUE -#else -#define DEBUGPROC_MSG -#endif - -#define PROFILEPOINT(point,thresh)\ -{\ -static unsigned int PROFPT##point = 0;\ -if (++PROFPT##point % thresh == 0)\ -ErrorF (#point ": PROFILEPOINT hit %u times\n", PROFPT##point);\ -} - - -/* We use xor this macro for detecting toggle key state changes */ -#define WIN_XOR(a,b) ((!(a) && (b)) || ((a) && !(b))) - -#define DEFINE_ATOM_HELPER(func,atom_name) \ -static Atom func (void) { \ - static int generation; \ - static Atom atom; \ - if (generation != serverGeneration) { \ - generation = serverGeneration; \ - atom = MakeAtom (atom_name, strlen (atom_name), TRUE); \ - } \ - return atom; \ -} - -/* - * Typedefs for engine dependent function pointers - */ - -typedef Bool (*winAllocateFBProcPtr)(ScreenPtr); - -typedef void (*winShadowUpdateProcPtr)(ScreenPtr, shadowBufPtr); - -typedef Bool (*winCloseScreenProcPtr)(int, ScreenPtr); - -typedef Bool (*winInitVisualsProcPtr)(ScreenPtr); - -typedef Bool (*winAdjustVideoModeProcPtr)(ScreenPtr); - -typedef Bool (*winCreateBoundingWindowProcPtr)(ScreenPtr); - -typedef Bool (*winFinishScreenInitProcPtr)(int, ScreenPtr, int, char **); - -typedef Bool (*winBltExposedRegionsProcPtr)(ScreenPtr); - -typedef Bool (*winActivateAppProcPtr)(ScreenPtr); - -typedef Bool (*winRedrawScreenProcPtr)(ScreenPtr pScreen); - -typedef Bool (*winRealizeInstalledPaletteProcPtr)(ScreenPtr pScreen); - -typedef Bool (*winInstallColormapProcPtr)(ColormapPtr pColormap); - -typedef Bool (*winStoreColorsProcPtr)(ColormapPtr pmap, - int ndef, xColorItem *pdefs); - -typedef Bool (*winCreateColormapProcPtr)(ColormapPtr pColormap); - -typedef Bool (*winDestroyColormapProcPtr)(ColormapPtr pColormap); - -typedef Bool (*winHotKeyAltTabProcPtr)(ScreenPtr); - -typedef Bool (*winCreatePrimarySurfaceProcPtr)(ScreenPtr); - -typedef Bool (*winReleasePrimarySurfaceProcPtr)(ScreenPtr); - -typedef Bool (*winFinishCreateWindowsWindowProcPtr)(WindowPtr pWin); - -typedef Bool (*winCreateScreenResourcesProc)(ScreenPtr); - -/* Typedef for DIX wrapper functions */ -typedef int (*winDispatchProcPtr) (ClientPtr); - - -/* - * GC (graphics context) privates - */ - -typedef struct -{ - HDC hdc; - HDC hdcMem; -} winPrivGCRec, *winPrivGCPtr; - - -/* - * Pixmap privates - */ - -typedef struct -{ - HDC hdcSelected; - HBITMAP hBitmap; - BYTE *pbBits; - DWORD dwScanlineBytes; - BITMAPINFOHEADER *pbmih; -} winPrivPixmapRec, *winPrivPixmapPtr; - - -/* - * Colormap privates - */ - -typedef struct -{ - HPALETTE hPalette; - LPDIRECTDRAWPALETTE lpDDPalette; - RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES]; - PALETTEENTRY peColors[WIN_NUM_PALETTE_ENTRIES]; -} winPrivCmapRec, *winPrivCmapPtr; - -/* - * Windows Cursor handling. - */ - -typedef struct { - /* from GetSystemMetrics */ - int sm_cx; - int sm_cy; - - BOOL visible; - HCURSOR handle; - QueryBestSizeProcPtr QueryBestSize; - miPointerSpriteFuncPtr spriteFuncs; -} winCursorRec; - -/* - * Screen information structure that we need before privates are available - * in the server startup sequence. - */ - -typedef struct -{ - ScreenPtr pScreen; - - /* Did the user specify a height and width? */ - Bool fUserGaveHeightAndWidth; - - DWORD dwScreen; - DWORD dwUserWidth; - DWORD dwUserHeight; - DWORD dwWidth; - DWORD dwHeight; - DWORD dwWidth_mm; - DWORD dwHeight_mm; - DWORD dwPaddedWidth; - - /* Did the user specify a screen position? */ - Bool fUserGavePosition; - DWORD dwInitialX; - DWORD dwInitialY; - - /* - * dwStride is the number of whole pixels that occupy a scanline, - * including those pixels that are not displayed. This is basically - * a rounding up of the width. - */ - DWORD dwStride; - - /* Offset of the screen in the window when using scrollbars */ - DWORD dwXOffset; - DWORD dwYOffset; - - DWORD dwBPP; - DWORD dwDepth; - DWORD dwRefreshRate; - char *pfb; - DWORD dwEngine; - DWORD dwEnginePreferred; - DWORD dwClipUpdatesNBoxes; -#ifdef XWIN_EMULATEPSEUDO - Bool fEmulatePseudo; -#endif - Bool fFullScreen; - Bool fDecoration; -#ifdef XWIN_MULTIWINDOWEXTWM - Bool fMWExtWM; - Bool fInternalWM; - Bool fAnotherWMRunning; -#endif - Bool fRootless; -#ifdef XWIN_MULTIWINDOW - Bool fMultiWindow; -#endif -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - Bool fMultiMonitorOverride; -#endif - Bool fMultipleMonitors; - Bool fLessPointer; - Bool fScrollbars; - Bool fNoTrayIcon; - int iE3BTimeout; - /* Windows (Alt+F4) and Unix (Ctrl+Alt+Backspace) Killkey */ - Bool fUseWinKillKey; - Bool fUseUnixKillKey; - Bool fIgnoreInput; - - /* Did the user explicitly set this screen? */ - Bool fExplicitScreen; -} winScreenInfo, *winScreenInfoPtr; - - -/* - * Screen privates - */ - -typedef struct _winPrivScreenRec -{ - winScreenInfoPtr pScreenInfo; - - Bool fEnabled; - Bool fClosed; - Bool fActive; - Bool fBadDepth; - - int iDeltaZ; - - int iConnectedClients; - - CloseScreenProcPtr CloseScreen; - - DWORD dwRedMask; - DWORD dwGreenMask; - DWORD dwBlueMask; - DWORD dwBitsPerRGB; - - DWORD dwModeKeyStates; - - /* Handle to icons that must be freed */ - HICON hiconNotifyIcon; - - /* Last width, height, and depth of the Windows display */ - DWORD dwLastWindowsWidth; - DWORD dwLastWindowsHeight; - DWORD dwLastWindowsBitsPixel; - - /* Palette management */ - ColormapPtr pcmapInstalled; - - /* Pointer to the root visual so we only have to look it up once */ - VisualPtr pRootVisual; - - /* 3 button emulation variables */ - int iE3BCachedPress; - Bool fE3BFakeButton2Sent; - - /* Privates used by shadow fb GDI server */ - HBITMAP hbmpShadow; - HDC hdcScreen; - HDC hdcShadow; - HWND hwndScreen; - - /* Privates used by shadow fb and primary fb DirectDraw servers */ - LPDIRECTDRAW pdd; - LPDIRECTDRAWSURFACE2 pddsPrimary; - LPDIRECTDRAW2 pdd2; - - /* Privates used by shadow fb DirectDraw server */ - LPDIRECTDRAWSURFACE2 pddsShadow; - LPDDSURFACEDESC pddsdShadow; - - /* Privates used by primary fb DirectDraw server */ - LPDIRECTDRAWSURFACE2 pddsOffscreen; - LPDDSURFACEDESC pddsdOffscreen; - LPDDSURFACEDESC pddsdPrimary; - - /* Privates used by shadow fb DirectDraw Nonlocking server */ - LPDIRECTDRAW4 pdd4; - LPDIRECTDRAWSURFACE4 pddsShadow4; - LPDIRECTDRAWSURFACE4 pddsPrimary4; - BOOL fRetryCreateSurface; - - /* Privates used by both shadow fb DirectDraw servers */ - LPDIRECTDRAWCLIPPER pddcPrimary; - -#ifdef XWIN_MULTIWINDOWEXTWM - /* Privates used by multi-window external window manager */ - RootlessFrameID widTop; - Bool fRestacking; -#endif - -#ifdef XWIN_MULTIWINDOW - /* Privates used by multi-window */ - pthread_t ptWMProc; - pthread_t ptXMsgProc; - void *pWMInfo; -#endif - -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - /* Privates used by both multi-window and rootless */ - Bool fRootWindowShown; -#endif - -#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) - /* Privates used for any module running in a seperate thread */ - pthread_mutex_t pmServerStarted; - Bool fServerStarted; -#endif - - /* Engine specific functions */ - winAllocateFBProcPtr pwinAllocateFB; - winShadowUpdateProcPtr pwinShadowUpdate; - winCloseScreenProcPtr pwinCloseScreen; - winInitVisualsProcPtr pwinInitVisuals; - winAdjustVideoModeProcPtr pwinAdjustVideoMode; - winCreateBoundingWindowProcPtr pwinCreateBoundingWindow; - winFinishScreenInitProcPtr pwinFinishScreenInit; - winBltExposedRegionsProcPtr pwinBltExposedRegions; - winActivateAppProcPtr pwinActivateApp; - winRedrawScreenProcPtr pwinRedrawScreen; - winRealizeInstalledPaletteProcPtr pwinRealizeInstalledPalette; - winInstallColormapProcPtr pwinInstallColormap; - winStoreColorsProcPtr pwinStoreColors; - winCreateColormapProcPtr pwinCreateColormap; - winDestroyColormapProcPtr pwinDestroyColormap; - winHotKeyAltTabProcPtr pwinHotKeyAltTab; - winCreatePrimarySurfaceProcPtr pwinCreatePrimarySurface; - winReleasePrimarySurfaceProcPtr pwinReleasePrimarySurface; - - winCreateScreenResourcesProc pwinCreateScreenResources; - -#ifdef XWIN_MULTIWINDOW - /* Window Procedures for MultiWindow mode */ - winFinishCreateWindowsWindowProcPtr pwinFinishCreateWindowsWindow; -#endif - - /* Window Procedures for Rootless mode */ - CreateWindowProcPtr CreateWindow; - DestroyWindowProcPtr DestroyWindow; - PositionWindowProcPtr PositionWindow; - ChangeWindowAttributesProcPtr ChangeWindowAttributes; - RealizeWindowProcPtr RealizeWindow; - UnrealizeWindowProcPtr UnrealizeWindow; - ValidateTreeProcPtr ValidateTree; - PostValidateTreeProcPtr PostValidateTree; - WindowExposuresProcPtr WindowExposures; - CopyWindowProcPtr CopyWindow; - ClearToBackgroundProcPtr ClearToBackground; - ClipNotifyProcPtr ClipNotify; - RestackWindowProcPtr RestackWindow; - ReparentWindowProcPtr ReparentWindow; - ResizeWindowProcPtr ResizeWindow; - MoveWindowProcPtr MoveWindow; - SetShapeProcPtr SetShape; - - winCursorRec cursor; -} winPrivScreenRec; - - -#ifdef XWIN_MULTIWINDOWEXTWM -typedef struct { - RootlessWindowPtr pFrame; - HWND hWnd; - int dwWidthBytes; - BITMAPINFOHEADER *pbmihShadow; - HBITMAP hbmpShadow; - HDC hdcShadow; - HDC hdcScreen; - BOOL fResized; - BOOL fRestackingNow; - BOOL fClose; - BOOL fMovingOrSizing; - BOOL fDestroyed;//for debug - char *pfb; -} win32RootlessWindowRec, *win32RootlessWindowPtr; -#endif - - -typedef struct { - pointer value; - XID id; -} WindowIDPairRec, *WindowIDPairPtr; - - -/* - * Extern declares for general global variables - */ - -extern winScreenInfo g_ScreenInfo[]; -extern miPointerScreenFuncRec g_winPointerCursorFuncs; -extern DWORD g_dwEvents; -#ifdef HAS_DEVWINDOWS -extern int g_fdMessageQueue; -#endif -extern DevPrivateKey g_iScreenPrivateKey; -extern DevPrivateKey g_iCmapPrivateKey; -extern DevPrivateKey g_iGCPrivateKey; -extern DevPrivateKey g_iPixmapPrivateKey; -extern DevPrivateKey g_iWindowPrivateKey; -extern unsigned long g_ulServerGeneration; -extern DWORD g_dwEnginesSupported; -extern HINSTANCE g_hInstance; -extern int g_copyROP[]; -extern int g_patternROP[]; -extern const char * g_pszQueryHost; -extern DeviceIntPtr g_pwinPointer; -extern DeviceIntPtr g_pwinKeyboard; - - -/* - * Extern declares for dynamically loaded libraries and function pointers - */ - -extern HMODULE g_hmodDirectDraw; -extern FARPROC g_fpDirectDrawCreate; -extern FARPROC g_fpDirectDrawCreateClipper; - -extern HMODULE g_hmodCommonControls; -extern FARPROC g_fpTrackMouseEvent; - - -/* - * Screen privates macros - */ - -#define winGetScreenPriv(pScreen) ((winPrivScreenPtr) \ - dixLookupPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey)) - -#define winSetScreenPriv(pScreen,v) \ - dixSetPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey, v) - -#define winScreenPriv(pScreen) \ - winPrivScreenPtr pScreenPriv = winGetScreenPriv(pScreen) - - -/* - * Colormap privates macros - */ - -#define winGetCmapPriv(pCmap) ((winPrivCmapPtr) \ - dixLookupPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey)) - -#define winSetCmapPriv(pCmap,v) \ - dixSetPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey, v) - -#define winCmapPriv(pCmap) \ - winPrivCmapPtr pCmapPriv = winGetCmapPriv(pCmap) - - -/* - * GC privates macros - */ - -#define winGetGCPriv(pGC) ((winPrivGCPtr) \ - dixLookupPrivate(&(pGC)->devPrivates, g_iGCPrivateKey)) - -#define winSetGCPriv(pGC,v) \ - dixSetPrivate(&(pGC)->devPrivates, g_iGCPrivateKey, v) - -#define winGCPriv(pGC) \ - winPrivGCPtr pGCPriv = winGetGCPriv(pGC) - - -/* - * Pixmap privates macros - */ - -#define winGetPixmapPriv(pPixmap) ((winPrivPixmapPtr) \ - dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey)) - -#define winSetPixmapPriv(pPixmap,v) \ - dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey, v) - -#define winPixmapPriv(pPixmap) \ - winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap) - - -/* - * Window privates macros - */ - -#define winGetWindowPriv(pWin) ((winPrivWinPtr) \ - dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey)) - -#define winSetWindowPriv(pWin,v) \ - dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey, v) - -#define winWindowPriv(pWin) \ - winPrivWinPtr pWinPriv = winGetWindowPriv(pWin) - -/* - * wrapper macros - */ -#define _WIN_WRAP(priv, real, mem, func) {\ - priv->mem = real->mem; \ - real->mem = func; \ -} - -#define _WIN_UNWRAP(priv, real, mem) {\ - real->mem = priv->mem; \ -} - -#define WIN_WRAP(mem, func) _WIN_WRAP(pScreenPriv, pScreen, mem, func) - -#define WIN_UNWRAP(mem) _WIN_UNWRAP(pScreenPriv, pScreen, mem) - -/* - * BEGIN DDX and DIX Function Prototypes - */ - - -/* - * winallpriv.c - */ - -Bool -winAllocatePrivates (ScreenPtr pScreen); - -Bool -winInitCmapPrivates (ColormapPtr pCmap, int index); - -Bool -winAllocateCmapPrivates (ColormapPtr pCmap); - - -/* - * winauth.c - */ - -#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) -Bool -winGenerateAuthorization (void); -void winSetAuthorization(void); -#endif - - -/* - * winblock.c - */ - -void -winBlockHandler (int nScreen, - pointer pBlockData, - pointer pTimeout, - pointer pReadMask); - - -#ifdef XWIN_NATIVEGDI -/* - * winclip.c - */ - -RegionPtr -winPixmapToRegionNativeGDI (PixmapPtr pPix); -#endif - - -#ifdef XWIN_CLIPBOARD -/* - * winclipboardinit.c - */ - -Bool -winInitClipboard (void); - -void -winFixClipboardChain (void); -#endif - - -/* - * wincmap.c - */ - -void -winSetColormapFunctions (ScreenPtr pScreen); - -Bool -winCreateDefColormap (ScreenPtr pScreen); - - -/* - * wincreatewnd.c - */ - -Bool -winCreateBoundingWindowFullScreen (ScreenPtr pScreen); - -Bool -winCreateBoundingWindowWindowed (ScreenPtr pScreen); - - -/* - * windialogs.c - */ - -void -winDisplayExitDialog (winPrivScreenPtr pScreenPriv); - -void -winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv); - -void -winDisplayAboutDialog (winPrivScreenPtr pScreenPriv); - - -/* - * winengine.c - */ - -void -winDetectSupportedEngines (void); - -Bool -winSetEngine (ScreenPtr pScreen); - -Bool -winGetDDProcAddresses (void); - - -/* - * winerror.c - */ - -#ifdef DDXOSVERRORF -void -OSVenderVErrorF (const char *pszFormat, va_list va_args); -#endif - -void -winMessageBoxF (const char *pszError, UINT uType, ...); - - -#ifdef XWIN_NATIVEGDI -/* - * winfillsp.c - */ - -void -winFillSpansNativeGDI (DrawablePtr pDrawable, - GCPtr pGC, - int nSpans, - DDXPointPtr pPoints, - int *pWidths, - int fSorted); -#endif - - -#ifdef XWIN_NATIVEGDI -/* - * winfont.c - */ - -Bool -winRealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont); - -Bool -winUnrealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont); -#endif - - -#ifdef XWIN_NATIVEGDI -/* - * wingc.c - */ - -Bool -winCreateGCNativeGDI (GCPtr pGC); -#endif - - -#ifdef XWIN_NATIVEGDI -/* - * wingetsp.c - */ - -void -winGetSpansNativeGDI (DrawablePtr pDrawable, - int wMax, - DDXPointPtr pPoints, - int *pWidths, - int nSpans, - char *pDst); -#endif - - -/* - * winglobals.c - */ - -void -winInitializeGlobals (void); - - -/* - * winkeybd.c - */ - -void -winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode); - -int -winKeybdProc (DeviceIntPtr pDeviceInt, int iState); - -void -winInitializeModeKeyStates (void); - -void -winRestoreModeKeyStates (void); - -Bool -winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam); - -void -winKeybdReleaseKeys (void); - -void -winSendKeyEvent (DWORD dwKey, Bool fDown); - -BOOL -winCheckKeyPressed(WPARAM wParam, LPARAM lParam); - -void -winFixShiftKeys (int iScanCode); - -/* - * winkeyhook.c - */ - -Bool -winInstallKeyboardHookLL (void); - -void -winRemoveKeyboardHookLL (void); - - -/* - * winmisc.c - */ - -#ifdef XWIN_NATIVEGDI -void -winQueryBestSizeNativeGDI (int class, unsigned short *pWidth, - unsigned short *pHeight, ScreenPtr pScreen); -#endif - -CARD8 -winCountBits (DWORD dw); - -Bool -winUpdateFBPointer (ScreenPtr pScreen, void *pbits); - -#ifdef XWIN_NATIVEGDI -BOOL -winPaintBackground (HWND hwnd, COLORREF colorref); -#endif - - -/* - * winmouse.c - */ - -int -winMouseProc (DeviceIntPtr pDeviceInt, int iState); - -int -winMouseWheel (ScreenPtr pScreen, int iDeltaZ); - -void -winMouseButtonsSendEvent (int iEventType, int iButton); - -int -winMouseButtonsHandle (ScreenPtr pScreen, - int iEventType, int iButton, - WPARAM wParam); - -void -winEnqueueMotion(int x, int y); - -#ifdef XWIN_NATIVEGDI -/* - * winnativegdi.c - */ - -HBITMAP -winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth, - BYTE **ppbBits, BITMAPINFO **ppbmi); - -Bool -winSetEngineFunctionsNativeGDI (ScreenPtr pScreen); -#endif - - -#ifdef XWIN_PRIMARYFB -/* - * winpfbddd.c - */ - -Bool -winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen); -#endif - - -#ifdef XWIN_NATIVEGDI -/* - * winpixmap.c - */ - -PixmapPtr -winCreatePixmapNativeGDI (ScreenPtr pScreen, int width, int height, int depth, - unsigned usage_hint); - -Bool -winDestroyPixmapNativeGDI (PixmapPtr pPixmap); - -Bool -winModifyPixmapHeaderNativeGDI (PixmapPtr pPixmap, - int iWidth, int iHeight, - int iDepth, - int iBitsPerPixel, - int devKind, - pointer pPixData); -#endif - -#ifdef XWIN_NATIVEGDI -/* - * winpolyline.c - */ - -void -winPolyLineNativeGDI (DrawablePtr pDrawable, - GCPtr pGC, - int mode, - int npt, - DDXPointPtr ppt); -#endif - - -#ifdef XWIN_NATIVEGDI -/* - * winpushpxl.c - */ - -void -winPushPixels (GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, - int dx, int dy, int xOrg, int yOrg); -#endif - - -/* - * winscrinit.c - */ - -Bool -winScreenInit (int index, - ScreenPtr pScreen, - int argc, char **argv); - -Bool -winFinishScreenInitFB (int index, - ScreenPtr pScreen, - int argc, char **argv); - -#if defined(XWIN_NATIVEGDI) -Bool -winFinishScreenInitNativeGDI (int index, - ScreenPtr pScreen, - int argc, char **argv); -#endif - - -#ifdef XWIN_NATIVEGDI -/* - * winsetsp.c - */ - -void -winSetSpansNativeGDI (DrawablePtr pDrawable, - GCPtr pGC, - char *pSrc, - DDXPointPtr pPoints, - int *pWidth, - int nSpans, - int fSorted); -#endif - - -/* - * winshaddd.c - */ - -Bool -winSetEngineFunctionsShadowDD (ScreenPtr pScreen); - - -/* - * winshadddnl.c - */ - -Bool -winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen); - - -/* - * winshadgdi.c - */ - -Bool -winSetEngineFunctionsShadowGDI (ScreenPtr pScreen); - - -/* - * winwakeup.c - */ - -void -winWakeupHandler (int nScreen, - pointer pWakeupData, - unsigned long ulResult, - pointer pReadmask); - - -/* - * winwindow.c - */ - -#ifdef XWIN_NATIVEGDI -Bool -winCreateWindowNativeGDI (WindowPtr pWin); - -Bool -winDestroyWindowNativeGDI (WindowPtr pWin); - -Bool -winPositionWindowNativeGDI (WindowPtr pWin, int x, int y); - -void -winCopyWindowNativeGDI (WindowPtr pWin, - DDXPointRec ptOldOrg, - RegionPtr prgnSrc); - -Bool -winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask); - -Bool -winUnmapWindowNativeGDI (WindowPtr pWindow); - -Bool -winMapWindowNativeGDI (WindowPtr pWindow); -#endif - -Bool -winCreateWindowRootless (WindowPtr pWindow); - -Bool -winDestroyWindowRootless (WindowPtr pWindow); - -Bool -winPositionWindowRootless (WindowPtr pWindow, int x, int y); - -Bool -winChangeWindowAttributesRootless (WindowPtr pWindow, unsigned long mask); - -Bool -winUnmapWindowRootless (WindowPtr pWindow); - -Bool -winMapWindowRootless (WindowPtr pWindow); - -void -winSetShapeRootless (WindowPtr pWindow); - - -/* - * winmultiwindowicons.c - Used by both multi-window and Win32Rootless - */ - -HICON -winXIconToHICON (WindowPtr pWin, int iconSize); - -void -winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon); - -#ifdef XWIN_MULTIWINDOW -/* - * winmultiwindowshape.c - */ - -void -winReshapeMultiWindow (WindowPtr pWin); - -void -winSetShapeMultiWindow (WindowPtr pWindow); - -void -winUpdateRgnMultiWindow (WindowPtr pWindow); -#endif - - -#ifdef XWIN_MULTIWINDOW -/* - * winmultiwindowwindow.c - */ - -Bool -winCreateWindowMultiWindow (WindowPtr pWindow); - -Bool -winDestroyWindowMultiWindow (WindowPtr pWindow); - -Bool -winPositionWindowMultiWindow (WindowPtr pWindow, int x, int y); - -Bool -winChangeWindowAttributesMultiWindow (WindowPtr pWindow, unsigned long mask); - -Bool -winUnmapWindowMultiWindow (WindowPtr pWindow); - -Bool -winMapWindowMultiWindow (WindowPtr pWindow); - -void -winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent); - -void -winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib); - -void -winReorderWindowsMultiWindow (void); - -void -winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w, - unsigned int h, WindowPtr pSib); -void -winMoveWindowMultiWindow (WindowPtr pWin, int x, int y, - WindowPtr pSib, VTKind kind); - -void -winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt, - RegionPtr oldRegion); - -XID -winGetWindowID (WindowPtr pWin); - -int -winAdjustXWindow (WindowPtr pWin, HWND hwnd); -#endif - - -#ifdef XWIN_MULTIWINDOW -/* - * winmultiwindowwndproc.c - */ - -LRESULT CALLBACK -winTopLevelWindowProc (HWND hwnd, UINT message, - WPARAM wParam, LPARAM lParam); -#endif - - -/* - * wintrayicon.c - */ - -void -winInitNotifyIcon (winPrivScreenPtr pScreenPriv); - -void -winDeleteNotifyIcon (winPrivScreenPtr pScreenPriv); - -LRESULT -winHandleIconMessage (HWND hwnd, UINT message, - WPARAM wParam, LPARAM lParam, - winPrivScreenPtr pScreenPriv); - - -/* - * winwndproc.c - */ - -LRESULT CALLBACK -winWindowProc (HWND hWnd, UINT message, - WPARAM wParam, LPARAM lParam); - - -#ifdef XWIN_MULTIWINDOWEXTWM -/* - * winwin32rootless.c - */ - -Bool -winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen, - int newX, int newY, RegionPtr pShape); - -void -winMWExtWMDestroyFrame (RootlessFrameID wid); - -void -winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY); - -void -winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen, - int newX, int newY, unsigned int newW, unsigned int newH, - unsigned int gravity); - -void -winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid); - -void -winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape); - -void -winMWExtWMUnmapFrame (RootlessFrameID wid); - -void -winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow); - -void -winMWExtWMStopDrawing (RootlessFrameID wid, Bool flush); - -void -winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage); - -void -winMWExtWMDamageRects (RootlessFrameID wid, int count, const BoxRec *rects, - int shift_x, int shift_y); - -void -winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin); - -void -winMWExtWMCopyBytes (unsigned int width, unsigned int height, - const void *src, unsigned int srcRowBytes, - void *dst, unsigned int dstRowBytes); - -void -winMWExtWMFillBytes (unsigned int width, unsigned int height, unsigned int value, - void *dst, unsigned int dstRowBytes); - -int -winMWExtWMCompositePixels (unsigned int width, unsigned int height, unsigned int function, - void *src[2], unsigned int srcRowBytes[2], - void *mask, unsigned int maskRowBytes, - void *dst[2], unsigned int dstRowBytes[2]); - -void -winMWExtWMCopyWindow (RootlessFrameID wid, int dstNrects, const BoxRec *dstRects, - int dx, int dy); -#endif - - -#ifdef XWIN_MULTIWINDOWEXTWM -/* - * winwin32rootlesswindow.c - */ - -void -winMWExtWMReorderWindows (ScreenPtr pScreen); - -void -winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y); - -void -winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h); - -void -winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h); - -void -winMWExtWMUpdateIcon (Window id); - -void -winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv, - winScreenInfoPtr pScreenInfo); - -wBOOL CALLBACK -winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam); - -Bool -winIsInternalWMRunning (winScreenInfoPtr pScreenInfo); - -void -winMWExtWMRestackWindows (ScreenPtr pScreen); -#endif - - -#ifdef XWIN_MULTIWINDOWEXTWM -/* - * winwin32rootlesswndproc.c - */ - -LRESULT CALLBACK -winMWExtWMWindowProc (HWND hwnd, UINT message, - WPARAM wParam, LPARAM lParam); -#endif - - -/* - * winwindowswm.c - */ - -void -winWindowsWMSendEvent (int type, unsigned int mask, int which, int arg, - Window window, int x, int y, int w, int h); - -void -winWindowsWMExtensionInit (void); - -/* - * wincursor.c - */ - -Bool -winInitCursor (ScreenPtr pScreen); - -/* - * END DDX and DIX Function Prototypes - */ - -#endif /* _WIN_H_ */ - +/*
+ *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: Dakshinamurthy Karra
+ * Suhaib M Siddiqi
+ * Peter Busch
+ * Harold L Hunt II
+ * Kensuke Matsuzaki
+ */
+
+#ifndef _WIN_H_
+#define _WIN_H_
+
+#ifndef NO
+#define NO 0
+#endif
+#ifndef YES
+#define YES 1
+#endif
+
+/* WM_XBUTTON Messages. They should go into w32api. */
+#ifndef WM_XBUTTONDOWN
+# define WM_XBUTTONDOWN 523
+#endif
+#ifndef WM_XBUTTONUP
+# define WM_XBUTTONUP 524
+#endif
+#ifndef WM_XBUTTONDBLCLK
+# define WM_XBUTTONDBLCLK 525
+#endif
+
+
+#define WIN_DEFAULT_BPP 0
+#define WIN_DEFAULT_WHITEPIXEL 255
+#define WIN_DEFAULT_BLACKPIXEL 0
+#define WIN_DEFAULT_LINEBIAS 0
+#define WIN_DEFAULT_E3B_TIME 50 /* milliseconds */
+#define WIN_DEFAULT_DPI 75
+#define WIN_DEFAULT_REFRESH 0
+#define WIN_DEFAULT_WIN_KILL TRUE
+#define WIN_DEFAULT_UNIX_KILL FALSE
+#define WIN_DEFAULT_CLIP_UPDATES_NBOXES 0
+#ifdef XWIN_EMULATEPSEUDO
+#define WIN_DEFAULT_EMULATE_PSEUDO FALSE
+#endif
+#define WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH FALSE
+
+#define WIN_DIB_MAXIMUM_SIZE 0x08000000 /* 16 MB on Windows 95, 98, Me */
+#define WIN_DIB_MAXIMUM_SIZE_MB (WIN_DIB_MAXIMUM_SIZE / 8 / 1024 / 1024)
+
+/*
+ * Windows only supports 256 color palettes
+ */
+#define WIN_NUM_PALETTE_ENTRIES 256
+
+/*
+ * Number of times to call Restore in an attempt to restore the primary surface
+ */
+#define WIN_REGAIN_SURFACE_RETRIES 1
+
+/*
+ * Build a supported display depths mask by shifting one to the left
+ * by the number of bits in the supported depth.
+ */
+#define WIN_SUPPORTED_BPPS ( (1 << (32 - 1)) | (1 << (24 - 1)) \
+ | (1 << (16 - 1)) | (1 << (15 - 1)) \
+ | (1 << ( 8 - 1)))
+#define WIN_CHECK_DEPTH YES
+
+/*
+ * Timer IDs for WM_TIMER
+ */
+#define WIN_E3B_TIMER_ID 1
+#define WIN_POLLING_MOUSE_TIMER_ID 2
+
+#define MOUSE_POLLING_INTERVAL 50
+
+#define WIN_E3B_OFF -1
+#define WIN_FD_INVALID -1
+
+#define WIN_SERVER_NONE 0x0L /* 0 */
+#define WIN_SERVER_SHADOW_GDI 0x1L /* 1 */
+#define WIN_SERVER_SHADOW_DD 0x2L /* 2 */
+#define WIN_SERVER_SHADOW_DDNL 0x4L /* 4 */
+#ifdef XWIN_PRIMARYFB
+#define WIN_SERVER_PRIMARY_DD 0x8L /* 8 */
+#endif
+#ifdef XWIN_NATIVEGDI
+# define WIN_SERVER_NATIVE_GDI 0x10L /* 16 */
+#endif
+
+#define AltMapIndex Mod1MapIndex
+#define NumLockMapIndex Mod2MapIndex
+#define AltLangMapIndex Mod3MapIndex
+#define KanaMapIndex Mod4MapIndex
+#define ScrollLockMapIndex Mod5MapIndex
+
+#define WIN_MOD_LALT 0x00000001
+#define WIN_MOD_RALT 0x00000002
+#define WIN_MOD_LCONTROL 0x00000004
+#define WIN_MOD_RCONTROL 0x00000008
+
+#define WIN_24BPP_MASK_RED 0x00FF0000
+#define WIN_24BPP_MASK_GREEN 0x0000FF00
+#define WIN_24BPP_MASK_BLUE 0x000000FF
+
+#define WIN_MAX_KEYS_PER_KEY 4
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+
+#include <errno.h>
+#if defined(XWIN_MULTIWINDOWEXTWM) || defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
+#define HANDLE void *
+#ifdef _MSC_VER
+typedef int pid_t;
+#endif
+#include <pthread.h>
+#undef HANDLE
+#endif
+
+#ifdef HAS_MMAP
+#include <sys/mman.h>
+#ifndef MAP_FILE
+#define MAP_FILE 0
+#endif /* MAP_FILE */
+#endif /* HAS_MMAP */
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/Xos.h>
+#include <X11/Xprotostr.h>
+#include "scrnintstr.h"
+#include "pixmapstr.h"
+#include "pixmap.h"
+#include "region.h"
+#include "gcstruct.h"
+#include "colormap.h"
+#include "colormapst.h"
+#include "miscstruct.h"
+#include "servermd.h"
+#include "windowstr.h"
+#include "mi.h"
+#include "micmap.h"
+#include "mifillarc.h"
+#include "mifpoly.h"
+#include "mibstore.h"
+#include "input.h"
+#include "mipointer.h"
+#include "X11/keysym.h"
+#include "mibstore.h"
+#include "micoord.h"
+#include "dix.h"
+#include "miline.h"
+#include "shadow.h"
+#include "fb.h"
+#include "rootless.h"
+
+#ifdef RENDER
+#include "mipict.h"
+#include "picturestr.h"
+#endif
+
+#ifdef RANDR
+#include "randrstr.h"
+#endif
+
+/*
+ * Windows headers
+ */
+#include "winms.h"
+#include "./winresource.h"
+
+
+/*
+ * Define Windows constants
+ */
+
+#define WM_TRAYICON (WM_USER + 1000)
+#define WM_INIT_SYS_MENU (WM_USER + 1001)
+#define WM_GIVEUP (WM_USER + 1002)
+
+
+/* Local includes */
+#include "winwindow.h"
+#include "winmsg.h"
+
+#define PROFILEPOINT(point,thresh)\
+{\
+static unsigned int PROFPT##point = 0;\
+if (++PROFPT##point % thresh == 0)\
+ErrorF (#point ": PROFILEPOINT hit %u times\n", PROFPT##point);\
+}
+
+
+/* We use xor this macro for detecting toggle key state changes */
+#define WIN_XOR(a,b) ((!(a) && (b)) || ((a) && !(b)))
+
+#define DEFINE_ATOM_HELPER(func,atom_name) \
+static Atom func (void) { \
+ static int generation; \
+ static Atom atom; \
+ if (generation != serverGeneration) { \
+ generation = serverGeneration; \
+ atom = MakeAtom (atom_name, strlen (atom_name), TRUE); \
+ } \
+ return atom; \
+}
+
+/*
+ * Typedefs for engine dependent function pointers
+ */
+
+typedef Bool (*winAllocateFBProcPtr)(ScreenPtr);
+
+typedef void (*winShadowUpdateProcPtr)(ScreenPtr, shadowBufPtr);
+
+typedef Bool (*winCloseScreenProcPtr)(int, ScreenPtr);
+
+typedef Bool (*winInitVisualsProcPtr)(ScreenPtr);
+
+typedef Bool (*winAdjustVideoModeProcPtr)(ScreenPtr);
+
+typedef Bool (*winCreateBoundingWindowProcPtr)(ScreenPtr);
+
+typedef Bool (*winFinishScreenInitProcPtr)(int, ScreenPtr, int, char **);
+
+typedef Bool (*winBltExposedRegionsProcPtr)(ScreenPtr);
+
+typedef Bool (*winActivateAppProcPtr)(ScreenPtr);
+
+typedef Bool (*winRedrawScreenProcPtr)(ScreenPtr pScreen);
+
+typedef Bool (*winRealizeInstalledPaletteProcPtr)(ScreenPtr pScreen);
+
+typedef Bool (*winInstallColormapProcPtr)(ColormapPtr pColormap);
+
+typedef Bool (*winStoreColorsProcPtr)(ColormapPtr pmap,
+ int ndef, xColorItem *pdefs);
+
+typedef Bool (*winCreateColormapProcPtr)(ColormapPtr pColormap);
+
+typedef Bool (*winDestroyColormapProcPtr)(ColormapPtr pColormap);
+
+typedef Bool (*winHotKeyAltTabProcPtr)(ScreenPtr);
+
+typedef Bool (*winCreatePrimarySurfaceProcPtr)(ScreenPtr);
+
+typedef Bool (*winReleasePrimarySurfaceProcPtr)(ScreenPtr);
+
+typedef Bool (*winFinishCreateWindowsWindowProcPtr)(WindowPtr pWin);
+
+typedef Bool (*winCreateScreenResourcesProc)(ScreenPtr);
+
+/* Typedef for DIX wrapper functions */
+typedef int (*winDispatchProcPtr) (ClientPtr);
+
+
+/*
+ * GC (graphics context) privates
+ */
+
+typedef struct
+{
+ HDC hdc;
+ HDC hdcMem;
+} winPrivGCRec, *winPrivGCPtr;
+
+
+/*
+ * Pixmap privates
+ */
+
+typedef struct
+{
+ HDC hdcSelected;
+ HBITMAP hBitmap;
+ BYTE *pbBits;
+ DWORD dwScanlineBytes;
+ BITMAPINFOHEADER *pbmih;
+} winPrivPixmapRec, *winPrivPixmapPtr;
+
+
+/*
+ * Colormap privates
+ */
+
+typedef struct
+{
+ HPALETTE hPalette;
+ LPDIRECTDRAWPALETTE lpDDPalette;
+ RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES];
+ PALETTEENTRY peColors[WIN_NUM_PALETTE_ENTRIES];
+} winPrivCmapRec, *winPrivCmapPtr;
+
+/*
+ * Windows Cursor handling.
+ */
+
+typedef struct {
+ /* from GetSystemMetrics */
+ int sm_cx;
+ int sm_cy;
+
+ BOOL visible;
+ HCURSOR handle;
+ QueryBestSizeProcPtr QueryBestSize;
+ miPointerSpriteFuncPtr spriteFuncs;
+} winCursorRec;
+
+/*
+ * Screen information structure that we need before privates are available
+ * in the server startup sequence.
+ */
+
+typedef struct
+{
+ ScreenPtr pScreen;
+
+ /* Did the user specify a height and width? */
+ Bool fUserGaveHeightAndWidth;
+
+ DWORD dwScreen;
+ DWORD dwUserWidth;
+ DWORD dwUserHeight;
+ DWORD dwWidth;
+ DWORD dwHeight;
+ DWORD dwWidth_mm;
+ DWORD dwHeight_mm;
+ DWORD dwPaddedWidth;
+
+ /* Did the user specify a screen position? */
+ Bool fUserGavePosition;
+ DWORD dwInitialX;
+ DWORD dwInitialY;
+
+ /*
+ * dwStride is the number of whole pixels that occupy a scanline,
+ * including those pixels that are not displayed. This is basically
+ * a rounding up of the width.
+ */
+ DWORD dwStride;
+
+ /* Offset of the screen in the window when using scrollbars */
+ DWORD dwXOffset;
+ DWORD dwYOffset;
+
+ DWORD dwBPP;
+ DWORD dwDepth;
+ DWORD dwRefreshRate;
+ char *pfb;
+ DWORD dwEngine;
+ DWORD dwEnginePreferred;
+ DWORD dwClipUpdatesNBoxes;
+#ifdef XWIN_EMULATEPSEUDO
+ Bool fEmulatePseudo;
+#endif
+ Bool fFullScreen;
+ Bool fDecoration;
+#ifdef XWIN_MULTIWINDOWEXTWM
+ Bool fMWExtWM;
+ Bool fInternalWM;
+ Bool fAnotherWMRunning;
+#endif
+ Bool fRootless;
+#ifdef XWIN_MULTIWINDOW
+ Bool fMultiWindow;
+#endif
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ Bool fMultiMonitorOverride;
+#endif
+ Bool fMultipleMonitors;
+ Bool fLessPointer;
+ Bool fScrollbars;
+ Bool fNoTrayIcon;
+ int iE3BTimeout;
+ /* Windows (Alt+F4) and Unix (Ctrl+Alt+Backspace) Killkey */
+ Bool fUseWinKillKey;
+ Bool fUseUnixKillKey;
+ Bool fIgnoreInput;
+
+ /* Did the user explicitly set this screen? */
+ Bool fExplicitScreen;
+} winScreenInfo, *winScreenInfoPtr;
+
+
+/*
+ * Screen privates
+ */
+
+typedef struct _winPrivScreenRec
+{
+ winScreenInfoPtr pScreenInfo;
+
+ Bool fEnabled;
+ Bool fClosed;
+ Bool fActive;
+ Bool fBadDepth;
+
+ int iDeltaZ;
+
+ int iConnectedClients;
+
+ CloseScreenProcPtr CloseScreen;
+
+ DWORD dwRedMask;
+ DWORD dwGreenMask;
+ DWORD dwBlueMask;
+ DWORD dwBitsPerRGB;
+
+ DWORD dwModeKeyStates;
+
+ /* Handle to icons that must be freed */
+ HICON hiconNotifyIcon;
+
+ /* Last width, height, and depth of the Windows display */
+ DWORD dwLastWindowsWidth;
+ DWORD dwLastWindowsHeight;
+ DWORD dwLastWindowsBitsPixel;
+
+ /* Palette management */
+ ColormapPtr pcmapInstalled;
+
+ /* Pointer to the root visual so we only have to look it up once */
+ VisualPtr pRootVisual;
+
+ /* 3 button emulation variables */
+ int iE3BCachedPress;
+ Bool fE3BFakeButton2Sent;
+
+ /* Privates used by shadow fb GDI server */
+ HBITMAP hbmpShadow;
+ HDC hdcScreen;
+ HDC hdcShadow;
+ HWND hwndScreen;
+
+ /* Privates used by shadow fb and primary fb DirectDraw servers */
+ LPDIRECTDRAW pdd;
+ LPDIRECTDRAWSURFACE2 pddsPrimary;
+ LPDIRECTDRAW2 pdd2;
+
+ /* Privates used by shadow fb DirectDraw server */
+ LPDIRECTDRAWSURFACE2 pddsShadow;
+ LPDDSURFACEDESC pddsdShadow;
+
+ /* Privates used by primary fb DirectDraw server */
+ LPDIRECTDRAWSURFACE2 pddsOffscreen;
+ LPDDSURFACEDESC pddsdOffscreen;
+ LPDDSURFACEDESC pddsdPrimary;
+
+ /* Privates used by shadow fb DirectDraw Nonlocking server */
+ LPDIRECTDRAW4 pdd4;
+ LPDIRECTDRAWSURFACE4 pddsShadow4;
+ LPDIRECTDRAWSURFACE4 pddsPrimary4;
+ BOOL fRetryCreateSurface;
+
+ /* Privates used by both shadow fb DirectDraw servers */
+ LPDIRECTDRAWCLIPPER pddcPrimary;
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+ /* Privates used by multi-window external window manager */
+ RootlessFrameID widTop;
+ Bool fRestacking;
+#endif
+
+#ifdef XWIN_MULTIWINDOW
+ /* Privates used by multi-window */
+ pthread_t ptWMProc;
+ pthread_t ptXMsgProc;
+ void *pWMInfo;
+#endif
+
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ /* Privates used by both multi-window and rootless */
+ Bool fRootWindowShown;
+#endif
+
+#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
+ /* Privates used for any module running in a seperate thread */
+ pthread_mutex_t pmServerStarted;
+ Bool fServerStarted;
+#endif
+
+ /* Engine specific functions */
+ winAllocateFBProcPtr pwinAllocateFB;
+ winShadowUpdateProcPtr pwinShadowUpdate;
+ winCloseScreenProcPtr pwinCloseScreen;
+ winInitVisualsProcPtr pwinInitVisuals;
+ winAdjustVideoModeProcPtr pwinAdjustVideoMode;
+ winCreateBoundingWindowProcPtr pwinCreateBoundingWindow;
+ winFinishScreenInitProcPtr pwinFinishScreenInit;
+ winBltExposedRegionsProcPtr pwinBltExposedRegions;
+ winActivateAppProcPtr pwinActivateApp;
+ winRedrawScreenProcPtr pwinRedrawScreen;
+ winRealizeInstalledPaletteProcPtr pwinRealizeInstalledPalette;
+ winInstallColormapProcPtr pwinInstallColormap;
+ winStoreColorsProcPtr pwinStoreColors;
+ winCreateColormapProcPtr pwinCreateColormap;
+ winDestroyColormapProcPtr pwinDestroyColormap;
+ winHotKeyAltTabProcPtr pwinHotKeyAltTab;
+ winCreatePrimarySurfaceProcPtr pwinCreatePrimarySurface;
+ winReleasePrimarySurfaceProcPtr pwinReleasePrimarySurface;
+
+ winCreateScreenResourcesProc pwinCreateScreenResources;
+
+#ifdef XWIN_MULTIWINDOW
+ /* Window Procedures for MultiWindow mode */
+ winFinishCreateWindowsWindowProcPtr pwinFinishCreateWindowsWindow;
+#endif
+
+ /* Window Procedures for Rootless mode */
+ CreateWindowProcPtr CreateWindow;
+ DestroyWindowProcPtr DestroyWindow;
+ PositionWindowProcPtr PositionWindow;
+ ChangeWindowAttributesProcPtr ChangeWindowAttributes;
+ RealizeWindowProcPtr RealizeWindow;
+ UnrealizeWindowProcPtr UnrealizeWindow;
+ ValidateTreeProcPtr ValidateTree;
+ PostValidateTreeProcPtr PostValidateTree;
+ WindowExposuresProcPtr WindowExposures;
+ CopyWindowProcPtr CopyWindow;
+ ClearToBackgroundProcPtr ClearToBackground;
+ ClipNotifyProcPtr ClipNotify;
+ RestackWindowProcPtr RestackWindow;
+ ReparentWindowProcPtr ReparentWindow;
+ ResizeWindowProcPtr ResizeWindow;
+ MoveWindowProcPtr MoveWindow;
+ SetShapeProcPtr SetShape;
+
+#ifdef XWIN_NATIVEGDI
+ RealizeFontProcPtr RealizeFont;
+ UnrealizeFontProcPtr UnrealizeFont;
+#endif
+
+ winCursorRec cursor;
+} winPrivScreenRec;
+
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+typedef struct {
+ RootlessWindowPtr pFrame;
+ HWND hWnd;
+ int dwWidthBytes;
+ BITMAPINFOHEADER *pbmihShadow;
+ HBITMAP hbmpShadow;
+ HDC hdcShadow;
+ HDC hdcScreen;
+ BOOL fResized;
+ BOOL fRestackingNow;
+ BOOL fClose;
+ BOOL fMovingOrSizing;
+ BOOL fDestroyed;//for debug
+ char *pfb;
+} win32RootlessWindowRec, *win32RootlessWindowPtr;
+#endif
+
+
+typedef struct {
+ pointer value;
+ XID id;
+} WindowIDPairRec, *WindowIDPairPtr;
+
+
+/*
+ * Extern declares for general global variables
+ */
+
+extern winScreenInfo g_ScreenInfo[];
+extern miPointerScreenFuncRec g_winPointerCursorFuncs;
+extern DWORD g_dwEvents;
+#ifdef HAS_DEVWINDOWS
+extern int g_fdMessageQueue;
+#endif
+extern DevPrivateKey g_iScreenPrivateKey;
+extern DevPrivateKey g_iCmapPrivateKey;
+extern DevPrivateKey g_iGCPrivateKey;
+extern DevPrivateKey g_iPixmapPrivateKey;
+extern DevPrivateKey g_iWindowPrivateKey;
+extern unsigned long g_ulServerGeneration;
+extern DWORD g_dwEnginesSupported;
+extern HINSTANCE g_hInstance;
+extern int g_copyROP[];
+extern int g_patternROP[];
+extern const char * g_pszQueryHost;
+extern DeviceIntPtr g_pwinPointer;
+extern DeviceIntPtr g_pwinKeyboard;
+
+
+/*
+ * Extern declares for dynamically loaded libraries and function pointers
+ */
+
+extern HMODULE g_hmodDirectDraw;
+extern FARPROC g_fpDirectDrawCreate;
+extern FARPROC g_fpDirectDrawCreateClipper;
+
+extern HMODULE g_hmodCommonControls;
+extern FARPROC g_fpTrackMouseEvent;
+
+
+/*
+ * Screen privates macros
+ */
+
+#define winGetScreenPriv(pScreen) ((winPrivScreenPtr) \
+ dixLookupPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey))
+
+#define winSetScreenPriv(pScreen,v) \
+ dixSetPrivate(&(pScreen)->devPrivates, g_iScreenPrivateKey, v)
+
+#define winScreenPriv(pScreen) \
+ winPrivScreenPtr pScreenPriv = winGetScreenPriv(pScreen)
+
+
+/*
+ * Colormap privates macros
+ */
+
+#define winGetCmapPriv(pCmap) ((winPrivCmapPtr) \
+ dixLookupPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey))
+
+#define winSetCmapPriv(pCmap,v) \
+ dixSetPrivate(&(pCmap)->devPrivates, g_iCmapPrivateKey, v)
+
+#define winCmapPriv(pCmap) \
+ winPrivCmapPtr pCmapPriv = winGetCmapPriv(pCmap)
+
+
+/*
+ * GC privates macros
+ */
+
+#define winGetGCPriv(pGC) ((winPrivGCPtr) \
+ dixLookupPrivate(&(pGC)->devPrivates, g_iGCPrivateKey))
+
+#define winSetGCPriv(pGC,v) \
+ dixSetPrivate(&(pGC)->devPrivates, g_iGCPrivateKey, v)
+
+#define winGCPriv(pGC) \
+ winPrivGCPtr pGCPriv = winGetGCPriv(pGC)
+
+
+/*
+ * Pixmap privates macros
+ */
+
+#define winGetPixmapPriv(pPixmap) ((winPrivPixmapPtr) \
+ dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey))
+
+#define winSetPixmapPriv(pPixmap,v) \
+ dixLookupPrivate(&(pPixmap)->devPrivates, g_iPixmapPrivateKey, v)
+
+#define winPixmapPriv(pPixmap) \
+ winPrivPixmapPtr pPixmapPriv = winGetPixmapPriv(pPixmap)
+
+
+/*
+ * Window privates macros
+ */
+
+#define winGetWindowPriv(pWin) ((winPrivWinPtr) \
+ dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey))
+
+#define winSetWindowPriv(pWin,v) \
+ dixLookupPrivate(&(pWin)->devPrivates, g_iWindowPrivateKey, v)
+
+#define winWindowPriv(pWin) \
+ winPrivWinPtr pWinPriv = winGetWindowPriv(pWin)
+
+/*
+ * wrapper macros
+ */
+#define _WIN_WRAP(priv, real, mem, func) {\
+ priv->mem = real->mem; \
+ real->mem = func; \
+}
+
+#define _WIN_UNWRAP(priv, real, mem) {\
+ real->mem = priv->mem; \
+}
+
+#define WIN_WRAP(mem, func) _WIN_WRAP(pScreenPriv, pScreen, mem, func)
+
+#define WIN_UNWRAP(mem) _WIN_UNWRAP(pScreenPriv, pScreen, mem)
+
+/*
+ * BEGIN DDX and DIX Function Prototypes
+ */
+
+
+/*
+ * winallpriv.c
+ */
+
+Bool
+winAllocatePrivates (ScreenPtr pScreen);
+
+Bool
+winInitCmapPrivates (ColormapPtr pCmap, int index);
+
+Bool
+winAllocateCmapPrivates (ColormapPtr pCmap);
+
+
+/*
+ * winauth.c
+ */
+
+#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
+Bool
+winGenerateAuthorization (void);
+void winSetAuthorization(void);
+#endif
+
+
+/*
+ * winblock.c
+ */
+
+void
+winBlockHandler (int nScreen,
+ pointer pBlockData,
+ pointer pTimeout,
+ pointer pReadMask);
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winclip.c
+ */
+
+RegionPtr
+winPixmapToRegionNativeGDI (PixmapPtr pPix);
+#endif
+
+
+#ifdef XWIN_CLIPBOARD
+/*
+ * winclipboardinit.c
+ */
+
+Bool
+winInitClipboard (void);
+
+void
+winFixClipboardChain (void);
+#endif
+
+
+/*
+ * wincmap.c
+ */
+
+void
+winSetColormapFunctions (ScreenPtr pScreen);
+
+Bool
+winCreateDefColormap (ScreenPtr pScreen);
+
+
+/*
+ * wincreatewnd.c
+ */
+
+Bool
+winCreateBoundingWindowFullScreen (ScreenPtr pScreen);
+
+Bool
+winCreateBoundingWindowWindowed (ScreenPtr pScreen);
+
+
+/*
+ * windialogs.c
+ */
+
+int
+GetLiveClients (winPrivScreenPtr pScreenPriv);
+
+void
+winDisplayExitDialog (winPrivScreenPtr pScreenPriv);
+
+void
+winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv);
+
+void
+winDisplayAboutDialog (winPrivScreenPtr pScreenPriv);
+
+
+/*
+ * winengine.c
+ */
+
+void
+winDetectSupportedEngines (void);
+
+Bool
+winSetEngine (ScreenPtr pScreen);
+
+Bool
+winGetDDProcAddresses (void);
+
+
+/*
+ * winerror.c
+ */
+
+#ifdef DDXOSVERRORF
+void
+OSVenderVErrorF (const char *pszFormat, va_list va_args);
+#endif
+
+void
+winMessageBoxF (const char *pszError, UINT uType, ...);
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winfillsp.c
+ */
+
+void
+winFillSpansNativeGDI (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int nSpans,
+ DDXPointPtr pPoints,
+ int *pWidths,
+ int fSorted);
+#endif
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winfont.c
+ */
+
+Bool
+winRealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont);
+
+Bool
+winUnrealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont);
+#endif
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * wingc.c
+ */
+
+Bool
+winCreateGCNativeGDI (GCPtr pGC);
+#endif
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * wingetsp.c
+ */
+
+void
+winGetSpansNativeGDI (DrawablePtr pDrawable,
+ int wMax,
+ DDXPointPtr pPoints,
+ int *pWidths,
+ int nSpans,
+ char *pDst);
+#endif
+
+
+/*
+ * winglobals.c
+ */
+
+void
+winInitializeGlobals (void);
+
+
+/*
+ * winkeybd.c
+ */
+
+void
+winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode);
+
+int
+winKeybdProc (DeviceIntPtr pDeviceInt, int iState);
+
+void
+winInitializeModeKeyStates (void);
+
+void
+winRestoreModeKeyStates (void);
+
+Bool
+winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam);
+
+void
+winKeybdReleaseKeys (void);
+
+void
+winSendKeyEvent (DWORD dwKey, Bool fDown);
+
+BOOL
+winCheckKeyPressed(WPARAM wParam, LPARAM lParam);
+
+void
+winFixShiftKeys (int iScanCode);
+
+/*
+ * winkeyhook.c
+ */
+
+Bool
+winInstallKeyboardHookLL (void);
+
+void
+winRemoveKeyboardHookLL (void);
+
+
+/*
+ * winmisc.c
+ */
+
+#ifdef XWIN_NATIVEGDI
+void
+winQueryBestSizeNativeGDI (int class, unsigned short *pWidth,
+ unsigned short *pHeight, ScreenPtr pScreen);
+#endif
+
+CARD8
+winCountBits (DWORD dw);
+
+Bool
+winUpdateFBPointer (ScreenPtr pScreen, void *pbits);
+
+#ifdef XWIN_NATIVEGDI
+BOOL
+winPaintBackground (HWND hwnd, COLORREF colorref);
+#endif
+
+
+/*
+ * winmouse.c
+ */
+
+int
+winMouseProc (DeviceIntPtr pDeviceInt, int iState);
+
+int
+winMouseWheel (ScreenPtr pScreen, int iDeltaZ);
+
+void
+winMouseButtonsSendEvent (int iEventType, int iButton);
+
+int
+winMouseButtonsHandle (ScreenPtr pScreen,
+ int iEventType, int iButton,
+ WPARAM wParam);
+
+void
+winEnqueueMotion(int x, int y);
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winnativegdi.c
+ */
+
+HBITMAP
+winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth,
+ BYTE **ppbBits, BITMAPINFO **ppbmi);
+
+Bool
+winSetEngineFunctionsNativeGDI (ScreenPtr pScreen);
+#endif
+
+
+#ifdef XWIN_PRIMARYFB
+/*
+ * winpfbddd.c
+ */
+
+Bool
+winSetEngineFunctionsPrimaryDD (ScreenPtr pScreen);
+#endif
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winpixmap.c
+ */
+
+PixmapPtr
+winCreatePixmapNativeGDI (ScreenPtr pScreen, int width, int height, int depth,
+ unsigned usage_hint);
+
+Bool
+winDestroyPixmapNativeGDI (PixmapPtr pPixmap);
+
+Bool
+winModifyPixmapHeaderNativeGDI (PixmapPtr pPixmap,
+ int iWidth, int iHeight,
+ int iDepth,
+ int iBitsPerPixel,
+ int devKind,
+ pointer pPixData);
+#endif
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winpolyline.c
+ */
+
+void
+winPolyLineNativeGDI (DrawablePtr pDrawable,
+ GCPtr pGC,
+ int mode,
+ int npt,
+ DDXPointPtr ppt);
+#endif
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winpushpxl.c
+ */
+
+void
+winPushPixels (GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable,
+ int dx, int dy, int xOrg, int yOrg);
+#endif
+
+
+/*
+ * winscrinit.c
+ */
+
+Bool
+winScreenInit (int index,
+ ScreenPtr pScreen,
+ int argc, char **argv);
+
+Bool
+winFinishScreenInitFB (int index,
+ ScreenPtr pScreen,
+ int argc, char **argv);
+
+#if defined(XWIN_NATIVEGDI)
+Bool
+winFinishScreenInitNativeGDI (int index,
+ ScreenPtr pScreen,
+ int argc, char **argv);
+#endif
+
+
+#ifdef XWIN_NATIVEGDI
+/*
+ * winsetsp.c
+ */
+
+void
+winSetSpansNativeGDI (DrawablePtr pDrawable,
+ GCPtr pGC,
+ char *pSrc,
+ DDXPointPtr pPoints,
+ int *pWidth,
+ int nSpans,
+ int fSorted);
+#endif
+
+
+/*
+ * winshaddd.c
+ */
+
+Bool
+winSetEngineFunctionsShadowDD (ScreenPtr pScreen);
+
+
+/*
+ * winshadddnl.c
+ */
+
+Bool
+winSetEngineFunctionsShadowDDNL (ScreenPtr pScreen);
+
+
+/*
+ * winshadgdi.c
+ */
+
+Bool
+winSetEngineFunctionsShadowGDI (ScreenPtr pScreen);
+
+
+/*
+ * winwakeup.c
+ */
+
+void
+winWakeupHandler (int nScreen,
+ pointer pWakeupData,
+ unsigned long ulResult,
+ pointer pReadmask);
+
+
+/*
+ * winwindow.c
+ */
+
+#ifdef XWIN_NATIVEGDI
+Bool
+winCreateWindowNativeGDI (WindowPtr pWin);
+
+Bool
+winDestroyWindowNativeGDI (WindowPtr pWin);
+
+Bool
+winPositionWindowNativeGDI (WindowPtr pWin, int x, int y);
+
+void
+winCopyWindowNativeGDI (WindowPtr pWin,
+ DDXPointRec ptOldOrg,
+ RegionPtr prgnSrc);
+
+Bool
+winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask);
+
+Bool
+winUnmapWindowNativeGDI (WindowPtr pWindow);
+
+Bool
+winMapWindowNativeGDI (WindowPtr pWindow);
+#endif
+
+Bool
+winCreateWindowRootless (WindowPtr pWindow);
+
+Bool
+winDestroyWindowRootless (WindowPtr pWindow);
+
+Bool
+winPositionWindowRootless (WindowPtr pWindow, int x, int y);
+
+Bool
+winChangeWindowAttributesRootless (WindowPtr pWindow, unsigned long mask);
+
+Bool
+winUnmapWindowRootless (WindowPtr pWindow);
+
+Bool
+winMapWindowRootless (WindowPtr pWindow);
+
+void
+winSetShapeRootless (WindowPtr pWindow);
+
+
+/*
+ * winmultiwindowicons.c - Used by both multi-window and Win32Rootless
+ */
+
+HICON
+winXIconToHICON (WindowPtr pWin, int iconSize);
+
+void
+winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon);
+
+#ifdef XWIN_MULTIWINDOW
+/*
+ * winmultiwindowshape.c
+ */
+
+void
+winReshapeMultiWindow (WindowPtr pWin);
+
+void
+winSetShapeMultiWindow (WindowPtr pWindow);
+
+void
+winUpdateRgnMultiWindow (WindowPtr pWindow);
+#endif
+
+
+#ifdef XWIN_MULTIWINDOW
+/*
+ * winmultiwindowwindow.c
+ */
+
+Bool
+winCreateWindowMultiWindow (WindowPtr pWindow);
+
+Bool
+winDestroyWindowMultiWindow (WindowPtr pWindow);
+
+Bool
+winPositionWindowMultiWindow (WindowPtr pWindow, int x, int y);
+
+Bool
+winChangeWindowAttributesMultiWindow (WindowPtr pWindow, unsigned long mask);
+
+Bool
+winUnmapWindowMultiWindow (WindowPtr pWindow);
+
+Bool
+winMapWindowMultiWindow (WindowPtr pWindow);
+
+void
+winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent);
+
+void
+winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib);
+
+void
+winReorderWindowsMultiWindow (void);
+
+void
+winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w,
+ unsigned int h, WindowPtr pSib);
+void
+winMoveWindowMultiWindow (WindowPtr pWin, int x, int y,
+ WindowPtr pSib, VTKind kind);
+
+void
+winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt,
+ RegionPtr oldRegion);
+
+XID
+winGetWindowID (WindowPtr pWin);
+
+int
+winAdjustXWindow (WindowPtr pWin, HWND hwnd);
+#endif
+
+
+#ifdef XWIN_MULTIWINDOW
+/*
+ * winmultiwindowwndproc.c
+ */
+
+LRESULT CALLBACK
+winTopLevelWindowProc (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam);
+#endif
+
+
+/*
+ * wintrayicon.c
+ */
+
+void
+winInitNotifyIcon (winPrivScreenPtr pScreenPriv, Bool Modify);
+
+void
+winDeleteNotifyIcon (winPrivScreenPtr pScreenPriv);
+
+LRESULT
+winHandleIconMessage (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam,
+ winPrivScreenPtr pScreenPriv);
+
+
+/*
+ * winwndproc.c
+ */
+
+LRESULT CALLBACK
+winWindowProc (HWND hWnd, UINT message,
+ WPARAM wParam, LPARAM lParam);
+
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+/*
+ * winwin32rootless.c
+ */
+
+Bool
+winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen,
+ int newX, int newY, RegionPtr pShape);
+
+void
+winMWExtWMDestroyFrame (RootlessFrameID wid);
+
+void
+winMWExtWMMoveFrame (RootlessFrameID wid, ScreenPtr pScreen, int newX, int newY);
+
+void
+winMWExtWMResizeFrame (RootlessFrameID wid, ScreenPtr pScreen,
+ int newX, int newY, unsigned int newW, unsigned int newH,
+ unsigned int gravity);
+
+void
+winMWExtWMRestackFrame (RootlessFrameID wid, RootlessFrameID nextWid);
+
+void
+winMWExtWMReshapeFrame (RootlessFrameID wid, RegionPtr pShape);
+
+void
+winMWExtWMUnmapFrame (RootlessFrameID wid);
+
+void
+winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow);
+
+void
+winMWExtWMStopDrawing (RootlessFrameID wid, Bool flush);
+
+void
+winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage);
+
+void
+winMWExtWMDamageRects (RootlessFrameID wid, int count, const BoxRec *rects,
+ int shift_x, int shift_y);
+
+void
+winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin);
+
+void
+winMWExtWMCopyBytes (unsigned int width, unsigned int height,
+ const void *src, unsigned int srcRowBytes,
+ void *dst, unsigned int dstRowBytes);
+
+void
+winMWExtWMFillBytes (unsigned int width, unsigned int height, unsigned int value,
+ void *dst, unsigned int dstRowBytes);
+
+int
+winMWExtWMCompositePixels (unsigned int width, unsigned int height, unsigned int function,
+ void *src[2], unsigned int srcRowBytes[2],
+ void *mask, unsigned int maskRowBytes,
+ void *dst[2], unsigned int dstRowBytes[2]);
+
+void
+winMWExtWMCopyWindow (RootlessFrameID wid, int dstNrects, const BoxRec *dstRects,
+ int dx, int dy);
+#endif
+
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+/*
+ * winwin32rootlesswindow.c
+ */
+
+void
+winMWExtWMReorderWindows (ScreenPtr pScreen);
+
+void
+winMWExtWMMoveXWindow (WindowPtr pWin, int x, int y);
+
+void
+winMWExtWMResizeXWindow (WindowPtr pWin, int w, int h);
+
+void
+winMWExtWMMoveResizeXWindow (WindowPtr pWin, int x, int y, int w, int h);
+
+void
+winMWExtWMUpdateIcon (Window id);
+
+void
+winMWExtWMUpdateWindowDecoration (win32RootlessWindowPtr pRLWinPriv,
+ winScreenInfoPtr pScreenInfo);
+
+wBOOL CALLBACK
+winMWExtWMDecorateWindow (HWND hwnd, LPARAM lParam);
+
+Bool
+winIsInternalWMRunning (winScreenInfoPtr pScreenInfo);
+
+void
+winMWExtWMRestackWindows (ScreenPtr pScreen);
+#endif
+
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+/*
+ * winwin32rootlesswndproc.c
+ */
+
+LRESULT CALLBACK
+winMWExtWMWindowProc (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam);
+#endif
+
+
+/*
+ * winwindowswm.c
+ */
+
+void
+winWindowsWMSendEvent (int type, unsigned int mask, int which, int arg,
+ Window window, int x, int y, int w, int h);
+
+void
+winWindowsWMExtensionInit (void);
+
+/*
+ * wincursor.c
+ */
+
+Bool
+winInitCursor (ScreenPtr pScreen);
+
+/*
+ * windisplay.c
+ */
+
+void
+winGetDisplayName(char *szDisplay, unsigned int screen);
+
+/*
+ * END DDX and DIX Function Prototypes
+ */
+
+#endif /* _WIN_H_ */
+
diff --git a/xorg-server/hw/xwin/winallpriv.c b/xorg-server/hw/xwin/winallpriv.c index 21ccd9b3b..3413ece53 100644 --- a/xorg-server/hw/xwin/winallpriv.c +++ b/xorg-server/hw/xwin/winallpriv.c @@ -48,11 +48,9 @@ winAllocatePrivates (ScreenPtr pScreen) { winPrivScreenPtr pScreenPriv; -#if CYGDEBUG winDebug ("winAllocateScreenPrivates - g_ulServerGeneration: %d " "serverGeneration: %d\n", g_ulServerGeneration, serverGeneration); -#endif /* We need a new slot for our privates if the screen gen has changed */ if (g_ulServerGeneration != serverGeneration) @@ -111,9 +109,7 @@ winAllocatePrivates (ScreenPtr pScreen) Bool winInitCmapPrivates (ColormapPtr pcmap, int index) { -#if CYGDEBUG winDebug ("winInitCmapPrivates\n"); -#endif /* * I see no way that this function can do anything useful @@ -139,9 +135,7 @@ winAllocateCmapPrivates (ColormapPtr pCmap) winPrivCmapPtr pCmapPriv; static unsigned long s_ulPrivateGeneration = 0; -#if CYGDEBUG winDebug ("winAllocateCmapPrivates\n"); -#endif /* Get a new privates index when the server generation changes */ if (s_ulPrivateGeneration != serverGeneration) @@ -164,9 +158,7 @@ winAllocateCmapPrivates (ColormapPtr pCmap) /* Save the cmap private pointer */ winSetCmapPriv (pCmap, pCmapPriv); -#if CYGDEBUG winDebug ("winAllocateCmapPrivates - Returning\n"); -#endif return TRUE; } diff --git a/xorg-server/hw/xwin/winauth.c b/xorg-server/hw/xwin/winauth.c index fcd1872da..fca6da086 100644 --- a/xorg-server/hw/xwin/winauth.c +++ b/xorg-server/hw/xwin/winauth.c @@ -1,202 +1,215 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II 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 HAROLD L HUNT II 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 Harold L Hunt II - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from Harold L Hunt II. - * - * Authors: Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif - -#include "win.h" - -/* Includes for authorization */ -#include "securitysrv.h" - - -/* - * Constants - */ - -#define AUTH_NAME "MIT-MAGIC-COOKIE-1" - - -/* - * Locals - */ - -static XID g_authId = 0; -static unsigned int g_uiAuthDataLen = 0; -static char *g_pAuthData = NULL; - -/* - * Code to generate a MIT-MAGIC-COOKIE-1, copied from under XCSECURITY - */ - -#ifndef XCSECURITY -static -void -GenerateRandomData (int len, char *buf) -{ - int fd; - - fd = open("/dev/urandom", O_RDONLY); - read(fd, buf, len); - close(fd); -} - - -static char cookie[16]; /* 128 bits */ - -XID -static MitGenerateCookie ( - unsigned data_length, - char *data, - XID id, - unsigned *data_length_return, - char **data_return) -{ - int i = 0; - int status; - - while (data_length--) - { - cookie[i++] += *data++; - if (i >= sizeof (cookie)) i = 0; - } - GenerateRandomData(sizeof (cookie), cookie); - status = MitAddCookie(sizeof (cookie), cookie, id); - if (!status) - { - id = -1; - } - else - { - *data_return = cookie; - *data_length_return = sizeof (cookie); - } - return id; -} - -static -XID -GenerateAuthorization( - unsigned name_length, - char *name, - unsigned data_length, - char *data, - unsigned *data_length_return, - char **data_return) -{ - return MitGenerateCookie(data_length, data, - FakeClientID(0), data_length_return, data_return); -} -#endif - -/* - * Generate authorization cookie for internal server clients - */ - -Bool -winGenerateAuthorization () -{ - Bool fFreeAuth = FALSE; - SecurityAuthorizationPtr pAuth = NULL; - - /* Call OS layer to generate authorization key */ - g_authId = GenerateAuthorization (strlen (AUTH_NAME), - AUTH_NAME, - 0, - NULL, - &g_uiAuthDataLen, - &g_pAuthData); - if ((XID) ~0L == g_authId) - { - ErrorF ("winGenerateAuthorization - GenerateAuthorization failed\n"); - goto auth_bailout; - } - - else - { - winDebug("winGenerateAuthorization - GenerateAuthorization success!\n" - "AuthDataLen: %d AuthData: %s\n", - g_uiAuthDataLen, g_pAuthData); - } - -#ifdef XCSECURITY - /* Allocate structure for additional auth information */ - pAuth = (SecurityAuthorizationPtr) - xalloc (sizeof (SecurityAuthorizationRec)); - if (!(pAuth)) - { - ErrorF ("winGenerateAuthorization - Failed allocating " - "SecurityAuthorizationPtr.\n"); - goto auth_bailout; - } - - /* Fill in the auth fields */ - pAuth->id = g_authId; - pAuth->timeout = 0; /* live for x seconds after refcnt == 0 */ - pAuth->group = None; - pAuth->trustLevel = XSecurityClientTrusted; - pAuth->refcnt = 1; /* this auth must stick around */ - pAuth->secondsRemaining = 0; - pAuth->timer = NULL; - pAuth->eventClients = NULL; - - /* Add the authorization to the server's auth list */ - if (!AddResource (g_authId, - SecurityAuthorizationResType, - pAuth)) - { - ErrorF ("winGenerateAuthorization - AddResource failed for auth.\n"); - fFreeAuth = TRUE; - goto auth_bailout; - } - - /* Don't free the auth data, since it is still used internally */ - pAuth = NULL; -#endif - - return TRUE; - - auth_bailout: - if (fFreeAuth) - xfree (pAuth); - - return FALSE; -} - -/* Use our generated cookie for authentication */ -void -winSetAuthorization(void) -{ - XSetAuthorization (AUTH_NAME, - strlen (AUTH_NAME), - g_pAuthData, - g_uiAuthDataLen); -} +/*
+ *Copyright (C) 2003-2004 Harold L Hunt II 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 HAROLD L HUNT II 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 Harold L Hunt II
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from Harold L Hunt II.
+ *
+ * Authors: Harold L Hunt II
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+
+#include "win.h"
+
+/* Includes for authorization */
+#include "securitysrv.h"
+
+/*
+ * Constants
+ */
+
+#define AUTH_NAME "MIT-MAGIC-COOKIE-1"
+
+
+/*
+ * Locals
+ */
+
+static XID g_authId = 0;
+static unsigned int g_uiAuthDataLen = 0;
+static char *g_pAuthData = NULL;
+
+/*
+ * Code to generate a MIT-MAGIC-COOKIE-1, copied from under XCSECURITY
+ */
+
+
+
+#ifndef XCSECURITY
+static
+void
+GenerateRandomData (int len, char *buf)
+{
+ int fd;
+#ifdef _MSC_VER
+ static HANDLE hAdvApi32;
+ static BOOLEAN (_stdcall * RtlGenRandom)(void *,unsigned long);
+
+ if (!hAdvApi32)
+ {
+ hAdvApi32=LoadLibrary("advapi32.dll");
+ RtlGenRandom=(BOOLEAN (_stdcall *)(void*,unsigned long))GetProcAddress(hAdvApi32,"SystemFunction036");
+ }
+ RtlGenRandom(buf, len);
+#else
+ fd = open("/dev/urandom", O_RDONLY);
+ read(fd, buf, len);
+ close(fd);
+#endif
+}
+
+
+static char cookie[16]; /* 128 bits */
+
+XID
+static MitGenerateCookie (
+ unsigned data_length,
+ char *data,
+ XID id,
+ unsigned *data_length_return,
+ char **data_return)
+{
+ int i = 0;
+ int status;
+
+ while (data_length--)
+ {
+ cookie[i++] += *data++;
+ if (i >= sizeof (cookie)) i = 0;
+ }
+ GenerateRandomData(sizeof (cookie), cookie);
+ status = MitAddCookie(sizeof (cookie), cookie, id);
+ if (!status)
+ {
+ id = -1;
+ }
+ else
+ {
+ *data_return = cookie;
+ *data_length_return = sizeof (cookie);
+ }
+ return id;
+}
+
+static
+XID
+GenerateAuthorization(
+ unsigned name_length,
+ char *name,
+ unsigned data_length,
+ char *data,
+ unsigned *data_length_return,
+ char **data_return)
+{
+ return MitGenerateCookie(data_length, data,
+ FakeClientID(0), data_length_return, data_return);
+}
+#endif
+
+/*
+ * Generate authorization cookie for internal server clients
+ */
+
+Bool
+winGenerateAuthorization ()
+{
+ Bool fFreeAuth = FALSE;
+ SecurityAuthorizationPtr pAuth = NULL;
+
+ /* Call OS layer to generate authorization key */
+ g_authId = GenerateAuthorization (strlen (AUTH_NAME),
+ AUTH_NAME,
+ 0,
+ NULL,
+ &g_uiAuthDataLen,
+ &g_pAuthData);
+ if ((XID) ~0L == g_authId)
+ {
+ ErrorF ("winGenerateAuthorization - GenerateAuthorization failed\n");
+ goto auth_bailout;
+ }
+#ifdef WINDBG
+ else
+ {
+ winDebug("winGenerateAuthorization - GenerateAuthorization success!\n"
+ "AuthDataLen: %d AuthData: %s\n",
+ g_uiAuthDataLen, g_pAuthData);
+ }
+#endif
+
+#ifdef XCSECURITY
+ /* Allocate structure for additional auth information */
+ pAuth = (SecurityAuthorizationPtr)
+ xalloc (sizeof (SecurityAuthorizationRec));
+ if (!(pAuth))
+ {
+ ErrorF ("winGenerateAuthorization - Failed allocating "
+ "SecurityAuthorizationPtr.\n");
+ goto auth_bailout;
+ }
+
+ /* Fill in the auth fields */
+ pAuth->id = g_authId;
+ pAuth->timeout = 0; /* live for x seconds after refcnt == 0 */
+ pAuth->group = None;
+ pAuth->trustLevel = XSecurityClientTrusted;
+ pAuth->refcnt = 1; /* this auth must stick around */
+ pAuth->secondsRemaining = 0;
+ pAuth->timer = NULL;
+ pAuth->eventClients = NULL;
+
+ /* Add the authorization to the server's auth list */
+ if (!AddResource (g_authId,
+ SecurityAuthorizationResType,
+ pAuth))
+ {
+ ErrorF ("winGenerateAuthorization - AddResource failed for auth.\n");
+ fFreeAuth = TRUE;
+ goto auth_bailout;
+ }
+
+ /* Don't free the auth data, since it is still used internally */
+ pAuth = NULL;
+#endif
+
+ return TRUE;
+
+ auth_bailout:
+ if (fFreeAuth)
+ xfree (pAuth);
+
+ return FALSE;
+}
+
+/* Use our generated cookie for authentication */
+void
+winSetAuthorization(void)
+{
+ XSetAuthorization (AUTH_NAME,
+ strlen (AUTH_NAME),
+ g_pAuthData,
+ g_uiAuthDataLen);
+}
diff --git a/xorg-server/hw/xwin/winclip.c b/xorg-server/hw/xwin/winclip.c index aab7d632d..cbbf08c59 100644 --- a/xorg-server/hw/xwin/winclip.c +++ b/xorg-server/hw/xwin/winclip.c @@ -37,6 +37,6 @@ RegionPtr winPixmapToRegionNativeGDI (PixmapPtr pPix) { - ErrorF ("winPixmapToRegion()\n"); + winDebug ("winPixmapToRegion()\n"); return NULL; } diff --git a/xorg-server/hw/xwin/winclipboard.h b/xorg-server/hw/xwin/winclipboard.h index 089c2913b..9bf7c9c0e 100644 --- a/xorg-server/hw/xwin/winclipboard.h +++ b/xorg-server/hw/xwin/winclipboard.h @@ -34,7 +34,9 @@ #include <assert.h> #include <stdio.h> #include <stdlib.h> +#ifndef _MSC_VER #include <unistd.h> +#endif #ifdef __CYGWIN__ #include <sys/select.h> #else @@ -43,6 +45,9 @@ #endif #include <fcntl.h> #include <setjmp.h> +#ifdef _MSC_VER +typedef int pid_t; +#endif #include <pthread.h> /* X headers */ @@ -74,15 +79,13 @@ #define WM_WM_REINIT (WM_USER + 1) +#include "winmsg.h" + /* * References to external symbols */ extern char *display; -extern void ErrorF (const char* /*f*/, ...); -extern void winDebug (const char *format, ...); -extern void winErrorFVerb (int verb, const char *format, ...); - /* * winclipboardinit.c @@ -145,5 +148,6 @@ int winClipboardFlushXEvents (HWND hwnd, int iWindow, Display *pDisplay, - Bool fUnicodeSupport); + Bool fUnicodeSupport, + Bool ClipboardOpened); #endif diff --git a/xorg-server/hw/xwin/winclipboardinit.c b/xorg-server/hw/xwin/winclipboardinit.c index bec63ac8e..d451314fb 100644 --- a/xorg-server/hw/xwin/winclipboardinit.c +++ b/xorg-server/hw/xwin/winclipboardinit.c @@ -61,7 +61,7 @@ extern HWND g_hwndClipboard; Bool winInitClipboard (void) { - ErrorF ("winInitClipboard ()\n"); + winDebug ("winInitClipboard ()\n"); /* Wrap some internal server functions */ if (ProcVector[X_SetSelectionOwner] != winProcSetSelectionOwner) diff --git a/xorg-server/hw/xwin/winclipboardtextconv.c b/xorg-server/hw/xwin/winclipboardtextconv.c index 400f560fa..487df81ef 100644 --- a/xorg-server/hw/xwin/winclipboardtextconv.c +++ b/xorg-server/hw/xwin/winclipboardtextconv.c @@ -1,155 +1,155 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II 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 HAROLD L HUNT II 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 Harold L Hunt II - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from Harold L Hunt II. - * - * Authors: Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" -#include <stdio.h> -#include <stdlib.h> - -void -winClipboardDOStoUNIX (char *pszSrc, int iLength); -void -winClipboardUNIXtoDOS (unsigned char **ppszData, int iLength); - -/* - * Convert \r\n to \n - * - * NOTE: This was heavily inspired by, Cygwin's - * winsup/cygwin/fhandler.cc/fhandler_base::read () - */ - -void -winClipboardDOStoUNIX (char *pszSrc, int iLength) -{ - char *pszDest = pszSrc; - char *pszEnd = pszSrc + iLength; - - /* Loop until the last character */ - while (pszSrc < pszEnd) - { - /* Copy the current source character to current destination character */ - *pszDest = *pszSrc; - - /* Advance to the next source character */ - pszSrc++; - - /* Don't advance the destination character if we need to drop an \r */ - if (*pszDest != '\r' || *pszSrc != '\n') - pszDest++; - } - - /* Move the terminating null */ - *pszDest = '\0'; -} - - -/* - * Convert \n to \r\n - */ - -void -winClipboardUNIXtoDOS (unsigned char **ppszData, int iLength) -{ - int iNewlineCount = 0; - unsigned char *pszSrc = *ppszData; - unsigned char *pszEnd = pszSrc + iLength; - unsigned char *pszDest = NULL, *pszDestBegin = NULL; - - winDebug("UNIXtoDOS () - Original data:'%s'\n", *ppszData); - - /* Count \n characters without leading \r */ - while (pszSrc < pszEnd) - { - /* Skip ahead two character if found set of \r\n */ - if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n') - { - pszSrc += 2; - continue; - } - - /* Increment the count if found naked \n */ - if (*pszSrc == '\n') - { - iNewlineCount++; - } - - pszSrc++; - } - - /* Return if no naked \n's */ - if (iNewlineCount == 0) - return; - - /* Allocate a new string */ - pszDestBegin = pszDest = malloc (iLength + iNewlineCount + 1); - - /* Set source pointer to beginning of data string */ - pszSrc = *ppszData; - - /* Loop through all characters in source string */ - while (pszSrc < pszEnd) - { - /* Copy line endings that are already valid */ - if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n') - { - *pszDest = *pszSrc; - *(pszDest + 1) = *(pszSrc + 1); - pszDest += 2; - pszSrc += 2; - continue; - } - - /* Add \r to naked \n's */ - if (*pszSrc == '\n') - { - *pszDest = '\r'; - *(pszDest + 1) = *pszSrc; - pszDest += 2; - pszSrc += 1; - continue; - } - - /* Copy normal characters */ - *pszDest = *pszSrc; - pszSrc++; - pszDest++; - } - - /* Put terminating null at end of new string */ - *pszDest = '\0'; - - /* Swap string pointers */ - free (*ppszData); - *ppszData = pszDestBegin; - - winDebug("UNIXtoDOS () - Final string:'%s'\n", pszDestBegin); -} +/*
+ *Copyright (C) 2003-2004 Harold L Hunt II 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 HAROLD L HUNT II 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 Harold L Hunt II
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from Harold L Hunt II.
+ *
+ * Authors: Harold L Hunt II
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+void
+winClipboardDOStoUNIX (char *pszSrc, int iLength);
+void
+winClipboardUNIXtoDOS (unsigned char **ppszData, int iLength);
+
+/*
+ * Convert \r\n to \n
+ *
+ * NOTE: This was heavily inspired by, Cygwin's
+ * winsup/cygwin/fhandler.cc/fhandler_base::read ()
+ */
+
+void
+winClipboardDOStoUNIX (char *pszSrc, int iLength)
+{
+ char *pszDest = pszSrc;
+ char *pszEnd = pszSrc + iLength;
+
+ /* Loop until the last character */
+ while (pszSrc < pszEnd)
+ {
+ /* Copy the current source character to current destination character */
+ *pszDest = *pszSrc;
+
+ /* Advance to the next source character */
+ pszSrc++;
+
+ /* Don't advance the destination character if we need to drop an \r */
+ if (*pszDest != '\r' || *pszSrc != '\n')
+ pszDest++;
+ }
+
+ /* Move the terminating null */
+ *pszDest = '\0';
+}
+
+
+/*
+ * Convert \n to \r\n
+ */
+
+void
+winClipboardUNIXtoDOS (unsigned char **ppszData, int iLength)
+{
+ int iNewlineCount = 0;
+ unsigned char *pszSrc = *ppszData;
+ unsigned char *pszEnd = pszSrc + iLength;
+ unsigned char *pszDest = NULL, *pszDestBegin = NULL;
+
+ winDebug("UNIXtoDOS () - Original data:'%s'\n", *ppszData);
+
+ /* Count \n characters without leading \r */
+ while (pszSrc < pszEnd)
+ {
+ /* Skip ahead two character if found set of \r\n */
+ if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n')
+ {
+ pszSrc += 2;
+ continue;
+ }
+
+ /* Increment the count if found naked \n */
+ if (*pszSrc == '\n')
+ {
+ iNewlineCount++;
+ }
+
+ pszSrc++;
+ }
+
+ /* Return if no naked \n's */
+ if (iNewlineCount == 0)
+ return;
+
+ /* Allocate a new string */
+ pszDestBegin = pszDest = malloc (iLength + iNewlineCount + 1);
+
+ /* Set source pointer to beginning of data string */
+ pszSrc = *ppszData;
+
+ /* Loop through all characters in source string */
+ while (pszSrc < pszEnd)
+ {
+ /* Copy line endings that are already valid */
+ if (*pszSrc == '\r' && pszSrc + 1 < pszEnd && *(pszSrc + 1) == '\n')
+ {
+ *pszDest = *pszSrc;
+ *(pszDest + 1) = *(pszSrc + 1);
+ pszDest += 2;
+ pszSrc += 2;
+ continue;
+ }
+
+ /* Add \r to naked \n's */
+ if (*pszSrc == '\n')
+ {
+ *pszDest = '\r';
+ *(pszDest + 1) = *pszSrc;
+ pszDest += 2;
+ pszSrc += 1;
+ continue;
+ }
+
+ /* Copy normal characters */
+ *pszDest = *pszSrc;
+ pszSrc++;
+ pszDest++;
+ }
+
+ /* Put terminating null at end of new string */
+ *pszDest = '\0';
+
+ /* Swap string pointers */
+ free (*ppszData);
+ *ppszData = pszDestBegin;
+
+ winDebug("UNIXtoDOS () - Final string:'%s'\n", pszDestBegin);
+}
diff --git a/xorg-server/hw/xwin/winclipboardthread.c b/xorg-server/hw/xwin/winclipboardthread.c index a3809034e..e08e7acd0 100644 --- a/xorg-server/hw/xwin/winclipboardthread.c +++ b/xorg-server/hw/xwin/winclipboardthread.c @@ -1,462 +1,501 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. - *Copyright (C) Colin Harrison 2005-2008 - * - *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 HAROLD L HUNT II 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 copyright holder(s) - *and author(s) 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 copyright holder(s) and author(s). - * - * Authors: Harold L Hunt II - * Colin Harrison - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include <sys/types.h> -#include "winclipboard.h" -#ifdef __CYGWIN__ -#include <errno.h> -#endif -#include "misc.h" - - -/* - * References to external symbols - */ - -extern Bool g_fUnicodeClipboard; -extern unsigned long serverGeneration; -extern Bool g_fClipboardStarted; -extern HWND g_hwndClipboard; -extern void *g_pClipboardDisplay; -extern Window g_iClipboardWindow; - - -/* - * Global variables - */ - -static jmp_buf g_jmpEntry; -Bool g_fUnicodeSupport = FALSE; -Bool g_fUseUnicode = FALSE; - - -/* - * Local function prototypes - */ - -static int -winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr); - -static int -winClipboardIOErrorHandler (Display *pDisplay); - - -/* - * Main thread function - */ - -void * -winClipboardProc (void *pvNotUsed) -{ - Atom atomClipboard, atomClipboardManager; - int iReturn; - HWND hwnd = NULL; - int iConnectionNumber = 0; -#ifdef HAS_DEVWINDOWS - int fdMessageQueue = 0; -#else - struct timeval tvTimeout; -#endif - fd_set fdsRead; - int iMaxDescriptor; - Display *pDisplay = NULL; - Window iWindow = None; - int iRetries; - Bool fUseUnicode; - char szDisplay[512]; - int iSelectError; - - ErrorF ("winClipboardProc - Hello\n"); - - /* Do we have Unicode support? */ - g_fUnicodeSupport = winClipboardDetectUnicodeSupport (); - - /* Do we use Unicode clipboard? */ - fUseUnicode = g_fUnicodeClipboard && g_fUnicodeSupport; - - /* Save the Unicode support flag in a global */ - g_fUseUnicode = fUseUnicode; - - /* Allow multiple threads to access Xlib */ - if (XInitThreads () == 0) - { - ErrorF ("winClipboardProc - XInitThreads failed.\n"); - pthread_exit (NULL); - } - - /* See if X supports the current locale */ - if (XSupportsLocale () == False) - { - ErrorF ("winClipboardProc - Warning: Locale not supported by X.\n"); - } - - /* Set jump point for Error exits */ - iReturn = setjmp (g_jmpEntry); - - /* Check if we should continue operations */ - if (iReturn != WIN_JMP_ERROR_IO - && iReturn != WIN_JMP_OKAY) - { - /* setjmp returned an unknown value, exit */ - ErrorF ("winClipboardProc - setjmp returned: %d exiting\n", - iReturn); - pthread_exit (NULL); - } - else if (iReturn == WIN_JMP_ERROR_IO) - { - /* TODO: Cleanup the Win32 window and free any allocated memory */ - ErrorF ("winClipboardProc - setjmp returned for IO Error Handler.\n"); - pthread_exit (NULL); - } - - /* Use our generated cookie for authentication */ - winSetAuthorization(); - - /* Set error handler */ - XSetErrorHandler (winClipboardErrorHandler); - XSetIOErrorHandler (winClipboardIOErrorHandler); - - /* Initialize retry count */ - iRetries = 0; - - /* Setup the display connection string x */ - /* - * NOTE: Always connect to screen 0 since we require that screen - * numbers start at 0 and increase without gaps. We only need - * to connect to one screen on the display to get events - * for all screens on the display. That is why there is only - * one clipboard client thread. - */ - snprintf (szDisplay, - 512, - "127.0.0.1:%s.0", - display); - - /* Print the display connection string */ - ErrorF ("winClipboardProc - DISPLAY=%s\n", szDisplay); - - /* Open the X display */ - do - { - pDisplay = XOpenDisplay (szDisplay); - if (pDisplay == NULL) - { - ErrorF ("winClipboardProc - Could not open display, " - "try: %d, sleeping: %d\n", - iRetries + 1, WIN_CONNECT_DELAY); - ++iRetries; - sleep (WIN_CONNECT_DELAY); - continue; - } - else - break; - } - while (pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES); - - /* Make sure that the display opened */ - if (pDisplay == NULL) - { - ErrorF ("winClipboardProc - Failed opening the display, giving up\n"); - pthread_exit (NULL); - } - - /* Save the display in the screen privates */ - g_pClipboardDisplay = pDisplay; - - ErrorF ("winClipboardProc - XOpenDisplay () returned and " - "successfully opened the display.\n"); - - /* Get our connection number */ - iConnectionNumber = ConnectionNumber (pDisplay); - -#ifdef HAS_DEVWINDOWS - /* Open a file descriptor for the windows message queue */ - fdMessageQueue = open (WIN_MSG_QUEUE_FNAME, O_RDONLY); - if (fdMessageQueue == -1) - { - ErrorF ("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME); - pthread_exit (NULL); - } - - /* Find max of our file descriptors */ - iMaxDescriptor = max (fdMessageQueue, iConnectionNumber) + 1; -#else - iMaxDescriptor = iConnectionNumber + 1; -#endif - - /* Create atoms */ - atomClipboard = XInternAtom (pDisplay, "CLIPBOARD", False); - atomClipboardManager = XInternAtom (pDisplay, "CLIPBOARD_MANAGER", False); - - /* Create a messaging window */ - iWindow = XCreateSimpleWindow (pDisplay, - DefaultRootWindow (pDisplay), - 1, 1, - 500, 500, - 0, - BlackPixel (pDisplay, 0), - BlackPixel (pDisplay, 0)); - if (iWindow == 0) - { - ErrorF ("winClipboardProc - Could not create an X window.\n"); - pthread_exit (NULL); - } - - /* Select event types to watch */ - if (XSelectInput (pDisplay, - iWindow, - PropertyChangeMask) == BadWindow) - ErrorF ("winClipboardProc - XSelectInput generated BadWindow " - "on messaging window\n"); - - /* Save the window in the screen privates */ - g_iClipboardWindow = iWindow; - - /* Create Windows messaging window */ - hwnd = winClipboardCreateMessagingWindow (); - - /* Save copy of HWND in screen privates */ - g_hwndClipboard = hwnd; - - /* Assert ownership of selections if Win32 clipboard is owned */ - if (NULL != GetClipboardOwner ()) - { - /* PRIMARY */ - iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY, - iWindow, CurrentTime); - if (iReturn == BadAtom || iReturn == BadWindow || - XGetSelectionOwner (pDisplay, XA_PRIMARY) != iWindow) - { - ErrorF ("winClipboardProc - Could not set PRIMARY owner\n"); - pthread_exit (NULL); - } - - /* CLIPBOARD */ - iReturn = XSetSelectionOwner (pDisplay, atomClipboard, - iWindow, CurrentTime); - if (iReturn == BadAtom || iReturn == BadWindow || - XGetSelectionOwner (pDisplay, atomClipboard) != iWindow) - { - ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n"); - pthread_exit (NULL); - } - } - - /* Pre-flush X events */ - /* - * NOTE: Apparently you'll freeze if you don't do this, - * because there may be events in local data structures - * already. - */ - winClipboardFlushXEvents (hwnd, - iWindow, - pDisplay, - fUseUnicode); - - /* Pre-flush Windows messages */ - if (!winClipboardFlushWindowsMessageQueue (hwnd)) - return 0; - - /* Signal that the clipboard client has started */ - g_fClipboardStarted = TRUE; - - /* Loop for X events */ - while (1) - { - /* Setup the file descriptor set */ - /* - * NOTE: You have to do this before every call to select - * because select modifies the mask to indicate - * which descriptors are ready. - */ - FD_ZERO (&fdsRead); - FD_SET (iConnectionNumber, &fdsRead); -#ifdef HAS_DEVWINDOWS - FD_SET (fdMessageQueue, &fdsRead); -#else - tvTimeout.tv_sec = 0; - tvTimeout.tv_usec = 100; -#endif - - /* Wait for a Windows event or an X event */ - iReturn = select (iMaxDescriptor, /* Highest fds number */ - &fdsRead, /* Read mask */ - NULL, /* No write mask */ - NULL, /* No exception mask */ -#ifdef HAS_DEVWINDOWS - NULL /* No timeout */ -#else - &tvTimeout /* Set timeout */ -#endif - ); - -#ifndef HAS_WINSOCK - iSelectError = errno; -#else - iSelectError = WSAGetLastError(); -#endif - - if (iReturn < 0) - { -#ifndef HAS_WINSOCK - if (iSelectError == EINTR) -#else - if (iSelectError == WSAEINTR) -#endif - continue; - - ErrorF ("winClipboardProc - Call to select () failed: %d. " - "Bailing.\n", iReturn); - break; - } - - /* Branch on which descriptor became active */ - if (FD_ISSET (iConnectionNumber, &fdsRead)) - { - /* Process X events */ - /* Exit when we see that server is shutting down */ - iReturn = winClipboardFlushXEvents (hwnd, - iWindow, - pDisplay, - fUseUnicode); - if (WIN_XEVENTS_SHUTDOWN == iReturn) - { - ErrorF ("winClipboardProc - winClipboardFlushXEvents " - "trapped shutdown event, exiting main loop.\n"); - break; - } - } - -#ifdef HAS_DEVWINDOWS - /* Check for Windows event ready */ - if (FD_ISSET (fdMessageQueue, &fdsRead)) -#else - if (1) -#endif - { - /* Process Windows messages */ - if (!winClipboardFlushWindowsMessageQueue (hwnd)) - { - ErrorF ("winClipboardProc - " - "winClipboardFlushWindowsMessageQueue trapped " - "WM_QUIT message, exiting main loop.\n"); - break; - } - } - } - - /* Close our X window */ - if (pDisplay && iWindow) - { - iReturn = XDestroyWindow (pDisplay, iWindow); - if (iReturn == BadWindow) - ErrorF ("winClipboardProc - XDestroyWindow returned BadWindow.\n"); - else - ErrorF ("winClipboardProc - XDestroyWindow succeeded.\n"); - } - - -#ifdef HAS_DEVWINDOWS - /* Close our Win32 message handle */ - if (fdMessageQueue) - close (fdMessageQueue); -#endif - -#if 0 - /* - * FIXME: XCloseDisplay hangs if we call it, as of 2004/03/26. The - * XSync and XSelectInput calls did not help. - */ - - /* Discard any remaining events */ - XSync (pDisplay, TRUE); - - /* Select event types to watch */ - XSelectInput (pDisplay, - DefaultRootWindow (pDisplay), - None); - - /* Close our X display */ - if (pDisplay) - { - XCloseDisplay (pDisplay); - } -#endif - - g_iClipboardWindow = None; - g_pClipboardDisplay = NULL; - g_hwndClipboard = NULL; - - return NULL; -} - - -/* - * winClipboardErrorHandler - Our application specific error handler - */ - -static int -winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr) -{ - char pszErrorMsg[100]; - - XGetErrorText (pDisplay, - pErr->error_code, - pszErrorMsg, - sizeof (pszErrorMsg)); - ErrorF ("winClipboardErrorHandler - ERROR: \n\t%s\n" - "\tSerial: %d, Request Code: %d, Minor Code: %d\n", - pszErrorMsg, - pErr->serial, - pErr->request_code, - pErr->minor_code); - return 0; -} - - -/* - * winClipboardIOErrorHandler - Our application specific IO error handler - */ - -static int -winClipboardIOErrorHandler (Display *pDisplay) -{ - ErrorF ("\nwinClipboardIOErrorHandler!\n\n"); - - /* Restart at the main entry point */ - longjmp (g_jmpEntry, WIN_JMP_ERROR_IO); - - return 0; -} +/*
+ *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
+ *Copyright (C) Colin Harrison 2005-2008
+ *
+ *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 HAROLD L HUNT II 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 copyright holder(s)
+ *and author(s) 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 copyright holder(s) and author(s).
+ *
+ * Authors: Harold L Hunt II
+ * Colin Harrison
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include <sys/types.h>
+#include "winclipboard.h"
+#ifdef __CYGWIN__
+#include <errno.h>
+#endif
+#include "misc.h"
+#include "winmsg.h"
+
+#ifdef _MSC_VER
+#define snprintf _snprintf
+#endif
+
+/*
+ * References to external symbols
+ */
+
+extern Bool g_fUnicodeClipboard;
+extern unsigned long serverGeneration;
+extern Bool g_fClipboardLaunched;
+extern Bool g_fClipboardStarted;
+extern HWND g_hwndClipboard;
+extern void *g_pClipboardDisplay;
+extern Window g_iClipboardWindow;
+
+
+/*
+ * Global variables
+ */
+
+static jmp_buf g_jmpEntry;
+Bool g_fUnicodeSupport = FALSE;
+Bool g_fUseUnicode = FALSE;
+
+
+/*
+ * Local function prototypes
+ */
+
+static int
+winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr);
+
+static int
+winClipboardIOErrorHandler (Display *pDisplay);
+
+
+/*
+ * Main thread function
+ */
+
+void *
+winClipboardProc (void *pvNotUsed)
+{
+ Atom atomClipboard, atomClipboardManager;
+ int iReturn;
+ HWND hwnd = NULL;
+ int iConnectionNumber = 0;
+#ifdef HAS_DEVWINDOWS
+ int fdMessageQueue = 0;
+#else
+ struct timeval tvTimeout;
+#endif
+ fd_set fdsRead;
+ int iMaxDescriptor;
+ Display *pDisplay = NULL;
+ Window iWindow = None;
+ int iRetries;
+ Bool fUseUnicode;
+ char szDisplay[512];
+ int iSelectError;
+
+ winDebug ("winClipboardProc - Hello\n");
+
+ /* Do we have Unicode support? */
+ g_fUnicodeSupport = winClipboardDetectUnicodeSupport ();
+
+ /* Do we use Unicode clipboard? */
+ fUseUnicode = g_fUnicodeClipboard && g_fUnicodeSupport;
+
+ /* Save the Unicode support flag in a global */
+ g_fUseUnicode = fUseUnicode;
+
+ /* See if X supports the current locale */
+ if (XSupportsLocale () == False)
+ {
+ ErrorF ("winClipboardProc - Warning: Locale not supported by X.\n");
+ }
+
+ /* Create Windows messaging window */
+ hwnd = winClipboardCreateMessagingWindow ();
+
+ /* Save copy of HWND in screen privates */
+ g_hwndClipboard = hwnd;
+
+ /* Set jump point for Error exits */
+ iReturn = setjmp (g_jmpEntry);
+
+ /* Check if we should continue operations */
+ if (iReturn != WIN_JMP_ERROR_IO
+ && iReturn != WIN_JMP_OKAY)
+ {
+ /* setjmp returned an unknown value, exit */
+ ErrorF ("winClipboardProc - setjmp returned: %d exiting\n",
+ iReturn);
+ goto thread_errorexit;
+ }
+ else if (iReturn == WIN_JMP_ERROR_IO)
+ {
+ /* TODO: Cleanup the Win32 window and free any allocated memory */
+ ErrorF ("winClipboardProc - setjmp returned for IO Error Handler.\n");
+ //goto thread_errorexit;
+ }
+
+ /* Use our generated cookie for authentication */
+ winSetAuthorization();
+
+ /* Set error handler */
+ XSetErrorHandler (winClipboardErrorHandler);
+ XSetIOErrorHandler (winClipboardIOErrorHandler);
+
+ /* Initialize retry count */
+ iRetries = 0;
+
+ /* Setup the display connection string x */
+ /*
+ * NOTE: Always connect to screen 0 since we require that screen
+ * numbers start at 0 and increase without gaps. We only need
+ * to connect to one screen on the display to get events
+ * for all screens on the display. That is why there is only
+ * one clipboard client thread.
+ */
+ snprintf (szDisplay,
+ 512,
+ "127.0.0.1:%s.0",
+ display);
+
+ /* Print the display connection string */
+ winDebug ("winClipboardProc - DISPLAY=%s\n", szDisplay);
+
+ /* Open the X display */
+ do
+ {
+ pDisplay = XOpenDisplay (szDisplay);
+ if (pDisplay == NULL)
+ {
+ ErrorF ("winClipboardProc - Could not open display, "
+ "try: %d, sleeping: %d\n",
+ iRetries + 1, WIN_CONNECT_DELAY);
+ ++iRetries;
+ sleep (WIN_CONNECT_DELAY);
+ continue;
+ }
+ else
+ break;
+ }
+ while (pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES);
+
+ /* Make sure that the display opened */
+ if (pDisplay == NULL)
+ {
+ ErrorF ("winClipboardProc - Failed opening the display, giving up\n");
+ goto thread_errorexit;
+ }
+
+ /* Save the display in the screen privates */
+ g_pClipboardDisplay = pDisplay;
+
+ winDebug ("winClipboardProc - XOpenDisplay () returned and "
+ "successfully opened the display.\n");
+
+ /* Get our connection number */
+ iConnectionNumber = ConnectionNumber (pDisplay);
+
+ winDebug("Clipboard is using socket %d\n",iConnectionNumber);
+
+#ifdef HAS_DEVWINDOWS
+ /* Open a file descriptor for the windows message queue */
+ fdMessageQueue = open (WIN_MSG_QUEUE_FNAME, _O_RDONLY);
+ if (fdMessageQueue == -1)
+ {
+ ErrorF ("winClipboardProc - Failed opening %s\n", WIN_MSG_QUEUE_FNAME);
+ goto thread_errorexit;
+ }
+
+ /* Find max of our file descriptors */
+ iMaxDescriptor = max (fdMessageQueue, iConnectionNumber) + 1;
+#else
+ iMaxDescriptor = iConnectionNumber + 1;
+#endif
+
+ /* Create atoms */
+ atomClipboard = XInternAtom (pDisplay, "CLIPBOARD", False);
+ atomClipboardManager = XInternAtom (pDisplay, "CLIPBOARD_MANAGER", False);
+ XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False);
+ XInternAtom (pDisplay, "UTF8_STRING", False);
+ XInternAtom (pDisplay, "COMPOUND_TEXT", False);
+ XInternAtom (pDisplay, "TARGETS", False);
+
+ /* Create a messaging window */
+ iWindow = XCreateSimpleWindow (pDisplay,
+ DefaultRootWindow (pDisplay),
+ 1, 1,
+ 500, 500,
+ 0,
+ BlackPixel (pDisplay, 0),
+ BlackPixel (pDisplay, 0));
+ if (iWindow == 0)
+ {
+ ErrorF ("winClipboardProc - Could not create an X window.\n");
+ goto thread_errorexit;
+ }
+
+ /* Select event types to watch */
+ if (XSelectInput (pDisplay,
+ iWindow,
+ PropertyChangeMask) == BadWindow)
+ ErrorF ("winClipboardProc - XSelectInput generated BadWindow "
+ "on messaging window\n");
+
+ /* Save the window in the screen privates */
+ g_iClipboardWindow = iWindow;
+
+ /* Assert ownership of selections if Win32 clipboard is owned */
+ if (NULL != GetClipboardOwner ())
+ {
+ /* PRIMARY */
+ winDebug("winClipboardProc - asserted ownership.\n");
+ iReturn = XSetSelectionOwner (pDisplay, XA_PRIMARY,
+ iWindow, CurrentTime);
+ if (iReturn == BadAtom || iReturn == BadWindow /*||
+ XGetSelectionOwner (pDisplay, XA_PRIMARY) != iWindow*/)
+ {
+ ErrorF ("winClipboardProc - Could not set PRIMARY owner\n");
+ goto thread_errorexit;
+ }
+
+ /* CLIPBOARD */
+ iReturn = XSetSelectionOwner (pDisplay, atomClipboard,
+ iWindow, CurrentTime);
+ if (iReturn == BadAtom || iReturn == BadWindow /*||
+ XGetSelectionOwner (pDisplay, atomClipboard) != iWindow*/)
+ {
+ ErrorF ("winClipboardProc - Could not set CLIPBOARD owner\n");
+ goto thread_errorexit;
+ }
+ }
+ /* Pre-flush X events */
+ /*
+ * NOTE: Apparently you'll freeze if you don't do this,
+ * because there may be events in local data structures
+ * already.
+ */
+ /*winClipboardFlushXEvents (hwnd,
+ iWindow,
+ pDisplay,
+ fUseUnicode);
+ */
+ /* Pre-flush Windows messages */
+ winDebug ("Start flushing \n");
+ if (!winClipboardFlushWindowsMessageQueue (hwnd))
+ {
+ ErrorF ("winClipboardFlushWindowsMessageQueue - returned 0\n");
+ goto thread_errorexit;
+ }
+
+ winDebug ("winClipboardProc - Started\n");
+ /* Signal that the clipboard client has started */
+ g_fClipboardStarted = TRUE;
+
+ /* Loop for X events */
+ while (1)
+ {
+ /* Setup the file descriptor set */
+ /*
+ * NOTE: You have to do this before every call to select
+ * because select modifies the mask to indicate
+ * which descriptors are ready.
+ */
+ FD_ZERO (&fdsRead);
+ FD_SET (iConnectionNumber, &fdsRead);
+#ifdef HAS_DEVWINDOWS
+ FD_SET (fdMessageQueue, &fdsRead);
+#else
+ tvTimeout.tv_sec = 0;
+ tvTimeout.tv_usec = 100;
+#endif
+
+ /* Wait for a Windows event or an X event */
+ iReturn = select (iMaxDescriptor, /* Highest fds number */
+ &fdsRead, /* Read mask */
+ NULL, /* No write mask */
+ NULL, /* No exception mask */
+#ifdef HAS_DEVWINDOWS
+ NULL /* No timeout */
+#else
+ &tvTimeout /* Set timeout */
+#endif
+ );
+
+#ifndef HAS_WINSOCK
+ iSelectError = errno;
+#else
+ iSelectError = WSAGetLastError();
+#endif
+
+ if (iReturn < 0)
+ {
+#ifndef HAS_WINSOCK
+ if (iSelectError == EINTR)
+#else
+ if (iSelectError == WSAEINTR)
+#endif
+ continue;
+
+ ErrorF ("winClipboardProc - Call to select () failed: %d. "
+ "Bailing.\n", iReturn);
+ break;
+ }
+
+ /* Branch on which descriptor became active */
+// if (FD_ISSET (iConnectionNumber, &fdsRead))
+// { Also do it when no read since winClipboardFlushXEvents
+// is sending the output.
+ /* Process X events */
+ /* Exit when we see that server is shutting down */
+ iReturn = winClipboardFlushXEvents (hwnd,
+ iWindow,
+ pDisplay,
+ fUseUnicode,
+ FALSE
+ );
+ if (WIN_XEVENTS_SHUTDOWN == iReturn)
+ {
+ ErrorF ("winClipboardProc - winClipboardFlushXEvents "
+ "trapped shutdown event, exiting main loop.\n");
+ break;
+ }
+// }
+
+#ifdef HAS_DEVWINDOWS
+ /* Check for Windows event ready */
+ if (FD_ISSET (fdMessageQueue, &fdsRead))
+#else
+ if (1)
+#endif
+ {
+ /* Process Windows messages */
+ if (!winClipboardFlushWindowsMessageQueue (hwnd))
+ {
+ ErrorF ("winClipboardProc - "
+ "winClipboardFlushWindowsMessageQueue trapped "
+ "WM_QUIT message, exiting main loop.\n");
+ break;
+ }
+ }
+ }
+
+ /* Close our X window */
+ if (pDisplay && iWindow)
+ {
+ iReturn = XDestroyWindow (pDisplay, iWindow);
+ if (iReturn == BadWindow)
+ ErrorF ("winClipboardProc - XDestroyWindow returned BadWindow.\n");
+#ifdef WINDBG
+ else
+ winDebug ("winClipboardProc - XDestroyWindow succeeded.\n");
+#endif
+ }
+
+
+#ifdef HAS_DEVWINDOWS
+ /* Close our Win32 message handle */
+ if (fdMessageQueue)
+ close (fdMessageQueue);
+#endif
+
+#if 0
+ /*
+ * FIXME: XCloseDisplay hangs if we call it, as of 2004/03/26. The
+ * XSync and XSelectInput calls did not help.
+ */
+
+ /* Discard any remaining events */
+ XSync (pDisplay, TRUE);
+
+ /* Select event types to watch */
+ XSelectInput (pDisplay,
+ DefaultRootWindow (pDisplay),
+ None);
+
+ /* Close our X display */
+ if (pDisplay)
+ {
+ XCloseDisplay (pDisplay);
+ }
+#endif
+
+ g_iClipboardWindow = None;
+ g_pClipboardDisplay = NULL;
+ g_fClipboardLaunched = FALSE;
+ g_fClipboardStarted = FALSE;
+
+ return NULL;
+thread_errorexit:
+ if (g_pClipboardDisplay && g_iClipboardWindow)
+ {
+ iReturn = XDestroyWindow (g_pClipboardDisplay, g_iClipboardWindow);
+ if (iReturn == BadWindow)
+ ErrorF ("winClipboardProc - XDestroyWindow returned BadWindow.\n");
+#ifdef WINDBG
+ else
+ winDebug ("winClipboardProc - XDestroyWindow succeeded.\n");
+#endif
+ }
+ g_iClipboardWindow = None;
+ g_pClipboardDisplay = NULL;
+ g_fClipboardLaunched = FALSE;
+ g_fClipboardStarted = FALSE;
+ //pthread_exit (NULL);
+ winDebug ("Clipboard thread died.\n");
+ return NULL;
+}
+
+
+/*
+ * winClipboardErrorHandler - Our application specific error handler
+ */
+
+static int
+winClipboardErrorHandler (Display *pDisplay, XErrorEvent *pErr)
+{
+ char pszErrorMsg[100];
+
+ XGetErrorText (pDisplay,
+ pErr->error_code,
+ pszErrorMsg,
+ sizeof (pszErrorMsg));
+ ErrorF ("winClipboardErrorHandler - ERROR: \n\t%s\n"
+ " errorCode %d\n"
+ " serial %d\n"
+ " resourceID 0x%x\n"
+ " majorCode %d\n"
+ " minorCode %d\n"
+ , pszErrorMsg
+ , pErr->error_code
+ , pErr->serial
+ , pErr->resourceid
+ , pErr->request_code
+ , pErr->minor_code);
+ return 0;
+}
+
+
+/*
+ * winClipboardIOErrorHandler - Our application specific IO error handler
+ */
+
+static int
+winClipboardIOErrorHandler (Display *pDisplay)
+{
+ ErrorF ("\nwinClipboardIOErrorHandler!\n\n");
+
+ /* Restart at the main entry point */
+ longjmp (g_jmpEntry, WIN_JMP_ERROR_IO);
+
+ return 0;
+}
diff --git a/xorg-server/hw/xwin/winclipboardunicode.c b/xorg-server/hw/xwin/winclipboardunicode.c index ba86915a4..947475509 100644 --- a/xorg-server/hw/xwin/winclipboardunicode.c +++ b/xorg-server/hw/xwin/winclipboardunicode.c @@ -43,25 +43,43 @@ Bool winClipboardDetectUnicodeSupport (void) { Bool fReturn = FALSE; - OSVERSIONINFO osvi = {0}; + OSVERSIONINFOEX osvi = {0}; /* Get operating system version information */ osvi.dwOSVersionInfoSize = sizeof (osvi); - GetVersionEx (&osvi); + GetVersionEx ((LPOSVERSIONINFO)&osvi); /* Branch on platform ID */ switch (osvi.dwPlatformId) { case VER_PLATFORM_WIN32_NT: - /* Unicode supported on NT only */ - ErrorF ("DetectUnicodeSupport - Windows NT/2000/XP\n"); - fReturn = TRUE; + if (osvi.dwMajorVersion >= 6) + { + if (osvi.wProductType == VER_NT_WORKSTATION) + winDebug ("OS: Windows Vista\n"); + else + winDebug ("OS: Windows Server 2008\n"); + fReturn = TRUE; + } + else if (osvi.dwMajorVersion == 5) + { + if (osvi.dwMinorVersion == 2) + { + winDebug ("OS: Windows 2003\n"); + fReturn = TRUE; + } + else if (osvi.dwMinorVersion == 1) + { + winDebug ("OS: Windows XP\n"); + fReturn = TRUE; + } + else if (osvi.dwMinorVersion == 0) winDebug ("OS: Windows 2000\n"); + } + else if (osvi.dwMajorVersion <= 4) winDebug ("OS: Windows NT\n"); break; case VER_PLATFORM_WIN32_WINDOWS: - /* Unicode is not supported on non-NT */ - ErrorF ("DetectUnicodeSupport - Windows 95/98/Me\n"); - fReturn = FALSE; + winDebug ("OS: Windows 95/98/Me\n"); break; } diff --git a/xorg-server/hw/xwin/winclipboardwndproc.c b/xorg-server/hw/xwin/winclipboardwndproc.c index 9394b04db..dbfc61e4e 100644 --- a/xorg-server/hw/xwin/winclipboardwndproc.c +++ b/xorg-server/hw/xwin/winclipboardwndproc.c @@ -1,629 +1,550 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. - *Copyright (C) Colin Harrison 2005-2008 - * - *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 HAROLD L HUNT II 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 copyright holder(s) - *and author(s) 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 copyright holder(s) and author(s). - * - * Authors: Harold L Hunt II - * Colin Harrison - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include <sys/types.h> -#include <sys/time.h> -#include "winclipboard.h" -#include "misc.h" - -/* - * Constants - */ - -#define WIN_CLIPBOARD_PROP "cyg_clipboard_prop" -#define WIN_POLL_TIMEOUT 1 - - -/* - * References to external symbols - */ - -extern Bool g_fUseUnicode; -extern Bool g_fUnicodeSupport; -extern void *g_pClipboardDisplay; -extern Window g_iClipboardWindow; -extern Atom g_atomLastOwnedSelection; - -/* BPS - g_hwndClipboard needed for X app->Windows paste fix */ -extern HWND g_hwndClipboard; - -/* - * Local function prototypes - */ - -static int -winProcessXEventsTimeout (HWND hwnd, int iWindow, Display *pDisplay, - Bool fUseUnicode, int iTimeoutSec); - - -/* - * Process X events up to specified timeout - */ - -static int -winProcessXEventsTimeout (HWND hwnd, int iWindow, Display *pDisplay, - Bool fUseUnicode, int iTimeoutSec) -{ - int iConnNumber; - struct timeval tv; - int iReturn; - DWORD dwStopTime = (GetTickCount () / 1000) + iTimeoutSec; - - /* We need to ensure that all pending events are processed */ - XSync (pDisplay, FALSE); - - /* Get our connection number */ - iConnNumber = ConnectionNumber (pDisplay); - - /* Loop for X events */ - while (1) - { - fd_set fdsRead; - - /* Setup the file descriptor set */ - FD_ZERO (&fdsRead); - FD_SET (iConnNumber, &fdsRead); - - /* Adjust timeout */ - tv.tv_sec = dwStopTime - (GetTickCount () / 1000); - tv.tv_usec = 0; - - /* Break out if no time left */ - if (tv.tv_sec < 0) - return WIN_XEVENTS_SUCCESS; - - /* Wait for an X event */ - iReturn = select (iConnNumber + 1,/* Highest fds number */ - &fdsRead, /* Read mask */ - NULL, /* No write mask */ - NULL, /* No exception mask */ - &tv); /* No timeout */ - if (iReturn < 0) - { - ErrorF ("winProcessXEventsTimeout - Call to select () failed: %d. " - "Bailing.\n", iReturn); - break; - } - - /* Branch on which descriptor became active */ - if (FD_ISSET (iConnNumber, &fdsRead)) - { - /* Process X events */ - /* Exit when we see that server is shutting down */ - iReturn = winClipboardFlushXEvents (hwnd, - iWindow, - pDisplay, - fUseUnicode); - if (WIN_XEVENTS_NOTIFY == iReturn - || WIN_XEVENTS_CONVERT == iReturn) - { - /* Bail out if convert or notify processed */ - return iReturn; - } - } - } - - return WIN_XEVENTS_SUCCESS; -} - - -/* - * Process a given Windows message - */ - -/* BPS - Define our own message, which we'll post to ourselves to facilitate - * resetting the delayed rendering mechanism after each paste from X app to - * Windows app. TODO - Perhaps move to win.h with the other WM_USER messages. - */ -#define WM_USER_PASTE_COMPLETE (WM_USER + 1003) - -LRESULT CALLBACK -winClipboardWindowProc (HWND hwnd, UINT message, - WPARAM wParam, LPARAM lParam) -{ - static HWND s_hwndNextViewer; - static Bool s_fCBCInitialized; - - /* Branch on message type */ - switch (message) - { - case WM_DESTROY: - { - winDebug ("winClipboardWindowProc - WM_DESTROY\n"); - - /* Remove ourselves from the clipboard chain */ - ChangeClipboardChain (hwnd, s_hwndNextViewer); - - s_hwndNextViewer = NULL; - - PostQuitMessage (0); - } - return 0; - - - case WM_CREATE: - { - HWND first, next; - DWORD error_code = 0; - winDebug ("winClipboardWindowProc - WM_CREATE\n"); - - first = GetClipboardViewer(); /* Get handle to first viewer in chain. */ - if (first == hwnd) return 0; /* Make sure it's not us! */ - /* Add ourselves to the clipboard viewer chain */ - next = SetClipboardViewer (hwnd); - error_code = GetLastError(); - if (SUCCEEDED(error_code) && (next == first)) /* SetClipboardViewer must have succeeded, and the handle */ - s_hwndNextViewer = next; /* it returned must have been the first window in the chain */ - else - s_fCBCInitialized = FALSE; - } - return 0; - - - case WM_CHANGECBCHAIN: - { - winDebug ("winClipboardWindowProc - WM_CHANGECBCHAIN: wParam(%x) " - "lParam(%x) s_hwndNextViewer(%x)\n", - wParam, lParam, s_hwndNextViewer); - - if ((HWND) wParam == s_hwndNextViewer) - { - s_hwndNextViewer = (HWND) lParam; - if (s_hwndNextViewer == hwnd) - { - s_hwndNextViewer = NULL; - winErrorFVerb (1, "winClipboardWindowProc - WM_CHANGECBCHAIN: " - "attempted to set next window to ourselves."); - } - } - else if (s_hwndNextViewer) - SendMessage (s_hwndNextViewer, message, - wParam, lParam); - - } - winDebug ("winClipboardWindowProc - WM_CHANGECBCHAIN: Exit\n"); - return 0; - - case WM_WM_REINIT: - { - /* Ensure that we're in the clipboard chain. Some apps, - * WinXP's remote desktop for one, don't play nice with the - * chain. This message is called whenever we receive a - * WM_ACTIVATEAPP message to ensure that we continue to - * receive clipboard messages. - * - * It might be possible to detect if we're still in the chain - * by calling SendMessage (GetClipboardViewer(), - * WM_DRAWCLIPBOARD, 0, 0); and then seeing if we get the - * WM_DRAWCLIPBOARD message. That, however, might be more - * expensive than just putting ourselves back into the chain. - */ - - HWND first, next; - DWORD error_code = 0; - winDebug ("winClipboardWindowProc - WM_WM_REINIT: Enter\n"); - - first = GetClipboardViewer(); /* Get handle to first viewer in chain. */ - if (first == hwnd) return 0; /* Make sure it's not us! */ - winDebug (" WM_WM_REINIT: Replacing us(%x) with %x at head " - "of chain\n", hwnd, s_hwndNextViewer); - s_fCBCInitialized = FALSE; - ChangeClipboardChain (hwnd, s_hwndNextViewer); - s_hwndNextViewer = NULL; - s_fCBCInitialized = FALSE; - winDebug (" WM_WM_REINIT: Putting us back at head of chain.\n"); - first = GetClipboardViewer(); /* Get handle to first viewer in chain. */ - if (first == hwnd) return 0; /* Make sure it's not us! */ - next = SetClipboardViewer (hwnd); - error_code = GetLastError(); - if (SUCCEEDED(error_code) && (next == first)) /* SetClipboardViewer must have succeeded, and the handle */ - s_hwndNextViewer = next; /* it returned must have been the first window in the chain */ - else - s_fCBCInitialized = FALSE; - } - winDebug ("winClipboardWindowProc - WM_WM_REINIT: Exit\n"); - return 0; - - - case WM_DRAWCLIPBOARD: - { - static Atom atomClipboard; - static int generation; - static Bool s_fProcessingDrawClipboard = FALSE; - Display *pDisplay = g_pClipboardDisplay; - Window iWindow = g_iClipboardWindow; - int iReturn; - - winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Enter\n"); - - if (generation != serverGeneration) - { - generation = serverGeneration; - atomClipboard = XInternAtom (pDisplay, "CLIPBOARD", False); - } - - /* - * We've occasionally seen a loop in the clipboard chain. - * Try and fix it on the first hint of recursion. - */ - if (! s_fProcessingDrawClipboard) - { - s_fProcessingDrawClipboard = TRUE; - } - else - { - /* Attempt to break the nesting by getting out of the chain, twice?, and then fix and bail */ - s_fCBCInitialized = FALSE; - ChangeClipboardChain (hwnd, s_hwndNextViewer); - winFixClipboardChain(); - winErrorFVerb (1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "Nested calls detected. Re-initing.\n"); - winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); - s_fProcessingDrawClipboard = FALSE; - return 0; - } - - /* Bail on first message */ - if (!s_fCBCInitialized) - { - s_fCBCInitialized = TRUE; - s_fProcessingDrawClipboard = FALSE; - winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); - return 0; - } - - /* - * NOTE: We cannot bail out when NULL == GetClipboardOwner () - * because some applications deal with the clipboard in a manner - * that causes the clipboard owner to be NULL when they are in - * fact taking ownership. One example of this is the Win32 - * native compile of emacs. - */ - - /* Bail when we still own the clipboard */ - if (hwnd == GetClipboardOwner ()) - { - - winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "We own the clipboard, returning.\n"); - winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); - s_fProcessingDrawClipboard = FALSE; - if (s_hwndNextViewer) - SendMessage (s_hwndNextViewer, message, wParam, lParam); - return 0; - } - - /* - * Do not take ownership of the X11 selections when something - * other than CF_TEXT or CF_UNICODETEXT has been copied - * into the Win32 clipboard. - */ - if (!IsClipboardFormatAvailable (CF_TEXT) - && !IsClipboardFormatAvailable (CF_UNICODETEXT)) - { - - winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "Clipboard does not contain CF_TEXT nor " - "CF_UNICODETEXT.\n"); - - /* - * We need to make sure that the X Server has processed - * previous XSetSelectionOwner messages. - */ - XSync (pDisplay, FALSE); - - /* Release PRIMARY selection if owned */ - iReturn = XGetSelectionOwner (pDisplay, XA_PRIMARY); - if (iReturn == g_iClipboardWindow) - { - winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "PRIMARY selection is owned by us.\n"); - XSetSelectionOwner (pDisplay, - XA_PRIMARY, - None, - CurrentTime); - } - else if (BadWindow == iReturn || BadAtom == iReturn) - winErrorFVerb (1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "XGetSelection failed for PRIMARY: %d\n", iReturn); - - /* Release CLIPBOARD selection if owned */ - iReturn = XGetSelectionOwner (pDisplay, - atomClipboard); - if (iReturn == g_iClipboardWindow) - { - winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "CLIPBOARD selection is owned by us.\n"); - XSetSelectionOwner (pDisplay, - atomClipboard, - None, - CurrentTime); - } - else if (BadWindow == iReturn || BadAtom == iReturn) - winErrorFVerb (1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "XGetSelection failed for CLIPBOARD: %d\n", iReturn); - - winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); - s_fProcessingDrawClipboard = FALSE; - if (s_hwndNextViewer) - SendMessage (s_hwndNextViewer, message, wParam, lParam); - return 0; - } - - /* Reassert ownership of PRIMARY */ - iReturn = XSetSelectionOwner (pDisplay, - XA_PRIMARY, - iWindow, - CurrentTime); - if (iReturn == BadAtom || iReturn == BadWindow || - XGetSelectionOwner (pDisplay, XA_PRIMARY) != iWindow) - { - winErrorFVerb (1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "Could not reassert ownership of PRIMARY\n"); - } - else - { - winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "Reasserted ownership of PRIMARY\n"); - } - - /* Reassert ownership of the CLIPBOARD */ - iReturn = XSetSelectionOwner (pDisplay, - atomClipboard, - iWindow, - CurrentTime); - - if (iReturn == BadAtom || iReturn == BadWindow || - XGetSelectionOwner (pDisplay, atomClipboard) != iWindow) - { - winErrorFVerb (1, "winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "Could not reassert ownership of CLIPBOARD\n"); - } - else - { - winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - " - "Reasserted ownership of CLIPBOARD\n"); - } - - /* Flush the pending SetSelectionOwner event now */ - XFlush (pDisplay); - - s_fProcessingDrawClipboard = FALSE; - } - winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n"); - /* Pass the message on the next window in the clipboard viewer chain */ - if (s_hwndNextViewer) - SendMessage (s_hwndNextViewer, message, wParam, lParam); - return 0; - - - case WM_DESTROYCLIPBOARD: - /* - * NOTE: Intentionally do nothing. - * Changes in the Win32 clipboard are handled by WM_DRAWCLIPBOARD - * above. We only process this message to conform to the specs - * for delayed clipboard rendering in Win32. You might think - * that we need to release ownership of the X11 selections, but - * we do not, because a WM_DRAWCLIPBOARD message will closely - * follow this message and reassert ownership of the X11 - * selections, handling the issue for us. - */ - winDebug ("winClipboardWindowProc - WM_DESTROYCLIPBOARD - Ignored.\n"); - return 0; - - case WM_RENDERFORMAT: - case WM_RENDERALLFORMATS: - { - int iReturn; - Display *pDisplay = g_pClipboardDisplay; - Window iWindow = g_iClipboardWindow; - Bool fConvertToUnicode; - - winDebug ("winClipboardWindowProc - WM_RENDER*FORMAT - Hello.\n"); - - /* Flag whether to convert to Unicode or not */ - if (message == WM_RENDERALLFORMATS) - fConvertToUnicode = FALSE; - else - fConvertToUnicode = g_fUnicodeSupport && (CF_UNICODETEXT == wParam); - - /* Request the selection contents */ - iReturn = XConvertSelection (pDisplay, - g_atomLastOwnedSelection, - XInternAtom (pDisplay, - "COMPOUND_TEXT", False), - XInternAtom (pDisplay, - "CYGX_CUT_BUFFER", False), - iWindow, - CurrentTime); - if (iReturn == BadAtom || iReturn == BadWindow) - { - winErrorFVerb (1, "winClipboardWindowProc - WM_RENDER*FORMAT - " - "XConvertSelection () failed\n"); - break; - } - - /* Special handling for WM_RENDERALLFORMATS */ - if (message == WM_RENDERALLFORMATS) - { - /* We must open and empty the clipboard */ - - /* Close clipboard if we have it open already */ - if (GetOpenClipboardWindow () == hwnd) - { - CloseClipboard (); - } - - if (!OpenClipboard (hwnd)) - { - winErrorFVerb (1, "winClipboardWindowProc - WM_RENDER*FORMATS - " - "OpenClipboard () failed: %08x\n", - GetLastError ()); - break; - } - - if (!EmptyClipboard ()) - { - winErrorFVerb (1, "winClipboardWindowProc - WM_RENDER*FORMATS - " - "EmptyClipboard () failed: %08x\n", - GetLastError ()); - break; - } - } - - /* Process the SelectionNotify event */ - iReturn = winProcessXEventsTimeout (hwnd, - iWindow, - pDisplay, - fConvertToUnicode, - WIN_POLL_TIMEOUT); - if (WIN_XEVENTS_CONVERT == iReturn) - { - /* - * The selection was offered for conversion first, so we have - * to process a second SelectionNotify event to get the actual - * data in the selection. - */ - iReturn = winProcessXEventsTimeout (hwnd, - iWindow, - pDisplay, - fConvertToUnicode, - WIN_POLL_TIMEOUT); - } - - /* - * The last of the up-to two calls to winProcessXEventsTimeout - * from above had better have seen a notify event, or else we - * are dealing with a buggy or old X11 app. In these cases we - * have to paste some fake data to the Win32 clipboard to - * satisfy the requirement that we write something to it. - */ - if (WIN_XEVENTS_NOTIFY != iReturn) - { - /* Paste no data, to satisfy required call to SetClipboardData */ - if (g_fUnicodeSupport) - SetClipboardData (CF_UNICODETEXT, NULL); - SetClipboardData (CF_TEXT, NULL); - - ErrorF("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY\n"); - } - - /* BPS - Post ourselves a user message whose handler will reset the - * delayed rendering mechanism after the paste is complete. This is - * necessary because calling SetClipboardData() with a NULL argument - * here will cause the data we just put on the clipboard to be lost! - */ - PostMessage(g_hwndClipboard, WM_USER_PASTE_COMPLETE, 0, 0); - - /* Special handling for WM_RENDERALLFORMATS */ - if (message == WM_RENDERALLFORMATS) - { - /* We must close the clipboard */ - - if (!CloseClipboard ()) - { - winErrorFVerb (1, "winClipboardWindowProc - WM_RENDERALLFORMATS - " - "CloseClipboard () failed: %08x\n", - GetLastError ()); - break; - } - } - - winDebug ("winClipboardWindowProc - WM_RENDER*FORMAT - Returning.\n"); - return 0; - } - /* BPS - This WM_USER message is posted by us. It gives us the opportunity - * to reset the delayed rendering mechanism after each and every paste - * from an X app to a Windows app. Without such a mechanism, subsequent - * changes of selection in the X app owning the selection are not - * reflected in pastes into Windows apps, since Windows won't send us the - * WM_RENDERFORMAT message unless someone has set changed data (or NULL) - * on the clipboard. */ - case WM_USER_PASTE_COMPLETE: - { - if (hwnd != GetClipboardOwner ()) - /* In case we've lost the selection since posting the message */ - return 0; - winDebug ("winClipboardWindowProc - WM_USER_PASTE_COMPLETE\n"); - - /* Set up for another delayed rendering callback */ - OpenClipboard (g_hwndClipboard); - - /* Take ownership of the Windows clipboard */ - EmptyClipboard (); - - /* Advertise Unicode if we support it */ - if (g_fUnicodeSupport) - SetClipboardData (CF_UNICODETEXT, NULL); - - /* Always advertise regular text */ - SetClipboardData (CF_TEXT, NULL); - - /* Release the clipboard */ - CloseClipboard (); - } - return 0; - } - - /* Let Windows perform default processing for unhandled messages */ - return DefWindowProc (hwnd, message, wParam, lParam); -} - - -/* - * Process any pending Windows messages - */ - -BOOL -winClipboardFlushWindowsMessageQueue (HWND hwnd) -{ - MSG msg; - - /* Flush the messaging window queue */ - /* NOTE: Do not pass the hwnd of our messaging window to PeekMessage, - * as this will filter out many non-window-specific messages that - * are sent to our thread, such as WM_QUIT. - */ - while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) - { - /* Dispatch the message if not WM_QUIT */ - if (msg.message == WM_QUIT) - return FALSE; - else - DispatchMessage (&msg); - } - - return TRUE; -} +/*
+ *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
+ *Copyright (C) Colin Harrison 2005-2008
+ *
+ *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 HAROLD L HUNT II 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 copyright holder(s)
+ *and author(s) 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 copyright holder(s) and author(s).
+ *
+ * Authors: Harold L Hunt II
+ * Colin Harrison
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include <sys/types.h>
+#include <sys/time.h>
+#include "winclipboard.h"
+#include "misc.h"
+#include "winmsg.h"
+
+/*
+ * Constants
+ */
+
+#define WIN_CLIPBOARD_PROP "cyg_clipboard_prop"
+#define WIN_POLL_TIMEOUT 1
+
+/*
+ * References to external symbols
+ */
+
+extern Bool g_fUseUnicode;
+extern Bool g_fUnicodeSupport;
+extern void *g_pClipboardDisplay;
+extern Window g_iClipboardWindow;
+extern Atom g_atomLastOwnedSelection;
+extern Bool g_fClipboardStarted;
+/* BPS - g_hwndClipboard needed for X app->Windows paste fix */
+extern HWND g_hwndClipboard;
+
+/*
+ * Local function prototypes
+ */
+
+static int
+winProcessXEventsTimeout (HWND hwnd, int iWindow, Display *pDisplay,
+ Bool fUseUnicode, int iTimeoutSec);
+
+
+/*
+ * Process X events up to specified timeout
+ */
+
+static int
+winProcessXEventsTimeout (HWND hwnd, int iWindow, Display *pDisplay,
+ Bool fUseUnicode, int iTimeoutSec)
+{
+ int iConnNumber;
+ struct timeval tv;
+ int iReturn;
+ DWORD dwStopTime = (GetTickCount () / 1000) + iTimeoutSec;
+
+ /* Make sure the output messages are sent before waiting on a response. */
+ iReturn = winClipboardFlushXEvents (hwnd,
+ iWindow,
+ pDisplay,
+ fUseUnicode,
+ TRUE);
+ if (WIN_XEVENTS_NOTIFY == iReturn || WIN_XEVENTS_CONVERT == iReturn)
+ {
+ /* Bail out if convert or notify processed */
+ return iReturn;
+ }
+
+ /* Get our connection number */
+ iConnNumber = ConnectionNumber (pDisplay);
+
+ /* Loop for X events */
+ while (1)
+ {
+ fd_set fdsRead;
+
+ /* Setup the file descriptor set */
+ FD_ZERO (&fdsRead);
+ FD_SET (iConnNumber, &fdsRead);
+
+ /* Adjust timeout */
+ tv.tv_sec = dwStopTime - (GetTickCount () / 1000);
+ tv.tv_usec = 0;
+
+ /* Break out if no time left */
+ if (tv.tv_sec < 0)
+ return WIN_XEVENTS_SUCCESS;
+
+ /* Wait for an X event */
+ iReturn = select (iConnNumber + 1,/* Highest fds number */
+ &fdsRead, /* Read mask */
+ NULL, /* No write mask */
+ NULL, /* No exception mask */
+ &tv); /* No timeout */
+ if (iReturn < 0)
+ {
+ ErrorF ("winProcessXEventsTimeout - Call to select () failed: %d (%x). "
+ "Bailing.\n", iReturn, WSAGetLastError());
+ break;
+ }
+
+ /* Branch on which descriptor became active */
+ if (FD_ISSET (iConnNumber, &fdsRead))
+ {
+ /* Process X events */
+ /* Exit when we see that server is shutting down */
+ iReturn = winClipboardFlushXEvents (hwnd,
+ iWindow,
+ pDisplay,
+ fUseUnicode,
+ TRUE);
+ if (WIN_XEVENTS_NOTIFY == iReturn
+ || WIN_XEVENTS_CONVERT == iReturn)
+ {
+ /* Bail out if convert or notify processed */
+ return iReturn;
+ }
+ }
+ }
+
+ return WIN_XEVENTS_SUCCESS;
+}
+
+/*
+ * Process a given Windows message
+ */
+
+LRESULT CALLBACK
+winClipboardWindowProc (HWND hwnd, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ static HWND s_hwndNextViewer;
+
+ /* Branch on message type */
+ switch (message)
+ {
+ case WM_DESTROY:
+ {
+ winDebug ("winClipboardWindowProc - WM_DESTROY\n");
+
+ /* Remove ourselves from the clipboard chain */
+ ChangeClipboardChain (hwnd, s_hwndNextViewer);
+
+ s_hwndNextViewer = NULL;
+ g_hwndClipboard = NULL;
+ PostQuitMessage (0);
+ }
+ return 0;
+
+
+ case WM_CREATE:
+ {
+ HWND first, next;
+ DWORD error_code = 0;
+ winDebug ("winClipboardWindowProc - WM_CREATE\n");
+
+ /* Add ourselves to the clipboard viewer chain */
+ s_hwndNextViewer = SetClipboardViewer (hwnd);
+ }
+ return 0;
+
+
+ case WM_CHANGECBCHAIN:
+ {
+ winDebug ("winClipboardWindowProc - WM_CHANGECBCHAIN: wParam(%x) "
+ "lParam(%x) s_hwndNextViewer(%x)\n",
+ wParam, lParam, s_hwndNextViewer);
+
+ if ((HWND) wParam == s_hwndNextViewer)
+ {
+ s_hwndNextViewer = (HWND) lParam;
+ }
+ else if (s_hwndNextViewer)
+ SendMessage (s_hwndNextViewer, message,
+ wParam, lParam);
+
+ }
+ winDebug ("winClipboardWindowProc - WM_CHANGECBCHAIN: Exit\n");
+ return 0;
+
+ case WM_WM_REINIT:
+ {
+ /* Ensure that we're in the clipboard chain. Some apps,
+ * WinXP's remote desktop for one, don't play nice with the
+ * chain. This message is called whenever we receive a
+ * WM_ACTIVATEAPP message to ensure that we continue to
+ * receive clipboard messages.
+ *
+ * It might be possible to detect if we're still in the chain
+ * by calling SendMessage (GetClipboardViewer(),
+ * WM_DRAWCLIPBOARD, 0, 0); and then seeing if we get the
+ * WM_DRAWCLIPBOARD message. That, however, might be more
+ * expensive than just putting ourselves back into the chain.
+ */
+
+ HWND first, next;
+ DWORD error_code = 0;
+ if (!g_hwndClipboard)
+ return 0;
+ winDebug ("winClipboardWindowProc - WM_WM_REINIT: Enter\n");
+
+ first = GetClipboardViewer(); /* Get handle to first viewer in chain. */
+ if (first != hwnd)
+ {
+ winDebug (" WM_WM_REINIT: Replacing us(%x) with %x at head "
+ "of chain\n", hwnd, s_hwndNextViewer);
+ ChangeClipboardChain (hwnd, s_hwndNextViewer);
+ winDebug (" WM_WM_REINIT: Putting us back at head of chain.\n");
+ s_hwndNextViewer = SetClipboardViewer (hwnd);
+ }
+ winDebug ("winClipboardWindowProc - WM_WM_REINIT: Exit\n");
+ }
+ return 0;
+
+
+ case WM_DRAWCLIPBOARD:
+ {
+ static Atom atomClipboard;
+ static int generation;
+ static Bool s_fProcessingDrawClipboard = FALSE;
+ Display *pDisplay = g_pClipboardDisplay;
+ Window iWindow = g_iClipboardWindow;
+ int iReturn;
+
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD 0x%x 0x%x 0x%x: Enter\n",hwnd,wParam,lParam);
+
+ if (!g_fClipboardStarted)
+ {
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit with no processing\n");
+ if (s_hwndNextViewer)
+ SendMessage (s_hwndNextViewer, message, wParam, lParam);
+ return 0;
+ }
+
+ if (generation != serverGeneration)
+ {
+ generation = serverGeneration;
+ atomClipboard = XInternAtom (pDisplay, "CLIPBOARD", False);
+ }
+
+ /*
+ * We've occasionally seen a loop in the clipboard chain.
+ * Try and fix it on the first hint of recursion.
+ */
+ if (! s_fProcessingDrawClipboard)
+ {
+ s_fProcessingDrawClipboard = TRUE;
+ }
+ else
+ {
+ /* Attempt to break the nesting by getting out of the chain, twice?, and then fix and bail */
+ ChangeClipboardChain (hwnd, s_hwndNextViewer);
+ winFixClipboardChain();
+ ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Nested calls detected. Re-initing.\n");
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
+ s_fProcessingDrawClipboard = FALSE;
+ return 0;
+ }
+
+ /*
+ * Do not take ownership of the X11 selections when something
+ * other than CF_TEXT or CF_UNICODETEXT has been copied
+ * into the Win32 clipboard.
+ */
+ if (!IsClipboardFormatAvailable (CF_TEXT)
+ && !IsClipboardFormatAvailable (CF_UNICODETEXT))
+ {
+
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Clipboard does not contain CF_TEXT nor "
+ "CF_UNICODETEXT.\n");
+
+ /*
+ * We need to make sure that the X Server has processed
+ * previous XSetSelectionOwner messages.
+ */
+ XSync (pDisplay, FALSE);
+
+ /* Release PRIMARY selection if owned */
+ iReturn = XGetSelectionOwner (pDisplay, XA_PRIMARY);
+ if (iReturn == g_iClipboardWindow)
+ {
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "PRIMARY selection is owned by us.\n");
+ XSetSelectionOwner (pDisplay,
+ XA_PRIMARY,
+ None,
+ CurrentTime);
+ }
+ else if (BadWindow == iReturn || BadAtom == iReturn)
+ ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "XGetSelection failed for PRIMARY: %d\n", iReturn);
+
+ /* Release CLIPBOARD selection if owned */
+ iReturn = XGetSelectionOwner (pDisplay,
+ atomClipboard);
+ if (iReturn == g_iClipboardWindow)
+ {
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "CLIPBOARD selection is owned by us.\n");
+ XSetSelectionOwner (pDisplay,
+ atomClipboard,
+ None,
+ CurrentTime);
+ }
+ else if (BadWindow == iReturn || BadAtom == iReturn)
+ ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "XGetSelection failed for CLIPBOARD: %d\n", iReturn);
+
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
+ s_fProcessingDrawClipboard = FALSE;
+ if (s_hwndNextViewer)
+ SendMessage (s_hwndNextViewer, message, wParam, lParam);
+ return 0;
+ }
+ /* Only reassert ownership when we did not change the clipboard ourselves */
+ if (hwnd!=(HWND)wParam)
+ {
+ /* Reassert ownership of PRIMARY */
+ iReturn = XSetSelectionOwner (pDisplay,
+ XA_PRIMARY,
+ iWindow,
+ CurrentTime);
+ if (iReturn == BadAtom || iReturn == BadWindow ||
+ XGetSelectionOwner (pDisplay, XA_PRIMARY) != iWindow)
+ {
+ ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Could not reassert ownership of PRIMARY\n");
+ }
+ else
+ {
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Reasserted ownership of PRIMARY\n");
+ }
+
+ /* Reassert ownership of the CLIPBOARD */
+ iReturn = XSetSelectionOwner (pDisplay,
+ atomClipboard,
+ iWindow,
+ CurrentTime);
+
+ if (iReturn == BadAtom || iReturn == BadWindow ||
+ XGetSelectionOwner (pDisplay, atomClipboard) != iWindow)
+ {
+ ErrorF ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Could not reassert ownership of CLIPBOARD\n");
+ }
+ else
+ {
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD - "
+ "Reasserted ownership of CLIPBOARD\n");
+ }
+
+ /* Flush the pending SetSelectionOwner event now */
+ XFlush (pDisplay);
+ }
+
+ s_fProcessingDrawClipboard = FALSE;
+ winDebug ("winClipboardWindowProc - WM_DRAWCLIPBOARD: Exit\n");
+ /* Pass the message on the next window in the clipboard viewer chain */
+ if (s_hwndNextViewer)
+ SendMessage (s_hwndNextViewer, message, wParam, lParam);
+ return 0;
+
+ }
+
+ case WM_DESTROYCLIPBOARD:
+ /*
+ * NOTE: Intentionally do nothing.
+ * Changes in the Win32 clipboard are handled by WM_DRAWCLIPBOARD
+ * above. We only process this message to conform to the specs
+ * for delayed clipboard rendering in Win32. You might think
+ * that we need to release ownership of the X11 selections, but
+ * we do not, because a WM_DRAWCLIPBOARD message will closely
+ * follow this message and reassert ownership of the X11
+ * selections, handling the issue for us.
+ */
+ winDebug ("winClipboardWindowProc - WM_DESTROYCLIPBOARD - Ignored.\n");
+ return 0;
+
+ case WM_RENDERFORMAT:
+ case WM_RENDERALLFORMATS:
+ {
+ int iReturn;
+ Display *pDisplay = g_pClipboardDisplay;
+ Window iWindow = g_iClipboardWindow;
+ Bool fConvertToUnicode;
+
+ winDebug ("winClipboardWindowProc - WM_RENDER*FORMAT - Hello.\n");
+
+ /* Flag whether to convert to Unicode or not */
+ if (message == WM_RENDERALLFORMATS)
+ fConvertToUnicode = FALSE;
+ else
+ fConvertToUnicode = g_fUnicodeSupport && (CF_UNICODETEXT == wParam);
+
+ /* Request the selection contents */
+ iReturn = XConvertSelection (pDisplay,
+ g_atomLastOwnedSelection,
+ XInternAtom (pDisplay,
+ "COMPOUND_TEXT", False),
+ XInternAtom (pDisplay,
+ WIN_LOCAL_PROPERTY, False),
+ iWindow,
+ CurrentTime);
+ if (iReturn == BadAtom || iReturn == BadWindow)
+ {
+ ErrorF ("winClipboardWindowProc - WM_RENDER*FORMAT - "
+ "XConvertSelection () failed\n");
+ break;
+ }
+
+ /* Special handling for WM_RENDERALLFORMATS */
+ if (message == WM_RENDERALLFORMATS)
+ {
+ /* We must open and empty the clipboard */
+ if (!OpenClipboard (hwnd))
+ {
+ ErrorF ("winClipboardWindowProc - WM_RENDER*FORMATS - "
+ "OpenClipboard () failed: %08x\n",
+ GetLastError ());
+ break;
+ }
+
+ if (!EmptyClipboard ())
+ {
+ ErrorF ("winClipboardWindowProc - WM_RENDER*FORMATS - "
+ "EmptyClipboard () failed: %08x\n",
+ GetLastError ());
+ CloseClipboard ();
+ break;
+ }
+ }
+
+ /* Process the SelectionNotify event */
+ iReturn = winProcessXEventsTimeout (hwnd,
+ iWindow,
+ pDisplay,
+ fConvertToUnicode,
+ WIN_POLL_TIMEOUT);
+ if (WIN_XEVENTS_CONVERT == iReturn)
+ {
+ /*
+ * The selection was offered for conversion first, so we have
+ * to process a second SelectionNotify event to get the actual
+ * data in the selection.
+ */
+ winDebug("winClipboardWindowProc - Previous winProcessXEventsTimeout returned WIN_XEVENTS_CONVERT, calling it again\n");
+ iReturn = winProcessXEventsTimeout (hwnd,
+ iWindow,
+ pDisplay,
+ fConvertToUnicode,
+ WIN_POLL_TIMEOUT);
+ }
+
+ /*
+ * The last of the up-to two calls to winProcessXEventsTimeout
+ * from above had better have seen a notify event, or else we
+ * are dealing with a buggy or old X11 app. In these cases we
+ * have to paste some fake data to the Win32 clipboard to
+ * satisfy the requirement that we write something to it.
+ */
+ if (WIN_XEVENTS_NOTIFY != iReturn)
+ {
+ ErrorF("winClipboardWindowProc - winProcessXEventsTimeout should have returned WIN_XEVENTS_NOTIFY was %d\n",iReturn);
+ /* Paste no data, to satisfy required call to SetClipboardData */
+ if (g_fUnicodeSupport)
+ SetClipboardData (CF_UNICODETEXT, NULL);
+ SetClipboardData (CF_TEXT, NULL);
+
+ ErrorF("winClipboardWindowProc - timed out waiting for WIN_XEVENTS_NOTIFY\n");
+ }
+
+ /* Special handling for WM_RENDERALLFORMATS */
+ if (message == WM_RENDERALLFORMATS)
+ {
+ /* We must close the clipboard */
+
+ if (!CloseClipboard ())
+ {
+ ErrorF ("winClipboardWindowProc - WM_RENDERALLFORMATS - "
+ "CloseClipboard () failed: %08x\n",
+ GetLastError ());
+ break;
+ }
+ }
+
+ winDebug ("winClipboardWindowProc - WM_RENDER*FORMAT - Returning.\n");
+ return 0;
+ }
+ }
+
+ /* Let Windows perform default processing for unhandled messages */
+ return DefWindowProc (hwnd, message, wParam, lParam);
+}
+
+
+/*
+ * Process any pending Windows messages
+ */
+
+BOOL
+winClipboardFlushWindowsMessageQueue (HWND hwnd)
+{
+ MSG msg;
+
+ /* Flush the messaging window queue */
+ /* NOTE: Do not pass the hwnd of our messaging window to PeekMessage,
+ * as this will filter out many non-window-specific messages that
+ * are sent to our thread, such as WM_QUIT.
+ */
+ while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ /* Dispatch the message if not WM_QUIT */
+ if (msg.message == WM_QUIT)
+ return FALSE;
+ else
+ DispatchMessage (&msg);
+ }
+
+ return TRUE;
+}
diff --git a/xorg-server/hw/xwin/winclipboardwrappers.c b/xorg-server/hw/xwin/winclipboardwrappers.c index 658d050d2..172365d27 100644 --- a/xorg-server/hw/xwin/winclipboardwrappers.c +++ b/xorg-server/hw/xwin/winclipboardwrappers.c @@ -1,527 +1,494 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. - *Copyright (C) Colin Harrison 2005-2008 - * - *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 HAROLD L HUNT II 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 copyright holder(s) - *and author(s) 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 copyright holder(s) and author(s). - * - * Authors: Harold L Hunt II - * Colin Harrison - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" -#include "dixstruct.h" -#include <X11/Xatom.h> - - -/* - * Constants - */ - -#define CLIP_NUM_CALLS 4 -#define CLIP_NUM_SELECTIONS 2 -#define CLIP_OWN_PRIMARY 0 -#define CLIP_OWN_CLIPBOARD 1 - - -/* - * Local function prototypes - */ - -DISPATCH_PROC(winProcEstablishConnection); -DISPATCH_PROC(winProcQueryTree); -DISPATCH_PROC(winProcSetSelectionOwner); - - -/* - * References to external symbols - */ - -extern Bool g_fUnicodeSupport; -extern int g_iNumScreens; -extern unsigned int g_uiAuthDataLen; -extern char *g_pAuthData; -extern Bool g_fXdmcpEnabled; -extern Bool g_fClipboardLaunched; -extern Bool g_fClipboardStarted; -extern Bool g_fClipboard; -extern Window g_iClipboardWindow; -extern Atom g_atomLastOwnedSelection; -extern HWND g_hwndClipboard; - -extern winDispatchProcPtr winProcEstablishConnectionOrig; -extern winDispatchProcPtr winProcQueryTreeOrig; -extern winDispatchProcPtr winProcSetSelectionOwnerOrig; - - -/* - * Wrapper for internal QueryTree function. - * Hides the clipboard client when it is the only client remaining. - */ - -int -winProcQueryTree (ClientPtr client) -{ - int iReturn; - - ErrorF ("winProcQueryTree - Hello\n"); - - /* - * This procedure is only used for initialization. - * We can unwrap the original procedure at this point - * so that this function is no longer called until the - * server resets and the function is wrapped again. - */ - ProcVector[X_QueryTree] = winProcQueryTreeOrig; - - /* - * Call original function and bail if it fails. - * NOTE: We must do this first, since we need XdmcpOpenDisplay - * to be called before we initialize our clipboard client. - */ - iReturn = (*winProcQueryTreeOrig) (client); - if (iReturn != 0) - { - ErrorF ("winProcQueryTree - ProcQueryTree failed, bailing.\n"); - return iReturn; - } - - /* Make errors more obvious */ - winProcQueryTreeOrig = NULL; - - /* Do nothing if clipboard is not enabled */ - if (!g_fClipboard) - { - ErrorF ("winProcQueryTree - Clipboard is not enabled, " - "returning.\n"); - return iReturn; - } - - /* If the clipboard client has already been started, abort */ - if (g_fClipboardLaunched) - { - ErrorF ("winProcQueryTree - Clipboard client already " - "launched, returning.\n"); - return iReturn; - } - - /* Startup the clipboard client if clipboard mode is being used */ - if (g_fXdmcpEnabled && g_fClipboard) - { - /* - * NOTE: The clipboard client is started here for a reason: - * 1) Assume you are using XDMCP (e.g. XWin -query %hostname%) - * 2) If the clipboard client attaches during X Server startup, - * then it becomes the "magic client" that causes the X Server - * to reset if it exits. - * 3) XDMCP calls KillAllClients when it starts up. - * 4) The clipboard client is a client, so it is killed. - * 5) The clipboard client is the "magic client", so the X Server - * resets itself. - * 6) This repeats ad infinitum. - * 7) We avoid this by waiting until at least one client (could - * be XDM, could be another client) connects, which makes it - * almost certain that the clipboard client will not connect - * until after XDM when using XDMCP. - * 8) Unfortunately, there is another problem. - * 9) XDM walks the list of windows with XQueryTree, - * killing any client it finds with a window. - * 10)Thus, when using XDMCP we wait until the first call - * to ProcQueryTree before we startup the clipboard client. - * This should prevent XDM from finding the clipboard client, - * since it has not yet created a window. - * 11)Startup when not using XDMCP is handled in - * winProcEstablishConnection. - */ - - /* Create the clipboard client thread */ - if (!winInitClipboard ()) - { - ErrorF ("winProcQueryTree - winClipboardInit " - "failed.\n"); - return iReturn; - } - - ErrorF ("winProcQueryTree - winInitClipboard returned.\n"); - } - - /* Flag that clipboard client has been launched */ - g_fClipboardLaunched = TRUE; - - return iReturn; -} - - -/* - * Wrapper for internal EstablishConnection function. - * Initializes internal clients that must not be started until - * an external client has connected. - */ - -int -winProcEstablishConnection (ClientPtr client) -{ - int iReturn; - static int s_iCallCount = 0; - static unsigned long s_ulServerGeneration = 0; - - if (s_iCallCount == 0 || s_iCallCount == CLIP_NUM_CALLS) ErrorF ("winProcEstablishConnection - Hello\n"); - - /* Do nothing if clipboard is not enabled */ - if (!g_fClipboard) - { - ErrorF ("winProcEstablishConnection - Clipboard is not enabled, " - "returning.\n"); - - /* Unwrap the original function, call it, and return */ - InitialVector[2] = winProcEstablishConnectionOrig; - iReturn = (*winProcEstablishConnectionOrig) (client); - winProcEstablishConnectionOrig = NULL; - return iReturn; - } - - /* Watch for server reset */ - if (s_ulServerGeneration != serverGeneration) - { - /* Save new generation number */ - s_ulServerGeneration = serverGeneration; - - /* Reset call count */ - s_iCallCount = 0; - } - - /* Increment call count */ - ++s_iCallCount; - - /* Wait for CLIP_NUM_CALLS when Xdmcp is enabled */ - if (g_fXdmcpEnabled - && !g_fClipboardLaunched - && s_iCallCount < CLIP_NUM_CALLS) - { - if (s_iCallCount == 1) ErrorF ("winProcEstablishConnection - Xdmcp, waiting to " - "start clipboard client until %dth call", CLIP_NUM_CALLS); - if (s_iCallCount == CLIP_NUM_CALLS - 1) ErrorF (".\n"); - else ErrorF ("."); - return (*winProcEstablishConnectionOrig) (client); - } - - /* - * This procedure is only used for initialization. - * We can unwrap the original procedure at this point - * so that this function is no longer called until the - * server resets and the function is wrapped again. - */ - InitialVector[2] = winProcEstablishConnectionOrig; - - /* - * Call original function and bail if it fails. - * NOTE: We must do this first, since we need XdmcpOpenDisplay - * to be called before we initialize our clipboard client. - */ - iReturn = (*winProcEstablishConnectionOrig) (client); - if (iReturn != 0) - { - ErrorF ("winProcEstablishConnection - ProcEstablishConnection " - "failed, bailing.\n"); - return iReturn; - } - - /* Clear original function pointer */ - winProcEstablishConnectionOrig = NULL; - - /* If the clipboard client has already been started, abort */ - if (g_fClipboardLaunched) - { - ErrorF ("winProcEstablishConnection - Clipboard client already " - "launched, returning.\n"); - return iReturn; - } - - /* Startup the clipboard client if clipboard mode is being used */ - if (g_fClipboard) - { - /* - * NOTE: The clipboard client is started here for a reason: - * 1) Assume you are using XDMCP (e.g. XWin -query %hostname%) - * 2) If the clipboard client attaches during X Server startup, - * then it becomes the "magic client" that causes the X Server - * to reset if it exits. - * 3) XDMCP calls KillAllClients when it starts up. - * 4) The clipboard client is a client, so it is killed. - * 5) The clipboard client is the "magic client", so the X Server - * resets itself. - * 6) This repeats ad infinitum. - * 7) We avoid this by waiting until at least one client (could - * be XDM, could be another client) connects, which makes it - * almost certain that the clipboard client will not connect - * until after XDM when using XDMCP. - * 8) Unfortunately, there is another problem. - * 9) XDM walks the list of windows with XQueryTree, - * killing any client it finds with a window. - * 10)Thus, when using XDMCP we wait until CLIP_NUM_CALLS - * to ProcEstablishCeonnection before we startup the clipboard - * client. This should prevent XDM from finding the clipboard - * client, since it has not yet created a window. - */ - - /* Create the clipboard client thread */ - if (!winInitClipboard ()) - { - ErrorF ("winProcEstablishConnection - winClipboardInit " - "failed.\n"); - return iReturn; - } - - ErrorF ("winProcEstablishConnection - winInitClipboard returned.\n"); - } - - /* Flag that clipboard client has been launched */ - g_fClipboardLaunched = TRUE; - - return iReturn; -} - - -/* - * Wrapper for internal SetSelectionOwner function. - * Grabs ownership of Windows clipboard when X11 clipboard owner changes. - */ - -int -winProcSetSelectionOwner (ClientPtr client) -{ - int i; - DrawablePtr pDrawable; - WindowPtr pWindow = None; - Bool fOwnedToNotOwned = FALSE; - static Window s_iOwners[CLIP_NUM_SELECTIONS] = {None}; - static unsigned long s_ulServerGeneration = 0; - REQUEST(xSetSelectionOwnerReq); - - REQUEST_SIZE_MATCH(xSetSelectionOwnerReq); - - winDebug("winProcSetSelectionOwner - Hello.\n"); - - /* Watch for server reset */ - if (s_ulServerGeneration != serverGeneration) - { - /* Save new generation number */ - s_ulServerGeneration = serverGeneration; - - /* Initialize static variables */ - for (i = 0; i < CLIP_NUM_SELECTIONS; ++i) - s_iOwners[i] = None; - } - - /* Abort if clipboard not completely initialized yet */ - if (!g_fClipboardStarted) - { - /* ErrorF ("winProcSetSelectionOwner - Clipboard not yet started, " - "aborting.\n"); */ - goto winProcSetSelectionOwner_Done; - } - - /* Grab window if we have one */ - if (None != stuff->window) - { - /* Grab the Window from the request */ - int rc = dixLookupWindow(&pWindow, stuff->window, client, DixReadAccess); - if (rc != Success) { - ErrorF ("winProcSetSelectionOwner - Found BadWindow, aborting.\n"); - goto winProcSetSelectionOwner_Done; - } - } - - /* Now we either have a valid window or None */ - - /* Save selection owners for monitored selections, ignore other selections */ - if (XA_PRIMARY == stuff->selection) - { - /* Look for owned -> not owned transition */ - if (None == stuff->window - && None != s_iOwners[CLIP_OWN_PRIMARY]) - { - fOwnedToNotOwned = TRUE; - - winDebug("winProcSetSelectionOwner - PRIMARY - Going from " - "owned to not owned.\n"); - - /* Adjust last owned selection */ - if (None != s_iOwners[CLIP_OWN_CLIPBOARD]) - g_atomLastOwnedSelection = MakeAtom ("CLIPBOARD", 9, TRUE); - else - g_atomLastOwnedSelection = None; - } - - /* Save new selection owner or None */ - s_iOwners[CLIP_OWN_PRIMARY] = stuff->window; - - winDebug("winProcSetSelectionOwner - PRIMARY - Now owned by: %d\n", - stuff->window); - } - else if (MakeAtom ("CLIPBOARD", 9, TRUE) == stuff->selection) - { - /* Look for owned -> not owned transition */ - if (None == stuff->window - && None != s_iOwners[CLIP_OWN_CLIPBOARD]) - { - fOwnedToNotOwned = TRUE; - - winDebug("winProcSetSelectionOwner - CLIPBOARD - Going from " - "owned to not owned.\n"); - - /* Adjust last owned selection */ - if (None != s_iOwners[CLIP_OWN_PRIMARY]) - g_atomLastOwnedSelection = XA_PRIMARY; - else - g_atomLastOwnedSelection = None; - } - - /* Save new selection owner or None */ - s_iOwners[CLIP_OWN_CLIPBOARD] = stuff->window; - - winDebug("winProcSetSelectionOwner - CLIPBOARD - Now owned by: %d\n", - stuff->window); - - } - else - goto winProcSetSelectionOwner_Done; - - /* - * At this point, if one of the selections is still owned by the - * clipboard manager then it should be marked as unowned since - * we will be taking ownership of the Win32 clipboard. - */ - if (g_iClipboardWindow == s_iOwners[CLIP_OWN_PRIMARY]) - s_iOwners[CLIP_OWN_PRIMARY] = None; - if (g_iClipboardWindow == s_iOwners[CLIP_OWN_CLIPBOARD]) - s_iOwners[CLIP_OWN_CLIPBOARD] = None; - - /* - * Handle case when selection is being disowned, - * WM_DRAWCLIPBOARD did not do the disowning, - * both monitored selections are no longer owned, - * an owned to not owned transition was detected, - * and we currently own the Win32 clipboard. - */ - if (stuff->window == None - && s_iOwners[CLIP_OWN_PRIMARY] == None - && s_iOwners[CLIP_OWN_CLIPBOARD] == None - && fOwnedToNotOwned - && g_hwndClipboard != NULL - && g_hwndClipboard == GetClipboardOwner ()) - { - winDebug("winProcSetSelectionOwner - We currently own the " - "clipboard and neither the PRIMARY nor the CLIPBOARD " - "selections are owned, releasing ownership of Win32 " - "clipboard.\n"); - - /* Release ownership of the Windows clipboard */ - OpenClipboard (NULL); - EmptyClipboard (); - CloseClipboard (); - - goto winProcSetSelectionOwner_Done; - } - - /* Abort if no window at this point */ - if (None == stuff->window) - { - winDebug("winProcSetSelectionOwner - No window, returning.\n"); - goto winProcSetSelectionOwner_Done; - } - - /* Abort if invalid selection */ - if (!ValidAtom (stuff->selection)) - { - ErrorF ("winProcSetSelectionOwner - Found BadAtom, aborting.\n"); - goto winProcSetSelectionOwner_Done; - } - - /* Cast Window to Drawable */ - pDrawable = (DrawablePtr) pWindow; - - /* Abort if clipboard manager is owning the selection */ - if (pDrawable->id == g_iClipboardWindow) - { - winDebug("winProcSetSelectionOwner - We changed ownership, " - "aborting.\n"); - goto winProcSetSelectionOwner_Done; - } - - /* Abort if root window is taking ownership */ - if (pDrawable->id == 0) - { - ErrorF ("winProcSetSelectionOwner - Root window taking ownership, " - "aborting\n"); - goto winProcSetSelectionOwner_Done; - } - - /* Close clipboard if we have it open already */ - if (GetOpenClipboardWindow () == g_hwndClipboard) - { - CloseClipboard (); - } - - /* Access the Windows clipboard */ - if (!OpenClipboard (g_hwndClipboard)) - { - ErrorF ("winProcSetSelectionOwner - OpenClipboard () failed: %08x\n", - (int) GetLastError ()); - goto winProcSetSelectionOwner_Done; - } - - /* Take ownership of the Windows clipboard */ - if (!EmptyClipboard ()) - { - ErrorF ("winProcSetSelectionOwner - EmptyClipboard () failed: %08x\n", - (int) GetLastError ()); - goto winProcSetSelectionOwner_Done; - } - - /* Advertise Unicode if we support it */ - if (g_fUnicodeSupport) - SetClipboardData (CF_UNICODETEXT, NULL); - - /* Always advertise regular text */ - SetClipboardData (CF_TEXT, NULL); - - /* Save handle to last owned selection */ - g_atomLastOwnedSelection = stuff->selection; - - /* Release the clipboard */ - if (!CloseClipboard ()) - { - ErrorF ("winProcSetSelectionOwner - CloseClipboard () failed: " - "%08x\n", - (int) GetLastError ()); - goto winProcSetSelectionOwner_Done; - } - - winProcSetSelectionOwner_Done: - return (*winProcSetSelectionOwnerOrig) (client); -} +/*
+ *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
+ *Copyright (C) Colin Harrison 2005-2008
+ *
+ *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 HAROLD L HUNT II 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 copyright holder(s)
+ *and author(s) 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 copyright holder(s) and author(s).
+ *
+ * Authors: Harold L Hunt II
+ * Colin Harrison
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include "dixstruct.h"
+#include <X11/Xatom.h>
+
+
+/*
+ * Constants
+ */
+
+#define CLIP_NUM_CALLS 4
+#define CLIP_NUM_SELECTIONS 2
+#define CLIP_OWN_PRIMARY 0
+#define CLIP_OWN_CLIPBOARD 1
+
+
+/*
+ * Local function prototypes
+ */
+
+DISPATCH_PROC(winProcEstablishConnection);
+DISPATCH_PROC(winProcQueryTree);
+DISPATCH_PROC(winProcSetSelectionOwner);
+
+
+/*
+ * References to external symbols
+ */
+
+extern Bool g_fUnicodeSupport;
+extern int g_iNumScreens;
+extern unsigned int g_uiAuthDataLen;
+extern char *g_pAuthData;
+extern Bool g_fXdmcpEnabled;
+extern Bool g_fClipboardLaunched;
+extern Bool g_fClipboardStarted;
+extern Bool g_fClipboard;
+extern Window g_iClipboardWindow;
+extern Atom g_atomLastOwnedSelection;
+extern HWND g_hwndClipboard;
+
+extern winDispatchProcPtr winProcEstablishConnectionOrig;
+extern winDispatchProcPtr winProcQueryTreeOrig;
+extern winDispatchProcPtr winProcSetSelectionOwnerOrig;
+
+
+/*
+ * Wrapper for internal QueryTree function.
+ * Hides the clipboard client when it is the only client remaining.
+ */
+
+int
+winProcQueryTree (ClientPtr client)
+{
+ int iReturn;
+
+ winDebug ("winProcQueryTree - Hello\n");
+
+ /*
+ * This procedure is only used for initialization.
+ * We can unwrap the original procedure at this point
+ * so that this function is no longer called until the
+ * server resets and the function is wrapped again.
+ */
+ ProcVector[X_QueryTree] = winProcQueryTreeOrig;
+
+ /*
+ * Call original function and bail if it fails.
+ * NOTE: We must do this first, since we need XdmcpOpenDisplay
+ * to be called before we initialize our clipboard client.
+ */
+ iReturn = (*winProcQueryTreeOrig) (client);
+ if (iReturn != 0)
+ {
+ ErrorF ("winProcQueryTree - ProcQueryTree failed, bailing.\n");
+ return iReturn;
+ }
+
+ /* Make errors more obvious */
+ winProcQueryTreeOrig = NULL;
+
+ /* Do nothing if clipboard is not enabled */
+ if (!g_fClipboard)
+ {
+ winDebug ("winProcQueryTree - Clipboard is not enabled, "
+ "returning.\n");
+ return iReturn;
+ }
+
+ /* If the clipboard client has already been started, abort */
+ if (g_fClipboardLaunched)
+ {
+ winDebug ("winProcQueryTree - Clipboard client already "
+ "launched, returning.\n");
+ return iReturn;
+ }
+
+ /* Startup the clipboard client if clipboard mode is being used */
+ if (g_fXdmcpEnabled && g_fClipboard)
+ {
+ /*
+ * NOTE: The clipboard client is started here for a reason:
+ * 1) Assume you are using XDMCP (e.g. XWin -query %hostname%)
+ * 2) If the clipboard client attaches during X Server startup,
+ * then it becomes the "magic client" that causes the X Server
+ * to reset if it exits.
+ * 3) XDMCP calls KillAllClients when it starts up.
+ * 4) The clipboard client is a client, so it is killed.
+ * 5) The clipboard client is the "magic client", so the X Server
+ * resets itself.
+ * 6) This repeats ad infinitum.
+ * 7) We avoid this by waiting until at least one client (could
+ * be XDM, could be another client) connects, which makes it
+ * almost certain that the clipboard client will not connect
+ * until after XDM when using XDMCP.
+ * 8) Unfortunately, there is another problem.
+ * 9) XDM walks the list of windows with XQueryTree,
+ * killing any client it finds with a window.
+ * 10)Thus, when using XDMCP we wait until the first call
+ * to ProcQueryTree before we startup the clipboard client.
+ * This should prevent XDM from finding the clipboard client,
+ * since it has not yet created a window.
+ * 11)Startup when not using XDMCP is handled in
+ * winProcEstablishConnection.
+ */
+
+ /* Create the clipboard client thread */
+ if (!winInitClipboard ())
+ {
+ ErrorF ("winProcQueryTree - winClipboardInit "
+ "failed.\n");
+ return iReturn;
+ }
+
+ winDebug ("winProcQueryTree - winInitClipboard returned.\n");
+ }
+
+ /* Flag that clipboard client has been launched */
+ g_fClipboardLaunched = TRUE;
+
+ return iReturn;
+}
+
+
+/*
+ * Wrapper for internal EstablishConnection function.
+ * Initializes internal clients that must not be started until
+ * an external client has connected.
+ */
+
+int
+winProcEstablishConnection (ClientPtr client)
+{
+ int iReturn;
+ static int s_iCallCount = 0;
+ static unsigned long s_ulServerGeneration = 0;
+
+ #ifdef WINDBG
+ if (s_iCallCount == 0 || s_iCallCount == CLIP_NUM_CALLS) winDebug ("winProcEstablishConnection - Hello\n");
+ #endif
+
+ /* Do nothing if clipboard is not enabled */
+ if (!g_fClipboard)
+ {
+ winDebug ("winProcEstablishConnection - Clipboard is not enabled, "
+ "returning.\n");
+
+ /* Unwrap the original function, call it, and return */
+ InitialVector[2] = winProcEstablishConnectionOrig;
+ iReturn = (*winProcEstablishConnectionOrig) (client);
+ winProcEstablishConnectionOrig = NULL;
+ return iReturn;
+ }
+
+ /* Watch for server reset */
+ if (s_ulServerGeneration != serverGeneration)
+ {
+ /* Save new generation number */
+ s_ulServerGeneration = serverGeneration;
+
+ /* Reset call count */
+ s_iCallCount = 0;
+ }
+
+ /* Increment call count */
+ ++s_iCallCount;
+
+ /* Wait for CLIP_NUM_CALLS when Xdmcp is enabled */
+ if (g_fXdmcpEnabled
+ && !g_fClipboardLaunched
+ && s_iCallCount < CLIP_NUM_CALLS)
+ {
+ #ifdef WINDBG
+ if (s_iCallCount == 1) winDebug ("winProcEstablishConnection - Xdmcp, waiting to "
+ "start clipboard client until %dth call", CLIP_NUM_CALLS);
+ if (s_iCallCount == CLIP_NUM_CALLS - 1) winDebug (".\n");
+ else winDebug (".");
+ #endif
+ return (*winProcEstablishConnectionOrig) (client);
+ }
+
+ /*
+ * This procedure is only used for initialization.
+ * We can unwrap the original procedure at this point
+ * so that this function is no longer called until the
+ * server resets and the function is wrapped again.
+ */
+ InitialVector[2] = winProcEstablishConnectionOrig;
+
+ /*
+ * Call original function and bail if it fails.
+ * NOTE: We must do this first, since we need XdmcpOpenDisplay
+ * to be called before we initialize our clipboard client.
+ */
+ iReturn = (*winProcEstablishConnectionOrig) (client);
+ if (iReturn != 0)
+ {
+ ErrorF ("winProcEstablishConnection - ProcEstablishConnection "
+ "failed, bailing.\n");
+ return iReturn;
+ }
+
+ /* Clear original function pointer */
+ winProcEstablishConnectionOrig = NULL;
+
+ /* If the clipboard client has already been started, abort */
+ if (g_fClipboardLaunched)
+ {
+ winDebug ("winProcEstablishConnection - Clipboard client already "
+ "launched, returning.\n");
+ return iReturn;
+ }
+
+ /* Startup the clipboard client if clipboard mode is being used */
+ if (g_fClipboard)
+ {
+ /*
+ * NOTE: The clipboard client is started here for a reason:
+ * 1) Assume you are using XDMCP (e.g. XWin -query %hostname%)
+ * 2) If the clipboard client attaches during X Server startup,
+ * then it becomes the "magic client" that causes the X Server
+ * to reset if it exits.
+ * 3) XDMCP calls KillAllClients when it starts up.
+ * 4) The clipboard client is a client, so it is killed.
+ * 5) The clipboard client is the "magic client", so the X Server
+ * resets itself.
+ * 6) This repeats ad infinitum.
+ * 7) We avoid this by waiting until at least one client (could
+ * be XDM, could be another client) connects, which makes it
+ * almost certain that the clipboard client will not connect
+ * until after XDM when using XDMCP.
+ * 8) Unfortunately, there is another problem.
+ * 9) XDM walks the list of windows with XQueryTree,
+ * killing any client it finds with a window.
+ * 10)Thus, when using XDMCP we wait until CLIP_NUM_CALLS
+ * to ProcEstablishCeonnection before we startup the clipboard
+ * client. This should prevent XDM from finding the clipboard
+ * client, since it has not yet created a window.
+ */
+
+ /* Create the clipboard client thread */
+ if (!winInitClipboard ())
+ {
+ ErrorF ("winProcEstablishConnection - winClipboardInit "
+ "failed.\n");
+ return iReturn;
+ }
+
+ winDebug ("winProcEstablishConnection - winInitClipboard returned.\n");
+ }
+
+ /* Flag that clipboard client has been launched */
+ g_fClipboardLaunched = TRUE;
+
+ return iReturn;
+}
+
+
+/*
+ * Wrapper for internal SetSelectionOwner function.
+ * Grabs ownership of Windows clipboard when X11 clipboard owner changes.
+ */
+int
+winProcSetSelectionOwner (ClientPtr client)
+{
+ int i;
+ DrawablePtr pDrawable;
+ WindowPtr pWindow = None;
+ static Window s_iOwners[CLIP_NUM_SELECTIONS] = {None};
+ static unsigned long s_ulServerGeneration = 0;
+ REQUEST(xSetSelectionOwnerReq);
+
+ REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);
+
+ winDebug ("winProcSetSelectionOwner - Hello.\n");
+
+ /* Watch for server reset */
+ if (s_ulServerGeneration != serverGeneration)
+ {
+ /* Save new generation number */
+ s_ulServerGeneration = serverGeneration;
+
+ /* Initialize static variables */
+ for (i = 0; i < CLIP_NUM_SELECTIONS; ++i)
+ s_iOwners[i] = None;
+ }
+
+ /* Abort if clipboard not completely initialized yet */
+ if (!g_fClipboardStarted)
+ {
+ winDebug ("winProcSetSelectionOwner - Clipboard not yet started, "
+ "aborting.\n");
+ goto winProcSetSelectionOwner_Done;
+ }
+
+ /* Grab window if we have one */
+ if (None != stuff->window)
+ {
+ /* Grab the Window from the request */
+ int rc = dixLookupWindow(&pWindow, stuff->window, client, DixReadAccess);
+ if (rc != Success) {
+ ErrorF ("winProcSetSelectionOwner - Found BadWindow, aborting.\n");
+ goto winProcSetSelectionOwner_Done;
+ }
+ }
+
+ /* Now we either have a valid window or None */
+
+ /* Save selection owners for monitored selections, ignore other selections */
+ if (XA_PRIMARY == stuff->selection)
+ {
+ /* Look for owned -> not owned transition */
+ if (None == stuff->window
+ && None != s_iOwners[CLIP_OWN_PRIMARY])
+ {
+ winDebug ("winProcSetSelectionOwner - PRIMARY - Going from "
+ "owned to not owned.\n");
+
+ /* Adjust last owned selection */
+ if (None != s_iOwners[CLIP_OWN_CLIPBOARD])
+ g_atomLastOwnedSelection = MakeAtom ("CLIPBOARD", 9, TRUE);
+ else
+ g_atomLastOwnedSelection = None;
+ }
+
+ /* Save new selection owner or None */
+ s_iOwners[CLIP_OWN_PRIMARY] = stuff->window;
+
+ winDebug ("winProcSetSelectionOwner - PRIMARY - Now owned by: 0x%x (clipboard is 0x%x)\n",
+ stuff->window,g_iClipboardWindow);
+ }
+ else if (MakeAtom ("CLIPBOARD", 9, TRUE) == stuff->selection)
+ {
+ /* Look for owned -> not owned transition */
+ if (None == stuff->window
+ && None != s_iOwners[CLIP_OWN_CLIPBOARD])
+ {
+ winDebug ("winProcSetSelectionOwner - CLIPBOARD - Going from "
+ "owned to not owned.\n");
+
+ /* Adjust last owned selection */
+ if (None != s_iOwners[CLIP_OWN_PRIMARY])
+ g_atomLastOwnedSelection = XA_PRIMARY;
+ else
+ g_atomLastOwnedSelection = None;
+ }
+
+ /* Save new selection owner or None */
+ s_iOwners[CLIP_OWN_CLIPBOARD] = stuff->window;
+
+ winDebug ("winProcSetSelectionOwner - CLIPBOARD - Now owned by: 0x%x, clipboard is 0x%x\n",
+ stuff->window,g_iClipboardWindow);
+ }
+ else
+ goto winProcSetSelectionOwner_Done;
+
+ /*
+ * At this point, if one of the selections is still owned by the
+ * clipboard manager then it should be marked as unowned since
+ * we will be taking ownership of the Win32 clipboard.
+ */
+ if (g_iClipboardWindow == s_iOwners[CLIP_OWN_PRIMARY])
+ s_iOwners[CLIP_OWN_PRIMARY] = None;
+ if (g_iClipboardWindow == s_iOwners[CLIP_OWN_CLIPBOARD])
+ s_iOwners[CLIP_OWN_CLIPBOARD] = None;
+
+ /* Abort if no window at this point */
+ if (None == stuff->window)
+ {
+ winDebug ("winProcSetSelectionOwner - No window, returning.\n");
+ goto winProcSetSelectionOwner_Done;
+ }
+
+ /* Abort if invalid selection */
+ if (!ValidAtom (stuff->selection))
+ {
+ winDebug ("winProcSetSelectionOwner - Found BadAtom, aborting.\n");
+ goto winProcSetSelectionOwner_Done;
+ }
+
+ /* Cast Window to Drawable */
+ pDrawable = (DrawablePtr) pWindow;
+
+ /* Abort if clipboard manager is owning the selection */
+ if (pDrawable->id == g_iClipboardWindow)
+ {
+ winDebug ("winProcSetSelectionOwner - We changed ownership, "
+ "aborting.\n");
+ goto winProcSetSelectionOwner_Done;
+ }
+
+ /* Abort if root window is taking ownership */
+ if (pDrawable->id == 0)
+ {
+ winDebug ("winProcSetSelectionOwner - Root window taking ownership, "
+ "aborting\n");
+ goto winProcSetSelectionOwner_Done;
+ }
+
+ /* Access the Windows clipboard */
+ if (!OpenClipboard (g_hwndClipboard))
+ {
+ ErrorF ("winProcSetSelectionOwner - OpenClipboard () failed: %08x, hwnd: %08x\n",
+ (int) GetLastError (),g_hwndClipboard);
+ goto winProcSetSelectionOwner_Done;
+ }
+
+ /* Take ownership of the Windows clipboard */
+ if (!EmptyClipboard ())
+ {
+ ErrorF ("winProcSetSelectionOwner - EmptyClipboard () failed: %08x\n",
+ (int) GetLastError ());
+ CloseClipboard ();
+ goto winProcSetSelectionOwner_Done;
+ }
+
+ winDebug("winProcSetSelectionOwner - SetClipboardData NULL\n");
+
+ /* Advertise Unicode if we support it */
+ if (g_fUnicodeSupport)
+ SetClipboardData (CF_UNICODETEXT, NULL);
+
+ /* Always advertise regular text */
+ SetClipboardData (CF_TEXT, NULL);
+
+ /* Save handle to last owned selection */
+ g_atomLastOwnedSelection = stuff->selection;
+
+ /* Release the clipboard */
+ if (!CloseClipboard ())
+ {
+ ErrorF ("winProcSetSelectionOwner - CloseClipboard () failed: "
+ "%08x\n",
+ (int) GetLastError ());
+ goto winProcSetSelectionOwner_Done;
+ }
+
+winProcSetSelectionOwner_Done:
+ return (*winProcSetSelectionOwnerOrig) (client);
+}
diff --git a/xorg-server/hw/xwin/winclipboardxevents.c b/xorg-server/hw/xwin/winclipboardxevents.c index ae8262ebf..d7fa8ffd7 100644 --- a/xorg-server/hw/xwin/winclipboardxevents.c +++ b/xorg-server/hw/xwin/winclipboardxevents.c @@ -1,802 +1,842 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. - *Copyright (C) Colin Harrison 2005-2008 - * - *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 HAROLD L HUNT II 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 copyright holder(s) - *and author(s) 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 copyright holder(s) and author(s). - * - * Authors: Harold L Hunt II - * Colin Harrison - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "winclipboard.h" -#include "misc.h" - - -/* - * References to external symbols - */ - -extern Bool g_fUnicodeSupport; - - -/* - * Process any pending X events - */ - -int -winClipboardFlushXEvents (HWND hwnd, - int iWindow, - Display *pDisplay, - Bool fUseUnicode) -{ - static Atom atomLocalProperty; - static Atom atomCompoundText; - static Atom atomUTF8String; - static Atom atomTargets; - static int generation; - - if (generation != serverGeneration) - { - generation = serverGeneration; - atomLocalProperty = XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False); - atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False); - atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False); - atomTargets = XInternAtom (pDisplay, "TARGETS", False); - } - - /* Process all pending events */ - while (XPending (pDisplay)) - { - XTextProperty xtpText = {0}; - XEvent event; - XSelectionEvent eventSelection; - unsigned long ulReturnBytesLeft; - unsigned char *pszReturnData = NULL; - char *pszGlobalData = NULL; - int iReturn; - HGLOBAL hGlobal = NULL; - XICCEncodingStyle xiccesStyle; - int iConvertDataLen = 0; - char *pszConvertData = NULL; - char *pszTextList[2] = {NULL}; - int iCount; - char **ppszTextList = NULL; - wchar_t *pwszUnicodeStr = NULL; - int iUnicodeLen = 0; - int iReturnDataLen = 0; - int i; - Bool fAbort = FALSE; - Bool fCloseClipboard = FALSE; - Bool fSetClipboardData = TRUE; - - /* Get the next event - will not block because one is ready */ - XNextEvent (pDisplay, &event); - - /* Branch on the event type */ - switch (event.type) - { - /* - * SelectionRequest - */ - - case SelectionRequest: - { - char *pszAtomName = NULL; - winDebug("SelectionRequest - target %d\n", - event.xselectionrequest.target); - - pszAtomName = XGetAtomName (pDisplay, - event.xselectionrequest.target); - winDebug("SelectionRequest - Target atom name %s\n", pszAtomName); - XFree (pszAtomName); - pszAtomName = NULL; - } - - /* Abort if invalid target type */ - if (event.xselectionrequest.target != XA_STRING - && event.xselectionrequest.target != atomUTF8String - && event.xselectionrequest.target != atomCompoundText - && event.xselectionrequest.target != atomTargets) - { - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - /* Handle targets type of request */ - if (event.xselectionrequest.target == atomTargets) - { - Atom atomTargetArr[] = {atomTargets, - atomCompoundText, - atomUTF8String, - XA_STRING}; - - /* Try to change the property */ - iReturn = XChangeProperty (pDisplay, - event.xselectionrequest.requestor, - event.xselectionrequest.property, - XA_ATOM, - 32, - PropModeReplace, - (unsigned char *) atomTargetArr, - (sizeof (atomTargetArr) - / sizeof (atomTargetArr[0]))); - if (iReturn == BadAlloc - || iReturn == BadAtom - || iReturn == BadMatch - || iReturn == BadValue - || iReturn == BadWindow) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "XChangeProperty failed: %d\n", - iReturn); - } - - /* Setup selection notify xevent */ - eventSelection.type = SelectionNotify; - eventSelection.send_event = True; - eventSelection.display = pDisplay; - eventSelection.requestor = event.xselectionrequest.requestor; - eventSelection.selection = event.xselectionrequest.selection; - eventSelection.target = event.xselectionrequest.target; - eventSelection.property = event.xselectionrequest.property; - eventSelection.time = event.xselectionrequest.time; - - /* - * Notify the requesting window that - * the operation has completed - */ - iReturn = XSendEvent (pDisplay, - eventSelection.requestor, - False, - 0L, - (XEvent *) &eventSelection); - if (iReturn == BadValue || iReturn == BadWindow) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "XSendEvent () failed\n"); - } - break; - } - - /* Check that clipboard format is available */ - if (fUseUnicode - && !IsClipboardFormatAvailable (CF_UNICODETEXT)) - { - static int count; /* Hack to stop acroread spamming the log */ - static HWND lasthwnd; /* I've not seen any other client get here repeatedly? */ - if (hwnd != lasthwnd) count = 0; - count++; - if (count < 6) ErrorF ("winClipboardFlushXEvents - CF_UNICODETEXT is not " - "available from Win32 clipboard. Aborting %d.\n", count); - lasthwnd = hwnd; - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - else if (!fUseUnicode - && !IsClipboardFormatAvailable (CF_TEXT)) - { - ErrorF ("winClipboardFlushXEvents - CF_TEXT is not " - "available from Win32 clipboard. Aborting.\n"); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - /* Close clipboard if we have it open already */ - if (GetOpenClipboardWindow () == hwnd) - { - CloseClipboard (); - } - - /* Access the clipboard */ - if (!OpenClipboard (hwnd)) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "OpenClipboard () failed: %08x\n", - GetLastError ()); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - /* Indicate that clipboard was opened */ - fCloseClipboard = TRUE; - - /* Setup the string style */ - if (event.xselectionrequest.target == XA_STRING) - xiccesStyle = XStringStyle; -#ifdef X_HAVE_UTF8_STRING - else if (event.xselectionrequest.target == atomUTF8String) - xiccesStyle = XUTF8StringStyle; -#endif - else if (event.xselectionrequest.target == atomCompoundText) - xiccesStyle = XCompoundTextStyle; - else - xiccesStyle = XStringStyle; - - /* - * FIXME: Can't pass CF_UNICODETEXT on Windows 95/98/Me - */ - - /* Get a pointer to the clipboard text, in desired format */ - if (fUseUnicode) - { - /* Retrieve clipboard data */ - hGlobal = GetClipboardData (CF_UNICODETEXT); - } - else - { - /* Retrieve clipboard data */ - hGlobal = GetClipboardData (CF_TEXT); - } - if (!hGlobal) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "GetClipboardData () failed: %08x\n", - GetLastError ()); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - pszGlobalData = (char *) GlobalLock (hGlobal); - - /* Convert the Unicode string to UTF8 (MBCS) */ - if (fUseUnicode) - { - iConvertDataLen = WideCharToMultiByte (CP_UTF8, - 0, - (LPCWSTR)pszGlobalData, - -1, - NULL, - 0, - NULL, - NULL); - /* NOTE: iConvertDataLen includes space for null terminator */ - pszConvertData = (char *) malloc (iConvertDataLen); - WideCharToMultiByte (CP_UTF8, - 0, - (LPCWSTR)pszGlobalData, - -1, - pszConvertData, - iConvertDataLen, - NULL, - NULL); - } - else - { - pszConvertData = strdup (pszGlobalData); - iConvertDataLen = strlen (pszConvertData) + 1; - } - - /* Convert DOS string to UNIX string */ - winClipboardDOStoUNIX (pszConvertData, strlen (pszConvertData)); - - /* Setup our text list */ - pszTextList[0] = pszConvertData; - pszTextList[1] = NULL; - - /* Initialize the text property */ - xtpText.value = NULL; - xtpText.nitems = 0; - - /* Create the text property from the text list */ - if (fUseUnicode) - { -#ifdef X_HAVE_UTF8_STRING - iReturn = Xutf8TextListToTextProperty (pDisplay, - pszTextList, - 1, - xiccesStyle, - &xtpText); -#endif - } - else - { - iReturn = XmbTextListToTextProperty (pDisplay, - pszTextList, - 1, - xiccesStyle, - &xtpText); - } - if (iReturn == XNoMemory || iReturn == XLocaleNotSupported) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "X*TextListToTextProperty failed: %d\n", - iReturn); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - /* Free the converted string */ - free (pszConvertData); - pszConvertData = NULL; - - /* Copy the clipboard text to the requesting window */ - iReturn = XChangeProperty (pDisplay, - event.xselectionrequest.requestor, - event.xselectionrequest.property, - event.xselectionrequest.target, - 8, - PropModeReplace, - xtpText.value, - xtpText.nitems); - if (iReturn == BadAlloc || iReturn == BadAtom - || iReturn == BadMatch || iReturn == BadValue - || iReturn == BadWindow) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "XChangeProperty failed: %d\n", - iReturn); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - /* Release the clipboard data */ - GlobalUnlock (hGlobal); - pszGlobalData = NULL; - fCloseClipboard = FALSE; - CloseClipboard (); - - /* Clean up */ - XFree (xtpText.value); - xtpText.value = NULL; - xtpText.nitems = 0; - - /* Setup selection notify event */ - eventSelection.type = SelectionNotify; - eventSelection.send_event = True; - eventSelection.display = pDisplay; - eventSelection.requestor = event.xselectionrequest.requestor; - eventSelection.selection = event.xselectionrequest.selection; - eventSelection.target = event.xselectionrequest.target; - eventSelection.property = event.xselectionrequest.property; - eventSelection.time = event.xselectionrequest.time; - - /* Notify the requesting window that the operation has completed */ - iReturn = XSendEvent (pDisplay, - eventSelection.requestor, - False, - 0L, - (XEvent *) &eventSelection); - if (iReturn == BadValue || iReturn == BadWindow) - { - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "XSendEvent () failed\n"); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionRequest_Done; - } - - winClipboardFlushXEvents_SelectionRequest_Done: - /* Free allocated resources */ - if (xtpText.value) - { - XFree (xtpText.value); - xtpText.value = NULL; - xtpText.nitems = 0; - } - if (pszConvertData) - free (pszConvertData); - if (hGlobal && pszGlobalData) - GlobalUnlock (hGlobal); - - /* - * Send a SelectionNotify event to the requesting - * client when we abort. - */ - if (fAbort) - { - /* Setup selection notify event */ - eventSelection.type = SelectionNotify; - eventSelection.send_event = True; - eventSelection.display = pDisplay; - eventSelection.requestor = event.xselectionrequest.requestor; - eventSelection.selection = event.xselectionrequest.selection; - eventSelection.target = event.xselectionrequest.target; - eventSelection.property = None; - eventSelection.time = event.xselectionrequest.time; - - /* Notify the requesting window that the operation is complete */ - iReturn = XSendEvent (pDisplay, - eventSelection.requestor, - False, - 0L, - (XEvent *) &eventSelection); - if (iReturn == BadValue || iReturn == BadWindow) - { - /* - * Should not be a problem if XSendEvent fails because - * the client may simply have exited. - */ - ErrorF ("winClipboardFlushXEvents - SelectionRequest - " - "XSendEvent () failed for abort event.\n"); - } - } - - /* Close clipboard if it was opened */ - if (fCloseClipboard) - { - fCloseClipboard = FALSE; - CloseClipboard (); - } - break; - - - /* - * SelectionNotify - */ - - case SelectionNotify: - - winDebug ("winClipboardFlushXEvents - SelectionNotify\n"); - { - char *pszAtomName; - pszAtomName = XGetAtomName (pDisplay, - event.xselection.selection); - - winDebug("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n", - pszAtomName); - XFree (pszAtomName); - } - - /* - * Request conversion of UTF8 and CompoundText targets. - */ - if (event.xselection.property == None) - { - if (event.xselection.target == XA_STRING) - { - winDebug ("winClipboardFlushXEvents - SelectionNotify - " - "XA_STRING\n"); - - return WIN_XEVENTS_CONVERT; - } - else if (event.xselection.target == atomUTF8String) - { - winDebug("winClipboardFlushXEvents - SelectionNotify - " - "Requesting conversion of UTF8 target.\n"); - - XConvertSelection (pDisplay, - event.xselection.selection, - XA_STRING, - atomLocalProperty, - iWindow, - CurrentTime); - - /* Process the ConvertSelection event */ - XFlush (pDisplay); - return WIN_XEVENTS_CONVERT; - } -#ifdef X_HAVE_UTF8_STRING - else if (event.xselection.target == atomCompoundText) - { - winDebug("winClipboardFlushXEvents - SelectionNotify - " - "Requesting conversion of CompoundText target.\n"); - - XConvertSelection (pDisplay, - event.xselection.selection, - atomUTF8String, - atomLocalProperty, - iWindow, - CurrentTime); - - /* Process the ConvertSelection event */ - XFlush (pDisplay); - return WIN_XEVENTS_CONVERT; - } -#endif - else - { - ErrorF ("winClipboardFlushXEvents - SelectionNotify - " - "Unknown format. Cannot request conversion, " - "aborting.\n"); - break; - } - } - - /* Retrieve the size of the stored data */ - iReturn = XGetWindowProperty (pDisplay, - iWindow, - atomLocalProperty, - 0, - 0, /* Don't get data, just size */ - False, - AnyPropertyType, - &xtpText.encoding, - &xtpText.format, - &xtpText.nitems, - &ulReturnBytesLeft, - &xtpText.value); - if (iReturn != Success) - { - ErrorF ("winClipboardFlushXEvents - SelectionNotify - " - "XGetWindowProperty () failed, aborting: %d\n", - iReturn); - break; - } - - winDebug("SelectionNotify - returned data %d left %d\n", - xtpText.nitems, ulReturnBytesLeft); - - /* Request the selection data */ - iReturn = XGetWindowProperty (pDisplay, - iWindow, - atomLocalProperty, - 0, - ulReturnBytesLeft, - False, - AnyPropertyType, - &xtpText.encoding, - &xtpText.format, - &xtpText.nitems, - &ulReturnBytesLeft, - &xtpText.value); - if (iReturn != Success) - { - ErrorF ("winClipboardFlushXEvents - SelectionNotify - " - "XGetWindowProperty () failed, aborting: %d\n", - iReturn); - break; - } - - { - char *pszAtomName = NULL; - - winDebug("SelectionNotify - returned data %d left %d\n", - xtpText.nitems, ulReturnBytesLeft); - pszAtomName = XGetAtomName(pDisplay, xtpText.encoding); - winDebug("Notify atom name %s\n", pszAtomName); - XFree (pszAtomName); - pszAtomName = NULL; - } - - if (fUseUnicode) - { -#ifdef X_HAVE_UTF8_STRING - /* Convert the text property to a text list */ - iReturn = Xutf8TextPropertyToTextList (pDisplay, - &xtpText, - &ppszTextList, - &iCount); -#endif - } - else - { - iReturn = XmbTextPropertyToTextList (pDisplay, - &xtpText, - &ppszTextList, - &iCount); - } - if (iReturn == Success || iReturn > 0) - { - /* Conversion succeeded or some unconvertible characters */ - if (ppszTextList != NULL) - { - iReturnDataLen = 0; - for (i = 0; i < iCount; i++) - { - iReturnDataLen += strlen(ppszTextList[i]); - } - pszReturnData = malloc (iReturnDataLen + 1); - pszReturnData[0] = '\0'; - for (i = 0; i < iCount; i++) - { - strcat (pszReturnData, ppszTextList[i]); - } - } - else - { - ErrorF ("winClipboardFlushXEvents - SelectionNotify - " - "X*TextPropertyToTextList list_return is NULL.\n"); - pszReturnData = malloc (1); - pszReturnData[0] = '\0'; - } - } - else - { - ErrorF ("winClipboardFlushXEvents - SelectionNotify - " - "X*TextPropertyToTextList returned: "); - switch (iReturn) - { - case XNoMemory: - ErrorF ("XNoMemory\n"); - break; - case XConverterNotFound: - ErrorF ("XConverterNotFound\n"); - break; - default: - ErrorF ("%d", iReturn); - break; - } - pszReturnData = malloc (1); - pszReturnData[0] = '\0'; - } - - /* Free the data returned from XGetWindowProperty */ - if (ppszTextList) - XFreeStringList (ppszTextList); - ppszTextList = NULL; - XFree (xtpText.value); - xtpText.value = NULL; - xtpText.nitems = 0; - - /* Convert the X clipboard string to DOS format */ - winClipboardUNIXtoDOS (&pszReturnData, strlen (pszReturnData)); - - if (fUseUnicode) - { - /* Find out how much space needed to convert MBCS to Unicode */ - iUnicodeLen = MultiByteToWideChar (CP_UTF8, - 0, - pszReturnData, - -1, - NULL, - 0); - - /* Allocate memory for the Unicode string */ - pwszUnicodeStr - = (wchar_t*) malloc (sizeof (wchar_t) * (iUnicodeLen + 1)); - if (!pwszUnicodeStr) - { - ErrorF ("winClipboardFlushXEvents - SelectionNotify " - "malloc failed for pwszUnicodeStr, aborting.\n"); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionNotify_Done; - } - - /* Do the actual conversion */ - MultiByteToWideChar (CP_UTF8, - 0, - pszReturnData, - -1, - pwszUnicodeStr, - iUnicodeLen); - - /* Allocate global memory for the X clipboard data */ - hGlobal = GlobalAlloc (GMEM_MOVEABLE, - sizeof (wchar_t) * (iUnicodeLen + 1)); - } - else - { - pszConvertData = strdup (pszReturnData); - iConvertDataLen = strlen (pszConvertData) + 1; - - /* Allocate global memory for the X clipboard data */ - hGlobal = GlobalAlloc (GMEM_MOVEABLE, iConvertDataLen); - } - - free (pszReturnData); - - /* Check that global memory was allocated */ - if (!hGlobal) - { - ErrorF ("winClipboardFlushXEvents - SelectionNotify " - "GlobalAlloc failed, aborting: %ld\n", - GetLastError ()); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionNotify_Done; - } - - /* Obtain a pointer to the global memory */ - pszGlobalData = GlobalLock (hGlobal); - if (pszGlobalData == NULL) - { - ErrorF ("winClipboardFlushXEvents - Could not lock global " - "memory for clipboard transfer\n"); - - /* Abort */ - fAbort = TRUE; - goto winClipboardFlushXEvents_SelectionNotify_Done; - } - - /* Copy the returned string into the global memory */ - if (fUseUnicode) - { - memcpy (pszGlobalData, - pwszUnicodeStr, - sizeof (wchar_t) * (iUnicodeLen + 1)); - free (pwszUnicodeStr); - pwszUnicodeStr = NULL; - } - else - { - strcpy (pszGlobalData, pszConvertData); - free (pszConvertData); - pszConvertData = NULL; - } - - /* Release the pointer to the global memory */ - GlobalUnlock (hGlobal); - pszGlobalData = NULL; - - /* Push the selection data to the Windows clipboard */ - if (fUseUnicode) - SetClipboardData (CF_UNICODETEXT, hGlobal); - else - SetClipboardData (CF_TEXT, hGlobal); - - /* Flag that SetClipboardData has been called */ - fSetClipboardData = FALSE; - - /* - * NOTE: Do not try to free pszGlobalData, it is owned by - * Windows after the call to SetClipboardData (). - */ - - winClipboardFlushXEvents_SelectionNotify_Done: - /* Free allocated resources */ - if (ppszTextList) - XFreeStringList (ppszTextList); - if (xtpText.value) - { - XFree (xtpText.value); - xtpText.value = NULL; - xtpText.nitems = 0; - } - if (pszConvertData) - free (pszConvertData); - if (pwszUnicodeStr) - free (pwszUnicodeStr); - if (hGlobal && pszGlobalData) - GlobalUnlock (hGlobal); - if (fSetClipboardData && g_fUnicodeSupport) - SetClipboardData (CF_UNICODETEXT, NULL); - if (fSetClipboardData) - SetClipboardData (CF_TEXT, NULL); - return WIN_XEVENTS_NOTIFY; - - case SelectionClear: - winDebug("SelectionClear - doing nothing\n"); - break; - - case PropertyNotify: - break; - - default: - ErrorF ("winClipboardFlushXEvents - unexpected event type %d\n", event.type); - break; - } - } - - return WIN_XEVENTS_SUCCESS; -} +/*
+ *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
+ *Copyright (C) Colin Harrison 2005-2008
+ *
+ *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 HAROLD L HUNT II 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 copyright holder(s)
+ *and author(s) 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 copyright holder(s) and author(s).
+ *
+ * Authors: Harold L Hunt II
+ * Colin Harrison
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "winclipboard.h"
+#include "misc.h"
+#include "winmsg.h"
+#include <unistd.h>
+
+/*
+ * References to external symbols
+ */
+
+extern Bool g_fUnicodeSupport;
+
+
+/*
+ * Process any pending X events
+ */
+
+int
+winClipboardFlushXEvents (HWND hwnd,
+ int iWindow,
+ Display *pDisplay,
+ Bool fUseUnicode,
+ Bool ClipboardOpened)
+{
+ static Atom atomLocalProperty;
+ static Atom atomCompoundText;
+ static Atom atomUTF8String;
+ static Atom atomTargets;
+ static int generation;
+
+ if (generation != serverGeneration)
+ {
+ generation = serverGeneration;
+ atomLocalProperty = XInternAtom (pDisplay, WIN_LOCAL_PROPERTY, False);
+ atomUTF8String = XInternAtom (pDisplay, "UTF8_STRING", False);
+ atomCompoundText = XInternAtom (pDisplay, "COMPOUND_TEXT", False);
+ atomTargets = XInternAtom (pDisplay, "TARGETS", False);
+ }
+
+ /* Process all pending events */
+ while (XPending (pDisplay))
+ {
+ XTextProperty xtpText = {0};
+ XEvent event;
+ XSelectionEvent eventSelection;
+ unsigned long ulReturnBytesLeft;
+ unsigned char *pszReturnData = NULL;
+ char *pszGlobalData = NULL;
+ int iReturn;
+ HGLOBAL hGlobal = NULL;
+ XICCEncodingStyle xiccesStyle;
+ int iConvertDataLen = 0;
+ char *pszConvertData = NULL;
+ char *pszTextList[2] = {NULL};
+ int iCount;
+ char **ppszTextList = NULL;
+ wchar_t *pwszUnicodeStr = NULL;
+ int iUnicodeLen = 0;
+ int iReturnDataLen = 0;
+ int i;
+ Bool fAbort = FALSE;
+ Bool fCloseClipboard = FALSE;
+ Bool fSetClipboardData = TRUE;
+
+ /* Get the next event - will not block because one is ready */
+ XNextEvent (pDisplay, &event);
+
+ winDebug ("Received event type %d\n",event.type);
+
+ /* Branch on the event type */
+ switch (event.type)
+ {
+ /*
+ * SelectionRequest
+ */
+
+ case SelectionRequest:
+#ifdef _DEBUG
+ {
+ char *pszAtomName = NULL;
+ winDebug("SelectionRequest - target %d\n",
+ event.xselectionrequest.target);
+
+ pszAtomName = XGetAtomName (pDisplay,
+ event.xselectionrequest.target);
+ winDebug("SelectionRequest - Target atom name %s\n", pszAtomName);
+ XFree (pszAtomName);
+ pszAtomName = NULL;
+ winDebug ("SelectionRequest - owner %d\n", event.xselectionrequest.owner);
+ winDebug ("SelectionRequest - requestor %d\n", event.xselectionrequest.requestor);
+ }
+#endif
+
+ /* Abort if invalid target type */
+ if (event.xselectionrequest.target != XA_STRING
+ && event.xselectionrequest.target != atomUTF8String
+ && event.xselectionrequest.target != atomCompoundText
+ && event.xselectionrequest.target != atomTargets)
+ {
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+
+ /* Handle targets type of request */
+ if (event.xselectionrequest.target == atomTargets)
+ {
+ Atom atomTargetArr[] = {atomTargets,
+ atomCompoundText,
+ atomUTF8String,
+ XA_STRING};
+
+ /* Try to change the property */
+ iReturn = XChangeProperty (pDisplay,
+ event.xselectionrequest.requestor,
+ event.xselectionrequest.property,
+ XA_ATOM,
+ 32,
+ PropModeReplace,
+ (unsigned char *) atomTargetArr,
+ (sizeof (atomTargetArr)
+ / sizeof (atomTargetArr[0])));
+ if (iReturn == BadAlloc
+ || iReturn == BadAtom
+ || iReturn == BadMatch
+ || iReturn == BadValue
+ || iReturn == BadWindow)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "XChangeProperty failed: %d\n",
+ iReturn);
+ }
+
+ /* Setup selection notify xevent */
+ eventSelection.type = SelectionNotify;
+ eventSelection.send_event = True;
+ eventSelection.display = pDisplay;
+ eventSelection.requestor = event.xselectionrequest.requestor;
+ eventSelection.selection = event.xselectionrequest.selection;
+ eventSelection.target = event.xselectionrequest.target;
+ eventSelection.property = event.xselectionrequest.property;
+ eventSelection.time = event.xselectionrequest.time;
+
+ /*
+ * Notify the requesting window that
+ * the operation has completed
+ */
+ iReturn = XSendEvent (pDisplay,
+ eventSelection.requestor,
+ False,
+ 0L,
+ (XEvent *) &eventSelection);
+ if (iReturn == BadValue || iReturn == BadWindow)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "XSendEvent () failed\n");
+ }
+ break;
+ }
+
+ /* Check that clipboard format is available */
+ if (fUseUnicode
+ && !IsClipboardFormatAvailable (CF_UNICODETEXT))
+ {
+ static int count; /* Hack to stop acroread spamming the log */
+ static HWND lasthwnd; /* I've not seen any other client get here repeatedly? */
+ if (hwnd != lasthwnd) count = 0;
+ count++;
+ if (count < 6) ErrorF ("winClipboardFlushXEvents - CF_UNICODETEXT is not "
+ "available from Win32 clipboard. Aborting %d.\n", count);
+ lasthwnd = hwnd;
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+ else if (!fUseUnicode
+ && !IsClipboardFormatAvailable (CF_TEXT))
+ {
+ ErrorF ("winClipboardFlushXEvents - CF_TEXT is not "
+ "available from Win32 clipboard. Aborting.\n");
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+
+ /* Access the clipboard */
+ if (!ClipboardOpened)
+ {
+ if (!OpenClipboard (hwnd))
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "OpenClipboard () failed: %08x\n",
+ GetLastError ());
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+
+ /* Indicate that clipboard was opened */
+ fCloseClipboard = TRUE;
+ }
+ /* Setup the string style */
+ if (event.xselectionrequest.target == XA_STRING)
+ xiccesStyle = XStringStyle;
+#ifdef X_HAVE_UTF8_STRING
+ else if (event.xselectionrequest.target == atomUTF8String)
+ xiccesStyle = XUTF8StringStyle;
+#endif
+ else if (event.xselectionrequest.target == atomCompoundText)
+ xiccesStyle = XCompoundTextStyle;
+ else
+ xiccesStyle = XStringStyle;
+
+ /*
+ * FIXME: Can't pass CF_UNICODETEXT on Windows 95/98/Me
+ */
+
+ /* Get a pointer to the clipboard text, in desired format */
+ if (fUseUnicode)
+ {
+ /* Retrieve clipboard data */
+ hGlobal = GetClipboardData (CF_UNICODETEXT);
+ }
+ else
+ {
+ /* Retrieve clipboard data */
+ hGlobal = GetClipboardData (CF_TEXT);
+ }
+ if (!hGlobal)
+ {
+ if (GetLastError()==ERROR_CLIPBOARD_NOT_OPEN && ClipboardOpened)
+ {
+ ErrorF("We should not have received a SelectionRequest????\n"
+ "The owner is the clipboard, but in reality it was"
+ "an X window\n");
+ /* Set the owner to None */
+ XSetSelectionOwner (pDisplay, XA_PRIMARY, None, CurrentTime);
+ XSetSelectionOwner (pDisplay, XInternAtom (pDisplay, "CLIPBOARD", False), None, CurrentTime);
+ }
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "GetClipboardData () failed: %08x\n",
+ GetLastError ());
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+ pszGlobalData = (char *) GlobalLock (hGlobal);
+
+ /* Convert the Unicode string to UTF8 (MBCS) */
+ if (fUseUnicode)
+ {
+ iConvertDataLen = WideCharToMultiByte (CP_UTF8,
+ 0,
+ (LPCWSTR)pszGlobalData,
+ -1,
+ NULL,
+ 0,
+ NULL,
+ NULL);
+ /* NOTE: iConvertDataLen includes space for null terminator */
+ pszConvertData = (char *) malloc (iConvertDataLen);
+ WideCharToMultiByte (CP_UTF8,
+ 0,
+ (LPCWSTR)pszGlobalData,
+ -1,
+ pszConvertData,
+ iConvertDataLen,
+ NULL,
+ NULL);
+ }
+ else
+ {
+ pszConvertData = strdup (pszGlobalData);
+ iConvertDataLen = strlen (pszConvertData) + 1;
+ }
+
+ /* Convert DOS string to UNIX string */
+ winClipboardDOStoUNIX (pszConvertData, strlen (pszConvertData));
+
+ /* Setup our text list */
+ pszTextList[0] = pszConvertData;
+ pszTextList[1] = NULL;
+
+ /* Initialize the text property */
+ xtpText.value = NULL;
+ xtpText.nitems = 0;
+
+ /* Create the text property from the text list */
+ if (fUseUnicode)
+ {
+#ifdef X_HAVE_UTF8_STRING
+ iReturn = Xutf8TextListToTextProperty (pDisplay,
+ pszTextList,
+ 1,
+ xiccesStyle,
+ &xtpText);
+#endif
+ }
+ else
+ {
+ iReturn = XmbTextListToTextProperty (pDisplay,
+ pszTextList,
+ 1,
+ xiccesStyle,
+ &xtpText);
+ }
+ if (iReturn == XNoMemory || iReturn == XLocaleNotSupported)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "X*TextListToTextProperty failed: %d\n",
+ iReturn);
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+
+ /* Free the converted string */
+ free (pszConvertData);
+ pszConvertData = NULL;
+
+ /* Copy the clipboard text to the requesting window */
+ iReturn = XChangeProperty (pDisplay,
+ event.xselectionrequest.requestor,
+ event.xselectionrequest.property,
+ event.xselectionrequest.target,
+ 8,
+ PropModeReplace,
+ xtpText.value,
+ xtpText.nitems);
+ if (iReturn == BadAlloc || iReturn == BadAtom
+ || iReturn == BadMatch || iReturn == BadValue
+ || iReturn == BadWindow)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "XChangeProperty failed: %d\n",
+ iReturn);
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+
+ /* Release the clipboard data */
+ GlobalUnlock (hGlobal);
+ pszGlobalData = NULL;
+ if (fCloseClipboard)
+ {
+ fCloseClipboard = FALSE;
+ CloseClipboard ();
+ }
+ /* Clean up */
+ XFree (xtpText.value);
+ xtpText.value = NULL;
+ xtpText.nitems = 0;
+
+ /* Setup selection notify event */
+ eventSelection.type = SelectionNotify;
+ eventSelection.send_event = True;
+ eventSelection.display = pDisplay;
+ eventSelection.requestor = event.xselectionrequest.requestor;
+ eventSelection.selection = event.xselectionrequest.selection;
+ eventSelection.target = event.xselectionrequest.target;
+ eventSelection.property = event.xselectionrequest.property;
+ eventSelection.time = event.xselectionrequest.time;
+
+ /* Notify the requesting window that the operation has completed */
+ iReturn = XSendEvent (pDisplay,
+ eventSelection.requestor,
+ False,
+ 0L,
+ (XEvent *) &eventSelection);
+ if (iReturn == BadValue || iReturn == BadWindow)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "XSendEvent () failed\n");
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionRequest_Done;
+ }
+
+ winClipboardFlushXEvents_SelectionRequest_Done:
+ /* Free allocated resources */
+ if (xtpText.value)
+ {
+ XFree (xtpText.value);
+ xtpText.value = NULL;
+ xtpText.nitems = 0;
+ }
+ if (pszConvertData)
+ free (pszConvertData);
+ if (hGlobal && pszGlobalData)
+ GlobalUnlock (hGlobal);
+
+ /*
+ * Send a SelectionNotify event to the requesting
+ * client when we abort.
+ */
+ if (fAbort)
+ {
+ /* Setup selection notify event */
+ eventSelection.type = SelectionNotify;
+ eventSelection.send_event = True;
+ eventSelection.display = pDisplay;
+ eventSelection.requestor = event.xselectionrequest.requestor;
+ eventSelection.selection = event.xselectionrequest.selection;
+ eventSelection.target = event.xselectionrequest.target;
+ eventSelection.property = None;
+ eventSelection.time = event.xselectionrequest.time;
+
+ /* Notify the requesting window that the operation is complete */
+ iReturn = XSendEvent (pDisplay,
+ eventSelection.requestor,
+ False,
+ 0L,
+ (XEvent *) &eventSelection);
+ if (iReturn == BadValue || iReturn == BadWindow)
+ {
+ /*
+ * Should not be a problem if XSendEvent fails because
+ * the client may simply have exited.
+ */
+ ErrorF ("winClipboardFlushXEvents - SelectionRequest - "
+ "XSendEvent () failed for abort event.\n");
+ }
+ }
+
+ /* Close clipboard if it was opened */
+ if (fCloseClipboard)
+ {
+ fCloseClipboard = FALSE;
+ CloseClipboard ();
+ }
+ break;
+
+
+ /*
+ * SelectionNotify
+ */
+ case SelectionNotify:
+#ifdef _DEBUG
+ winDebug ("winClipboardFlushXEvents - SelectionNotify\n");
+ {
+ char *pszAtomName;
+ pszAtomName = XGetAtomName (pDisplay,
+ event.xselection.selection);
+
+ winDebug("winClipboardFlushXEvents - SelectionNotify - ATOM: %s\n",
+ pszAtomName);
+ winDebug ("SelectionNotify - requestor %d\n", event.xselectionrequest.requestor);
+ XFree (pszAtomName);
+ }
+#endif
+
+
+ /*
+ * Request conversion of UTF8 and CompoundText targets.
+ */
+ if (event.xselection.property == None)
+ {
+ if (event.xselection.target == XA_STRING)
+ {
+ winDebug ("winClipboardFlushXEvents - SelectionNotify - "
+ "XA_STRING\n");
+
+ return WIN_XEVENTS_CONVERT;
+ }
+ else if (event.xselection.target == atomUTF8String)
+ {
+ winDebug("winClipboardFlushXEvents - SelectionNotify - "
+ "Requesting conversion of UTF8 target.\n");
+
+ XConvertSelection (pDisplay,
+ event.xselection.selection,
+ XA_STRING,
+ atomLocalProperty,
+ iWindow,
+ CurrentTime);
+
+ /* Process the ConvertSelection event */
+ XFlush (pDisplay);
+ return WIN_XEVENTS_CONVERT;
+ }
+#ifdef X_HAVE_UTF8_STRING
+ else if (event.xselection.target == atomCompoundText)
+ {
+ winDebug("winClipboardFlushXEvents - SelectionNotify - "
+ "Requesting conversion of CompoundText target.\n");
+
+ XConvertSelection (pDisplay,
+ event.xselection.selection,
+ atomUTF8String,
+ atomLocalProperty,
+ iWindow,
+ CurrentTime);
+
+ /* Process the ConvertSelection event */
+ XFlush (pDisplay);
+ return WIN_XEVENTS_CONVERT;
+ }
+#endif
+ else
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
+ "Unknown format. Cannot request conversion, "
+ "aborting.\n");
+ break;
+ }
+ }
+
+ /* Retrieve the size of the stored data */
+ iReturn = XGetWindowProperty (pDisplay,
+ iWindow,
+ atomLocalProperty,
+ 0,
+ 0, /* Don't get data, just size */
+ False,
+ AnyPropertyType,
+ &xtpText.encoding,
+ &xtpText.format,
+ &xtpText.nitems,
+ &ulReturnBytesLeft,
+ &xtpText.value);
+ if (iReturn != Success)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
+ "XGetWindowProperty () failed, aborting: %d\n",
+ iReturn);
+ break;
+ }
+
+ winDebug("SelectionNotify - returned data %d left %d\n",
+ xtpText.nitems, ulReturnBytesLeft);
+
+ /* Request the selection data */
+ iReturn = XGetWindowProperty (pDisplay,
+ iWindow,
+ atomLocalProperty,
+ 0,
+ ulReturnBytesLeft,
+ False,
+ AnyPropertyType,
+ &xtpText.encoding,
+ &xtpText.format,
+ &xtpText.nitems,
+ &ulReturnBytesLeft,
+ &xtpText.value);
+ if (iReturn != Success)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
+ "XGetWindowProperty () failed, aborting: %d\n",
+ iReturn);
+ break;
+ }
+
+#ifdef WINDBG
+ {
+ char *pszAtomName = NULL;
+
+ winDebug("SelectionNotify - returned data %d left %d\n",
+ xtpText.nitems, ulReturnBytesLeft);
+ pszAtomName = XGetAtomName(pDisplay, xtpText.encoding);
+ winDebug("Notify atom name %s\n", pszAtomName);
+ XFree (pszAtomName);
+ pszAtomName = NULL;
+ }
+#endif
+
+ if (fUseUnicode)
+ {
+#ifdef X_HAVE_UTF8_STRING
+ /* Convert the text property to a text list */
+ iReturn = Xutf8TextPropertyToTextList (pDisplay,
+ &xtpText,
+ &ppszTextList,
+ &iCount);
+#endif
+ }
+ else
+ {
+ iReturn = XmbTextPropertyToTextList (pDisplay,
+ &xtpText,
+ &ppszTextList,
+ &iCount);
+ }
+ if (iReturn == Success || iReturn > 0)
+ {
+ /* Conversion succeeded or some unconvertible characters */
+ if (ppszTextList != NULL)
+ {
+ iReturnDataLen = 0;
+ for (i = 0; i < iCount; i++)
+ {
+ iReturnDataLen += strlen(ppszTextList[i]);
+ }
+ pszReturnData = (char *) malloc (iReturnDataLen + 1);
+ pszReturnData[0] = '\0';
+ for (i = 0; i < iCount; i++)
+ {
+ strcat (pszReturnData, ppszTextList[i]);
+ }
+ }
+ else
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
+ "X*TextPropertyToTextList list_return is NULL.\n");
+ pszReturnData = (char *) malloc (1);
+ pszReturnData[0] = '\0';
+ }
+ }
+ else
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify - "
+ "X*TextPropertyToTextList returned: ");
+ switch (iReturn)
+ {
+ case XNoMemory:
+ ErrorF ("XNoMemory\n");
+ break;
+ case XConverterNotFound:
+ ErrorF ("XConverterNotFound\n");
+ break;
+ default:
+ ErrorF ("%d", iReturn);
+ break;
+ }
+ pszReturnData = (char *) malloc (1);
+ pszReturnData[0] = '\0';
+ }
+
+ /* Free the data returned from XGetWindowProperty */
+ if (ppszTextList)
+ XFreeStringList (ppszTextList);
+ ppszTextList = NULL;
+ XFree (xtpText.value);
+ xtpText.value = NULL;
+ xtpText.nitems = 0;
+
+ /* Convert the X clipboard string to DOS format */
+ winClipboardUNIXtoDOS ((unsigned char **)&pszReturnData, strlen (pszReturnData));
+
+ if (fUseUnicode)
+ {
+ /* Find out how much space needed to convert MBCS to Unicode */
+ iUnicodeLen = MultiByteToWideChar (CP_UTF8,
+ 0,
+ pszReturnData,
+ -1,
+ NULL,
+ 0);
+
+ /* Allocate memory for the Unicode string */
+ pwszUnicodeStr
+ = (wchar_t*) malloc (sizeof (wchar_t) * (iUnicodeLen + 1));
+ if (!pwszUnicodeStr)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify "
+ "malloc failed for pwszUnicodeStr, aborting.\n");
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionNotify_Done;
+ }
+
+ /* Do the actual conversion */
+ MultiByteToWideChar (CP_UTF8,
+ 0,
+ pszReturnData,
+ -1,
+ pwszUnicodeStr,
+ iUnicodeLen);
+
+ /* Allocate global memory for the X clipboard data */
+ hGlobal = GlobalAlloc (GMEM_MOVEABLE,
+ sizeof (wchar_t) * (iUnicodeLen + 1));
+ }
+ else
+ {
+ pszConvertData = strdup (pszReturnData);
+ iConvertDataLen = strlen (pszConvertData) + 1;
+
+ /* Allocate global memory for the X clipboard data */
+ hGlobal = GlobalAlloc (GMEM_MOVEABLE, iConvertDataLen);
+ }
+
+ free (pszReturnData);
+
+ /* Check that global memory was allocated */
+ if (!hGlobal)
+ {
+ ErrorF ("winClipboardFlushXEvents - SelectionNotify "
+ "GlobalAlloc failed, aborting: %ld\n",
+ GetLastError ());
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionNotify_Done;
+ }
+
+ /* Obtain a pointer to the global memory */
+ pszGlobalData = GlobalLock (hGlobal);
+ if (pszGlobalData == NULL)
+ {
+ ErrorF ("winClipboardFlushXEvents - Could not lock global "
+ "memory for clipboard transfer\n");
+
+ /* Abort */
+ fAbort = TRUE;
+ goto winClipboardFlushXEvents_SelectionNotify_Done;
+ }
+
+ /* Copy the returned string into the global memory */
+ if (fUseUnicode)
+ {
+ memcpy (pszGlobalData,
+ pwszUnicodeStr,
+ sizeof (wchar_t) * (iUnicodeLen + 1));
+ free (pwszUnicodeStr);
+ pwszUnicodeStr = NULL;
+ }
+ else
+ {
+ strcpy (pszGlobalData, pszConvertData);
+ free (pszConvertData);
+ pszConvertData = NULL;
+ }
+
+ /* Release the pointer to the global memory */
+ GlobalUnlock (hGlobal);
+ pszGlobalData = NULL;
+
+ /* Push the selection data to the Windows clipboard */
+ if (fUseUnicode)
+ SetClipboardData (CF_UNICODETEXT, hGlobal);
+ else
+ SetClipboardData (CF_TEXT, hGlobal);
+
+ /* Flag that SetClipboardData has been called */
+ fSetClipboardData = FALSE;
+
+ /*
+ * NOTE: Do not try to free pszGlobalData, it is owned by
+ * Windows after the call to SetClipboardData ().
+ */
+
+ winClipboardFlushXEvents_SelectionNotify_Done:
+ /* Free allocated resources */
+ if (ppszTextList)
+ XFreeStringList (ppszTextList);
+ if (xtpText.value)
+ {
+ XFree (xtpText.value);
+ xtpText.value = NULL;
+ xtpText.nitems = 0;
+ }
+ if (pszConvertData)
+ free (pszConvertData);
+ if (pwszUnicodeStr)
+ free (pwszUnicodeStr);
+ if (hGlobal && pszGlobalData)
+ GlobalUnlock (hGlobal);
+ if (fSetClipboardData && g_fUnicodeSupport)
+ SetClipboardData (CF_UNICODETEXT, NULL);
+ if (fSetClipboardData)
+ SetClipboardData (CF_TEXT, NULL);
+ return WIN_XEVENTS_NOTIFY;
+
+ /*
+ * SelectionClear
+ */
+ case SelectionClear:
+#ifdef _DEBUG
+ winDebug ("SelectionClear - doing nothing\n");
+ {
+ char *pszAtomName;
+
+ pszAtomName = XGetAtomName (pDisplay,
+ event.xselection.selection);
+
+ winDebug ("SelectionClear - ATOM: %s\n",
+ pszAtomName);
+ winDebug ("SelectionClear - owner %d\n", event.xselectionrequest.owner);
+
+ XFree (pszAtomName);
+ }
+#endif
+ break;
+
+ case PropertyNotify:
+ break;
+
+ case MappingNotify:
+ XRefreshKeyboardMapping((XMappingEvent *)&event);
+ break;
+
+ default:
+ ErrorF ("winClipboardFlushXEvents - unexpected event type %d\n", event.type);
+ break;
+ }
+ }
+
+ return WIN_XEVENTS_SUCCESS;
+}
diff --git a/xorg-server/hw/xwin/wincmap.c b/xorg-server/hw/xwin/wincmap.c index 9da03888d..370a4c584 100644 --- a/xorg-server/hw/xwin/wincmap.c +++ b/xorg-server/hw/xwin/wincmap.c @@ -1,674 +1,622 @@ -/* - *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: Dakshinamurthy Karra - * Suhaib M Siddiqi - * Peter Busch - * Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" - - -/* - * Local prototypes - */ - -static int -winListInstalledColormaps (ScreenPtr pScreen, Colormap *pmaps); - -static void -winStoreColors (ColormapPtr pmap, int ndef, xColorItem *pdefs); - -static void -winInstallColormap (ColormapPtr pmap); - -static void -winUninstallColormap (ColormapPtr pmap); - -static void -winResolveColor (unsigned short *pred, - unsigned short *pgreen, - unsigned short *pblue, - VisualPtr pVisual); - -static Bool -winCreateColormap (ColormapPtr pmap); - -static void -winDestroyColormap (ColormapPtr pmap); - -static Bool -winGetPaletteDIB (ScreenPtr pScreen, ColormapPtr pcmap); - -static Bool -winGetPaletteDD (ScreenPtr pScreen, ColormapPtr pcmap); - - -/* - * Set screen functions for colormaps - */ - -void -winSetColormapFunctions (ScreenPtr pScreen) -{ - pScreen->CreateColormap = winCreateColormap; - pScreen->DestroyColormap = winDestroyColormap; - pScreen->InstallColormap = winInstallColormap; - pScreen->UninstallColormap = winUninstallColormap; - pScreen->ListInstalledColormaps = winListInstalledColormaps; - pScreen->StoreColors = winStoreColors; - pScreen->ResolveColor = winResolveColor; -} - - -/* See Porting Layer Definition - p. 30 */ -/* - * Walk the list of installed colormaps, filling the pmaps list - * with the resource ids of the installed maps, and return - * a count of the total number of installed maps. - */ -static int -winListInstalledColormaps (ScreenPtr pScreen, Colormap *pmaps) -{ - winScreenPriv(pScreen); - - /* - * There will only be one installed colormap, so we only need - * to return one id, and the count of installed maps will always - * be one. - */ - *pmaps = pScreenPriv->pcmapInstalled->mid; - return 1; -} - - -/* See Porting Layer Definition - p. 30 */ -/* See Programming Windows - p. 663 */ -static void -winInstallColormap (ColormapPtr pColormap) -{ - ScreenPtr pScreen = pColormap->pScreen; - winScreenPriv(pScreen); - ColormapPtr oldpmap = pScreenPriv->pcmapInstalled; - -#if CYGDEBUG - winDebug ("winInstallColormap\n"); -#endif - - /* Did the colormap actually change? */ - if (pColormap != oldpmap) - { -#if CYGDEBUG - winDebug ("winInstallColormap - Colormap has changed, attempt " - "to install.\n"); -#endif - - /* Was there a previous colormap? */ - if (oldpmap != (ColormapPtr) None) - { - /* There was a previous colormap; tell clients it is gone */ - WalkTree (pColormap->pScreen, TellLostMap, (char *)&oldpmap->mid); - } - - /* Install new colormap */ - pScreenPriv->pcmapInstalled = pColormap; - WalkTree (pColormap->pScreen, TellGainedMap, (char *)&pColormap->mid); - - /* Call the engine specific colormap install procedure */ - if (!((*pScreenPriv->pwinInstallColormap) (pColormap))) - { - winErrorFVerb (2, "winInstallColormap - Screen specific colormap install " - "procedure failed. Continuing, but colors may be " - "messed up from now on.\n"); - } - } - - /* Save a pointer to the newly installed colormap */ - pScreenPriv->pcmapInstalled = pColormap; -} - - -/* See Porting Layer Definition - p. 30 */ -static void -winUninstallColormap (ColormapPtr pmap) -{ - winScreenPriv(pmap->pScreen); - ColormapPtr curpmap = pScreenPriv->pcmapInstalled; - -#if CYGDEBUG - winDebug ("winUninstallColormap\n"); -#endif - - /* Is the colormap currently installed? */ - if (pmap != curpmap) - { - /* Colormap not installed, nothing to do */ - return; - } - - /* Clear the installed colormap flag */ - pScreenPriv->pcmapInstalled = NULL; - - /* - * NOTE: The default colormap does not get "uninstalled" before - * it is destroyed. - */ - - /* Install the default cmap in place of the cmap to be uninstalled */ - if (pmap->mid != pmap->pScreen->defColormap) - { - dixLookupResourceByType((pointer) &curpmap, pmap->pScreen->defColormap, - RT_COLORMAP, NullClient, DixUnknownAccess); - (*pmap->pScreen->InstallColormap) (curpmap); - } -} - - -/* See Porting Layer Definition - p. 30 */ -static void -winStoreColors (ColormapPtr pmap, - int ndef, - xColorItem *pdefs) -{ - ScreenPtr pScreen = pmap->pScreen; - winScreenPriv(pScreen); - winCmapPriv(pmap); - int i; - unsigned short nRed, nGreen, nBlue; - -#if CYGDEBUG - if (ndef != 1) - winDebug ("winStoreColors - ndef: %d\n", - ndef); -#endif - - /* Save the new colors in the colormap privates */ - for (i = 0; i < ndef; ++i) - { - /* Adjust the colors from the X color spec to the Windows color spec */ - nRed = pdefs[i].red >> 8; - nGreen = pdefs[i].green >> 8; - nBlue = pdefs[i].blue >> 8; - - /* Copy the colors to a palette entry table */ - pCmapPriv->peColors[pdefs[0].pixel + i].peRed = nRed; - pCmapPriv->peColors[pdefs[0].pixel + i].peGreen = nGreen; - pCmapPriv->peColors[pdefs[0].pixel + i].peBlue = nBlue; - - /* Copy the colors to a RGBQUAD table */ - pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbRed = nRed; - pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbGreen = nGreen; - pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbBlue = nBlue; - -#if CYGDEBUG - winDebug ("winStoreColors - nRed %d nGreen %d nBlue %d\n", - nRed, nGreen, nBlue); -#endif - } - - /* Call the engine specific store colors procedure */ - if (!((pScreenPriv->pwinStoreColors) (pmap, ndef, pdefs))) - { - winErrorFVerb (2, "winStoreColors - Engine cpecific color storage procedure " - "failed. Continuing, but colors may be messed up from now " - "on.\n"); - } -} - - -/* See Porting Layer Definition - p. 30 */ -static void -winResolveColor (unsigned short *pred, - unsigned short *pgreen, - unsigned short *pblue, - VisualPtr pVisual) -{ -#if CYGDEBUG - winDebug ("winResolveColor ()\n"); -#endif - - miResolveColor (pred, pgreen, pblue, pVisual); -} - - -/* See Porting Layer Definition - p. 29 */ -static Bool -winCreateColormap (ColormapPtr pmap) -{ - winPrivCmapPtr pCmapPriv = NULL; - ScreenPtr pScreen = pmap->pScreen; - winScreenPriv(pScreen); - -#if CYGDEBUG - winDebug ("winCreateColormap\n"); -#endif - - /* Allocate colormap privates */ - if (!winAllocateCmapPrivates (pmap)) - { - ErrorF ("winCreateColorma - Couldn't allocate cmap privates\n"); - return FALSE; - } - - /* Get a pointer to the newly allocated privates */ - pCmapPriv = winGetCmapPriv (pmap); - - /* - * FIXME: This is some evil hackery to help in handling some X clients - * that expect the top pixel to be white. This "help" only lasts until - * some client overwrites the top colormap entry. - * - * We don't want to actually allocate the top entry, as that causes - * problems with X clients that need 7 planes (128 colors) in the default - * colormap, such as Magic 7.1. - */ - pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbRed = 255; - pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbGreen = 255; - pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbBlue = 255; - pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peRed = 255; - pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peGreen = 255; - pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peBlue = 255; - - /* Call the engine specific colormap initialization procedure */ - if (!((*pScreenPriv->pwinCreateColormap) (pmap))) - { - ErrorF ("winCreateColormap - Engine specific colormap creation " - "procedure failed. Aborting.\n"); - return FALSE; - } - - return TRUE; -} - - -/* See Porting Layer Definition - p. 29, 30 */ -static void -winDestroyColormap (ColormapPtr pColormap) -{ - winScreenPriv(pColormap->pScreen); - winCmapPriv(pColormap); - - /* Call the engine specific colormap destruction procedure */ - if (!((*pScreenPriv->pwinDestroyColormap) (pColormap))) - { - winErrorFVerb (2, "winDestroyColormap - Engine specific colormap destruction " - "procedure failed. Continuing, but it is possible that memory " - "was leaked, or that colors will be messed up from now on.\n"); - } - - /* Free the colormap privates */ - free (pCmapPriv); - winSetCmapPriv (pColormap, NULL); - -#if CYGDEBUG - winDebug ("winDestroyColormap - Returning\n"); -#endif -} - - -/* - * Internal function to load the palette used by the Shadow DIB - */ - -static Bool -winGetPaletteDIB (ScreenPtr pScreen, ColormapPtr pcmap) -{ - winScreenPriv(pScreen); - int i; - Pixel pixel; /* Pixel == CARD32 */ - CARD16 nRed, nGreen, nBlue; /* CARD16 == unsigned short */ - UINT uiColorsRetrieved = 0; - RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES]; - - /* Get the color table for the screen */ - uiColorsRetrieved = GetDIBColorTable (pScreenPriv->hdcScreen, - 0, - WIN_NUM_PALETTE_ENTRIES, - rgbColors); - if (uiColorsRetrieved == 0) - { - ErrorF ("winGetPaletteDIB - Could not retrieve screen color table\n"); - return FALSE; - } - -#if CYGDEBUG - winDebug ("winGetPaletteDIB - Retrieved %d colors from DIB\n", - uiColorsRetrieved); -#endif - - /* Set the DIB color table to the default screen palette */ - if (SetDIBColorTable (pScreenPriv->hdcShadow, - 0, - uiColorsRetrieved, - rgbColors) == 0) - { - ErrorF ("winGetPaletteDIB - SetDIBColorTable () failed\n"); - return FALSE; - } - - /* Alloc each color in the DIB color table */ - for (i = 0; i < uiColorsRetrieved; ++i) - { - pixel = i; - - /* Extract the color values for current palette entry */ - nRed = rgbColors[i].rgbRed << 8; - nGreen = rgbColors[i].rgbGreen << 8; - nBlue = rgbColors[i].rgbBlue << 8; - -#if CYGDEBUG - winDebug ("winGetPaletteDIB - Allocating a color: %d; " - "%d %d %d\n", - pixel, nRed, nGreen, nBlue); -#endif - - /* Allocate a entry in the X colormap */ - if (AllocColor (pcmap, - &nRed, - &nGreen, - &nBlue, - &pixel, - 0) != Success) - { - ErrorF ("winGetPaletteDIB - AllocColor () failed, pixel %d\n", - i); - return FALSE; - } - - if (i != pixel - || nRed != rgbColors[i].rgbRed - || nGreen != rgbColors[i].rgbGreen - || nBlue != rgbColors[i].rgbBlue) - { - winDebug ("winGetPaletteDIB - Got: %d; " - "%d %d %d\n", - (int) pixel, nRed, nGreen, nBlue); - } - - /* FIXME: Not sure that this bit is needed at all */ - pcmap->red[i].co.local.red = nRed; - pcmap->red[i].co.local.green = nGreen; - pcmap->red[i].co.local.blue = nBlue; - } - - /* System is using a colormap */ - /* Set the black and white pixel indices */ - pScreen->whitePixel = uiColorsRetrieved - 1; - pScreen->blackPixel = 0; - - return TRUE; -} - - -/* - * Internal function to load the standard system palette being used by DD - */ - -static Bool -winGetPaletteDD (ScreenPtr pScreen, ColormapPtr pcmap) -{ - int i; - Pixel pixel; /* Pixel == CARD32 */ - CARD16 nRed, nGreen, nBlue; /* CARD16 == unsigned short */ - UINT uiSystemPaletteEntries; - LPPALETTEENTRY ppeColors = NULL; - HDC hdc = NULL; - - /* Get a DC to obtain the default palette */ - hdc = GetDC (NULL); - if (hdc == NULL) - { - ErrorF ("winGetPaletteDD - Couldn't get a DC\n"); - return FALSE; - } - - /* Get the number of entries in the system palette */ - uiSystemPaletteEntries = GetSystemPaletteEntries (hdc, - 0, 0, NULL); - if (uiSystemPaletteEntries == 0) - { - ErrorF ("winGetPaletteDD - Unable to determine number of " - "system palette entries\n"); - return FALSE; - } - -#if CYGDEBUG - winDebug ("winGetPaletteDD - uiSystemPaletteEntries %d\n", - uiSystemPaletteEntries); -#endif - - /* Allocate palette entries structure */ - ppeColors = malloc (uiSystemPaletteEntries * sizeof (PALETTEENTRY)); - if (ppeColors == NULL) - { - ErrorF ("winGetPaletteDD - malloc () for colormap failed\n"); - return FALSE; - } - - /* Get system palette entries */ - GetSystemPaletteEntries (hdc, - 0, uiSystemPaletteEntries, ppeColors); - - /* Allocate an X colormap entry for every system palette entry */ - for (i = 0; i < uiSystemPaletteEntries; ++i) - { - pixel = i; - - /* Extract the color values for current palette entry */ - nRed = ppeColors[i].peRed << 8; - nGreen = ppeColors[i].peGreen << 8; - nBlue = ppeColors[i].peBlue << 8; -#if CYGDEBUG - winDebug ("winGetPaletteDD - Allocating a color: %d; " - "%d %d %d\n", - pixel, nRed, nGreen, nBlue); -#endif - if (AllocColor (pcmap, - &nRed, - &nGreen, - &nBlue, - &pixel, - 0) != Success) - { - ErrorF ("winGetPaletteDD - AllocColor () failed, pixel %d\n", - i); - free (ppeColors); - ppeColors = NULL; - return FALSE; - } - - pcmap->red[i].co.local.red = nRed; - pcmap->red[i].co.local.green = nGreen; - pcmap->red[i].co.local.blue = nBlue; - } - - /* System is using a colormap */ - /* Set the black and white pixel indices */ - pScreen->whitePixel = uiSystemPaletteEntries - 1; - pScreen->blackPixel = 0; - - /* Free colormap */ - if (ppeColors != NULL) - { - free (ppeColors); - ppeColors = NULL; - } - - /* Free the DC */ - if (hdc != NULL) - { - ReleaseDC (NULL, hdc); - hdc = NULL; - } - - return TRUE; -} - - -/* - * Install the standard fb colormap, or the GDI colormap, - * depending on the current screen depth. - */ - -Bool -winCreateDefColormap (ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - unsigned short zero = 0, ones = 0xFFFF; - VisualPtr pVisual = pScreenPriv->pRootVisual; - ColormapPtr pcmap = NULL; - Pixel wp, bp; - -#if CYGDEBUG - winDebug ("winCreateDefColormap\n"); -#endif - - /* Use standard fb colormaps for non palettized color modes */ - if (pScreenInfo->dwBPP > 8) - { - winDebug ("winCreateDefColormap - Deferring to " \ - "fbCreateDefColormap ()\n"); - return fbCreateDefColormap (pScreen); - } - - /* - * AllocAll for non-Dynamic visual classes, - * AllocNone for Dynamic visual classes. - */ - - /* - * Dynamic visual classes allow the colors of the color map - * to be changed by clients. - */ - -#if CYGDEBUG - winDebug ("winCreateDefColormap - defColormap: %d\n", - pScreen->defColormap); -#endif - - /* Allocate an X colormap, owned by client 0 */ - if (CreateColormap (pScreen->defColormap, - pScreen, - pVisual, - &pcmap, - (pVisual->class & DynamicClass) ? AllocNone : AllocAll, - 0) != Success) - { - ErrorF ("winCreateDefColormap - CreateColormap failed\n"); - return FALSE; - } - if (pcmap == NULL) - { - ErrorF ("winCreateDefColormap - Colormap could not be created\n"); - return FALSE; - } - -#if CYGDEBUG - winDebug ("winCreateDefColormap - Created a colormap\n"); -#endif - - /* Branch on the visual class */ - if (!(pVisual->class & DynamicClass)) - { - /* Branch on engine type */ - if (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI) - { - /* Load the colors being used by the Shadow DIB */ - if (!winGetPaletteDIB (pScreen, pcmap)) - { - ErrorF ("winCreateDefColormap - Couldn't get DIB colors\n"); - return FALSE; - } - } - else - { - /* Load the colors from the default system palette */ - if (!winGetPaletteDD (pScreen, pcmap)) - { - ErrorF ("winCreateDefColormap - Couldn't get colors " - "for DD\n"); - return FALSE; - } - } - } - else - { - wp = pScreen->whitePixel; - bp = pScreen->blackPixel; - - /* Allocate a black and white pixel */ - if ((AllocColor (pcmap, &ones, &ones, &ones, &wp, 0) != - Success) - || - (AllocColor (pcmap, &zero, &zero, &zero, &bp, 0) != - Success)) - { - ErrorF ("winCreateDefColormap - Couldn't allocate bp or wp\n"); - return FALSE; - } - - pScreen->whitePixel = wp; - pScreen->blackPixel = bp; - -#if 0 - /* Have to reserve first 10 and last ten pixels in DirectDraw windowed */ - if (pScreenInfo->dwEngine != WIN_SERVER_SHADOW_GDI) - { - int k; - Pixel p; - - for (k = 1; k < 10; ++k) - { - p = k; - if (AllocColor (pcmap, &ones, &ones, &ones, &p, 0) != Success) - FatalError ("Foo!\n"); - } - - for (k = 245; k < 255; ++k) - { - p = k; - if (AllocColor (pcmap, &zero, &zero, &zero, &p, 0) != Success) - FatalError ("Baz!\n"); - } - } -#endif - } - - /* Install the created colormap */ - (*pScreen->InstallColormap)(pcmap); - -#if CYGDEBUG - winDebug ("winCreateDefColormap - Returning\n"); -#endif - - return TRUE; -} +/*
+ *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: Dakshinamurthy Karra
+ * Suhaib M Siddiqi
+ * Peter Busch
+ * Harold L Hunt II
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+
+
+/*
+ * Local prototypes
+ */
+
+static int
+winListInstalledColormaps (ScreenPtr pScreen, Colormap *pmaps);
+
+static void
+winStoreColors (ColormapPtr pmap, int ndef, xColorItem *pdefs);
+
+static void
+winInstallColormap (ColormapPtr pmap);
+
+static void
+winUninstallColormap (ColormapPtr pmap);
+
+static void
+winResolveColor (unsigned short *pred,
+ unsigned short *pgreen,
+ unsigned short *pblue,
+ VisualPtr pVisual);
+
+static Bool
+winCreateColormap (ColormapPtr pmap);
+
+static void
+winDestroyColormap (ColormapPtr pmap);
+
+static Bool
+winGetPaletteDIB (ScreenPtr pScreen, ColormapPtr pcmap);
+
+static Bool
+winGetPaletteDD (ScreenPtr pScreen, ColormapPtr pcmap);
+
+
+/*
+ * Set screen functions for colormaps
+ */
+
+void
+winSetColormapFunctions (ScreenPtr pScreen)
+{
+ pScreen->CreateColormap = winCreateColormap;
+ pScreen->DestroyColormap = winDestroyColormap;
+ pScreen->InstallColormap = winInstallColormap;
+ pScreen->UninstallColormap = winUninstallColormap;
+ pScreen->ListInstalledColormaps = winListInstalledColormaps;
+ pScreen->StoreColors = winStoreColors;
+ pScreen->ResolveColor = winResolveColor;
+}
+
+
+/* See Porting Layer Definition - p. 30 */
+/*
+ * Walk the list of installed colormaps, filling the pmaps list
+ * with the resource ids of the installed maps, and return
+ * a count of the total number of installed maps.
+ */
+static int
+winListInstalledColormaps (ScreenPtr pScreen, Colormap *pmaps)
+{
+ winScreenPriv(pScreen);
+
+ /*
+ * There will only be one installed colormap, so we only need
+ * to return one id, and the count of installed maps will always
+ * be one.
+ */
+ *pmaps = pScreenPriv->pcmapInstalled->mid;
+ return 1;
+}
+
+
+/* See Porting Layer Definition - p. 30 */
+/* See Programming Windows - p. 663 */
+static void
+winInstallColormap (ColormapPtr pColormap)
+{
+ ScreenPtr pScreen = pColormap->pScreen;
+ winScreenPriv(pScreen);
+ ColormapPtr oldpmap = pScreenPriv->pcmapInstalled;
+
+ winDebug ("winInstallColormap\n");
+
+ /* Did the colormap actually change? */
+ if (pColormap != oldpmap)
+ {
+ winDebug ("winInstallColormap - Colormap has changed, attempt "
+ "to install.\n");
+
+ /* Was there a previous colormap? */
+ if (oldpmap != (ColormapPtr) None)
+ {
+ /* There was a previous colormap; tell clients it is gone */
+ WalkTree (pColormap->pScreen, TellLostMap, (char *)&oldpmap->mid);
+ }
+
+ /* Install new colormap */
+ pScreenPriv->pcmapInstalled = pColormap;
+ WalkTree (pColormap->pScreen, TellGainedMap, (char *)&pColormap->mid);
+
+ /* Call the engine specific colormap install procedure */
+ if (!((*pScreenPriv->pwinInstallColormap) (pColormap)))
+ {
+ ErrorF ("winInstallColormap - Screen specific colormap install "
+ "procedure failed. Continuing, but colors may be "
+ "messed up from now on.\n");
+ }
+ }
+
+ /* Save a pointer to the newly installed colormap */
+ pScreenPriv->pcmapInstalled = pColormap;
+}
+
+
+/* See Porting Layer Definition - p. 30 */
+static void
+winUninstallColormap (ColormapPtr pmap)
+{
+ winScreenPriv(pmap->pScreen);
+ ColormapPtr curpmap = pScreenPriv->pcmapInstalled;
+
+ winDebug ("winUninstallColormap\n");
+
+ /* Is the colormap currently installed? */
+ if (pmap != curpmap)
+ {
+ /* Colormap not installed, nothing to do */
+ return;
+ }
+
+ /* Clear the installed colormap flag */
+ pScreenPriv->pcmapInstalled = NULL;
+
+ /*
+ * NOTE: The default colormap does not get "uninstalled" before
+ * it is destroyed.
+ */
+
+ /* Install the default cmap in place of the cmap to be uninstalled */
+ if (pmap->mid != pmap->pScreen->defColormap)
+ {
+ dixLookupResourceByType((pointer) &curpmap, pmap->pScreen->defColormap,
+ RT_COLORMAP, NullClient, DixUnknownAccess);
+ (*pmap->pScreen->InstallColormap) (curpmap);
+ }
+}
+
+
+/* See Porting Layer Definition - p. 30 */
+static void
+winStoreColors (ColormapPtr pmap,
+ int ndef,
+ xColorItem *pdefs)
+{
+ ScreenPtr pScreen = pmap->pScreen;
+ winScreenPriv(pScreen);
+ winCmapPriv(pmap);
+ int i;
+ unsigned short nRed, nGreen, nBlue;
+
+#ifdef WINDBG
+ if (ndef != 1)
+ winDebug ("winStoreColors - ndef: %d\n",
+ ndef);
+#endif
+
+ /* Save the new colors in the colormap privates */
+ for (i = 0; i < ndef; ++i)
+ {
+ /* Adjust the colors from the X color spec to the Windows color spec */
+ nRed = pdefs[i].red >> 8;
+ nGreen = pdefs[i].green >> 8;
+ nBlue = pdefs[i].blue >> 8;
+
+ /* Copy the colors to a palette entry table */
+ pCmapPriv->peColors[pdefs[0].pixel + i].peRed = nRed;
+ pCmapPriv->peColors[pdefs[0].pixel + i].peGreen = nGreen;
+ pCmapPriv->peColors[pdefs[0].pixel + i].peBlue = nBlue;
+
+ /* Copy the colors to a RGBQUAD table */
+ pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbRed = nRed;
+ pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbGreen = nGreen;
+ pCmapPriv->rgbColors[pdefs[0].pixel + i].rgbBlue = nBlue;
+
+ winDebug ("winStoreColors - nRed %d nGreen %d nBlue %d\n",
+ nRed, nGreen, nBlue);
+ }
+
+ /* Call the engine specific store colors procedure */
+ if (!((pScreenPriv->pwinStoreColors) (pmap, ndef, pdefs)))
+ {
+ ErrorF ("winStoreColors - Engine cpecific color storage procedure "
+ "failed. Continuing, but colors may be messed up from now "
+ "on.\n");
+ }
+}
+
+
+/* See Porting Layer Definition - p. 30 */
+static void
+winResolveColor (unsigned short *pred,
+ unsigned short *pgreen,
+ unsigned short *pblue,
+ VisualPtr pVisual)
+{
+ winDebug ("winResolveColor ()\n");
+
+ miResolveColor (pred, pgreen, pblue, pVisual);
+}
+
+
+/* See Porting Layer Definition - p. 29 */
+static Bool
+winCreateColormap (ColormapPtr pmap)
+{
+ winPrivCmapPtr pCmapPriv = NULL;
+ ScreenPtr pScreen = pmap->pScreen;
+ winScreenPriv(pScreen);
+
+ winDebug ("winCreateColormap\n");
+
+ /* Allocate colormap privates */
+ if (!winAllocateCmapPrivates (pmap))
+ {
+ ErrorF ("winCreateColorma - Couldn't allocate cmap privates\n");
+ return FALSE;
+ }
+
+ /* Get a pointer to the newly allocated privates */
+ pCmapPriv = winGetCmapPriv (pmap);
+
+ /*
+ * FIXME: This is some evil hackery to help in handling some X clients
+ * that expect the top pixel to be white. This "help" only lasts until
+ * some client overwrites the top colormap entry.
+ *
+ * We don't want to actually allocate the top entry, as that causes
+ * problems with X clients that need 7 planes (128 colors) in the default
+ * colormap, such as Magic 7.1.
+ */
+ pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbRed = 255;
+ pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbGreen = 255;
+ pCmapPriv->rgbColors[WIN_NUM_PALETTE_ENTRIES - 1].rgbBlue = 255;
+ pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peRed = 255;
+ pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peGreen = 255;
+ pCmapPriv->peColors[WIN_NUM_PALETTE_ENTRIES - 1].peBlue = 255;
+
+ /* Call the engine specific colormap initialization procedure */
+ if (!((*pScreenPriv->pwinCreateColormap) (pmap)))
+ {
+ ErrorF ("winCreateColormap - Engine specific colormap creation "
+ "procedure failed. Aborting.\n");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+
+/* See Porting Layer Definition - p. 29, 30 */
+static void
+winDestroyColormap (ColormapPtr pColormap)
+{
+ winScreenPriv(pColormap->pScreen);
+ winCmapPriv(pColormap);
+
+ /* Call the engine specific colormap destruction procedure */
+ if (!((*pScreenPriv->pwinDestroyColormap) (pColormap)))
+ {
+ ErrorF ("winDestroyColormap - Engine specific colormap destruction "
+ "procedure failed. Continuing, but it is possible that memory "
+ "was leaked, or that colors will be messed up from now on.\n");
+ }
+
+ /* Free the colormap privates */
+ free (pCmapPriv);
+ winSetCmapPriv (pColormap, NULL);
+
+ winDebug ("winDestroyColormap - Returning\n");
+}
+
+
+/*
+ * Internal function to load the palette used by the Shadow DIB
+ */
+
+static Bool
+winGetPaletteDIB (ScreenPtr pScreen, ColormapPtr pcmap)
+{
+ winScreenPriv(pScreen);
+ int i;
+ Pixel pixel; /* Pixel == CARD32 */
+ CARD16 nRed, nGreen, nBlue; /* CARD16 == unsigned short */
+ UINT uiColorsRetrieved = 0;
+ RGBQUAD rgbColors[WIN_NUM_PALETTE_ENTRIES];
+
+ /* Get the color table for the screen */
+ uiColorsRetrieved = GetDIBColorTable (pScreenPriv->hdcScreen,
+ 0,
+ WIN_NUM_PALETTE_ENTRIES,
+ rgbColors);
+ if (uiColorsRetrieved == 0)
+ {
+ ErrorF ("winGetPaletteDIB - Could not retrieve screen color table\n");
+ return FALSE;
+ }
+
+ winDebug ("winGetPaletteDIB - Retrieved %d colors from DIB\n",
+ uiColorsRetrieved);
+
+ /* Set the DIB color table to the default screen palette */
+ if (SetDIBColorTable (pScreenPriv->hdcShadow,
+ 0,
+ uiColorsRetrieved,
+ rgbColors) == 0)
+ {
+ ErrorF ("winGetPaletteDIB - SetDIBColorTable () failed\n");
+ return FALSE;
+ }
+
+ /* Alloc each color in the DIB color table */
+ for (i = 0; i < uiColorsRetrieved; ++i)
+ {
+ pixel = i;
+
+ /* Extract the color values for current palette entry */
+ nRed = rgbColors[i].rgbRed << 8;
+ nGreen = rgbColors[i].rgbGreen << 8;
+ nBlue = rgbColors[i].rgbBlue << 8;
+
+ winDebug ("winGetPaletteDIB - Allocating a color: %d; "
+ "%d %d %d\n",
+ pixel, nRed, nGreen, nBlue);
+
+ /* Allocate a entry in the X colormap */
+ if (AllocColor (pcmap,
+ &nRed,
+ &nGreen,
+ &nBlue,
+ &pixel,
+ 0) != Success)
+ {
+ ErrorF ("winGetPaletteDIB - AllocColor () failed, pixel %d\n",
+ i);
+ return FALSE;
+ }
+
+ if (i != pixel
+ || nRed != rgbColors[i].rgbRed
+ || nGreen != rgbColors[i].rgbGreen
+ || nBlue != rgbColors[i].rgbBlue)
+ {
+ winDebug ("winGetPaletteDIB - Got: %d; "
+ "%d %d %d\n",
+ (int) pixel, nRed, nGreen, nBlue);
+ }
+
+ /* FIXME: Not sure that this bit is needed at all */
+ pcmap->red[i].co.local.red = nRed;
+ pcmap->red[i].co.local.green = nGreen;
+ pcmap->red[i].co.local.blue = nBlue;
+ }
+
+ /* System is using a colormap */
+ /* Set the black and white pixel indices */
+ pScreen->whitePixel = uiColorsRetrieved - 1;
+ pScreen->blackPixel = 0;
+
+ return TRUE;
+}
+
+
+/*
+ * Internal function to load the standard system palette being used by DD
+ */
+
+static Bool
+winGetPaletteDD (ScreenPtr pScreen, ColormapPtr pcmap)
+{
+ int i;
+ Pixel pixel; /* Pixel == CARD32 */
+ CARD16 nRed, nGreen, nBlue; /* CARD16 == unsigned short */
+ UINT uiSystemPaletteEntries;
+ LPPALETTEENTRY ppeColors = NULL;
+ HDC hdc = NULL;
+
+ /* Get a DC to obtain the default palette */
+ hdc = GetDC (NULL);
+ if (hdc == NULL)
+ {
+ ErrorF ("winGetPaletteDD - Couldn't get a DC\n");
+ return FALSE;
+ }
+
+ /* Get the number of entries in the system palette */
+ uiSystemPaletteEntries = GetSystemPaletteEntries (hdc,
+ 0, 0, NULL);
+ if (uiSystemPaletteEntries == 0)
+ {
+ ErrorF ("winGetPaletteDD - Unable to determine number of "
+ "system palette entries\n");
+ return FALSE;
+ }
+
+ winDebug ("winGetPaletteDD - uiSystemPaletteEntries %d\n",
+ uiSystemPaletteEntries);
+
+ /* Allocate palette entries structure */
+ ppeColors = malloc (uiSystemPaletteEntries * sizeof (PALETTEENTRY));
+ if (ppeColors == NULL)
+ {
+ ErrorF ("winGetPaletteDD - malloc () for colormap failed\n");
+ return FALSE;
+ }
+
+ /* Get system palette entries */
+ GetSystemPaletteEntries (hdc,
+ 0, uiSystemPaletteEntries, ppeColors);
+
+ /* Allocate an X colormap entry for every system palette entry */
+ for (i = 0; i < uiSystemPaletteEntries; ++i)
+ {
+ pixel = i;
+
+ /* Extract the color values for current palette entry */
+ nRed = ppeColors[i].peRed << 8;
+ nGreen = ppeColors[i].peGreen << 8;
+ nBlue = ppeColors[i].peBlue << 8;
+ winDebug ("winGetPaletteDD - Allocating a color: %d; "
+ "%d %d %d\n",
+ pixel, nRed, nGreen, nBlue);
+ if (AllocColor (pcmap,
+ &nRed,
+ &nGreen,
+ &nBlue,
+ &pixel,
+ 0) != Success)
+ {
+ ErrorF ("winGetPaletteDD - AllocColor () failed, pixel %d\n",
+ i);
+ free (ppeColors);
+ ppeColors = NULL;
+ return FALSE;
+ }
+
+ pcmap->red[i].co.local.red = nRed;
+ pcmap->red[i].co.local.green = nGreen;
+ pcmap->red[i].co.local.blue = nBlue;
+ }
+
+ /* System is using a colormap */
+ /* Set the black and white pixel indices */
+ pScreen->whitePixel = uiSystemPaletteEntries - 1;
+ pScreen->blackPixel = 0;
+
+ /* Free colormap */
+ if (ppeColors != NULL)
+ {
+ free (ppeColors);
+ ppeColors = NULL;
+ }
+
+ /* Free the DC */
+ if (hdc != NULL)
+ {
+ ReleaseDC (NULL, hdc);
+ hdc = NULL;
+ }
+
+ return TRUE;
+}
+
+
+/*
+ * Install the standard fb colormap, or the GDI colormap,
+ * depending on the current screen depth.
+ */
+
+Bool
+winCreateDefColormap (ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ unsigned short zero = 0, ones = 0xFFFF;
+ VisualPtr pVisual = pScreenPriv->pRootVisual;
+ ColormapPtr pcmap = NULL;
+ Pixel wp, bp;
+
+ winDebug ("winCreateDefColormap\n");
+
+ /* Use standard fb colormaps for non palettized color modes */
+ if (pScreenInfo->dwBPP > 8)
+ {
+ winDebug ("winCreateDefColormap - Deferring to " \
+ "fbCreateDefColormap ()\n");
+ return fbCreateDefColormap (pScreen);
+ }
+
+ /*
+ * AllocAll for non-Dynamic visual classes,
+ * AllocNone for Dynamic visual classes.
+ */
+
+ /*
+ * Dynamic visual classes allow the colors of the color map
+ * to be changed by clients.
+ */
+
+ winDebug ("winCreateDefColormap - defColormap: %d\n",
+ pScreen->defColormap);
+
+ /* Allocate an X colormap, owned by client 0 */
+ if (CreateColormap (pScreen->defColormap,
+ pScreen,
+ pVisual,
+ &pcmap,
+ (pVisual->class & DynamicClass) ? AllocNone : AllocAll,
+ 0) != Success)
+ {
+ ErrorF ("winCreateDefColormap - CreateColormap failed\n");
+ return FALSE;
+ }
+ if (pcmap == NULL)
+ {
+ ErrorF ("winCreateDefColormap - Colormap could not be created\n");
+ return FALSE;
+ }
+
+ winDebug ("winCreateDefColormap - Created a colormap\n");
+
+ /* Branch on the visual class */
+ if (!(pVisual->class & DynamicClass))
+ {
+ /* Branch on engine type */
+ if (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI)
+ {
+ /* Load the colors being used by the Shadow DIB */
+ if (!winGetPaletteDIB (pScreen, pcmap))
+ {
+ ErrorF ("winCreateDefColormap - Couldn't get DIB colors\n");
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* Load the colors from the default system palette */
+ if (!winGetPaletteDD (pScreen, pcmap))
+ {
+ ErrorF ("winCreateDefColormap - Couldn't get colors "
+ "for DD\n");
+ return FALSE;
+ }
+ }
+ }
+ else
+ {
+ wp = pScreen->whitePixel;
+ bp = pScreen->blackPixel;
+
+ /* Allocate a black and white pixel */
+ if ((AllocColor (pcmap, &ones, &ones, &ones, &wp, 0) !=
+ Success)
+ ||
+ (AllocColor (pcmap, &zero, &zero, &zero, &bp, 0) !=
+ Success))
+ {
+ ErrorF ("winCreateDefColormap - Couldn't allocate bp or wp\n");
+ return FALSE;
+ }
+
+ pScreen->whitePixel = wp;
+ pScreen->blackPixel = bp;
+
+ }
+
+ /* Install the created colormap */
+ (*pScreen->InstallColormap)(pcmap);
+
+ winDebug ("winCreateDefColormap - Returning\n");
+
+ return TRUE;
+}
diff --git a/xorg-server/hw/xwin/winconfig.c b/xorg-server/hw/xwin/winconfig.c index 259b3d238..c2a0ef7ec 100644 --- a/xorg-server/hw/xwin/winconfig.c +++ b/xorg-server/hw/xwin/winconfig.c @@ -1,1064 +1,1051 @@ -/* - *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: Alexander Gottwald - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" -#include "winconfig.h" -#include "winmsg.h" -#include "globals.h" - -#include "xkbsrv.h" - -#ifdef XWIN_XF86CONFIG -#ifndef CONFIGPATH -#define CONFIGPATH "%A," "%R," \ - "/etc/X11/%R," "%P/etc/X11/%R," \ - "%E," "%F," \ - "/etc/X11/%F," "%P/etc/X11/%F," \ - "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \ - "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \ - "%P/etc/X11/%X," \ - "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \ - "%P/lib/X11/%X" -#endif -#ifndef CONFIGDIRPATH -#define CONFIGDIRPATH "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \ - "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \ - "%P/etc/X11/%X," \ - "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \ - "%P/lib/X11/%X" -#endif - -XF86ConfigPtr g_xf86configptr = NULL; -#endif - -WinCmdlineRec g_cmdline = { -#ifdef XWIN_XF86CONFIG - NULL, /* configFile */ - NULL, /* configDir */ -#endif - NULL, /* fontPath */ -#ifdef XWIN_XF86CONFIG - NULL, /* keyboard */ -#endif - NULL, /* xkbRules */ - NULL, /* xkbModel */ - NULL, /* xkbLayout */ - NULL, /* xkbVariant */ - NULL, /* xkbOptions */ - NULL, /* screenname */ - NULL, /* mousename */ - FALSE, /* emulate3Buttons */ - 0 /* emulate3Timeout */ -}; - -winInfoRec g_winInfo = { - { /* keyboard */ - 0, /* leds */ - 500, /* delay */ - 30 /* rate */ - } - , - { /* xkb */ - NULL, /* rules */ - NULL, /* model */ - NULL, /* layout */ - NULL, /* variant */ - NULL, /* options */ - } - , - { - FALSE, - 50} -}; - -#define NULL_IF_EMPTY(x) (winNameCompare(x,"")?x:NULL) - -#ifdef XWIN_XF86CONFIG -serverLayoutRec g_winConfigLayout; - -static Bool ParseOptionValue (int scrnIndex, pointer options, - OptionInfoPtr p); -static Bool configLayout (serverLayoutPtr, XF86ConfLayoutPtr, char *); -static Bool configImpliedLayout (serverLayoutPtr, XF86ConfScreenPtr); -static Bool GetBoolValue (OptionInfoPtr p, const char *s); - - -Bool -winReadConfigfile () -{ - Bool retval = TRUE; - const char *filename, *dirname; - MessageType filefrom = X_DEFAULT; - MessageType dirfrom = X_DEFAULT; - char *xf86ConfigFile = NULL; - char *xf86ConfigDir = NULL; - - if (g_cmdline.configFile) - { - filefrom = X_CMDLINE; - xf86ConfigFile = g_cmdline.configFile; - } - if (g_cmdline.configDir) - { - dirfrom = X_CMDLINE; - xf86ConfigDir = g_cmdline.configDir; - } - - /* Parse config file into data structure */ - xf86initConfigFiles(); - dirname = xf86openConfigDirFiles (CONFIGDIRPATH, xf86ConfigDir, PROJECTROOT); - filename = xf86openConfigFile (CONFIGPATH, xf86ConfigFile, PROJECTROOT); - - /* Hack for backward compatibility */ - if (!filename && from == X_DEFAULT) - filename = xf86openConfigFile (CONFIGPATH, "XF86Config", PROJECTROOT); - - if (filename) - { - winMsg (from, "Using config file: \"%s\"\n", filename); - } - else - { - winMsg (X_ERROR, "Unable to locate/open config file"); - if (xf86ConfigFile) - ErrorF (": \"%s\"", xf86ConfigFile); - ErrorF ("\n"); - } - if (dirname) - { - winMsg (from, "Using config directory: \"%s\"\n", dirname); - } - else - { - winMsg (X_ERROR, "Unable to locate/open config directory"); - if (xf86ConfigDir) - ErrorF (": \"%s\"", xf86ConfigDir); - ErrorF ("\n"); - } - if (!filename && !dirname) - { - return FALSE; - } - if ((g_xf86configptr = xf86readConfigFile ()) == NULL) - { - winMsg (X_ERROR, "Problem parsing the config file\n"); - return FALSE; - } - xf86closeConfigFile (); - - LogPrintMarkers(); - - /* set options from data structure */ - - if (g_xf86configptr->conf_layout_lst == NULL || g_cmdline.screenname != NULL) - { - if (g_cmdline.screenname == NULL) - { - winMsg (X_WARNING, - "No Layout section. Using the first Screen section.\n"); - } - if (!configImpliedLayout (&g_winConfigLayout, - g_xf86configptr->conf_screen_lst)) - { - winMsg (X_ERROR, "Unable to determine the screen layout\n"); - return FALSE; - } - } - else - { - /* Check if layout is given in the config file */ - if (g_xf86configptr->conf_flags != NULL) - { - char *dfltlayout = NULL; - pointer optlist = g_xf86configptr->conf_flags->flg_option_lst; - - if (optlist && winFindOption (optlist, "defaultserverlayout")) - dfltlayout = - winSetStrOption (optlist, "defaultserverlayout", NULL); - - if (!configLayout (&g_winConfigLayout, - g_xf86configptr->conf_layout_lst, - dfltlayout)) - { - winMsg (X_ERROR, "Unable to determine the screen layout\n"); - return FALSE; - } - } - else - { - if (!configLayout (&g_winConfigLayout, - g_xf86configptr->conf_layout_lst, - NULL)) - { - winMsg (X_ERROR, "Unable to determine the screen layout\n"); - return FALSE; - } - } - } - - /* setup special config files */ - winConfigFiles (); - return retval; -} -#endif - -/* load layout definitions */ -#include "winlayouts.h" - -/* Set the keyboard configuration */ -Bool -winConfigKeyboard (DeviceIntPtr pDevice) -{ - char layoutName[KL_NAMELENGTH]; - static unsigned int layoutNum = 0; - int keyboardType; -#ifdef XWIN_XF86CONFIG - XF86ConfInputPtr kbd = NULL; - XF86ConfInputPtr input_list = NULL; - MessageType kbdfrom = X_CONFIG; -#endif - MessageType from = X_DEFAULT; - char *s = NULL; - - /* Setup defaults */ - XkbGetRulesDflts(&g_winInfo.xkb); - - /* - * Query the windows autorepeat settings and change the xserver defaults. - */ - { - int kbd_delay; - DWORD kbd_speed; - if (SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &kbd_delay, 0) && - SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &kbd_speed, 0)) - { - switch (kbd_delay) - { - case 0: g_winInfo.keyboard.delay = 250; break; - case 1: g_winInfo.keyboard.delay = 500; break; - case 2: g_winInfo.keyboard.delay = 750; break; - default: - case 3: g_winInfo.keyboard.delay = 1000; break; - } - g_winInfo.keyboard.rate = (kbd_speed>0)?kbd_speed:1; - winMsgVerb(X_PROBED, 1, "Setting autorepeat to delay=%d, rate=%d\n", - g_winInfo.keyboard.delay, g_winInfo.keyboard.rate); - } - } - - - keyboardType = GetKeyboardType (0); - if (keyboardType > 0 && GetKeyboardLayoutName (layoutName)) - { - WinKBLayoutPtr pLayout; - Bool bfound = FALSE; - - if (! layoutNum) - layoutNum = strtoul (layoutName, (char **)NULL, 16); - if ((layoutNum & 0xffff) == 0x411) { - /* The japanese layouts know a lot of different IMEs which all have - different layout numbers set. Map them to a single entry. - Same might apply for chinese, korean and other symbol languages - too */ - layoutNum = (layoutNum & 0xffff); - if (keyboardType == 7) - { - /* Japanese layouts have problems with key event messages - such as the lack of WM_KEYUP for Caps Lock key. - Loading US layout fixes this problem. */ - if (LoadKeyboardLayout("00000409", KLF_ACTIVATE) != NULL) - winMsg (X_INFO, "Loading US keyboard layout.\n"); - else - winMsg (X_ERROR, "LoadKeyboardLaout failed.\n"); - } - } - winMsg (X_PROBED, "winConfigKeyboard - Layout: \"%s\" (%08x) \n", - layoutName, layoutNum); - - for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++) - { - if (pLayout->winlayout != layoutNum) - continue; - if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType) - continue; - - bfound = TRUE; - winMsg (X_PROBED, - "Using preset keyboard for \"%s\" (%x), type \"%d\"\n", - pLayout->layoutname, pLayout->winlayout, keyboardType); - - g_winInfo.xkb.model = pLayout->xkbmodel; - g_winInfo.xkb.layout = pLayout->xkblayout; - g_winInfo.xkb.variant = pLayout->xkbvariant; - g_winInfo.xkb.options = pLayout->xkboptions; - break; - } - - if (!bfound) - { - HKEY regkey = NULL; - const char regtempl[] = - "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\"; - char *regpath; - char lname[256]; - DWORD namesize = sizeof(lname); - - regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1); - strcpy(regpath, regtempl); - strcat(regpath, layoutName); - - if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, ®key) && - !RegQueryValueEx(regkey, "Layout Text", 0, NULL, lname, &namesize)) - { - winMsg (X_ERROR, - "Keyboardlayout \"%s\" (%s) is unknown\n", lname, layoutName); - } - - /* Close registry key */ - if (regkey) - RegCloseKey (regkey); - free(regpath); - } - } - - /* parse the configuration */ -#ifdef XWIN_XF86CONFIG - if (g_cmdline.keyboard) - kbdfrom = X_CMDLINE; - - /* - * Until the layout code is finished, I search for the keyboard - * device and configure the server with it. - */ - - if (g_xf86configptr != NULL) - input_list = g_xf86configptr->conf_input_lst; - - while (input_list != NULL) - { - if (winNameCompare (input_list->inp_driver, "keyboard") == 0) - { - /* Check if device name matches requested name */ - if (g_cmdline.keyboard && winNameCompare (input_list->inp_identifier, - g_cmdline.keyboard)) - continue; - kbd = input_list; - } - input_list = input_list->list.next; - } - - if (kbd != NULL) - { - - if (kbd->inp_identifier) - winMsg (kbdfrom, "Using keyboard \"%s\" as primary keyboard\n", - kbd->inp_identifier); - - if ((s = winSetStrOption(kbd->inp_option_lst, "AutoRepeat", NULL))) - { - if ((sscanf(s, "%ld %ld", &g_winInfo.keyboard.delay, - &g_winInfo.keyboard.rate) != 2) || - (g_winInfo.keyboard.delay < 1) || - (g_winInfo.keyboard.rate == 0) || - (1000 / g_winInfo.keyboard.rate) < 1) - { - winErrorFVerb (2, "\"%s\" is not a valid AutoRepeat value", s); - xfree(s); - return FALSE; - } - xfree(s); - winMsg (X_CONFIG, "AutoRepeat: %ld %ld\n", - g_winInfo.keyboard.delay, g_winInfo.keyboard.rate); - } -#endif - - s = NULL; - if (g_cmdline.xkbRules) - { - s = g_cmdline.xkbRules; - from = X_CMDLINE; - } -#ifdef XWIN_XF86CONFIG - else - { - s = winSetStrOption (kbd->inp_option_lst, "XkbRules", NULL); - from = X_CONFIG; - } -#endif - if (s) - { - g_winInfo.xkb.rules = NULL_IF_EMPTY (s); - winMsg (from, "XKB: rules: \"%s\"\n", s); - } - - s = NULL; - if (g_cmdline.xkbModel) - { - s = g_cmdline.xkbModel; - from = X_CMDLINE; - } -#ifdef XWIN_XF86CONFIG - else - { - s = winSetStrOption (kbd->inp_option_lst, "XkbModel", NULL); - from = X_CONFIG; - } -#endif - if (s) - { - g_winInfo.xkb.model = NULL_IF_EMPTY (s); - winMsg (from, "XKB: model: \"%s\"\n", s); - } - - s = NULL; - if (g_cmdline.xkbLayout) - { - s = g_cmdline.xkbLayout; - from = X_CMDLINE; - } -#ifdef XWIN_XF86CONFIG - else - { - s = winSetStrOption (kbd->inp_option_lst, "XkbLayout", NULL); - from = X_CONFIG; - } -#endif - if (s) - { - g_winInfo.xkb.layout = NULL_IF_EMPTY (s); - winMsg (from, "XKB: layout: \"%s\"\n", s); - } - - s = NULL; - if (g_cmdline.xkbVariant) - { - s = g_cmdline.xkbVariant; - from = X_CMDLINE; - } -#ifdef XWIN_XF86CONFIG - else - { - s = winSetStrOption (kbd->inp_option_lst, "XkbVariant", NULL); - from = X_CONFIG; - } -#endif - if (s) - { - g_winInfo.xkb.variant = NULL_IF_EMPTY (s); - winMsg (from, "XKB: variant: \"%s\"\n", s); - } - - s = NULL; - if (g_cmdline.xkbOptions) - { - s = g_cmdline.xkbOptions; - from = X_CMDLINE; - } -#ifdef XWIN_XF86CONFIG - else - { - s = winSetStrOption (kbd->inp_option_lst, "XkbOptions", NULL); - from = X_CONFIG; - } -#endif - if (s) - { - g_winInfo.xkb.options = NULL_IF_EMPTY (s); - winMsg (from, "XKB: options: \"%s\"\n", s); - } - -#ifdef XWIN_XF86CONFIG - } -#endif - - return TRUE; -} - - -#ifdef XWIN_XF86CONFIG -Bool -winConfigMouse (DeviceIntPtr pDevice) -{ - MessageType mousefrom = X_CONFIG; - - XF86ConfInputPtr mouse = NULL; - XF86ConfInputPtr input_list = NULL; - - if (g_cmdline.mouse) - mousefrom = X_CMDLINE; - - if (g_xf86configptr != NULL) - input_list = g_xf86configptr->conf_input_lst; - - while (input_list != NULL) - { - if (winNameCompare (input_list->inp_driver, "mouse") == 0) - { - /* Check if device name matches requested name */ - if (g_cmdline.mouse && winNameCompare (input_list->inp_identifier, - g_cmdline.mouse)) - continue; - mouse = input_list; - } - input_list = input_list->list.next; - } - - if (mouse != NULL) - { - if (mouse->inp_identifier) - winMsg (mousefrom, "Using pointer \"%s\" as primary pointer\n", - mouse->inp_identifier); - - g_winInfo.pointer.emulate3Buttons = - winSetBoolOption (mouse->inp_option_lst, "Emulate3Buttons", FALSE); - if (g_cmdline.emulate3buttons) - g_winInfo.pointer.emulate3Buttons = g_cmdline.emulate3buttons; - - g_winInfo.pointer.emulate3Timeout = - winSetIntOption (mouse->inp_option_lst, "Emulate3Timeout", 50); - if (g_cmdline.emulate3timeout) - g_winInfo.pointer.emulate3Timeout = g_cmdline.emulate3timeout; - } - else - { - winMsg (X_ERROR, "No primary pointer configured\n"); - winMsg (X_DEFAULT, "Using compiletime defaults for pointer\n"); - } - - return TRUE; -} - - -Bool -winConfigFiles () -{ - MessageType from; - XF86ConfFilesPtr filesptr = NULL; - - /* set some shortcuts */ - if (g_xf86configptr != NULL) - { - filesptr = g_xf86configptr->conf_files; - } - - - /* Fontpath */ - from = X_DEFAULT; - - if (g_cmdline.fontPath) - { - from = X_CMDLINE; - defaultFontPath = g_cmdline.fontPath; - } - else if (filesptr != NULL && filesptr->file_fontpath) - { - from = X_CONFIG; - defaultFontPath = xstrdup (filesptr->file_fontpath); - } - winMsg (from, "FontPath set to \"%s\"\n", defaultFontPath); - - return TRUE; -} -#else -Bool -winConfigFiles (void) -{ - /* Fontpath */ - if (g_cmdline.fontPath) - { - defaultFontPath = g_cmdline.fontPath; - winMsg (X_CMDLINE, "FontPath set to \"%s\"\n", defaultFontPath); - } - - return TRUE; -} -#endif - - -Bool -winConfigOptions (void) -{ - return TRUE; -} - - -Bool -winConfigScreens (void) -{ - return TRUE; -} - - -#ifdef XWIN_XF86CONFIG -char * -winSetStrOption (pointer optlist, const char *name, char *deflt) -{ - OptionInfoRec o; - - o.name = name; - o.type = OPTV_STRING; - if (ParseOptionValue (-1, optlist, &o)) - deflt = o.value.str; - if (deflt) - return xstrdup (deflt); - else - return NULL; -} - - -int -winSetBoolOption (pointer optlist, const char *name, int deflt) -{ - OptionInfoRec o; - - o.name = name; - o.type = OPTV_BOOLEAN; - if (ParseOptionValue (-1, optlist, &o)) - deflt = o.value.bool; - return deflt; -} - - -int -winSetIntOption (pointer optlist, const char *name, int deflt) -{ - OptionInfoRec o; - - o.name = name; - o.type = OPTV_INTEGER; - if (ParseOptionValue (-1, optlist, &o)) - deflt = o.value.num; - return deflt; -} - - -double -winSetRealOption (pointer optlist, const char *name, double deflt) -{ - OptionInfoRec o; - - o.name = name; - o.type = OPTV_REAL; - if (ParseOptionValue (-1, optlist, &o)) - deflt = o.value.realnum; - return deflt; -} -#endif - - -/* - * Compare two strings for equality. This is caseinsensitive and - * The characters '_', ' ' (space) and '\t' (tab) are treated as - * not existing. - */ - -int -winNameCompare (const char *s1, const char *s2) -{ - char c1, c2; - - if (!s1 || *s1 == 0) - { - if (!s2 || *s2 == 0) - return 0; - else - return 1; - } - - while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') - s1++; - while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') - s2++; - - c1 = (isupper (*s1) ? tolower (*s1) : *s1); - c2 = (isupper (*s2) ? tolower (*s2) : *s2); - - while (c1 == c2) - { - if (c1 == 0) - return 0; - s1++; - s2++; - - while (*s1 == '_' || *s1 == ' ' || *s1 == '\t') - s1++; - while (*s2 == '_' || *s2 == ' ' || *s2 == '\t') - s2++; - - c1 = (isupper (*s1) ? tolower (*s1) : *s1); - c2 = (isupper (*s2) ? tolower (*s2) : *s2); - } - return (c1 - c2); -} - - -#ifdef XWIN_XF86CONFIG -/* - * Find the named option in the list. - * @return the pointer to the option record, or NULL if not found. - */ - -XF86OptionPtr -winFindOption (XF86OptionPtr list, const char *name) -{ - while (list) - { - if (winNameCompare (list->opt_name, name) == 0) - return list; - list = list->list.next; - } - return NULL; -} - - -/* - * Find the Value of an named option. - * @return The option value or NULL if not found. - */ - -char * -winFindOptionValue (XF86OptionPtr list, const char *name) -{ - list = winFindOption (list, name); - if (list) - { - if (list->opt_val) - return (list->opt_val); - else - return ""; - } - return (NULL); -} - - -/* - * Parse the option. - */ - -static Bool -ParseOptionValue (int scrnIndex, pointer options, OptionInfoPtr p) -{ - char *s, *end; - - if ((s = winFindOptionValue (options, p->name)) != NULL) - { - switch (p->type) - { - case OPTV_INTEGER: - if (*s == '\0') - { - winDrvMsg (scrnIndex, X_WARNING, - "Option \"%s\" requires an integer value\n", - p->name); - p->found = FALSE; - } - else - { - p->value.num = strtoul (s, &end, 0); - if (*end == '\0') - { - p->found = TRUE; - } - else - { - winDrvMsg (scrnIndex, X_WARNING, - "Option \"%s\" requires an integer value\n", - p->name); - p->found = FALSE; - } - } - break; - case OPTV_STRING: - if (*s == '\0') - { - winDrvMsg (scrnIndex, X_WARNING, - "Option \"%s\" requires an string value\n", p->name); - p->found = FALSE; - } - else - { - p->value.str = s; - p->found = TRUE; - } - break; - case OPTV_ANYSTR: - p->value.str = s; - p->found = TRUE; - break; - case OPTV_REAL: - if (*s == '\0') - { - winDrvMsg (scrnIndex, X_WARNING, - "Option \"%s\" requires a floating point value\n", - p->name); - p->found = FALSE; - } - else - { - p->value.realnum = strtod (s, &end); - if (*end == '\0') - { - p->found = TRUE; - } - else - { - winDrvMsg (scrnIndex, X_WARNING, - "Option \"%s\" requires a floating point value\n", - p->name); - p->found = FALSE; - } - } - break; - case OPTV_BOOLEAN: - if (GetBoolValue (p, s)) - { - p->found = TRUE; - } - else - { - winDrvMsg (scrnIndex, X_WARNING, - "Option \"%s\" requires a boolean value\n", p->name); - p->found = FALSE; - } - break; - case OPTV_FREQ: - if (*s == '\0') - { - winDrvMsg (scrnIndex, X_WARNING, - "Option \"%s\" requires a frequency value\n", - p->name); - p->found = FALSE; - } - else - { - double freq = strtod (s, &end); - int units = 0; - - if (end != s) - { - p->found = TRUE; - if (!winNameCompare (end, "Hz")) - units = 1; - else if (!winNameCompare (end, "kHz") || - !winNameCompare (end, "k")) - units = 1000; - else if (!winNameCompare (end, "MHz") || - !winNameCompare (end, "M")) - units = 1000000; - else - { - winDrvMsg (scrnIndex, X_WARNING, - "Option \"%s\" requires a frequency value\n", - p->name); - p->found = FALSE; - } - if (p->found) - freq *= (double) units; - } - else - { - winDrvMsg (scrnIndex, X_WARNING, - "Option \"%s\" requires a frequency value\n", - p->name); - p->found = FALSE; - } - if (p->found) - { - p->value.freq.freq = freq; - p->value.freq.units = units; - } - } - break; - case OPTV_NONE: - /* Should never get here */ - p->found = FALSE; - break; - } - if (p->found) - { - winDrvMsgVerb (scrnIndex, X_CONFIG, 2, "Option \"%s\"", p->name); - if (!(p->type == OPTV_BOOLEAN && *s == 0)) - { - winErrorFVerb (2, " \"%s\"", s); - } - winErrorFVerb (2, "\n"); - } - } - else if (p->type == OPTV_BOOLEAN) - { - /* Look for matches with options with or without a "No" prefix. */ - char *n, *newn; - OptionInfoRec opt; - - n = winNormalizeName (p->name); - if (!n) - { - p->found = FALSE; - return FALSE; - } - if (strncmp (n, "no", 2) == 0) - { - newn = n + 2; - } - else - { - free (n); - n = malloc (strlen (p->name) + 2 + 1); - if (!n) - { - p->found = FALSE; - return FALSE; - } - strcpy (n, "No"); - strcat (n, p->name); - newn = n; - } - if ((s = winFindOptionValue (options, newn)) != NULL) - { - if (GetBoolValue (&opt, s)) - { - p->value.bool = !opt.value.bool; - p->found = TRUE; - } - else - { - winDrvMsg (scrnIndex, X_WARNING, - "Option \"%s\" requires a boolean value\n", newn); - p->found = FALSE; - } - } - else - { - p->found = FALSE; - } - if (p->found) - { - winDrvMsgVerb (scrnIndex, X_CONFIG, 2, "Option \"%s\"", newn); - if (*s != 0) - { - winErrorFVerb (2, " \"%s\"", s); - } - winErrorFVerb (2, "\n"); - } - free (n); - } - else - { - p->found = FALSE; - } - return p->found; -} - - -static Bool -configLayout (serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout, - char *default_layout) -{ -#if 0 -#pragma warn UNIMPLEMENTED -#endif - return TRUE; -} - - -static Bool -configImpliedLayout (serverLayoutPtr servlayoutp, - XF86ConfScreenPtr conf_screen) -{ -#if 0 -#pragma warn UNIMPLEMENTED -#endif - return TRUE; -} - - -static Bool -GetBoolValue (OptionInfoPtr p, const char *s) -{ - if (*s == 0) - { - p->value.bool = TRUE; - } - else - { - if (winNameCompare (s, "1") == 0) - p->value.bool = TRUE; - else if (winNameCompare (s, "on") == 0) - p->value.bool = TRUE; - else if (winNameCompare (s, "true") == 0) - p->value.bool = TRUE; - else if (winNameCompare (s, "yes") == 0) - p->value.bool = TRUE; - else if (winNameCompare (s, "0") == 0) - p->value.bool = FALSE; - else if (winNameCompare (s, "off") == 0) - p->value.bool = FALSE; - else if (winNameCompare (s, "false") == 0) - p->value.bool = FALSE; - else if (winNameCompare (s, "no") == 0) - p->value.bool = FALSE; - } - return TRUE; -} -#endif - - -char * -winNormalizeName (const char *s) -{ - char *ret, *q; - const char *p; - - if (s == NULL) - return NULL; - - ret = malloc (strlen (s) + 1); - for (p = s, q = ret; *p != 0; p++) - { - switch (*p) - { - case '_': - case ' ': - case '\t': - continue; - default: - if (isupper (*p)) - *q++ = tolower (*p); - else - *q++ = *p; - } - } - *q = '\0'; - return ret; -} - +/*
+ *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: Alexander Gottwald
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include "winconfig.h"
+#include "winmsg.h"
+#include "globals.h"
+
+#include "xkbsrv.h"
+
+#ifdef XWIN_XF86CONFIG
+#ifndef CONFIGPATH
+#define CONFIGPATH "%A," "%R," \
+ "/etc/X11/%R," "%P/etc/X11/%R," \
+ "%E," "%F," \
+ "/etc/X11/%F," "%P/etc/X11/%F," \
+ "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \
+ "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
+ "%P/etc/X11/%X," \
+ "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
+ "%P/lib/X11/%X"
+#endif
+#ifndef CONFIGDIRPATH
+#define CONFIGDIRPATH "/etc/X11/%X-%M," "/etc/X11/%X," "/etc/%X," \
+ "%P/etc/X11/%X.%H," "%P/etc/X11/%X-%M," \
+ "%P/etc/X11/%X," \
+ "%P/lib/X11/%X.%H," "%P/lib/X11/%X-%M," \
+ "%P/lib/X11/%X"
+#endif
+
+XF86ConfigPtr g_xf86configptr = NULL;
+#endif
+
+WinCmdlineRec g_cmdline = {
+#ifdef XWIN_XF86CONFIG
+ NULL, /* configFile */
+ NULL, /* configDir */
+#endif
+ NULL, /* fontPath */
+#ifdef XWIN_XF86CONFIG
+ NULL, /* keyboard */
+#endif
+ NULL, /* xkbRules */
+ NULL, /* xkbModel */
+ NULL, /* xkbLayout */
+ NULL, /* xkbVariant */
+ NULL, /* xkbOptions */
+ NULL, /* screenname */
+ NULL, /* mousename */
+ FALSE, /* emulate3Buttons */
+ 0 /* emulate3Timeout */
+};
+
+winInfoRec g_winInfo = {
+ { /* keyboard */
+ 0, /* leds */
+ 500, /* delay */
+ 30 /* rate */
+ }
+ ,
+ { /* xkb */
+ NULL, /* rules */
+ NULL, /* model */
+ NULL, /* layout */
+ NULL, /* variant */
+ NULL, /* options */
+ }
+ ,
+ {
+ FALSE,
+ 50}
+};
+
+#define NULL_IF_EMPTY(x) (winNameCompare(x,"")?x:NULL)
+
+#ifdef XWIN_XF86CONFIG
+serverLayoutRec g_winConfigLayout;
+
+static Bool ParseOptionValue (int scrnIndex, pointer options,
+ OptionInfoPtr p);
+static Bool configLayout (serverLayoutPtr, XF86ConfLayoutPtr, char *);
+static Bool configImpliedLayout (serverLayoutPtr, XF86ConfScreenPtr);
+static Bool GetBoolValue (OptionInfoPtr p, const char *s);
+
+
+Bool
+winReadConfigfile ()
+{
+ Bool retval = TRUE;
+ const char *filename, *dirname;
+ MessageType filefrom = X_DEFAULT;
+ MessageType dirfrom = X_DEFAULT;
+ char *xf86ConfigFile = NULL;
+ char *xf86ConfigDir = NULL;
+
+ if (g_cmdline.configFile)
+ {
+ filefrom = X_CMDLINE;
+ xf86ConfigFile = g_cmdline.configFile;
+ }
+ if (g_cmdline.configDir)
+ {
+ dirfrom = X_CMDLINE;
+ xf86ConfigDir = g_cmdline.configDir;
+ }
+
+ /* Parse config file into data structure */
+ xf86initConfigFiles();
+ dirname = xf86openConfigDirFiles (CONFIGDIRPATH, xf86ConfigDir, PROJECTROOT);
+ filename = xf86openConfigFile (CONFIGPATH, xf86ConfigFile, PROJECTROOT);
+
+ /* Hack for backward compatibility */
+ if (!filename && from == X_DEFAULT)
+ filename = xf86openConfigFile (CONFIGPATH, "XF86Config", PROJECTROOT);
+
+ if (filename)
+ {
+ winDebug ("Using config file: \"%s\"\n", filename);
+ }
+ else
+ {
+ ErrorF ("Unable to locate/open config file");
+ if (xf86ConfigFile)
+ ErrorF (": \"%s\"", xf86ConfigFile);
+ ErrorF ("\n");
+ }
+ if (dirname)
+ {
+ winMsg (from, "Using config directory: \"%s\"\n", dirname);
+ }
+ else
+ {
+ winMsg (X_ERROR, "Unable to locate/open config directory");
+ if (xf86ConfigDir)
+ ErrorF (": \"%s\"", xf86ConfigDir);
+ ErrorF ("\n");
+ }
+ if (!filename && !dirname)
+ {
+ return FALSE;
+ }
+ if ((g_xf86configptr = xf86readConfigFile ()) == NULL)
+ {
+ ErrorF ("Problem parsing the config file\n");
+ return FALSE;
+ }
+ xf86closeConfigFile ();
+
+ LogPrintMarkers();
+
+ /* set options from data structure */
+
+ if (g_xf86configptr->conf_layout_lst == NULL || g_cmdline.screenname != NULL)
+ {
+ if (g_cmdline.screenname == NULL)
+ {
+ winDebug ("No Layout section. Using the first Screen section.\n");
+ }
+ if (!configImpliedLayout (&g_winConfigLayout,
+ g_xf86configptr->conf_screen_lst))
+ {
+ ErrorF ("Unable to determine the screen layout\n");
+ return FALSE;
+ }
+ }
+ else
+ {
+ /* Check if layout is given in the config file */
+ if (g_xf86configptr->conf_flags != NULL)
+ {
+ char *dfltlayout = NULL;
+ pointer optlist = g_xf86configptr->conf_flags->flg_option_lst;
+
+ if (optlist && winFindOption (optlist, "defaultserverlayout"))
+ dfltlayout =
+ winSetStrOption (optlist, "defaultserverlayout", NULL);
+
+ if (!configLayout (&g_winConfigLayout,
+ g_xf86configptr->conf_layout_lst,
+ dfltlayout))
+ {
+ ErrorF ("Unable to determine the screen layout\n");
+ return FALSE;
+ }
+ }
+ else
+ {
+ if (!configLayout (&g_winConfigLayout,
+ g_xf86configptr->conf_layout_lst,
+ NULL))
+ {
+ ErrorF ("Unable to determine the screen layout\n");
+ return FALSE;
+ }
+ }
+ }
+
+ /* setup special config files */
+ winConfigFiles ();
+ return retval;
+}
+#endif
+
+/* load layout definitions */
+#include "winlayouts.h"
+
+/* Set the keyboard configuration */
+Bool
+winConfigKeyboard (DeviceIntPtr pDevice)
+{
+ char layoutName[KL_NAMELENGTH];
+ static unsigned int layoutNum = 0;
+ int keyboardType;
+#ifdef XWIN_XF86CONFIG
+ XF86ConfInputPtr kbd = NULL;
+ XF86ConfInputPtr input_list = NULL;
+ MessageType kbdfrom = X_CONFIG;
+#endif
+ MessageType from = X_DEFAULT;
+ char *s = NULL;
+
+ /* Setup defaults */
+ XkbGetRulesDflts(&g_winInfo.xkb);
+
+ /*
+ * Query the windows autorepeat settings and change the xserver defaults.
+ */
+ {
+ int kbd_delay;
+ DWORD kbd_speed;
+ if (SystemParametersInfo(SPI_GETKEYBOARDDELAY, 0, &kbd_delay, 0) &&
+ SystemParametersInfo(SPI_GETKEYBOARDSPEED, 0, &kbd_speed, 0))
+ {
+ switch (kbd_delay)
+ {
+ case 0: g_winInfo.keyboard.delay = 250; break;
+ case 1: g_winInfo.keyboard.delay = 500; break;
+ case 2: g_winInfo.keyboard.delay = 750; break;
+ default:
+ case 3: g_winInfo.keyboard.delay = 1000; break;
+ }
+ g_winInfo.keyboard.rate = (kbd_speed>0)?kbd_speed:1;
+ winDebug("Setting autorepeat to delay=%d, rate=%d\n",
+ g_winInfo.keyboard.delay, g_winInfo.keyboard.rate);
+ }
+ }
+
+
+ keyboardType = GetKeyboardType (0);
+ if (keyboardType > 0 && GetKeyboardLayoutName (layoutName))
+ {
+ WinKBLayoutPtr pLayout;
+ Bool bfound = FALSE;
+
+ if (! layoutNum)
+ layoutNum = strtoul (layoutName, (char **)NULL, 16);
+ if ((layoutNum & 0xffff) == 0x411) {
+ /* The japanese layouts know a lot of different IMEs which all have
+ different layout numbers set. Map them to a single entry.
+ Same might apply for chinese, korean and other symbol languages
+ too */
+ layoutNum = (layoutNum & 0xffff);
+ if (keyboardType == 7)
+ {
+ /* Japanese layouts have problems with key event messages
+ such as the lack of WM_KEYUP for Caps Lock key.
+ Loading US layout fixes this problem. */
+ if (LoadKeyboardLayout("00000409", KLF_ACTIVATE) != NULL)
+ winDebug("Loading US keyboard layout.\n");
+ else
+ ErrorF ("LoadKeyboardLaout failed.\n");
+ }
+ }
+ winDebug ("winConfigKeyboard - Layout: \"%s\" (%08x) \n",
+ layoutName, layoutNum);
+
+ for (pLayout = winKBLayouts; pLayout->winlayout != -1; pLayout++)
+ {
+ if (pLayout->winlayout != layoutNum)
+ continue;
+ if (pLayout->winkbtype > 0 && pLayout->winkbtype != keyboardType)
+ continue;
+
+ bfound = TRUE;
+ winDebug ("Using preset keyboard for \"%s\" (%x), type \"%d\"\n",
+ pLayout->layoutname, pLayout->winlayout, keyboardType);
+
+ g_winInfo.xkb.model = pLayout->xkbmodel;
+ g_winInfo.xkb.layout = pLayout->xkblayout;
+ g_winInfo.xkb.variant = pLayout->xkbvariant;
+ g_winInfo.xkb.options = pLayout->xkboptions;
+ break;
+ }
+
+ if (!bfound)
+ {
+ HKEY regkey = NULL;
+ const char regtempl[] =
+ "SYSTEM\\CurrentControlSet\\Control\\Keyboard Layouts\\";
+ char *regpath;
+ char lname[256];
+ DWORD namesize = sizeof(lname);
+
+ regpath = malloc(sizeof(regtempl) + KL_NAMELENGTH + 1);
+ strcpy(regpath, regtempl);
+ strcat(regpath, layoutName);
+
+ if (!RegOpenKey(HKEY_LOCAL_MACHINE, regpath, ®key) &&
+ !RegQueryValueEx(regkey, "Layout Text", 0, NULL, lname, &namesize))
+ {
+ ErrorF ("Keyboardlayout \"%s\" (%s) is unknown\n", lname, layoutName);
+ }
+
+ /* Close registry key */
+ if (regkey)
+ RegCloseKey (regkey);
+ free(regpath);
+ }
+ }
+
+ /* parse the configuration */
+#ifdef XWIN_XF86CONFIG
+ if (g_cmdline.keyboard)
+ kbdfrom = X_CMDLINE;
+
+ /*
+ * Until the layout code is finished, I search for the keyboard
+ * device and configure the server with it.
+ */
+
+ if (g_xf86configptr != NULL)
+ input_list = g_xf86configptr->conf_input_lst;
+
+ while (input_list != NULL)
+ {
+ if (winNameCompare (input_list->inp_driver, "keyboard") == 0)
+ {
+ /* Check if device name matches requested name */
+ if (g_cmdline.keyboard && winNameCompare (input_list->inp_identifier,
+ g_cmdline.keyboard))
+ continue;
+ kbd = input_list;
+ }
+ input_list = input_list->list.next;
+ }
+
+ if (kbd != NULL)
+ {
+
+ if (kbd->inp_identifier)
+ winDebug ("Using keyboard \"%s\" as primary keyboard\n",
+ kbd->inp_identifier);
+
+ if ((s = winSetStrOption(kbd->inp_option_lst, "AutoRepeat", NULL)))
+ {
+ if ((sscanf(s, "%ld %ld", &g_winInfo.keyboard.delay,
+ &g_winInfo.keyboard.rate) != 2) ||
+ (g_winInfo.keyboard.delay < 1) ||
+ (g_winInfo.keyboard.rate == 0) ||
+ (1000 / g_winInfo.keyboard.rate) < 1)
+ {
+ ErrorF ("\"%s\" is not a valid AutoRepeat value", s);
+ xfree(s);
+ return FALSE;
+ }
+ xfree(s);
+ winDebug ("AutoRepeat: %ld %ld\n",
+ g_winInfo.keyboard.delay, g_winInfo.keyboard.rate);
+ }
+#endif
+
+ s = NULL;
+ if (g_cmdline.xkbRules)
+ {
+ s = g_cmdline.xkbRules;
+ from = X_CMDLINE;
+ }
+#ifdef XWIN_XF86CONFIG
+ else
+ {
+ s = winSetStrOption (kbd->inp_option_lst, "XkbRules", NULL);
+ from = X_CONFIG;
+ }
+#endif
+ if (s)
+ {
+ g_winInfo.xkb.rules = NULL_IF_EMPTY (s);
+ winDebug ("XKB: rules: \"%s\"\n", s);
+ }
+
+ s = NULL;
+ if (g_cmdline.xkbModel)
+ {
+ s = g_cmdline.xkbModel;
+ from = X_CMDLINE;
+ }
+#ifdef XWIN_XF86CONFIG
+ else
+ {
+ s = winSetStrOption (kbd->inp_option_lst, "XkbModel", NULL);
+ from = X_CONFIG;
+ }
+#endif
+ if (s)
+ {
+ g_winInfo.xkb.model = NULL_IF_EMPTY (s);
+ winDebug ("XKB: model: \"%s\"\n", s);
+ }
+
+ s = NULL;
+ if (g_cmdline.xkbLayout)
+ {
+ s = g_cmdline.xkbLayout;
+ from = X_CMDLINE;
+ }
+#ifdef XWIN_XF86CONFIG
+ else
+ {
+ s = winSetStrOption (kbd->inp_option_lst, "XkbLayout", NULL);
+ from = X_CONFIG;
+ }
+#endif
+ if (s)
+ {
+ g_winInfo.xkb.layout = NULL_IF_EMPTY (s);
+ winDebug ("XKB: layout: \"%s\"\n", s);
+ }
+
+ s = NULL;
+ if (g_cmdline.xkbVariant)
+ {
+ s = g_cmdline.xkbVariant;
+ from = X_CMDLINE;
+ }
+#ifdef XWIN_XF86CONFIG
+ else
+ {
+ s = winSetStrOption (kbd->inp_option_lst, "XkbVariant", NULL);
+ from = X_CONFIG;
+ }
+#endif
+ if (s)
+ {
+ g_winInfo.xkb.variant = NULL_IF_EMPTY (s);
+ winDebug ("XKB: variant: \"%s\"\n", s);
+ }
+
+ s = NULL;
+ if (g_cmdline.xkbOptions)
+ {
+ s = g_cmdline.xkbOptions;
+ from = X_CMDLINE;
+ }
+#ifdef XWIN_XF86CONFIG
+ else
+ {
+ s = winSetStrOption (kbd->inp_option_lst, "XkbOptions", NULL);
+ from = X_CONFIG;
+ }
+#endif
+ if (s)
+ {
+ g_winInfo.xkb.options = NULL_IF_EMPTY (s);
+ winDebug ("XKB: options: \"%s\"\n", s);
+ }
+
+#ifdef XWIN_XF86CONFIG
+ }
+#endif
+
+ return TRUE;
+}
+
+
+#ifdef XWIN_XF86CONFIG
+Bool
+winConfigMouse (DeviceIntPtr pDevice)
+{
+ MessageType mousefrom = X_CONFIG;
+
+ XF86ConfInputPtr mouse = NULL;
+ XF86ConfInputPtr input_list = NULL;
+
+ if (g_cmdline.mouse)
+ mousefrom = X_CMDLINE;
+
+ if (g_xf86configptr != NULL)
+ input_list = g_xf86configptr->conf_input_lst;
+
+ while (input_list != NULL)
+ {
+ if (winNameCompare (input_list->inp_driver, "mouse") == 0)
+ {
+ /* Check if device name matches requested name */
+ if (g_cmdline.mouse && winNameCompare (input_list->inp_identifier,
+ g_cmdline.mouse))
+ continue;
+ mouse = input_list;
+ }
+ input_list = input_list->list.next;
+ }
+
+ if (mouse != NULL)
+ {
+ if (mouse->inp_identifier)
+ winDebug ("Using pointer \"%s\" as primary pointer\n",
+ mouse->inp_identifier);
+
+ g_winInfo.pointer.emulate3Buttons =
+ winSetBoolOption (mouse->inp_option_lst, "Emulate3Buttons", FALSE);
+ if (g_cmdline.emulate3buttons)
+ g_winInfo.pointer.emulate3Buttons = g_cmdline.emulate3buttons;
+
+ g_winInfo.pointer.emulate3Timeout =
+ winSetIntOption (mouse->inp_option_lst, "Emulate3Timeout", 50);
+ if (g_cmdline.emulate3timeout)
+ g_winInfo.pointer.emulate3Timeout = g_cmdline.emulate3timeout;
+ }
+ else
+ {
+ winDebug ("No primary pointer configured\n");
+ winDebug ("Using compiletime defaults for pointer\n");
+ }
+
+ return TRUE;
+}
+
+
+Bool
+winConfigFiles ()
+{
+ MessageType from;
+ XF86ConfFilesPtr filesptr = NULL;
+
+ /* set some shortcuts */
+ if (g_xf86configptr != NULL)
+ {
+ filesptr = g_xf86configptr->conf_files;
+ }
+
+
+ /* Fontpath */
+ from = X_DEFAULT;
+
+ if (g_cmdline.fontPath)
+ {
+ from = X_CMDLINE;
+ defaultFontPath = g_cmdline.fontPath;
+ }
+ else if (filesptr != NULL && filesptr->file_fontpath)
+ {
+ from = X_CONFIG;
+ defaultFontPath = xstrdup (filesptr->file_fontpath);
+ }
+ winDebug ("FontPath set to \"%s\"\n", defaultFontPath);
+
+ return TRUE;
+}
+#else
+Bool
+winConfigFiles (void)
+{
+ /* Fontpath */
+ if (g_cmdline.fontPath)
+ {
+ defaultFontPath = g_cmdline.fontPath;
+ winDebug("FontPath set to \"%s\"\n", defaultFontPath);
+ }
+
+ return TRUE;
+}
+#endif
+
+
+Bool
+winConfigOptions (void)
+{
+ return TRUE;
+}
+
+
+Bool
+winConfigScreens (void)
+{
+ return TRUE;
+}
+
+
+#ifdef XWIN_XF86CONFIG
+char *
+winSetStrOption (pointer optlist, const char *name, char *deflt)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_STRING;
+ if (ParseOptionValue (-1, optlist, &o))
+ deflt = o.value.str;
+ if (deflt)
+ return xstrdup (deflt);
+ else
+ return NULL;
+}
+
+
+int
+winSetBoolOption (pointer optlist, const char *name, int deflt)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_BOOLEAN;
+ if (ParseOptionValue (-1, optlist, &o))
+ deflt = o.value.bool;
+ return deflt;
+}
+
+
+int
+winSetIntOption (pointer optlist, const char *name, int deflt)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_INTEGER;
+ if (ParseOptionValue (-1, optlist, &o))
+ deflt = o.value.num;
+ return deflt;
+}
+
+
+double
+winSetRealOption (pointer optlist, const char *name, double deflt)
+{
+ OptionInfoRec o;
+
+ o.name = name;
+ o.type = OPTV_REAL;
+ if (ParseOptionValue (-1, optlist, &o))
+ deflt = o.value.realnum;
+ return deflt;
+}
+#endif
+
+
+/*
+ * Compare two strings for equality. This is caseinsensitive and
+ * The characters '_', ' ' (space) and '\t' (tab) are treated as
+ * not existing.
+ */
+
+int
+winNameCompare (const char *s1, const char *s2)
+{
+ char c1, c2;
+
+ if (!s1 || *s1 == 0)
+ {
+ if (!s2 || *s2 == 0)
+ return 0;
+ else
+ return 1;
+ }
+
+ while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
+ s1++;
+ while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
+ s2++;
+
+ c1 = (isupper (*s1) ? tolower (*s1) : *s1);
+ c2 = (isupper (*s2) ? tolower (*s2) : *s2);
+
+ while (c1 == c2)
+ {
+ if (c1 == 0)
+ return 0;
+ s1++;
+ s2++;
+
+ while (*s1 == '_' || *s1 == ' ' || *s1 == '\t')
+ s1++;
+ while (*s2 == '_' || *s2 == ' ' || *s2 == '\t')
+ s2++;
+
+ c1 = (isupper (*s1) ? tolower (*s1) : *s1);
+ c2 = (isupper (*s2) ? tolower (*s2) : *s2);
+ }
+ return (c1 - c2);
+}
+
+
+#ifdef XWIN_XF86CONFIG
+/*
+ * Find the named option in the list.
+ * @return the pointer to the option record, or NULL if not found.
+ */
+
+XF86OptionPtr
+winFindOption (XF86OptionPtr list, const char *name)
+{
+ while (list)
+ {
+ if (winNameCompare (list->opt_name, name) == 0)
+ return list;
+ list = list->list.next;
+ }
+ return NULL;
+}
+
+
+/*
+ * Find the Value of an named option.
+ * @return The option value or NULL if not found.
+ */
+
+char *
+winFindOptionValue (XF86OptionPtr list, const char *name)
+{
+ list = winFindOption (list, name);
+ if (list)
+ {
+ if (list->opt_val)
+ return (list->opt_val);
+ else
+ return "";
+ }
+ return (NULL);
+}
+
+
+/*
+ * Parse the option.
+ */
+
+static Bool
+ParseOptionValue (int scrnIndex, pointer options, OptionInfoPtr p)
+{
+ char *s, *end;
+
+ if ((s = winFindOptionValue (options, p->name)) != NULL)
+ {
+ switch (p->type)
+ {
+ case OPTV_INTEGER:
+ if (*s == '\0')
+ {
+ winDebug ( "Option \"%s\" requires an integer value\n",
+ p->name);
+ p->found = FALSE;
+ }
+ else
+ {
+ p->value.num = strtoul (s, &end, 0);
+ if (*end == '\0')
+ {
+ p->found = TRUE;
+ }
+ else
+ {
+ winDebug ( "Option \"%s\" requires an integer value\n",
+ p->name);
+ p->found = FALSE;
+ }
+ }
+ break;
+ case OPTV_STRING:
+ if (*s == '\0')
+ {
+ winDebug ( "Option \"%s\" requires an string value\n", p->name);
+ p->found = FALSE;
+ }
+ else
+ {
+ p->value.str = s;
+ p->found = TRUE;
+ }
+ break;
+ case OPTV_ANYSTR:
+ p->value.str = s;
+ p->found = TRUE;
+ break;
+ case OPTV_REAL:
+ if (*s == '\0')
+ {
+ winDebug ( "Option \"%s\" requires a floating point value\n",
+ p->name);
+ p->found = FALSE;
+ }
+ else
+ {
+ p->value.realnum = strtod (s, &end);
+ if (*end == '\0')
+ {
+ p->found = TRUE;
+ }
+ else
+ {
+ winDebug ( "Option \"%s\" requires a floating point value\n",
+ p->name);
+ p->found = FALSE;
+ }
+ }
+ break;
+ case OPTV_BOOLEAN:
+ if (GetBoolValue (p, s))
+ {
+ p->found = TRUE;
+ }
+ else
+ {
+ winDebug ( "Option \"%s\" requires a boolean value\n", p->name);
+ p->found = FALSE;
+ }
+ break;
+ case OPTV_FREQ:
+ if (*s == '\0')
+ {
+ winDebug ( "Option \"%s\" requires a frequency value\n",
+ p->name);
+ p->found = FALSE;
+ }
+ else
+ {
+ double freq = strtod (s, &end);
+ int units = 0;
+
+ if (end != s)
+ {
+ p->found = TRUE;
+ if (!winNameCompare (end, "Hz"))
+ units = 1;
+ else if (!winNameCompare (end, "kHz") ||
+ !winNameCompare (end, "k"))
+ units = 1000;
+ else if (!winNameCompare (end, "MHz") ||
+ !winNameCompare (end, "M"))
+ units = 1000000;
+ else
+ {
+ winDebug ( "Option \"%s\" requires a frequency value\n",
+ p->name);
+ p->found = FALSE;
+ }
+ if (p->found)
+ freq *= (double) units;
+ }
+ else
+ {
+ winDebug ( "Option \"%s\" requires a frequency value\n",
+ p->name);
+ p->found = FALSE;
+ }
+ if (p->found)
+ {
+ p->value.freq.freq = freq;
+ p->value.freq.units = units;
+ }
+ }
+ break;
+ case OPTV_NONE:
+ /* Should never get here */
+ p->found = FALSE;
+ break;
+ }
+ if (p->found)
+ {
+ winDebug ("Option \"%s\"", p->name);
+ if (!(p->type == OPTV_BOOLEAN && *s == 0))
+ {
+ winDebug (" \"%s\"", s);
+ }
+ winDebug ("\n");
+ }
+ }
+ else if (p->type == OPTV_BOOLEAN)
+ {
+ /* Look for matches with options with or without a "No" prefix. */
+ char *n, *newn;
+ OptionInfoRec opt;
+
+ n = winNormalizeName (p->name);
+ if (!n)
+ {
+ p->found = FALSE;
+ return FALSE;
+ }
+ if (strncmp (n, "no", 2) == 0)
+ {
+ newn = n + 2;
+ }
+ else
+ {
+ free (n);
+ n = malloc (strlen (p->name) + 2 + 1);
+ if (!n)
+ {
+ p->found = FALSE;
+ return FALSE;
+ }
+ strcpy (n, "No");
+ strcat (n, p->name);
+ newn = n;
+ }
+ if ((s = winFindOptionValue (options, newn)) != NULL)
+ {
+ if (GetBoolValue (&opt, s))
+ {
+ p->value.bool = !opt.value.bool;
+ p->found = TRUE;
+ }
+ else
+ {
+ winDebug ( "Option \"%s\" requires a boolean value\n", newn);
+ p->found = FALSE;
+ }
+ }
+ else
+ {
+ p->found = FALSE;
+ }
+ if (p->found)
+ {
+ winDebug ("Option \"%s\"", newn);
+ if (*s != 0)
+ {
+ winDebug (" \"%s\"", s);
+ }
+ winDebug ("\n");
+ }
+ free (n);
+ }
+ else
+ {
+ p->found = FALSE;
+ }
+ return p->found;
+}
+
+
+static Bool
+configLayout (serverLayoutPtr servlayoutp, XF86ConfLayoutPtr conf_layout,
+ char *default_layout)
+{
+#if 0
+#pragma warn UNIMPLEMENTED
+#endif
+ return TRUE;
+}
+
+
+static Bool
+configImpliedLayout (serverLayoutPtr servlayoutp,
+ XF86ConfScreenPtr conf_screen)
+{
+#if 0
+#pragma warn UNIMPLEMENTED
+#endif
+ return TRUE;
+}
+
+
+static Bool
+GetBoolValue (OptionInfoPtr p, const char *s)
+{
+ if (*s == 0)
+ {
+ p->value.bool = TRUE;
+ }
+ else
+ {
+ if (winNameCompare (s, "1") == 0)
+ p->value.bool = TRUE;
+ else if (winNameCompare (s, "on") == 0)
+ p->value.bool = TRUE;
+ else if (winNameCompare (s, "true") == 0)
+ p->value.bool = TRUE;
+ else if (winNameCompare (s, "yes") == 0)
+ p->value.bool = TRUE;
+ else if (winNameCompare (s, "0") == 0)
+ p->value.bool = FALSE;
+ else if (winNameCompare (s, "off") == 0)
+ p->value.bool = FALSE;
+ else if (winNameCompare (s, "false") == 0)
+ p->value.bool = FALSE;
+ else if (winNameCompare (s, "no") == 0)
+ p->value.bool = FALSE;
+ }
+ return TRUE;
+}
+#endif
+
+
+char *
+winNormalizeName (const char *s)
+{
+ char *ret, *q;
+ const char *p;
+
+ if (s == NULL)
+ return NULL;
+
+ ret = malloc (strlen (s) + 1);
+ for (p = s, q = ret; *p != 0; p++)
+ {
+ switch (*p)
+ {
+ case '_':
+ case ' ':
+ case '\t':
+ continue;
+ default:
+ if (isupper (*p))
+ *q++ = tolower (*p);
+ else
+ *q++ = *p;
+ }
+ }
+ *q = '\0';
+ return ret;
+}
+
diff --git a/xorg-server/hw/xwin/wincreatewnd.c b/xorg-server/hw/xwin/wincreatewnd.c index 0c342e1ae..b684922aa 100644 --- a/xorg-server/hw/xwin/wincreatewnd.c +++ b/xorg-server/hw/xwin/wincreatewnd.c @@ -66,9 +66,7 @@ winCreateBoundingWindowFullScreen (ScreenPtr pScreen) WNDCLASSEX wc; char szTitle[256]; -#if CYGDEBUG winDebug ("winCreateBoundingWindowFullScreen\n"); -#endif /* Setup our window class */ wc.cbSize=sizeof(WNDCLASSEX); @@ -95,13 +93,17 @@ winCreateBoundingWindowFullScreen (ScreenPtr pScreen) g_pszQueryHost, display, (int) pScreenInfo->dwScreen); - else + else + { + char HostName[256]; + gethostname(HostName,256); snprintf (szTitle, sizeof (szTitle), WINDOW_TITLE, + HostName, display, (int) pScreenInfo->dwScreen); - + } /* Create the window */ *phwnd = CreateWindowExA (0, /* Extended styles */ WINDOW_CLASS, /* Class name */ @@ -237,10 +239,8 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen) if (pScreenInfo->fUserGaveHeightAndWidth) { /* User gave a desired height and width, try to accomodate */ -#if CYGDEBUG winDebug ("winCreateBoundingWindowWindowed - User gave height " "and width\n"); -#endif /* Adjust the window width and height for borders and title bar */ if (pScreenInfo->fDecoration @@ -253,16 +253,12 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen) #endif ) { -#if CYGDEBUG winDebug ("winCreateBoundingWindowWindowed - Window has decoration\n"); -#endif /* Are we using scrollbars? */ if (pScreenInfo->fScrollbars) { -#if CYGDEBUG winDebug ("winCreateBoundingWindowWindowed - Window has " "scrollbars\n"); -#endif iWidth += 2 * GetSystemMetrics (SM_CXSIZEFRAME); iHeight += 2 * GetSystemMetrics (SM_CYSIZEFRAME) @@ -270,10 +266,8 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen) } else { -#if CYGDEBUG winDebug ("winCreateBoundingWindowWindowed - Window does not have " "scrollbars\n"); -#endif iWidth += 2 * GetSystemMetrics (SM_CXFIXEDFRAME); iHeight += 2 * GetSystemMetrics (SM_CYFIXEDFRAME) @@ -284,10 +278,8 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen) else { /* By default, we are creating a window that is as large as possible */ -#if CYGDEBUG winDebug ("winCreateBoundingWindowWindowed - User did not give " "height and width\n"); -#endif /* Defaults are wrong if we have multiple monitors */ if (pScreenInfo->fMultipleMonitors) { @@ -329,11 +321,9 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen) if (iHeight >= (rcWorkArea.bottom - rcWorkArea.top)) iHeight = rcWorkArea.bottom - rcWorkArea.top; -#if CYGDEBUG winDebug ("winCreateBoundingWindowWindowed - Adjusted width: %d "\ "height: %d\n", iWidth, iHeight); -#endif } /* Set display and screen-specific tooltip text */ @@ -344,12 +334,17 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen) g_pszQueryHost, display, (int) pScreenInfo->dwScreen); - else + else + { + char HostName[256]; + gethostname(HostName,256); snprintf (szTitle, sizeof (szTitle), WINDOW_TITLE, + HostName, display, (int) pScreenInfo->dwScreen); + } /* Create the window */ *phwnd = CreateWindowExA (0, /* Extended styles */ @@ -370,9 +365,7 @@ winCreateBoundingWindowWindowed (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug ("winCreateBoundingWindowWindowed - CreateWindowEx () returned\n"); -#endif if (fForceShowWindow) { diff --git a/xorg-server/hw/xwin/wincursor.c b/xorg-server/hw/xwin/wincursor.c index 7f1935a5d..a29e90c66 100644 --- a/xorg-server/hw/xwin/wincursor.c +++ b/xorg-server/hw/xwin/wincursor.c @@ -45,10 +45,9 @@ extern Bool g_fSoftwareCursor; #define BRIGHTNESS(x) (x##Red * 0.299 + x##Green * 0.587 + x##Blue * 0.114) -#if 0 -# define WIN_DEBUG_MSG winDebug -#else -# define WIN_DEBUG_MSG(...) +#ifdef _MSC_VER +#define min(a,b) (((a) < (b)) ? (a) : (b)) +#define max(a,b) (((a) > (b)) ? (a) : (b)) #endif /* @@ -87,7 +86,7 @@ winPointerWarpCursor (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y) /* Don't ignore subsequent warps */ s_fInitialWarp = FALSE; - winErrorFVerb (2, "winPointerWarpCursor - Discarding first warp: %d %d\n", + winDebug ("winPointerWarpCursor - Discarding first warp: %d %d\n", x, y); return; @@ -172,7 +171,7 @@ winLoadCursor (ScreenPtr pScreen, CursorPtr pCursor, int screen) BITMAPINFO *pbmi; unsigned long *lpBits; - WIN_DEBUG_MSG("winLoadCursor: Win32: %dx%d X11: %dx%d hotspot: %d,%d\n", + winDebug("winLoadCursor: Win32: %dx%d X11: %dx%d hotspot: %d,%d\n", pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy, pCursor->bits->width, pCursor->bits->height, pCursor->bits->xhot, pCursor->bits->yhot @@ -188,7 +187,7 @@ winLoadCursor (ScreenPtr pScreen, CursorPtr pCursor, int screen) if (pScreenPriv->cursor.sm_cx < pCursor->bits->width || pScreenPriv->cursor.sm_cy < pCursor->bits->height) { - winErrorFVerb (3, "winLoadCursor - Windows requires %dx%d cursor but X requires %dx%d\n", + ErrorF ("winLoadCursor - Windows requires %dx%d cursor but X requires %dx%d\n", pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy, pCursor->bits->width, pCursor->bits->height); } @@ -250,7 +249,7 @@ winLoadCursor (ScreenPtr pScreen, CursorPtr pCursor, int screen) /* We have a truecolor alpha-blended cursor and can use it! */ if (pCursor->bits->argb) { - WIN_DEBUG_MSG("winLoadCursor: Trying truecolor alphablended cursor\n"); + winDebug("winLoadCursor: Trying truecolor alphablended cursor\n"); memset (&bi, 0, sizeof (BITMAPV4HEADER)); bi.bV4Size = sizeof(BITMAPV4HEADER); bi.bV4Width = pScreenPriv->cursor.sm_cx; @@ -281,7 +280,7 @@ winLoadCursor (ScreenPtr pScreen, CursorPtr pCursor, int screen) if (!lpBits) { /* Bicolor, use a palettized DIB */ - WIN_DEBUG_MSG("winLoadCursor: Trying two color cursor\n"); + winDebug("winLoadCursor: Trying two color cursor\n"); pbmi = (BITMAPINFO*)&bi; memset (pbmi, 0, sizeof (BITMAPINFOHEADER)); pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER); @@ -345,7 +344,7 @@ winLoadCursor (ScreenPtr pScreen, CursorPtr pCursor, int screen) /* If one of the previous two methods gave us the bitmap we need, make a cursor */ if (lpBits) { - WIN_DEBUG_MSG("winLoadCursor: Creating bitmap cursor: hotspot %d,%d\n", + winDebug("winLoadCursor: Creating bitmap cursor: hotspot %d,%d\n", pCursor->bits->xhot, pCursor->bits->yhot); hAnd = NULL; @@ -373,14 +372,14 @@ winLoadCursor (ScreenPtr pScreen, CursorPtr pCursor, int screen) hCursor = (HCURSOR) CreateIconIndirect( &ii ); if (hCursor == NULL) - winW32Error(2, "winLoadCursor - CreateIconIndirect failed:"); + winW32Error("winLoadCursor - CreateIconIndirect failed:"); else { if (GetIconInfo(hCursor, &ii)) { if (ii.fIcon) { - WIN_DEBUG_MSG("winLoadCursor: CreateIconIndirect returned no cursor. Trying again.\n"); + winDebug("winLoadCursor: CreateIconIndirect returned no cursor. Trying again.\n"); DestroyCursor(hCursor); @@ -390,7 +389,7 @@ winLoadCursor (ScreenPtr pScreen, CursorPtr pCursor, int screen) hCursor = (HCURSOR) CreateIconIndirect( &ii ); if (hCursor == NULL) - winW32Error(2, "winLoadCursor - CreateIconIndirect failed:"); + winW32Error("winLoadCursor - CreateIconIndirect failed:"); } /* GetIconInfo creates new bitmaps. Destroy them again */ if (ii.hbmMask) @@ -416,7 +415,7 @@ winLoadCursor (ScreenPtr pScreen, CursorPtr pCursor, int screen) pScreenPriv->cursor.sm_cx, pScreenPriv->cursor.sm_cy, pAnd, pXor); if (hCursor == NULL) - winW32Error(2, "winLoadCursor - CreateCursor failed:"); + winW32Error("winLoadCursor - CreateCursor failed:"); } free (pAnd); free (pXor); @@ -471,7 +470,7 @@ winSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, in RECT rcClient; BOOL bInhibit; winScreenPriv(pScreen); - WIN_DEBUG_MSG("winSetCursor: cursor=%p\n", pCursor); + winDebug("winSetCursor: cursor=%p\n", pCursor); /* Inhibit changing the cursor if the mouse is not in a client area */ bInhibit = FALSE; @@ -522,7 +521,7 @@ winSetCursor (DeviceIntPtr pDev, ScreenPtr pScreen, CursorPtr pCursor, int x, in } pScreenPriv->cursor.handle = winLoadCursor (pScreen, pCursor, pScreen->myNum); - WIN_DEBUG_MSG("winSetCursor: handle=%p\n", pScreenPriv->cursor.handle); + winDebug("winSetCursor: handle=%p\n", pScreenPriv->cursor.handle); if (!bInhibit) SetCursor (pScreenPriv->cursor.handle); @@ -557,7 +556,7 @@ static void winDeviceCursorCleanup(DeviceIntPtr pDev, ScreenPtr pScr) { winScreenPriv(pScr); - return pScreenPriv->cursor.spriteFuncs->DeviceCursorCleanup(pDev, pScr); + pScreenPriv->cursor.spriteFuncs->DeviceCursorCleanup(pDev, pScr); } static miPointerSpriteFuncRec winSpriteFuncsRec = { @@ -616,9 +615,11 @@ winInitCursor (ScreenPtr pScreen) pPointPriv = (miPointerScreenPtr) dixLookupPrivate(&pScreen->devPrivates, miPointerScreenKey); + if (pPointPriv) + { pScreenPriv->cursor.spriteFuncs = pPointPriv->spriteFuncs; pPointPriv->spriteFuncs = &winSpriteFuncsRec; - + } pScreenPriv->cursor.handle = NULL; pScreenPriv->cursor.visible = FALSE; diff --git a/xorg-server/hw/xwin/windialogs.c b/xorg-server/hw/xwin/windialogs.c index a8153535f..adbec19cb 100644 --- a/xorg-server/hw/xwin/windialogs.c +++ b/xorg-server/hw/xwin/windialogs.c @@ -1,787 +1,781 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II 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 HAROLD L HUNT II 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 Harold L Hunt II - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from Harold L Hunt II. - * - * Authors: Harold L Hunt II - * Earle F. Philhower III - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" -#ifdef __CYGWIN__ -#include <sys/cygwin.h> -#endif -#include <shellapi.h> -#include "winprefs.h" - - -/* - * References to external globals - */ - -extern Bool g_fCursor; -extern HWND g_hDlgDepthChange; -extern HWND g_hDlgExit; -extern HWND g_hDlgAbout; -extern WINPREFS pref; -#ifdef XWIN_CLIPBOARD -extern Bool g_fClipboardStarted; -#endif -extern Bool g_fSoftwareCursor; - -#if defined(XWIN_MULTIWINDOW) -extern HICON g_hIconX; -extern HICON g_hSmallIconX; -#endif - -/* - * Local function prototypes - */ - -static wBOOL CALLBACK -winExitDlgProc (HWND hDialog, UINT message, - WPARAM wParam, LPARAM lParam); - -static wBOOL CALLBACK -winChangeDepthDlgProc (HWND hDialog, UINT message, - WPARAM wParam, LPARAM lParam); - -static wBOOL CALLBACK -winAboutDlgProc (HWND hDialog, UINT message, - WPARAM wParam, LPARAM lParam); - - -static void -winDrawURLWindow (LPARAM lParam); - -static LRESULT CALLBACK -winURLWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); - -static void -winOverrideURLButton (HWND hdlg, int id); - -static void -winUnoverrideURLButton (HWND hdlg, int id); - - -/* - * Owner-draw a button as a URL - */ - -static void -winDrawURLWindow (LPARAM lParam) -{ - DRAWITEMSTRUCT *draw; - char str[256]; - RECT rect; - HFONT font; - COLORREF crText; - - draw = (DRAWITEMSTRUCT *) lParam; - GetWindowText (draw->hwndItem, str, sizeof(str)); - str[255] = 0; - GetClientRect (draw->hwndItem, &rect); - - /* Color the button depending upon its state */ - if (draw->itemState & ODS_SELECTED) - crText = RGB(128+64,0,0); - else if (draw->itemState & ODS_FOCUS) - crText = RGB(0,128+64,0); - else - crText = RGB(0,0,128+64); - SetTextColor (draw->hDC, crText); - - /* Create font 8 high, standard dialog font */ - font = CreateFont (-8, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE, - 0, 0, 0, 0, 0, "MS Sans Serif"); - if (!font) - { - ErrorF ("winDrawURLWindow: Unable to create URL font, bailing.\n"); - return; - } - /* Draw it */ - SetBkMode (draw->hDC, OPAQUE); - SelectObject (draw->hDC, font); - DrawText (draw->hDC, str, strlen (str),&rect,DT_CENTER | DT_VCENTER); - /* Delete the created font, replace it with stock font */ - DeleteObject (SelectObject (draw->hDC, GetStockObject (ANSI_VAR_FONT))); -} - - -/* - * WndProc for overridden buttons - */ - -static LRESULT CALLBACK -winURLWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) -{ - WNDPROC origCB = NULL; - HCURSOR cursor; - - /* If it's a SetCursor message, tell it to the hand */ - if (msg==WM_SETCURSOR) { - cursor = LoadCursor (NULL, IDC_HAND); - if (cursor) - SetCursor (cursor); - return TRUE; - } - origCB = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA); - /* Otherwise fall through to original WndProc */ - if (origCB) - return CallWindowProc (origCB, hwnd, msg, wParam, lParam); - else - return FALSE; -} - - -/* - * Register and unregister the custom WndProc - */ - -static void -winOverrideURLButton (HWND hwnd, int id) -{ - WNDPROC origCB; - origCB = (WNDPROC)SetWindowLongPtr(GetDlgItem (hwnd, id), - GWLP_WNDPROC, (LONG_PTR)winURLWndProc); - SetWindowLongPtr(GetDlgItem (hwnd, id), GWLP_USERDATA, (LONG_PTR)origCB); -} - -static void -winUnoverrideURLButton (HWND hwnd, int id) -{ - WNDPROC origCB; - origCB = (WNDPROC)SetWindowLongPtr(GetDlgItem (hwnd, id), - GWLP_USERDATA, 0); - if (origCB) - SetWindowLongPtr(GetDlgItem (hwnd, id), GWLP_WNDPROC, (LONG_PTR)origCB); -} - - -/* - * Center a dialog window in the desktop window - * and set small and large icons to X icons. - */ - -static void -winInitDialog (HWND hwndDlg) -{ - HWND hwndDesk; - RECT rc, rcDlg, rcDesk; - HICON hIcon, hIconSmall; - - hwndDesk = GetParent (hwndDlg); - if (!hwndDesk || IsIconic (hwndDesk)) - hwndDesk = GetDesktopWindow (); - - /* Remove minimize and maximize buttons */ - SetWindowLongPtr(hwndDlg, GWL_STYLE, - GetWindowLongPtr(hwndDlg, GWL_STYLE) - & ~(WS_MAXIMIZEBOX | WS_MINIMIZEBOX)); - - /* Set Window not to show in the task bar */ - SetWindowLongPtr(hwndDlg, GWL_EXSTYLE, - GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) & ~WS_EX_APPWINDOW ); - - /* Center dialog window in the screen. Not done for multi-monitor systems, where - * it is likely to end up split across the screens. In that case, it appears - * near the Tray icon. - */ - if (GetSystemMetrics(SM_CMONITORS)>1) { - /* Still need to refresh the frame change. */ - SetWindowPos (hwndDlg, HWND_TOPMOST, 0,0,0,0, - SWP_NOMOVE | SWP_NOSIZE | SWP_FRAMECHANGED); - } else { - GetWindowRect (hwndDesk, &rcDesk); - GetWindowRect (hwndDlg, &rcDlg); - CopyRect (&rc, &rcDesk); - - OffsetRect (&rcDlg, -rcDlg.left, -rcDlg.top); - OffsetRect (&rc, -rc.left, -rc.top); - OffsetRect (&rc, -rcDlg.right, -rcDlg.bottom); - - SetWindowPos (hwndDlg, - HWND_TOPMOST, - rcDesk.left + (rc.right / 2), - rcDesk.top + (rc.bottom / 2), - 0, 0, - SWP_NOSIZE | SWP_FRAMECHANGED); - } - -#ifdef XWIN_MULTIWINDOW - if (g_hIconX) hIcon=g_hIconX; - else -#endif - hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN)); - -#ifdef XWIN_MULTIWINDOW - if (g_hSmallIconX) hIconSmall=g_hSmallIconX; - else -#endif - hIconSmall = LoadImage (g_hInstance, - MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON, - GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - LR_SHARED); - - PostMessage (hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) hIcon); - PostMessage (hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall); -} - - -/* - * Display the Exit dialog box - */ - -void -winDisplayExitDialog (winPrivScreenPtr pScreenPriv) -{ - int i; - int liveClients = 0; - - /* Count up running clients (clients[0] is serverClient) */ - for (i = 1; i < currentMaxClients; i++) - if (clients[i] != NullClient) - liveClients++; -#if defined(XWIN_MULTIWINDOW) - /* Count down server internal clients */ - if (pScreenPriv->pScreenInfo->fMultiWindow) - liveClients -= 2; /* multiwindow window manager & XMsgProc */ -#endif -#if defined(XWIN_CLIPBOARD) - if (g_fClipboardStarted) - liveClients--; /* clipboard manager */ -#endif - - /* A user reported that this sometimes drops below zero. just eye-candy. */ - if (liveClients < 0) - liveClients = 0; - - /* Don't show the exit confirmation dialog if SilentExit & no clients, - or ForceExit, is enabled */ - if ((pref.fSilentExit && liveClients <= 0) || pref.fForceExit) - { - if (g_hDlgExit != NULL) - { - DestroyWindow (g_hDlgExit); - g_hDlgExit = NULL; - } - PostMessage (pScreenPriv->hwndScreen, WM_GIVEUP, 0, 0); - return; - } - - pScreenPriv->iConnectedClients = liveClients; - - /* Check if dialog already exists */ - if (g_hDlgExit != NULL) - { - /* Dialog box already exists, display it */ - ShowWindow (g_hDlgExit, SW_SHOWDEFAULT); - - /* User has lost the dialog. Show them where it is. */ - SetForegroundWindow (g_hDlgExit); - - return; - } - - /* Create dialog box */ - g_hDlgExit = CreateDialogParam (g_hInstance, - "EXIT_DIALOG", - pScreenPriv->hwndScreen, - winExitDlgProc, - (int) pScreenPriv); - - /* Show the dialog box */ - ShowWindow (g_hDlgExit, SW_SHOW); - - /* Needed to get keyboard controls (tab, arrows, enter, esc) to work */ - SetForegroundWindow (g_hDlgExit); - - /* Set focus to the Cancel button */ - PostMessage (g_hDlgExit, WM_NEXTDLGCTL, - GetDlgItem (g_hDlgExit, IDCANCEL), TRUE); -} - -#define CONNECTED_CLIENTS_FORMAT "There %s currently %d client%s connected." - - -/* - * Exit dialog window procedure - */ - -static wBOOL CALLBACK -winExitDlgProc (HWND hDialog, UINT message, - WPARAM wParam, LPARAM lParam) -{ - static winPrivScreenPtr s_pScreenPriv = NULL; - - /* Branch on message type */ - switch (message) - { - case WM_INITDIALOG: - { - char *pszConnectedClients; - - /* Store pointers to private structures for future use */ - s_pScreenPriv = (winPrivScreenPtr) lParam; - - winInitDialog (hDialog); - - /* Format the connected clients string */ - pszConnectedClients = Xprintf (CONNECTED_CLIENTS_FORMAT, - (s_pScreenPriv->iConnectedClients == 1) ? "is" : "are", - s_pScreenPriv->iConnectedClients, - (s_pScreenPriv->iConnectedClients == 1) ? "" : "s"); - if (!pszConnectedClients) - return TRUE; - - - - /* Set the number of connected clients */ - SetWindowText (GetDlgItem (hDialog, IDC_CLIENTS_CONNECTED), - pszConnectedClients); - xfree (pszConnectedClients); - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD (wParam)) - { - case IDOK: - /* Send message to call the GiveUp function */ - PostMessage (s_pScreenPriv->hwndScreen, WM_GIVEUP, 0, 0); - DestroyWindow (g_hDlgExit); - g_hDlgExit = NULL; - - /* Fix to make sure keyboard focus isn't trapped */ - PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); - return TRUE; - - case IDCANCEL: - DestroyWindow (g_hDlgExit); - g_hDlgExit = NULL; - - /* Fix to make sure keyboard focus isn't trapped */ - PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); - return TRUE; - } - break; - - case WM_MOUSEMOVE: - case WM_NCMOUSEMOVE: - /* Show the cursor if it is hidden */ - if (g_fSoftwareCursor && !g_fCursor) - { - g_fCursor = TRUE; - ShowCursor (TRUE); - } - return TRUE; - - case WM_CLOSE: - DestroyWindow (g_hDlgExit); - g_hDlgExit = NULL; - - /* Fix to make sure keyboard focus isn't trapped */ - PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); - return TRUE; - } - - return FALSE; -} - - -/* - * Display the Depth Change dialog box - */ - -void -winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv) -{ - /* Check if dialog already exists */ - if (g_hDlgDepthChange != NULL) - { - /* Dialog box already exists, display it */ - ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT); - - /* User has lost the dialog. Show them where it is. */ - SetForegroundWindow (g_hDlgDepthChange); - - return; - } - - /* - * Display a notification to the user that the visual - * will not be displayed until the Windows display depth - * is restored to the original value. - */ - g_hDlgDepthChange = CreateDialogParam (g_hInstance, - "DEPTH_CHANGE_BOX", - pScreenPriv->hwndScreen, - winChangeDepthDlgProc, - (int) pScreenPriv); - /* Show the dialog box */ - ShowWindow (g_hDlgDepthChange, SW_SHOW); - - ErrorF ("winDisplayDepthChangeDialog - DialogBox returned: %d\n", - (int) g_hDlgDepthChange); - ErrorF ("winDisplayDepthChangeDialog - GetLastError: %d\n", - (int) GetLastError ()); - - /* Minimize the display window */ - ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE); -} - - -/* - * Process messages for the dialog that is displayed for - * disruptive screen depth changes. - */ - -static wBOOL CALLBACK -winChangeDepthDlgProc (HWND hwndDialog, UINT message, - WPARAM wParam, LPARAM lParam) -{ - static winPrivScreenPtr s_pScreenPriv = NULL; - static winScreenInfo *s_pScreenInfo = NULL; - static ScreenPtr s_pScreen = NULL; - -#if CYGDEBUG - winDebug ("winChangeDepthDlgProc\n"); -#endif - - /* Branch on message type */ - switch (message) - { - case WM_INITDIALOG: -#if CYGDEBUG - winDebug ("winChangeDepthDlgProc - WM_INITDIALOG\n"); -#endif - - /* Store pointers to private structures for future use */ - s_pScreenPriv = (winPrivScreenPtr) lParam; - s_pScreenInfo = s_pScreenPriv->pScreenInfo; - s_pScreen = s_pScreenInfo->pScreen; - -#if CYGDEBUG - winDebug ("winChangeDepthDlgProc - WM_INITDIALOG - s_pScreenPriv: %08x, " - "s_pScreenInfo: %08x, s_pScreen: %08x\n", - s_pScreenPriv, s_pScreenInfo, s_pScreen); -#endif - -#if CYGDEBUG - winDebug ("winChangeDepthDlgProc - WM_INITDIALOG - orig bpp: %d, " - "last bpp: %d\n", - s_pScreenInfo->dwBPP, - s_pScreenPriv->dwLastWindowsBitsPixel); -#endif - - winInitDialog( hwndDialog ); - - return TRUE; - - case WM_DISPLAYCHANGE: -#if CYGDEBUG - winDebug ("winChangeDepthDlgProc - WM_DISPLAYCHANGE - orig bpp: %d, " - "last bpp: %d, new bpp: %d\n", - s_pScreenInfo->dwBPP, - s_pScreenPriv->dwLastWindowsBitsPixel, - wParam); -#endif - - /* Dismiss the dialog if the display returns to the original depth */ - if (wParam == s_pScreenInfo->dwBPP) - { - ErrorF ("winChangeDelthDlgProc - wParam == s_pScreenInfo->dwBPP\n"); - - /* Depth has been restored, dismiss dialog */ - DestroyWindow (g_hDlgDepthChange); - g_hDlgDepthChange = NULL; - - /* Flag that we have a valid screen depth */ - s_pScreenPriv->fBadDepth = FALSE; - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD (wParam)) - { - case IDOK: - case IDCANCEL: - ErrorF ("winChangeDepthDlgProc - WM_COMMAND - IDOK or IDCANCEL\n"); - - /* - * User dismissed the dialog, hide it until the - * display mode is restored. - */ - ShowWindow (g_hDlgDepthChange, SW_HIDE); - return TRUE; - } - break; - - case WM_CLOSE: - ErrorF ("winChangeDepthDlgProc - WM_CLOSE\n"); - - DestroyWindow (g_hDlgAbout); - g_hDlgAbout = NULL; - - /* Fix to make sure keyboard focus isn't trapped */ - PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); - return TRUE; - } - - return FALSE; -} - - -/* - * Display the About dialog box - */ - -void -winDisplayAboutDialog (winPrivScreenPtr pScreenPriv) -{ - /* Check if dialog already exists */ - if (g_hDlgAbout != NULL) - { - /* Dialog box already exists, display it */ - ShowWindow (g_hDlgAbout, SW_SHOWDEFAULT); - - /* User has lost the dialog. Show them where it is. */ - SetForegroundWindow (g_hDlgAbout); - - return; - } - - /* - * Display the about box - */ - g_hDlgAbout = CreateDialogParam (g_hInstance, - "ABOUT_BOX", - pScreenPriv->hwndScreen, - winAboutDlgProc, - (int) pScreenPriv); - - /* Show the dialog box */ - ShowWindow (g_hDlgAbout, SW_SHOW); - - /* Needed to get keyboard controls (tab, arrows, enter, esc) to work */ - SetForegroundWindow (g_hDlgAbout); - - /* Set focus to the OK button */ - PostMessage (g_hDlgAbout, WM_NEXTDLGCTL, - GetDlgItem (g_hDlgAbout, IDOK), TRUE); -} - - -/* - * Process messages for the about dialog. - */ - -static wBOOL CALLBACK -winAboutDlgProc (HWND hwndDialog, UINT message, - WPARAM wParam, LPARAM lParam) -{ - static winPrivScreenPtr s_pScreenPriv = NULL; - static winScreenInfo *s_pScreenInfo = NULL; - static ScreenPtr s_pScreen = NULL; - -#if CYGDEBUG - winDebug ("winAboutDlgProc\n"); -#endif - - /* Branch on message type */ - switch (message) - { - case WM_INITDIALOG: -#if CYGDEBUG - winDebug ("winAboutDlgProc - WM_INITDIALOG\n"); -#endif - - /* Store pointers to private structures for future use */ - s_pScreenPriv = (winPrivScreenPtr) lParam; - s_pScreenInfo = s_pScreenPriv->pScreenInfo; - s_pScreen = s_pScreenInfo->pScreen; - - winInitDialog (hwndDialog); - - /* Override the URL buttons */ - winOverrideURLButton (hwndDialog, ID_ABOUT_CHANGELOG); - winOverrideURLButton (hwndDialog, ID_ABOUT_WEBSITE); - winOverrideURLButton (hwndDialog, ID_ABOUT_UG); - winOverrideURLButton (hwndDialog, ID_ABOUT_FAQ); - - return TRUE; - - case WM_DRAWITEM: - /* Draw the URL buttons as needed */ - winDrawURLWindow (lParam); - return TRUE; - - case WM_MOUSEMOVE: - case WM_NCMOUSEMOVE: - /* Show the cursor if it is hidden */ - if (g_fSoftwareCursor && !g_fCursor) - { - g_fCursor = TRUE; - ShowCursor (TRUE); - } - return TRUE; - - case WM_COMMAND: - switch (LOWORD (wParam)) - { - case IDOK: - case IDCANCEL: - ErrorF ("winAboutDlgProc - WM_COMMAND - IDOK or IDCANCEL\n"); - - DestroyWindow (g_hDlgAbout); - g_hDlgAbout = NULL; - - /* Fix to make sure keyboard focus isn't trapped */ - PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); - - /* Restore window procedures for URL buttons */ - winUnoverrideURLButton (hwndDialog, ID_ABOUT_CHANGELOG); - winUnoverrideURLButton (hwndDialog, ID_ABOUT_WEBSITE); - winUnoverrideURLButton (hwndDialog, ID_ABOUT_UG); - winUnoverrideURLButton (hwndDialog, ID_ABOUT_FAQ); - - return TRUE; - - case ID_ABOUT_CHANGELOG: - { - HINSTANCE iReturn; -#ifdef __CYGWIN__ - const char * pszCygPath = "/usr/X11R6/share/doc/" - "xorg-x11-xwin/changelog.html"; - char pszWinPath[MAX_PATH + 1]; - - /* Convert the POSIX path to a Win32 path */ - cygwin_conv_to_win32_path (pszCygPath, pszWinPath); -#else - const char * pszWinPath = "http://x.cygwin.com/" - "devel/server/changelog.html"; -#endif - - iReturn = ShellExecute (NULL, - "open", - pszWinPath, - NULL, - NULL, - SW_MAXIMIZE); - if (iReturn < 32) - { - ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_CHANGELOG - " - "ShellExecute failed: %d\n", - iReturn); - } - } - return TRUE; - - case ID_ABOUT_WEBSITE: - { - const char * pszPath = __VENDORDWEBSUPPORT__; - int iReturn; - - iReturn = ShellExecute (NULL, - "open", - pszPath, - NULL, - NULL, - SW_MAXIMIZE); - if (iReturn < 32) - { - ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_WEBSITE - " - "ShellExecute failed: %d\n", - iReturn); - } - } - return TRUE; - - case ID_ABOUT_UG: - { - const char * pszPath = "http://x.cygwin.com/docs/ug/"; - int iReturn; - - iReturn = ShellExecute (NULL, - "open", - pszPath, - NULL, - NULL, - SW_MAXIMIZE); - if (iReturn < 32) - { - ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_UG - " - "ShellExecute failed: %d\n", - iReturn); - } - } - return TRUE; - - case ID_ABOUT_FAQ: - { - const char * pszPath = "http://x.cygwin.com/docs/faq/"; - int iReturn; - - iReturn = ShellExecute (NULL, - "open", - pszPath, - NULL, - NULL, - SW_MAXIMIZE); - if (iReturn < 32) - { - ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_FAQ - " - "ShellExecute failed: %d\n", - iReturn); - } - } - return TRUE; - } - break; - - case WM_CLOSE: - ErrorF ("winAboutDlgProc - WM_CLOSE\n"); - - DestroyWindow (g_hDlgAbout); - g_hDlgAbout = NULL; - - /* Fix to make sure keyboard focus isn't trapped */ - PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0); - - /* Restore window procedures for URL buttons */ - winUnoverrideURLButton (hwndDialog, ID_ABOUT_CHANGELOG); - winUnoverrideURLButton (hwndDialog, ID_ABOUT_WEBSITE); - winUnoverrideURLButton (hwndDialog, ID_ABOUT_UG); - winUnoverrideURLButton (hwndDialog, ID_ABOUT_FAQ); - - return TRUE; - } - - return FALSE; -} +/*
+ *Copyright (C) 2003-2004 Harold L Hunt II 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 HAROLD L HUNT II 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 Harold L Hunt II
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from Harold L Hunt II.
+ *
+ * Authors: Harold L Hunt II
+ * Earle F. Philhower III
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#ifdef __CYGWIN__
+#include <sys/cygwin.h>
+#endif
+#include <shellapi.h>
+#include "winprefs.h"
+
+
+/*
+ * References to external globals
+ */
+
+extern Bool g_fCursor;
+extern HWND g_hDlgDepthChange;
+extern HWND g_hDlgExit;
+extern HWND g_hDlgAbout;
+extern WINPREFS pref;
+#ifdef XWIN_CLIPBOARD
+extern Bool g_fClipboardStarted;
+#endif
+extern Bool g_fSoftwareCursor;
+
+#if defined(XWIN_MULTIWINDOW)
+extern HICON g_hIconX;
+extern HICON g_hSmallIconX;
+#endif
+
+/*
+ * Local function prototypes
+ */
+
+static wBOOL CALLBACK
+winExitDlgProc (HWND hDialog, UINT message,
+ WPARAM wParam, LPARAM lParam);
+
+static wBOOL CALLBACK
+winChangeDepthDlgProc (HWND hDialog, UINT message,
+ WPARAM wParam, LPARAM lParam);
+
+static wBOOL CALLBACK
+winAboutDlgProc (HWND hDialog, UINT message,
+ WPARAM wParam, LPARAM lParam);
+
+
+static void
+winDrawURLWindow (LPARAM lParam);
+
+static LRESULT CALLBACK
+winURLWndProc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
+
+static void
+winOverrideURLButton (HWND hdlg, int id);
+
+static void
+winUnoverrideURLButton (HWND hdlg, int id);
+
+
+/*
+ * Owner-draw a button as a URL
+ */
+
+static void
+winDrawURLWindow (LPARAM lParam)
+{
+ DRAWITEMSTRUCT *draw;
+ char str[256];
+ RECT rect;
+ HFONT font;
+ COLORREF crText;
+
+ draw = (DRAWITEMSTRUCT *) lParam;
+ GetWindowText (draw->hwndItem, str, sizeof(str));
+ str[255] = 0;
+ GetClientRect (draw->hwndItem, &rect);
+
+ /* Color the button depending upon its state */
+ if (draw->itemState & ODS_SELECTED)
+ crText = RGB(128+64,0,0);
+ else if (draw->itemState & ODS_FOCUS)
+ crText = RGB(0,128+64,0);
+ else
+ crText = RGB(0,0,128+64);
+ SetTextColor (draw->hDC, crText);
+
+ /* Create font 8 high, standard dialog font */
+ font = CreateFont (-8, 0, 0, 0, FW_DONTCARE, FALSE, FALSE, FALSE,
+ 0, 0, 0, 0, 0, "MS Sans Serif");
+ if (!font)
+ {
+ ErrorF ("winDrawURLWindow: Unable to create URL font, bailing.\n");
+ return;
+ }
+ /* Draw it */
+ SetBkMode (draw->hDC, OPAQUE);
+ SelectObject (draw->hDC, font);
+ DrawText (draw->hDC, str, strlen (str),&rect,DT_CENTER | DT_VCENTER);
+ /* Delete the created font, replace it with stock font */
+ DeleteObject (SelectObject (draw->hDC, GetStockObject (ANSI_VAR_FONT)));
+}
+
+
+/*
+ * WndProc for overridden buttons
+ */
+
+static LRESULT CALLBACK
+winURLWndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
+{
+ WNDPROC origCB = NULL;
+ HCURSOR cursor;
+
+ /* If it's a SetCursor message, tell it to the hand */
+ if (msg==WM_SETCURSOR) {
+ cursor = LoadCursor (NULL, IDC_HAND);
+ if (cursor)
+ SetCursor (cursor);
+ return TRUE;
+ }
+ origCB = (WNDPROC)GetWindowLongPtr(hwnd, GWLP_USERDATA);
+ /* Otherwise fall through to original WndProc */
+ if (origCB)
+ return CallWindowProc (origCB, hwnd, msg, wParam, lParam);
+ else
+ return FALSE;
+}
+
+
+/*
+ * Register and unregister the custom WndProc
+ */
+
+static void
+winOverrideURLButton (HWND hwnd, int id)
+{
+ WNDPROC origCB;
+ origCB = (WNDPROC)SetWindowLongPtr(GetDlgItem (hwnd, id),
+ GWLP_WNDPROC, (LONG_PTR)winURLWndProc);
+ SetWindowLongPtr(GetDlgItem (hwnd, id), GWLP_USERDATA, (LONG_PTR)origCB);
+}
+
+static void
+winUnoverrideURLButton (HWND hwnd, int id)
+{
+ WNDPROC origCB;
+ origCB = (WNDPROC)SetWindowLongPtr(GetDlgItem (hwnd, id),
+ GWLP_USERDATA, 0);
+ if (origCB)
+ SetWindowLongPtr(GetDlgItem (hwnd, id), GWLP_WNDPROC, (LONG_PTR)origCB);
+}
+
+
+/*
+ * Center a dialog window in the desktop window
+ * and set small and large icons to X icons.
+ */
+
+static void
+winInitDialog (HWND hwndDlg)
+{
+ HWND hwndDesk;
+ RECT rc, rcDlg, rcDesk;
+ HICON hIcon, hIconSmall;
+
+ hwndDesk = GetParent (hwndDlg);
+ if (!hwndDesk || IsIconic (hwndDesk))
+ hwndDesk = GetDesktopWindow ();
+
+ /* Remove minimize and maximize buttons */
+ SetWindowLongPtr(hwndDlg, GWL_STYLE,
+ GetWindowLongPtr(hwndDlg, GWL_STYLE)
+ & ~(WS_MAXIMIZEBOX | WS_MINIMIZEBOX));
+
+ /* Set Window not to show in the task bar */
+ SetWindowLongPtr(hwndDlg, GWL_EXSTYLE,
+ GetWindowLongPtr(hwndDlg, GWL_EXSTYLE) & ~WS_EX_APPWINDOW );
+
+ /* Center dialog window in the screen. Not done for multi-monitor systems, where
+ * it is likely to end up split across the screens. In that case, it appears
+ * near the Tray icon.
+ */
+ if (GetSystemMetrics(SM_CMONITORS)>1) {
+ /* Still need to refresh the frame change. */
+ SetWindowPos (hwndDlg, HWND_TOP, 0,0,0,0,
+ SWP_NOMOVE | SWP_NOSIZE | SWP_NOZORDER | SWP_FRAMECHANGED);
+ } else {
+ GetWindowRect (hwndDesk, &rcDesk);
+ GetWindowRect (hwndDlg, &rcDlg);
+ CopyRect (&rc, &rcDesk);
+
+ OffsetRect (&rcDlg, -rcDlg.left, -rcDlg.top);
+ OffsetRect (&rc, -rc.left, -rc.top);
+ OffsetRect (&rc, -rcDlg.right, -rcDlg.bottom);
+
+ SetWindowPos (hwndDlg,
+ HWND_TOPMOST,
+ rcDesk.left + (rc.right / 2),
+ rcDesk.top + (rc.bottom / 2),
+ 0, 0,
+ SWP_NOSIZE | SWP_FRAMECHANGED);
+ }
+
+#ifdef XWIN_MULTIWINDOW
+ if (g_hIconX) hIcon=g_hIconX;
+ else
+#endif
+ hIcon = LoadIcon (g_hInstance, MAKEINTRESOURCE(IDI_XWIN));
+
+#ifdef XWIN_MULTIWINDOW
+ if (g_hSmallIconX) hIconSmall=g_hSmallIconX;
+ else
+#endif
+ hIconSmall = LoadImage (g_hInstance,
+ MAKEINTRESOURCE(IDI_XWIN), IMAGE_ICON,
+ GetSystemMetrics(SM_CXSMICON),
+ GetSystemMetrics(SM_CYSMICON),
+ LR_SHARED);
+
+ PostMessage (hwndDlg, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
+ PostMessage (hwndDlg, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall);
+}
+
+
+int
+GetLiveClients (winPrivScreenPtr pScreenPriv)
+{
+ int i;
+ int liveClients = 0;
+
+ /* Count up running clients (clients[0] is serverClient) */
+ for (i = 1; i < currentMaxClients; i++)
+ if (clients[i] != NullClient)
+ liveClients++;
+#if defined(XWIN_MULTIWINDOW)
+ /* Count down server internal clients */
+ if (pScreenPriv->pScreenInfo->fMultiWindow)
+ liveClients -= 2; /* multiwindow window manager & XMsgProc */
+#endif
+#if defined(XWIN_CLIPBOARD)
+ if (g_fClipboardStarted)
+ liveClients--; /* clipboard manager */
+#endif
+
+ /* A user reported that this sometimes drops below zero. just eye-candy. */
+ if (liveClients < 0)
+ liveClients = 0;
+
+ pScreenPriv->iConnectedClients = liveClients;
+
+ return liveClients;
+}
+
+/*
+ * Display the Exit dialog box
+ */
+
+void
+winDisplayExitDialog (winPrivScreenPtr pScreenPriv)
+{
+ int liveClients = GetLiveClients(pScreenPriv);
+
+ /* Don't show the exit confirmation dialog if SilentExit & no clients,
+ or ForceExit, is enabled */
+ if ((pref.fSilentExit && liveClients <= 0) || pref.fForceExit)
+ {
+ if (g_hDlgExit != NULL)
+ {
+ DestroyWindow (g_hDlgExit);
+ g_hDlgExit = NULL;
+ }
+ PostMessage (pScreenPriv->hwndScreen, WM_GIVEUP, 0, 0);
+ return;
+ }
+
+ /* Check if dialog already exists */
+ if (g_hDlgExit != NULL)
+ {
+ /* Dialog box already exists, display it */
+ ShowWindow (g_hDlgExit, SW_SHOWDEFAULT);
+
+ /* User has lost the dialog. Show them where it is. */
+ SetForegroundWindow (g_hDlgExit);
+
+ return;
+ }
+
+ /* Create dialog box */
+ g_hDlgExit = CreateDialogParam (g_hInstance,
+ "EXIT_DIALOG",
+ pScreenPriv->hwndScreen,
+ winExitDlgProc,
+ (int) pScreenPriv);
+
+ /* Show the dialog box */
+ ShowWindow (g_hDlgExit, SW_SHOW);
+
+ /* Needed to get keyboard controls (tab, arrows, enter, esc) to work */
+ SetForegroundWindow (g_hDlgExit);
+
+ /* Set focus to the Cancel button */
+ PostMessage (g_hDlgExit, WM_NEXTDLGCTL,
+ (WPARAM)GetDlgItem (g_hDlgExit, IDCANCEL), TRUE);
+}
+
+#define CONNECTED_CLIENTS_FORMAT "There %s currently %d client%s connected."
+
+
+/*
+ * Exit dialog window procedure
+ */
+
+static wBOOL CALLBACK
+winExitDlgProc (HWND hDialog, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ static winPrivScreenPtr s_pScreenPriv = NULL;
+
+ /* Branch on message type */
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ {
+ char *pszConnectedClients;
+
+ /* Store pointers to private structures for future use */
+ s_pScreenPriv = (winPrivScreenPtr) lParam;
+
+ winInitDialog (hDialog);
+
+ /* Format the connected clients string */
+ pszConnectedClients = Xprintf (CONNECTED_CLIENTS_FORMAT,
+ (s_pScreenPriv->iConnectedClients == 1) ? "is" : "are",
+ s_pScreenPriv->iConnectedClients,
+ (s_pScreenPriv->iConnectedClients == 1) ? "" : "s");
+ if (!pszConnectedClients)
+ return TRUE;
+
+
+
+ /* Set the number of connected clients */
+ SetWindowText (GetDlgItem (hDialog, IDC_CLIENTS_CONNECTED),
+ pszConnectedClients);
+ xfree (pszConnectedClients);
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (LOWORD (wParam))
+ {
+ case IDOK:
+ /* Send message to call the GiveUp function */
+ PostMessage (s_pScreenPriv->hwndScreen, WM_GIVEUP, 0, 0);
+ DestroyWindow (g_hDlgExit);
+ g_hDlgExit = NULL;
+
+ /* Fix to make sure keyboard focus isn't trapped */
+ PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0);
+ return TRUE;
+
+ case IDCANCEL:
+ DestroyWindow (g_hDlgExit);
+ g_hDlgExit = NULL;
+
+ /* Fix to make sure keyboard focus isn't trapped */
+ PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0);
+ return TRUE;
+ }
+ break;
+
+ case WM_MOUSEMOVE:
+ case WM_NCMOUSEMOVE:
+ /* Show the cursor if it is hidden */
+ if (g_fSoftwareCursor && !g_fCursor)
+ {
+ g_fCursor = TRUE;
+ ShowCursor (TRUE);
+ }
+ return TRUE;
+
+ case WM_CLOSE:
+ DestroyWindow (g_hDlgExit);
+ g_hDlgExit = NULL;
+
+ /* Fix to make sure keyboard focus isn't trapped */
+ PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Display the Depth Change dialog box
+ */
+
+void
+winDisplayDepthChangeDialog (winPrivScreenPtr pScreenPriv)
+{
+ /* Check if dialog already exists */
+ if (g_hDlgDepthChange != NULL)
+ {
+ /* Dialog box already exists, display it */
+ ShowWindow (g_hDlgDepthChange, SW_SHOWDEFAULT);
+
+ /* User has lost the dialog. Show them where it is. */
+ SetForegroundWindow (g_hDlgDepthChange);
+
+ return;
+ }
+
+ /*
+ * Display a notification to the user that the visual
+ * will not be displayed until the Windows display depth
+ * is restored to the original value.
+ */
+ g_hDlgDepthChange = CreateDialogParam (g_hInstance,
+ "DEPTH_CHANGE_BOX",
+ pScreenPriv->hwndScreen,
+ winChangeDepthDlgProc,
+ (int) pScreenPriv);
+ /* Show the dialog box */
+ ShowWindow (g_hDlgDepthChange, SW_SHOW);
+
+ winDebug ("winDisplayDepthChangeDialog - DialogBox returned: %d\n",
+ (int) g_hDlgDepthChange);
+ winDebug ("winDisplayDepthChangeDialog - GetLastError: %d\n",
+ (int) GetLastError ());
+
+ /* Minimize the display window */
+ ShowWindow (pScreenPriv->hwndScreen, SW_MINIMIZE);
+}
+
+
+/*
+ * Process messages for the dialog that is displayed for
+ * disruptive screen depth changes.
+ */
+
+static wBOOL CALLBACK
+winChangeDepthDlgProc (HWND hwndDialog, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ static winPrivScreenPtr s_pScreenPriv = NULL;
+ static winScreenInfo *s_pScreenInfo = NULL;
+ static ScreenPtr s_pScreen = NULL;
+
+ winDebug ("winChangeDepthDlgProc\n");
+
+ /* Branch on message type */
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ winDebug ("winChangeDepthDlgProc - WM_INITDIALOG\n");
+
+ /* Store pointers to private structures for future use */
+ s_pScreenPriv = (winPrivScreenPtr) lParam;
+ s_pScreenInfo = s_pScreenPriv->pScreenInfo;
+ s_pScreen = s_pScreenInfo->pScreen;
+
+ winDebug ("winChangeDepthDlgProc - WM_INITDIALOG - s_pScreenPriv: %08x, "
+ "s_pScreenInfo: %08x, s_pScreen: %08x\n",
+ s_pScreenPriv, s_pScreenInfo, s_pScreen);
+
+ winDebug ("winChangeDepthDlgProc - WM_INITDIALOG - orig bpp: %d, "
+ "last bpp: %d\n",
+ s_pScreenInfo->dwBPP,
+ s_pScreenPriv->dwLastWindowsBitsPixel);
+
+ winInitDialog( hwndDialog );
+
+ return TRUE;
+
+ case WM_DISPLAYCHANGE:
+ winDebug ("winChangeDepthDlgProc - WM_DISPLAYCHANGE - orig bpp: %d, "
+ "last bpp: %d, new bpp: %d\n",
+ s_pScreenInfo->dwBPP,
+ s_pScreenPriv->dwLastWindowsBitsPixel,
+ wParam);
+
+ /* Dismiss the dialog if the display returns to the original depth */
+ if (wParam == s_pScreenInfo->dwBPP)
+ {
+ winDebug ("winChangeDelthDlgProc - wParam == s_pScreenInfo->dwBPP\n");
+
+ /* Depth has been restored, dismiss dialog */
+ DestroyWindow (g_hDlgDepthChange);
+ g_hDlgDepthChange = NULL;
+
+ /* Flag that we have a valid screen depth */
+ s_pScreenPriv->fBadDepth = FALSE;
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (LOWORD (wParam))
+ {
+ case IDOK:
+ case IDCANCEL:
+ ErrorF ("winChangeDepthDlgProc - WM_COMMAND - IDOK or IDCANCEL\n");
+
+ /*
+ * User dismissed the dialog, hide it until the
+ * display mode is restored.
+ */
+ ShowWindow (g_hDlgDepthChange, SW_HIDE);
+ return TRUE;
+ }
+ break;
+
+ case WM_CLOSE:
+ winDebug ("winChangeDepthDlgProc - WM_CLOSE\n");
+
+ DestroyWindow (g_hDlgAbout);
+ g_hDlgAbout = NULL;
+
+ /* Fix to make sure keyboard focus isn't trapped */
+ PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/*
+ * Display the About dialog box
+ */
+
+void
+winDisplayAboutDialog (winPrivScreenPtr pScreenPriv)
+{
+ /* Check if dialog already exists */
+ if (g_hDlgAbout != NULL)
+ {
+ /* Dialog box already exists, display it */
+ ShowWindow (g_hDlgAbout, SW_SHOWDEFAULT);
+
+ /* User has lost the dialog. Show them where it is. */
+ SetForegroundWindow (g_hDlgAbout);
+
+ return;
+ }
+
+ /*
+ * Display the about box
+ */
+ g_hDlgAbout = CreateDialogParam (g_hInstance,
+ "ABOUT_BOX",
+ pScreenPriv->hwndScreen,
+ winAboutDlgProc,
+ (int) pScreenPriv);
+
+ /* Show the dialog box */
+ ShowWindow (g_hDlgAbout, SW_SHOW);
+
+ /* Needed to get keyboard controls (tab, arrows, enter, esc) to work */
+ SetForegroundWindow (g_hDlgAbout);
+
+ /* Set focus to the OK button */
+ PostMessage (g_hDlgAbout, WM_NEXTDLGCTL,
+ (WPARAM)GetDlgItem (g_hDlgAbout, IDOK), TRUE);
+}
+
+
+/*
+ * Process messages for the about dialog.
+ */
+
+static wBOOL CALLBACK
+winAboutDlgProc (HWND hwndDialog, UINT message,
+ WPARAM wParam, LPARAM lParam)
+{
+ static winPrivScreenPtr s_pScreenPriv = NULL;
+ static winScreenInfo *s_pScreenInfo = NULL;
+ static ScreenPtr s_pScreen = NULL;
+
+ winDebug ("winAboutDlgProc\n");
+
+ /* Branch on message type */
+ switch (message)
+ {
+ case WM_INITDIALOG:
+ winDebug ("winAboutDlgProc - WM_INITDIALOG\n");
+
+ /* Store pointers to private structures for future use */
+ s_pScreenPriv = (winPrivScreenPtr) lParam;
+ s_pScreenInfo = s_pScreenPriv->pScreenInfo;
+ s_pScreen = s_pScreenInfo->pScreen;
+
+ winInitDialog (hwndDialog);
+
+ /* Override the URL buttons */
+ winOverrideURLButton (hwndDialog, ID_ABOUT_CHANGELOG);
+ winOverrideURLButton (hwndDialog, ID_ABOUT_WEBSITE);
+ winOverrideURLButton (hwndDialog, ID_ABOUT_UG);
+ winOverrideURLButton (hwndDialog, ID_ABOUT_FAQ);
+
+ return TRUE;
+
+ case WM_DRAWITEM:
+ /* Draw the URL buttons as needed */
+ winDrawURLWindow (lParam);
+ return TRUE;
+
+ case WM_MOUSEMOVE:
+ case WM_NCMOUSEMOVE:
+ /* Show the cursor if it is hidden */
+ if (g_fSoftwareCursor && !g_fCursor)
+ {
+ g_fCursor = TRUE;
+ ShowCursor (TRUE);
+ }
+ return TRUE;
+
+ case WM_COMMAND:
+ switch (LOWORD (wParam))
+ {
+ case IDOK:
+ case IDCANCEL:
+ winDebug ("winAboutDlgProc - WM_COMMAND - IDOK or IDCANCEL\n");
+
+ DestroyWindow (g_hDlgAbout);
+ g_hDlgAbout = NULL;
+
+ /* Fix to make sure keyboard focus isn't trapped */
+ PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0);
+
+ /* Restore window procedures for URL buttons */
+ winUnoverrideURLButton (hwndDialog, ID_ABOUT_CHANGELOG);
+ winUnoverrideURLButton (hwndDialog, ID_ABOUT_WEBSITE);
+ winUnoverrideURLButton (hwndDialog, ID_ABOUT_UG);
+ winUnoverrideURLButton (hwndDialog, ID_ABOUT_FAQ);
+
+ return TRUE;
+
+ case ID_ABOUT_CHANGELOG:
+ {
+ int iReturn;
+#ifdef __CYGWIN__
+ const char * pszCygPath = "/usr/X11R6/share/doc/"
+ "xorg-x11-xwin/changelog.html";
+ char pszWinPath[MAX_PATH + 1];
+
+ /* Convert the POSIX path to a Win32 path */
+ cygwin_conv_to_win32_path (pszCygPath, pszWinPath);
+#else
+ const char * pszWinPath = "http://x.cygwin.com/"
+ "devel/server/changelog.html";
+#endif
+
+ iReturn = (int)ShellExecute (NULL,
+ "open",
+ pszWinPath,
+ NULL,
+ NULL,
+ SW_MAXIMIZE);
+ if (iReturn < 32)
+ {
+ ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_CHANGELOG - "
+ "ShellExecute failed: %d\n",
+ iReturn);
+ }
+ }
+ return TRUE;
+
+ case ID_ABOUT_WEBSITE:
+ {
+ const char * pszPath = __VENDORDWEBSUPPORT__;
+ int iReturn;
+
+ iReturn = (int)ShellExecute (NULL,
+ "open",
+ pszPath,
+ NULL,
+ NULL,
+ SW_MAXIMIZE);
+ if (iReturn < 32)
+ {
+ ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_WEBSITE - "
+ "ShellExecute failed: %d\n",
+ iReturn);
+ }
+ }
+ return TRUE;
+
+ case ID_ABOUT_UG:
+ {
+ const char * pszPath = "http://x.cygwin.com/docs/ug/";
+ int iReturn;
+
+ iReturn = (int)ShellExecute (NULL,
+ "open",
+ pszPath,
+ NULL,
+ NULL,
+ SW_MAXIMIZE);
+ if (iReturn < 32)
+ {
+ ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_UG - "
+ "ShellExecute failed: %d\n",
+ iReturn);
+ }
+ }
+ return TRUE;
+
+ case ID_ABOUT_FAQ:
+ {
+ const char * pszPath = "http://x.cygwin.com/docs/faq/";
+ int iReturn;
+
+ iReturn = (int)ShellExecute (NULL,
+ "open",
+ pszPath,
+ NULL,
+ NULL,
+ SW_MAXIMIZE);
+ if (iReturn < 32)
+ {
+ ErrorF ("winAboutDlgProc - WM_COMMAND - ID_ABOUT_FAQ - "
+ "ShellExecute failed: %d\n",
+ iReturn);
+ }
+ }
+ return TRUE;
+ }
+ break;
+
+ case WM_CLOSE:
+ ErrorF ("winAboutDlgProc - WM_CLOSE\n");
+
+ DestroyWindow (g_hDlgAbout);
+ g_hDlgAbout = NULL;
+
+ /* Fix to make sure keyboard focus isn't trapped */
+ PostMessage (s_pScreenPriv->hwndScreen, WM_NULL, 0, 0);
+
+ /* Restore window procedures for URL buttons */
+ winUnoverrideURLButton (hwndDialog, ID_ABOUT_CHANGELOG);
+ winUnoverrideURLButton (hwndDialog, ID_ABOUT_WEBSITE);
+ winUnoverrideURLButton (hwndDialog, ID_ABOUT_UG);
+ winUnoverrideURLButton (hwndDialog, ID_ABOUT_FAQ);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
diff --git a/xorg-server/hw/xwin/windisplay.c b/xorg-server/hw/xwin/windisplay.c new file mode 100644 index 000000000..316df5ffb --- /dev/null +++ b/xorg-server/hw/xwin/windisplay.c @@ -0,0 +1,60 @@ +/* + * Copyright (C) Jon TURNEY 2009 + * + * 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_XWIN_CONFIG_H +#include <xwin-config.h> +#endif +#include "win.h" + +#include <X11/Xwindows.h> + +/* + Generate a display name string referring to the display of this server, + using a transport we know is enabled +*/ + +void +winGetDisplayName(char *szDisplay, unsigned int screen) +{ + if (TransIsListening("local")) + { + snprintf(szDisplay, 512, ":%s.%d", display, screen); + } + else if (TransIsListening("inet")) + { + snprintf(szDisplay, 512, "127.0.0.1:%s.%d", display, screen); + } + else if (TransIsListening("inet6")) + { + snprintf(szDisplay, 512, "::1:%s.%d", display, screen); + } + else + { + // this can't happen! + winDebug ("winGetDisplay: Don't know what to use for DISPLAY\n"); + snprintf(szDisplay, 512, "localhost:%s.%d", display, screen); + } + + winDebug ("winGetDisplay: DISPLAY=%s\n", szDisplay); +} diff --git a/xorg-server/hw/xwin/winengine.c b/xorg-server/hw/xwin/winengine.c index fb9aed8a0..fadd11b39 100644 --- a/xorg-server/hw/xwin/winengine.c +++ b/xorg-server/hw/xwin/winengine.c @@ -69,12 +69,12 @@ winDetectSupportedEngines (void) { case VER_PLATFORM_WIN32_NT: /* Engine 4 is supported on NT only */ - winErrorFVerb (2, "winDetectSupportedEngines - Windows NT/2000/XP\n"); + winDebug ("winDetectSupportedEngines - Windows NT/2000/XP\n"); break; case VER_PLATFORM_WIN32_WINDOWS: /* Engine 4 is supported on NT only */ - winErrorFVerb (2, "winDetectSupportedEngines - Windows 95/98/Me\n"); + winDebug ("winDetectSupportedEngines - Windows 95/98/Me\n"); break; } @@ -100,13 +100,13 @@ winDetectSupportedEngines (void) if (FAILED (ddrval)) { /* No DirectDraw support */ - winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw not installed\n"); + winDebug ("winDetectSupportedEngines - DirectDraw not installed\n"); return; } else { /* We have DirectDraw */ - winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw installed\n"); + winDebug ("winDetectSupportedEngines - DirectDraw installed\n"); g_dwEnginesSupported |= WIN_SERVER_SHADOW_DD; #ifdef XWIN_PRIMARYFB @@ -114,7 +114,7 @@ winDetectSupportedEngines (void) if (osvi.dwPlatformId == VER_PLATFORM_WIN32_NT) { g_dwEnginesSupported |= WIN_SERVER_PRIMARY_DD; - winErrorFVerb (2, "winDetectSupportedEngines - Allowing PrimaryDD\n"); + winDebug ("winDetectSupportedEngines - Allowing PrimaryDD\n"); } #endif } @@ -126,7 +126,7 @@ winDetectSupportedEngines (void) if (SUCCEEDED (ddrval)) { /* We have DirectDraw4 */ - winErrorFVerb (2, "winDetectSupportedEngines - DirectDraw4 installed\n"); + winDebug ("winDetectSupportedEngines - DirectDraw4 installed\n"); g_dwEnginesSupported |= WIN_SERVER_SHADOW_DDNL; } @@ -137,7 +137,7 @@ winDetectSupportedEngines (void) IDirectDraw_Release (lpdd); } - winErrorFVerb (2, "winDetectSupportedEngines - Returning, supported engines %08x\n", + winDebug ("winDetectSupportedEngines - Returning, supported engines %08x\n", (unsigned int) g_dwEnginesSupported); } @@ -178,7 +178,7 @@ winSetEngine (ScreenPtr pScreen) /* ShadowGDI is the only engine that supports windowed PseudoColor */ if (dwBPP == 8 && !pScreenInfo->fFullScreen) { - winErrorFVerb (2, "winSetEngine - Windowed && PseudoColor => ShadowGDI\n"); + winDebug ("winSetEngine - Windowed && PseudoColor => ShadowGDI\n"); pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; /* Set engine function pointers */ @@ -200,7 +200,7 @@ winSetEngine (ScreenPtr pScreen) #endif ) { - winErrorFVerb (2, "winSetEngine - Multi Window or Rootless => ShadowGDI\n"); + winDebug ("winSetEngine - Multi Window or Rootless => ShadowGDI\n"); pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; /* Set engine function pointers */ @@ -211,7 +211,7 @@ winSetEngine (ScreenPtr pScreen) /* If the user's choice is supported, we'll use that */ if (g_dwEnginesSupported & pScreenInfo->dwEnginePreferred) { - winErrorFVerb (2, "winSetEngine - Using user's preference: %d\n", + winDebug ("winSetEngine - Using user's preference: %d\n", (int) pScreenInfo->dwEnginePreferred); pScreenInfo->dwEngine = pScreenInfo->dwEnginePreferred; @@ -246,7 +246,7 @@ winSetEngine (ScreenPtr pScreen) /* ShadowDDNL has good performance, so why not */ if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DDNL) { - winErrorFVerb (2, "winSetEngine - Using Shadow DirectDraw NonLocking\n"); + winDebug ("winSetEngine - Using Shadow DirectDraw NonLocking\n"); pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DDNL; /* Set engine function pointers */ @@ -257,7 +257,7 @@ winSetEngine (ScreenPtr pScreen) /* ShadowDD is next in line */ if (g_dwEnginesSupported & WIN_SERVER_SHADOW_DD) { - winErrorFVerb (2, "winSetEngine - Using Shadow DirectDraw\n"); + winDebug ("winSetEngine - Using Shadow DirectDraw\n"); pScreenInfo->dwEngine = WIN_SERVER_SHADOW_DD; /* Set engine function pointers */ @@ -268,7 +268,7 @@ winSetEngine (ScreenPtr pScreen) /* ShadowGDI is next in line */ if (g_dwEnginesSupported & WIN_SERVER_SHADOW_GDI) { - winErrorFVerb (2, "winSetEngine - Using Shadow GDI DIB\n"); + winDebug ("winSetEngine - Using Shadow GDI DIB\n"); pScreenInfo->dwEngine = WIN_SERVER_SHADOW_GDI; /* Set engine function pointers */ diff --git a/xorg-server/hw/xwin/winerror.c b/xorg-server/hw/xwin/winerror.c index 9ed27c3d0..7cbfd65e2 100644 --- a/xorg-server/hw/xwin/winerror.c +++ b/xorg-server/hw/xwin/winerror.c @@ -41,9 +41,10 @@ /* References to external symbols */ extern char * g_pszCommandLine; -extern char * g_pszLogFile; +extern const char * g_pszLogFile; extern Bool g_fSilentFatalError; - +extern Bool g_fSilentDupError; +extern Bool g_fLogInited; #ifdef DDXOSVERRORF /* Prototype */ @@ -62,6 +63,24 @@ OsVendorVErrorF (const char *pszFormat, va_list va_args) pthread_mutex_lock (&s_pmPrinting); #endif + /* + If we want to silence it, + detect if we are going to abort due to duplication error + */ + if (g_fSilentDupError) + { + if ((strcmp(pszFormat, + "InitOutput - Duplicate invocation on display " + "number: %s. Exiting.\n") == 0) + || (strcmp(pszFormat, + "Server is already active for display %s\n%s %s\n%s\n") == 0) + || (strcmp(pszFormat, + "MakeAllCOTSServerListeners: server already running\n") == 0)) + { + g_fSilentFatalError = TRUE; + } + } + /* Print the error message to a log file, could be stderr */ LogVWrite (0, pszFormat, va_args); @@ -87,6 +106,12 @@ OsVendorFatalError (void) if (g_fSilentFatalError) return; + if (!g_fLogInited) { + g_fLogInited = TRUE; + g_pszLogFile = LogInit (g_pszLogFile, NULL); + } + LogClose (); + winMessageBoxF ( "A fatal error has occurred and " PROJECT_NAME " will now exit.\n" \ "Please open %s for more information.\n", diff --git a/xorg-server/hw/xwin/winfont.c b/xorg-server/hw/xwin/winfont.c index af3e90da5..5a3011c0a 100644 --- a/xorg-server/hw/xwin/winfont.c +++ b/xorg-server/hw/xwin/winfont.c @@ -42,9 +42,7 @@ winRealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont) BOOL fResult = TRUE; winScreenPriv(pScreen); -#if CYGDEBUG - winTrace ("winRealizeFont (%p, %p)\n", pScreen, pFont); -#endif + winDebug ("winRealizeFont (%p, %p)\n", pScreen, pFont); WIN_UNWRAP(RealizeFont); if (pScreen->RealizeFont) @@ -62,9 +60,7 @@ winUnrealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont) BOOL fResult = TRUE; winScreenPriv(pScreen); -#if CYGDEBUG - winTrace ("winUnrealizeFont (%p, %p)\n", pScreen, pFont); -#endif + winDebug ("winUnrealizeFont (%p, %p)\n", pScreen, pFont); WIN_UNWRAP(UnrealizeFont); if (pScreen->UnrealizeFont) @@ -72,9 +68,5 @@ winUnrealizeFontNativeGDI (ScreenPtr pScreen, FontPtr pFont) WIN_WRAP(UnrealizeFont, winUnrealizeFontNativeGDI); return fResult; -#if CYGDEBUG - winDebug ("winUnrealizeFont()\n"); -#endif - return TRUE; } #endif diff --git a/xorg-server/hw/xwin/wingc.c b/xorg-server/hw/xwin/wingc.c index 1f3775263..61ba78a54 100644 --- a/xorg-server/hw/xwin/wingc.c +++ b/xorg-server/hw/xwin/wingc.c @@ -41,47 +41,14 @@ winPushPixels (GCPtr pGC, PixmapPtr pBitMap, DrawablePtr pDrawable, int dx, int * Local prototypes */ -#if 0 -static void -winChangeGCNativeGDI (GCPtr pGC, unsigned long ulChanges); -#endif - static void winValidateGCNativeGDI (GCPtr pGC, unsigned long changes, DrawablePtr pDrawable); -#if 0 -static void -winCopyGCNativeGDI (GCPtr pGCsrc, unsigned long ulMask, GCPtr pGCdst); -#endif - static void winDestroyGCNativeGDI (GCPtr pGC); -#if 0 -static void -winChangeClipNativeGDI (GCPtr pGC, int nType, pointer pValue, int nRects); - -static void -winDestroyClipNativeGDI (GCPtr pGC); - -static void -winCopyClipNativeGDI (GCPtr pGCdst, GCPtr pGCsrc); -#endif - -#if 0 -/* GC Handling Routines */ -const GCFuncs winGCFuncs = { - winValidateGCNativeGDI, - winChangeGCNativeGDI, - winCopyGCNativeGDI, - winDestroyGCNativeGDI, - winChangeClipNativeGDI, - winDestroyClipNativeGDI, - winCopyClipNativeGDI, -}; -#else const GCFuncs winGCFuncs = { winValidateGCNativeGDI, miChangeGC, @@ -91,7 +58,6 @@ const GCFuncs winGCFuncs = { miDestroyClip, miCopyClip, }; -#endif /* Drawing Primitives */ const GCOps winGCOps = { @@ -112,13 +78,8 @@ const GCOps winGCOps = { miPolyText16, miImageText8, miImageText16, -#if 0 - winImageGlyphBltNativeGDI, - winPolyGlyphBltNativeGDI, -#else miImageGlyphBlt, miPolyGlyphBlt, -#endif miPushPixels, }; @@ -132,10 +93,8 @@ winCreateGCNativeGDI (GCPtr pGC) winPrivGCPtr pGCPriv = NULL; winPrivScreenPtr pScreenPriv = NULL; -#if 0 - ErrorF ("winCreateGCNativeGDI - depth: %d\n", + winDebug ("winCreateGCNativeGDI - depth: %d\n", pGC->depth); -#endif pGC->clientClip = NULL; pGC->clientClipType = CT_NONE; @@ -166,19 +125,6 @@ winCreateGCNativeGDI (GCPtr pGC) return TRUE; } - -#if 0 -/* See Porting Layer Definition - p. 45 */ -static void -winChangeGCNativeGDI (GCPtr pGC, unsigned long ulChanges) -{ -#if 0 - ErrorF ("winChangeGCNativeGDI () - Doing nothing\n"); -#endif -} -#endif - - static void winValidateGCNativeGDI (GCPtr pGC, unsigned long ulChanges, @@ -192,16 +138,6 @@ winValidateGCNativeGDI (GCPtr pGC, } -#if 0 -/* See Porting Layer Definition - p. 46 */ -static void -winCopyGCNativeGDI (GCPtr pGCsrc, unsigned long ulMask, GCPtr pGCdst) -{ - -} -#endif - - /* See Porting Layer Definition - p. 46 */ static void winDestroyGCNativeGDI (GCPtr pGC) @@ -229,28 +165,3 @@ winDestroyGCNativeGDI (GCPtr pGC) /* Invalidate the GC privates pointer */ winSetGCPriv (pGC, NULL); } - -#if 0 -/* See Porting Layer Definition - p. 46 */ -static void -winChangeClipNativeGDI (GCPtr pGC, int nType, pointer pValue, int nRects) -{ - -} - - -/* See Porting Layer Definition - p. 47 */ -static void -winDestroyClipNativeGDI (GCPtr pGC) -{ - -} - - -/* See Porting Layer Definition - p. 47 */ -static void -winCopyClipNativeGDI (GCPtr pGCdst, GCPtr pGCsrc) -{ - -} -#endif diff --git a/xorg-server/hw/xwin/wingetsp.c b/xorg-server/hw/xwin/wingetsp.c index 03f7f1012..e9c23881f 100644 --- a/xorg-server/hw/xwin/wingetsp.c +++ b/xorg-server/hw/xwin/wingetsp.c @@ -59,10 +59,8 @@ winGetSpansNativeGDI (DrawablePtr pDrawable, switch (pDrawable->type) { case DRAWABLE_PIXMAP: -#if 0 - ErrorF ("winGetSpans - DRAWABLE_PIXMAP %08x\n", + winDebug ("winGetSpans - DRAWABLE_PIXMAP %08x\n", pDrawable); -#endif pPixmap = (PixmapPtr) pDrawable; pPixmapPriv = winGetPixmapPriv (pPixmap); @@ -107,12 +105,6 @@ winGetSpansNativeGDI (DrawablePtr pDrawable, SelectObject (hdcMem, hbmpOrig); DeleteObject (hbmpWindow); -#if 0 - ErrorF ("(%dx%dx%d) (%d,%d) w: %d\n", - pDrawable->width, pDrawable->height, pDrawable->depth, - pPoint->x, pPoint->y, *piWidth); -#endif - /* Calculate offset of next bit destination */ pDst += PixmapBytePad (*piWidth, pDrawable->depth); } @@ -126,9 +118,6 @@ winGetSpansNativeGDI (DrawablePtr pDrawable, break; case DRAWABLE_WINDOW: -#if 0 - ErrorF ("winGetSpans - DRAWABLE_WINDOW\n"); -#endif /* Open a memory HDC */ hdcMem = CreateCompatibleDC (NULL); @@ -163,12 +152,6 @@ winGetSpansNativeGDI (DrawablePtr pDrawable, DeleteObject (hbmpWindow); -#if 0 - ErrorF ("(%dx%dx%d) (%d,%d) w: %d\n", - pDrawable->width, pDrawable->height, pDrawable->depth, - pPoint->x, pPoint->y, *piWidth); -#endif - /* Calculate offset of next bit destination */ pDst += PixmapBytePad (*piWidth, pDrawable->depth); } diff --git a/xorg-server/hw/xwin/winglobals.c b/xorg-server/hw/xwin/winglobals.c index 7bb4a602d..768eeb8fa 100644 --- a/xorg-server/hw/xwin/winglobals.c +++ b/xorg-server/hw/xwin/winglobals.c @@ -1,146 +1,146 @@ -/* - *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved. - *Copyright (C) Colin Harrison 2005-2008 - * - *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 HAROLD L HUNT II 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 Harold L Hunt II - *shall not be used in advertising or otherwise to promote the sale, use - *or other dealings in this Software without prior written authorization - *from Harold L Hunt II. - * - * Authors: Harold L Hunt II - * Colin Harrison - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" - - -/* - * General global variables - */ - -int g_iNumScreens = 0; -winScreenInfo g_ScreenInfo[MAXSCREENS]; -int g_iLastScreen = -1; -#ifdef HAS_DEVWINDOWS -int g_fdMessageQueue = WIN_FD_INVALID; -#endif -static int g_iScreenPrivateKeyIndex; -DevPrivateKey g_iScreenPrivateKey = &g_iScreenPrivateKeyIndex; -static int g_iCmapPrivateKeyIndex; -DevPrivateKey g_iCmapPrivateKey = &g_iCmapPrivateKeyIndex; -static int g_iGCPrivateKeyIndex; -DevPrivateKey g_iGCPrivateKey = &g_iGCPrivateKeyIndex; -static int g_iPixmapPrivateKeyIndex; -DevPrivateKey g_iPixmapPrivateKey = &g_iPixmapPrivateKeyIndex; -static int g_iWindowPrivateKeyIndex; -DevPrivateKey g_iWindowPrivateKey = &g_iWindowPrivateKeyIndex; -unsigned long g_ulServerGeneration = 0; -Bool g_fInitializedDefaultScreens = FALSE; -DWORD g_dwEnginesSupported = 0; -HINSTANCE g_hInstance = 0; -HWND g_hDlgDepthChange = NULL; -HWND g_hDlgExit = NULL; -HWND g_hDlgAbout = NULL; -const char * g_pszQueryHost = NULL; -Bool g_fXdmcpEnabled = FALSE; -Bool g_fAuthEnabled = FALSE; -HICON g_hIconX = NULL; -HICON g_hSmallIconX = NULL; -#ifndef RELOCATE_PROJECTROOT -char * g_pszLogFile = "/tmp/XWin.log"; -#else -char * g_pszLogFile = "XWin.log"; -Bool g_fLogFileChanged = FALSE; -#endif -int g_iLogVerbose = 2; -Bool g_fLogInited = FALSE; -char * g_pszCommandLine = NULL; -Bool g_fSilentFatalError = FALSE; -DWORD g_dwCurrentThreadID = 0; -Bool g_fKeyboardHookLL = FALSE; -HHOOK g_hhookKeyboardLL = NULL; -HWND g_hwndKeyboardFocus = NULL; -Bool g_fNoHelpMessageBox = FALSE; -Bool g_fSoftwareCursor = FALSE; -Bool g_fSilentDupError = FALSE; - - -/* - * Global variables for dynamically loaded libraries and - * their function pointers - */ - -HMODULE g_hmodDirectDraw = NULL; -FARPROC g_fpDirectDrawCreate = NULL; -FARPROC g_fpDirectDrawCreateClipper = NULL; - -HMODULE g_hmodCommonControls = NULL; -FARPROC g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA; - - -#ifdef XWIN_CLIPBOARD -/* - * Wrapped DIX functions - */ -winDispatchProcPtr winProcEstablishConnectionOrig = NULL; -winDispatchProcPtr winProcQueryTreeOrig = NULL; -winDispatchProcPtr winProcSetSelectionOwnerOrig = NULL; - - -/* - * Clipboard variables - */ - -Bool g_fUnicodeClipboard = TRUE; -Bool g_fClipboard = TRUE; -Bool g_fClipboardLaunched = FALSE; -Bool g_fClipboardStarted = FALSE; -pthread_t g_ptClipboardProc; -HWND g_hwndClipboard = NULL; -void *g_pClipboardDisplay = NULL; -Window g_iClipboardWindow = None; -Atom g_atomLastOwnedSelection = None; -#endif - - -/* - * Re-initialize global variables that are invalidated - * by a server reset. - */ - -void -winInitializeGlobals (void) -{ - g_dwCurrentThreadID = GetCurrentThreadId (); - g_hwndKeyboardFocus = NULL; -#ifdef XWIN_CLIPBOARD - g_fClipboardLaunched = FALSE; - g_fClipboardStarted = FALSE; - g_iClipboardWindow = None; - g_pClipboardDisplay = NULL; - g_atomLastOwnedSelection = None; - g_hwndClipboard = NULL; -#endif -} +/*
+ *Copyright (C) 2003-2004 Harold L Hunt II All Rights Reserved.
+ *Copyright (C) Colin Harrison 2005-2008
+ *
+ *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 HAROLD L HUNT II 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 Harold L Hunt II
+ *shall not be used in advertising or otherwise to promote the sale, use
+ *or other dealings in this Software without prior written authorization
+ *from Harold L Hunt II.
+ *
+ * Authors: Harold L Hunt II
+ * Colin Harrison
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+
+
+/*
+ * General global variables
+ */
+
+int g_iNumScreens = 0;
+winScreenInfo g_ScreenInfo[MAXSCREENS];
+int g_iLastScreen = -1;
+#ifdef HAS_DEVWINDOWS
+int g_fdMessageQueue = WIN_FD_INVALID;
+#endif
+static int g_iScreenPrivateKeyIndex;
+DevPrivateKey g_iScreenPrivateKey = &g_iScreenPrivateKeyIndex;
+static int g_iCmapPrivateKeyIndex;
+DevPrivateKey g_iCmapPrivateKey = &g_iCmapPrivateKeyIndex;
+static int g_iGCPrivateKeyIndex;
+DevPrivateKey g_iGCPrivateKey = &g_iGCPrivateKeyIndex;
+static int g_iPixmapPrivateKeyIndex;
+DevPrivateKey g_iPixmapPrivateKey = &g_iPixmapPrivateKeyIndex;
+static int g_iWindowPrivateKeyIndex;
+DevPrivateKey g_iWindowPrivateKey = &g_iWindowPrivateKeyIndex;
+unsigned long g_ulServerGeneration = 0;
+Bool g_fInitializedDefaultScreens = FALSE;
+DWORD g_dwEnginesSupported = 0;
+HINSTANCE g_hInstance = 0;
+HWND g_hDlgDepthChange = NULL;
+HWND g_hDlgExit = NULL;
+HWND g_hDlgAbout = NULL;
+const char * g_pszQueryHost = NULL;
+Bool g_fXdmcpEnabled = FALSE;
+Bool g_fAuthEnabled = FALSE;
+HICON g_hIconX = NULL;
+HICON g_hSmallIconX = NULL;
+#ifndef RELOCATE_PROJECTROOT
+const char * g_pszLogFile = DEFAULT_LOGDIR "/XWin.%s.log";
+#else
+const char * g_pszLogFile = "XWin.log";
+Bool g_fLogFileChanged = FALSE;
+#endif
+int g_iLogVerbose = 2;
+Bool g_fLogInited = FALSE;
+char * g_pszCommandLine = NULL;
+Bool g_fSilentFatalError = FALSE;
+DWORD g_dwCurrentThreadID = 0;
+Bool g_fKeyboardHookLL = FALSE;
+HHOOK g_hhookKeyboardLL = NULL;
+HWND g_hwndKeyboardFocus = NULL;
+Bool g_fNoHelpMessageBox = FALSE;
+Bool g_fSoftwareCursor = FALSE;
+Bool g_fSilentDupError = FALSE;
+Bool g_fNativeGl = FALSE;
+
+/*
+ * Global variables for dynamically loaded libraries and
+ * their function pointers
+ */
+
+HMODULE g_hmodDirectDraw = NULL;
+FARPROC g_fpDirectDrawCreate = NULL;
+FARPROC g_fpDirectDrawCreateClipper = NULL;
+
+HMODULE g_hmodCommonControls = NULL;
+FARPROC g_fpTrackMouseEvent = (FARPROC) (void (*)(void))NoopDDA;
+
+
+#ifdef XWIN_CLIPBOARD
+/*
+ * Wrapped DIX functions
+ */
+winDispatchProcPtr winProcEstablishConnectionOrig = NULL;
+winDispatchProcPtr winProcQueryTreeOrig = NULL;
+winDispatchProcPtr winProcSetSelectionOwnerOrig = NULL;
+
+
+/*
+ * Clipboard variables
+ */
+
+Bool g_fUnicodeClipboard = TRUE;
+Bool g_fClipboard = TRUE;
+Bool g_fClipboardLaunched = FALSE;
+Bool g_fClipboardStarted = FALSE;
+pthread_t g_ptClipboardProc;
+HWND g_hwndClipboard = NULL;
+void *g_pClipboardDisplay = NULL;
+Window g_iClipboardWindow = None;
+Atom g_atomLastOwnedSelection = None;
+#endif
+
+
+/*
+ * Re-initialize global variables that are invalidated
+ * by a server reset.
+ */
+
+void
+winInitializeGlobals (void)
+{
+ g_dwCurrentThreadID = GetCurrentThreadId ();
+ g_hwndKeyboardFocus = NULL;
+#ifdef XWIN_CLIPBOARD
+ g_fClipboardLaunched = FALSE;
+ g_fClipboardStarted = FALSE;
+ g_iClipboardWindow = None;
+ g_pClipboardDisplay = NULL;
+ g_atomLastOwnedSelection = None;
+ g_hwndClipboard = NULL;
+#endif
+}
diff --git a/xorg-server/hw/xwin/winkeybd.c b/xorg-server/hw/xwin/winkeybd.c index a423b499a..dd00655e3 100644 --- a/xorg-server/hw/xwin/winkeybd.c +++ b/xorg-server/hw/xwin/winkeybd.c @@ -1,617 +1,616 @@ -/* - *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: Dakshinamurthy Karra - * Suhaib M Siddiqi - * Peter Busch - * Harold L Hunt II - */ - - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" -#include "winkeybd.h" -#include "winconfig.h" -#include "winmsg.h" - -#include "xkbsrv.h" - -static Bool g_winKeyState[NUM_KEYCODES]; - -/* - * Local prototypes - */ - -static void -winGetKeyMappings (KeySymsPtr pKeySyms, CARD8 *pModMap); - -static void -winKeybdBell (int iPercent, DeviceIntPtr pDeviceInt, - pointer pCtrl, int iClass); - -static void -winKeybdCtrl (DeviceIntPtr pDevice, KeybdCtrl *pCtrl); - - -/* - * Translate a Windows WM_[SYS]KEY(UP/DOWN) message - * into an ASCII scan code. - * - * We do this ourselves, rather than letting Windows handle it, - * because Windows tends to munge the handling of special keys, - * like AltGr on European keyboards. - */ - -void -winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode) -{ - int iKeyFixup = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 1]; - int iKeyFixupEx = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 2]; - int iParam = HIWORD (lParam); - int iParamScanCode = LOBYTE (iParam); - -/* WM_ key messages faked by Vista speech recognition (WSR) don't have a - * scan code. - * - * Vocola 3 (Rick Mohr's supplement to WSR) uses - * System.Windows.Forms.SendKeys.SendWait(), which appears always to give a - * scan code of 1 - */ - if (iParamScanCode <= 1) - { - if (VK_PRIOR <= wParam && wParam <= VK_DOWN) - /* Trigger special case table to translate to extended - * keycode, otherwise if num_lock is on, we can get keypad - * numbers instead of navigation keys. */ - iParam |= KF_EXTENDED; - else - iParamScanCode = MapVirtualKeyEx(wParam, - /*MAPVK_VK_TO_VSC*/0, - GetKeyboardLayout(0)); - } - - /* Branch on special extended, special non-extended, or normal key */ - if ((iParam & KF_EXTENDED) && iKeyFixupEx) - *piScanCode = iKeyFixupEx; - else if (iKeyFixup) - *piScanCode = iKeyFixup; - else if (wParam == 0 && iParamScanCode == 0x70) - *piScanCode = KEY_HKTG; - else - switch (iParamScanCode) - { - case 0x70: - *piScanCode = KEY_HKTG; - break; - case 0x73: - *piScanCode = KEY_BSlash2; - break; - default: - *piScanCode = iParamScanCode; - break; - } -} - - -/* - * We call this function from winKeybdProc when we are - * initializing the keyboard. - */ - -static void -winGetKeyMappings (KeySymsPtr pKeySyms, CARD8 *pModMap) -{ - int i; - KeySym *pMap = map; - KeySym *pKeySym; - - /* - * Initialize all key states to up... which may not be true - * but it is close enough. - */ - ZeroMemory (g_winKeyState, sizeof (g_winKeyState[0]) * NUM_KEYCODES); - - /* MAP_LENGTH is defined in Xserver/include/input.h to be 256 */ - for (i = 0; i < MAP_LENGTH; i++) - pModMap[i] = NoSymbol; /* make sure it is restored */ - - /* Loop through all valid entries in the key symbol table */ - for (pKeySym = pMap, i = MIN_KEYCODE; - i < (MIN_KEYCODE + NUM_KEYCODES); - i++, pKeySym += GLYPHS_PER_KEY) - { - switch (*pKeySym) - { - case XK_Shift_L: - case XK_Shift_R: - pModMap[i] = ShiftMask; - break; - - case XK_Control_L: - case XK_Control_R: - pModMap[i] = ControlMask; - break; - - case XK_Caps_Lock: - pModMap[i] = LockMask; - break; - - case XK_Alt_L: - case XK_Alt_R: - pModMap[i] = AltMask; - break; - - case XK_Num_Lock: - pModMap[i] = NumLockMask; - break; - - case XK_Scroll_Lock: - pModMap[i] = ScrollLockMask; - break; - -#if 0 - case XK_Super_L: - case XK_Super_R: - pModMap[i] = Mod4Mask; - break; -#else - /* Hirigana/Katakana toggle */ - case XK_Kana_Lock: - case XK_Kana_Shift: - pModMap[i] = KanaMask; - break; -#endif - - /* alternate toggle for multinational support */ - case XK_Mode_switch: - pModMap[i] = AltLangMask; - break; - } - } - - pKeySyms->map = (KeySym *) pMap; - pKeySyms->mapWidth = GLYPHS_PER_KEY; - pKeySyms->minKeyCode = MIN_KEYCODE; - pKeySyms->maxKeyCode = MAX_KEYCODE; -} - - -/* Ring the keyboard bell (system speaker on PCs) */ -static void -winKeybdBell (int iPercent, DeviceIntPtr pDeviceInt, - pointer pCtrl, int iClass) -{ - /* - * We can't use Beep () here because it uses the PC speaker - * on NT/2000. MessageBeep (MB_OK) will play the default system - * sound on systems with a sound card or it will beep the PC speaker - * on systems that do not have a sound card. - */ - MessageBeep (MB_OK); -} - - -/* Change some keyboard configuration parameters */ -static void -winKeybdCtrl (DeviceIntPtr pDevice, KeybdCtrl *pCtrl) -{ -} - - -/* - * See Porting Layer Definition - p. 18 - * winKeybdProc is known as a DeviceProc. - */ - -int -winKeybdProc (DeviceIntPtr pDeviceInt, int iState) -{ - DevicePtr pDevice = (DevicePtr) pDeviceInt; - XkbSrvInfoPtr xkbi; - XkbControlsPtr ctrl; - - switch (iState) - { - case DEVICE_INIT: - winConfigKeyboard (pDeviceInt); - - /* FIXME: Maybe we should use winGetKbdLeds () here? */ - defaultKeyboardControl.leds = g_winInfo.keyboard.leds; - - winErrorFVerb(2, "Rules = \"%s\" Model = \"%s\" Layout = \"%s\"" - " Variant = \"%s\" Options = \"%s\"\n", - g_winInfo.xkb.rules ? g_winInfo.xkb.rules : "none", - g_winInfo.xkb.model ? g_winInfo.xkb.model : "none", - g_winInfo.xkb.layout ? g_winInfo.xkb.layout : "none", - g_winInfo.xkb.variant ? g_winInfo.xkb.variant : "none", - g_winInfo.xkb.options ? g_winInfo.xkb.options : "none"); - - InitKeyboardDeviceStruct (pDeviceInt, - &g_winInfo.xkb, - winKeybdBell, - winKeybdCtrl); - - xkbi = pDeviceInt->key->xkbInfo; - if ((xkbi != NULL) && (xkbi->desc != NULL)) - { - ctrl = xkbi->desc->ctrls; - ctrl->repeat_delay = g_winInfo.keyboard.delay; - ctrl->repeat_interval = 1000/g_winInfo.keyboard.rate; - } - else - { - winErrorFVerb (1, "winKeybdProc - Error initializing keyboard AutoRepeat\n"); - } - - break; - - case DEVICE_ON: - pDevice->on = TRUE; - - // immediately copy the state of this keyboard device to the VCK - // (which otherwise happens lazily after the first keypress) - CopyKeyClass(pDeviceInt, inputInfo.keyboard); - break; - - case DEVICE_CLOSE: - case DEVICE_OFF: - pDevice->on = FALSE; - break; - } - - return Success; -} - - -/* - * Detect current mode key states upon server startup. - * - * Simulate a press and release of any key that is currently - * toggled. - */ - -void -winInitializeModeKeyStates (void) -{ - /* Restore NumLock */ - if (GetKeyState (VK_NUMLOCK) & 0x0001) - { - winSendKeyEvent (KEY_NumLock, TRUE); - winSendKeyEvent (KEY_NumLock, FALSE); - } - - /* Restore CapsLock */ - if (GetKeyState (VK_CAPITAL) & 0x0001) - { - winSendKeyEvent (KEY_CapsLock, TRUE); - winSendKeyEvent (KEY_CapsLock, FALSE); - } - - /* Restore ScrollLock */ - if (GetKeyState (VK_SCROLL) & 0x0001) - { - winSendKeyEvent (KEY_ScrollLock, TRUE); - winSendKeyEvent (KEY_ScrollLock, FALSE); - } - - /* Restore KanaLock */ - if (GetKeyState (VK_KANA) & 0x0001) - { - winSendKeyEvent (KEY_HKTG, TRUE); - winSendKeyEvent (KEY_HKTG, FALSE); - } -} - - -/* - * Upon regaining the keyboard focus we must - * resynchronize our internal mode key states - * with the actual state of the keys. - */ - -void -winRestoreModeKeyStates (void) -{ - DWORD dwKeyState; - BOOL processEvents = TRUE; - unsigned short internalKeyStates; - - /* X server is being initialized */ - if (!inputInfo.keyboard) - return; - - /* Only process events if the rootwindow is mapped. The keyboard events - * will cause segfaults otherwise */ - if (WindowTable && WindowTable[0] && WindowTable[0]->mapped == FALSE) - processEvents = FALSE; - - /* Force to process all pending events in the mi event queue */ - if (processEvents) - mieqProcessInputEvents (); - - /* Read the mode key states of our X server */ - /* (stored in the virtual core keyboard) */ - internalKeyStates = XkbStateFieldFromRec(&inputInfo.keyboard->key->xkbInfo->state); - winDebug("winRestoreModeKeyStates: state %d\n", internalKeyStates); - - /* - * NOTE: The C XOR operator, ^, will not work here because it is - * a bitwise operator, not a logical operator. C does not - * have a logical XOR operator, so we use a macro instead. - */ - - /* Has the key state changed? */ - dwKeyState = GetKeyState (VK_NUMLOCK) & 0x0001; - if (WIN_XOR (internalKeyStates & NumLockMask, dwKeyState)) - { - winSendKeyEvent (KEY_NumLock, TRUE); - winSendKeyEvent (KEY_NumLock, FALSE); - } - - /* Has the key state changed? */ - dwKeyState = GetKeyState (VK_CAPITAL) & 0x0001; - if (WIN_XOR (internalKeyStates & LockMask, dwKeyState)) - { - winSendKeyEvent (KEY_CapsLock, TRUE); - winSendKeyEvent (KEY_CapsLock, FALSE); - } - - /* Has the key state changed? */ - dwKeyState = GetKeyState (VK_SCROLL) & 0x0001; - if (WIN_XOR (internalKeyStates & ScrollLockMask, dwKeyState)) - { - winSendKeyEvent (KEY_ScrollLock, TRUE); - winSendKeyEvent (KEY_ScrollLock, FALSE); - } - - /* Has the key state changed? */ - dwKeyState = GetKeyState (VK_KANA) & 0x0001; - if (WIN_XOR (internalKeyStates & KanaMask, dwKeyState)) - { - winSendKeyEvent (KEY_HKTG, TRUE); - winSendKeyEvent (KEY_HKTG, FALSE); - } -} - - -/* - * Look for the lovely fake Control_L press/release generated by Windows - * when AltGr is pressed/released on a non-U.S. keyboard. - */ - -Bool -winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam) -{ - MSG msgNext; - LONG lTime; - Bool fReturn; - - /* - * Fake Ctrl_L presses will be followed by an Alt_R keypress - * with the same timestamp as the Ctrl_L press. - */ - if ((message == WM_KEYDOWN || message == WM_SYSKEYDOWN) - && wParam == VK_CONTROL - && (HIWORD (lParam) & KF_EXTENDED) == 0) - { - /* Got a Ctrl_L press */ - - /* Get time of current message */ - lTime = GetMessageTime (); - - /* Look for fake Ctrl_L preceeding an Alt_R press. */ - fReturn = PeekMessage (&msgNext, NULL, - WM_KEYDOWN, WM_SYSKEYDOWN, - PM_NOREMOVE); - - /* - * Try again if the first call fails. - * NOTE: This usually happens when TweakUI is enabled. - */ - if (!fReturn) - { - /* Voodoo to make sure that the Alt_R message has posted */ - Sleep (0); - - /* Look for fake Ctrl_L preceeding an Alt_R press. */ - fReturn = PeekMessage (&msgNext, NULL, - WM_KEYDOWN, WM_SYSKEYDOWN, - PM_NOREMOVE); - } - if (msgNext.message != WM_KEYDOWN && msgNext.message != WM_SYSKEYDOWN) - fReturn = 0; - - /* Is next press an Alt_R with the same timestamp? */ - if (fReturn && msgNext.wParam == VK_MENU - && msgNext.time == lTime - && (HIWORD (msgNext.lParam) & KF_EXTENDED)) - { - /* - * Next key press is Alt_R with same timestamp as current - * Ctrl_L message. Therefore, this Ctrl_L press is a fake - * event, so discard it. - */ - return TRUE; - } - } - - /* - * Fake Ctrl_L releases will be followed by an Alt_R release - * with the same timestamp as the Ctrl_L release. - */ - if ((message == WM_KEYUP || message == WM_SYSKEYUP) - && wParam == VK_CONTROL - && (HIWORD (lParam) & KF_EXTENDED) == 0) - { - /* Got a Ctrl_L release */ - - /* Get time of current message */ - lTime = GetMessageTime (); - - /* Look for fake Ctrl_L release preceeding an Alt_R release. */ - fReturn = PeekMessage (&msgNext, NULL, - WM_KEYUP, WM_SYSKEYUP, - PM_NOREMOVE); - - /* - * Try again if the first call fails. - * NOTE: This usually happens when TweakUI is enabled. - */ - if (!fReturn) - { - /* Voodoo to make sure that the Alt_R message has posted */ - Sleep (0); - - /* Look for fake Ctrl_L release preceeding an Alt_R release. */ - fReturn = PeekMessage (&msgNext, NULL, - WM_KEYUP, WM_SYSKEYUP, - PM_NOREMOVE); - } - - if (msgNext.message != WM_KEYUP && msgNext.message != WM_SYSKEYUP) - fReturn = 0; - - /* Is next press an Alt_R with the same timestamp? */ - if (fReturn - && (msgNext.message == WM_KEYUP - || msgNext.message == WM_SYSKEYUP) - && msgNext.wParam == VK_MENU - && msgNext.time == lTime - && (HIWORD (msgNext.lParam) & KF_EXTENDED)) - { - /* - * Next key release is Alt_R with same timestamp as current - * Ctrl_L message. Therefore, this Ctrl_L release is a fake - * event, so discard it. - */ - return TRUE; - } - } - - /* Not a fake control left press/release */ - return FALSE; -} - - -/* - * Lift any modifier keys that are pressed - */ - -void -winKeybdReleaseKeys (void) -{ - int i; - -#ifdef HAS_DEVWINDOWS - /* Verify that the mi input system has been initialized */ - if (g_fdMessageQueue == WIN_FD_INVALID) - return; -#endif - - /* Loop through all keys */ - for (i = 0; i < NUM_KEYCODES; ++i) - { - /* Pop key if pressed */ - if (g_winKeyState[i]) - winSendKeyEvent (i, FALSE); - - /* Reset pressed flag for keys */ - g_winKeyState[i] = FALSE; - } -} - - -/* - * Take a raw X key code and send an up or down event for it. - * - * Thanks to VNC for inspiration, though it is a simple function. - */ - -void -winSendKeyEvent (DWORD dwKey, Bool fDown) -{ - EventListPtr events; - int i, nevents; - - /* - * When alt-tabing between screens we can get phantom key up messages - * Here we only pass them through it we think we should! - */ - if (g_winKeyState[dwKey] == FALSE && fDown == FALSE) return; - - /* Update the keyState map */ - g_winKeyState[dwKey] = fDown; - - GetEventList(&events); - nevents = GetKeyboardEvents(events, g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE); - - for (i = 0; i < nevents; i++) - mieqEnqueue(g_pwinKeyboard, events[i].event); - -#if CYGDEBUG - ErrorF("winSendKeyEvent: dwKey: %d, fDown: %d, nEvents %d\n", - dwKey, fDown, nevents); -#endif -} - -BOOL winCheckKeyPressed(WPARAM wParam, LPARAM lParam) -{ - switch (wParam) - { - case VK_CONTROL: - if ((lParam & 0x1ff0000) == 0x11d0000 && g_winKeyState[KEY_RCtrl]) - return TRUE; - if ((lParam & 0x1ff0000) == 0x01d0000 && g_winKeyState[KEY_LCtrl]) - return TRUE; - break; - case VK_SHIFT: - if ((lParam & 0x1ff0000) == 0x0360000 && g_winKeyState[KEY_ShiftR]) - return TRUE; - if ((lParam & 0x1ff0000) == 0x02a0000 && g_winKeyState[KEY_ShiftL]) - return TRUE; - break; - default: - return TRUE; - } - return FALSE; -} - -/* Only on shift release message is sent even if both are pressed. - * Fix this here - */ -void winFixShiftKeys (int iScanCode) -{ - if (GetKeyState (VK_SHIFT) & 0x8000) - return; - - if (iScanCode == KEY_ShiftL && g_winKeyState[KEY_ShiftR]) - winSendKeyEvent (KEY_ShiftR, FALSE); - if (iScanCode == KEY_ShiftR && g_winKeyState[KEY_ShiftL]) - winSendKeyEvent (KEY_ShiftL, FALSE); -} +/*
+ *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: Dakshinamurthy Karra
+ * Suhaib M Siddiqi
+ * Peter Busch
+ * Harold L Hunt II
+ */
+
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include "winkeybd.h"
+#include "winconfig.h"
+#include "winmsg.h"
+
+#include "xkbsrv.h"
+
+static Bool g_winKeyState[NUM_KEYCODES];
+
+/*
+ * Local prototypes
+ */
+
+static void
+winGetKeyMappings (KeySymsPtr pKeySyms, CARD8 *pModMap);
+
+static void
+winKeybdBell (int iPercent, DeviceIntPtr pDeviceInt,
+ pointer pCtrl, int iClass);
+
+static void
+winKeybdCtrl (DeviceIntPtr pDevice, KeybdCtrl *pCtrl);
+
+
+/*
+ * Translate a Windows WM_[SYS]KEY(UP/DOWN) message
+ * into an ASCII scan code.
+ *
+ * We do this ourselves, rather than letting Windows handle it,
+ * because Windows tends to munge the handling of special keys,
+ * like AltGr on European keyboards.
+ */
+
+void
+winTranslateKey (WPARAM wParam, LPARAM lParam, int *piScanCode)
+{
+ int iKeyFixup = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 1];
+ int iKeyFixupEx = g_iKeyMap[wParam * WIN_KEYMAP_COLS + 2];
+ int iParam = HIWORD (lParam);
+ int iParamScanCode = LOBYTE (iParam);
+
+/* WM_ key messages faked by Vista speech recognition (WSR) don't have a
+ * scan code.
+ *
+ * Vocola 3 (Rick Mohr's supplement to WSR) uses
+ * System.Windows.Forms.SendKeys.SendWait(), which appears always to give a
+ * scan code of 1
+ */
+ if (iParamScanCode <= 1)
+ {
+ if (VK_PRIOR <= wParam && wParam <= VK_DOWN)
+ /* Trigger special case table to translate to extended
+ * keycode, otherwise if num_lock is on, we can get keypad
+ * numbers instead of navigation keys. */
+ iParam |= KF_EXTENDED;
+ else
+ iParamScanCode = MapVirtualKeyEx(wParam,
+ /*MAPVK_VK_TO_VSC*/0,
+ GetKeyboardLayout(0));
+ }
+
+ /* Branch on special extended, special non-extended, or normal key */
+ if ((iParam & KF_EXTENDED) && iKeyFixupEx)
+ *piScanCode = iKeyFixupEx;
+ else if (iKeyFixup)
+ *piScanCode = iKeyFixup;
+ else if (wParam == 0 && iParamScanCode == 0x70)
+ *piScanCode = KEY_HKTG;
+ else
+ switch (iParamScanCode)
+ {
+ case 0x70:
+ *piScanCode = KEY_HKTG;
+ break;
+ case 0x73:
+ *piScanCode = KEY_BSlash2;
+ break;
+ default:
+ *piScanCode = iParamScanCode;
+ break;
+ }
+}
+
+
+/*
+ * We call this function from winKeybdProc when we are
+ * initializing the keyboard.
+ */
+
+static void
+winGetKeyMappings (KeySymsPtr pKeySyms, CARD8 *pModMap)
+{
+ int i;
+ KeySym *pMap = map;
+ KeySym *pKeySym;
+
+ /*
+ * Initialize all key states to up... which may not be true
+ * but it is close enough.
+ */
+ ZeroMemory (g_winKeyState, sizeof (g_winKeyState[0]) * NUM_KEYCODES);
+
+ /* MAP_LENGTH is defined in Xserver/include/input.h to be 256 */
+ for (i = 0; i < MAP_LENGTH; i++)
+ pModMap[i] = NoSymbol; /* make sure it is restored */
+
+ /* Loop through all valid entries in the key symbol table */
+ for (pKeySym = pMap, i = MIN_KEYCODE;
+ i < (MIN_KEYCODE + NUM_KEYCODES);
+ i++, pKeySym += GLYPHS_PER_KEY)
+ {
+ switch (*pKeySym)
+ {
+ case XK_Shift_L:
+ case XK_Shift_R:
+ pModMap[i] = ShiftMask;
+ break;
+
+ case XK_Control_L:
+ case XK_Control_R:
+ pModMap[i] = ControlMask;
+ break;
+
+ case XK_Caps_Lock:
+ pModMap[i] = LockMask;
+ break;
+
+ case XK_Alt_L:
+ case XK_Alt_R:
+ pModMap[i] = AltMask;
+ break;
+
+ case XK_Num_Lock:
+ pModMap[i] = NumLockMask;
+ break;
+
+ case XK_Scroll_Lock:
+ pModMap[i] = ScrollLockMask;
+ break;
+
+#if 0
+ case XK_Super_L:
+ case XK_Super_R:
+ pModMap[i] = Mod4Mask;
+ break;
+#else
+ /* Hirigana/Katakana toggle */
+ case XK_Kana_Lock:
+ case XK_Kana_Shift:
+ pModMap[i] = KanaMask;
+ break;
+#endif
+
+ /* alternate toggle for multinational support */
+ case XK_Mode_switch:
+ pModMap[i] = AltLangMask;
+ break;
+ }
+ }
+
+ pKeySyms->map = (KeySym *) pMap;
+ pKeySyms->mapWidth = GLYPHS_PER_KEY;
+ pKeySyms->minKeyCode = MIN_KEYCODE;
+ pKeySyms->maxKeyCode = MAX_KEYCODE;
+}
+
+
+/* Ring the keyboard bell (system speaker on PCs) */
+static void
+winKeybdBell (int iPercent, DeviceIntPtr pDeviceInt,
+ pointer pCtrl, int iClass)
+{
+ /*
+ * We can't use Beep () here because it uses the PC speaker
+ * on NT/2000. MessageBeep (MB_OK) will play the default system
+ * sound on systems with a sound card or it will beep the PC speaker
+ * on systems that do not have a sound card.
+ */
+ MessageBeep (MB_OK);
+}
+
+
+/* Change some keyboard configuration parameters */
+static void
+winKeybdCtrl (DeviceIntPtr pDevice, KeybdCtrl *pCtrl)
+{
+}
+
+
+/*
+ * See Porting Layer Definition - p. 18
+ * winKeybdProc is known as a DeviceProc.
+ */
+
+int
+winKeybdProc (DeviceIntPtr pDeviceInt, int iState)
+{
+ DevicePtr pDevice = (DevicePtr) pDeviceInt;
+ XkbSrvInfoPtr xkbi;
+ XkbControlsPtr ctrl;
+
+ switch (iState)
+ {
+ case DEVICE_INIT:
+ winConfigKeyboard (pDeviceInt);
+
+ /* FIXME: Maybe we should use winGetKbdLeds () here? */
+ defaultKeyboardControl.leds = g_winInfo.keyboard.leds;
+
+ winDebug("Rules = \"%s\" Model = \"%s\" Layout = \"%s\""
+ " Variant = \"%s\" Options = \"%s\"\n",
+ g_winInfo.xkb.rules ? g_winInfo.xkb.rules : "none",
+ g_winInfo.xkb.model ? g_winInfo.xkb.model : "none",
+ g_winInfo.xkb.layout ? g_winInfo.xkb.layout : "none",
+ g_winInfo.xkb.variant ? g_winInfo.xkb.variant : "none",
+ g_winInfo.xkb.options ? g_winInfo.xkb.options : "none");
+
+ InitKeyboardDeviceStruct (pDeviceInt,
+ &g_winInfo.xkb,
+ winKeybdBell,
+ winKeybdCtrl);
+
+ xkbi = pDeviceInt->key->xkbInfo;
+ if ((xkbi != NULL) && (xkbi->desc != NULL))
+ {
+ ctrl = xkbi->desc->ctrls;
+ ctrl->repeat_delay = g_winInfo.keyboard.delay;
+ ctrl->repeat_interval = 1000/g_winInfo.keyboard.rate;
+ }
+ else
+ {
+ winDebug ("winKeybdProc - Error initializing keyboard AutoRepeat\n");
+ }
+
+ XkbSetExtension(pDeviceInt, ProcessKeyboardEvent);
+ break;
+
+ case DEVICE_ON:
+ pDevice->on = TRUE;
+
+ // immediately copy the state of this keyboard device to the VCK
+ // (which otherwise happens lazily after the first keypress)
+ CopyKeyClass(pDeviceInt, inputInfo.keyboard);
+ break;
+
+ case DEVICE_CLOSE:
+ case DEVICE_OFF:
+ pDevice->on = FALSE;
+ break;
+ }
+
+ return Success;
+}
+
+
+/*
+ * Detect current mode key states upon server startup.
+ *
+ * Simulate a press and release of any key that is currently
+ * toggled.
+ */
+
+void
+winInitializeModeKeyStates (void)
+{
+ /* Restore NumLock */
+ if (GetKeyState (VK_NUMLOCK) & 0x0001)
+ {
+ winSendKeyEvent (KEY_NumLock, TRUE);
+ winSendKeyEvent (KEY_NumLock, FALSE);
+ }
+
+ /* Restore CapsLock */
+ if (GetKeyState (VK_CAPITAL) & 0x0001)
+ {
+ winSendKeyEvent (KEY_CapsLock, TRUE);
+ winSendKeyEvent (KEY_CapsLock, FALSE);
+ }
+
+ /* Restore ScrollLock */
+ if (GetKeyState (VK_SCROLL) & 0x0001)
+ {
+ winSendKeyEvent (KEY_ScrollLock, TRUE);
+ winSendKeyEvent (KEY_ScrollLock, FALSE);
+ }
+
+ /* Restore KanaLock */
+ if (GetKeyState (VK_KANA) & 0x0001)
+ {
+ winSendKeyEvent (KEY_HKTG, TRUE);
+ winSendKeyEvent (KEY_HKTG, FALSE);
+ }
+}
+
+
+/*
+ * Upon regaining the keyboard focus we must
+ * resynchronize our internal mode key states
+ * with the actual state of the keys.
+ */
+
+void
+winRestoreModeKeyStates (void)
+{
+ DWORD dwKeyState;
+ BOOL processEvents = TRUE;
+ unsigned short internalKeyStates;
+
+ /* X server is being initialized */
+ if (!inputInfo.keyboard)
+ return;
+
+ /* Only process events if the rootwindow is mapped. The keyboard events
+ * will cause segfaults otherwise */
+ if (WindowTable && WindowTable[0] && WindowTable[0]->mapped == FALSE)
+ processEvents = FALSE;
+
+ /* Force to process all pending events in the mi event queue */
+ if (processEvents)
+ mieqProcessInputEvents ();
+
+ /* Read the mode key states of our X server */
+ /* (stored in the virtual core keyboard) */
+ internalKeyStates = XkbStateFieldFromRec(&inputInfo.keyboard->key->xkbInfo->state);
+ winDebug("winRestoreModeKeyStates: state %d\n", internalKeyStates);
+
+ /*
+ * NOTE: The C XOR operator, ^, will not work here because it is
+ * a bitwise operator, not a logical operator. C does not
+ * have a logical XOR operator, so we use a macro instead.
+ */
+
+ /* Has the key state changed? */
+ dwKeyState = GetKeyState (VK_NUMLOCK) & 0x0001;
+ if (WIN_XOR (internalKeyStates & NumLockMask, dwKeyState))
+ {
+ winSendKeyEvent (KEY_NumLock, TRUE);
+ winSendKeyEvent (KEY_NumLock, FALSE);
+ }
+
+ /* Has the key state changed? */
+ dwKeyState = GetKeyState (VK_CAPITAL) & 0x0001;
+ if (WIN_XOR (internalKeyStates & LockMask, dwKeyState))
+ {
+ winSendKeyEvent (KEY_CapsLock, TRUE);
+ winSendKeyEvent (KEY_CapsLock, FALSE);
+ }
+
+ /* Has the key state changed? */
+ dwKeyState = GetKeyState (VK_SCROLL) & 0x0001;
+ if (WIN_XOR (internalKeyStates & ScrollLockMask, dwKeyState))
+ {
+ winSendKeyEvent (KEY_ScrollLock, TRUE);
+ winSendKeyEvent (KEY_ScrollLock, FALSE);
+ }
+
+ /* Has the key state changed? */
+ dwKeyState = GetKeyState (VK_KANA) & 0x0001;
+ if (WIN_XOR (internalKeyStates & KanaMask, dwKeyState))
+ {
+ winSendKeyEvent (KEY_HKTG, TRUE);
+ winSendKeyEvent (KEY_HKTG, FALSE);
+ }
+}
+
+
+/*
+ * Look for the lovely fake Control_L press/release generated by Windows
+ * when AltGr is pressed/released on a non-U.S. keyboard.
+ */
+
+Bool
+winIsFakeCtrl_L (UINT message, WPARAM wParam, LPARAM lParam)
+{
+ MSG msgNext;
+ LONG lTime;
+ Bool fReturn;
+
+ /*
+ * Fake Ctrl_L presses will be followed by an Alt_R keypress
+ * with the same timestamp as the Ctrl_L press.
+ */
+ if ((message == WM_KEYDOWN || message == WM_SYSKEYDOWN)
+ && wParam == VK_CONTROL
+ && (HIWORD (lParam) & KF_EXTENDED) == 0)
+ {
+ /* Got a Ctrl_L press */
+
+ /* Get time of current message */
+ lTime = GetMessageTime ();
+
+ /* Look for fake Ctrl_L preceeding an Alt_R press. */
+ fReturn = PeekMessage (&msgNext, NULL,
+ WM_KEYDOWN, WM_SYSKEYDOWN,
+ PM_NOREMOVE);
+
+ /*
+ * Try again if the first call fails.
+ * NOTE: This usually happens when TweakUI is enabled.
+ */
+ if (!fReturn)
+ {
+ /* Voodoo to make sure that the Alt_R message has posted */
+ Sleep (0);
+
+ /* Look for fake Ctrl_L preceeding an Alt_R press. */
+ fReturn = PeekMessage (&msgNext, NULL,
+ WM_KEYDOWN, WM_SYSKEYDOWN,
+ PM_NOREMOVE);
+ }
+ if (msgNext.message != WM_KEYDOWN && msgNext.message != WM_SYSKEYDOWN)
+ fReturn = 0;
+
+ /* Is next press an Alt_R with the same timestamp? */
+ if (fReturn && msgNext.wParam == VK_MENU
+ && msgNext.time == lTime
+ && (HIWORD (msgNext.lParam) & KF_EXTENDED))
+ {
+ /*
+ * Next key press is Alt_R with same timestamp as current
+ * Ctrl_L message. Therefore, this Ctrl_L press is a fake
+ * event, so discard it.
+ */
+ return TRUE;
+ }
+ }
+
+ /*
+ * Fake Ctrl_L releases will be followed by an Alt_R release
+ * with the same timestamp as the Ctrl_L release.
+ */
+ if ((message == WM_KEYUP || message == WM_SYSKEYUP)
+ && wParam == VK_CONTROL
+ && (HIWORD (lParam) & KF_EXTENDED) == 0)
+ {
+ /* Got a Ctrl_L release */
+
+ /* Get time of current message */
+ lTime = GetMessageTime ();
+
+ /* Look for fake Ctrl_L release preceeding an Alt_R release. */
+ fReturn = PeekMessage (&msgNext, NULL,
+ WM_KEYUP, WM_SYSKEYUP,
+ PM_NOREMOVE);
+
+ /*
+ * Try again if the first call fails.
+ * NOTE: This usually happens when TweakUI is enabled.
+ */
+ if (!fReturn)
+ {
+ /* Voodoo to make sure that the Alt_R message has posted */
+ Sleep (0);
+
+ /* Look for fake Ctrl_L release preceeding an Alt_R release. */
+ fReturn = PeekMessage (&msgNext, NULL,
+ WM_KEYUP, WM_SYSKEYUP,
+ PM_NOREMOVE);
+ }
+
+ if (msgNext.message != WM_KEYUP && msgNext.message != WM_SYSKEYUP)
+ fReturn = 0;
+
+ /* Is next press an Alt_R with the same timestamp? */
+ if (fReturn
+ && (msgNext.message == WM_KEYUP
+ || msgNext.message == WM_SYSKEYUP)
+ && msgNext.wParam == VK_MENU
+ && msgNext.time == lTime
+ && (HIWORD (msgNext.lParam) & KF_EXTENDED))
+ {
+ /*
+ * Next key release is Alt_R with same timestamp as current
+ * Ctrl_L message. Therefore, this Ctrl_L release is a fake
+ * event, so discard it.
+ */
+ return TRUE;
+ }
+ }
+
+ /* Not a fake control left press/release */
+ return FALSE;
+}
+
+
+/*
+ * Lift any modifier keys that are pressed
+ */
+
+void
+winKeybdReleaseKeys (void)
+{
+ int i;
+
+#ifdef HAS_DEVWINDOWS
+ /* Verify that the mi input system has been initialized */
+ if (g_fdMessageQueue == WIN_FD_INVALID)
+ return;
+#endif
+
+ /* Loop through all keys */
+ for (i = 0; i < NUM_KEYCODES; ++i)
+ {
+ /* Pop key if pressed */
+ if (g_winKeyState[i])
+ winSendKeyEvent (i, FALSE);
+
+ /* Reset pressed flag for keys */
+ g_winKeyState[i] = FALSE;
+ }
+}
+
+
+/*
+ * Take a raw X key code and send an up or down event for it.
+ *
+ * Thanks to VNC for inspiration, though it is a simple function.
+ */
+
+void
+winSendKeyEvent (DWORD dwKey, Bool fDown)
+{
+ EventListPtr events;
+ int i, nevents;
+
+ /*
+ * When alt-tabing between screens we can get phantom key up messages
+ * Here we only pass them through it we think we should!
+ */
+ if (g_winKeyState[dwKey] == FALSE && fDown == FALSE) return;
+
+ /* Update the keyState map */
+ g_winKeyState[dwKey] = fDown;
+
+ GetEventList(&events);
+ nevents = GetKeyboardEvents(events, g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE);
+
+ for (i = 0; i < nevents; i++)
+ mieqEnqueue(g_pwinKeyboard, (InternalEvent*)(events + i)->event);
+
+ winDebug("winSendKeyEvent: dwKey: %d, fDown: %d, nEvents %d\n",
+ dwKey, fDown, nevents);
+}
+
+BOOL winCheckKeyPressed(WPARAM wParam, LPARAM lParam)
+{
+ switch (wParam)
+ {
+ case VK_CONTROL:
+ if ((lParam & 0x1ff0000) == 0x11d0000 && g_winKeyState[KEY_RCtrl])
+ return TRUE;
+ if ((lParam & 0x1ff0000) == 0x01d0000 && g_winKeyState[KEY_LCtrl])
+ return TRUE;
+ break;
+ case VK_SHIFT:
+ if ((lParam & 0x1ff0000) == 0x0360000 && g_winKeyState[KEY_ShiftR])
+ return TRUE;
+ if ((lParam & 0x1ff0000) == 0x02a0000 && g_winKeyState[KEY_ShiftL])
+ return TRUE;
+ break;
+ default:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/* Only on shift release message is sent even if both are pressed.
+ * Fix this here
+ */
+void winFixShiftKeys (int iScanCode)
+{
+ if (GetKeyState (VK_SHIFT) & 0x8000)
+ return;
+
+ if (iScanCode == KEY_ShiftL && g_winKeyState[KEY_ShiftR])
+ winSendKeyEvent (KEY_ShiftR, FALSE);
+ if (iScanCode == KEY_ShiftR && g_winKeyState[KEY_ShiftL])
+ winSendKeyEvent (KEY_ShiftL, FALSE);
+}
diff --git a/xorg-server/hw/xwin/winkeybd.h b/xorg-server/hw/xwin/winkeybd.h index d0d6b9cad..8646bcec8 100644 --- a/xorg-server/hw/xwin/winkeybd.h +++ b/xorg-server/hw/xwin/winkeybd.h @@ -1,312 +1,314 @@ -#if !defined(WINKEYBD_H) -#define WINKEYBD_H -/* - *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: Harold L Hunt II - */ - -/* - * We need symbols for the scan codes of keys. - */ -#include "winkeynames.h" - - -/* - * Include the standard ASCII keymap. - * - * This header declares a static KeySym array called 'map'. - */ -#include "winkeymap.h" - -#define WIN_KEYMAP_COLS 3 - -/* Rows 160 through 165 correspond to software-generated codes, which - * may not be associated with the appropriate scan code. - */ -const int -g_iKeyMap [] = { - /* count Windows VK, ASCII, ASCII when extended VK */ - /* 0 */ 0, 0, 0, - /* 1 */ 0, 0, 0, - /* 2 */ 0, 0, 0, - /* 3 */ VK_CANCEL, 0, KEY_Break, - /* 4 */ 0, 0, 0, - /* 5 */ 0, 0, 0, - /* 6 */ 0, 0, 0, - /* 7 */ 0, 0, 0, - /* 8 */ 0, 0, 0, - /* 9 */ 0, 0, 0, - /* 10 */ 0, 0, 0, - /* 11 */ 0, 0, 0, - /* 12 */ 0, 0, 0, - /* 13 */ VK_RETURN, 0, KEY_KP_Enter, - /* 14 */ 0, 0, 0, - /* 15 */ 0, 0, 0, - /* 16 */ VK_SHIFT, 0, 0, - /* 17 */ VK_CONTROL, 0, KEY_RCtrl, - /* 18 */ VK_MENU, 0, KEY_AltLang, - /* 19 */ VK_PAUSE, KEY_Pause, 0, - /* 20 */ 0, 0, 0, - /* 21 */ 0, 0, 0, - /* 22 */ 0, 0, 0, - /* 23 */ 0, 0, 0, - /* 24 */ 0, 0, 0, - /* 25 */ 0, 0, 0, - /* 26 */ 0, 0, 0, - /* 27 */ 0, 0, 0, - /* 28 */ 0, 0, 0, - /* 29 */ 0, 0, 0, - /* 30 */ 0, 0, 0, - /* 31 */ 0, 0, 0, - /* 32 */ 0, 0, 0, - /* 33 */ VK_PRIOR, 0, KEY_PgUp, - /* 34 */ VK_NEXT, 0, KEY_PgDown, - /* 35 */ VK_END, 0, KEY_End, - /* 36 */ VK_HOME, 0, KEY_Home, - /* 37 */ VK_LEFT, 0, KEY_Left, - /* 38 */ VK_UP, 0, KEY_Up, - /* 39 */ VK_RIGHT, 0, KEY_Right, - /* 40 */ VK_DOWN, 0, KEY_Down, - /* 41 */ 0, 0, 0, - /* 42 */ 0, 0, 0, - /* 43 */ 0, 0, 0, - /* 44 */ VK_SNAPSHOT, 0, KEY_Print, - /* 45 */ VK_INSERT, 0, KEY_Insert, - /* 46 */ VK_DELETE, 0, KEY_Delete, - /* 47 */ 0, 0, 0, - /* 48 */ 0, 0, 0, - /* 49 */ 0, 0, 0, - /* 50 */ 0, 0, 0, - /* 51 */ 0, 0, 0, - /* 52 */ 0, 0, 0, - /* 53 */ 0, 0, 0, - /* 54 */ 0, 0, 0, - /* 55 */ 0, 0, 0, - /* 56 */ 0, 0, 0, - /* 57 */ 0, 0, 0, - /* 58 */ 0, 0, 0, - /* 59 */ 0, 0, 0, - /* 60 */ 0, 0, 0, - /* 61 */ 0, 0, 0, - /* 62 */ 0, 0, 0, - /* 63 */ 0, 0, 0, - /* 64 */ 0, 0, 0, - /* 65 */ 0, 0, 0, - /* 66 */ 0, 0, 0, - /* 67 */ 0, 0, 0, - /* 68 */ 0, 0, 0, - /* 69 */ 0, 0, 0, - /* 70 */ 0, 0, 0, - /* 71 */ 0, 0, 0, - /* 72 */ 0, 0, 0, - /* 73 */ 0, 0, 0, - /* 74 */ 0, 0, 0, - /* 75 */ 0, 0, 0, - /* 76 */ 0, 0, 0, - /* 77 */ 0, 0, 0, - /* 78 */ 0, 0, 0, - /* 79 */ 0, 0, 0, - /* 80 */ 0, 0, 0, - /* 81 */ 0, 0, 0, - /* 82 */ 0, 0, 0, - /* 83 */ 0, 0, 0, - /* 84 */ 0, 0, 0, - /* 85 */ 0, 0, 0, - /* 86 */ 0, 0, 0, - /* 87 */ 0, 0, 0, - /* 88 */ 0, 0, 0, - /* 89 */ 0, 0, 0, - /* 90 */ 0, 0, 0, - /* 91 */ VK_LWIN, KEY_LMeta, 0, - /* 92 */ VK_RWIN, KEY_RMeta, 0, - /* 93 */ VK_APPS, KEY_Menu, 0, - /* 94 */ 0, 0, 0, - /* 95 */ 0, 0, 0, - /* 96 */ 0, 0, 0, - /* 97 */ 0, 0, 0, - /* 98 */ 0, 0, 0, - /* 99 */ 0, 0, 0, - /* 100 */ 0, 0, 0, - /* 101 */ 0, 0, 0, - /* 102 */ 0, 0, 0, - /* 103 */ 0, 0, 0, - /* 104 */ 0, 0, 0, - /* 105 */ 0, 0, 0, - /* 106 */ 0, 0, 0, - /* 107 */ 0, 0, 0, - /* 108 */ 0, 0, 0, - /* 109 */ 0, 0, 0, - /* 110 */ 0, 0, 0, - /* 111 */ VK_DIVIDE, 0, KEY_KP_Divide, - /* 112 */ 0, 0, 0, - /* 113 */ 0, 0, 0, - /* 114 */ 0, 0, 0, - /* 115 */ 0, 0, 0, - /* 116 */ 0, 0, 0, - /* 117 */ 0, 0, 0, - /* 118 */ 0, 0, 0, - /* 119 */ 0, 0, 0, - /* 120 */ 0, 0, 0, - /* 121 */ 0, 0, 0, - /* 122 */ 0, 0, 0, - /* 123 */ 0, 0, 0, - /* 124 */ 0, 0, 0, - /* 125 */ 0, 0, 0, - /* 126 */ 0, 0, 0, - /* 127 */ 0, 0, 0, - /* 128 */ 0, 0, 0, - /* 129 */ 0, 0, 0, - /* 130 */ 0, 0, 0, - /* 131 */ 0, 0, 0, - /* 132 */ 0, 0, 0, - /* 133 */ 0, 0, 0, - /* 134 */ 0, 0, 0, - /* 135 */ 0, 0, 0, - /* 136 */ 0, 0, 0, - /* 137 */ 0, 0, 0, - /* 138 */ 0, 0, 0, - /* 139 */ 0, 0, 0, - /* 140 */ 0, 0, 0, - /* 141 */ 0, 0, 0, - /* 142 */ 0, 0, 0, - /* 143 */ 0, 0, 0, - /* 144 */ 0, 0, 0, - /* 145 */ 0, 0, 0, - /* 146 */ 0, 0, 0, - /* 147 */ 0, 0, 0, - /* 148 */ 0, 0, 0, - /* 149 */ 0, 0, 0, - /* 150 */ 0, 0, 0, - /* 151 */ 0, 0, 0, - /* 152 */ 0, 0, 0, - /* 153 */ 0, 0, 0, - /* 154 */ 0, 0, 0, - /* 155 */ 0, 0, 0, - /* 156 */ 0, 0, 0, - /* 157 */ 0, 0, 0, - /* 158 */ 0, 0, 0, - /* 159 */ 0, 0, 0, - /* 160 */ VK_LSHIFT, KEY_ShiftL, 0, - /* 161 */ VK_RSHIFT, KEY_ShiftR, 0, - /* 162 */ VK_LCONTROL, KEY_LCtrl, 0, - /* 163 */ VK_RCONTROL, KEY_RCtrl, 0, - /* 164 */ VK_LMENU, KEY_Alt, 0, - /* 165 */ VK_RMENU, KEY_AltLang, 0, - /* 166 */ 0, 0, 0, - /* 167 */ 0, 0, 0, - /* 168 */ 0, 0, 0, - /* 169 */ 0, 0, 0, - /* 170 */ 0, 0, 0, - /* 171 */ 0, 0, 0, - /* 172 */ 0, 0, 0, - /* 173 */ 0, 0, 0, - /* 174 */ 0, 0, 0, - /* 175 */ 0, 0, 0, - /* 176 */ 0, 0, 0, - /* 177 */ 0, 0, 0, - /* 178 */ 0, 0, 0, - /* 179 */ 0, 0, 0, - /* 180 */ 0, 0, 0, - /* 181 */ 0, 0, 0, - /* 182 */ 0, 0, 0, - /* 183 */ 0, 0, 0, - /* 184 */ 0, 0, 0, - /* 185 */ 0, 0, 0, - /* 186 */ 0, 0, 0, - /* 187 */ 0, 0, 0, - /* 188 */ 0, 0, 0, - /* 189 */ 0, 0, 0, - /* 190 */ 0, 0, 0, - /* 191 */ 0, 0, 0, - /* 192 */ 0, 0, 0, - /* 193 */ 0, 0, 0, - /* 194 */ 0, 0, 0, - /* 195 */ 0, 0, 0, - /* 196 */ 0, 0, 0, - /* 197 */ 0, 0, 0, - /* 198 */ 0, 0, 0, - /* 199 */ 0, 0, 0, - /* 200 */ 0, 0, 0, - /* 201 */ 0, 0, 0, - /* 202 */ 0, 0, 0, - /* 203 */ 0, 0, 0, - /* 204 */ 0, 0, 0, - /* 205 */ 0, 0, 0, - /* 206 */ 0, 0, 0, - /* 207 */ 0, 0, 0, - /* 208 */ 0, 0, 0, - /* 209 */ 0, 0, 0, - /* 210 */ 0, 0, 0, - /* 211 */ 0, 0, 0, - /* 212 */ 0, 0, 0, - /* 213 */ 0, 0, 0, - /* 214 */ 0, 0, 0, - /* 215 */ 0, 0, 0, - /* 216 */ 0, 0, 0, - /* 217 */ 0, 0, 0, - /* 218 */ 0, 0, 0, - /* 219 */ 0, 0, 0, - /* 220 */ 0, 0, 0, - /* 221 */ 0, 0, 0, - /* 222 */ 0, 0, 0, - /* 223 */ 0, 0, 0, - /* 224 */ 0, 0, 0, - /* 225 */ 0, 0, 0, - /* 226 */ 0, 0, 0, - /* 227 */ 0, 0, 0, - /* 228 */ 0, 0, 0, - /* 229 */ 0, 0, 0, - /* 230 */ 0, 0, 0, - /* 231 */ 0, 0, 0, - /* 232 */ 0, 0, 0, - /* 233 */ 0, 0, 0, - /* 234 */ 0, 0, 0, - /* 235 */ 0, 0, 0, - /* 236 */ 0, 0, 0, - /* 237 */ 0, 0, 0, - /* 238 */ 0, 0, 0, - /* 239 */ 0, 0, 0, - /* 240 */ 0, 0, 0, - /* 241 */ 0, 0, 0, - /* 242 */ 0, 0, 0, - /* 243 */ 0, 0, 0, - /* 244 */ 0, 0, 0, - /* 245 */ 0, 0, 0, - /* 246 */ 0, 0, 0, - /* 247 */ 0, 0, 0, - /* 248 */ 0, 0, 0, - /* 249 */ 0, 0, 0, - /* 250 */ 0, 0, 0, - /* 251 */ 0, 0, 0, - /* 252 */ 0, 0, 0, - /* 253 */ 0, 0, 0, - /* 254 */ 0, 0, 0, - /* 255 */ 0, 0, 0 -}; - -#endif /* WINKEYBD_H */ +#if !defined(WINKEYBD_H)
+#define WINKEYBD_H
+/*
+ *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: Harold L Hunt II
+ */
+
+/*
+ * We need symbols for the scan codes of keys.
+ */
+#include "winkeynames.h"
+
+
+/*
+ * Include the standard ASCII keymap.
+ *
+ * This header declares a static KeySym array called 'map'.
+ */
+#include "winkeymap.h"
+
+#define WIN_KEYMAP_COLS 3
+
+/* ASCII column, rows 33 through 40 are for Speech Recognition with
+ * num-lock asserted.
+ * Rows 160 through 165 correspond to software-generated codes, which
+ * may not be associated with the appropriate scan code/extended bit
+ */
+const int
+g_iKeyMap [] = {
+ /* count Windows VK, ASCII, ASCII when extended VK */
+ /* 0 */ 0, 0, 0,
+ /* 1 */ 0, 0, 0,
+ /* 2 */ 0, 0, 0,
+ /* 3 */ VK_CANCEL, 0, KEY_Break,
+ /* 4 */ 0, 0, 0,
+ /* 5 */ 0, 0, 0,
+ /* 6 */ 0, 0, 0,
+ /* 7 */ 0, 0, 0,
+ /* 8 */ 0, 0, 0,
+ /* 9 */ 0, 0, 0,
+ /* 10 */ 0, 0, 0,
+ /* 11 */ 0, 0, 0,
+ /* 12 */ 0, 0, 0,
+ /* 13 */ VK_RETURN, 0, KEY_KP_Enter,
+ /* 14 */ 0, 0, 0,
+ /* 15 */ 0, 0, 0,
+ /* 16 */ VK_SHIFT, 0, 0,
+ /* 17 */ VK_CONTROL, 0, KEY_RCtrl,
+ /* 18 */ VK_MENU, 0, KEY_AltLang,
+ /* 19 */ VK_PAUSE, KEY_Pause, 0,
+ /* 20 */ 0, 0, 0,
+ /* 21 */ 0, 0, 0,
+ /* 22 */ 0, 0, 0,
+ /* 23 */ 0, 0, 0,
+ /* 24 */ 0, 0, 0,
+ /* 25 */ 0, 0, 0,
+ /* 26 */ 0, 0, 0,
+ /* 27 */ 0, 0, 0,
+ /* 28 */ 0, 0, 0,
+ /* 29 */ 0, 0, 0,
+ /* 30 */ 0, 0, 0,
+ /* 31 */ 0, 0, 0,
+ /* 32 */ 0, 0, 0,
+ /* 33 */ VK_PRIOR, KEY_PgUp, KEY_PgUp,
+ /* 34 */ VK_NEXT, KEY_PgDown, KEY_PgDown,
+ /* 35 */ VK_END, KEY_End, KEY_End,
+ /* 36 */ VK_HOME, KEY_Home, KEY_Home,
+ /* 37 */ VK_LEFT, KEY_Left, KEY_Left,
+ /* 38 */ VK_UP, KEY_Up, KEY_Up,
+ /* 39 */ VK_RIGHT, KEY_Right, KEY_Right,
+ /* 40 */ VK_DOWN, KEY_Down, KEY_Down,
+ /* 41 */ 0, 0, 0,
+ /* 42 */ 0, 0, 0,
+ /* 43 */ 0, 0, 0,
+ /* 44 */ VK_SNAPSHOT, 0, KEY_Print,
+ /* 45 */ VK_INSERT, 0, KEY_Insert,
+ /* 46 */ VK_DELETE, 0, KEY_Delete,
+ /* 47 */ 0, 0, 0,
+ /* 48 */ 0, 0, 0,
+ /* 49 */ 0, 0, 0,
+ /* 50 */ 0, 0, 0,
+ /* 51 */ 0, 0, 0,
+ /* 52 */ 0, 0, 0,
+ /* 53 */ 0, 0, 0,
+ /* 54 */ 0, 0, 0,
+ /* 55 */ 0, 0, 0,
+ /* 56 */ 0, 0, 0,
+ /* 57 */ 0, 0, 0,
+ /* 58 */ 0, 0, 0,
+ /* 59 */ 0, 0, 0,
+ /* 60 */ 0, 0, 0,
+ /* 61 */ 0, 0, 0,
+ /* 62 */ 0, 0, 0,
+ /* 63 */ 0, 0, 0,
+ /* 64 */ 0, 0, 0,
+ /* 65 */ 0, 0, 0,
+ /* 66 */ 0, 0, 0,
+ /* 67 */ 0, 0, 0,
+ /* 68 */ 0, 0, 0,
+ /* 69 */ 0, 0, 0,
+ /* 70 */ 0, 0, 0,
+ /* 71 */ 0, 0, 0,
+ /* 72 */ 0, 0, 0,
+ /* 73 */ 0, 0, 0,
+ /* 74 */ 0, 0, 0,
+ /* 75 */ 0, 0, 0,
+ /* 76 */ 0, 0, 0,
+ /* 77 */ 0, 0, 0,
+ /* 78 */ 0, 0, 0,
+ /* 79 */ 0, 0, 0,
+ /* 80 */ 0, 0, 0,
+ /* 81 */ 0, 0, 0,
+ /* 82 */ 0, 0, 0,
+ /* 83 */ 0, 0, 0,
+ /* 84 */ 0, 0, 0,
+ /* 85 */ 0, 0, 0,
+ /* 86 */ 0, 0, 0,
+ /* 87 */ 0, 0, 0,
+ /* 88 */ 0, 0, 0,
+ /* 89 */ 0, 0, 0,
+ /* 90 */ 0, 0, 0,
+ /* 91 */ VK_LWIN, KEY_LMeta, 0,
+ /* 92 */ VK_RWIN, KEY_RMeta, 0,
+ /* 93 */ VK_APPS, KEY_Menu, 0,
+ /* 94 */ 0, 0, 0,
+ /* 95 */ 0, 0, 0,
+ /* 96 */ 0, 0, 0,
+ /* 97 */ 0, 0, 0,
+ /* 98 */ 0, 0, 0,
+ /* 99 */ 0, 0, 0,
+ /* 100 */ 0, 0, 0,
+ /* 101 */ 0, 0, 0,
+ /* 102 */ 0, 0, 0,
+ /* 103 */ 0, 0, 0,
+ /* 104 */ 0, 0, 0,
+ /* 105 */ 0, 0, 0,
+ /* 106 */ 0, 0, 0,
+ /* 107 */ 0, 0, 0,
+ /* 108 */ 0, 0, 0,
+ /* 109 */ 0, 0, 0,
+ /* 110 */ 0, 0, 0,
+ /* 111 */ VK_DIVIDE, 0, KEY_KP_Divide,
+ /* 112 */ 0, 0, 0,
+ /* 113 */ 0, 0, 0,
+ /* 114 */ 0, 0, 0,
+ /* 115 */ 0, 0, 0,
+ /* 116 */ 0, 0, 0,
+ /* 117 */ 0, 0, 0,
+ /* 118 */ 0, 0, 0,
+ /* 119 */ 0, 0, 0,
+ /* 120 */ 0, 0, 0,
+ /* 121 */ 0, 0, 0,
+ /* 122 */ 0, 0, 0,
+ /* 123 */ 0, 0, 0,
+ /* 124 */ 0, 0, 0,
+ /* 125 */ 0, 0, 0,
+ /* 126 */ 0, 0, 0,
+ /* 127 */ 0, 0, 0,
+ /* 128 */ 0, 0, 0,
+ /* 129 */ 0, 0, 0,
+ /* 130 */ 0, 0, 0,
+ /* 131 */ 0, 0, 0,
+ /* 132 */ 0, 0, 0,
+ /* 133 */ 0, 0, 0,
+ /* 134 */ 0, 0, 0,
+ /* 135 */ 0, 0, 0,
+ /* 136 */ 0, 0, 0,
+ /* 137 */ 0, 0, 0,
+ /* 138 */ 0, 0, 0,
+ /* 139 */ 0, 0, 0,
+ /* 140 */ 0, 0, 0,
+ /* 141 */ 0, 0, 0,
+ /* 142 */ 0, 0, 0,
+ /* 143 */ 0, 0, 0,
+ /* 144 */ 0, 0, 0,
+ /* 145 */ 0, 0, 0,
+ /* 146 */ 0, 0, 0,
+ /* 147 */ 0, 0, 0,
+ /* 148 */ 0, 0, 0,
+ /* 149 */ 0, 0, 0,
+ /* 150 */ 0, 0, 0,
+ /* 151 */ 0, 0, 0,
+ /* 152 */ 0, 0, 0,
+ /* 153 */ 0, 0, 0,
+ /* 154 */ 0, 0, 0,
+ /* 155 */ 0, 0, 0,
+ /* 156 */ 0, 0, 0,
+ /* 157 */ 0, 0, 0,
+ /* 158 */ 0, 0, 0,
+ /* 159 */ 0, 0, 0,
+ /* 160 */ VK_LSHIFT, KEY_ShiftL, KEY_ShiftL,
+ /* 161 */ VK_RSHIFT, KEY_ShiftR, KEY_ShiftR,
+ /* 162 */ VK_LCONTROL, KEY_LCtrl, KEY_LCtrl,
+ /* 163 */ VK_RCONTROL, KEY_RCtrl, KEY_RCtrl,
+ /* 164 */ VK_LMENU, KEY_Alt, KEY_Alt,
+ /* 165 */ VK_RMENU, KEY_AltLang, KEY_AltLang,
+ /* 166 */ 0, 0, 0,
+ /* 167 */ 0, 0, 0,
+ /* 168 */ 0, 0, 0,
+ /* 169 */ 0, 0, 0,
+ /* 170 */ 0, 0, 0,
+ /* 171 */ 0, 0, 0,
+ /* 172 */ 0, 0, 0,
+ /* 173 */ 0, 0, 0,
+ /* 174 */ 0, 0, 0,
+ /* 175 */ 0, 0, 0,
+ /* 176 */ 0, 0, 0,
+ /* 177 */ 0, 0, 0,
+ /* 178 */ 0, 0, 0,
+ /* 179 */ 0, 0, 0,
+ /* 180 */ 0, 0, 0,
+ /* 181 */ 0, 0, 0,
+ /* 182 */ 0, 0, 0,
+ /* 183 */ 0, 0, 0,
+ /* 184 */ 0, 0, 0,
+ /* 185 */ 0, 0, 0,
+ /* 186 */ 0, 0, 0,
+ /* 187 */ 0, 0, 0,
+ /* 188 */ 0, 0, 0,
+ /* 189 */ 0, 0, 0,
+ /* 190 */ 0, 0, 0,
+ /* 191 */ 0, 0, 0,
+ /* 192 */ 0, 0, 0,
+ /* 193 */ 0, 0, 0,
+ /* 194 */ 0, 0, 0,
+ /* 195 */ 0, 0, 0,
+ /* 196 */ 0, 0, 0,
+ /* 197 */ 0, 0, 0,
+ /* 198 */ 0, 0, 0,
+ /* 199 */ 0, 0, 0,
+ /* 200 */ 0, 0, 0,
+ /* 201 */ 0, 0, 0,
+ /* 202 */ 0, 0, 0,
+ /* 203 */ 0, 0, 0,
+ /* 204 */ 0, 0, 0,
+ /* 205 */ 0, 0, 0,
+ /* 206 */ 0, 0, 0,
+ /* 207 */ 0, 0, 0,
+ /* 208 */ 0, 0, 0,
+ /* 209 */ 0, 0, 0,
+ /* 210 */ 0, 0, 0,
+ /* 211 */ 0, 0, 0,
+ /* 212 */ 0, 0, 0,
+ /* 213 */ 0, 0, 0,
+ /* 214 */ 0, 0, 0,
+ /* 215 */ 0, 0, 0,
+ /* 216 */ 0, 0, 0,
+ /* 217 */ 0, 0, 0,
+ /* 218 */ 0, 0, 0,
+ /* 219 */ 0, 0, 0,
+ /* 220 */ 0, 0, 0,
+ /* 221 */ 0, 0, 0,
+ /* 222 */ 0, 0, 0,
+ /* 223 */ 0, 0, 0,
+ /* 224 */ 0, 0, 0,
+ /* 225 */ 0, 0, 0,
+ /* 226 */ 0, 0, 0,
+ /* 227 */ 0, 0, 0,
+ /* 228 */ 0, 0, 0,
+ /* 229 */ 0, 0, 0,
+ /* 230 */ 0, 0, 0,
+ /* 231 */ 0, 0, 0,
+ /* 232 */ 0, 0, 0,
+ /* 233 */ 0, 0, 0,
+ /* 234 */ 0, 0, 0,
+ /* 235 */ 0, 0, 0,
+ /* 236 */ 0, 0, 0,
+ /* 237 */ 0, 0, 0,
+ /* 238 */ 0, 0, 0,
+ /* 239 */ 0, 0, 0,
+ /* 240 */ 0, 0, 0,
+ /* 241 */ 0, 0, 0,
+ /* 242 */ 0, 0, 0,
+ /* 243 */ 0, 0, 0,
+ /* 244 */ 0, 0, 0,
+ /* 245 */ 0, 0, 0,
+ /* 246 */ 0, 0, 0,
+ /* 247 */ 0, 0, 0,
+ /* 248 */ 0, 0, 0,
+ /* 249 */ 0, 0, 0,
+ /* 250 */ 0, 0, 0,
+ /* 251 */ 0, 0, 0,
+ /* 252 */ 0, 0, 0,
+ /* 253 */ 0, 0, 0,
+ /* 254 */ 0, 0, 0,
+ /* 255 */ 0, 0, 0
+};
+
+#endif /* WINKEYBD_H */
diff --git a/xorg-server/hw/xwin/winkeyhook.c b/xorg-server/hw/xwin/winkeyhook.c index 2d6ed18b7..82e30df88 100644 --- a/xorg-server/hw/xwin/winkeyhook.c +++ b/xorg-server/hw/xwin/winkeyhook.c @@ -94,9 +94,6 @@ winKeyboardMessageHookLL (int iCode, WPARAM wParam, LPARAM lParam) /* Pass keystrokes on to our main message loop */ if (iCode == HC_ACTION) { -#if 0 - ErrorF ("vkCode: %08x\tscanCode: %08x\n", p->vkCode, p->scanCode); -#endif switch (wParam) { diff --git a/xorg-server/hw/xwin/winlayouts.h b/xorg-server/hw/xwin/winlayouts.h index d1d21a12d..193cc1a41 100644 --- a/xorg-server/hw/xwin/winlayouts.h +++ b/xorg-server/hw/xwin/winlayouts.h @@ -61,6 +61,7 @@ WinKBLayoutRec winKBLayouts[] = { 0x40b, -1, "pc105", "fi", NULL, NULL, "Finnish"}, { 0x40c, -1, "pc105", "fr", NULL, NULL, "French (Standard)"}, { 0x80c, -1, "pc105", "be", NULL, NULL, "French (Belgian)"}, + {0x1080c, -1, "pc105", "be", NULL, NULL, "Belgian (Comma)"}, { 0xc0c, -1, "pc105", "ca", "fr", NULL, "French (Canada)"}, { 0x100c, -1, "pc105", "ch", "fr", NULL, "French (Switzerland)"}, { 0x40d, -1, "pc105", "il", NULL, NULL, "Hebrew"}, @@ -163,6 +164,7 @@ Support ID XKB Language Finnish (with Sami) X 0x040c fr French (Standard) X 0x080c be French (Belgian) + X 0x1080c be Belgian (Comma) . 0x0c0c French (Canadian) French (Canadian, Legacy) Canadian (Multilingual) diff --git a/xorg-server/hw/xwin/winmisc.c b/xorg-server/hw/xwin/winmisc.c index 8e6698118..a5a2d3d1c 100644 --- a/xorg-server/hw/xwin/winmisc.c +++ b/xorg-server/hw/xwin/winmisc.c @@ -44,7 +44,7 @@ void winQueryBestSizeNativeGDI (int class, unsigned short *pWidth, unsigned short *pHeight, ScreenPtr pScreen) { - ErrorF ("winQueryBestSizeNativeGDI\n"); + winDebug ("winQueryBestSizeNativeGDI\n"); } #endif diff --git a/xorg-server/hw/xwin/winmouse.c b/xorg-server/hw/xwin/winmouse.c index 342f20d56..c5069d630 100644 --- a/xorg-server/hw/xwin/winmouse.c +++ b/xorg-server/hw/xwin/winmouse.c @@ -1,388 +1,385 @@ -/* - *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: Dakshinamurthy Karra - * Suhaib M Siddiqi - * Peter Busch - * Harold L Hunt II - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" - -#if defined(XFree86Server) -#include "inputstr.h" -#include "exevents.h" /* for button/axes labels */ -#include "xserver-properties.h" - -/* Peek the internal button mapping */ -static CARD8 const *g_winMouseButtonMap = NULL; -#endif - - -/* - * Local prototypes - */ - -static void -winMouseCtrl (DeviceIntPtr pDevice, PtrCtrl *pCtrl); - - -static void -winMouseCtrl (DeviceIntPtr pDevice, PtrCtrl *pCtrl) -{ -} - - -/* - * See Porting Layer Definition - p. 18 - * This is known as a DeviceProc - */ - -int -winMouseProc (DeviceIntPtr pDeviceInt, int iState) -{ - int lngMouseButtons, i; - int lngWheelEvents = 2; - CARD8 *map; - DevicePtr pDevice = (DevicePtr) pDeviceInt; - Atom *btn_labels; - Atom axes_labels[2]; - - switch (iState) - { - case DEVICE_INIT: - /* Get number of mouse buttons */ - lngMouseButtons = GetSystemMetrics(SM_CMOUSEBUTTONS); - - /* Mapping of windows events to X events: - * LEFT:1 MIDDLE:2 RIGHT:3 - * SCROLL_UP:4 SCROLL_DOWN:5 - * XBUTTON 1:6 XBUTTON 2:7 ... - * - * To map scroll wheel correctly we need at least the 3 normal buttons - */ - if (lngMouseButtons < 3) - lngMouseButtons = 3; - winMsg(X_PROBED, "%d mouse buttons found\n", lngMouseButtons); - - /* allocate memory: - * number of buttons + 2x mouse wheel event + 1 extra (offset for map) - */ - map = malloc(sizeof(CARD8) * (lngMouseButtons + lngWheelEvents + 1)); - - /* initalize button map */ - map[0] = 0; - for (i=1; i <= lngMouseButtons + lngWheelEvents; i++) - map[i] = i; - - btn_labels = calloc((lngMouseButtons + lngWheelEvents), sizeof(Atom)); - btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT); - btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE); - btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT); - btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP); - btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN); - - axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X); - axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y); - - InitPointerDeviceStruct (pDevice, - map, - lngMouseButtons + lngWheelEvents, - btn_labels, - winMouseCtrl, - GetMotionHistorySize(), - 2, - axes_labels); - free(map); - free(btn_labels); - -#if defined(XFree86Server) - g_winMouseButtonMap = pDeviceInt->button->map; -#endif - break; - - case DEVICE_ON: - pDevice->on = TRUE; - break; - - case DEVICE_CLOSE: -#if defined(XFree86Server) - g_winMouseButtonMap = NULL; -#endif - case DEVICE_OFF: - pDevice->on = FALSE; - break; - } - return Success; -} - - -/* Handle the mouse wheel */ -int -winMouseWheel (ScreenPtr pScreen, int iDeltaZ) -{ - winScreenPriv(pScreen); - int button; /* Button4 or Button5 */ - - /* Button4 = WheelUp */ - /* Button5 = WheelDown */ - - /* Do we have any previous delta stored? */ - if ((pScreenPriv->iDeltaZ > 0 - && iDeltaZ > 0) - || (pScreenPriv->iDeltaZ < 0 - && iDeltaZ < 0)) - { - /* Previous delta and of same sign as current delta */ - iDeltaZ += pScreenPriv->iDeltaZ; - pScreenPriv->iDeltaZ = 0; - } - else - { - /* - * Previous delta of different sign, or zero. - * We will set it to zero for either case, - * as blindly setting takes just as much time - * as checking, then setting if necessary :) - */ - pScreenPriv->iDeltaZ = 0; - } - - /* - * Only process this message if the wheel has moved further than - * WHEEL_DELTA - */ - if (iDeltaZ >= WHEEL_DELTA || (-1 * iDeltaZ) >= WHEEL_DELTA) - { - pScreenPriv->iDeltaZ = 0; - - /* Figure out how many whole deltas of the wheel we have */ - iDeltaZ /= WHEEL_DELTA; - } - else - { - /* - * Wheel has not moved past WHEEL_DELTA threshold; - * we will store the wheel delta until the threshold - * has been reached. - */ - pScreenPriv->iDeltaZ = iDeltaZ; - return 0; - } - - /* Set the button to indicate up or down wheel delta */ - if (iDeltaZ > 0) - { - button = Button4; - } - else - { - button = Button5; - } - - /* - * Flip iDeltaZ to positive, if negative, - * because always need to generate a *positive* number of - * button clicks for the Z axis. - */ - if (iDeltaZ < 0) - { - iDeltaZ *= -1; - } - - /* Generate X input messages for each wheel delta we have seen */ - while (iDeltaZ--) - { - /* Push the wheel button */ - winMouseButtonsSendEvent (ButtonPress, button); - - /* Release the wheel button */ - winMouseButtonsSendEvent (ButtonRelease, button); - } - - return 0; -} - - -/* - * Enqueue a mouse button event - */ - -void -winMouseButtonsSendEvent (int iEventType, int iButton) -{ - EventListPtr events; - int i, nevents; - -#if defined(XFree86Server) - if (g_winMouseButtonMap) - iButton = g_winMouseButtonMap[iButton]; -#endif - - GetEventList(&events); - nevents = GetPointerEvents(events, g_pwinPointer, iEventType, iButton, - POINTER_RELATIVE, 0, 0, NULL); - - for (i = 0; i < nevents; i++) - mieqEnqueue(g_pwinPointer, events[i].event); - -#if CYGDEBUG - ErrorF("winMouseButtonsSendEvent: iEventType: %d, iButton: %d, nEvents %d\n", - iEventType, iButton, nevents); -#endif -} - - -/* - * Decide what to do with a Windows mouse message - */ - -int -winMouseButtonsHandle (ScreenPtr pScreen, - int iEventType, int iButton, - WPARAM wParam) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - - /* Send button events right away if emulate 3 buttons is off */ - if (pScreenInfo->iE3BTimeout == WIN_E3B_OFF) - { - /* Emulate 3 buttons is off, send the button event */ - winMouseButtonsSendEvent (iEventType, iButton); - return 0; - } - - /* Emulate 3 buttons is on, let the fun begin */ - if (iEventType == ButtonPress - && pScreenPriv->iE3BCachedPress == 0 - && !pScreenPriv->fE3BFakeButton2Sent) - { - /* - * Button was pressed, no press is cached, - * and there is no fake button 2 release pending. - */ - - /* Store button press type */ - pScreenPriv->iE3BCachedPress = iButton; - - /* - * Set a timer to send this button press if the other button - * is not pressed within the timeout time. - */ - SetTimer (pScreenPriv->hwndScreen, - WIN_E3B_TIMER_ID, - pScreenInfo->iE3BTimeout, - NULL); - } - else if (iEventType == ButtonPress - && pScreenPriv->iE3BCachedPress != 0 - && pScreenPriv->iE3BCachedPress != iButton - && !pScreenPriv->fE3BFakeButton2Sent) - { - /* - * Button press is cached, other button was pressed, - * and there is no fake button 2 release pending. - */ - - /* Mouse button was cached and other button was pressed */ - KillTimer (pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID); - pScreenPriv->iE3BCachedPress = 0; - - /* Send fake middle button */ - winMouseButtonsSendEvent (ButtonPress, Button2); - - /* Indicate that a fake middle button event was sent */ - pScreenPriv->fE3BFakeButton2Sent = TRUE; - } - else if (iEventType == ButtonRelease - && pScreenPriv->iE3BCachedPress == iButton) - { - /* - * Cached button was released before timer ran out, - * and before the other mouse button was pressed. - */ - KillTimer (pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID); - pScreenPriv->iE3BCachedPress = 0; - - /* Send cached press, then send release */ - winMouseButtonsSendEvent (ButtonPress, iButton); - winMouseButtonsSendEvent (ButtonRelease, iButton); - } - else if (iEventType == ButtonRelease - && pScreenPriv->fE3BFakeButton2Sent - && !(wParam & MK_LBUTTON) - && !(wParam & MK_RBUTTON)) - { - /* - * Fake button 2 was sent and both mouse buttons have now been released - */ - pScreenPriv->fE3BFakeButton2Sent = FALSE; - - /* Send middle mouse button release */ - winMouseButtonsSendEvent (ButtonRelease, Button2); - } - else if (iEventType == ButtonRelease - && pScreenPriv->iE3BCachedPress == 0 - && !pScreenPriv->fE3BFakeButton2Sent) - { - /* - * Button was release, no button is cached, - * and there is no fake button 2 release is pending. - */ - winMouseButtonsSendEvent (ButtonRelease, iButton); - } - - return 0; -} - -/** - * Enqueue a motion event. - * - * XXX: miPointerMove does exactly this, but is static :-( (and uses a static buffer) - * - */ -void winEnqueueMotion(int x, int y) -{ - int i, nevents; - int valuators[2]; - EventListPtr events; - - miPointerSetPosition(g_pwinPointer, &x, &y); - valuators[0] = x; - valuators[1] = y; - - GetEventList(&events); - nevents = GetPointerEvents(events, g_pwinPointer, MotionNotify, 0, - POINTER_ABSOLUTE | POINTER_SCREEN, 0, 2, valuators); - - for (i = 0; i < nevents; i++) - mieqEnqueue(g_pwinPointer, events[i].event); -} +/*
+ *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: Dakshinamurthy Karra
+ * Suhaib M Siddiqi
+ * Peter Busch
+ * Harold L Hunt II
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+
+#ifdef XKB
+#ifndef XKB_IN_SERVER
+#define XKB_IN_SERVER
+#endif
+#include <xkbsrv.h>
+#endif
+
+#include "inputstr.h"
+#include "exevents.h" /* for button/axes labels */
+#include "xserver-properties.h"
+
+/* Peek the internal button mapping */
+static CARD8 const *g_winMouseButtonMap = NULL;
+
+
+/*
+ * Local prototypes
+ */
+
+static void
+winMouseCtrl (DeviceIntPtr pDevice, PtrCtrl *pCtrl);
+
+
+static void
+winMouseCtrl (DeviceIntPtr pDevice, PtrCtrl *pCtrl)
+{
+}
+
+
+/*
+ * See Porting Layer Definition - p. 18
+ * This is known as a DeviceProc
+ */
+
+int
+winMouseProc (DeviceIntPtr pDeviceInt, int iState)
+{
+ int lngMouseButtons, i;
+ int lngWheelEvents = 2;
+ CARD8 *map;
+ DevicePtr pDevice = (DevicePtr) pDeviceInt;
+ Atom *btn_labels;
+ Atom axes_labels[2];
+
+ switch (iState)
+ {
+ case DEVICE_INIT:
+ /* Get number of mouse buttons */
+ lngMouseButtons = GetSystemMetrics(SM_CMOUSEBUTTONS);
+
+ /* Mapping of windows events to X events:
+ * LEFT:1 MIDDLE:2 RIGHT:3
+ * SCROLL_UP:4 SCROLL_DOWN:5
+ * XBUTTON 1:6 XBUTTON 2:7 ...
+ *
+ * To map scroll wheel correctly we need at least the 3 normal buttons
+ */
+ if (lngMouseButtons < 3)
+ lngMouseButtons = 3;
+ winDebug("%d mouse buttons found\n", lngMouseButtons);
+
+ /* allocate memory:
+ * number of buttons + 2x mouse wheel event + 1 extra (offset for map)
+ */
+ map = malloc(sizeof(CARD8) * (lngMouseButtons + lngWheelEvents + 1));
+
+ /* initalize button map */
+ map[0] = 0;
+ for (i=1; i <= lngMouseButtons + lngWheelEvents; i++)
+ map[i] = i;
+
+ btn_labels = calloc((lngMouseButtons + lngWheelEvents), sizeof(Atom));
+ btn_labels[0] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_LEFT);
+ btn_labels[1] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_MIDDLE);
+ btn_labels[2] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_RIGHT);
+ btn_labels[3] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_UP);
+ btn_labels[4] = XIGetKnownProperty(BTN_LABEL_PROP_BTN_WHEEL_DOWN);
+
+ axes_labels[0] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_X);
+ axes_labels[1] = XIGetKnownProperty(AXIS_LABEL_PROP_REL_Y);
+
+ InitPointerDeviceStruct (pDevice,
+ map,
+ lngMouseButtons + lngWheelEvents,
+ btn_labels,
+ winMouseCtrl,
+ GetMotionHistorySize(),
+ 2,
+ axes_labels);
+ free(map);
+ free(btn_labels);
+
+ g_winMouseButtonMap = pDeviceInt->button->map;
+ break;
+
+ case DEVICE_ON:
+ pDevice->on = TRUE;
+ break;
+
+ case DEVICE_CLOSE:
+ g_winMouseButtonMap = NULL;
+ case DEVICE_OFF:
+ pDevice->on = FALSE;
+ break;
+ }
+ return Success;
+}
+
+
+/* Handle the mouse wheel */
+int
+winMouseWheel (ScreenPtr pScreen, int iDeltaZ)
+{
+ winScreenPriv(pScreen);
+ int button; /* Button4 or Button5 */
+
+ /* Button4 = WheelUp */
+ /* Button5 = WheelDown */
+
+ /* Do we have any previous delta stored? */
+ if ((pScreenPriv->iDeltaZ > 0
+ && iDeltaZ > 0)
+ || (pScreenPriv->iDeltaZ < 0
+ && iDeltaZ < 0))
+ {
+ /* Previous delta and of same sign as current delta */
+ iDeltaZ += pScreenPriv->iDeltaZ;
+ pScreenPriv->iDeltaZ = 0;
+ }
+ else
+ {
+ /*
+ * Previous delta of different sign, or zero.
+ * We will set it to zero for either case,
+ * as blindly setting takes just as much time
+ * as checking, then setting if necessary :)
+ */
+ pScreenPriv->iDeltaZ = 0;
+ }
+
+ /*
+ * Only process this message if the wheel has moved further than
+ * WHEEL_DELTA
+ */
+ if (iDeltaZ >= WHEEL_DELTA || (-1 * iDeltaZ) >= WHEEL_DELTA)
+ {
+ pScreenPriv->iDeltaZ = 0;
+
+ /* Figure out how many whole deltas of the wheel we have */
+ iDeltaZ /= WHEEL_DELTA;
+ }
+ else
+ {
+ /*
+ * Wheel has not moved past WHEEL_DELTA threshold;
+ * we will store the wheel delta until the threshold
+ * has been reached.
+ */
+ pScreenPriv->iDeltaZ = iDeltaZ;
+ return 0;
+ }
+
+ /* Set the button to indicate up or down wheel delta */
+ if (iDeltaZ > 0)
+ {
+ button = Button4;
+ }
+ else
+ {
+ button = Button5;
+ }
+
+ /*
+ * Flip iDeltaZ to positive, if negative,
+ * because always need to generate a *positive* number of
+ * button clicks for the Z axis.
+ */
+ if (iDeltaZ < 0)
+ {
+ iDeltaZ *= -1;
+ }
+
+ /* Generate X input messages for each wheel delta we have seen */
+ while (iDeltaZ--)
+ {
+ /* Push the wheel button */
+ winMouseButtonsSendEvent (ButtonPress, button);
+
+ /* Release the wheel button */
+ winMouseButtonsSendEvent (ButtonRelease, button);
+ }
+
+ return 0;
+}
+
+
+/*
+ * Enqueue a mouse button event
+ */
+
+void
+winMouseButtonsSendEvent (int iEventType, int iButton)
+{
+ EventListPtr events;
+ int i, nevents;
+
+ if (g_winMouseButtonMap)
+ iButton = g_winMouseButtonMap[iButton];
+
+ GetEventList(&events);
+ nevents = GetPointerEvents(events, g_pwinPointer, iEventType, iButton,
+ POINTER_RELATIVE, 0, 0, NULL);
+
+ for (i = 0; i < nevents; i++)
+ mieqEnqueue(g_pwinPointer, (InternalEvent*)(events + i)->event);
+
+ winDebug("winMouseButtonsSendEvent: iEventType: %d, iButton: %d, nEvents %d\n",
+ iEventType, iButton, nevents);
+}
+
+
+/*
+ * Decide what to do with a Windows mouse message
+ */
+
+int
+winMouseButtonsHandle (ScreenPtr pScreen,
+ int iEventType, int iButton,
+ WPARAM wParam)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+
+ /* Send button events right away if emulate 3 buttons is off */
+ if (pScreenInfo->iE3BTimeout == WIN_E3B_OFF)
+ {
+ /* Emulate 3 buttons is off, send the button event */
+ winMouseButtonsSendEvent (iEventType, iButton);
+ return 0;
+ }
+
+ /* Emulate 3 buttons is on, let the fun begin */
+ if (iEventType == ButtonPress
+ && pScreenPriv->iE3BCachedPress == 0
+ && !pScreenPriv->fE3BFakeButton2Sent)
+ {
+ /*
+ * Button was pressed, no press is cached,
+ * and there is no fake button 2 release pending.
+ */
+
+ /* Store button press type */
+ pScreenPriv->iE3BCachedPress = iButton;
+
+ /*
+ * Set a timer to send this button press if the other button
+ * is not pressed within the timeout time.
+ */
+ SetTimer (pScreenPriv->hwndScreen,
+ WIN_E3B_TIMER_ID,
+ pScreenInfo->iE3BTimeout,
+ NULL);
+ }
+ else if (iEventType == ButtonPress
+ && pScreenPriv->iE3BCachedPress != 0
+ && pScreenPriv->iE3BCachedPress != iButton
+ && !pScreenPriv->fE3BFakeButton2Sent)
+ {
+ /*
+ * Button press is cached, other button was pressed,
+ * and there is no fake button 2 release pending.
+ */
+
+ /* Mouse button was cached and other button was pressed */
+ KillTimer (pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID);
+ pScreenPriv->iE3BCachedPress = 0;
+
+ /* Send fake middle button */
+ winMouseButtonsSendEvent (ButtonPress, Button2);
+
+ /* Indicate that a fake middle button event was sent */
+ pScreenPriv->fE3BFakeButton2Sent = TRUE;
+ }
+ else if (iEventType == ButtonRelease
+ && pScreenPriv->iE3BCachedPress == iButton)
+ {
+ /*
+ * Cached button was released before timer ran out,
+ * and before the other mouse button was pressed.
+ */
+ KillTimer (pScreenPriv->hwndScreen, WIN_E3B_TIMER_ID);
+ pScreenPriv->iE3BCachedPress = 0;
+
+ /* Send cached press, then send release */
+ winMouseButtonsSendEvent (ButtonPress, iButton);
+ winMouseButtonsSendEvent (ButtonRelease, iButton);
+ }
+ else if (iEventType == ButtonRelease
+ && pScreenPriv->fE3BFakeButton2Sent
+ && !(wParam & MK_LBUTTON)
+ && !(wParam & MK_RBUTTON))
+ {
+ /*
+ * Fake button 2 was sent and both mouse buttons have now been released
+ */
+ pScreenPriv->fE3BFakeButton2Sent = FALSE;
+
+ /* Send middle mouse button release */
+ winMouseButtonsSendEvent (ButtonRelease, Button2);
+ }
+ else if (iEventType == ButtonRelease
+ && pScreenPriv->iE3BCachedPress == 0
+ && !pScreenPriv->fE3BFakeButton2Sent)
+ {
+ /*
+ * Button was release, no button is cached,
+ * and there is no fake button 2 release is pending.
+ */
+ winMouseButtonsSendEvent (ButtonRelease, iButton);
+ }
+
+ return 0;
+}
+
+/**
+ * Enqueue a motion event.
+ *
+ * XXX: miPointerMove does exactly this, but is static :-( (and uses a static buffer)
+ *
+ */
+void winEnqueueMotion(int x, int y)
+{
+ int i, nevents;
+ int valuators[2];
+ EventListPtr events;
+
+ miPointerSetPosition(g_pwinPointer, &x, &y);
+ valuators[0] = x;
+ valuators[1] = y;
+
+ GetEventList(&events);
+ nevents = GetPointerEvents(events, g_pwinPointer, MotionNotify, 0,
+ POINTER_ABSOLUTE | POINTER_SCREEN, 0, 2, valuators);
+
+ for (i = 0; i < nevents; i++)
+ mieqEnqueue(g_pwinPointer, (InternalEvent*)(events + i)->event);
+}
diff --git a/xorg-server/hw/xwin/winmsg.c b/xorg-server/hw/xwin/winmsg.c index d0464f71b..a77fde299 100644 --- a/xorg-server/hw/xwin/winmsg.c +++ b/xorg-server/hw/xwin/winmsg.c @@ -33,71 +33,12 @@ #endif #include "win.h" #include "winmsg.h" -#if CYGDEBUG +#ifdef WINDBG #include "winmessages.h" #endif #include <stdarg.h> -void winVMsg (int, MessageType, int verb, const char *, va_list); - -void -winVMsg (int scrnIndex, MessageType type, int verb, const char *format, - va_list ap) -{ - LogVMessageVerb(type, verb, format, ap); -} - - -void -winDrvMsg (int scrnIndex, MessageType type, const char *format, ...) -{ - va_list ap; - va_start (ap, format); - LogVMessageVerb(type, 0, format, ap); - va_end (ap); -} - - -void -winMsg (MessageType type, const char *format, ...) -{ - va_list ap; - va_start (ap, format); - LogVMessageVerb(type, 1, format, ap); - va_end (ap); -} - - -void -winDrvMsgVerb (int scrnIndex, MessageType type, int verb, const char *format, - ...) -{ - va_list ap; - va_start (ap, format); - LogVMessageVerb(type, verb, format, ap); - va_end (ap); -} - - -void -winMsgVerb (MessageType type, int verb, const char *format, ...) -{ - va_list ap; - va_start (ap, format); - LogVMessageVerb(type, verb, format, ap); - va_end (ap); -} - - -void -winErrorFVerb (int verb, const char *format, ...) -{ - va_list ap; - va_start (ap, format); - LogVMessageVerb(X_NONE, verb, format, ap); - va_end (ap); -} - +#ifdef WINDBG void winDebug (const char *format, ...) { @@ -106,24 +47,16 @@ winDebug (const char *format, ...) LogVMessageVerb(X_NONE, 3, format, ap); va_end (ap); } +#endif void -winTrace (const char *format, ...) -{ - va_list ap; - va_start (ap, format); - LogVMessageVerb(X_NONE, 10, format, ap); - va_end (ap); -} - -void -winW32Error(int verb, const char *msg) +winW32Error(const char *msg) { - winW32ErrorEx(verb, msg, GetLastError()); + winW32ErrorEx(msg, GetLastError()); } void -winW32ErrorEx(int verb, const char *msg, DWORD errorcode) +winW32ErrorEx(const char *msg, DWORD errorcode) { LPVOID buffer; if (!FormatMessage( @@ -137,16 +70,17 @@ winW32ErrorEx(int verb, const char *msg, DWORD errorcode) 0, NULL )) { - winErrorFVerb(verb, "Unknown error in FormatMessage!\n"); + ErrorF(msg); + ErrorF("Unknown error in FormatMessage!\n"); } else { - winErrorFVerb(verb, "%s %s", msg, (char *)buffer); + ErrorF("%s %s", msg, (char *)buffer); LocalFree(buffer); } } -#if CYGDEBUG +#ifdef WINDBG void winDebugWin32Message(const char* function, HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { static int force = 0; @@ -172,8 +106,4 @@ void winDebugWin32Message(const char* function, HWND hwnd, UINT message, WPARAM } } } -#else -void winDebugWin32Message(const char* function, HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) -{ -} #endif diff --git a/xorg-server/hw/xwin/winmsg.h b/xorg-server/hw/xwin/winmsg.h index 611dd6962..ecee86994 100644 --- a/xorg-server/hw/xwin/winmsg.h +++ b/xorg-server/hw/xwin/winmsg.h @@ -33,18 +33,19 @@ /* * Function prototypes */ + +#include "os.h" -void winDrvMsgVerb (int scrnIndex, - MessageType type, int verb, const char *format, ...); -void winDrvMsg (int scrnIndex, MessageType type, const char *format, ...); -void winMsgVerb (MessageType type, int verb, const char *format, ...); -void winMsg (MessageType type, const char *format, ...); +#if !defined(_MSC_VER) || defined(_DEBUG) +#define WINDBG void winDebug (const char *format, ...); -void winTrace (const char *format, ...); - -void winErrorFVerb (int verb, const char *format, ...); -void winW32Error(int verb, const char *message); -void winW32ErrorEx(int verb, const char *message, DWORD errorcode); void winDebugWin32Message(const char* function, HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam); +#else +#define winDebug(...) +#define winDebugWin32Message(...) +#endif + +void winW32Error(const char *message); +void winW32ErrorEx(const char *message, DWORD errorcode); #endif diff --git a/xorg-server/hw/xwin/winmultiwindowicons.c b/xorg-server/hw/xwin/winmultiwindowicons.c index cb27d2fe3..8dae068af 100644 --- a/xorg-server/hw/xwin/winmultiwindowicons.c +++ b/xorg-server/hw/xwin/winmultiwindowicons.c @@ -1,649 +1,657 @@ -/* - *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: Earle F. Philhower, III - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" -#include "dixevents.h" -#include "winmultiwindowclass.h" -#include "winprefs.h" - -#include "propertyst.h" - -#include "propertyst.h" -#include "windowstr.h" - -/* - * External global variables - */ - -extern HICON g_hIconX; -extern HICON g_hSmallIconX; - - -/* - * Prototypes for local functions - */ - -static void -winScaleXBitmapToWindows (int iconSize, int effBPP, - PixmapPtr pixmap, unsigned char *image); - - -/* - * Scale an X icon bitmap into a Windoze icon bitmap - */ - -static void -winScaleXBitmapToWindows (int iconSize, - int effBPP, - PixmapPtr pixmap, - unsigned char *image) -{ - int row, column, effXBPP, effXDepth; - unsigned char *outPtr; - char *iconData = 0; - int stride, xStride; - float factX, factY; - int posX, posY; - unsigned char *ptr; - unsigned int zero; - unsigned int color; - - effXBPP = BitsPerPixel(pixmap->drawable.depth); - effXDepth = pixmap->drawable.depth; - - if (pixmap->drawable.bitsPerPixel == 15) - effXBPP = 16; - - if (pixmap->drawable.depth == 15) - effXDepth = 16; - - /* Need 16-bit aligned rows for DDBitmaps */ - stride = ((iconSize * effBPP + 15) & (~15)) / 8; - xStride = PixmapBytePad (pixmap->drawable.width, pixmap->drawable.depth); - if (stride == 0 || xStride == 0) - { - ErrorF ("winScaleXBitmapToWindows - stride or xStride is zero. " - "Bailing.\n"); - return; - } - - /* Allocate memory for icon data */ - iconData = malloc (xStride * pixmap->drawable.height); - if (!iconData) - { - ErrorF ("winScaleXBitmapToWindows - malloc failed for iconData. " - "Bailing.\n"); - return; - } - - /* Get icon data */ - miGetImage ((DrawablePtr) &(pixmap->drawable), 0, 0, - pixmap->drawable.width, pixmap->drawable.height, - ZPixmap, 0xffffffff, iconData); - - /* Keep aspect ratio */ - factX = ((float)pixmap->drawable.width) / ((float)iconSize); - factY = ((float)pixmap->drawable.height) / ((float)iconSize); - if (factX > factY) - factY = factX; - else - factX = factY; - - /* Out-of-bounds, fill icon with zero */ - zero = 0; - - for (row = 0; row < iconSize; row++) - { - outPtr = image + stride * row; - for (column = 0; column < iconSize; column++) - { - posX = factX * column; - posY = factY * row; - - ptr = (unsigned char*) iconData + posY*xStride; - if (effXBPP == 1) - { - ptr += posX / 8; - - /* Out of X icon bounds, leave space blank */ - if (posX >= pixmap->drawable.width - || posY >= pixmap->drawable.height) - ptr = (unsigned char *) &zero; - - if ((*ptr) & (1 << (posX & 7))) - switch (effBPP) - { - case 32: - *(outPtr++) = 0; - case 24: - *(outPtr++) = 0; - case 16: - *(outPtr++) = 0; - case 8: - *(outPtr++) = 0; - break; - case 1: - outPtr[column / 8] &= ~(1 << (7 - (column & 7))); - break; - } - else - switch (effBPP) - { - case 32: - *(outPtr++) = 255; - *(outPtr++) = 255; - *(outPtr++) = 255; - *(outPtr++) = 0; - break; - case 24: - *(outPtr++) = 255; - case 16: - *(outPtr++) = 255; - case 8: - *(outPtr++) = 255; - break; - case 1: - outPtr[column / 8] |= (1 << (7 - (column & 7))); - break; - } - } - else if (effXDepth == 24 || effXDepth == 32) - { - ptr += posX * (effXBPP / 8); - - /* Out of X icon bounds, leave space blank */ - if (posX >= pixmap->drawable.width - || posY >= pixmap->drawable.height) - ptr = (unsigned char *) &zero; - color = (((*ptr) << 16) - + ((*(ptr + 1)) << 8) - + ((*(ptr + 2)) << 0)); - switch (effBPP) - { - case 32: - *(outPtr++) = *(ptr++); /* b */ - *(outPtr++) = *(ptr++); /* g */ - *(outPtr++) = *(ptr++); /* r */ - *(outPtr++) = (effXDepth == 32) ? *(ptr++) : 0x0; /* alpha */ - break; - case 24: - *(outPtr++) = *(ptr++); - *(outPtr++) = *(ptr++); - *(outPtr++) = *(ptr++); - break; - case 16: - color = ((((*ptr) >> 2) << 10) - + (((*(ptr + 1)) >> 2) << 5) - + (((*(ptr + 2)) >> 2))); - *(outPtr++) = (color >> 8); - *(outPtr++) = (color & 255); - break; - case 8: - color = (((*ptr))) + (((*(ptr + 1)))) + (((*(ptr + 2)))); - color /= 3; - *(outPtr++) = color; - break; - case 1: - if (color) - outPtr[column / 8] |= (1 << (7 - (column & 7))); - else - outPtr[column / 8] &= ~(1 << (7 - (column & 7))); - } - } - else if (effXDepth == 16) - { - ptr += posX * (effXBPP / 8); - - /* Out of X icon bounds, leave space blank */ - if (posX >= pixmap->drawable.width - || posY >= pixmap->drawable.height) - ptr = (unsigned char *) &zero; - color = ((*ptr) << 8) + (*(ptr + 1)); - switch (effBPP) - { - case 32: - *(outPtr++) = (color & 31) << 2; - *(outPtr++) = ((color >> 5) & 31) << 2; - *(outPtr++) = ((color >> 10) & 31) << 2; - *(outPtr++) = 0; /* resvd */ - break; - case 24: - *(outPtr++) = (color & 31) << 2; - *(outPtr++) = ((color >> 5) & 31) << 2; - *(outPtr++) = ((color >> 10) & 31) << 2; - break; - case 16: - *(outPtr++) = *(ptr++); - *(outPtr++) = *(ptr++); - break; - case 8: - *(outPtr++) = (((color & 31) - + ((color >> 5) & 31) - + ((color >> 10) & 31)) / 3) << 2; - break; - case 1: - if (color) - outPtr[column / 8] |= (1 << (7 - (column & 7))); - else - outPtr[column / 8] &= ~(1 << (7 - (column & 7))); - break; - } /* end switch(effbpp) */ - } /* end if effxbpp==16) */ - } /* end for column */ - } /* end for row */ - free (iconData); -} - -static HICON -NetWMToWinIconAlpha(uint32_t *icon) -{ - int width = icon[0]; - int height = icon[1]; - uint32_t *pixels = &icon[2]; - HICON result; - HDC hdc = GetDC(NULL); - uint32_t *DIB_pixels; - ICONINFO ii = {TRUE}; - BITMAPV4HEADER bmh = {sizeof(bmh)}; - - /* Define an ARGB pixel format used for Color+Alpha icons */ - bmh.bV4Width = width; - bmh.bV4Height = -height; /* Invert the image */ - bmh.bV4Planes = 1; - bmh.bV4BitCount = 32; - bmh.bV4V4Compression = BI_BITFIELDS; - bmh.bV4AlphaMask = 0xFF000000; - bmh.bV4RedMask = 0x00FF0000; - bmh.bV4GreenMask = 0x0000FF00; - bmh.bV4BlueMask = 0x000000FF; - - ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO*)&bmh, - DIB_RGB_COLORS, (void**)&DIB_pixels, NULL, 0); - ReleaseDC(NULL, hdc); - ii.hbmMask = CreateBitmap(width, height, 1, 1, NULL); - memcpy(DIB_pixels, pixels, height*width*4); - - /* CreateIconIndirect() traditionally required DDBitmaps */ - /* Systems from WinXP accept 32-bit ARGB DIBitmaps with full 8-bit alpha support */ - /* The icon is created with a DIB + empty DDB mask (an MS example does the same) */ - result = CreateIconIndirect(&ii); - - DeleteObject(ii.hbmColor); - DeleteObject(ii.hbmMask); - - winDebug("NetWMToWinIconAlpha - %d x %d = %p\n", icon[0], icon[1], result); - return result; -} - -static HICON -NetWMToWinIconThreshold(uint32_t *icon) -{ - int width = icon[0]; - int height = icon[1]; - uint32_t *pixels = &icon[2]; - int row, col; - HICON result; - ICONINFO ii = {TRUE}; - - HDC hdc = GetDC(NULL); - HDC xorDC = CreateCompatibleDC(hdc); - HDC andDC = CreateCompatibleDC(hdc); - ii.hbmColor = CreateCompatibleBitmap(hdc, width, height); - ii.hbmMask = CreateCompatibleBitmap(hdc, width, height); - ReleaseDC(NULL, hdc); - SelectObject(xorDC, ii.hbmColor); - SelectObject(andDC, ii.hbmMask); - - for (row = 0; row < height; row++) { - for (col = 0; col < width; col++) { - if ((*pixels & 0xFF000000) > 31<<24) { /* 31 alpha threshold, i.e. opaque above, transparent below */ - SetPixelV(xorDC, col, row, RGB(((char*)pixels)[2], ((char*)pixels)[1], - ((char*)pixels)[0])); - SetPixelV(andDC, col, row, RGB(0, 0, 0)); /* black mask */ - } - else { - SetPixelV(xorDC, col, row, RGB(0, 0, 0)); - SetPixelV(andDC, col, row, RGB(255, 255, 255)); /* white mask */ - } - pixels++; - } - } - DeleteDC(xorDC); - DeleteDC(andDC); - - result = CreateIconIndirect(&ii); - - DeleteObject(ii.hbmColor); - DeleteObject(ii.hbmMask ); - - winDebug("NetWMToWinIconThreshold - %d x %d = %p\n", icon[0], icon[1], result); - return result; -} - -static HICON -NetWMToWinIcon(int bpp, uint32_t *icon) -{ - static Bool hasIconAlphaChannel = FALSE; - static BOOL versionChecked = FALSE; - - if (!versionChecked) - { - OSVERSIONINFOEX osvi = {0}; - ULONGLONG dwlConditionMask = 0; - - osvi.dwOSVersionInfoSize = sizeof (osvi); - osvi.dwMajorVersion = 5; - osvi.dwMinorVersion = 1; - - /* Windows versions later than XP have icon alpha channel suport, 2000 does not */ - VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL); - VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL); - hasIconAlphaChannel = VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask); - versionChecked = TRUE; - - ErrorF("OS has icon alpha channel support: %s\n", hasIconAlphaChannel ? "yes" : "no"); - } - - if (hasIconAlphaChannel && (bpp==32)) - return NetWMToWinIconAlpha(icon); - else - return NetWMToWinIconThreshold(icon); -} - -static pointer -GetWindowProp(WindowPtr pWin, Atom name, long int *size_return) -{ - struct _Window *pwin; - struct _Property *prop; - - if (!pWin || !name) { - ErrorF ("GetWindowProp - pWin or name was NULL\n"); - return 0; - } - pwin = (struct _Window*) pWin; - if (!pwin->optional) return NULL; - for (prop = (struct _Property *) pwin->optional->userProps; - prop; - prop=prop->next){ - if (prop->propertyName == name) { - *size_return=prop->size; - return prop->data; - } - } - return NULL; -} - -/* - * Attempt to create a custom icon from the WM_HINTS bitmaps - */ - -HICON -winXIconToHICON (WindowPtr pWin, int iconSize) -{ - unsigned char *mask, *image, *imageMask; - unsigned char *dst, *src; - PixmapPtr iconPtr; - PixmapPtr maskPtr; - int planes, bpp, effBPP, stride, maskStride, i; - int biggest_size = 0; - HDC hDC; - ICONINFO ii; - WinXWMHints hints; - HICON hIcon = NULL; - uint32_t *biggest_icon = NULL; - - /* Try to get _NET_WM_ICON icons first */ - static Atom _XA_NET_WM_ICON; - static int generation; - uint32_t *icon, *icon_data = NULL; - long int size=0; - - hDC = GetDC (GetDesktopWindow ()); - planes = GetDeviceCaps (hDC, PLANES); - bpp = GetDeviceCaps (hDC, BITSPIXEL); - ReleaseDC (GetDesktopWindow (), hDC); - - if (generation != serverGeneration) { - generation = serverGeneration; - _XA_NET_WM_ICON = MakeAtom("_NET_WM_ICON", 12, TRUE); - } - - if (_XA_NET_WM_ICON) icon_data = GetWindowProp(pWin, _XA_NET_WM_ICON, &size); - if (icon_data) - { - for(icon = icon_data; - icon < &icon_data[size] && *icon; - icon = &icon[icon[0]*icon[1]+2]) - { - if (icon[0]==iconSize && icon[1]==iconSize) - return NetWMToWinIcon(bpp, icon); - /* Find the biggest icon and let Windows scale the size */ - else if (biggest_size < icon[0]) - { - biggest_icon = icon; - biggest_size = icon[0]; - } - } - if (biggest_icon) - return NetWMToWinIcon(bpp, biggest_icon); - } - winDebug("winXIconToHICON - pWin %x: no suitable NetIcon\n",(int)pWin, iconSize); - - winMultiWindowGetWMHints (pWin, &hints); - if (!hints.icon_pixmap) return NULL; - - dixLookupResourceByType((pointer) &iconPtr, hints.icon_pixmap, RT_PIXMAP, - NullClient, DixUnknownAccess); - - if (!iconPtr) return NULL; - - /* 15 BPP is really 16BPP as far as we care */ - if (bpp == 15) - effBPP = 16; - else - effBPP = bpp; - - /* Need 16-bit aligned rows for DDBitmaps */ - stride = ((iconSize * effBPP + 15) & (~15)) / 8; - - /* Mask is 1-bit deep */ - maskStride = ((iconSize * 1 + 15) & (~15)) / 8; - - image = malloc (stride * iconSize); - imageMask = malloc (stride * iconSize); - /* Default to a completely black mask */ - mask = calloc (maskStride, iconSize); - - winScaleXBitmapToWindows (iconSize, effBPP, iconPtr, image); - dixLookupResourceByType((pointer) &maskPtr, hints.icon_mask, RT_PIXMAP, - NullClient, DixUnknownAccess); - - if (maskPtr) - { - winScaleXBitmapToWindows (iconSize, 1, maskPtr, mask); - - winScaleXBitmapToWindows (iconSize, effBPP, maskPtr, imageMask); - - /* Now we need to set all bits of the icon which are not masked */ - /* on to 0 because Color is really an XOR, not an OR function */ - dst = image; - src = imageMask; - - for (i = 0; i < (stride * iconSize); i++) - if ((*(src++))) - *(dst++) = 0; - else - dst++; - } - - ii.fIcon = TRUE; - ii.xHotspot = 0; /* ignored */ - ii.yHotspot = 0; /* ignored */ - - /* Create Win32 mask from pixmap shape */ - ii.hbmMask = CreateBitmap (iconSize, iconSize, planes, 1, mask); - - /* Create Win32 bitmap from pixmap */ - ii.hbmColor = CreateBitmap (iconSize, iconSize, planes, bpp, image); - - /* Merge Win32 mask and bitmap into icon */ - hIcon = CreateIconIndirect (&ii); - - /* Release Win32 mask and bitmap */ - DeleteObject (ii.hbmMask); - DeleteObject (ii.hbmColor); - - /* Free X mask and bitmap */ - free (mask); - free (image); - free (imageMask); - - return hIcon; -} - - - -/* - * Change the Windows window icon - */ - -#ifdef XWIN_MULTIWINDOW -void -winUpdateIcon (Window id) -{ - WindowPtr pWin; - HICON hIcon, hIconSmall=NULL, hIconOld; - - dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess); - if (pWin) - { - winWindowPriv(pWin); - if (pWinPriv->hWnd) { - hIcon = winOverrideIcon ((unsigned long)pWin); - if (!hIcon) { - hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON)); - if (!hIcon) { - hIcon = g_hIconX; - hIconSmall = g_hSmallIconX; - } else { - /* Leave undefined if not found */ - hIconSmall = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON)); - } - } - - /* Set the large icon */ - hIconOld = (HICON) SendMessage (pWinPriv->hWnd, - WM_SETICON, ICON_BIG, (LPARAM) hIcon); - - /* Delete the icon if its not the default */ - winDestroyIcon(hIconOld); - - /* Same for the small icon */ - hIconOld = (HICON) SendMessage (pWinPriv->hWnd, - WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall); - winDestroyIcon(hIconOld); - } - } -} - -void winInitGlobalIcons (void) -{ - int sm_cx = GetSystemMetrics(SM_CXICON); - int sm_cxsm = GetSystemMetrics(SM_CXSMICON); - /* Load default X icon in case it's not ready yet */ - if (!g_hIconX) - { - g_hIconX = winOverrideDefaultIcon(sm_cx); - g_hSmallIconX = winOverrideDefaultIcon(sm_cxsm); - } - - if (!g_hIconX) - { - g_hIconX = (HICON)LoadImage (g_hInstance, - MAKEINTRESOURCE(IDI_XWIN), - IMAGE_ICON, - GetSystemMetrics(SM_CXICON), - GetSystemMetrics(SM_CYICON), - 0); - g_hSmallIconX = (HICON)LoadImage (g_hInstance, - MAKEINTRESOURCE(IDI_XWIN), - IMAGE_ICON, - GetSystemMetrics(SM_CXSMICON), - GetSystemMetrics(SM_CYSMICON), - LR_DEFAULTSIZE); - } -} - -void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon) -{ - HICON hIcon, hSmallIcon; - - winInitGlobalIcons(); - - /* Try and get the icon from WM_HINTS */ - hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON)); - hSmallIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON)); - - /* If we got the small, but not the large one swap them */ - if (!hIcon && hSmallIcon) - { - hIcon = hSmallIcon; - hSmallIcon = NULL; - } - - /* Use default X icon if no icon loaded from WM_HINTS */ - if (!hIcon) { - hIcon = g_hIconX; - hSmallIcon = g_hSmallIconX; - } - - if (pIcon) - *pIcon = hIcon; - else - winDestroyIcon(hIcon); - if (pSmallIcon) - *pSmallIcon = hSmallIcon; - else - winDestroyIcon(hSmallIcon); -} - -void winDestroyIcon(HICON hIcon) -{ - /* Delete the icon if its not the default */ - if (hIcon && - hIcon != g_hIconX && - hIcon != g_hSmallIconX && - !winIconIsOverride((unsigned long)hIcon)) - DestroyIcon (hIcon); -} -#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: Earle F. Philhower, III
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include "dixevents.h"
+#include "winmultiwindowclass.h"
+#include "winprefs.h"
+
+#include "propertyst.h"
+
+#include "propertyst.h"
+#include "windowstr.h"
+
+/*
+ * External global variables
+ */
+
+extern HICON g_hIconX;
+extern HICON g_hSmallIconX;
+
+
+/*
+ * Prototypes for local functions
+ */
+
+static void
+winScaleXBitmapToWindows (int iconSize, int effBPP,
+ PixmapPtr pixmap, unsigned char *image);
+
+
+/*
+ * Scale an X icon bitmap into a Windoze icon bitmap
+ */
+
+static void
+winScaleXBitmapToWindows (int iconSize,
+ int effBPP,
+ PixmapPtr pixmap,
+ unsigned char *image)
+{
+ int row, column, effXBPP, effXDepth;
+ unsigned char *outPtr;
+ char *iconData = 0;
+ int stride, xStride;
+ float factX, factY;
+ int posX, posY;
+ unsigned char *ptr;
+ unsigned int zero;
+ unsigned int color;
+
+ effXBPP = BitsPerPixel(pixmap->drawable.depth);
+ effXDepth = pixmap->drawable.depth;
+
+ if (pixmap->drawable.bitsPerPixel == 15)
+ effXBPP = 16;
+
+ if (pixmap->drawable.depth == 15)
+ effXDepth = 16;
+
+ /* Need 16-bit aligned rows for DDBitmaps */
+ stride = ((iconSize * effBPP + 15) & (~15)) / 8;
+ xStride = PixmapBytePad (pixmap->drawable.width, pixmap->drawable.depth);
+ if (stride == 0 || xStride == 0)
+ {
+ ErrorF ("winScaleXBitmapToWindows - stride or xStride is zero. "
+ "Bailing.\n");
+ return;
+ }
+
+ /* Allocate memory for icon data */
+ iconData = malloc (xStride * pixmap->drawable.height);
+ if (!iconData)
+ {
+ ErrorF ("winScaleXBitmapToWindows - malloc failed for iconData. "
+ "Bailing.\n");
+ return;
+ }
+
+ /* Get icon data */
+ miGetImage ((DrawablePtr) &(pixmap->drawable), 0, 0,
+ pixmap->drawable.width, pixmap->drawable.height,
+ ZPixmap, 0xffffffff, iconData);
+
+ /* Keep aspect ratio */
+ factX = ((float)pixmap->drawable.width) / ((float)iconSize);
+ factY = ((float)pixmap->drawable.height) / ((float)iconSize);
+ if (factX > factY)
+ factY = factX;
+ else
+ factX = factY;
+
+ /* Out-of-bounds, fill icon with zero */
+ zero = 0;
+
+ for (row = 0; row < iconSize; row++)
+ {
+ outPtr = image + stride * row;
+ for (column = 0; column < iconSize; column++)
+ {
+ posX = factX * column;
+ posY = factY * row;
+
+ ptr = (unsigned char*) iconData + posY*xStride;
+ if (effXBPP == 1)
+ {
+ ptr += posX / 8;
+
+ /* Out of X icon bounds, leave space blank */
+ if (posX >= pixmap->drawable.width
+ || posY >= pixmap->drawable.height)
+ ptr = (unsigned char *) &zero;
+
+ if ((*ptr) & (1 << (posX & 7)))
+ switch (effBPP)
+ {
+ case 32:
+ *(outPtr++) = 0;
+ case 24:
+ *(outPtr++) = 0;
+ case 16:
+ *(outPtr++) = 0;
+ case 8:
+ *(outPtr++) = 0;
+ break;
+ case 1:
+ outPtr[column / 8] &= ~(1 << (7 - (column & 7)));
+ break;
+ }
+ else
+ switch (effBPP)
+ {
+ case 32:
+ *(outPtr++) = 255;
+ *(outPtr++) = 255;
+ *(outPtr++) = 255;
+ *(outPtr++) = 0;
+ break;
+ case 24:
+ *(outPtr++) = 255;
+ case 16:
+ *(outPtr++) = 255;
+ case 8:
+ *(outPtr++) = 255;
+ break;
+ case 1:
+ outPtr[column / 8] |= (1 << (7 - (column & 7)));
+ break;
+ }
+ }
+ else if (effXDepth == 24 || effXDepth == 32)
+ {
+ ptr += posX * (effXBPP / 8);
+
+ /* Out of X icon bounds, leave space blank */
+ if (posX >= pixmap->drawable.width
+ || posY >= pixmap->drawable.height)
+ ptr = (unsigned char *) &zero;
+ color = (((*ptr) << 16)
+ + ((*(ptr + 1)) << 8)
+ + ((*(ptr + 2)) << 0));
+ switch (effBPP)
+ {
+ case 32:
+ *(outPtr++) = *(ptr++); /* b */
+ *(outPtr++) = *(ptr++); /* g */
+ *(outPtr++) = *(ptr++); /* r */
+ *(outPtr++) = (effXDepth == 32) ? *(ptr++) : 0x0; /* alpha */
+ break;
+ case 24:
+ *(outPtr++) = *(ptr++);
+ *(outPtr++) = *(ptr++);
+ *(outPtr++) = *(ptr++);
+ break;
+ case 16:
+ color = ((((*ptr) >> 2) << 10)
+ + (((*(ptr + 1)) >> 2) << 5)
+ + (((*(ptr + 2)) >> 2)));
+ *(outPtr++) = (color >> 8);
+ *(outPtr++) = (color & 255);
+ break;
+ case 8:
+ color = (((*ptr))) + (((*(ptr + 1)))) + (((*(ptr + 2))));
+ color /= 3;
+ *(outPtr++) = color;
+ break;
+ case 1:
+ if (color)
+ outPtr[column / 8] |= (1 << (7 - (column & 7)));
+ else
+ outPtr[column / 8] &= ~(1 << (7 - (column & 7)));
+ }
+ }
+ else if (effXDepth == 16)
+ {
+ ptr += posX * (effXBPP / 8);
+
+ /* Out of X icon bounds, leave space blank */
+ if (posX >= pixmap->drawable.width
+ || posY >= pixmap->drawable.height)
+ ptr = (unsigned char *) &zero;
+ color = ((*ptr) << 8) + (*(ptr + 1));
+ switch (effBPP)
+ {
+ case 32:
+ *(outPtr++) = (color & 31) << 2;
+ *(outPtr++) = ((color >> 5) & 31) << 2;
+ *(outPtr++) = ((color >> 10) & 31) << 2;
+ *(outPtr++) = 0; /* resvd */
+ break;
+ case 24:
+ *(outPtr++) = (color & 31) << 2;
+ *(outPtr++) = ((color >> 5) & 31) << 2;
+ *(outPtr++) = ((color >> 10) & 31) << 2;
+ break;
+ case 16:
+ *(outPtr++) = *(ptr++);
+ *(outPtr++) = *(ptr++);
+ break;
+ case 8:
+ *(outPtr++) = (((color & 31)
+ + ((color >> 5) & 31)
+ + ((color >> 10) & 31)) / 3) << 2;
+ break;
+ case 1:
+ if (color)
+ outPtr[column / 8] |= (1 << (7 - (column & 7)));
+ else
+ outPtr[column / 8] &= ~(1 << (7 - (column & 7)));
+ break;
+ } /* end switch(effbpp) */
+ } /* end if effxbpp==16) */
+ } /* end for column */
+ } /* end for row */
+ free (iconData);
+}
+
+static HICON
+NetWMToWinIconAlpha(uint32_t *icon)
+{
+ int width = icon[0];
+ int height = icon[1];
+ uint32_t *pixels = &icon[2];
+ HICON result;
+ HDC hdc = GetDC(NULL);
+ uint32_t *DIB_pixels;
+ ICONINFO ii;
+ BITMAPV5HEADER bmh;
+
+ /* Define an ARGB pixel format used for Color+Alpha icons */
+ ZeroMemory(&bmh,sizeof(bmh));
+ bmh.bV5Size = sizeof(bmh);
+ bmh.bV5Width = width;
+ bmh.bV5Height = -height; /* Invert the image */
+ bmh.bV5Planes = 1;
+ bmh.bV5BitCount = 32;
+ bmh.bV5Compression = BI_BITFIELDS;
+ bmh.bV5AlphaMask = 0xFF000000;
+ bmh.bV5RedMask = 0x00FF0000;
+ bmh.bV5GreenMask = 0x0000FF00;
+ bmh.bV5BlueMask = 0x000000FF;
+
+ ii.hbmColor = CreateDIBSection(hdc, (BITMAPINFO*)&bmh,
+ DIB_RGB_COLORS, (void**)&DIB_pixels, NULL, 0);
+ ReleaseDC(NULL, hdc);
+ ii.hbmMask = CreateBitmap(width, height, 1, 1, NULL);
+ memcpy(DIB_pixels, pixels, height*width*4);
+
+ /* CreateIconIndirect() traditionally required DDBitmaps */
+ /* Systems from WinXP accept 32-bit ARGB DIBitmaps with full 8-bit alpha support */
+ /* The icon is created with a DIB + empty DDB mask (an MS example does the same) */
+ ii.fIcon = TRUE;
+ ii.xHotspot = 0;
+ ii.yHotspot = 0;
+ result = CreateIconIndirect(&ii);
+
+ DeleteObject(ii.hbmColor);
+ DeleteObject(ii.hbmMask);
+
+ winDebug("NetWMToWinIconAlpha - %d x %d = %p\n", icon[0], icon[1], result);
+ return result;
+}
+
+static HICON
+NetWMToWinIconThreshold(uint32_t *icon)
+{
+ int width = icon[0];
+ int height = icon[1];
+ uint32_t *pixels = &icon[2];
+ int row, col;
+ HICON result;
+ ICONINFO ii;
+
+ HDC hdc = GetDC(NULL);
+ HDC xorDC = CreateCompatibleDC(hdc);
+ HDC andDC = CreateCompatibleDC(hdc);
+ ii.hbmColor = CreateCompatibleBitmap(hdc, width, height);
+ ii.hbmMask = CreateCompatibleBitmap(hdc, width, height);
+ ReleaseDC(NULL, hdc);
+ SelectObject(xorDC, ii.hbmColor);
+ SelectObject(andDC, ii.hbmMask);
+
+ for (row = 0; row < height; row++) {
+ for (col = 0; col < width; col++) {
+ if ((*pixels & 0xFF000000) > 31<<24) { /* 31 alpha threshold, i.e. opaque above, transparent below */
+ SetPixelV(xorDC, col, row, RGB(((char*)pixels)[2], ((char*)pixels)[1],
+ ((char*)pixels)[0]));
+ SetPixelV(andDC, col, row, RGB(0, 0, 0)); /* black mask */
+ }
+ else {
+ SetPixelV(xorDC, col, row, RGB(0, 0, 0));
+ SetPixelV(andDC, col, row, RGB(255, 255, 255)); /* white mask */
+ }
+ pixels++;
+ }
+ }
+ DeleteDC(xorDC);
+ DeleteDC(andDC);
+
+ ii.fIcon = TRUE;
+ ii.xHotspot = 0;
+ ii.yHotspot = 0;
+ result = CreateIconIndirect(&ii);
+
+ DeleteObject(ii.hbmColor);
+ DeleteObject(ii.hbmMask );
+
+ winDebug("NetWMToWinIconThreshold - %d x %d = %p\n", icon[0], icon[1], result);
+ return result;
+}
+
+static HICON
+NetWMToWinIcon(int bpp, uint32_t *icon)
+{
+ static Bool hasIconAlphaChannel = FALSE;
+ static BOOL versionChecked = FALSE;
+
+ if (!versionChecked)
+ {
+ OSVERSIONINFOEX osvi = {0};
+ ULONGLONG dwlConditionMask = 0;
+
+ osvi.dwOSVersionInfoSize = sizeof (osvi);
+ osvi.dwMajorVersion = 5;
+ osvi.dwMinorVersion = 1;
+
+ /* Windows versions later than XP have icon alpha channel suport, 2000 does not */
+ VER_SET_CONDITION(dwlConditionMask, VER_MAJORVERSION, VER_GREATER_EQUAL);
+ VER_SET_CONDITION(dwlConditionMask, VER_MINORVERSION, VER_GREATER_EQUAL);
+ hasIconAlphaChannel = VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, dwlConditionMask);
+ versionChecked = TRUE;
+
+ winDebug("OS has icon alpha channel support: %s\n", hasIconAlphaChannel ? "yes" : "no");
+ }
+
+ if (hasIconAlphaChannel && (bpp==32))
+ return NetWMToWinIconAlpha(icon);
+ else
+ return NetWMToWinIconThreshold(icon);
+}
+
+static pointer
+GetWindowProp(WindowPtr pWin, Atom name, long int *size_return)
+{
+ struct _Window *pwin;
+ struct _Property *prop;
+
+ if (!pWin || !name) {
+ ErrorF ("GetWindowProp - pWin or name was NULL\n");
+ return 0;
+ }
+ pwin = (struct _Window*) pWin;
+ if (!pwin->optional) return NULL;
+ for (prop = (struct _Property *) pwin->optional->userProps;
+ prop;
+ prop=prop->next){
+ if (prop->propertyName == name) {
+ *size_return=prop->size;
+ return prop->data;
+ }
+ }
+ return NULL;
+}
+
+/*
+ * Attempt to create a custom icon from the WM_HINTS bitmaps
+ */
+
+HICON
+winXIconToHICON (WindowPtr pWin, int iconSize)
+{
+ unsigned char *mask, *image, *imageMask;
+ unsigned char *dst, *src;
+ PixmapPtr iconPtr;
+ PixmapPtr maskPtr;
+ int planes, bpp, effBPP, stride, maskStride, i;
+ int biggest_size = 0;
+ HDC hDC;
+ ICONINFO ii;
+ WinXWMHints hints;
+ HICON hIcon = NULL;
+ uint32_t *biggest_icon = NULL;
+
+ /* Try to get _NET_WM_ICON icons first */
+ static Atom _XA_NET_WM_ICON;
+ static int generation;
+ uint32_t *icon, *icon_data = NULL;
+ long int size=0;
+
+ hDC = GetDC (GetDesktopWindow ());
+ planes = GetDeviceCaps (hDC, PLANES);
+ bpp = GetDeviceCaps (hDC, BITSPIXEL);
+ ReleaseDC (GetDesktopWindow (), hDC);
+
+ if (generation != serverGeneration) {
+ generation = serverGeneration;
+ _XA_NET_WM_ICON = MakeAtom("_NET_WM_ICON", 12, TRUE);
+ }
+
+ if (_XA_NET_WM_ICON) icon_data = GetWindowProp(pWin, _XA_NET_WM_ICON, &size);
+ if (icon_data)
+ {
+ for(icon = icon_data;
+ icon < &icon_data[size] && *icon;
+ icon = &icon[icon[0]*icon[1]+2])
+ {
+ if (icon[0]==iconSize && icon[1]==iconSize)
+ return NetWMToWinIcon(bpp, icon);
+ /* Find the biggest icon and let Windows scale the size */
+ else if (biggest_size < icon[0])
+ {
+ biggest_icon = icon;
+ biggest_size = icon[0];
+ }
+ }
+ if (biggest_icon)
+ return NetWMToWinIcon(bpp, biggest_icon);
+ }
+ winDebug("winXIconToHICON - pWin %x: no suitable NetIcon\n",(int)pWin, iconSize);
+
+ winMultiWindowGetWMHints (pWin, &hints);
+ if (!hints.icon_pixmap) return NULL;
+
+ dixLookupResourceByType((pointer) &iconPtr, hints.icon_pixmap, RT_PIXMAP,
+ NullClient, DixUnknownAccess);
+
+ if (!iconPtr) return NULL;
+
+ /* 15 BPP is really 16BPP as far as we care */
+ if (bpp == 15)
+ effBPP = 16;
+ else
+ effBPP = bpp;
+
+ /* Need 16-bit aligned rows for DDBitmaps */
+ stride = ((iconSize * effBPP + 15) & (~15)) / 8;
+
+ /* Mask is 1-bit deep */
+ maskStride = ((iconSize * 1 + 15) & (~15)) / 8;
+
+ image = malloc (stride * iconSize);
+ imageMask = malloc (stride * iconSize);
+ /* Default to a completely black mask */
+ mask = calloc (maskStride, iconSize);
+
+ winScaleXBitmapToWindows (iconSize, effBPP, iconPtr, image);
+ dixLookupResourceByType((pointer) &maskPtr, hints.icon_mask, RT_PIXMAP,
+ NullClient, DixUnknownAccess);
+
+ if (maskPtr)
+ {
+ winScaleXBitmapToWindows (iconSize, 1, maskPtr, mask);
+
+ winScaleXBitmapToWindows (iconSize, effBPP, maskPtr, imageMask);
+
+ /* Now we need to set all bits of the icon which are not masked */
+ /* on to 0 because Color is really an XOR, not an OR function */
+ dst = image;
+ src = imageMask;
+
+ for (i = 0; i < (stride * iconSize); i++)
+ if ((*(src++)))
+ *(dst++) = 0;
+ else
+ dst++;
+ }
+
+ ii.fIcon = TRUE;
+ ii.xHotspot = 0; /* ignored */
+ ii.yHotspot = 0; /* ignored */
+
+ /* Create Win32 mask from pixmap shape */
+ ii.hbmMask = CreateBitmap (iconSize, iconSize, planes, 1, mask);
+
+ /* Create Win32 bitmap from pixmap */
+ ii.hbmColor = CreateBitmap (iconSize, iconSize, planes, bpp, image);
+
+ /* Merge Win32 mask and bitmap into icon */
+ hIcon = CreateIconIndirect (&ii);
+
+ /* Release Win32 mask and bitmap */
+ DeleteObject (ii.hbmMask);
+ DeleteObject (ii.hbmColor);
+
+ /* Free X mask and bitmap */
+ free (mask);
+ free (image);
+ free (imageMask);
+
+ return hIcon;
+}
+
+
+
+/*
+ * Change the Windows window icon
+ */
+
+#ifdef XWIN_MULTIWINDOW
+void
+winUpdateIcon (Window id)
+{
+ WindowPtr pWin;
+ HICON hIcon, hIconSmall=NULL, hIconOld;
+
+ dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess);
+ if (pWin)
+ {
+ winWindowPriv(pWin);
+ if (pWinPriv->hWnd) {
+ hIcon = winOverrideIcon ((unsigned long)pWin);
+ if (!hIcon) {
+ hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON));
+ if (!hIcon) {
+ hIcon = g_hIconX;
+ hIconSmall = g_hSmallIconX;
+ } else {
+ /* Leave undefined if not found */
+ hIconSmall = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON));
+ }
+ }
+
+ /* Set the large icon */
+ hIconOld = (HICON) SendMessage (pWinPriv->hWnd,
+ WM_SETICON, ICON_BIG, (LPARAM) hIcon);
+
+ /* Delete the icon if its not the default */
+ winDestroyIcon(hIconOld);
+
+ /* Same for the small icon */
+ hIconOld = (HICON) SendMessage (pWinPriv->hWnd,
+ WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall);
+ winDestroyIcon(hIconOld);
+ }
+ }
+}
+
+void winInitGlobalIcons (void)
+{
+ int sm_cx = GetSystemMetrics(SM_CXICON);
+ int sm_cxsm = GetSystemMetrics(SM_CXSMICON);
+ /* Load default X icon in case it's not ready yet */
+ if (!g_hIconX)
+ {
+ g_hIconX = winOverrideDefaultIcon(sm_cx);
+ g_hSmallIconX = winOverrideDefaultIcon(sm_cxsm);
+ }
+
+ if (!g_hIconX)
+ {
+ g_hIconX = (HICON)LoadImage (g_hInstance,
+ MAKEINTRESOURCE(IDI_XWIN),
+ IMAGE_ICON,
+ GetSystemMetrics(SM_CXICON),
+ GetSystemMetrics(SM_CYICON),
+ 0);
+ g_hSmallIconX = (HICON)LoadImage (g_hInstance,
+ MAKEINTRESOURCE(IDI_XWIN),
+ IMAGE_ICON,
+ GetSystemMetrics(SM_CXSMICON),
+ GetSystemMetrics(SM_CYSMICON),
+ LR_DEFAULTSIZE);
+ }
+}
+
+void winSelectIcons(WindowPtr pWin, HICON *pIcon, HICON *pSmallIcon)
+{
+ HICON hIcon, hSmallIcon;
+
+ winInitGlobalIcons();
+
+ /* Try and get the icon from WM_HINTS */
+ hIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXICON));
+ hSmallIcon = winXIconToHICON (pWin, GetSystemMetrics(SM_CXSMICON));
+
+ /* If we got the small, but not the large one swap them */
+ if (!hIcon && hSmallIcon)
+ {
+ hIcon = hSmallIcon;
+ hSmallIcon = NULL;
+ }
+
+ /* Use default X icon if no icon loaded from WM_HINTS */
+ if (!hIcon) {
+ hIcon = g_hIconX;
+ hSmallIcon = g_hSmallIconX;
+ }
+
+ if (pIcon)
+ *pIcon = hIcon;
+ else
+ winDestroyIcon(hIcon);
+ if (pSmallIcon)
+ *pSmallIcon = hSmallIcon;
+ else
+ winDestroyIcon(hSmallIcon);
+}
+
+void winDestroyIcon(HICON hIcon)
+{
+ /* Delete the icon if its not the default */
+ if (hIcon &&
+ hIcon != g_hIconX &&
+ hIcon != g_hSmallIconX &&
+ !winIconIsOverride((unsigned long)hIcon))
+ DestroyIcon (hIcon);
+}
+#endif
diff --git a/xorg-server/hw/xwin/winmultiwindowshape.c b/xorg-server/hw/xwin/winmultiwindowshape.c index 353235760..32a3f16e6 100644 --- a/xorg-server/hw/xwin/winmultiwindowshape.c +++ b/xorg-server/hw/xwin/winmultiwindowshape.c @@ -46,9 +46,7 @@ winSetShapeMultiWindow (WindowPtr pWin) ScreenPtr pScreen = pWin->drawable.pScreen; winScreenPriv(pScreen); -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winSetShapeMultiWindow - pWin: %08x\n", pWin); -#endif + winDebug ("winSetShapeMultiWindow - pWin: %08x\n", pWin); WIN_UNWRAP(SetShape); (*pScreen->SetShape)(pWin); @@ -90,9 +88,7 @@ winReshapeMultiWindow (WindowPtr pWin) HRGN hRgn, hRgnRect; winWindowPriv(pWin); -#if CYGDEBUG winDebug ("winReshape ()\n"); -#endif /* Bail if the window is the root window */ if (pWin->parent == NULL) @@ -209,3 +205,14 @@ winReshapeMultiWindow (WindowPtr pWin) return; } + +void +winShapeRgnUpdateMultiwindow(HWND hwnd) +{ + WindowPtr pWin = GetProp (hwnd, WIN_WINDOW_PROP); + if (pWin) + { + winReshapeMultiWindow(pWin); + winUpdateRgnMultiWindow(pWin); + } +} diff --git a/xorg-server/hw/xwin/winmultiwindowwindow.c b/xorg-server/hw/xwin/winmultiwindowwindow.c index 87ffc6d6b..fbde122a1 100644 --- a/xorg-server/hw/xwin/winmultiwindowwindow.c +++ b/xorg-server/hw/xwin/winmultiwindowwindow.c @@ -1,1001 +1,918 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. - *Copyright (C) Colin Harrison 2005-2008 - * - *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: Kensuke Matsuzaki - * Earle F. Philhower, III - * Harold L Hunt II - * Colin Harrison - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" -#include "dixevents.h" -#include "winmultiwindowclass.h" -#include "winprefs.h" - -/* - * External global variables - */ - -extern HICON g_hIconX; -extern HICON g_hSmallIconX; -extern HWND g_hDlgDepthChange; - -/* - * Prototypes for local functions - */ - -void -winCreateWindowsWindow (WindowPtr pWin); - -static void -winDestroyWindowsWindow (WindowPtr pWin); - -static void -winUpdateWindowsWindow (WindowPtr pWin); - -static void -winFindWindow (pointer value, XID id, pointer cdata); - -static -void winInitMultiWindowClass(void) -{ - static wATOM atomXWinClass=0; - WNDCLASSEX wcx; - - if (atomXWinClass==0) - { - /* Setup our window class */ - wcx.cbSize=sizeof(WNDCLASSEX); - wcx.style = CS_HREDRAW | CS_VREDRAW; - wcx.lpfnWndProc = winTopLevelWindowProc; - wcx.cbClsExtra = 0; - wcx.cbWndExtra = 0; - wcx.hInstance = g_hInstance; - wcx.hIcon = g_hIconX; - wcx.hCursor = 0; - wcx.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH); - wcx.lpszMenuName = NULL; - wcx.lpszClassName = WINDOW_CLASS_X; - wcx.hIconSm = g_hSmallIconX; - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X); -#endif - - atomXWinClass = RegisterClassEx (&wcx); - } -} - -/* - * CreateWindow - See Porting Layer Definition - p. 37 - */ - -Bool -winCreateWindowMultiWindow (WindowPtr pWin) -{ - Bool fResult = TRUE; - ScreenPtr pScreen = pWin->drawable.pScreen; - winWindowPriv(pWin); - winScreenPriv(pScreen); - -#if CYGMULTIWINDOW_DEBUG - winTrace ("winCreateWindowMultiWindow - pWin: %p\n", pWin); -#endif - - WIN_UNWRAP(CreateWindow); - fResult = (*pScreen->CreateWindow) (pWin); - WIN_WRAP(CreateWindow, winCreateWindowMultiWindow); - - /* Initialize some privates values */ - pWinPriv->hRgn = NULL; - pWinPriv->hWnd = NULL; - pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen); - pWinPriv->fXKilled = FALSE; - - return fResult; -} - - -/* - * DestroyWindow - See Porting Layer Definition - p. 37 - */ - -Bool -winDestroyWindowMultiWindow (WindowPtr pWin) -{ - Bool fResult = TRUE; - ScreenPtr pScreen = pWin->drawable.pScreen; - winWindowPriv(pWin); - winScreenPriv(pScreen); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winDestroyWindowMultiWindow - pWin: %p\n", pWin); -#endif - - WIN_UNWRAP(DestroyWindow); - fResult = (*pScreen->DestroyWindow)(pWin); - WIN_WRAP(DestroyWindow, winDestroyWindowMultiWindow); - - /* Flag that the window has been destroyed */ - pWinPriv->fXKilled = TRUE; - - /* Kill the MS Windows window associated with this window */ - winDestroyWindowsWindow (pWin); - - return fResult; -} - - -/* - * PositionWindow - See Porting Layer Definition - p. 37 - * - * This function adjusts the position and size of Windows window - * with respect to the underlying X window. This is the inverse - * of winAdjustXWindow, which adjusts X window to Windows window. - */ - -Bool -winPositionWindowMultiWindow (WindowPtr pWin, int x, int y) -{ - Bool fResult = TRUE; - int iX, iY, iWidth, iHeight; - ScreenPtr pScreen = pWin->drawable.pScreen; - winWindowPriv(pWin); - winScreenPriv(pScreen); - - HWND hWnd = pWinPriv->hWnd; - RECT rcNew; - RECT rcOld; -#if CYGMULTIWINDOW_DEBUG - RECT rcClient; - RECT *lpRc; -#endif - DWORD dwExStyle; - DWORD dwStyle; - -#if CYGMULTIWINDOW_DEBUG - winTrace ("winPositionWindowMultiWindow - pWin: %p\n", pWin); -#endif - - WIN_UNWRAP(PositionWindow); - fResult = (*pScreen->PositionWindow)(pWin, x, y); - WIN_WRAP(PositionWindow, winPositionWindowMultiWindow); - -#if CYGWINDOWING_DEBUG - ErrorF ("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n", - x, y); -#endif - - /* Bail out if the Windows window handle is bad */ - if (!hWnd) - { -#if CYGWINDOWING_DEBUG - ErrorF ("\timmediately return since hWnd is NULL\n"); -#endif - return fResult; - } - - /* Get the Windows window style and extended style */ - dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE); - dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE); - - /* Get the X and Y location of the X window */ - iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); - iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); - - /* Get the height and width of the X window */ - iWidth = pWin->drawable.width; - iHeight = pWin->drawable.height; - - /* Store the origin, height, and width in a rectangle structure */ - SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight); - -#if CYGMULTIWINDOW_DEBUG - lpRc = &rcNew; - ErrorF ("winPositionWindowMultiWindow - (%d ms)drawable (%d, %d)-(%d, %d)\n", - GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); -#endif - - /* - * Calculate the required size of the Windows window rectangle, - * given the size of the Windows window client area. - */ - AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle); - - /* Get a rectangle describing the old Windows window */ - GetWindowRect (hWnd, &rcOld); - -#if CYGMULTIWINDOW_DEBUG - /* Get a rectangle describing the Windows window client area */ - GetClientRect (hWnd, &rcClient); - - lpRc = &rcNew; - ErrorF ("winPositionWindowMultiWindow - (%d ms)rcNew (%d, %d)-(%d, %d)\n", - GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); - - lpRc = &rcOld; - ErrorF ("winPositionWindowMultiWindow - (%d ms)rcOld (%d, %d)-(%d, %d)\n", - GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); - - lpRc = &rcClient; - ErrorF ("(%d ms)rcClient (%d, %d)-(%d, %d)\n", - GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom); -#endif - - /* Check if the old rectangle and new rectangle are the same */ - if (!EqualRect (&rcNew, &rcOld)) - { -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winPositionWindowMultiWindow - Need to move\n"); -#endif - -#if CYGWINDOWING_DEBUG - ErrorF ("\tMoveWindow to (%ld, %ld) - %ldx%ld\n", rcNew.left, rcNew.top, - rcNew.right - rcNew.left, rcNew.bottom - rcNew.top); -#endif - /* Change the position and dimensions of the Windows window */ - MoveWindow (hWnd, - rcNew.left, rcNew.top, - rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, - TRUE); - } - else - { -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winPositionWindowMultiWindow - Not need to move\n"); -#endif - } - - return fResult; -} - - -/* - * ChangeWindowAttributes - See Porting Layer Definition - p. 37 - */ - -Bool -winChangeWindowAttributesMultiWindow (WindowPtr pWin, unsigned long mask) -{ - Bool fResult = TRUE; - ScreenPtr pScreen = pWin->drawable.pScreen; - winScreenPriv(pScreen); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin); -#endif - - WIN_UNWRAP(ChangeWindowAttributes); - fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask); - WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesMultiWindow); - - /* - * NOTE: We do not currently need to do anything here. - */ - - return fResult; -} - - -/* - * UnmapWindow - See Porting Layer Definition - p. 37 - * Also referred to as UnrealizeWindow - */ - -Bool -winUnmapWindowMultiWindow (WindowPtr pWin) -{ - Bool fResult = TRUE; - ScreenPtr pScreen = pWin->drawable.pScreen; - winWindowPriv(pWin); - winScreenPriv(pScreen); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin); -#endif - - WIN_UNWRAP(UnrealizeWindow); - fResult = (*pScreen->UnrealizeWindow)(pWin); - WIN_WRAP(UnrealizeWindow, winUnmapWindowMultiWindow); - - /* Flag that the window has been killed */ - pWinPriv->fXKilled = TRUE; - - /* Destroy the Windows window associated with this X window */ - winDestroyWindowsWindow (pWin); - - return fResult; -} - - -/* - * MapWindow - See Porting Layer Definition - p. 37 - * Also referred to as RealizeWindow - */ - -Bool -winMapWindowMultiWindow (WindowPtr pWin) -{ - Bool fResult = TRUE; - ScreenPtr pScreen = pWin->drawable.pScreen; - winWindowPriv(pWin); - winScreenPriv(pScreen); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winMapWindowMultiWindow - pWin: %08x\n", pWin); -#endif - - WIN_UNWRAP(RealizeWindow); - fResult = (*pScreen->RealizeWindow)(pWin); - WIN_WRAP(RealizeWindow, winMapWindowMultiWindow); - - /* Flag that this window has not been destroyed */ - pWinPriv->fXKilled = FALSE; - - /* Refresh/redisplay the Windows window associated with this X window */ - winUpdateWindowsWindow (pWin); - - /* Update the Windows window's shape */ - winReshapeMultiWindow (pWin); - winUpdateRgnMultiWindow (pWin); - - return fResult; -} - - -/* - * ReparentWindow - See Porting Layer Definition - p. 42 - */ - -void -winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - winScreenPriv(pScreen); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winReparentMultiWindow - pWin: %08x\n", pWin); -#endif - - WIN_UNWRAP(ReparentWindow); - if (pScreen->ReparentWindow) - (*pScreen->ReparentWindow)(pWin, pPriorParent); - WIN_WRAP(ReparentWindow, winReparentWindowMultiWindow); - - /* Update the Windows window associated with this X window */ - winUpdateWindowsWindow (pWin); -} - - -/* - * RestackWindow - Shuffle the z-order of a window - */ - -void -winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib) -{ -#if 0 - WindowPtr pPrevWin; - UINT uFlags; - HWND hInsertAfter; - HWND hWnd = NULL; -#endif - ScreenPtr pScreen = pWin->drawable.pScreen; - winScreenPriv(pScreen); - -#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG - winTrace ("winRestackMultiWindow - %08x\n", pWin); -#endif - - WIN_UNWRAP(RestackWindow); - if (pScreen->RestackWindow) - (*pScreen->RestackWindow)(pWin, pOldNextSib); - WIN_WRAP(RestackWindow, winRestackWindowMultiWindow); - -#if 1 - /* - * Calling winReorderWindowsMultiWindow here means our window manager - * (i.e. Windows Explorer) has initiative to determine Z order. - */ - if (pWin->nextSib != pOldNextSib) - winReorderWindowsMultiWindow (); -#else - /* Bail out if no window privates or window handle is invalid */ - if (!pWinPriv || !pWinPriv->hWnd) - return; - - /* Get a pointer to our previous sibling window */ - pPrevWin = pWin->prevSib; - - /* - * Look for a sibling window with - * valid privates and window handle - */ - while (pPrevWin - && !winGetWindowPriv(pPrevWin) - && !winGetWindowPriv(pPrevWin)->hWnd) - pPrevWin = pPrevWin->prevSib; - - /* Check if we found a valid sibling */ - if (pPrevWin) - { - /* Valid sibling - get handle to insert window after */ - hInsertAfter = winGetWindowPriv(pPrevWin)->hWnd; - uFlags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOSIZE; - - hWnd = GetNextWindow (pWinPriv->hWnd, GW_HWNDPREV); - - do - { - if (GetProp (hWnd, WIN_WINDOW_PROP)) - { - if (hWnd == winGetWindowPriv(pPrevWin)->hWnd) - { - uFlags |= SWP_NOZORDER; - } - break; - } - hWnd = GetNextWindow (hWnd, GW_HWNDPREV); - } - while (hWnd); - } - else - { - /* No valid sibling - make this window the top window */ - hInsertAfter = HWND_TOP; - uFlags = SWP_NOMOVE | SWP_NOSIZE; - } - - /* Perform the restacking operation in Windows */ - SetWindowPos (pWinPriv->hWnd, - hInsertAfter, - 0, 0, - 0, 0, - uFlags); -#endif -} - - -/* - * winCreateWindowsWindow - Create a Windows window associated with an X window - */ - -void -winCreateWindowsWindow (WindowPtr pWin) -{ - int iX, iY; - int iWidth; - int iHeight; - HWND hWnd; - HWND hFore = NULL; - winWindowPriv(pWin); - HICON hIcon; - HICON hIconSmall; - winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv; - WinXSizeHints hints; - WindowPtr pDaddy; - - winInitMultiWindowClass(); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winCreateWindowsWindow - pWin: %08x\n", pWin); -#endif - - iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); - iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); - - iWidth = pWin->drawable.width; - iHeight = pWin->drawable.height; - - /* ensure window actually ends up somewhere visible */ - if (iX > GetSystemMetrics (SM_CXVIRTUALSCREEN)) - iX = CW_USEDEFAULT; - - if (iY > GetSystemMetrics (SM_CYVIRTUALSCREEN)) - iY = CW_USEDEFAULT; - - if (winMultiWindowGetTransientFor (pWin, &pDaddy)) - { - if (pDaddy) - { - hFore = GetForegroundWindow(); - if (hFore && (pDaddy != (WindowPtr)GetProp(hFore, WIN_WID_PROP))) hFore = NULL; - } - } - else - { - /* Default positions if none specified */ - if (!winMultiWindowGetWMNormalHints(pWin, &hints)) - hints.flags = 0; - if (!(hints.flags & (USPosition|PPosition)) && - !pWin->overrideRedirect) - { - iX = CW_USEDEFAULT; - iY = CW_USEDEFAULT; - } - } - - /* Create the window */ - /* Make it OVERLAPPED in create call since WS_POPUP doesn't support */ - /* CW_USEDEFAULT, change back to popup after creation */ - hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */ - WINDOW_CLASS_X, /* Class name */ - WINDOW_TITLE_X, /* Window name */ - WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, - iX, /* Horizontal position */ - iY, /* Vertical position */ - iWidth, /* Right edge */ - iHeight, /* Bottom edge */ - hFore, /* Null or Parent window if transient*/ - (HMENU) NULL, /* No menu */ - GetModuleHandle (NULL), /* Instance handle */ - pWin); /* ScreenPrivates */ - if (hWnd == NULL) - { - ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n", - (int) GetLastError ()); - } - pWinPriv->hWnd = hWnd; - - /* Set application or .XWinrc defined Icons */ - winSelectIcons(pWin, &hIcon, &hIconSmall); - if (hIcon) SendMessage (hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon); - if (hIconSmall) SendMessage (hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall); - - /* Change style back to popup, already placed... */ - SetWindowLongPtr(hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS); - SetWindowPos (hWnd, 0, 0, 0, 0, 0, - SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); - /* Make sure it gets the proper system menu for a WS_POPUP, too */ - GetSystemMenu (hWnd, TRUE); - - /* Cause any .XWinrc menus to be added in main WNDPROC */ - PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0); - - SetProp (hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin)); - - /* Flag that this Windows window handles its own activation */ - SetProp (hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0); - - /* Call engine-specific create window procedure */ - (*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin); -} - - -Bool winInDestroyWindowsWindow = FALSE; -/* - * winDestroyWindowsWindow - Destroy a Windows window associated - * with an X window - */ -static void -winDestroyWindowsWindow (WindowPtr pWin) -{ - MSG msg; - winWindowPriv(pWin); - BOOL oldstate = winInDestroyWindowsWindow; - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winDestroyWindowsWindow\n"); -#endif - - /* Bail out if the Windows window handle is invalid */ - if (pWinPriv->hWnd == NULL) - return; - - winInDestroyWindowsWindow = TRUE; - - SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, NULL); - /* Destroy the Windows window */ - DestroyWindow (pWinPriv->hWnd); - - /* Null our handle to the Window so referencing it will cause an error */ - pWinPriv->hWnd = NULL; - - /* Process all messages on our queue */ - while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) - { - if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg)) - { - DispatchMessage (&msg); - } - } - - winInDestroyWindowsWindow = oldstate; - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("-winDestroyWindowsWindow\n"); -#endif -} - - -/* - * winUpdateWindowsWindow - Redisplay/redraw a Windows window - * associated with an X window - */ - -static void -winUpdateWindowsWindow (WindowPtr pWin) -{ - winWindowPriv(pWin); - HWND hWnd = pWinPriv->hWnd; - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winUpdateWindowsWindow\n"); -#endif - - /* Check if the Windows window's parents have been destroyed */ - if (pWin->parent != NULL - && pWin->parent->parent == NULL - && pWin->mapped) - { - /* Create the Windows window if it has been destroyed */ - if (hWnd == NULL) - { - winCreateWindowsWindow (pWin); - assert (pWinPriv->hWnd != NULL); - } - - /* Display the window without activating it */ - ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE); - - /* Send first paint message */ - UpdateWindow (pWinPriv->hWnd); - } - else if (hWnd != NULL) - { - /* Destroy the Windows window if its parents are destroyed */ - winDestroyWindowsWindow (pWin); - assert (pWinPriv->hWnd == NULL); - } - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("-winUpdateWindowsWindow\n"); -#endif -} - - -/* - * winGetWindowID - - */ - -XID -winGetWindowID (WindowPtr pWin) -{ - WindowIDPairRec wi = {pWin, 0}; - ClientPtr c = wClient(pWin); - - /* */ - FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winGetWindowID - Window ID: %d\n", wi.id); -#endif - - return wi.id; -} - - -/* - * winFindWindow - - */ - -static void -winFindWindow (pointer value, XID id, pointer cdata) -{ - WindowIDPairPtr wi = (WindowIDPairPtr)cdata; - - if (value == wi->value) - { - wi->id = id; - } -} - - -/* - * winReorderWindowsMultiWindow - - */ - -void -winReorderWindowsMultiWindow (void) -{ - HWND hwnd = NULL; - WindowPtr pWin = NULL; - WindowPtr pWinSib = NULL; - XID vlist[2]; - static Bool fRestacking = FALSE; /* Avoid recusive calls to this function */ - DWORD dwCurrentProcessID = GetCurrentProcessId (); - DWORD dwWindowProcessID = 0; - -#if CYGMULTIWINDOW_DEBUG || CYGWINDOWING_DEBUG - winTrace ("winReorderWindowsMultiWindow\n"); -#endif - - if (fRestacking) - { - /* It is a recusive call so immediately exit */ -#if CYGWINDOWING_DEBUG - ErrorF ("winReorderWindowsMultiWindow - " - "exit because fRestacking == TRUE\n"); -#endif - return; - } - fRestacking = TRUE; - - /* Loop through top level Window windows, descending in Z order */ - for ( hwnd = GetTopWindow (NULL); - hwnd; - hwnd = GetNextWindow (hwnd, GW_HWNDNEXT) ) - { - /* Don't take care of other Cygwin/X process's windows */ - GetWindowThreadProcessId (hwnd, &dwWindowProcessID); - - if ( GetProp (hwnd, WIN_WINDOW_PROP) - && (dwWindowProcessID == dwCurrentProcessID) - && !IsIconic (hwnd) ) /* ignore minimized windows */ - { - pWinSib = pWin; - pWin = GetProp (hwnd, WIN_WINDOW_PROP); - - if (!pWinSib) - { /* 1st window - raise to the top */ - vlist[0] = Above; - - ConfigureWindow (pWin, CWStackMode, vlist, wClient(pWin)); - } - else - { /* 2nd or deeper windows - just below the previous one */ - vlist[0] = winGetWindowID (pWinSib); - vlist[1] = Below; - - ConfigureWindow (pWin, CWSibling | CWStackMode, - vlist, wClient(pWin)); - } - } - } - - fRestacking = FALSE; -} - - -/* - * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE - */ - -void -winMinimizeWindow (Window id) -{ - WindowPtr pWin; - winPrivWinPtr pWinPriv; -#ifdef XWIN_MULTIWINDOWEXTWM - win32RootlessWindowPtr pRLWinPriv; -#endif - HWND hWnd; - ScreenPtr pScreen = NULL; - winPrivScreenPtr pScreenPriv = NULL; - winScreenInfo *pScreenInfo = NULL; - -#if CYGWINDOWING_DEBUG - ErrorF ("winMinimizeWindow\n"); -#endif - - dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess); - if (!pWin) - { - ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__); - return; - } - - pScreen = pWin->drawable.pScreen; - if (pScreen) pScreenPriv = winGetScreenPriv(pScreen); - if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo; - -#ifdef XWIN_MULTIWINDOWEXTWM - if (pScreenPriv && pScreenInfo->fInternalWM) - { - pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); - hWnd = pRLWinPriv->hWnd; - } - else -#else - if (pScreenPriv) -#endif - { - pWinPriv = winGetWindowPriv (pWin); - hWnd = pWinPriv->hWnd; - } - - ShowWindow (hWnd, SW_MINIMIZE); -} - - -/* - * CopyWindow - See Porting Layer Definition - p. 39 - */ -void -winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt, - RegionPtr oldRegion) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - winScreenPriv(pScreen); - -#if CYGWINDOWING_DEBUG - ErrorF ("CopyWindowMultiWindow\n"); -#endif - WIN_UNWRAP(CopyWindow); - (*pScreen->CopyWindow)(pWin, oldpt, oldRegion); - WIN_WRAP(CopyWindow, winCopyWindowMultiWindow); -} - - -/* - * MoveWindow - See Porting Layer Definition - p. 42 - */ -void -winMoveWindowMultiWindow (WindowPtr pWin, int x, int y, - WindowPtr pSib, VTKind kind) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - winScreenPriv(pScreen); - -#if CYGWINDOWING_DEBUG - ErrorF ("MoveWindowMultiWindow to (%d, %d)\n", x, y); -#endif - - WIN_UNWRAP(MoveWindow); - (*pScreen->MoveWindow)(pWin, x, y, pSib, kind); - WIN_WRAP(MoveWindow, winMoveWindowMultiWindow); -} - - -/* - * ResizeWindow - See Porting Layer Definition - p. 42 - */ -void -winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w, - unsigned int h, WindowPtr pSib) -{ - ScreenPtr pScreen = pWin->drawable.pScreen; - winScreenPriv(pScreen); - -#if CYGWINDOWING_DEBUG - ErrorF ("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x, y, w, h); -#endif - WIN_UNWRAP(ResizeWindow); - (*pScreen->ResizeWindow)(pWin, x, y, w, h, pSib); - WIN_WRAP(ResizeWindow, winResizeWindowMultiWindow); -} - - -/* - * winAdjustXWindow - * - * Move and resize X window with respect to corresponding Windows window. - * This is called from WM_MOVE/WM_SIZE handlers when the user performs - * any windowing operation (move, resize, minimize, maximize, restore). - * - * The functionality is the inverse of winPositionWindowMultiWindow, which - * adjusts Windows window with respect to X window. - */ -int -winAdjustXWindow (WindowPtr pWin, HWND hwnd) -{ - RECT rcDraw; /* Rect made from pWin->drawable to be adjusted */ - RECT rcWin; /* The source: WindowRect from hwnd */ - DrawablePtr pDraw; - XID vlist[4]; - LONG dX, dY, dW, dH, x, y; - DWORD dwStyle, dwExStyle; - -#define WIDTH(rc) (rc.right - rc.left) -#define HEIGHT(rc) (rc.bottom - rc.top) - -#if CYGWINDOWING_DEBUG - ErrorF ("winAdjustXWindow\n"); -#endif - - if (IsIconic (hwnd)) - { -#if CYGWINDOWING_DEBUG - ErrorF ("\timmediately return because the window is iconized\n"); -#endif - /* - * If the Windows window is minimized, its WindowRect has - * meaningless values so we don't adjust X window to it. - */ - vlist[0] = 0; - vlist[1] = 0; - return ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin)); - } - - pDraw = &pWin->drawable; - - /* Calculate the window rect from the drawable */ - x = pDraw->x + GetSystemMetrics (SM_XVIRTUALSCREEN); - y = pDraw->y + GetSystemMetrics (SM_YVIRTUALSCREEN); - SetRect (&rcDraw, x, y, x + pDraw->width, y + pDraw->height); -#ifdef CYGMULTIWINDOW_DEBUG - winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n", - rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom, - rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top); -#endif - dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE); - dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE); -#ifdef CYGMULTIWINDOW_DEBUG - winDebug("\tWindowStyle: %08x %08x\n", dwStyle, dwExStyle); -#endif - AdjustWindowRectEx (&rcDraw, dwStyle, FALSE, dwExStyle); - - /* The source of adjust */ - GetWindowRect (hwnd, &rcWin); -#ifdef CYGMULTIWINDOW_DEBUG - winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n", - rcWin.left, rcWin.top, rcWin.right, rcWin.bottom, - rcWin.right - rcWin.left, rcWin.bottom - rcWin.top); - winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n", - rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom, - rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top); -#endif - - if (EqualRect (&rcDraw, &rcWin)) { - /* Bail if no adjust is needed */ -#if CYGWINDOWING_DEBUG - ErrorF ("\treturn because already adjusted\n"); -#endif - return 0; - } - - /* Calculate delta values */ - dX = rcWin.left - rcDraw.left; - dY = rcWin.top - rcDraw.top; - dW = WIDTH(rcWin) - WIDTH(rcDraw); - dH = HEIGHT(rcWin) - HEIGHT(rcDraw); - - /* - * Adjust. - * We may only need to move (vlist[0] and [1]), or only resize - * ([2] and [3]) but currently we set all the parameters and leave - * the decision to ConfigureWindow. The reason is code simplicity. - */ - vlist[0] = pDraw->x + dX - wBorderWidth(pWin); - vlist[1] = pDraw->y + dY - wBorderWidth(pWin); - vlist[2] = pDraw->width + dW; - vlist[3] = pDraw->height + dH; -#if CYGWINDOWING_DEBUG - ErrorF ("\tConfigureWindow to (%ld, %ld) - %ldx%ld\n", vlist[0], vlist[1], - vlist[2], vlist[3]); -#endif - return ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight, - vlist, wClient(pWin)); - -#undef WIDTH -#undef HEIGHT -} - +/*
+ *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
+ *Copyright (C) Colin Harrison 2005-2008
+ *
+ *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: Kensuke Matsuzaki
+ * Earle F. Philhower, III
+ * Harold L Hunt II
+ * Colin Harrison
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include "dixevents.h"
+#include "winmultiwindowclass.h"
+#include "winprefs.h"
+
+/*
+ * External global variables
+ */
+
+extern HICON g_hIconX;
+extern HICON g_hSmallIconX;
+extern HWND g_hDlgDepthChange;
+
+/*
+ * Prototypes for local functions
+ */
+
+void
+winCreateWindowsWindow (WindowPtr pWin);
+
+static void
+winDestroyWindowsWindow (WindowPtr pWin);
+
+static void
+winUpdateWindowsWindow (WindowPtr pWin);
+
+static void
+winFindWindow (pointer value, XID id, pointer cdata);
+
+static
+void winInitMultiWindowClass(void)
+{
+ static wATOM atomXWinClass=0;
+ WNDCLASSEX wcx;
+
+ if (atomXWinClass==0)
+ {
+ /* Setup our window class */
+ wcx.cbSize=sizeof(WNDCLASSEX);
+ wcx.style = CS_HREDRAW | CS_VREDRAW;
+ wcx.lpfnWndProc = winTopLevelWindowProc;
+ wcx.cbClsExtra = 0;
+ wcx.cbWndExtra = 0;
+ wcx.hInstance = g_hInstance;
+ wcx.hIcon = g_hIconX;
+ wcx.hCursor = 0;
+ wcx.hbrBackground = (HBRUSH) GetStockObject (WHITE_BRUSH);
+ wcx.lpszMenuName = NULL;
+ wcx.lpszClassName = WINDOW_CLASS_X;
+ wcx.hIconSm = g_hSmallIconX;
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winCreateWindowsWindow - Creating class: %s\n", WINDOW_CLASS_X);
+#endif
+
+ atomXWinClass = RegisterClassEx (&wcx);
+ }
+}
+
+/*
+ * CreateWindow - See Porting Layer Definition - p. 37
+ */
+
+Bool
+winCreateWindowMultiWindow (WindowPtr pWin)
+{
+ Bool fResult = TRUE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winWindowPriv(pWin);
+ winScreenPriv(pScreen);
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winCreateWindowMultiWindow - pWin: %p\n", pWin);
+#endif
+
+ WIN_UNWRAP(CreateWindow);
+ fResult = (*pScreen->CreateWindow) (pWin);
+ WIN_WRAP(CreateWindow, winCreateWindowMultiWindow);
+
+ /* Initialize some privates values */
+ pWinPriv->hRgn = NULL;
+ pWinPriv->hWnd = NULL;
+ pWinPriv->GlCtxWnd = FALSE;
+ pWinPriv->pScreenPriv = winGetScreenPriv(pWin->drawable.pScreen);
+ pWinPriv->fXKilled = FALSE;
+
+ return fResult;
+}
+
+
+/*
+ * DestroyWindow - See Porting Layer Definition - p. 37
+ */
+
+Bool
+winDestroyWindowMultiWindow (WindowPtr pWin)
+{
+ Bool fResult = TRUE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winWindowPriv(pWin);
+ winScreenPriv(pScreen);
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winDestroyWindowMultiWindow - pWin: %p\n", pWin);
+#endif
+
+ WIN_UNWRAP(DestroyWindow);
+ fResult = (*pScreen->DestroyWindow)(pWin);
+ WIN_WRAP(DestroyWindow, winDestroyWindowMultiWindow);
+
+ /* Flag that the window has been destroyed */
+ pWinPriv->fXKilled = TRUE;
+
+ /* Kill the MS Windows window associated with this window */
+ winDestroyWindowsWindow (pWin);
+
+ return fResult;
+}
+
+
+/*
+ * PositionWindow - See Porting Layer Definition - p. 37
+ *
+ * This function adjusts the position and size of Windows window
+ * with respect to the underlying X window. This is the inverse
+ * of winAdjustXWindow, which adjusts X window to Windows window.
+ */
+
+Bool
+winPositionWindowMultiWindow (WindowPtr pWin, int x, int y)
+{
+ Bool fResult = TRUE;
+ int iX, iY, iWidth, iHeight;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winWindowPriv(pWin);
+ winScreenPriv(pScreen);
+
+ HWND hWnd = pWinPriv->hWnd;
+ RECT rcNew;
+ RECT rcOld;
+#ifdef WINDBG
+ RECT rcClient;
+ RECT *lpRc;
+#endif
+ DWORD dwExStyle;
+ DWORD dwStyle;
+
+ winDebug ("winPositionWindowMultiWindow - pWin: %p\n", pWin);
+
+ WIN_UNWRAP(PositionWindow);
+ fResult = (*pScreen->PositionWindow)(pWin, x, y);
+ WIN_WRAP(PositionWindow, winPositionWindowMultiWindow);
+
+ winDebug ("winPositionWindowMultiWindow: (x, y) = (%d, %d)\n",
+ x, y);
+
+ /* Bail out if the Windows window handle is bad */
+ if (!hWnd)
+ {
+ winDebug ("\timmediately return since hWnd is NULL\n");
+ return fResult;
+ }
+
+ /* Get the Windows window style and extended style */
+ dwExStyle = GetWindowLongPtr (hWnd, GWL_EXSTYLE);
+ dwStyle = GetWindowLongPtr (hWnd, GWL_STYLE);
+
+ /* Get the X and Y location of the X window */
+ iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
+ iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
+
+ /* Get the height and width of the X window */
+ iWidth = pWin->drawable.width;
+ iHeight = pWin->drawable.height;
+
+ /* Store the origin, height, and width in a rectangle structure */
+ SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight);
+
+#if CYGMULTIWINDOW_DEBUG
+ lpRc = &rcNew;
+ winDebug ("winPositionWindowMultiWindow - (%d ms)drawable (%d, %d)-(%d, %d)\n",
+ GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
+#endif
+
+ /*
+ * Calculate the required size of the Windows window rectangle,
+ * given the size of the Windows window client area.
+ */
+ AdjustWindowRectEx (&rcNew, dwStyle, FALSE, dwExStyle);
+
+ /* Get a rectangle describing the old Windows window */
+ GetWindowRect (hWnd, &rcOld);
+
+#if CYGMULTIWINDOW_DEBUG
+ /* Get a rectangle describing the Windows window client area */
+ GetClientRect (hWnd, &rcClient);
+
+ lpRc = &rcNew;
+ winDebug ("winPositionWindowMultiWindow - (%d ms)rcNew (%d, %d)-(%d, %d)\n",
+ GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
+
+ lpRc = &rcOld;
+ winDebug ("winPositionWindowMultiWindow - (%d ms)rcOld (%d, %d)-(%d, %d)\n",
+ GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
+
+ lpRc = &rcClient;
+ winDebug ("(%d ms)rcClient (%d, %d)-(%d, %d)\n",
+ GetTickCount (), lpRc->left, lpRc->top, lpRc->right, lpRc->bottom);
+#endif
+
+ /* Check if the old rectangle and new rectangle are the same */
+ if (!EqualRect (&rcNew, &rcOld))
+ {
+ winDebug ("winPositionWindowMultiWindow - Need to move\n");
+ winDebug ("\tMoveWindow to (%ld, %ld) - %ldx%ld\n", rcNew.left, rcNew.top,
+ rcNew.right - rcNew.left, rcNew.bottom - rcNew.top);
+
+ /* Change the position and dimensions of the Windows window */
+ MoveWindow (hWnd,
+ rcNew.left, rcNew.top,
+ rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
+ TRUE);
+ }
+ else
+ {
+ winDebug ("winPositionWindowMultiWindow - Not need to move\n");
+ }
+
+ return fResult;
+}
+
+
+/*
+ * ChangeWindowAttributes - See Porting Layer Definition - p. 37
+ */
+
+Bool
+winChangeWindowAttributesMultiWindow (WindowPtr pWin, unsigned long mask)
+{
+ Bool fResult = TRUE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winScreenPriv(pScreen);
+
+ winDebug ("winChangeWindowAttributesMultiWindow - pWin: %08x\n", pWin);
+
+ WIN_UNWRAP(ChangeWindowAttributes);
+ fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask);
+ WIN_WRAP(ChangeWindowAttributes, winChangeWindowAttributesMultiWindow);
+
+ /*
+ * NOTE: We do not currently need to do anything here.
+ */
+
+ return fResult;
+}
+
+
+/*
+ * UnmapWindow - See Porting Layer Definition - p. 37
+ * Also referred to as UnrealizeWindow
+ */
+
+Bool
+winUnmapWindowMultiWindow (WindowPtr pWin)
+{
+ Bool fResult = TRUE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winWindowPriv(pWin);
+ winScreenPriv(pScreen);
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winUnmapWindowMultiWindow - pWin: %08x\n", pWin);
+#endif
+
+ WIN_UNWRAP(UnrealizeWindow);
+ fResult = (*pScreen->UnrealizeWindow)(pWin);
+ WIN_WRAP(UnrealizeWindow, winUnmapWindowMultiWindow);
+
+ /* Flag that the window has been killed */
+ pWinPriv->fXKilled = TRUE;
+
+ /* Destroy the Windows window associated with this X window */
+ winDestroyWindowsWindow (pWin);
+
+ return fResult;
+}
+
+
+/*
+ * MapWindow - See Porting Layer Definition - p. 37
+ * Also referred to as RealizeWindow
+ */
+
+Bool
+winMapWindowMultiWindow (WindowPtr pWin)
+{
+ Bool fResult = TRUE;
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winWindowPriv(pWin);
+ winScreenPriv(pScreen);
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winMapWindowMultiWindow - pWin: %08x\n", pWin);
+#endif
+
+ WIN_UNWRAP(RealizeWindow);
+ fResult = (*pScreen->RealizeWindow)(pWin);
+ WIN_WRAP(RealizeWindow, winMapWindowMultiWindow);
+
+ /* Flag that this window has not been destroyed */
+ pWinPriv->fXKilled = FALSE;
+
+ /* Refresh/redisplay the Windows window associated with this X window */
+ winUpdateWindowsWindow (pWin);
+
+ /* Update the Windows window's shape */
+ winReshapeMultiWindow (pWin);
+ winUpdateRgnMultiWindow (pWin);
+
+ return fResult;
+}
+
+
+/*
+ * ReparentWindow - See Porting Layer Definition - p. 42
+ */
+
+void
+winReparentWindowMultiWindow (WindowPtr pWin, WindowPtr pPriorParent)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winScreenPriv(pScreen);
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winReparentMultiWindow - pWin: %08x\n", pWin);
+#endif
+
+ WIN_UNWRAP(ReparentWindow);
+ if (pScreen->ReparentWindow)
+ (*pScreen->ReparentWindow)(pWin, pPriorParent);
+ WIN_WRAP(ReparentWindow, winReparentWindowMultiWindow);
+
+ /* Update the Windows window associated with this X window */
+ winUpdateWindowsWindow (pWin);
+}
+
+
+/*
+ * RestackWindow - Shuffle the z-order of a window
+ */
+
+void
+winRestackWindowMultiWindow (WindowPtr pWin, WindowPtr pOldNextSib)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winScreenPriv(pScreen);
+
+ winDebug ("winRestackMultiWindow - %08x\n", pWin);
+
+ WIN_UNWRAP(RestackWindow);
+ if (pScreen->RestackWindow)
+ (*pScreen->RestackWindow)(pWin, pOldNextSib);
+ WIN_WRAP(RestackWindow, winRestackWindowMultiWindow);
+
+ /*
+ * Calling winReorderWindowsMultiWindow here means our window manager
+ * (i.e. Windows Explorer) has initiative to determine Z order.
+ */
+ if (pWin->nextSib != pOldNextSib)
+ winReorderWindowsMultiWindow ();
+}
+
+
+static void ClientResize(HWND hWnd, int nWidth, int nHeight)
+{
+ RECT rcClient, rcWindow;
+ POINT ptDiff;
+
+ GetClientRect(hWnd, &rcClient);
+ GetWindowRect(hWnd, &rcWindow);
+ ptDiff.x = (rcWindow.right - rcWindow.left) - rcClient.right;
+ ptDiff.y = (rcWindow.bottom - rcWindow.top) - rcClient.bottom;
+ MoveWindow(hWnd,rcWindow.left, rcWindow.top, nWidth + ptDiff.x, nHeight + ptDiff.y, TRUE);
+}
+
+
+/*
+ * winCreateWindowsWindow - Create a Windows window associated with an X window
+ */
+
+void
+winCreateWindowsWindow (WindowPtr pWin)
+{
+ int iX, iY;
+ int iWidth;
+ int iHeight;
+ HWND hWnd;
+ HWND hFore = NULL;
+ winWindowPriv(pWin);
+ HICON hIcon;
+ HICON hIconSmall;
+ winPrivScreenPtr pScreenPriv = pWinPriv->pScreenPriv;
+ WinXSizeHints hints;
+ WindowPtr pDaddy;
+
+ winInitMultiWindowClass();
+
+ winDebug ("winCreateWindowsWindow - pWin: %08x\n", pWin);
+
+ iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
+ iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
+
+ iWidth = pWin->drawable.width;
+ iHeight = pWin->drawable.height;
+
+ /* ensure window actually ends up somewhere visible */
+ if (iX > GetSystemMetrics (SM_CXVIRTUALSCREEN))
+ iX = CW_USEDEFAULT;
+
+ if (iY > GetSystemMetrics (SM_CYVIRTUALSCREEN))
+ iY = CW_USEDEFAULT;
+
+ if (winMultiWindowGetTransientFor (pWin, &pDaddy))
+ {
+ if (pDaddy)
+ {
+ hFore = GetForegroundWindow();
+ if (hFore && (pDaddy != (WindowPtr)GetProp(hFore, WIN_WID_PROP))) hFore = NULL;
+ }
+ }
+ else
+ {
+ /* Default positions if none specified */
+ if (!winMultiWindowGetWMNormalHints(pWin, &hints))
+ hints.flags = 0;
+ if (!(hints.flags & (USPosition|PPosition)) &&
+ !pWin->overrideRedirect)
+ {
+ iX = CW_USEDEFAULT;
+ iY = CW_USEDEFAULT;
+ }
+ }
+
+ /* Create the window */
+ /* Make it OVERLAPPED in create call since WS_POPUP doesn't support */
+ /* CW_USEDEFAULT, change back to popup after creation */
+ hWnd = CreateWindowExA (WS_EX_TOOLWINDOW, /* Extended styles */
+ WINDOW_CLASS_X, /* Class name */
+ WINDOW_TITLE_X, /* Window name */
+ WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,
+ iX, /* Horizontal position */
+ iY, /* Vertical position */
+ iWidth, /* Right edge */
+ iHeight, /* Bottom edge */
+ hFore, /* Null or Parent window if transient*/
+ (HMENU) NULL, /* No menu */
+ GetModuleHandle (NULL), /* Instance handle */
+ pWin); /* ScreenPrivates */
+ if (hWnd == NULL)
+ {
+ ErrorF ("winCreateWindowsWindow - CreateWindowExA () failed: %d\n",
+ (int) GetLastError ());
+ }
+ pWinPriv->hWnd = hWnd;
+
+ /* Set application or .XWinrc defined Icons */
+ winSelectIcons(pWin, &hIcon, &hIconSmall);
+ if (hIcon) SendMessage (hWnd, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
+ if (hIconSmall) SendMessage (hWnd, WM_SETICON, ICON_SMALL, (LPARAM) hIconSmall);
+
+ /* If we asked the native WM to place the window, synchronize the X window position */
+ if ((iX == CW_USEDEFAULT) || (iY == CW_USEDEFAULT))
+ winAdjustXWindow(pWin, hWnd);
+
+ /* Change style back to popup, already placed... */
+ SetWindowLongPtr(hWnd, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
+ SetWindowPos (hWnd, 0, 0, 0, 0, 0,
+ SWP_FRAMECHANGED | SWP_NOZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
+ /* Make sure it gets the proper system menu for a WS_POPUP, too */
+ GetSystemMenu (hWnd, TRUE);
+
+ ClientResize(hWnd,iWidth,iHeight);
+
+ /* Cause any .XWinrc menus to be added in main WNDPROC */
+ PostMessage (hWnd, WM_INIT_SYS_MENU, 0, 0);
+
+ SetProp (hWnd, WIN_WID_PROP, (HANDLE) winGetWindowID(pWin));
+
+ /* Flag that this Windows window handles its own activation */
+ SetProp (hWnd, WIN_NEEDMANAGE_PROP, (HANDLE) 0);
+
+ /* Call engine-specific create window procedure */
+ (*pScreenPriv->pwinFinishCreateWindowsWindow) (pWin);
+}
+
+
+Bool winInDestroyWindowsWindow = FALSE;
+/*
+ * winDestroyWindowsWindow - Destroy a Windows window associated
+ * with an X window
+ */
+static void
+winDestroyWindowsWindow (WindowPtr pWin)
+{
+ MSG msg;
+ winWindowPriv(pWin);
+ BOOL oldstate = winInDestroyWindowsWindow;
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winDestroyWindowsWindow\n");
+#endif
+
+ /* Bail out if the Windows window handle is invalid */
+ if (pWinPriv->hWnd == NULL)
+ return;
+
+ winInDestroyWindowsWindow = TRUE;
+
+ SetProp (pWinPriv->hWnd, WIN_WINDOW_PROP, NULL);
+ /* Destroy the Windows window */
+ DestroyWindow (pWinPriv->hWnd);
+
+ /* Null our handle to the Window so referencing it will cause an error */
+ pWinPriv->hWnd = NULL;
+
+ /* Process all messages on our queue */
+ while (PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ if (g_hDlgDepthChange == 0 || !IsDialogMessage (g_hDlgDepthChange, &msg))
+ {
+ DispatchMessage (&msg);
+ }
+ }
+
+ winInDestroyWindowsWindow = oldstate;
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("-winDestroyWindowsWindow\n");
+#endif
+}
+
+
+/*
+ * winUpdateWindowsWindow - Redisplay/redraw a Windows window
+ * associated with an X window
+ */
+
+static void
+winUpdateWindowsWindow (WindowPtr pWin)
+{
+ winWindowPriv(pWin);
+ HWND hWnd = pWinPriv->hWnd;
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winUpdateWindowsWindow\n");
+#endif
+
+ /* Check if the Windows window's parents have been destroyed */
+ if (pWin->parent != NULL
+ && pWin->parent->parent == NULL
+ && pWin->mapped)
+ {
+ /* Create the Windows window if it has been destroyed */
+ if (hWnd == NULL)
+ {
+ winCreateWindowsWindow (pWin);
+ assert (pWinPriv->hWnd != NULL);
+ }
+
+ /* Display the window without activating it */
+ ShowWindow (pWinPriv->hWnd, SW_SHOWNOACTIVATE);
+
+ /* Send first paint message */
+ UpdateWindow (pWinPriv->hWnd);
+ }
+ else if (hWnd != NULL)
+ {
+ /* Destroy the Windows window if its parents are destroyed */
+ winDestroyWindowsWindow (pWin);
+ assert (pWinPriv->hWnd == NULL);
+ }
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("-winUpdateWindowsWindow\n");
+#endif
+}
+
+
+/*
+ * winGetWindowID -
+ */
+
+XID
+winGetWindowID (WindowPtr pWin)
+{
+ WindowIDPairRec wi = {pWin, 0};
+ ClientPtr c = wClient(pWin);
+
+ /* */
+ FindClientResourcesByType (c, RT_WINDOW, winFindWindow, &wi);
+
+#if CYGMULTIWINDOW_DEBUG
+ winDebug ("winGetWindowID - Window ID: %d\n", wi.id);
+#endif
+
+ return wi.id;
+}
+
+
+/*
+ * winFindWindow -
+ */
+
+static void
+winFindWindow (pointer value, XID id, pointer cdata)
+{
+ WindowIDPairPtr wi = (WindowIDPairPtr)cdata;
+
+ if (value == wi->value)
+ {
+ wi->id = id;
+ }
+}
+
+
+/*
+ * winReorderWindowsMultiWindow -
+ */
+
+void
+winReorderWindowsMultiWindow (void)
+{
+ HWND hwnd = NULL;
+ WindowPtr pWin = NULL;
+ WindowPtr pWinSib = NULL;
+ XID vlist[2];
+ static Bool fRestacking = FALSE; /* Avoid recusive calls to this function */
+ DWORD dwCurrentProcessID = GetCurrentProcessId ();
+ DWORD dwWindowProcessID = 0;
+
+ winDebug ("winReorderWindowsMultiWindow\n");
+
+ if (fRestacking)
+ {
+ /* It is a recusive call so immediately exit */
+ winDebug ("winReorderWindowsMultiWindow - "
+ "exit because fRestacking == TRUE\n");
+ return;
+ }
+ fRestacking = TRUE;
+
+ /* Loop through top level Window windows, descending in Z order */
+ for ( hwnd = GetTopWindow (NULL);
+ hwnd;
+ hwnd = GetNextWindow (hwnd, GW_HWNDNEXT) )
+ {
+ /* Don't take care of other Cygwin/X process's windows */
+ GetWindowThreadProcessId (hwnd, &dwWindowProcessID);
+
+ if ( GetProp (hwnd, WIN_WINDOW_PROP)
+ && (dwWindowProcessID == dwCurrentProcessID)
+ && !IsIconic (hwnd) ) /* ignore minimized windows */
+ {
+ pWinSib = pWin;
+ pWin = GetProp (hwnd, WIN_WINDOW_PROP);
+
+ if (!pWinSib)
+ { /* 1st window - raise to the top */
+ vlist[0] = Above;
+
+ ConfigureWindow (pWin, CWStackMode, vlist, wClient(pWin));
+ }
+ else
+ { /* 2nd or deeper windows - just below the previous one */
+ vlist[0] = winGetWindowID (pWinSib);
+ vlist[1] = Below;
+
+ ConfigureWindow (pWin, CWSibling | CWStackMode,
+ vlist, wClient(pWin));
+ }
+ }
+ }
+
+ fRestacking = FALSE;
+}
+
+
+/*
+ * winMinimizeWindow - Minimize in response to WM_CHANGE_STATE
+ */
+
+void
+winMinimizeWindow (Window id)
+{
+ WindowPtr pWin;
+ winPrivWinPtr pWinPriv;
+#ifdef XWIN_MULTIWINDOWEXTWM
+ win32RootlessWindowPtr pRLWinPriv;
+#endif
+ HWND hWnd;
+ ScreenPtr pScreen = NULL;
+ winPrivScreenPtr pScreenPriv = NULL;
+ winScreenInfo *pScreenInfo = NULL;
+
+ winDebug ("winMinimizeWindow\n");
+
+ dixLookupResourceByType((pointer) &pWin, id, RT_WINDOW, NullClient, DixUnknownAccess);
+ if (!pWin)
+ {
+ ErrorF("%s: NULL pWin. Leaving\n", __FUNCTION__);
+ return;
+ }
+
+ pScreen = pWin->drawable.pScreen;
+ if (pScreen) pScreenPriv = winGetScreenPriv(pScreen);
+ if (pScreenPriv) pScreenInfo = pScreenPriv->pScreenInfo;
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+ if (pScreenPriv && pScreenInfo->fInternalWM)
+ {
+ pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
+ hWnd = pRLWinPriv->hWnd;
+ }
+ else
+#else
+ if (pScreenPriv)
+#endif
+ {
+ pWinPriv = winGetWindowPriv (pWin);
+ hWnd = pWinPriv->hWnd;
+ }
+
+ ShowWindow (hWnd, SW_MINIMIZE);
+}
+
+
+/*
+ * CopyWindow - See Porting Layer Definition - p. 39
+ */
+void
+winCopyWindowMultiWindow (WindowPtr pWin, DDXPointRec oldpt,
+ RegionPtr oldRegion)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winScreenPriv(pScreen);
+
+ winDebug ("CopyWindowMultiWindow\n");
+
+ WIN_UNWRAP(CopyWindow);
+ (*pScreen->CopyWindow)(pWin, oldpt, oldRegion);
+ WIN_WRAP(CopyWindow, winCopyWindowMultiWindow);
+}
+
+
+/*
+ * MoveWindow - See Porting Layer Definition - p. 42
+ */
+void
+winMoveWindowMultiWindow (WindowPtr pWin, int x, int y,
+ WindowPtr pSib, VTKind kind)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winScreenPriv(pScreen);
+
+ winDebug ("MoveWindowMultiWindow to (%d, %d)\n", x, y);
+
+ WIN_UNWRAP(MoveWindow);
+ (*pScreen->MoveWindow)(pWin, x, y, pSib, kind);
+ WIN_WRAP(MoveWindow, winMoveWindowMultiWindow);
+}
+
+
+/*
+ * ResizeWindow - See Porting Layer Definition - p. 42
+ */
+void
+winResizeWindowMultiWindow (WindowPtr pWin, int x, int y, unsigned int w,
+ unsigned int h, WindowPtr pSib)
+{
+ ScreenPtr pScreen = pWin->drawable.pScreen;
+ winScreenPriv(pScreen);
+
+ winDebug ("ResizeWindowMultiWindow to (%d, %d) - %dx%d\n", x, y, w, h);
+
+ WIN_UNWRAP(ResizeWindow);
+ (*pScreen->ResizeWindow)(pWin, x, y, w, h, pSib);
+ WIN_WRAP(ResizeWindow, winResizeWindowMultiWindow);
+}
+
+
+/*
+ * winAdjustXWindow
+ *
+ * Move and resize X window with respect to corresponding Windows window.
+ * This is called from WM_MOVE/WM_SIZE handlers when the user performs
+ * any windowing operation (move, resize, minimize, maximize, restore).
+ *
+ * The functionality is the inverse of winPositionWindowMultiWindow, which
+ * adjusts Windows window with respect to X window.
+ */
+int
+winAdjustXWindow (WindowPtr pWin, HWND hwnd)
+{
+ RECT rcDraw; /* Rect made from pWin->drawable to be adjusted */
+ RECT rcWin; /* The source: WindowRect from hwnd */
+ DrawablePtr pDraw;
+ XID vlist[4];
+ LONG dX, dY, dW, dH, x, y;
+ DWORD dwStyle, dwExStyle;
+
+#define WIDTH(rc) (rc.right - rc.left)
+#define HEIGHT(rc) (rc.bottom - rc.top)
+
+ winDebug ("winAdjustXWindow\n");
+
+ if (IsIconic (hwnd))
+ {
+ winDebug ("\timmediately return because the window is iconized\n");
+ /*
+ * If the Windows window is minimized, its WindowRect has
+ * meaningless values so we don't adjust X window to it.
+ */
+ vlist[0] = 0;
+ vlist[1] = 0;
+ return ConfigureWindow (pWin, CWX | CWY, vlist, wClient(pWin));
+ }
+
+ pDraw = &pWin->drawable;
+
+ /* Calculate the window rect from the drawable */
+ x = pDraw->x + GetSystemMetrics (SM_XVIRTUALSCREEN);
+ y = pDraw->y + GetSystemMetrics (SM_YVIRTUALSCREEN);
+ SetRect (&rcDraw, x, y, x + pDraw->width, y + pDraw->height);
+ winDebug("\tDrawable extend {%d, %d, %d, %d}, {%d, %d}\n",
+ rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom,
+ rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top);
+ dwExStyle = GetWindowLongPtr (hwnd, GWL_EXSTYLE);
+ dwStyle = GetWindowLongPtr (hwnd, GWL_STYLE);
+ winDebug("\tWindowStyle: %08x %08x\n", dwStyle, dwExStyle);
+ AdjustWindowRectEx (&rcDraw, dwStyle, FALSE, dwExStyle);
+
+ /* The source of adjust */
+ GetWindowRect (hwnd, &rcWin);
+ winDebug("\tWindow extend {%d, %d, %d, %d}, {%d, %d}\n",
+ rcWin.left, rcWin.top, rcWin.right, rcWin.bottom,
+ rcWin.right - rcWin.left, rcWin.bottom - rcWin.top);
+ winDebug("\tDraw extend {%d, %d, %d, %d}, {%d, %d}\n",
+ rcDraw.left, rcDraw.top, rcDraw.right, rcDraw.bottom,
+ rcDraw.right - rcDraw.left, rcDraw.bottom - rcDraw.top);
+
+ if (EqualRect (&rcDraw, &rcWin)) {
+ /* Bail if no adjust is needed */
+ winDebug ("\treturn because already adjusted\n");
+ return 0;
+ }
+
+ /* Calculate delta values */
+ dX = rcWin.left - rcDraw.left;
+ dY = rcWin.top - rcDraw.top;
+ dW = WIDTH(rcWin) - WIDTH(rcDraw);
+ dH = HEIGHT(rcWin) - HEIGHT(rcDraw);
+
+ /*
+ * Adjust.
+ * We may only need to move (vlist[0] and [1]), or only resize
+ * ([2] and [3]) but currently we set all the parameters and leave
+ * the decision to ConfigureWindow. The reason is code simplicity.
+ */
+ vlist[0] = pDraw->x + dX - wBorderWidth(pWin);
+ vlist[1] = pDraw->y + dY - wBorderWidth(pWin);
+ vlist[2] = pDraw->width + dW;
+ vlist[3] = pDraw->height + dH;
+ winDebug ("\tConfigureWindow to (%ld, %ld) - %ldx%ld\n", vlist[0], vlist[1],
+ vlist[2], vlist[3]);
+ return ConfigureWindow (pWin, CWX | CWY | CWWidth | CWHeight,
+ vlist, wClient(pWin));
+
+#undef WIDTH
+#undef HEIGHT
+}
+
diff --git a/xorg-server/hw/xwin/winmultiwindowwm.c b/xorg-server/hw/xwin/winmultiwindowwm.c index 21d913e5e..c3742b755 100644 --- a/xorg-server/hw/xwin/winmultiwindowwm.c +++ b/xorg-server/hw/xwin/winmultiwindowwm.c @@ -1,1745 +1,1653 @@ -/* - *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. - *Copyright (C) Colin Harrison 2005-2009 - * - *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: Kensuke Matsuzaki - * Colin Harrison - */ - -/* X headers */ -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <unistd.h> -#ifdef __CYGWIN__ -#include <sys/select.h> -#endif -#include <fcntl.h> -#include <setjmp.h> -#define HANDLE void * -#include <pthread.h> -#undef HANDLE -#include <X11/X.h> -#include <X11/Xatom.h> -#include <X11/Xlib.h> -#include <X11/Xlocale.h> -#include <X11/Xproto.h> -#include <X11/Xutil.h> -#include <X11/cursorfont.h> -#include <X11/Xwindows.h> - -/* Local headers */ -#include "objbase.h" -#include "ddraw.h" -#include "winwindow.h" -#include "winprefs.h" -#include "window.h" -#include "pixmapstr.h" -#include "windowstr.h" - -#ifdef XWIN_MULTIWINDOWEXTWM -#include <X11/extensions/windowswmstr.h> -#else -/* We need the native HWND atom for intWM, so for consistency use the - same name as extWM would if we were building with enabled... */ -#define WINDOWSWM_NATIVE_HWND "_WINDOWSWM_NATIVE_HWND" -#endif - -extern void winDebug(const char *format, ...); -extern void winReshapeMultiWindow(WindowPtr pWin); -extern void winUpdateRgnMultiWindow(WindowPtr pWin); - -#ifndef CYGDEBUG -#define CYGDEBUG NO -#endif - -/* - * Constant defines - */ - -#define WIN_CONNECT_RETRIES 5 -#define WIN_CONNECT_DELAY 5 -#ifdef HAS_DEVWINDOWS -# define WIN_MSG_QUEUE_FNAME "/dev/windows" -#endif -#define WIN_JMP_OKAY 0 -#define WIN_JMP_ERROR_IO 2 - -/* - * Local structures - */ - -typedef struct _WMMsgNodeRec { - winWMMessageRec msg; - struct _WMMsgNodeRec *pNext; -} WMMsgNodeRec, *WMMsgNodePtr; - -typedef struct _WMMsgQueueRec { - struct _WMMsgNodeRec *pHead; - struct _WMMsgNodeRec *pTail; - pthread_mutex_t pmMutex; - pthread_cond_t pcNotEmpty; - int nQueueSize; -} WMMsgQueueRec, *WMMsgQueuePtr; - -typedef struct _WMInfo { - Display *pDisplay; - WMMsgQueueRec wmMsgQueue; - Atom atmWmProtos; - Atom atmWmDelete; - Atom atmPrivMap; - Bool fAllowOtherWM; -} WMInfoRec, *WMInfoPtr; - -typedef struct _WMProcArgRec { - DWORD dwScreen; - WMInfoPtr pWMInfo; - pthread_mutex_t *ppmServerStarted; -} WMProcArgRec, *WMProcArgPtr; - -typedef struct _XMsgProcArgRec { - Display *pDisplay; - DWORD dwScreen; - WMInfoPtr pWMInfo; - pthread_mutex_t *ppmServerStarted; - HWND hwndScreen; -} XMsgProcArgRec, *XMsgProcArgPtr; - - -/* - * References to external symbols - */ - -extern char *display; -extern void ErrorF (const char* /*f*/, ...); - -/* - * Prototypes for local functions - */ - -static void -PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode); - -static WMMsgNodePtr -PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo); - -static Bool -InitQueue (WMMsgQueuePtr pQueue); - -static void -GetWindowName (Display * pDpy, Window iWin, wchar_t **ppName); - -static int -SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData); - -static void -UpdateName (WMInfoPtr pWMInfo, Window iWindow); - -static void* -winMultiWindowWMProc (void* pArg); - -static int -winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr); - -static int -winMultiWindowWMIOErrorHandler (Display *pDisplay); - -static void * -winMultiWindowXMsgProc (void *pArg); - -static int -winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr); - -static int -winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay); - -static int -winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr); - -static void -winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg); - -#if 0 -static void -PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction); -#endif - -static Bool -CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen, Bool fAllowOtherWM); - -static void -winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle); - -void -winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle); - -/* - * Local globals - */ - -static jmp_buf g_jmpWMEntry; -static jmp_buf g_jmpXMsgProcEntry; -static Bool g_shutdown = FALSE; -static Bool redirectError = FALSE; -static Bool g_fAnotherWMRunning = FALSE; - -/* - * PushMessage - Push a message onto the queue - */ - -static void -PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode) -{ - - /* Lock the queue mutex */ - pthread_mutex_lock (&pQueue->pmMutex); - - pNode->pNext = NULL; - - if (pQueue->pTail != NULL) - { - pQueue->pTail->pNext = pNode; - } - pQueue->pTail = pNode; - - if (pQueue->pHead == NULL) - { - pQueue->pHead = pNode; - } - - -#if 0 - switch (pNode->msg.msg) - { - case WM_WM_MOVE: - ErrorF ("\tWM_WM_MOVE\n"); - break; - case WM_WM_SIZE: - ErrorF ("\tWM_WM_SIZE\n"); - break; - case WM_WM_RAISE: - ErrorF ("\tWM_WM_RAISE\n"); - break; - case WM_WM_LOWER: - ErrorF ("\tWM_WM_LOWER\n"); - break; - case WM_WM_MAP: - ErrorF ("\tWM_WM_MAP\n"); - break; - case WM_WM_MAP2: - ErrorF ("\tWM_WM_MAP2\n"); - break; - case WM_WM_MAP3: - ErrorF ("\tWM_WM_MAP3\n"); - break; - case WM_WM_UNMAP: - ErrorF ("\tWM_WM_UNMAP\n"); - break; - case WM_WM_KILL: - ErrorF ("\tWM_WM_KILL\n"); - break; - case WM_WM_ACTIVATE: - ErrorF ("\tWM_WM_ACTIVATE\n"); - break; - default: - ErrorF ("\tUnknown Message.\n"); - break; - } -#endif - - /* Increase the count of elements in the queue by one */ - ++(pQueue->nQueueSize); - - /* Release the queue mutex */ - pthread_mutex_unlock (&pQueue->pmMutex); - - /* Signal that the queue is not empty */ - pthread_cond_signal (&pQueue->pcNotEmpty); -} - - -#if CYGMULTIWINDOW_DEBUG -/* - * QueueSize - Return the size of the queue - */ - -static int -QueueSize (WMMsgQueuePtr pQueue) -{ - WMMsgNodePtr pNode; - int nSize = 0; - - /* Loop through all elements in the queue */ - for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext) - ++nSize; - - return nSize; -} -#endif - - -/* - * PopMessage - Pop a message from the queue - */ - -static WMMsgNodePtr -PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo) -{ - WMMsgNodePtr pNode; - - /* Lock the queue mutex */ - pthread_mutex_lock (&pQueue->pmMutex); - - /* Wait for --- */ - while (pQueue->pHead == NULL) - { - pthread_cond_wait (&pQueue->pcNotEmpty, &pQueue->pmMutex); - } - - pNode = pQueue->pHead; - if (pQueue->pHead != NULL) - { - pQueue->pHead = pQueue->pHead->pNext; - } - - if (pQueue->pTail == pNode) - { - pQueue->pTail = NULL; - } - - /* Drop the number of elements in the queue by one */ - --(pQueue->nQueueSize); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("Queue Size %d %d\n", pQueue->nQueueSize, QueueSize(pQueue)); -#endif - - /* Release the queue mutex */ - pthread_mutex_unlock (&pQueue->pmMutex); - - return pNode; -} - - -#if 0 -/* - * HaveMessage - - */ - -static Bool -HaveMessage (WMMsgQueuePtr pQueue, UINT msg, Window iWindow) -{ - WMMsgNodePtr pNode; - - for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext) - { - if (pNode->msg.msg==msg && pNode->msg.iWindow==iWindow) - return True; - } - - return False; -} -#endif - - -/* - * InitQueue - Initialize the Window Manager message queue - */ - -static -Bool -InitQueue (WMMsgQueuePtr pQueue) -{ - /* Check if the pQueue pointer is NULL */ - if (pQueue == NULL) - { - ErrorF ("InitQueue - pQueue is NULL. Exiting.\n"); - return FALSE; - } - - /* Set the head and tail to NULL */ - pQueue->pHead = NULL; - pQueue->pTail = NULL; - - /* There are no elements initially */ - pQueue->nQueueSize = 0; - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("InitQueue - Queue Size %d %d\n", pQueue->nQueueSize, - QueueSize(pQueue)); -#endif - - ErrorF ("InitQueue - Calling pthread_mutex_init\n"); - - /* Create synchronization objects */ - pthread_mutex_init (&pQueue->pmMutex, NULL); - - ErrorF ("InitQueue - pthread_mutex_init returned\n"); - ErrorF ("InitQueue - Calling pthread_cond_init\n"); - - pthread_cond_init (&pQueue->pcNotEmpty, NULL); - - ErrorF ("InitQueue - pthread_cond_init returned\n"); - - return TRUE; -} - - -/* - * GetWindowName - Retrieve the title of an X Window - */ - -static void -GetWindowName (Display *pDisplay, Window iWin, wchar_t **ppName) -{ - int nResult, nNum; - char **ppList; - char *pszReturnData; - int iLen, i; - XTextProperty xtpName; - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("GetWindowName\n"); -#endif - - /* Intialize ppName to NULL */ - *ppName = NULL; - - /* Try to get --- */ - nResult = XGetWMName (pDisplay, iWin, &xtpName); - if (!nResult || !xtpName.value || !xtpName.nitems) - { -#if CYGMULTIWINDOW_DEBUG - ErrorF ("GetWindowName - XGetWMName failed. No name.\n"); -#endif - return; - } - - if (Xutf8TextPropertyToTextList (pDisplay, &xtpName, &ppList, &nNum) >= Success && nNum > 0 && *ppList) - { - iLen = 0; - for (i = 0; i < nNum; i++) iLen += strlen(ppList[i]); - pszReturnData = (char *) malloc (iLen + 1); - pszReturnData[0] = '\0'; - for (i = 0; i < nNum; i++) strcat (pszReturnData, ppList[i]); - if (ppList) XFreeStringList (ppList); - } - else - { - pszReturnData = (char *) malloc (1); - pszReturnData[0] = '\0'; - } - iLen = MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, NULL, 0); - *ppName = (wchar_t*)malloc(sizeof(wchar_t)*(iLen + 1)); - MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, *ppName, iLen); - XFree (xtpName.value); - free (pszReturnData); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("GetWindowName - Returning\n"); -#endif -} - - -/* - * Send a message to the X server from the WM thread - */ - -static int -SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData) -{ - XEvent e; - - /* Prepare the X event structure */ - e.type = ClientMessage; - e.xclient.window = iWin; - e.xclient.message_type = atmType; - e.xclient.format = 32; - e.xclient.data.l[0] = nData; - e.xclient.data.l[1] = CurrentTime; - - /* Send the event to X */ - return XSendEvent (pDisplay, iWin, False, NoEventMask, &e); -} - - -/* - * Updates the name of a HWND according to its X WM_NAME property - */ - -static void -UpdateName (WMInfoPtr pWMInfo, Window iWindow) -{ - wchar_t *pszName; - Atom atmType; - int fmtRet; - unsigned long items, remain; - HWND *retHwnd, hWnd; - XWindowAttributes attr; - - hWnd = 0; - - /* See if we can get the cached HWND for this window... */ - if (XGetWindowProperty (pWMInfo->pDisplay, - iWindow, - pWMInfo->atmPrivMap, - 0, - 1, - False, - XA_INTEGER,//pWMInfo->atmPrivMap, - &atmType, - &fmtRet, - &items, - &remain, - (unsigned char **) &retHwnd) == Success) - { - if (retHwnd) - { - hWnd = *retHwnd; - XFree (retHwnd); - } - } - - /* Some sanity checks */ - if (!hWnd) return; - if (!IsWindow (hWnd)) return; - - /* Set the Windows window name */ - GetWindowName (pWMInfo->pDisplay, iWindow, &pszName); - if (pszName) - { - /* Get the window attributes */ - XGetWindowAttributes (pWMInfo->pDisplay, - iWindow, - &attr); - if (!attr.override_redirect) - { - SetWindowTextW (hWnd, pszName); - winUpdateIcon (iWindow); - } - - free (pszName); - } -} - - -#if 0 -/* - * Fix up any differences between the X11 and Win32 window stacks - * starting at the window passed in - */ -static void -PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction) -{ - Atom atmType; - int fmtRet; - unsigned long items, remain; - HWND hWnd, *retHwnd; - DWORD myWinProcID, winProcID; - Window xWindow; - WINDOWPLACEMENT wndPlace; - - hWnd = NULL; - /* See if we can get the cached HWND for this window... */ - if (XGetWindowProperty (pWMInfo->pDisplay, - iWindow, - pWMInfo->atmPrivMap, - 0, - 1, - False, - XA_INTEGER,//pWMInfo->atmPrivMap, - &atmType, - &fmtRet, - &items, - &remain, - (unsigned char **) &retHwnd) == Success) - { - if (retHwnd) - { - hWnd = *retHwnd; - XFree (retHwnd); - } - } - - if (!hWnd) return; - - GetWindowThreadProcessId (hWnd, &myWinProcID); - hWnd = GetNextWindow (hWnd, direction); - - while (hWnd) { - GetWindowThreadProcessId (hWnd, &winProcID); - if (winProcID == myWinProcID) - { - wndPlace.length = sizeof(WINDOWPLACEMENT); - GetWindowPlacement (hWnd, &wndPlace); - if ( !(wndPlace.showCmd==SW_HIDE || - wndPlace.showCmd==SW_MINIMIZE) ) - { - xWindow = (Window)GetProp (hWnd, WIN_WID_PROP); - if (xWindow) - { - if (direction==GW_HWNDPREV) - XRaiseWindow (pWMInfo->pDisplay, xWindow); - else - XLowerWindow (pWMInfo->pDisplay, xWindow); - } - } - } - hWnd = GetNextWindow(hWnd, direction); - } -} -#endif /* PreserveWin32Stack */ - - -/* - * winMultiWindowWMProc - */ - -static void * -winMultiWindowWMProc (void *pArg) -{ - WMProcArgPtr pProcArg = (WMProcArgPtr)pArg; - WMInfoPtr pWMInfo = pProcArg->pWMInfo; - - /* Initialize the Window Manager */ - winInitMultiWindowWM (pWMInfo, pProcArg); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winMultiWindowWMProc ()\n"); -#endif - - /* Loop until we explicity break out */ - for (;;) - { - WMMsgNodePtr pNode; - - if(g_fAnotherWMRunning)/* Another Window manager exists. */ - { - Sleep (1000); - continue; - } - - /* Pop a message off of our queue */ - pNode = PopMessage (&pWMInfo->wmMsgQueue, pWMInfo); - if (pNode == NULL) - { - /* Bail if PopMessage returns without a message */ - /* NOTE: Remember that PopMessage is a blocking function. */ - ErrorF ("winMultiWindowWMProc - Queue is Empty? Exiting.\n"); - pthread_exit (NULL); - } - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winMultiWindowWMProc - %d ms MSG: %d ID: %d\n", - GetTickCount (), (int)pNode->msg.msg, (int)pNode->msg.dwID); -#endif - - /* Branch on the message type */ - switch (pNode->msg.msg) - { -#if 0 - case WM_WM_MOVE: - ErrorF ("\tWM_WM_MOVE\n"); - break; - - case WM_WM_SIZE: - ErrorF ("\tWM_WM_SIZE\n"); - break; -#endif - - case WM_WM_RAISE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\tWM_WM_RAISE\n"); -#endif - /* Raise the window */ - XRaiseWindow (pWMInfo->pDisplay, pNode->msg.iWindow); -#if 0 - PreserveWin32Stack (pWMInfo, pNode->msg.iWindow, GW_HWNDPREV); -#endif - break; - - case WM_WM_LOWER: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\tWM_WM_LOWER\n"); -#endif - - /* Lower the window */ - XLowerWindow (pWMInfo->pDisplay, pNode->msg.iWindow); - break; - - case WM_WM_MAP: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\tWM_WM_MAP\n"); -#endif - /* Put a note as to the HWND associated with this Window */ - XChangeProperty (pWMInfo->pDisplay, - pNode->msg.iWindow, - pWMInfo->atmPrivMap, - XA_INTEGER,//pWMInfo->atmPrivMap, - 32, - PropModeReplace, - (unsigned char *) &(pNode->msg.hwndWindow), - 1); - UpdateName (pWMInfo, pNode->msg.iWindow); - winUpdateIcon (pNode->msg.iWindow); - break; - - case WM_WM_MAP2: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\tWM_WM_MAP2\n"); -#endif - XChangeProperty (pWMInfo->pDisplay, - pNode->msg.iWindow, - pWMInfo->atmPrivMap, - XA_INTEGER,//pWMInfo->atmPrivMap, - 32, - PropModeReplace, - (unsigned char *) &(pNode->msg.hwndWindow), - 1); - break; - - case WM_WM_MAP3: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\tWM_WM_MAP3\n"); -#endif - /* Put a note as to the HWND associated with this Window */ - XChangeProperty (pWMInfo->pDisplay, - pNode->msg.iWindow, - pWMInfo->atmPrivMap, - XA_INTEGER,//pWMInfo->atmPrivMap, - 32, - PropModeReplace, - (unsigned char *) &(pNode->msg.hwndWindow), - 1); - UpdateName (pWMInfo, pNode->msg.iWindow); - winUpdateIcon (pNode->msg.iWindow); - { - HWND zstyle = HWND_NOTOPMOST; - winApplyHints (pWMInfo->pDisplay, pNode->msg.iWindow, pNode->msg.hwndWindow, &zstyle); - winUpdateWindowPosition (pNode->msg.hwndWindow, TRUE, &zstyle); - } - break; - - case WM_WM_UNMAP: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\tWM_WM_UNMAP\n"); -#endif - - /* Unmap the window */ - XUnmapWindow (pWMInfo->pDisplay, pNode->msg.iWindow); - break; - - case WM_WM_KILL: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\tWM_WM_KILL\n"); -#endif - { - int i, n, found = 0; - Atom *protocols; - - /* --- */ - if (XGetWMProtocols (pWMInfo->pDisplay, - pNode->msg.iWindow, - &protocols, - &n)) - { - for (i = 0; i < n; ++i) - if (protocols[i] == pWMInfo->atmWmDelete) - ++found; - - XFree (protocols); - } - - /* --- */ - if (found) - SendXMessage (pWMInfo->pDisplay, - pNode->msg.iWindow, - pWMInfo->atmWmProtos, - pWMInfo->atmWmDelete); - else - XKillClient (pWMInfo->pDisplay, - pNode->msg.iWindow); - } - break; - - case WM_WM_ACTIVATE: -#if CYGMULTIWINDOW_DEBUG - ErrorF ("\tWM_WM_ACTIVATE\n"); -#endif - - /* Set the input focus */ - XSetInputFocus (pWMInfo->pDisplay, - pNode->msg.iWindow, - RevertToPointerRoot, - CurrentTime); - break; - - case WM_WM_NAME_EVENT: - UpdateName (pWMInfo, pNode->msg.iWindow); - break; - - case WM_WM_HINTS_EVENT: - winUpdateIcon (pNode->msg.iWindow); - break; - - case WM_WM_CHANGE_STATE: - /* Minimize the window in Windows */ - winMinimizeWindow (pNode->msg.iWindow); - break; - - default: - ErrorF ("winMultiWindowWMProc - Unknown Message. Exiting.\n"); - pthread_exit (NULL); - break; - } - - /* Free the retrieved message */ - free (pNode); - - /* Flush any pending events on our display */ - XFlush (pWMInfo->pDisplay); - } - - /* Free the condition variable */ - pthread_cond_destroy (&pWMInfo->wmMsgQueue.pcNotEmpty); - - /* Free the mutex variable */ - pthread_mutex_destroy (&pWMInfo->wmMsgQueue.pmMutex); - - /* Free the passed-in argument */ - free (pProcArg); - -#if CYGMULTIWINDOW_DEBUG - ErrorF("-winMultiWindowWMProc ()\n"); -#endif - return NULL; -} - - -/* - * X message procedure - */ - -static void * -winMultiWindowXMsgProc (void *pArg) -{ - winWMMessageRec msg; - XMsgProcArgPtr pProcArg = (XMsgProcArgPtr) pArg; - char pszDisplay[512]; - int iRetries; - XEvent event; - Atom atmWmName; - Atom atmWmHints; - Atom atmWmChange; - int iReturn; - XIconSize *xis; - - ErrorF ("winMultiWindowXMsgProc - Hello\n"); - - /* Check that argument pointer is not invalid */ - if (pProcArg == NULL) - { - ErrorF ("winMultiWindowXMsgProc - pProcArg is NULL. Exiting.\n"); - pthread_exit (NULL); - } - - ErrorF ("winMultiWindowXMsgProc - Calling pthread_mutex_lock ()\n"); - - /* Grab the server started mutex - pause until we get it */ - iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted); - if (iReturn != 0) - { - ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () failed: %d. " - "Exiting.\n", - iReturn); - pthread_exit (NULL); - } - - ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () returned.\n"); - - /* Allow multiple threads to access Xlib */ - if (XInitThreads () == 0) - { - ErrorF ("winMultiWindowXMsgProc - XInitThreads () failed. Exiting.\n"); - pthread_exit (NULL); - } - - /* See if X supports the current locale */ - if (XSupportsLocale () == False) - { - ErrorF ("winMultiWindowXMsgProc - Warning: locale not supported by X\n"); - } - - /* Release the server started mutex */ - pthread_mutex_unlock (pProcArg->ppmServerStarted); - - ErrorF ("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n"); - - /* Set jump point for IO Error exits */ - iReturn = setjmp (g_jmpXMsgProcEntry); - - /* Check if we should continue operations */ - if (iReturn != WIN_JMP_ERROR_IO - && iReturn != WIN_JMP_OKAY) - { - /* setjmp returned an unknown value, exit */ - ErrorF ("winInitMultiWindowXMsgProc - setjmp returned: %d. Exiting.\n", - iReturn); - pthread_exit (NULL); - } - else if (iReturn == WIN_JMP_ERROR_IO) - { - ErrorF ("winInitMultiWindowXMsgProc - Caught IO Error. Exiting.\n"); - pthread_exit (NULL); - } - - /* Install our error handler */ - XSetErrorHandler (winMultiWindowXMsgProcErrorHandler); - XSetIOErrorHandler (winMultiWindowXMsgProcIOErrorHandler); - - /* Setup the display connection string x */ - snprintf (pszDisplay, - 512, "127.0.0.1:%s.%d", display, (int)pProcArg->dwScreen); - - /* Print the display connection string */ - ErrorF ("winMultiWindowXMsgProc - DISPLAY=%s\n", pszDisplay); - - /* Use our generated cookie for authentication */ - winSetAuthorization(); - - /* Initialize retry count */ - iRetries = 0; - - /* Open the X display */ - do - { - /* Try to open the display */ - pProcArg->pDisplay = XOpenDisplay (pszDisplay); - if (pProcArg->pDisplay == NULL) - { - ErrorF ("winMultiWindowXMsgProc - Could not open display, try: %d, " - "sleeping: %d\n\f", - iRetries + 1, WIN_CONNECT_DELAY); - ++iRetries; - sleep (WIN_CONNECT_DELAY); - continue; - } - else - break; - } - while (pProcArg->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES); - - /* Make sure that the display opened */ - if (pProcArg->pDisplay == NULL) - { - ErrorF ("winMultiWindowXMsgProc - Failed opening the display. " - "Exiting.\n"); - pthread_exit (NULL); - } - - ErrorF ("winMultiWindowXMsgProc - XOpenDisplay () returned and " - "successfully opened the display.\n"); - - /* Check if another window manager is already running */ - g_fAnotherWMRunning = CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen, pProcArg->pWMInfo->fAllowOtherWM); - - if (g_fAnotherWMRunning && !pProcArg->pWMInfo->fAllowOtherWM) - { - ErrorF ("winMultiWindowXMsgProc - " - "another window manager is running. Exiting.\n"); - pthread_exit (NULL); - } - - /* Set up the supported icon sizes */ - xis = XAllocIconSize (); - if (xis) - { - xis->min_width = xis->min_height = 16; - xis->max_width = xis->max_height = 48; - xis->width_inc = xis->height_inc = 16; - XSetIconSizes (pProcArg->pDisplay, - RootWindow (pProcArg->pDisplay, pProcArg->dwScreen), - xis, - 1); - XFree (xis); - } - - atmWmName = XInternAtom (pProcArg->pDisplay, - "WM_NAME", - False); - atmWmHints = XInternAtom (pProcArg->pDisplay, - "WM_HINTS", - False); - atmWmChange = XInternAtom (pProcArg->pDisplay, - "WM_CHANGE_STATE", - False); - - /* - iiimxcf had a bug until 2009-04-27, assuming that the - WM_STATE atom exists, causing clients to fail with - a BadAtom X error if it doesn't. - - Since this is on in the default Solaris 10 install, - workaround this by making sure it does exist... - */ - XInternAtom(pProcArg->pDisplay, "WM_STATE", 0); - - /* Loop until we explicitly break out */ - while (1) - { - if (g_shutdown) - break; - - if (pProcArg->pWMInfo->fAllowOtherWM && !XPending (pProcArg->pDisplay)) - { - if (CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen, TRUE)) - { - if (!g_fAnotherWMRunning) - { - g_fAnotherWMRunning = TRUE; - SendMessage(*(HWND*)pProcArg->hwndScreen, WM_UNMANAGE, 0, 0); - } - } - else - { - if (g_fAnotherWMRunning) - { - g_fAnotherWMRunning = FALSE; - SendMessage(*(HWND*)pProcArg->hwndScreen, WM_MANAGE, 0, 0); - } - } - Sleep (500); - continue; - } - - /* Fetch next event */ - XNextEvent (pProcArg->pDisplay, &event); - - /* Branch on event type */ - if (event.type == CreateNotify) - { - XWindowAttributes attr; - - XSelectInput (pProcArg->pDisplay, - event.xcreatewindow.window, - PropertyChangeMask); - - /* Get the window attributes */ - XGetWindowAttributes (pProcArg->pDisplay, - event.xcreatewindow.window, - &attr); - - if (!attr.override_redirect) - XSetWindowBorderWidth(pProcArg->pDisplay, - event.xcreatewindow.window, - 0); - } - else if (event.type == MapNotify) - { - /* Fake a reparentNotify event as SWT/Motif expects a - Window Manager to reparent a top-level window when - it is mapped and waits until they do. - - We don't actually need to reparent, as the frame is - a native window, not an X window - - We do this on MapNotify, not MapRequest like a real - Window Manager would, so we don't have do get involved - in actually mapping the window via it's (non-existent) - parent... - - See sourceware bugzilla #9848 - */ - - XWindowAttributes attr; - Window root; - Window parent; - Window *children; - unsigned int nchildren; - - if (XGetWindowAttributes(event.xmap.display, - event.xmap.window, - &attr) && - XQueryTree(event.xmap.display, - event.xmap.window, - &root, &parent, &children, &nchildren)) - { - if (children) XFree(children); - - /* - It's a top-level window if the parent window is a root window - Only non-override_redirect windows can get reparented - */ - if ((attr.root == parent) && !event.xmap.override_redirect) - { - XEvent event_send; - - event_send.type = ReparentNotify; - event_send.xreparent.event = event.xmap.window; - event_send.xreparent.window = event.xmap.window; - event_send.xreparent.parent = parent; - event_send.xreparent.x = attr.x; - event_send.xreparent.y = attr.y; - - XSendEvent(event.xmap.display, - event.xmap.window, - True, StructureNotifyMask, - &event_send); - } - } - } - else if (event.type == PropertyNotify - && event.xproperty.atom == atmWmName) - { - memset (&msg, 0, sizeof (msg)); - - msg.msg = WM_WM_NAME_EVENT; - msg.iWindow = event.xproperty.window; - - /* Other fields ignored */ - winSendMessageToWM (pProcArg->pWMInfo, &msg); - } - else if (event.type == PropertyNotify - && event.xproperty.atom == atmWmHints) - { - memset (&msg, 0, sizeof (msg)); - - msg.msg = WM_WM_HINTS_EVENT; - msg.iWindow = event.xproperty.window; - - /* Other fields ignored */ - winSendMessageToWM (pProcArg->pWMInfo, &msg); - } - else if (event.type == ClientMessage - && event.xclient.message_type == atmWmChange - && event.xclient.data.l[0] == IconicState) - { - ErrorF ("winMultiWindowXMsgProc - WM_CHANGE_STATE - IconicState\n"); - - memset (&msg, 0, sizeof (msg)); - - msg.msg = WM_WM_CHANGE_STATE; - msg.iWindow = event.xclient.window; - - winSendMessageToWM (pProcArg->pWMInfo, &msg); - } - } - - XCloseDisplay (pProcArg->pDisplay); - pthread_exit (NULL); - return NULL; -} - - -/* - * winInitWM - Entry point for the X server to spawn - * the Window Manager thread. Called from - * winscrinit.c/winFinishScreenInitFB (). - */ - -Bool -winInitWM (void **ppWMInfo, - pthread_t *ptWMProc, - pthread_t *ptXMsgProc, - pthread_mutex_t *ppmServerStarted, - int dwScreen, - HWND hwndScreen, - BOOL allowOtherWM) -{ - WMProcArgPtr pArg = (WMProcArgPtr) malloc (sizeof(WMProcArgRec)); - WMInfoPtr pWMInfo = (WMInfoPtr) malloc (sizeof(WMInfoRec)); - XMsgProcArgPtr pXMsgArg = (XMsgProcArgPtr) malloc (sizeof(XMsgProcArgRec)); - - /* Bail if the input parameters are bad */ - if (pArg == NULL || pWMInfo == NULL) - { - ErrorF ("winInitWM - malloc failed.\n"); - return FALSE; - } - - /* Zero the allocated memory */ - ZeroMemory (pArg, sizeof (WMProcArgRec)); - ZeroMemory (pWMInfo, sizeof (WMInfoRec)); - ZeroMemory (pXMsgArg, sizeof (XMsgProcArgRec)); - - /* Set a return pointer to the Window Manager info structure */ - *ppWMInfo = pWMInfo; - pWMInfo->fAllowOtherWM = allowOtherWM; - - /* Setup the argument structure for the thread function */ - pArg->dwScreen = dwScreen; - pArg->pWMInfo = pWMInfo; - pArg->ppmServerStarted = ppmServerStarted; - - /* Intialize the message queue */ - if (!InitQueue (&pWMInfo->wmMsgQueue)) - { - ErrorF ("winInitWM - InitQueue () failed.\n"); - return FALSE; - } - - /* Spawn a thread for the Window Manager */ - if (pthread_create (ptWMProc, NULL, winMultiWindowWMProc, pArg)) - { - /* Bail if thread creation failed */ - ErrorF ("winInitWM - pthread_create failed for Window Manager.\n"); - return FALSE; - } - - /* Spawn the XNextEvent thread, will send messages to WM */ - pXMsgArg->dwScreen = dwScreen; - pXMsgArg->pWMInfo = pWMInfo; - pXMsgArg->ppmServerStarted = ppmServerStarted; - pXMsgArg->hwndScreen = hwndScreen; - if (pthread_create (ptXMsgProc, NULL, winMultiWindowXMsgProc, pXMsgArg)) - { - /* Bail if thread creation failed */ - ErrorF ("winInitWM - pthread_create failed on XMSG.\n"); - return FALSE; - } - -#if CYGDEBUG || YES - winDebug ("winInitWM - Returning.\n"); -#endif - - return TRUE; -} - - -/* - * Window manager thread - setup - */ - -static void -winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg) -{ - int iRetries = 0; - char pszDisplay[512]; - int iReturn; - - ErrorF ("winInitMultiWindowWM - Hello\n"); - - /* Check that argument pointer is not invalid */ - if (pProcArg == NULL) - { - ErrorF ("winInitMultiWindowWM - pProcArg is NULL. Exiting.\n"); - pthread_exit (NULL); - } - - ErrorF ("winInitMultiWindowWM - Calling pthread_mutex_lock ()\n"); - - /* Grab our garbage mutex to satisfy pthread_cond_wait */ - iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted); - if (iReturn != 0) - { - ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () failed: %d. " - "Exiting.\n", - iReturn); - pthread_exit (NULL); - } - - ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () returned.\n"); - - /* Allow multiple threads to access Xlib */ - if (XInitThreads () == 0) - { - ErrorF ("winInitMultiWindowWM - XInitThreads () failed. Exiting.\n"); - pthread_exit (NULL); - } - - /* See if X supports the current locale */ - if (XSupportsLocale () == False) - { - ErrorF ("winInitMultiWindowWM - Warning: Locale not supported by X.\n"); - } - - /* Release the server started mutex */ - pthread_mutex_unlock (pProcArg->ppmServerStarted); - - ErrorF ("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n"); - - /* Set jump point for IO Error exits */ - iReturn = setjmp (g_jmpWMEntry); - - /* Check if we should continue operations */ - if (iReturn != WIN_JMP_ERROR_IO - && iReturn != WIN_JMP_OKAY) - { - /* setjmp returned an unknown value, exit */ - ErrorF ("winInitMultiWindowWM - setjmp returned: %d. Exiting.\n", - iReturn); - pthread_exit (NULL); - } - else if (iReturn == WIN_JMP_ERROR_IO) - { - ErrorF ("winInitMultiWindowWM - Caught IO Error. Exiting.\n"); - pthread_exit (NULL); - } - - /* Install our error handler */ - XSetErrorHandler (winMultiWindowWMErrorHandler); - XSetIOErrorHandler (winMultiWindowWMIOErrorHandler); - - /* Setup the display connection string x */ - snprintf (pszDisplay, - 512, - "127.0.0.1:%s.%d", - display, - (int) pProcArg->dwScreen); - - /* Print the display connection string */ - ErrorF ("winInitMultiWindowWM - DISPLAY=%s\n", pszDisplay); - - /* Use our generated cookie for authentication */ - winSetAuthorization(); - - /* Open the X display */ - do - { - /* Try to open the display */ - pWMInfo->pDisplay = XOpenDisplay (pszDisplay); - if (pWMInfo->pDisplay == NULL) - { - ErrorF ("winInitMultiWindowWM - Could not open display, try: %d, " - "sleeping: %d\n\f", - iRetries + 1, WIN_CONNECT_DELAY); - ++iRetries; - sleep (WIN_CONNECT_DELAY); - continue; - } - else - break; - } - while (pWMInfo->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES); - - /* Make sure that the display opened */ - if (pWMInfo->pDisplay == NULL) - { - ErrorF ("winInitMultiWindowWM - Failed opening the display. " - "Exiting.\n"); - pthread_exit (NULL); - } - - ErrorF ("winInitMultiWindowWM - XOpenDisplay () returned and " - "successfully opened the display.\n"); - - - /* Create some atoms */ - pWMInfo->atmWmProtos = XInternAtom (pWMInfo->pDisplay, - "WM_PROTOCOLS", - False); - pWMInfo->atmWmDelete = XInternAtom (pWMInfo->pDisplay, - "WM_DELETE_WINDOW", - False); - - pWMInfo->atmPrivMap = XInternAtom (pWMInfo->pDisplay, - WINDOWSWM_NATIVE_HWND, - False); - - - if (1) { - Cursor cursor = XCreateFontCursor (pWMInfo->pDisplay, XC_left_ptr); - if (cursor) - { - XDefineCursor (pWMInfo->pDisplay, DefaultRootWindow(pWMInfo->pDisplay), cursor); - XFreeCursor (pWMInfo->pDisplay, cursor); - } - } -} - - -/* - * winSendMessageToWM - Send a message from the X thread to the WM thread - */ - -void -winSendMessageToWM (void *pWMInfo, winWMMessagePtr pMsg) -{ - WMMsgNodePtr pNode; - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winSendMessageToWM ()\n"); -#endif - - pNode = (WMMsgNodePtr)malloc(sizeof(WMMsgNodeRec)); - if (pNode != NULL) - { - memcpy (&pNode->msg, pMsg, sizeof(winWMMessageRec)); - PushMessage (&((WMInfoPtr)pWMInfo)->wmMsgQueue, pNode); - } -} - - -/* - * Window manager error handler - */ - -static int -winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr) -{ - char pszErrorMsg[100]; - - if (pErr->request_code == X_ChangeWindowAttributes - && pErr->error_code == BadAccess) - { - ErrorF ("winMultiWindowWMErrorHandler - ChangeWindowAttributes " - "BadAccess.\n"); - return 0; - } - - XGetErrorText (pDisplay, - pErr->error_code, - pszErrorMsg, - sizeof (pszErrorMsg)); - ErrorF ("winMultiWindowWMErrorHandler - ERROR: %s\n", pszErrorMsg); - - return 0; -} - - -/* - * Window manager IO error handler - */ - -static int -winMultiWindowWMIOErrorHandler (Display *pDisplay) -{ - ErrorF ("\nwinMultiWindowWMIOErrorHandler!\n\n"); - - if (g_shutdown) - pthread_exit(NULL); - - /* Restart at the main entry point */ - longjmp (g_jmpWMEntry, WIN_JMP_ERROR_IO); - - return 0; -} - - -/* - * X message procedure error handler - */ - -static int -winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr) -{ - char pszErrorMsg[100]; - - XGetErrorText (pDisplay, - pErr->error_code, - pszErrorMsg, - sizeof (pszErrorMsg)); -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winMultiWindowXMsgProcErrorHandler - ERROR: %s\n", pszErrorMsg); -#endif - - return 0; -} - - -/* - * X message procedure IO error handler - */ - -static int -winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay) -{ - ErrorF ("\nwinMultiWindowXMsgProcIOErrorHandler!\n\n"); - - /* Restart at the main entry point */ - longjmp (g_jmpXMsgProcEntry, WIN_JMP_ERROR_IO); - - return 0; -} - - -/* - * Catch RedirectError to detect other window manager running - */ - -static int -winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr) -{ - redirectError = TRUE; - return 0; -} - - -/* - * Check if another window manager is running - */ - -static Bool -CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen, Bool fAllowOtherWM) -{ - /* - Try to select the events which only one client at a time is allowed to select. - If this causes an error, another window manager is already running... - */ - redirectError = FALSE; - XSetErrorHandler (winRedirectErrorHandler); - XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen), - ResizeRedirectMask | SubstructureRedirectMask | ButtonPressMask); - XSync (pDisplay, 0); - XSetErrorHandler (winMultiWindowXMsgProcErrorHandler); - - /* - Side effect: select the events we are actually interested in... - - If other WMs are not allowed, also select one of the events which only one client - at a time is allowed to select, so other window managers won't start... - */ - XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen), - SubstructureNotifyMask | ( !fAllowOtherWM ? ButtonPressMask : 0)); - XSync (pDisplay, 0); - return redirectError; -} - -/* - * Notify the MWM thread we're exiting and not to reconnect - */ - -void -winDeinitMultiWindowWM (void) -{ - ErrorF ("winDeinitMultiWindowWM - Noting shutdown in progress\n"); - g_shutdown = TRUE; -} - -/* Windows window styles */ -#define HINT_NOFRAME (1l<<0) -#define HINT_BORDER (1L<<1) -#define HINT_SIZEBOX (1l<<2) -#define HINT_CAPTION (1l<<3) -#define HINT_NOMAXIMIZE (1L<<4) -/* These two are used on their own */ -#define HINT_MAX (1L<<0) -#define HINT_MIN (1L<<1) - -static void -winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle) -{ - static Atom windowState, motif_wm_hints, windowType; - static Atom hiddenState, fullscreenState, belowState, aboveState; - static Atom dockWindow; - static int generation; - Atom type, *pAtom = NULL; - int format; - unsigned long hint = 0, maxmin = 0, style, nitems = 0 , left = 0; - WindowPtr pWin = GetProp (hWnd, WIN_WINDOW_PROP); - - if (!hWnd) return; - if (!IsWindow (hWnd)) return; - - if (generation != serverGeneration) { - generation = serverGeneration; - windowState = XInternAtom(pDisplay, "_NET_WM_STATE", False); - motif_wm_hints = XInternAtom(pDisplay, "_MOTIF_WM_HINTS", False); - windowType = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE", False); - hiddenState = XInternAtom(pDisplay, "_NET_WM_STATE_HIDDEN", False); - fullscreenState = XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", False); - belowState = XInternAtom(pDisplay, "_NET_WM_STATE_BELOW", False); - aboveState = XInternAtom(pDisplay, "_NET_WM_STATE_ABOVE", False); - dockWindow = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE_DOCK", False); - } - - if (XGetWindowProperty(pDisplay, iWindow, windowState, 0L, - 1L, False, XA_ATOM, &type, &format, - &nitems, &left, (unsigned char **)&pAtom) == Success) - { - if (pAtom && nitems == 1) - { - if (*pAtom == hiddenState) maxmin |= HINT_MIN; - else if (*pAtom == fullscreenState) maxmin |= HINT_MAX; - if (*pAtom == belowState) *zstyle = HWND_BOTTOM; - else if (*pAtom == aboveState) *zstyle = HWND_TOPMOST; - } - if (pAtom) XFree(pAtom); - } - - nitems = left = 0; - MwmHints *mwm_hint = NULL; - if (XGetWindowProperty(pDisplay, iWindow, motif_wm_hints, 0L, - PropMwmHintsElements, False, motif_wm_hints, &type, &format, - &nitems, &left, (unsigned char **)&mwm_hint) == Success) - { - if (mwm_hint && nitems == PropMwmHintsElements && (mwm_hint->flags & MwmHintsDecorations)) - { - if (!mwm_hint->decorations) hint |= HINT_NOFRAME; - else if (!(mwm_hint->decorations & MwmDecorAll)) - { - if (mwm_hint->decorations & MwmDecorBorder) hint |= HINT_BORDER; - if (mwm_hint->decorations & MwmDecorHandle) hint |= HINT_SIZEBOX; - if (mwm_hint->decorations & MwmDecorTitle) hint |= HINT_CAPTION; - } - } - if (mwm_hint) XFree(mwm_hint); - } - - nitems = left = 0; - pAtom = NULL; - if (XGetWindowProperty(pDisplay, iWindow, windowType, 0L, - 1L, False, XA_ATOM, &type, &format, - &nitems, &left, (unsigned char **)&pAtom) == Success) - { - if (pAtom && nitems == 1) - { - if (*pAtom == dockWindow) - { - hint = (hint & ~HINT_NOFRAME) | HINT_SIZEBOX; /* Xming puts a sizebox on dock windows */ - *zstyle = HWND_TOPMOST; - } - } - if (pAtom) XFree(pAtom); - } - - { - XSizeHints *normal_hint = XAllocSizeHints(); - long supplied; - if (normal_hint && (XGetWMNormalHints(pDisplay, iWindow, normal_hint, &supplied) == Success)) - { - if (normal_hint->flags & PMaxSize) - { - /* Not maximizable if a maximum size is specified */ - hint |= HINT_NOMAXIMIZE; - - if (normal_hint->flags & PMinSize) - { - /* - If both minimum size and maximum size are specified and are the same, - don't bother with a resizing frame - */ - if ((normal_hint->min_width == normal_hint->max_width) - && (normal_hint->min_height == normal_hint->max_height)) - hint = (hint & ~HINT_SIZEBOX); - } - } - } - XFree(normal_hint); - } - - /* Override hint settings from above with settings from config file */ - style = winOverrideStyle((unsigned long)pWin); - if (style & STYLE_TOPMOST) *zstyle = HWND_TOPMOST; - else if (style & STYLE_MAXIMIZE) maxmin = (hint & ~HINT_MIN) | HINT_MAX; - else if (style & STYLE_MINIMIZE) maxmin = (hint & ~HINT_MAX) | HINT_MIN; - else if (style & STYLE_BOTTOM) *zstyle = HWND_BOTTOM; - - if (maxmin & HINT_MAX) SendMessage(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0); - else if (maxmin & HINT_MIN) SendMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0); - - if (style & STYLE_NOTITLE) - hint = (hint & ~HINT_NOFRAME & ~HINT_BORDER & ~HINT_CAPTION) | HINT_SIZEBOX; - else if (style & STYLE_OUTLINE) - hint = (hint & ~HINT_NOFRAME & ~HINT_SIZEBOX & ~HINT_CAPTION) | HINT_BORDER; - else if (style & STYLE_NOFRAME) - hint = (hint & ~HINT_BORDER & ~HINT_CAPTION & ~HINT_SIZEBOX) | HINT_NOFRAME; - - /* Now apply styles to window */ - style = GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION & ~WS_SIZEBOX; /* Just in case */ - if (!style) return; - - if (!hint) /* All on */ - style = style | WS_CAPTION | WS_SIZEBOX; - else if (hint & HINT_NOFRAME) /* All off */ - style = style & ~WS_CAPTION & ~WS_SIZEBOX; - else style = style | ((hint & HINT_BORDER) ? WS_BORDER : 0) | - ((hint & HINT_SIZEBOX) ? WS_SIZEBOX : 0) | - ((hint & HINT_CAPTION) ? WS_CAPTION : 0); - - if (hint & HINT_NOMAXIMIZE) - style = style & ~WS_MAXIMIZEBOX; - - SetWindowLongPtr (hWnd, GWL_STYLE, style); -} - -void -winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle) -{ - int iX, iY, iWidth, iHeight; - int iDx, iDy; - RECT rcNew; - WindowPtr pWin = GetProp (hWnd, WIN_WINDOW_PROP); - DrawablePtr pDraw = NULL; - - if (!pWin) return; - pDraw = &pWin->drawable; - if (!pDraw) return; - - /* Get the X and Y location of the X window */ - iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN); - iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN); - - /* Get the height and width of the X window */ - iWidth = pWin->drawable.width; - iHeight = pWin->drawable.height; - - /* Setup a rectangle with the X window position and size */ - SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight); - -#if 0 - ErrorF ("winUpdateWindowPosition - (%d, %d)-(%d, %d)\n", - rcNew.left, rcNew.top, - rcNew.right, rcNew.bottom); -#endif - - AdjustWindowRectEx (&rcNew, GetWindowLongPtr (hWnd, GWL_STYLE), FALSE, WS_EX_APPWINDOW); - - /* Don't allow window decoration to disappear off to top-left as a result of this adjustment */ - if (rcNew.left < GetSystemMetrics(SM_XVIRTUALSCREEN)) - { - iDx = GetSystemMetrics(SM_XVIRTUALSCREEN) - rcNew.left; - rcNew.left += iDx; - rcNew.right += iDx; - } - - if (rcNew.top < GetSystemMetrics(SM_YVIRTUALSCREEN)) - { - iDy = GetSystemMetrics(SM_YVIRTUALSCREEN) - rcNew.top; - rcNew.top += iDy; - rcNew.bottom += iDy; - } - -#if 0 - ErrorF ("winUpdateWindowPosition - (%d, %d)-(%d, %d)\n", - rcNew.left, rcNew.top, - rcNew.right, rcNew.bottom); -#endif - - /* Position the Windows window */ - SetWindowPos (hWnd, *zstyle, rcNew.left, rcNew.top, - rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, - 0); - - if (reshape) - { - winReshapeMultiWindow(pWin); - winUpdateRgnMultiWindow(pWin); - } -} +/*
+ *Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
+ *Copyright (C) Colin Harrison 2005-2009
+ *
+ *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: Kensuke Matsuzaki
+ * Colin Harrison
+ */
+
+/* X headers */
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#ifdef __CYGWIN__
+#include <sys/select.h>
+#endif
+#include <fcntl.h>
+#include <setjmp.h>
+#define HANDLE void *
+#ifdef _MSC_VER
+typedef int pid_t;
+#endif
+#include <pthread.h>
+#undef HANDLE
+#include <X11/X.h>
+#include <X11/Xatom.h>
+#include <X11/Xlib.h>
+#include <X11/Xlocale.h>
+#include <X11/Xproto.h>
+#include <X11/Xutil.h>
+#include <X11/cursorfont.h>
+#include <X11/Xwindows.h>
+
+/* Local headers */
+#include "objbase.h"
+#include "ddraw.h"
+#include "winwindow.h"
+#include "winprefs.h"
+#include "window.h"
+#include "pixmapstr.h"
+#include "winmsg.h"
+#include "windowstr.h"
+#include "winmultiwindowclass.h"
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+#include <X11/extensions/windowswmstr.h>
+#else
+/* We need the native HWND atom for intWM, so for consistency use the
+ same name as extWM would if we were building with enabled... */
+#define WINDOWSWM_NATIVE_HWND "_WINDOWSWM_NATIVE_HWND"
+#endif
+
+extern void winDebug(const char *format, ...);
+extern void winReshapeMultiWindow(WindowPtr pWin);
+extern void winUpdateRgnMultiWindow(WindowPtr pWin);
+
+/*
+ * Constant defines
+ */
+
+#define WIN_CONNECT_RETRIES 5
+#define WIN_CONNECT_DELAY 5
+#ifdef HAS_DEVWINDOWS
+# define WIN_MSG_QUEUE_FNAME "/dev/windows"
+#endif
+#define WIN_JMP_OKAY 0
+#define WIN_JMP_ERROR_IO 2
+
+/*
+ * Local structures
+ */
+
+typedef struct _WMMsgNodeRec {
+ winWMMessageRec msg;
+ struct _WMMsgNodeRec *pNext;
+} WMMsgNodeRec, *WMMsgNodePtr;
+
+typedef struct _WMMsgQueueRec {
+ struct _WMMsgNodeRec *pHead;
+ struct _WMMsgNodeRec *pTail;
+ pthread_mutex_t pmMutex;
+ pthread_cond_t pcNotEmpty;
+ int nQueueSize;
+} WMMsgQueueRec, *WMMsgQueuePtr;
+
+typedef struct _WMInfo {
+ Display *pDisplay;
+ WMMsgQueueRec wmMsgQueue;
+ Atom atmWmProtos;
+ Atom atmWmDelete;
+ Atom atmPrivMap;
+ Bool fAllowOtherWM;
+} WMInfoRec, *WMInfoPtr;
+
+typedef struct _WMProcArgRec {
+ DWORD dwScreen;
+ WMInfoPtr pWMInfo;
+ pthread_mutex_t *ppmServerStarted;
+} WMProcArgRec, *WMProcArgPtr;
+
+typedef struct _XMsgProcArgRec {
+ Display *pDisplay;
+ DWORD dwScreen;
+ WMInfoPtr pWMInfo;
+ pthread_mutex_t *ppmServerStarted;
+ HWND hwndScreen;
+} XMsgProcArgRec, *XMsgProcArgPtr;
+
+
+/*
+ * References to external symbols
+ */
+
+extern char *display;
+extern void ErrorF (const char* /*f*/, ...);
+
+/*
+ * Prototypes for local functions
+ */
+
+static void
+PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode);
+
+static WMMsgNodePtr
+PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo);
+
+static Bool
+InitQueue (WMMsgQueuePtr pQueue);
+
+static void
+GetWindowName (Display * pDpy, Window iWin, wchar_t **ppName);
+
+static int
+SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData);
+
+static void
+UpdateName (WMInfoPtr pWMInfo, Window iWindow);
+
+static void*
+winMultiWindowWMProc (void* pArg);
+
+static int
+winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr);
+
+static int
+winMultiWindowWMIOErrorHandler (Display *pDisplay);
+
+static void *
+winMultiWindowXMsgProc (void *pArg);
+
+static int
+winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr);
+
+static int
+winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay);
+
+static int
+winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr);
+
+static void
+winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg);
+
+static Bool
+CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen, Bool fAllowOtherWM);
+
+static void
+winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle);
+
+void
+winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle);
+
+/*
+ * Local globals
+ */
+
+static jmp_buf g_jmpWMEntry;
+static jmp_buf g_jmpXMsgProcEntry;
+static Bool g_shutdown = FALSE;
+static Bool redirectError = FALSE;
+static Bool g_fAnotherWMRunning = FALSE;
+
+/*
+ * PushMessage - Push a message onto the queue
+ */
+
+static void
+PushMessage (WMMsgQueuePtr pQueue, WMMsgNodePtr pNode)
+{
+
+ /* Lock the queue mutex */
+ pthread_mutex_lock (&pQueue->pmMutex);
+
+ pNode->pNext = NULL;
+
+ if (pQueue->pTail != NULL)
+ {
+ pQueue->pTail->pNext = pNode;
+ }
+ pQueue->pTail = pNode;
+
+ if (pQueue->pHead == NULL)
+ {
+ pQueue->pHead = pNode;
+ }
+
+ /* Increase the count of elements in the queue by one */
+ ++(pQueue->nQueueSize);
+
+ /* Release the queue mutex */
+ pthread_mutex_unlock (&pQueue->pmMutex);
+
+ /* Signal that the queue is not empty */
+ pthread_cond_signal (&pQueue->pcNotEmpty);
+}
+
+
+#ifdef WINDBG
+/*
+ * QueueSize - Return the size of the queue
+ */
+
+static int
+QueueSize (WMMsgQueuePtr pQueue)
+{
+ WMMsgNodePtr pNode;
+ int nSize = 0;
+
+ /* Loop through all elements in the queue */
+ for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext)
+ ++nSize;
+
+ return nSize;
+}
+#endif
+
+
+/*
+ * PopMessage - Pop a message from the queue
+ */
+
+static WMMsgNodePtr
+PopMessage (WMMsgQueuePtr pQueue, WMInfoPtr pWMInfo)
+{
+ WMMsgNodePtr pNode;
+
+ /* Lock the queue mutex */
+ pthread_mutex_lock (&pQueue->pmMutex);
+
+ /* Wait for --- */
+ while (pQueue->pHead == NULL)
+ {
+ pthread_cond_wait (&pQueue->pcNotEmpty, &pQueue->pmMutex);
+ }
+
+ pNode = pQueue->pHead;
+ if (pQueue->pHead != NULL)
+ {
+ pQueue->pHead = pQueue->pHead->pNext;
+ }
+
+ if (pQueue->pTail == pNode)
+ {
+ pQueue->pTail = NULL;
+ }
+
+ /* Drop the number of elements in the queue by one */
+ --(pQueue->nQueueSize);
+
+ winDebug ("Queue Size %d %d\n", pQueue->nQueueSize, QueueSize(pQueue));
+
+ /* Release the queue mutex */
+ pthread_mutex_unlock (&pQueue->pmMutex);
+
+ return pNode;
+}
+
+
+#if 0
+/*
+ * HaveMessage -
+ */
+
+static Bool
+HaveMessage (WMMsgQueuePtr pQueue, UINT msg, Window iWindow)
+{
+ WMMsgNodePtr pNode;
+
+ for (pNode = pQueue->pHead; pNode != NULL; pNode = pNode->pNext)
+ {
+ if (pNode->msg.msg==msg && pNode->msg.iWindow==iWindow)
+ return True;
+ }
+
+ return False;
+}
+#endif
+
+
+/*
+ * InitQueue - Initialize the Window Manager message queue
+ */
+
+static
+Bool
+InitQueue (WMMsgQueuePtr pQueue)
+{
+ /* Check if the pQueue pointer is NULL */
+ if (pQueue == NULL)
+ {
+ ErrorF ("InitQueue - pQueue is NULL. Exiting.\n");
+ return FALSE;
+ }
+
+ /* Set the head and tail to NULL */
+ pQueue->pHead = NULL;
+ pQueue->pTail = NULL;
+
+ /* There are no elements initially */
+ pQueue->nQueueSize = 0;
+
+ winDebug ("InitQueue - Queue Size %d %d\n", pQueue->nQueueSize,
+ QueueSize(pQueue));
+
+ winDebug ("InitQueue - Calling pthread_mutex_init\n");
+
+ /* Create synchronization objects */
+ pthread_mutex_init (&pQueue->pmMutex, NULL);
+
+ winDebug ("InitQueue - pthread_mutex_init returned\n");
+ winDebug ("InitQueue - Calling pthread_cond_init\n");
+
+ pthread_cond_init (&pQueue->pcNotEmpty, NULL);
+
+ winDebug ("InitQueue - pthread_cond_init returned\n");
+
+ return TRUE;
+}
+
+
+/*
+ * GetWindowName - Retrieve the title of an X Window
+ */
+
+static void
+GetWindowName (Display *pDisplay, Window iWin, wchar_t **ppName)
+{
+ int nResult, nNum;
+ char **ppList;
+ char *pszReturnData;
+ int iLen, i;
+ XTextProperty xtpName;
+
+ winDebug ("GetWindowName\n");
+
+ /* Intialize ppName to NULL */
+ *ppName = NULL;
+
+ /* Try to get --- */
+ nResult = XGetWMName (pDisplay, iWin, &xtpName);
+ if (!nResult || !xtpName.value || !xtpName.nitems)
+ {
+ ErrorF ("GetWindowName - XGetWMName failed. No name.\n");
+ return;
+ }
+
+ if (Xutf8TextPropertyToTextList (pDisplay, &xtpName, &ppList, &nNum) >= Success && nNum > 0 && *ppList)
+ {
+ iLen = 0;
+ for (i = 0; i < nNum; i++) iLen += strlen(ppList[i]);
+ pszReturnData = (char *) malloc (iLen + 1);
+ pszReturnData[0] = '\0';
+ for (i = 0; i < nNum; i++) strcat (pszReturnData, ppList[i]);
+ if (ppList) XFreeStringList (ppList);
+ }
+ else
+ {
+ pszReturnData = (char *) malloc (1);
+ pszReturnData[0] = '\0';
+ }
+ iLen = MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, NULL, 0);
+ *ppName = (wchar_t*)malloc(sizeof(wchar_t)*(iLen + 1));
+ MultiByteToWideChar (CP_UTF8, 0, pszReturnData, -1, *ppName, iLen);
+ XFree (xtpName.value);
+ free (pszReturnData);
+ winDebug ("GetWindowName - Returning\n");
+}
+
+
+/*
+ * Send a message to the X server from the WM thread
+ */
+
+static int
+SendXMessage (Display *pDisplay, Window iWin, Atom atmType, long nData)
+{
+ XEvent e;
+
+ /* Prepare the X event structure */
+ e.type = ClientMessage;
+ e.xclient.window = iWin;
+ e.xclient.message_type = atmType;
+ e.xclient.format = 32;
+ e.xclient.data.l[0] = nData;
+ e.xclient.data.l[1] = CurrentTime;
+
+ /* Send the event to X */
+ return XSendEvent (pDisplay, iWin, False, NoEventMask, &e);
+}
+
+
+/*
+ * Updates the name of a HWND according to its X WM_NAME property
+ */
+
+static void
+UpdateName (WMInfoPtr pWMInfo, Window iWindow)
+{
+ wchar_t *pszName;
+ Atom atmType;
+ int fmtRet;
+ unsigned long items, remain;
+ HWND *retHwnd, hWnd;
+ XWindowAttributes attr;
+
+ hWnd = 0;
+
+ /* See if we can get the cached HWND for this window... */
+ if (XGetWindowProperty (pWMInfo->pDisplay,
+ iWindow,
+ pWMInfo->atmPrivMap,
+ 0,
+ 1,
+ False,
+ XA_INTEGER,//pWMInfo->atmPrivMap,
+ &atmType,
+ &fmtRet,
+ &items,
+ &remain,
+ (unsigned char **) &retHwnd) == Success)
+ {
+ if (retHwnd)
+ {
+ hWnd = *retHwnd;
+ XFree (retHwnd);
+ }
+ }
+
+ /* Some sanity checks */
+ if (!hWnd) return;
+ if (!IsWindow (hWnd)) return;
+
+ /* Set the Windows window name */
+ GetWindowName (pWMInfo->pDisplay, iWindow, &pszName);
+ if (pszName)
+ {
+ /* Get the window attributes */
+ XGetWindowAttributes (pWMInfo->pDisplay,
+ iWindow,
+ &attr);
+ if (!attr.override_redirect)
+ {
+ SetWindowTextW (hWnd, pszName);
+ winUpdateIcon (iWindow);
+ }
+
+ free (pszName);
+ }
+}
+
+
+#if 0
+/*
+ * Fix up any differences between the X11 and Win32 window stacks
+ * starting at the window passed in
+ */
+static void
+PreserveWin32Stack(WMInfoPtr pWMInfo, Window iWindow, UINT direction)
+{
+ Atom atmType;
+ int fmtRet;
+ unsigned long items, remain;
+ HWND hWnd, *retHwnd;
+ DWORD myWinProcID, winProcID;
+ Window xWindow;
+ WINDOWPLACEMENT wndPlace;
+
+ hWnd = NULL;
+ /* See if we can get the cached HWND for this window... */
+ if (XGetWindowProperty (pWMInfo->pDisplay,
+ iWindow,
+ pWMInfo->atmPrivMap,
+ 0,
+ 1,
+ False,
+ XA_INTEGER,//pWMInfo->atmPrivMap,
+ &atmType,
+ &fmtRet,
+ &items,
+ &remain,
+ (unsigned char **) &retHwnd) == Success)
+ {
+ if (retHwnd)
+ {
+ hWnd = *retHwnd;
+ XFree (retHwnd);
+ }
+ }
+
+ if (!hWnd) return;
+
+ GetWindowThreadProcessId (hWnd, &myWinProcID);
+ hWnd = GetNextWindow (hWnd, direction);
+
+ while (hWnd) {
+ GetWindowThreadProcessId (hWnd, &winProcID);
+ if (winProcID == myWinProcID)
+ {
+ wndPlace.length = sizeof(WINDOWPLACEMENT);
+ GetWindowPlacement (hWnd, &wndPlace);
+ if ( !(wndPlace.showCmd==SW_HIDE ||
+ wndPlace.showCmd==SW_MINIMIZE) )
+ {
+ xWindow = (Window)GetProp (hWnd, WIN_WID_PROP);
+ if (xWindow)
+ {
+ if (direction==GW_HWNDPREV)
+ XRaiseWindow (pWMInfo->pDisplay, xWindow);
+ else
+ XLowerWindow (pWMInfo->pDisplay, xWindow);
+ }
+ }
+ }
+ hWnd = GetNextWindow(hWnd, direction);
+ }
+}
+#endif /* PreserveWin32Stack */
+
+
+/*
+ * winMultiWindowWMProc
+ */
+
+static void *
+winMultiWindowWMProc (void *pArg)
+{
+ WMProcArgPtr pProcArg = (WMProcArgPtr)pArg;
+ WMInfoPtr pWMInfo = pProcArg->pWMInfo;
+
+ /* Initialize the Window Manager */
+ winInitMultiWindowWM (pWMInfo, pProcArg);
+
+ winDebug ("winMultiWindowWMProc ()\n");
+
+ /* Loop until we explicity break out */
+ for (;;)
+ {
+ WMMsgNodePtr pNode;
+
+ if(g_fAnotherWMRunning)/* Another Window manager exists. */
+ {
+ Sleep (1000);
+ continue;
+ }
+
+ /* Pop a message off of our queue */
+ pNode = PopMessage (&pWMInfo->wmMsgQueue, pWMInfo);
+ if (pNode == NULL)
+ {
+ /* Bail if PopMessage returns without a message */
+ /* NOTE: Remember that PopMessage is a blocking function. */
+ ErrorF ("winMultiWindowWMProc - Queue is Empty? Exiting.\n");
+ pthread_exit (NULL);
+ }
+
+ winDebug ("winMultiWindowWMProc - %d ms MSG: %d ID: %d\n",
+ GetTickCount (), (int)pNode->msg.msg, (int)pNode->msg.dwID);
+
+ /* Branch on the message type */
+ switch (pNode->msg.msg)
+ {
+ case WM_WM_RAISE:
+ winDebug ("\tWM_WM_RAISE\n");
+ /* Raise the window */
+ XRaiseWindow (pWMInfo->pDisplay, pNode->msg.iWindow);
+ break;
+
+ case WM_WM_LOWER:
+ winDebug ("\tWM_WM_LOWER\n");
+
+ /* Lower the window */
+ XLowerWindow (pWMInfo->pDisplay, pNode->msg.iWindow);
+ break;
+
+ case WM_WM_MAP:
+ winDebug ("\tWM_WM_MAP\n");
+ /* Put a note as to the HWND associated with this Window */
+ XChangeProperty (pWMInfo->pDisplay,
+ pNode->msg.iWindow,
+ pWMInfo->atmPrivMap,
+ XA_INTEGER,//pWMInfo->atmPrivMap,
+ 32,
+ PropModeReplace,
+ (unsigned char *) &(pNode->msg.hwndWindow),
+ 1);
+ UpdateName (pWMInfo, pNode->msg.iWindow);
+ winUpdateIcon (pNode->msg.iWindow);
+ {
+ HWND zstyle = HWND_NOTOPMOST;
+ winApplyHints (pWMInfo->pDisplay, pNode->msg.iWindow, pNode->msg.hwndWindow, &zstyle);
+ winUpdateWindowPosition (pNode->msg.hwndWindow, TRUE, &zstyle);
+ }
+ break;
+
+ case WM_WM_MAP2:
+ winDebug ("\tWM_WM_MAP2\n");
+
+ XChangeProperty (pWMInfo->pDisplay,
+ pNode->msg.iWindow,
+ pWMInfo->atmPrivMap,
+ XA_INTEGER,//pWMInfo->atmPrivMap,
+ 32,
+ PropModeReplace,
+ (unsigned char *) &(pNode->msg.hwndWindow),
+ 1);
+ break;
+
+ case WM_WM_MAP3:
+ winDebug ("\tWM_WM_MAP3\n");
+
+ /* Put a note as to the HWND associated with this Window */
+ XChangeProperty (pWMInfo->pDisplay,
+ pNode->msg.iWindow,
+ pWMInfo->atmPrivMap,
+ XA_INTEGER,//pWMInfo->atmPrivMap,
+ 32,
+ PropModeReplace,
+ (unsigned char *) &(pNode->msg.hwndWindow),
+ 1);
+ UpdateName (pWMInfo, pNode->msg.iWindow);
+ winUpdateIcon (pNode->msg.iWindow);
+ {
+ HWND zstyle = HWND_NOTOPMOST;
+ winApplyHints (pWMInfo->pDisplay, pNode->msg.iWindow, pNode->msg.hwndWindow, &zstyle);
+ winUpdateWindowPosition (pNode->msg.hwndWindow, TRUE, &zstyle);
+ }
+ break;
+
+ case WM_WM_UNMAP:
+ winDebug ("\tWM_WM_UNMAP\n");
+
+ /* Unmap the window */
+ XUnmapWindow (pWMInfo->pDisplay, pNode->msg.iWindow);
+ break;
+
+ case WM_WM_KILL:
+ winDebug ("\tWM_WM_KILL\n");
+ {
+ int i, n, found = 0;
+ Atom *protocols;
+
+ /* --- */
+ if (XGetWMProtocols (pWMInfo->pDisplay,
+ pNode->msg.iWindow,
+ &protocols,
+ &n))
+ {
+ for (i = 0; i < n; ++i)
+ if (protocols[i] == pWMInfo->atmWmDelete)
+ ++found;
+
+ XFree (protocols);
+ }
+
+ /* --- */
+ if (found)
+ SendXMessage (pWMInfo->pDisplay,
+ pNode->msg.iWindow,
+ pWMInfo->atmWmProtos,
+ pWMInfo->atmWmDelete);
+ else
+ XKillClient (pWMInfo->pDisplay,
+ pNode->msg.iWindow);
+ }
+ break;
+
+ case WM_WM_ACTIVATE:
+ winDebug ("\tWM_WM_ACTIVATE\n");
+
+ /* Set the input focus */
+ XSetInputFocus (pWMInfo->pDisplay,
+ pNode->msg.iWindow,
+ RevertToPointerRoot,
+ CurrentTime);
+ break;
+
+ case WM_WM_NAME_EVENT:
+ UpdateName (pWMInfo, pNode->msg.iWindow);
+ break;
+
+ case WM_WM_HINTS_EVENT:
+ winUpdateIcon (pNode->msg.iWindow);
+ break;
+
+ case WM_WM_CHANGE_STATE:
+ /* Minimize the window in Windows */
+ winMinimizeWindow (pNode->msg.iWindow);
+ break;
+
+ default:
+ ErrorF ("winMultiWindowWMProc - Unknown Message. Exiting.\n");
+ pthread_exit (NULL);
+ break;
+ }
+
+ /* Free the retrieved message */
+ free (pNode);
+
+ /* Flush any pending events on our display */
+ XFlush (pWMInfo->pDisplay);
+ }
+
+ /* Free the condition variable */
+ pthread_cond_destroy (&pWMInfo->wmMsgQueue.pcNotEmpty);
+
+ /* Free the mutex variable */
+ pthread_mutex_destroy (&pWMInfo->wmMsgQueue.pmMutex);
+
+ /* Free the passed-in argument */
+ free (pProcArg);
+
+ winDebug("-winMultiWindowWMProc ()\n");
+ return NULL;
+}
+
+
+/*
+ * X message procedure
+ */
+
+static void *
+winMultiWindowXMsgProc (void *pArg)
+{
+ winWMMessageRec msg;
+ XMsgProcArgPtr pProcArg = (XMsgProcArgPtr) pArg;
+ char pszDisplay[512];
+ int iRetries;
+ XEvent event;
+ Atom atmWmName;
+ Atom atmWmHints;
+ Atom atmWmChange;
+ int iReturn;
+ XIconSize *xis;
+
+ winDebug ("winMultiWindowXMsgProc - Hello\n");
+
+ /* Check that argument pointer is not invalid */
+ if (pProcArg == NULL)
+ {
+ ErrorF ("winMultiWindowXMsgProc - pProcArg is NULL. Exiting.\n");
+ pthread_exit (NULL);
+ }
+
+ winDebug ("winMultiWindowXMsgProc - Calling pthread_mutex_lock ()\n");
+
+ /* Grab the server started mutex - pause until we get it */
+ iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted);
+ if (iReturn != 0)
+ {
+ ErrorF ("winMultiWindowXMsgProc - pthread_mutex_lock () failed: %d. "
+ "Exiting.\n",
+ iReturn);
+ pthread_exit (NULL);
+ }
+
+ winDebug ("winMultiWindowXMsgProc - pthread_mutex_lock () returned.\n");
+
+ /* See if X supports the current locale */
+ if (XSupportsLocale () == False)
+ {
+ ErrorF ("winMultiWindowXMsgProc - Warning: locale not supported by X\n");
+ }
+
+ /* Release the server started mutex */
+ pthread_mutex_unlock (pProcArg->ppmServerStarted);
+
+ winDebug ("winMultiWindowXMsgProc - pthread_mutex_unlock () returned.\n");
+
+ /* Set jump point for IO Error exits */
+ iReturn = setjmp (g_jmpXMsgProcEntry);
+
+ /* Check if we should continue operations */
+ if (iReturn != WIN_JMP_ERROR_IO
+ && iReturn != WIN_JMP_OKAY)
+ {
+ /* setjmp returned an unknown value, exit */
+ ErrorF ("winInitMultiWindowXMsgProc - setjmp returned: %d. Exiting.\n",
+ iReturn);
+ pthread_exit (NULL);
+ }
+ else if (iReturn == WIN_JMP_ERROR_IO)
+ {
+ ErrorF ("winInitMultiWindowXMsgProc - Caught IO Error. Exiting.\n");
+ pthread_exit (NULL);
+ }
+
+ /* Install our error handler */
+ XSetErrorHandler (winMultiWindowXMsgProcErrorHandler);
+ XSetIOErrorHandler (winMultiWindowXMsgProcIOErrorHandler);
+
+ /* Setup the display connection string x */
+ winGetDisplayName(pszDisplay, (int)pProcArg->dwScreen);
+
+ /* Print the display connection string */
+ winDebug ("winMultiWindowXMsgProc - DISPLAY=%s\n", pszDisplay);
+
+ /* Use our generated cookie for authentication */
+ winSetAuthorization();
+
+ /* Initialize retry count */
+ iRetries = 0;
+
+ /* Open the X display */
+ do
+ {
+ /* Try to open the display */
+ pProcArg->pDisplay = XOpenDisplay (pszDisplay);
+ if (pProcArg->pDisplay == NULL)
+ {
+ winDebug ("winMultiWindowXMsgProc - Could not open display, try: %d, "
+ "sleeping: %d\n\f",
+ iRetries + 1, WIN_CONNECT_DELAY);
+ ++iRetries;
+ sleep (WIN_CONNECT_DELAY);
+ continue;
+ }
+ else
+ break;
+ }
+ while (pProcArg->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES);
+
+ /* Make sure that the display opened */
+ if (pProcArg->pDisplay == NULL)
+ {
+ ErrorF ("winMultiWindowXMsgProc - Failed opening the display. "
+ "Exiting.\n");
+ pthread_exit (NULL);
+ }
+
+ winDebug ("winMultiWindowXMsgProc - XOpenDisplay () returned and "
+ "successfully opened the display.\n");
+
+ /* Check if another window manager is already running */
+ g_fAnotherWMRunning = CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen, pProcArg->pWMInfo->fAllowOtherWM);
+
+ if (g_fAnotherWMRunning && !pProcArg->pWMInfo->fAllowOtherWM)
+ {
+ ErrorF ("winMultiWindowXMsgProc - "
+ "another window manager is running. Exiting.\n");
+ pthread_exit (NULL);
+ }
+
+ /* Set up the supported icon sizes */
+ xis = XAllocIconSize ();
+ if (xis)
+ {
+ xis->min_width = xis->min_height = 16;
+ xis->max_width = xis->max_height = 48;
+ xis->width_inc = xis->height_inc = 16;
+ XSetIconSizes (pProcArg->pDisplay,
+ RootWindow (pProcArg->pDisplay, pProcArg->dwScreen),
+ xis,
+ 1);
+ XFree (xis);
+ }
+
+ atmWmName = XInternAtom (pProcArg->pDisplay,
+ "WM_NAME",
+ False);
+ atmWmHints = XInternAtom (pProcArg->pDisplay,
+ "WM_HINTS",
+ False);
+ atmWmChange = XInternAtom (pProcArg->pDisplay,
+ "WM_CHANGE_STATE",
+ False);
+
+ /*
+ iiimxcf had a bug until 2009-04-27, assuming that the
+ WM_STATE atom exists, causing clients to fail with
+ a BadAtom X error if it doesn't.
+
+ Since this is on in the default Solaris 10 install,
+ workaround this by making sure it does exist...
+ */
+ XInternAtom(pProcArg->pDisplay, "WM_STATE", 0);
+
+ /* Loop until we explicitly break out */
+ while (1)
+ {
+ if (g_shutdown)
+ break;
+
+ if (pProcArg->pWMInfo->fAllowOtherWM && !XPending (pProcArg->pDisplay))
+ {
+ if (CheckAnotherWindowManager (pProcArg->pDisplay, pProcArg->dwScreen, TRUE))
+ {
+ if (!g_fAnotherWMRunning)
+ {
+ g_fAnotherWMRunning = TRUE;
+ SendMessage(*(HWND*)pProcArg->hwndScreen, WM_UNMANAGE, 0, 0);
+ }
+ }
+ else
+ {
+ if (g_fAnotherWMRunning)
+ {
+ g_fAnotherWMRunning = FALSE;
+ SendMessage(*(HWND*)pProcArg->hwndScreen, WM_MANAGE, 0, 0);
+ }
+ }
+ Sleep (500);
+ continue;
+ }
+
+ /* Fetch next event */
+ XNextEvent (pProcArg->pDisplay, &event);
+
+ /* Branch on event type */
+ if (event.type == MapNotify /* CreateNotify */)
+ {
+ XWindowAttributes attr;
+
+ XSelectInput (pProcArg->pDisplay,
+ event.xcreatewindow.window,
+ PropertyChangeMask);
+
+ /* Get the window attributes */
+ XGetWindowAttributes (pProcArg->pDisplay,
+ event.xcreatewindow.window,
+ &attr);
+
+ if (!attr.override_redirect && attr.class != InputOnly)
+ XSetWindowBorderWidth(pProcArg->pDisplay,
+ event.xcreatewindow.window,
+ 0);
+ }
+ else if (event.type == MapNotify)
+ {
+ /* Fake a reparentNotify event as SWT/Motif expects a
+ Window Manager to reparent a top-level window when
+ it is mapped and waits until they do.
+
+ We don't actually need to reparent, as the frame is
+ a native window, not an X window
+
+ We do this on MapNotify, not MapRequest like a real
+ Window Manager would, so we don't have do get involved
+ in actually mapping the window via it's (non-existent)
+ parent...
+
+ See sourceware bugzilla #9848
+ */
+
+ XWindowAttributes attr;
+ Window root;
+ Window parent;
+ Window *children;
+ unsigned int nchildren;
+
+ if (XGetWindowAttributes(event.xmap.display,
+ event.xmap.window,
+ &attr) &&
+ XQueryTree(event.xmap.display,
+ event.xmap.window,
+ &root, &parent, &children, &nchildren))
+ {
+ if (children) XFree(children);
+
+ /*
+ It's a top-level window if the parent window is a root window
+ Only non-override_redirect windows can get reparented
+ */
+ if ((attr.root == parent) && !event.xmap.override_redirect)
+ {
+ XEvent event_send;
+
+ event_send.type = ReparentNotify;
+ event_send.xreparent.event = event.xmap.window;
+ event_send.xreparent.window = event.xmap.window;
+ event_send.xreparent.parent = parent;
+ event_send.xreparent.x = attr.x;
+ event_send.xreparent.y = attr.y;
+
+ XSendEvent(event.xmap.display,
+ event.xmap.window,
+ True, StructureNotifyMask,
+ &event_send);
+ }
+ }
+ }
+ else if (event.type == PropertyNotify
+ && event.xproperty.atom == atmWmName)
+ {
+ memset (&msg, 0, sizeof (msg));
+
+ msg.msg = WM_WM_NAME_EVENT;
+ msg.iWindow = event.xproperty.window;
+
+ /* Other fields ignored */
+ winSendMessageToWM (pProcArg->pWMInfo, &msg);
+ }
+ else if (event.type == PropertyNotify
+ && event.xproperty.atom == atmWmHints)
+ {
+ memset (&msg, 0, sizeof (msg));
+
+ msg.msg = WM_WM_HINTS_EVENT;
+ msg.iWindow = event.xproperty.window;
+
+ /* Other fields ignored */
+ winSendMessageToWM (pProcArg->pWMInfo, &msg);
+ }
+ else if (event.type == ClientMessage
+ && event.xclient.message_type == atmWmChange
+ && event.xclient.data.l[0] == IconicState)
+ {
+ winDebug ("winMultiWindowXMsgProc - WM_CHANGE_STATE - IconicState\n");
+
+ memset (&msg, 0, sizeof (msg));
+
+ msg.msg = WM_WM_CHANGE_STATE;
+ msg.iWindow = event.xclient.window;
+
+ winSendMessageToWM (pProcArg->pWMInfo, &msg);
+ }
+ }
+
+ XCloseDisplay (pProcArg->pDisplay);
+ pthread_exit (NULL);
+ return NULL;
+}
+
+
+/*
+ * winInitWM - Entry point for the X server to spawn
+ * the Window Manager thread. Called from
+ * winscrinit.c/winFinishScreenInitFB ().
+ */
+
+Bool
+winInitWM (void **ppWMInfo,
+ pthread_t *ptWMProc,
+ pthread_t *ptXMsgProc,
+ pthread_mutex_t *ppmServerStarted,
+ int dwScreen,
+ HWND hwndScreen,
+ BOOL allowOtherWM)
+{
+ WMProcArgPtr pArg = (WMProcArgPtr) malloc (sizeof(WMProcArgRec));
+ WMInfoPtr pWMInfo = (WMInfoPtr) malloc (sizeof(WMInfoRec));
+ XMsgProcArgPtr pXMsgArg = (XMsgProcArgPtr) malloc (sizeof(XMsgProcArgRec));
+
+ /* Bail if the input parameters are bad */
+ if (pArg == NULL || pWMInfo == NULL)
+ {
+ ErrorF ("winInitWM - malloc failed.\n");
+ return FALSE;
+ }
+
+ /* Zero the allocated memory */
+ ZeroMemory (pArg, sizeof (WMProcArgRec));
+ ZeroMemory (pWMInfo, sizeof (WMInfoRec));
+ ZeroMemory (pXMsgArg, sizeof (XMsgProcArgRec));
+
+ /* Set a return pointer to the Window Manager info structure */
+ *ppWMInfo = pWMInfo;
+ pWMInfo->fAllowOtherWM = allowOtherWM;
+
+ /* Setup the argument structure for the thread function */
+ pArg->dwScreen = dwScreen;
+ pArg->pWMInfo = pWMInfo;
+ pArg->ppmServerStarted = ppmServerStarted;
+
+ /* Intialize the message queue */
+ if (!InitQueue (&pWMInfo->wmMsgQueue))
+ {
+ ErrorF ("winInitWM - InitQueue () failed.\n");
+ return FALSE;
+ }
+
+ /* Spawn a thread for the Window Manager */
+ if (pthread_create (ptWMProc, NULL, winMultiWindowWMProc, pArg))
+ {
+ /* Bail if thread creation failed */
+ ErrorF ("winInitWM - pthread_create failed for Window Manager.\n");
+ return FALSE;
+ }
+
+ /* Spawn the XNextEvent thread, will send messages to WM */
+ pXMsgArg->dwScreen = dwScreen;
+ pXMsgArg->pWMInfo = pWMInfo;
+ pXMsgArg->ppmServerStarted = ppmServerStarted;
+ pXMsgArg->hwndScreen = hwndScreen;
+ if (pthread_create (ptXMsgProc, NULL, winMultiWindowXMsgProc, pXMsgArg))
+ {
+ /* Bail if thread creation failed */
+ ErrorF ("winInitWM - pthread_create failed on XMSG.\n");
+ return FALSE;
+ }
+
+ winDebug ("winInitWM - Returning.\n");
+
+ return TRUE;
+}
+
+
+/*
+ * Window manager thread - setup
+ */
+
+static void
+winInitMultiWindowWM (WMInfoPtr pWMInfo, WMProcArgPtr pProcArg)
+{
+ int iRetries = 0;
+ char pszDisplay[512];
+ int iReturn;
+
+ winDebug ("winInitMultiWindowWM - Hello\n");
+
+ /* Check that argument pointer is not invalid */
+ if (pProcArg == NULL)
+ {
+ ErrorF ("winInitMultiWindowWM - pProcArg is NULL. Exiting.\n");
+ pthread_exit (NULL);
+ }
+
+ winDebug ("winInitMultiWindowWM - Calling pthread_mutex_lock ()\n");
+
+ /* Grab our garbage mutex to satisfy pthread_cond_wait */
+ iReturn = pthread_mutex_lock (pProcArg->ppmServerStarted);
+ if (iReturn != 0)
+ {
+ ErrorF ("winInitMultiWindowWM - pthread_mutex_lock () failed: %d. "
+ "Exiting.\n",
+ iReturn);
+ pthread_exit (NULL);
+ }
+
+ winDebug ("winInitMultiWindowWM - pthread_mutex_lock () returned.\n");
+
+ /* See if X supports the current locale */
+ if (XSupportsLocale () == False)
+ {
+ ErrorF ("winInitMultiWindowWM - Warning: Locale not supported by X.\n");
+ }
+
+ /* Release the server started mutex */
+ pthread_mutex_unlock (pProcArg->ppmServerStarted);
+
+ winDebug ("winInitMultiWindowWM - pthread_mutex_unlock () returned.\n");
+
+ /* Set jump point for IO Error exits */
+ iReturn = setjmp (g_jmpWMEntry);
+
+ /* Check if we should continue operations */
+ if (iReturn != WIN_JMP_ERROR_IO
+ && iReturn != WIN_JMP_OKAY)
+ {
+ /* setjmp returned an unknown value, exit */
+ ErrorF ("winInitMultiWindowWM - setjmp returned: %d. Exiting.\n",
+ iReturn);
+ pthread_exit (NULL);
+ }
+ else if (iReturn == WIN_JMP_ERROR_IO)
+ {
+ ErrorF ("winInitMultiWindowWM - Caught IO Error. Exiting.\n");
+ pthread_exit (NULL);
+ }
+
+ /* Install our error handler */
+ XSetErrorHandler (winMultiWindowWMErrorHandler);
+ XSetIOErrorHandler (winMultiWindowWMIOErrorHandler);
+
+ /* Setup the display connection string x */
+ winGetDisplayName(pszDisplay, (int)pProcArg->dwScreen);
+
+ /* Print the display connection string */
+ winDebug ("winInitMultiWindowWM - DISPLAY=%s\n", pszDisplay);
+
+ /* Use our generated cookie for authentication */
+ winSetAuthorization();
+
+ /* Open the X display */
+ do
+ {
+ /* Try to open the display */
+ pWMInfo->pDisplay = XOpenDisplay (pszDisplay);
+ if (pWMInfo->pDisplay == NULL)
+ {
+ ErrorF ("winInitMultiWindowWM - Could not open display, try: %d, "
+ "sleeping: %d\n\f",
+ iRetries + 1, WIN_CONNECT_DELAY);
+ ++iRetries;
+ sleep (WIN_CONNECT_DELAY);
+ continue;
+ }
+ else
+ break;
+ }
+ while (pWMInfo->pDisplay == NULL && iRetries < WIN_CONNECT_RETRIES);
+
+ /* Make sure that the display opened */
+ if (pWMInfo->pDisplay == NULL)
+ {
+ ErrorF ("winInitMultiWindowWM - Failed opening the display. "
+ "Exiting.\n");
+ pthread_exit (NULL);
+ }
+
+ winDebug ("winInitMultiWindowWM - XOpenDisplay () returned and "
+ "successfully opened the display.\n");
+
+
+ /* Create some atoms */
+ pWMInfo->atmWmProtos = XInternAtom (pWMInfo->pDisplay,
+ "WM_PROTOCOLS",
+ False);
+ pWMInfo->atmWmDelete = XInternAtom (pWMInfo->pDisplay,
+ "WM_DELETE_WINDOW",
+ False);
+
+ pWMInfo->atmPrivMap = XInternAtom (pWMInfo->pDisplay,
+ WINDOWSWM_NATIVE_HWND,
+ False);
+
+
+ if (1) {
+ Cursor cursor = XCreateFontCursor (pWMInfo->pDisplay, XC_left_ptr);
+ if (cursor)
+ {
+ XDefineCursor (pWMInfo->pDisplay, DefaultRootWindow(pWMInfo->pDisplay), cursor);
+ XFreeCursor (pWMInfo->pDisplay, cursor);
+ }
+ }
+}
+
+
+/*
+ * winSendMessageToWM - Send a message from the X thread to the WM thread
+ */
+
+void
+winSendMessageToWM (void *pWMInfo, winWMMessagePtr pMsg)
+{
+ WMMsgNodePtr pNode;
+
+ winDebug ("winSendMessageToWM ()\n");
+
+ pNode = (WMMsgNodePtr)malloc(sizeof(WMMsgNodeRec));
+ if (pNode != NULL)
+ {
+ memcpy (&pNode->msg, pMsg, sizeof(winWMMessageRec));
+ PushMessage (&((WMInfoPtr)pWMInfo)->wmMsgQueue, pNode);
+ }
+}
+
+
+/*
+ * Window manager error handler
+ */
+
+static int
+winMultiWindowWMErrorHandler (Display *pDisplay, XErrorEvent *pErr)
+{
+ char pszErrorMsg[100];
+
+ if (pErr->request_code == X_ChangeWindowAttributes
+ && pErr->error_code == BadAccess)
+ {
+ ErrorF ("winMultiWindowWMErrorHandler - ChangeWindowAttributes "
+ "BadAccess.\n");
+ return 0;
+ }
+
+ XGetErrorText (pDisplay,
+ pErr->error_code,
+ pszErrorMsg,
+ sizeof (pszErrorMsg));
+ ErrorF ("winMultiWindowWMErrorHandler - ERROR: %s\n"
+ " errorCode %d\n"
+ " serial %d\n"
+ " resourceID 0x%x\n"
+ " majorCode %d\n"
+ " minorCode %d\n"
+ , pszErrorMsg
+ , pErr->error_code
+ , pErr->serial
+ , pErr->resourceid
+ , pErr->request_code
+ , pErr->minor_code);
+
+ return 0;
+}
+
+
+/*
+ * Window manager IO error handler
+ */
+
+static int
+winMultiWindowWMIOErrorHandler (Display *pDisplay)
+{
+ ErrorF ("\nwinMultiWindowWMIOErrorHandler!\n\n");
+
+ if (g_shutdown)
+ pthread_exit(NULL);
+
+ /* Restart at the main entry point */
+ longjmp (g_jmpWMEntry, WIN_JMP_ERROR_IO);
+
+ return 0;
+}
+
+
+/*
+ * X message procedure error handler
+ */
+
+static int
+winMultiWindowXMsgProcErrorHandler (Display *pDisplay, XErrorEvent *pErr)
+{
+ char pszErrorMsg[100];
+
+ XGetErrorText (pDisplay,
+ pErr->error_code,
+ pszErrorMsg,
+ sizeof (pszErrorMsg));
+ ErrorF ("winMultiWindowXMsgProcErrorHandler - ERROR: %s\n"
+ " errorCode %d\n"
+ " serial %d\n"
+ " resourceID 0x%x\n"
+ " majorCode %d\n"
+ " minorCode %d\n"
+ , pszErrorMsg
+ , pErr->error_code
+ , pErr->serial
+ , pErr->resourceid
+ , pErr->request_code
+ , pErr->minor_code);
+
+ return 0;
+}
+
+
+/*
+ * X message procedure IO error handler
+ */
+
+static int
+winMultiWindowXMsgProcIOErrorHandler (Display *pDisplay)
+{
+ ErrorF ("\nwinMultiWindowXMsgProcIOErrorHandler!\n\n");
+
+ /* Restart at the main entry point */
+ longjmp (g_jmpXMsgProcEntry, WIN_JMP_ERROR_IO);
+
+ return 0;
+}
+
+
+/*
+ * Catch RedirectError to detect other window manager running
+ */
+
+static int
+winRedirectErrorHandler (Display *pDisplay, XErrorEvent *pErr)
+{
+ redirectError = TRUE;
+ return 0;
+}
+
+
+/*
+ * Check if another window manager is running
+ */
+
+static Bool
+CheckAnotherWindowManager (Display *pDisplay, DWORD dwScreen, Bool fAllowOtherWM)
+{
+ /*
+ Try to select the events which only one client at a time is allowed to select.
+ If this causes an error, another window manager is already running...
+ */
+ redirectError = FALSE;
+ XSetErrorHandler (winRedirectErrorHandler);
+ XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen),
+ ResizeRedirectMask | SubstructureRedirectMask | ButtonPressMask);
+ XSync (pDisplay, 0);
+ XSetErrorHandler (winMultiWindowXMsgProcErrorHandler);
+
+ /*
+ Side effect: select the events we are actually interested in...
+
+ If other WMs are not allowed, also select one of the events which only one client
+ at a time is allowed to select, so other window managers won't start...
+ */
+ XSelectInput(pDisplay, RootWindow (pDisplay, dwScreen),
+ SubstructureNotifyMask | ( !fAllowOtherWM ? ButtonPressMask : 0));
+ XSync (pDisplay, 0);
+ return redirectError;
+}
+
+/*
+ * Notify the MWM thread we're exiting and not to reconnect
+ */
+
+void
+winDeinitMultiWindowWM (void)
+{
+ winDebug ("winDeinitMultiWindowWM - Noting shutdown in progress\n");
+ g_shutdown = TRUE;
+}
+
+/* Windows window styles */
+#define HINT_NOFRAME (1l<<0)
+#define HINT_BORDER (1L<<1)
+#define HINT_SIZEBOX (1l<<2)
+#define HINT_CAPTION (1l<<3)
+#define HINT_NOMAXIMIZE (1L<<4)
+/* These two are used on their own */
+#define HINT_MAX (1L<<0)
+#define HINT_MIN (1L<<1)
+
+static void
+winApplyHints (Display *pDisplay, Window iWindow, HWND hWnd, HWND *zstyle)
+{
+ static Atom windowState, motif_wm_hints, windowType;
+ static Atom hiddenState, fullscreenState, belowState, aboveState;
+ static Atom dockWindow;
+ static int generation;
+ Atom type, *pAtom = NULL;
+ int format;
+ unsigned long hint = 0, maxmin = 0, style, nitems = 0 , left = 0;
+ WindowPtr pWin = GetProp (hWnd, WIN_WINDOW_PROP);
+ MwmHints *mwm_hint = NULL;
+ WinXSizeHints SizeHints;
+
+ if (!hWnd) return;
+ if (!IsWindow (hWnd)) return;
+
+ if (generation != serverGeneration) {
+ generation = serverGeneration;
+ windowState = XInternAtom(pDisplay, "_NET_WM_STATE", False);
+ motif_wm_hints = XInternAtom(pDisplay, "_MOTIF_WM_HINTS", False);
+ windowType = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE", False);
+ hiddenState = XInternAtom(pDisplay, "_NET_WM_STATE_HIDDEN", False);
+ fullscreenState = XInternAtom(pDisplay, "_NET_WM_STATE_FULLSCREEN", False);
+ belowState = XInternAtom(pDisplay, "_NET_WM_STATE_BELOW", False);
+ aboveState = XInternAtom(pDisplay, "_NET_WM_STATE_ABOVE", False);
+ dockWindow = XInternAtom(pDisplay, "_NET_WM_WINDOW_TYPE_DOCK", False);
+ }
+
+ if (XGetWindowProperty(pDisplay, iWindow, windowState, 0L,
+ 1L, False, XA_ATOM, &type, &format,
+ &nitems, &left, (unsigned char **)&pAtom) == Success)
+ {
+ if (pAtom && nitems == 1)
+ {
+ if (*pAtom == hiddenState) maxmin |= HINT_MIN;
+ else if (*pAtom == fullscreenState) maxmin |= HINT_MAX;
+ if (*pAtom == belowState) *zstyle = HWND_BOTTOM;
+ else if (*pAtom == aboveState) *zstyle = HWND_TOPMOST;
+ }
+ if (pAtom) XFree(pAtom);
+ }
+
+ nitems = left = 0;
+ if (XGetWindowProperty(pDisplay, iWindow, motif_wm_hints, 0L,
+ PropMwmHintsElements, False, motif_wm_hints, &type, &format,
+ &nitems, &left, (unsigned char **)&mwm_hint) == Success)
+ {
+ if (mwm_hint && nitems == PropMwmHintsElements && (mwm_hint->flags & MwmHintsDecorations))
+ {
+ if (!mwm_hint->decorations) hint |= HINT_NOFRAME;
+ else if (!(mwm_hint->decorations & MwmDecorAll))
+ {
+ if (mwm_hint->decorations & MwmDecorBorder) hint |= HINT_BORDER;
+ if (mwm_hint->decorations & MwmDecorTitle) hint |= HINT_CAPTION;
+ }
+ }
+ if (mwm_hint) XFree(mwm_hint);
+ }
+
+ nitems = left = 0;
+ pAtom = NULL;
+ if (XGetWindowProperty(pDisplay, iWindow, windowType, 0L,
+ 1L, False, XA_ATOM, &type, &format,
+ &nitems, &left, (unsigned char **)&pAtom) == Success)
+ {
+ if (pAtom && nitems == 1)
+ {
+ if (*pAtom == dockWindow)
+ {
+ hint = (hint & ~HINT_NOFRAME); /* Xming puts a sizebox on dock windows */
+ *zstyle = HWND_TOPMOST;
+ }
+ }
+ if (pAtom) XFree(pAtom);
+ }
+
+ {
+ XSizeHints *normal_hint = XAllocSizeHints();
+ long supplied;
+ if (normal_hint && (XGetWMNormalHints(pDisplay, iWindow, normal_hint, &supplied) == Success))
+ {
+ if (normal_hint->flags & PMaxSize)
+ {
+ /* Not maximizable if a maximum size is specified */
+ hint |= HINT_NOMAXIMIZE;
+
+ if (normal_hint->flags & PMinSize)
+ {
+ /*
+ If both minimum size and maximum size are specified and are the same,
+ don't bother with a resizing frame
+ */
+ if ((normal_hint->min_width == normal_hint->max_width)
+ && (normal_hint->min_height == normal_hint->max_height))
+ hint = (hint & ~HINT_SIZEBOX);
+ }
+ }
+ }
+ XFree(normal_hint);
+ }
+
+ /* Override hint settings from above with settings from config file */
+ style = winOverrideStyle((unsigned long)pWin);
+ if (style & STYLE_TOPMOST) *zstyle = HWND_TOPMOST;
+ else if (style & STYLE_MAXIMIZE) maxmin = (hint & ~HINT_MIN) | HINT_MAX;
+ else if (style & STYLE_MINIMIZE) maxmin = (hint & ~HINT_MAX) | HINT_MIN;
+ else if (style & STYLE_BOTTOM) *zstyle = HWND_BOTTOM;
+
+ if (maxmin & HINT_MAX) SendMessage(hWnd, WM_SYSCOMMAND, SC_MAXIMIZE, 0);
+ else if (maxmin & HINT_MIN) SendMessage(hWnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
+
+ if (style & STYLE_NOTITLE)
+ hint = (hint & ~HINT_NOFRAME & ~HINT_BORDER & ~HINT_CAPTION);
+ else if (style & STYLE_OUTLINE)
+ hint = (hint & ~HINT_NOFRAME & ~HINT_CAPTION) | HINT_BORDER;
+ else if (style & STYLE_NOFRAME)
+ hint = (hint & ~HINT_BORDER & ~HINT_CAPTION) | HINT_NOFRAME;
+
+ /* Now apply styles to window */
+ style = GetWindowLongPtr(hWnd, GWL_STYLE) & ~WS_CAPTION & ~WS_SIZEBOX; /* Just in case */
+ if (!hint) /* All on, but no resize of children is allowed */
+ style = style | WS_CAPTION;
+ else if (hint & HINT_NOFRAME) /* All off */
+ style = style & ~WS_CAPTION & ~WS_SIZEBOX;
+ else style = style | ((hint & HINT_BORDER) ? WS_BORDER : 0) |
+ ((hint & HINT_SIZEBOX) ? WS_SIZEBOX : 0) |
+ ((hint & HINT_CAPTION) ? WS_CAPTION : 0);
+
+ if (hint & HINT_NOMAXIMIZE)
+ style = style & ~WS_MAXIMIZEBOX;
+
+
+ if (winMultiWindowGetWMNormalHints(pWin, &SizeHints))
+ {
+ if (!((SizeHints.min_width == SizeHints.max_width)&&(SizeHints.min_height == SizeHints.max_height) ))
+ style|=WS_SIZEBOX;
+ }
+ else
+ style|=WS_SIZEBOX;
+ SetWindowLongPtr (hWnd, GWL_STYLE, style);
+}
+
+void
+winUpdateWindowPosition (HWND hWnd, Bool reshape, HWND *zstyle)
+{
+ int iX, iY, iWidth, iHeight;
+ int iDx, iDy;
+ RECT rcNew;
+ WindowPtr pWin = GetProp (hWnd, WIN_WINDOW_PROP);
+ DrawablePtr pDraw = NULL;
+
+ if (!pWin) return;
+ pDraw = &pWin->drawable;
+ if (!pDraw) return;
+
+ /* Get the X and Y location of the X window */
+ iX = pWin->drawable.x + GetSystemMetrics (SM_XVIRTUALSCREEN);
+ iY = pWin->drawable.y + GetSystemMetrics (SM_YVIRTUALSCREEN);
+
+ /* Get the height and width of the X window */
+ iWidth = pWin->drawable.width;
+ iHeight = pWin->drawable.height;
+
+ /* Setup a rectangle with the X window position and size */
+ SetRect (&rcNew, iX, iY, iX + iWidth, iY + iHeight);
+
+ AdjustWindowRectEx (&rcNew, GetWindowLongPtr (hWnd, GWL_STYLE), FALSE, WS_EX_APPWINDOW);
+
+ /* Don't allow window decoration to disappear off to top-left as a result of this adjustment */
+ if (rcNew.left < GetSystemMetrics(SM_XVIRTUALSCREEN))
+ {
+ iDx = GetSystemMetrics(SM_XVIRTUALSCREEN) - rcNew.left;
+ rcNew.left += iDx;
+ rcNew.right += iDx;
+ }
+
+ if (rcNew.top < GetSystemMetrics(SM_YVIRTUALSCREEN))
+ {
+ iDy = GetSystemMetrics(SM_YVIRTUALSCREEN) - rcNew.top;
+ rcNew.top += iDy;
+ rcNew.bottom += iDy;
+ }
+
+ /* Position the Windows window */
+ SetWindowPos (hWnd, *zstyle, rcNew.left, rcNew.top,
+ rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
+ 0);
+
+ if (reshape)
+ {
+ winReshapeMultiWindow(pWin);
+ winUpdateRgnMultiWindow(pWin);
+ }
+}
diff --git a/xorg-server/hw/xwin/winmultiwindowwndproc.c b/xorg-server/hw/xwin/winmultiwindowwndproc.c index d14ceee9c..ef5f3114a 100644 --- a/xorg-server/hw/xwin/winmultiwindowwndproc.c +++ b/xorg-server/hw/xwin/winmultiwindowwndproc.c @@ -42,6 +42,13 @@ #include "winmsg.h" #include "inputstr.h" +#ifdef XKB +#ifndef XKB_IN_SERVER +#define XKB_IN_SERVER +#endif +#include <xkbsrv.h> +#endif + /* * External global variables */ @@ -331,9 +338,7 @@ winTopLevelWindowProc (HWND hwnd, UINT message, Bool needRestack = FALSE; LRESULT ret; -#if CYGDEBUG winDebugWin32Message("winTopLevelWindowProc", hwnd, message, wParam, lParam); -#endif /* Check if the Windows window property for our X window pointer is valid */ if ((pWin = GetProp (hwnd, WIN_WINDOW_PROP)) != NULL) @@ -366,31 +371,6 @@ winTopLevelWindowProc (HWND hwnd, UINT message, fWMMsgInitialized = TRUE; -#if 0 - /* - * Print some debugging information - */ - - ErrorF ("hWnd %08X\n", hwnd); - ErrorF ("pWin %08X\n", pWin); - ErrorF ("pDraw %08X\n", pDraw); - ErrorF ("\ttype %08X\n", pWin->drawable.type); - ErrorF ("\tclass %08X\n", pWin->drawable.class); - ErrorF ("\tdepth %08X\n", pWin->drawable.depth); - ErrorF ("\tbitsPerPixel %08X\n", pWin->drawable.bitsPerPixel); - ErrorF ("\tid %08X\n", pWin->drawable.id); - ErrorF ("\tx %08X\n", pWin->drawable.x); - ErrorF ("\ty %08X\n", pWin->drawable.y); - ErrorF ("\twidth %08X\n", pWin->drawable.width); - ErrorF ("\thenght %08X\n", pWin->drawable.height); - ErrorF ("\tpScreen %08X\n", pWin->drawable.pScreen); - ErrorF ("\tserialNumber %08X\n", pWin->drawable.serialNumber); - ErrorF ("g_iWindowPrivateKey %p\n", g_iWindowPrivateKey); - ErrorF ("pWinPriv %08X\n", pWinPriv); - ErrorF ("s_pScreenPriv %08X\n", s_pScreenPriv); - ErrorF ("s_pScreenInfo %08X\n", s_pScreenInfo); - ErrorF ("hwndScreen %08X\n", hwndScreen); -#endif } /* Branch on message type */ @@ -425,7 +405,7 @@ winTopLevelWindowProc (HWND hwnd, UINT message, DeleteObject(hRgnWindow); } - SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)XMING_SIGNATURE); + SetWindowLongPtr(hwnd, GWLP_USERDATA, (LONG_PTR)VCXSRV_SIGNATURE); return 0; @@ -741,7 +721,7 @@ winTopLevelWindowProc (HWND hwnd, UINT message, if (wParam == VK_F4 && (GetKeyState (VK_MENU) & 0x8000)) break; -#if CYGWINDOWING_DEBUG +#ifdef WINDBG if (wParam == VK_ESCAPE) { /* Place for debug: put any tests and dumps here */ @@ -752,27 +732,27 @@ winTopLevelWindowProc (HWND hwnd, UINT message, windPlace.length = sizeof (WINDOWPLACEMENT); GetWindowPlacement (hwnd, &windPlace); pRect = &windPlace.rcNormalPosition; - ErrorF ("\nCYGWINDOWING Dump:\n" + winDebug ("\nCYGWINDOWING Dump:\n" "\tdrawable: (%hd, %hd) - %hdx%hd\n", pDraw->x, pDraw->y, pDraw->width, pDraw->height); - ErrorF ("\twindPlace: (%ld, %ld) - %ldx%ld\n", pRect->left, + winDebug ("\twindPlace: (%ld, %ld) - %ldx%ld\n", pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top); if (GetClientRect (hwnd, &rc)) { pRect = &rc; - ErrorF ("\tClientRect: (%ld, %ld) - %ldx%ld\n", pRect->left, + winDebug ("\tClientRect: (%ld, %ld) - %ldx%ld\n", pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top); } if (GetWindowRect (hwnd, &rc)) { pRect = &rc; - ErrorF ("\tWindowRect: (%ld, %ld) - %ldx%ld\n", pRect->left, + winDebug ("\tWindowRect: (%ld, %ld) - %ldx%ld\n", pRect->left, pRect->top, pRect->right - pRect->left, pRect->bottom - pRect->top); } - ErrorF ("\n"); + winDebug ("\n"); } #endif @@ -847,7 +827,7 @@ winTopLevelWindowProc (HWND hwnd, UINT message, /* Branch on if the window was killed in X already */ if (pWinPriv && !pWinPriv->fXKilled) { - ErrorF ("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n"); + winDebug ("winTopLevelWindowProc - WM_DESTROY - WM_WM_KILL\n"); /* Tell our Window Manager thread to kill the window */ wmMsg.msg = WM_WM_KILL; @@ -900,12 +880,10 @@ winTopLevelWindowProc (HWND hwnd, UINT message, else /* It is an overridden window so make it top of Z stack */ { HWND forHwnd = GetForegroundWindow(); -#if CYGWINDOWING_DEBUG - ErrorF ("overridden window is shown\n"); -#endif + winDebug ("overridden window is shown\n"); if (forHwnd != NULL) { - if (GetWindowLongPtr(forHwnd, GWLP_USERDATA) & (LONG_PTR)XMING_SIGNATURE) + if (GetWindowLongPtr(forHwnd, GWLP_USERDATA) & (LONG_PTR)VCXSRV_SIGNATURE) { if (GetWindowLongPtr(forHwnd, GWL_EXSTYLE) & WS_EX_TOPMOST) SetWindowPos (hwnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); @@ -991,7 +969,7 @@ winTopLevelWindowProc (HWND hwnd, UINT message, case WM_SIZE: /* see dix/window.c */ -#if CYGWINDOWING_DEBUG +#ifdef WINDBG { char buf[64]; switch (wParam) @@ -1008,24 +986,34 @@ winTopLevelWindowProc (HWND hwnd, UINT message, default: strcpy(buf, "UNKNOWN_FLAG"); } - ErrorF ("winTopLevelWindowProc - WM_SIZE to %dx%d (%s) - %d ms\n", + winDebug ("winTopLevelWindowProc - WM_SIZE to %dx%d (%s) - %d ms\n", (int)LOWORD(lParam), (int)HIWORD(lParam), buf, (int)(GetTickCount ())); } #endif /* Adjust the X Window to the moved Windows window */ winAdjustXWindow (pWin, hwnd); + if (wParam == SIZE_MINIMIZED) winReorderWindowsMultiWindow(); return 0; /* end of WM_SIZE handler */ + case WM_STYLECHANGED: + /* when the style changes, adjust the window size so the client area remains the same */ + { + LONG x,y; + DrawablePtr pDraw = &pWin->drawable; + x = pDraw->x - wBorderWidth(pWin); + y = pDraw->y - wBorderWidth(pWin); + winPositionWindowMultiWindow(pWin, x, y); + } + return 0; + case WM_MOUSEACTIVATE: /* Check if this window needs to be made active when clicked */ if (!GetProp (pWinPriv->hWnd, WIN_NEEDMANAGE_PROP)) { -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winTopLevelWindowProc - WM_MOUSEACTIVATE - " + winDebug ("winTopLevelWindowProc - WM_MOUSEACTIVATE - " "MA_NOACTIVATE\n"); -#endif /* */ return MA_NOACTIVATE; diff --git a/xorg-server/hw/xwin/winnativegdi.c b/xorg-server/hw/xwin/winnativegdi.c index 48a467a2c..7b4f7e0e4 100644 --- a/xorg-server/hw/xwin/winnativegdi.c +++ b/xorg-server/hw/xwin/winnativegdi.c @@ -111,7 +111,7 @@ winCloseScreenNativeGDI (int nIndex, ScreenPtr pScreen) winScreenPriv(pScreen); winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - ErrorF ("winCloseScreenNativeGDI - Freeing screen resources\n"); + winDebug ("winCloseScreenNativeGDI - Freeing screen resources\n"); /* Flag that the screen is closed */ pScreenPriv->fClosed = TRUE; @@ -125,7 +125,7 @@ winCloseScreenNativeGDI (int nIndex, ScreenPtr pScreen) /* Delete the window property */ RemoveProp (pScreenPriv->hwndScreen, WIN_SCR_PROP); - ErrorF ("winCloseScreenNativeGDI - Destroying window\n"); + winDebug ("winCloseScreenNativeGDI - Destroying window\n"); /* Delete tray icon, if we have one */ if (!pScreenInfo->fNoTrayIcon) @@ -151,7 +151,7 @@ winCloseScreenNativeGDI (int nIndex, ScreenPtr pScreen) /* Free the screen privates for this screen */ free (pScreenPriv); - ErrorF ("winCloseScreenNativeGDI - Returning\n"); + winDebug ("winCloseScreenNativeGDI - Returning\n"); return TRUE; } @@ -210,7 +210,7 @@ winInitVisualsNativeGDI (ScreenPtr pScreen) } /* Tell the user how many bits per RGB we are using */ - ErrorF ("winInitVisualsNativeGDI - Using dwBitsPerRGB: %d\n", + winDebug ("winInitVisualsNativeGDI - Using dwBitsPerRGB: %d\n", (int) pScreenPriv->dwBitsPerRGB); /* Create a single visual according to the Windows screen depth */ @@ -233,7 +233,7 @@ winInitVisualsNativeGDI (ScreenPtr pScreen) break; case 8: - ErrorF ("winInitVisuals - Calling miSetVisualTypesAndMasks\n"); + winDebug ("winInitVisuals - Calling miSetVisualTypesAndMasks\n"); if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, StaticColorMask, pScreenPriv->dwBitsPerRGB, @@ -252,9 +252,7 @@ winInitVisualsNativeGDI (ScreenPtr pScreen) return FALSE; } -#if 1 - ErrorF ("winInitVisualsNativeGDI - Returning\n"); -#endif + winDebug ("winInitVisualsNativeGDI - Returning\n"); return TRUE; } @@ -300,7 +298,7 @@ winAdjustVideoModeNativeGDI (ScreenPtr pScreen) if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) { /* No -depth parameter passed, let the user know the depth being used */ - ErrorF ("winAdjustVideoModeNativeGDI - Using Windows display " + winDebug ("winAdjustVideoModeNativeGDI - Using Windows display " "depth of %d bits per pixel, %d depth\n", (int) dwBPP, (int) pScreenInfo->dwDepth); @@ -310,7 +308,7 @@ winAdjustVideoModeNativeGDI (ScreenPtr pScreen) else if (dwBPP != pScreenInfo->dwBPP) { /* Warn user if GDI depth is different than -depth parameter */ - ErrorF ("winAdjustVideoModeNativeGDI - Command line bpp: %d, "\ + winDebug ("winAdjustVideoModeNativeGDI - Command line bpp: %d, "\ "using bpp: %d\n", (int) pScreenInfo->dwBPP, (int) dwBPP); @@ -400,11 +398,13 @@ winCreateDIBNativeGDI (int iWidth, int iHeight, int iDepth, pbmih->biPlanes = 1; pbmih->biBitCount = iDepth; pbmih->biCompression = BI_RGB; + /* pbmih->biSizeImage = 0; pbmih->biXPelsPerMeter = 0; pbmih->biYPelsPerMeter = 0; pbmih->biClrUsed = 0; pbmih->biClrImportant = 0; + */ /* Setup color table for mono DIBs */ if (iDepth == 1) diff --git a/xorg-server/hw/xwin/winpfbdd.c b/xorg-server/hw/xwin/winpfbdd.c index 13fc1058d..6c0c2bffd 100644 --- a/xorg-server/hw/xwin/winpfbdd.c +++ b/xorg-server/hw/xwin/winpfbdd.c @@ -83,7 +83,7 @@ winAllocateFBPrimaryDD (ScreenPtr pScreen) DDSURFACEDESC *pddsdOffscreen = NULL; RECT rcClient; - ErrorF ("winAllocateFBPrimaryDD\n"); + winDebug ("winAllocateFBPrimaryDD\n"); /* Get client area location in screen coords */ GetClientRect (pScreenPriv->hwndScreen, &rcClient); @@ -108,7 +108,7 @@ winAllocateFBPrimaryDD (ScreenPtr pScreen) } - ErrorF ("winAllocateFBPrimaryDD - Created and initialized DD\n"); + winDebug ("winAllocateFBPrimaryDD - Created and initialized DD\n"); /* Are we windowed or fullscreen? */ if (pScreenInfo->fFullScreen) @@ -159,7 +159,7 @@ winAllocateFBPrimaryDD (ScreenPtr pScreen) FatalError ("winAllocateFBPrimaryDD - Could not create primary " "surface %08x\n", (unsigned int) ddrval); - ErrorF ("winAllocateFBPrimaryDD - Created primary\n"); + winDebug ("winAllocateFBPrimaryDD - Created primary\n"); /* Allocate a DD surface description for our screen privates */ pddsdPrimary = pScreenPriv->pddsdPrimary @@ -195,7 +195,7 @@ winAllocateFBPrimaryDD (ScreenPtr pScreen) FatalError ("winAllocateFBPrimaryDD - Could not create shadow " "surface\n"); - ErrorF ("winAllocateFBPrimaryDD - Created offscreen\n"); + winDebug ("winAllocateFBPrimaryDD - Created offscreen\n"); /* Allocate a DD surface description for our screen privates */ pddsdOffscreen = pScreenPriv->pddsdOffscreen @@ -206,7 +206,7 @@ winAllocateFBPrimaryDD (ScreenPtr pScreen) ZeroMemory (pddsdOffscreen, sizeof (*pddsdOffscreen)); pddsdOffscreen->dwSize = sizeof (*pddsdOffscreen); - ErrorF ("winAllocateFBPrimaryDD - Locking primary\n"); + winDebug ("winAllocateFBPrimaryDD - Locking primary\n"); /* Lock the primary surface */ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsPrimary, @@ -218,7 +218,7 @@ winAllocateFBPrimaryDD (ScreenPtr pScreen) FatalError ("winAllocateFBPrimaryDD - Could not lock " "primary surface\n"); - ErrorF ("winAllocateFBPrimaryDD - Locked primary\n"); + winDebug ("winAllocateFBPrimaryDD - Locked primary\n"); /* We don't know how to deal with anything other than RGB */ if (!(pddsdPrimary->ddpfPixelFormat.dwFlags & DDPF_RGB)) @@ -236,7 +236,7 @@ winAllocateFBPrimaryDD (ScreenPtr pScreen) pScreenPriv->dwGreenMask = pddsdPrimary->ddpfPixelFormat.u3.dwGBitMask; pScreenPriv->dwBlueMask = pddsdPrimary->ddpfPixelFormat.u4.dwBBitMask; - ErrorF ("winAllocateFBPrimaryDD - Returning\n"); + winDebug ("winAllocateFBPrimaryDD - Returning\n"); return TRUE; } @@ -255,7 +255,7 @@ winCloseScreenPrimaryDD (int nIndex, ScreenPtr pScreen) winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; Bool fReturn; - ErrorF ("winCloseScreenPrimaryDD - Freeing screen resources\n"); + winDebug ("winCloseScreenPrimaryDD - Freeing screen resources\n"); /* Flag that the screen is closed */ pScreenPriv->fClosed = TRUE; @@ -351,7 +351,7 @@ winInitVisualsPrimaryDD (ScreenPtr pScreen) else pScreenPriv->dwBitsPerRGB = dwBlueBits; - ErrorF ("winInitVisualsPrimaryDD - Masks: %08x %08x %08x bpRGB: %d\n", + winDebug ("winInitVisualsPrimaryDD - Masks: %08x %08x %08x bpRGB: %d\n", (unsigned int) pScreenPriv->dwRedMask, (unsigned int) pScreenPriv->dwGreenMask, (unsigned int) pScreenPriv->dwBlueMask, @@ -378,9 +378,7 @@ winInitVisualsPrimaryDD (ScreenPtr pScreen) break; case 8: -#if CYGDEBUG winDebug ("winInitVisuals - Calling miSetVisualTypesAndMasks\n"); -#endif /* CYGDEBUG */ if (!miSetVisualTypesAndMasks (pScreenInfo->dwDepth, PseudoColorMask, pScreenPriv->dwBitsPerRGB, @@ -393,10 +391,8 @@ winInitVisualsPrimaryDD (ScreenPtr pScreen) "miSetVisualTypesAndMasks failed\n"); return FALSE; } -#if CYGDEBUG winDebug ("winInitVisualsPrimaryDD - Returned from " "miSetVisualTypesAndMasks\n"); -#endif /* CYGDEBUG */ break; default: @@ -404,7 +400,7 @@ winInitVisualsPrimaryDD (ScreenPtr pScreen) return FALSE; } - ErrorF ("winInitVisualsPrimaryDD - Returning\n"); + winDebug ("winInitVisualsPrimaryDD - Returning\n"); return TRUE; } @@ -433,7 +429,7 @@ winAdjustVideoModePrimaryDD (ScreenPtr pScreen) if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) { /* No -depth parameter passed, let the user know the depth being used */ - ErrorF ("winAdjustVideoModePrimaryDD - Using Windows display " + winDebug ("winAdjustVideoModePrimaryDD - Using Windows display " "depth of %d bits per pixel\n", (int) dwBPP); /* Use GDI's depth */ @@ -443,13 +439,13 @@ winAdjustVideoModePrimaryDD (ScreenPtr pScreen) && pScreenInfo->dwBPP != dwBPP) { /* FullScreen, and GDI depth differs from -depth parameter */ - ErrorF ("winAdjustVideoModePrimaryDD - FullScreen, using command " + winDebug ("winAdjustVideoModePrimaryDD - FullScreen, using command " "line depth: %d\n", (int) pScreenInfo->dwBPP); } else if (dwBPP != pScreenInfo->dwBPP) { /* Windowed, and GDI depth differs from -depth parameter */ - ErrorF ("winAdjustVideoModePrimaryDD - Windowed, command line " + winDebug ("winAdjustVideoModePrimaryDD - Windowed, command line " "depth: %d, using depth: %d\n", (int) pScreenInfo->dwBPP, (int) dwBPP); @@ -567,7 +563,7 @@ winHotKeyAltTabPrimaryDD (ScreenPtr pScreen) RECT rcClient, rcSrc; HRESULT ddrval = DD_OK; - ErrorF ("\nwinHotKeyAltTabPrimaryDD\n\n"); + winDebug ("\nwinHotKeyAltTabPrimaryDD\n\n"); /* Alt+Tab was pressed, we will lose focus very soon */ pScreenPriv->fActive = FALSE; diff --git a/xorg-server/hw/xwin/winpixmap.c b/xorg-server/hw/xwin/winpixmap.c index 050c71a7f..e5b36a000 100644 --- a/xorg-server/hw/xwin/winpixmap.c +++ b/xorg-server/hw/xwin/winpixmap.c @@ -70,11 +70,9 @@ winCreatePixmapNativeGDI (ScreenPtr pScreen, 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; @@ -114,11 +112,9 @@ winCreatePixmapNativeGDI (ScreenPtr pScreen, &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; } @@ -135,9 +131,7 @@ 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) @@ -149,10 +143,8 @@ winDestroyPixmapNativeGDI (PixmapPtr pPixmap) /* 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; @@ -193,43 +185,3 @@ winModifyPixmapHeaderNativeGDI (PixmapPtr pPixmap, 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/hw/xwin/winpolyline.c b/xorg-server/hw/xwin/winpolyline.c index db9dd345b..bf98d73ec 100644 --- a/xorg-server/hw/xwin/winpolyline.c +++ b/xorg-server/hw/xwin/winpolyline.c @@ -45,7 +45,7 @@ winPolyLineNativeGDI (DrawablePtr pDrawable, { case LineSolid: if (pGC->lineWidth == 0) - return miZeroLine (pDrawable, pGC, mode, npt, ppt); + miZeroLine (pDrawable, pGC, mode, npt, ppt); else miWideLine (pDrawable, pGC, mode, npt, ppt); break; diff --git a/xorg-server/hw/xwin/winprefs.c b/xorg-server/hw/xwin/winprefs.c index 93901cac7..2472ea5aa 100644 --- a/xorg-server/hw/xwin/winprefs.c +++ b/xorg-server/hw/xwin/winprefs.c @@ -387,8 +387,8 @@ HandleCustomWM_COMMAND (unsigned long hwndIn, memset (&start, 0, sizeof (start)); start.cb = sizeof (start); - start.dwFlags = STARTF_USESHOWWINDOW; - start.wShowWindow = SW_HIDE; + //start.dwFlags = STARTF_USESHOWWINDOW; + //start.wShowWindow = SW_HIDE; memset (&child, 0, sizeof (child)); @@ -399,7 +399,7 @@ HandleCustomWM_COMMAND (unsigned long hwndIn, CloseHandle (child.hProcess); } else - MessageBox(NULL, m->menuItem[j].param, "Mingrc Exec Command Error!", MB_OK | MB_ICONEXCLAMATION); + MessageBox(NULL, m->menuItem[j].param, "VcXsrv Exec Command Error!", MB_OK | MB_ICONEXCLAMATION); } return TRUE; #endif @@ -753,7 +753,9 @@ LoadPreferences (void) prefFile = fopen (fname, "r"); if (prefFile) - ErrorF ("winPrefsLoadPreferences: %s\n", fname); + { + winDebug ("winPrefsLoadPreferences: %s\n", fname); + } } /* No home file found, check system default */ @@ -768,7 +770,9 @@ LoadPreferences (void) buffer[sizeof(buffer)-1] = 0; prefFile = fopen (buffer, "r"); if (prefFile) - ErrorF ("winPrefsLoadPreferences: %s\n", buffer); + { + winDebug ("winPrefsLoadPreferences: %s\n", buffer); + } } /* If we could open it, then read the settings and close it */ @@ -779,17 +783,16 @@ LoadPreferences (void) } /* Setup a DISPLAY environment variable, need to allocate on heap */ - /* because putenv doesn't copy the argument... */ - snprintf (szDisplay, 512, "DISPLAY=127.0.0.1:%s.0", display); - szEnvDisplay = (char *)(malloc (strlen(szDisplay)+1)); + /* because putenv doesn't copy the argument... Always use screen 0 */ + winGetDisplayName(szDisplay, 0); + szEnvDisplay = (char *)(malloc(strlen(szDisplay)+strlen("DISPLAY=")+1)); if (szEnvDisplay) { - strcpy (szEnvDisplay, szDisplay); + snprintf(szEnvDisplay, 512, "DISPLAY=%s", szDisplay); putenv (szEnvDisplay); } /* Replace any "%display%" in menu commands with display string */ - snprintf (szDisplay, 512, "127.0.0.1:%s.0", display); for (i=0; i<pref.menuItems; i++) { for (j=0; j<pref.menu[i].menuItems; j++) diff --git a/xorg-server/hw/xwin/winprefs.h b/xorg-server/hw/xwin/winprefs.h index 4daf47401..ccd771d72 100644 --- a/xorg-server/hw/xwin/winprefs.h +++ b/xorg-server/hw/xwin/winprefs.h @@ -1,189 +1,192 @@ -#if !defined(WINPREFS_H) -#define WINPREFS_H -/* - * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. - * Copyright (C) Colin Harrison 2005-2008 - * - * 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: Earle F. Philhower, III - * Colin Harrison - */ - -/* Need Bool */ -#include <X11/Xdefs.h> -/* Need TRUE */ -#include "misc.h" - -/* Need to know how long paths can be... */ -#include <limits.h> -/* Xwindows redefines PATH_MAX to at least 1024 */ -#include <X11/Xwindows.h> - -#ifndef NAME_MAX -#define NAME_MAX PATH_MAX -#endif -#define MENU_MAX 128 /* Maximum string length of a menu name or item */ -#define PARAM_MAX (4*PATH_MAX) /* Maximum length of a parameter to a MENU */ - - -/* Supported commands in a MENU {} statement */ -typedef enum MENUCOMMANDTYPE -{ - CMD_EXEC, /* /bin/sh -c the parameter */ - CMD_MENU, /* Display a popup menu named param */ - CMD_SEPARATOR, /* Menu separator */ - CMD_ALWAYSONTOP, /* Toggle always-on-top mode */ - CMD_RELOAD /* Reparse the .XWINRC file */ -} MENUCOMMANDTYPE; - -#define STYLE_NONE (0L) /* Dummy the first entry */ -#define STYLE_NOTITLE (1L) /* Force window style no titlebar */ -#define STYLE_OUTLINE (1L<<1) /* Force window style just thin-line border */ -#define STYLE_NOFRAME (1L<<2) /* Force window style no frame */ -#define STYLE_TOPMOST (1L<<3) /* Open a window always-on-top */ -#define STYLE_MAXIMIZE (1L<<4) /* Open a window maximized */ -#define STYLE_MINIMIZE (1L<<5) /* Open a window minimized */ -#define STYLE_BOTTOM (1L<<6) /* Open a window at the bottom of the Z order */ - -/* Where to place a system menu */ -typedef enum MENUPOSITION -{ - AT_START, /* Place menu at the top of the system menu */ - AT_END /* Put it at the bottom of the menu (default) */ -} MENUPOSITION; - -/* Menu item definitions */ -typedef struct MENUITEM -{ - char text[MENU_MAX+1]; /* To be displayed in menu */ - MENUCOMMANDTYPE cmd; /* What should it do? */ - char param[PARAM_MAX+1]; /* Any parameters? */ - unsigned long commandID; /* Windows WM_COMMAND ID assigned at runtime */ -} MENUITEM; - -/* A completely read in menu... */ -typedef struct MENUPARSED -{ - char menuName[MENU_MAX+1]; /* What's it called in the text? */ - MENUITEM *menuItem; /* Array of items */ - int menuItems; /* How big's the array? */ -} MENUPARSED; - -/* To map between a window and a system menu to add for it */ -typedef struct SYSMENUITEM -{ - char match[MENU_MAX+1]; /* String to look for to apply this sysmenu */ - char menuName[MENU_MAX+1]; /* Which menu to show? Used to set *menu */ - MENUPOSITION menuPos; /* Where to place it (ignored in root) */ -} SYSMENUITEM; - -/* To redefine icons for certain window types */ -typedef struct ICONITEM -{ - char match[MENU_MAX+1]; /* What string to search for? */ - char iconFile[PATH_MAX+NAME_MAX+2]; /* Icon location, WIN32 path */ - HICON hicon; /* LoadImage() result */ -} ICONITEM; - -/* To redefine styles for certain window types */ -typedef struct STYLEITEM -{ - char match[MENU_MAX+1]; /* What string to search for? */ - unsigned long type; /* What should it do? */ -} STYLEITEM; - -typedef struct WINPREFS -{ - /* Menu information */ - MENUPARSED *menu; /* Array of created menus */ - int menuItems; /* How big? */ - - /* Taskbar menu settings */ - char rootMenuName[MENU_MAX+1]; /* Menu for taskbar icon */ - - /* System menu addition menus */ - SYSMENUITEM *sysMenu; - int sysMenuItems; - - /* Which menu to add to unmatched windows? */ - char defaultSysMenuName[MENU_MAX+1]; - MENUPOSITION defaultSysMenuPos; /* Where to place it */ - - /* Icon information */ - char iconDirectory[PATH_MAX+1]; /* Where do the .icos lie? (Win32 path) */ - char defaultIconName[NAME_MAX+1]; /* Replacement for x.ico */ - char trayIconName[NAME_MAX+1]; /* Replacement for tray icon */ - - ICONITEM *icon; - int iconItems; - - STYLEITEM *style; - int styleItems; - - /* Force exit flag */ - Bool fForceExit; - - /* Silent exit flag */ - Bool fSilentExit; - -} WINPREFS; - - - - -/* Functions */ -void -LoadPreferences(void); - -void -SetupRootMenu (unsigned long hmenuRoot); - -void -SetupSysMenu (unsigned long hwndIn); - -void -HandleCustomWM_INITMENU(unsigned long hwndIn, - unsigned long hmenuIn); - -Bool -HandleCustomWM_COMMAND (unsigned long hwndIn, - int command); - -int -winIconIsOverride (unsigned hiconIn); - -HICON -winOverrideIcon (unsigned long longpWin); - -unsigned long -winOverrideStyle (unsigned long longpWin); - -HICON -winTaskbarIcon(void); - -HICON -winOverrideDefaultIcon(int size); -#endif +#if !defined(WINPREFS_H)
+#define WINPREFS_H
+/*
+ * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
+ * Copyright (C) Colin Harrison 2005-2008
+ *
+ * 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: Earle F. Philhower, III
+ * Colin Harrison
+ */
+
+/* Need Bool */
+#include <X11/Xdefs.h>
+/* Need TRUE */
+#include "misc.h"
+
+/* Need to know how long paths can be... */
+#include <limits.h>
+/* Xwindows redefines PATH_MAX to at least 1024 */
+#include <X11/Xwindows.h>
+
+#ifndef NAME_MAX
+#define NAME_MAX PATH_MAX
+#endif
+#define MENU_MAX 128 /* Maximum string length of a menu name or item */
+#define PARAM_MAX (4*PATH_MAX) /* Maximum length of a parameter to a MENU */
+
+
+/* Supported commands in a MENU {} statement */
+typedef enum MENUCOMMANDTYPE
+{
+ CMD_EXEC, /* /bin/sh -c the parameter */
+ CMD_MENU, /* Display a popup menu named param */
+ CMD_SEPARATOR, /* Menu separator */
+ CMD_ALWAYSONTOP, /* Toggle always-on-top mode */
+ CMD_RELOAD /* Reparse the .XWINRC file */
+} MENUCOMMANDTYPE;
+
+#define STYLE_NONE (0L) /* Dummy the first entry */
+#define STYLE_NOTITLE (1L) /* Force window style no titlebar */
+#define STYLE_OUTLINE (1L<<1) /* Force window style just thin-line border */
+#define STYLE_NOFRAME (1L<<2) /* Force window style no frame */
+#define STYLE_TOPMOST (1L<<3) /* Open a window always-on-top */
+#define STYLE_MAXIMIZE (1L<<4) /* Open a window maximized */
+#define STYLE_MINIMIZE (1L<<5) /* Open a window minimized */
+#define STYLE_BOTTOM (1L<<6) /* Open a window at the bottom of the Z order */
+
+/* Where to place a system menu */
+typedef enum MENUPOSITION
+{
+ AT_START, /* Place menu at the top of the system menu */
+ AT_END /* Put it at the bottom of the menu (default) */
+} MENUPOSITION;
+
+/* Menu item definitions */
+typedef struct MENUITEM
+{
+ char text[MENU_MAX+1]; /* To be displayed in menu */
+ MENUCOMMANDTYPE cmd; /* What should it do? */
+ char param[PARAM_MAX+1]; /* Any parameters? */
+ unsigned long commandID; /* Windows WM_COMMAND ID assigned at runtime */
+} MENUITEM;
+
+/* A completely read in menu... */
+typedef struct MENUPARSED
+{
+ char menuName[MENU_MAX+1]; /* What's it called in the text? */
+ MENUITEM *menuItem; /* Array of items */
+ int menuItems; /* How big's the array? */
+} MENUPARSED;
+
+/* To map between a window and a system menu to add for it */
+typedef struct SYSMENUITEM
+{
+ char match[MENU_MAX+1]; /* String to look for to apply this sysmenu */
+ char menuName[MENU_MAX+1]; /* Which menu to show? Used to set *menu */
+ MENUPOSITION menuPos; /* Where to place it (ignored in root) */
+} SYSMENUITEM;
+
+/* To redefine icons for certain window types */
+typedef struct ICONITEM
+{
+ char match[MENU_MAX+1]; /* What string to search for? */
+ char iconFile[PATH_MAX+NAME_MAX+2]; /* Icon location, WIN32 path */
+ HICON hicon; /* LoadImage() result */
+} ICONITEM;
+
+/* To redefine styles for certain window types */
+typedef struct STYLEITEM
+{
+ char match[MENU_MAX+1]; /* What string to search for? */
+ unsigned long type; /* What should it do? */
+} STYLEITEM;
+
+typedef struct WINPREFS
+{
+ /* Menu information */
+ MENUPARSED *menu; /* Array of created menus */
+ int menuItems; /* How big? */
+
+ /* Taskbar menu settings */
+ char rootMenuName[MENU_MAX+1]; /* Menu for taskbar icon */
+
+ /* System menu addition menus */
+ SYSMENUITEM *sysMenu;
+ int sysMenuItems;
+
+ /* Which menu to add to unmatched windows? */
+ char defaultSysMenuName[MENU_MAX+1];
+ MENUPOSITION defaultSysMenuPos; /* Where to place it */
+
+ /* Icon information */
+ char iconDirectory[PATH_MAX+1]; /* Where do the .icos lie? (Win32 path) */
+ char defaultIconName[NAME_MAX+1]; /* Replacement for x.ico */
+ char trayIconName[NAME_MAX+1]; /* Replacement for tray icon */
+
+ ICONITEM *icon;
+ int iconItems;
+
+ STYLEITEM *style;
+ int styleItems;
+
+ /* Force exit flag */
+ Bool fForceExit;
+
+ /* Silent exit flag */
+ Bool fSilentExit;
+
+} WINPREFS;
+
+
+
+
+/* Functions */
+void
+LoadPreferences(void);
+
+void
+SetupRootMenu (unsigned long hmenuRoot);
+
+void
+SetupSysMenu (unsigned long hwndIn);
+
+void
+HandleCustomWM_INITMENU(unsigned long hwndIn,
+ unsigned long hmenuIn);
+
+Bool
+HandleCustomWM_COMMAND (unsigned long hwndIn,
+ int command);
+
+int
+winIconIsOverride (unsigned hiconIn);
+
+HICON
+winOverrideIcon (unsigned long longpWin);
+
+unsigned long
+winOverrideStyle (unsigned long longpWin);
+
+unsigned long
+winOverrideStyle (unsigned long longpWin);
+
+HICON
+winTaskbarIcon(void);
+
+HICON
+winOverrideDefaultIcon(int size);
+#endif
diff --git a/xorg-server/hw/xwin/winprefslex.l b/xorg-server/hw/xwin/winprefslex.l index 463dff4ca..5a443407f 100644 --- a/xorg-server/hw/xwin/winprefslex.l +++ b/xorg-server/hw/xwin/winprefslex.l @@ -41,8 +41,6 @@ extern YYSTYPE yylval; extern char *yytext; extern int yyparse(void); -extern void ErrorF (const char* /*f*/, ...); - int yylineno; /* Copy the parsed string, must be free()d in yacc parser */ diff --git a/xorg-server/hw/xwin/winprefsyacc.y b/xorg-server/hw/xwin/winprefsyacc.y index 0acf160e4..b9e961622 100644 --- a/xorg-server/hw/xwin/winprefsyacc.y +++ b/xorg-server/hw/xwin/winprefsyacc.y @@ -1,457 +1,460 @@ -%{ -/* - * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved. - * Copyright (C) Colin Harrison 2005-2008 - * - * 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: Earle F. Philhower, III - * Colin Harrison - */ -/* $XFree86: $ */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "winprefs.h" - -/* The following give better error messages in bison at the cost of a few KB */ -#define YYERROR_VERBOSE 1 - -/* YYLTYPE_IS_TRIVIAL and YYENABLE_NLS defined to suppress warnings */ -#define YYLTYPE_IS_TRIVIAL 1 -#define YYENABLE_NLS 0 - -/* The global pref settings */ -WINPREFS pref; - -/* The working menu */ -static MENUPARSED menu; - -/* Functions for parsing the tokens into out structure */ -/* Defined at the end section of this file */ - -static void SetIconDirectory (char *path); -static void SetDefaultIcon (char *fname); -static void SetRootMenu (char *menu); -static void SetDefaultSysMenu (char *menu, int pos); -static void SetTrayIcon (char *fname); - -static void OpenMenu(char *menuname); -static void AddMenuLine(char *name, MENUCOMMANDTYPE cmd, char *param); -static void CloseMenu(void); - -static void OpenIcons(void); -static void AddIconLine(char *matchstr, char *iconfile); -static void CloseIcons(void); - -static void OpenStyles(void); -static void AddStyleLine(char *matchstr, unsigned long style); -static void CloseStyles(void); - -static void OpenSysMenu(void); -static void AddSysMenuLine(char *matchstr, char *menuname, int pos); -static void CloseSysMenu(void); - -static int yyerror (char *s); - -extern void ErrorF (const char* /*f*/, ...); -extern char *yytext; -extern int yylex(void); - -%} - -%union { - char *sVal; - unsigned long uVal; - int iVal; -} - -%token NEWLINE -%token MENU -%token LB -%token RB -%token ICONDIRECTORY -%token DEFAULTICON -%token ICONS -%token STYLES -%token TOPMOST -%token MAXIMIZE -%token MINIMIZE -%token BOTTOM -%token NOTITLE -%token OUTLINE -%token NOFRAME -%token DEFAULTSYSMENU -%token SYSMENU -%token ROOTMENU -%token SEPARATOR -%token ATSTART -%token ATEND -%token EXEC -%token ALWAYSONTOP -%token DEBUGOUTPUT "DEBUG" -%token RELOAD -%token TRAYICON -%token FORCEEXIT -%token SILENTEXIT - -%token <sVal> STRING -%type <uVal> group1 -%type <uVal> group2 -%type <uVal> stylecombo -%type <iVal> atspot - -%% - -input: /* empty */ - | input line - ; - -line: NEWLINE - | command - ; - - -newline_or_nada: - | NEWLINE newline_or_nada - ; - -command: defaulticon - | icondirectory - | menu - | icons - | styles - | sysmenu - | rootmenu - | defaultsysmenu - | debug - | trayicon - | forceexit - | silentexit - ; - -trayicon: TRAYICON STRING NEWLINE { SetTrayIcon($2); free($2); } - ; - -rootmenu: ROOTMENU STRING NEWLINE { SetRootMenu($2); free($2); } - ; - -defaultsysmenu: DEFAULTSYSMENU STRING atspot NEWLINE { SetDefaultSysMenu($2, $3); free($2); } - ; - -defaulticon: DEFAULTICON STRING NEWLINE { SetDefaultIcon($2); free($2); } - ; - -icondirectory: ICONDIRECTORY STRING NEWLINE { SetIconDirectory($2); free($2); } - ; - -menuline: SEPARATOR NEWLINE newline_or_nada { AddMenuLine("-", CMD_SEPARATOR, ""); } - | STRING ALWAYSONTOP NEWLINE newline_or_nada { AddMenuLine($1, CMD_ALWAYSONTOP, ""); free($1); } - | STRING EXEC STRING NEWLINE newline_or_nada { AddMenuLine($1, CMD_EXEC, $3); free($1); free($3); } - | STRING MENU STRING NEWLINE newline_or_nada { AddMenuLine($1, CMD_MENU, $3); free($1); free($3); } - | STRING RELOAD NEWLINE newline_or_nada { AddMenuLine($1, CMD_RELOAD, ""); free($1); } - ; - -menulist: menuline - | menuline menulist - ; - -menu: MENU STRING LB { OpenMenu($2); free($2); } newline_or_nada menulist RB {CloseMenu();} - ; - -iconline: STRING STRING NEWLINE newline_or_nada { AddIconLine($1, $2); free($1); free($2); } - ; - -iconlist: iconline - | iconline iconlist - ; - -icons: ICONS LB {OpenIcons();} newline_or_nada iconlist RB {CloseIcons();} - ; - -group1: TOPMOST { $$=STYLE_TOPMOST; } - | MAXIMIZE { $$=STYLE_MAXIMIZE; } - | MINIMIZE { $$=STYLE_MINIMIZE; } - | BOTTOM { $$=STYLE_BOTTOM; } - ; - -group2: NOTITLE { $$=STYLE_NOTITLE; } - | OUTLINE { $$=STYLE_OUTLINE; } - | NOFRAME { $$=STYLE_NOFRAME; } - ; - -stylecombo: group1 { $$=$1; } - | group2 { $$=$1; } - | group1 group2 { $$=$1|$2; } - | group2 group1 { $$=$1|$2; } - ; - -styleline: STRING stylecombo NEWLINE newline_or_nada { AddStyleLine($1, $2); free($1); } - ; - -stylelist: styleline - | styleline stylelist - ; - -styles: STYLES LB {OpenStyles();} newline_or_nada stylelist RB {CloseStyles();} - ; - -atspot: { $$=AT_END; } - | ATSTART { $$=AT_START; } - | ATEND { $$=AT_END; } - ; - -sysmenuline: STRING STRING atspot NEWLINE newline_or_nada { AddSysMenuLine($1, $2, $3); free($1); free($2); } - ; - -sysmenulist: sysmenuline - | sysmenuline sysmenulist - ; - -sysmenu: SYSMENU LB NEWLINE {OpenSysMenu();} newline_or_nada sysmenulist RB {CloseSysMenu();} - ; - -forceexit: FORCEEXIT NEWLINE { pref.fForceExit = TRUE; } - ; - -silentexit: SILENTEXIT NEWLINE { pref.fSilentExit = TRUE; } - ; - -debug: DEBUGOUTPUT STRING NEWLINE { ErrorF("LoadPreferences: %s\n", $2); free($2); } - ; - - -%% -/* - * Errors in parsing abort and print log messages - */ -static int -yyerror (char *s) -{ - extern int yylineno; /* Handled by flex internally */ - - ErrorF("LoadPreferences: %s line %d\n", s, yylineno); - return 1; -} - -/* Miscellaneous functions to store TOKENs into the structure */ -static void -SetIconDirectory (char *path) -{ - strncpy (pref.iconDirectory, path, PATH_MAX); - pref.iconDirectory[PATH_MAX] = 0; -} - -static void -SetDefaultIcon (char *fname) -{ - strncpy (pref.defaultIconName, fname, NAME_MAX); - pref.defaultIconName[NAME_MAX] = 0; -} - -static void -SetTrayIcon (char *fname) -{ - strncpy (pref.trayIconName, fname, NAME_MAX); - pref.trayIconName[NAME_MAX] = 0; -} - -static void -SetRootMenu (char *menu) -{ - strncpy (pref.rootMenuName, menu, MENU_MAX); - pref.rootMenuName[MENU_MAX] = 0; -} - -static void -SetDefaultSysMenu (char *menu, int pos) -{ - strncpy (pref.defaultSysMenuName, menu, MENU_MAX); - pref.defaultSysMenuName[MENU_MAX] = 0; - pref.defaultSysMenuPos = pos; -} - -static void -OpenMenu (char *menuname) -{ - if (menu.menuItem) free(menu.menuItem); - menu.menuItem = NULL; - strncpy(menu.menuName, menuname, MENU_MAX); - menu.menuName[MENU_MAX] = 0; - menu.menuItems = 0; -} - -static void -AddMenuLine (char *text, MENUCOMMANDTYPE cmd, char *param) -{ - if (menu.menuItem==NULL) - menu.menuItem = (MENUITEM*)malloc(sizeof(MENUITEM)); - else - menu.menuItem = (MENUITEM*) - realloc(menu.menuItem, sizeof(MENUITEM)*(menu.menuItems+1)); - - strncpy (menu.menuItem[menu.menuItems].text, text, MENU_MAX); - menu.menuItem[menu.menuItems].text[MENU_MAX] = 0; - - menu.menuItem[menu.menuItems].cmd = cmd; - - strncpy(menu.menuItem[menu.menuItems].param, param, PARAM_MAX); - menu.menuItem[menu.menuItems].param[PARAM_MAX] = 0; - - menu.menuItem[menu.menuItems].commandID = 0; - - menu.menuItems++; -} - -static void -CloseMenu (void) -{ - if (menu.menuItem==NULL || menu.menuItems==0) - { - ErrorF("LoadPreferences: Empty menu detected\n"); - return; - } - - if (pref.menuItems) - pref.menu = (MENUPARSED*) - realloc (pref.menu, (pref.menuItems+1)*sizeof(MENUPARSED)); - else - pref.menu = (MENUPARSED*)malloc (sizeof(MENUPARSED)); - - memcpy (pref.menu+pref.menuItems, &menu, sizeof(MENUPARSED)); - pref.menuItems++; - - memset (&menu, 0, sizeof(MENUPARSED)); -} - -static void -OpenIcons (void) -{ - if (pref.icon != NULL) { - ErrorF("LoadPreferences: Redefining icon mappings\n"); - free(pref.icon); - pref.icon = NULL; - } - pref.iconItems = 0; -} - -static void -AddIconLine (char *matchstr, char *iconfile) -{ - if (pref.icon==NULL) - pref.icon = (ICONITEM*)malloc(sizeof(ICONITEM)); - else - pref.icon = (ICONITEM*) - realloc(pref.icon, sizeof(ICONITEM)*(pref.iconItems+1)); - - strncpy(pref.icon[pref.iconItems].match, matchstr, MENU_MAX); - pref.icon[pref.iconItems].match[MENU_MAX] = 0; - - strncpy(pref.icon[pref.iconItems].iconFile, iconfile, PATH_MAX+NAME_MAX+1); - pref.icon[pref.iconItems].iconFile[PATH_MAX+NAME_MAX+1] = 0; - - pref.icon[pref.iconItems].hicon = 0; - - pref.iconItems++; -} - -static void -CloseIcons (void) -{ -} - -static void -OpenStyles (void) -{ - if (pref.style != NULL) { - ErrorF("LoadPreferences: Redefining window style\n"); - free(pref.style); - pref.style = NULL; - } - pref.styleItems = 0; -} - -static void -AddStyleLine (char *matchstr, unsigned long style) -{ - if (pref.style==NULL) - pref.style = (STYLEITEM*)malloc(sizeof(STYLEITEM)); - else - pref.style = (STYLEITEM*) - realloc(pref.style, sizeof(STYLEITEM)*(pref.styleItems+1)); - - strncpy(pref.style[pref.styleItems].match, matchstr, MENU_MAX); - pref.style[pref.styleItems].match[MENU_MAX] = 0; - - pref.style[pref.styleItems].type = style; - - pref.styleItems++; -} - -static void -CloseStyles (void) -{ -} - -static void -OpenSysMenu (void) -{ - if (pref.sysMenu != NULL) { - ErrorF("LoadPreferences: Redefining system menu\n"); - free(pref.sysMenu); - pref.sysMenu = NULL; - } - pref.sysMenuItems = 0; -} - -static void -AddSysMenuLine (char *matchstr, char *menuname, int pos) -{ - if (pref.sysMenu==NULL) - pref.sysMenu = (SYSMENUITEM*)malloc(sizeof(SYSMENUITEM)); - else - pref.sysMenu = (SYSMENUITEM*) - realloc(pref.sysMenu, sizeof(SYSMENUITEM)*(pref.sysMenuItems+1)); - - strncpy (pref.sysMenu[pref.sysMenuItems].match, matchstr, MENU_MAX); - pref.sysMenu[pref.sysMenuItems].match[MENU_MAX] = 0; - - strncpy (pref.sysMenu[pref.sysMenuItems].menuName, menuname, MENU_MAX); - pref.sysMenu[pref.sysMenuItems].menuName[MENU_MAX] = 0; - - pref.sysMenu[pref.sysMenuItems].menuPos = pos; - - pref.sysMenuItems++; -} - -static void -CloseSysMenu (void) -{ -} - +%{
+/*
+ * Copyright (C) 1994-2000 The XFree86 Project, Inc. All Rights Reserved.
+ * Copyright (C) Colin Harrison 2005-2008
+ *
+ * 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: Earle F. Philhower, III
+ * Colin Harrison
+ */
+/* $XFree86: $ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "winprefs.h"
+#include "winmsg.h"
+
+/* The following give better error messages in bison at the cost of a few KB */
+#define YYERROR_VERBOSE 1
+
+/* YYLTYPE_IS_TRIVIAL and YYENABLE_NLS defined to suppress warnings */
+#define YYLTYPE_IS_TRIVIAL 1
+#define YYENABLE_NLS 0
+
+/* The global pref settings */
+WINPREFS pref;
+
+/* The working menu */
+static MENUPARSED menu;
+
+/* Functions for parsing the tokens into out structure */
+/* Defined at the end section of this file */
+
+static void SetIconDirectory (char *path);
+static void SetDefaultIcon (char *fname);
+static void SetRootMenu (char *menu);
+static void SetDefaultSysMenu (char *menu, int pos);
+static void SetTrayIcon (char *fname);
+
+static void OpenMenu(char *menuname);
+static void AddMenuLine(char *name, MENUCOMMANDTYPE cmd, char *param);
+static void CloseMenu(void);
+
+static void OpenIcons(void);
+static void AddIconLine(char *matchstr, char *iconfile);
+static void CloseIcons(void);
+
+static void OpenStyles(void);
+static void AddStyleLine(char *matchstr, unsigned long style);
+static void CloseStyles(void);
+
+static void OpenSysMenu(void);
+static void AddSysMenuLine(char *matchstr, char *menuname, int pos);
+static void CloseSysMenu(void);
+
+static int yyerror (char *s);
+
+extern char *yytext;
+extern int yylex(void);
+
+#define YYMALLOC malloc
+#define YYFREE free
+
+%}
+
+%union {
+ char *sVal;
+ unsigned long uVal;
+ int iVal;
+}
+
+%token NEWLINE
+%token MENU
+%token LB
+%token RB
+%token ICONDIRECTORY
+%token DEFAULTICON
+%token ICONS
+%token STYLES
+%token TOPMOST
+%token MAXIMIZE
+%token MINIMIZE
+%token BOTTOM
+%token NOTITLE
+%token OUTLINE
+%token NOFRAME
+%token DEFAULTSYSMENU
+%token SYSMENU
+%token ROOTMENU
+%token SEPARATOR
+%token ATSTART
+%token ATEND
+%token EXEC
+%token ALWAYSONTOP
+%token DEBUGOUTPUT "DEBUG"
+%token RELOAD
+%token TRAYICON
+%token FORCEEXIT
+%token SILENTEXIT
+
+%token <sVal> STRING
+%type <uVal> group1
+%type <uVal> group2
+%type <uVal> stylecombo
+%type <iVal> atspot
+
+%%
+
+input: /* empty */
+ | input line
+ ;
+
+line: NEWLINE
+ | command
+ ;
+
+
+newline_or_nada:
+ | NEWLINE newline_or_nada
+ ;
+
+command: defaulticon
+ | icondirectory
+ | menu
+ | icons
+ | styles
+ | sysmenu
+ | rootmenu
+ | defaultsysmenu
+ | debug
+ | trayicon
+ | forceexit
+ | silentexit
+ ;
+
+trayicon: TRAYICON STRING NEWLINE { SetTrayIcon($2); free($2); }
+ ;
+
+rootmenu: ROOTMENU STRING NEWLINE { SetRootMenu($2); free($2); }
+ ;
+
+defaultsysmenu: DEFAULTSYSMENU STRING atspot NEWLINE { SetDefaultSysMenu($2, $3); free($2); }
+ ;
+
+defaulticon: DEFAULTICON STRING NEWLINE { SetDefaultIcon($2); free($2); }
+ ;
+
+icondirectory: ICONDIRECTORY STRING NEWLINE { SetIconDirectory($2); free($2); }
+ ;
+
+menuline: SEPARATOR NEWLINE newline_or_nada { AddMenuLine("-", CMD_SEPARATOR, ""); }
+ | STRING ALWAYSONTOP NEWLINE newline_or_nada { AddMenuLine($1, CMD_ALWAYSONTOP, ""); free($1); }
+ | STRING EXEC STRING NEWLINE newline_or_nada { AddMenuLine($1, CMD_EXEC, $3); free($1); free($3); }
+ | STRING MENU STRING NEWLINE newline_or_nada { AddMenuLine($1, CMD_MENU, $3); free($1); free($3); }
+ | STRING RELOAD NEWLINE newline_or_nada { AddMenuLine($1, CMD_RELOAD, ""); free($1); }
+ ;
+
+menulist: menuline
+ | menuline menulist
+ ;
+
+menu: MENU STRING LB { OpenMenu($2); free($2); } newline_or_nada menulist RB {CloseMenu();}
+ ;
+
+iconline: STRING STRING NEWLINE newline_or_nada { AddIconLine($1, $2); free($1); free($2); }
+ ;
+
+iconlist: iconline
+ | iconline iconlist
+ ;
+
+icons: ICONS LB {OpenIcons();} newline_or_nada iconlist RB {CloseIcons();}
+ ;
+
+group1: TOPMOST { $$=STYLE_TOPMOST; }
+ | MAXIMIZE { $$=STYLE_MAXIMIZE; }
+ | MINIMIZE { $$=STYLE_MINIMIZE; }
+ | BOTTOM { $$=STYLE_BOTTOM; }
+ ;
+
+group2: NOTITLE { $$=STYLE_NOTITLE; }
+ | OUTLINE { $$=STYLE_OUTLINE; }
+ | NOFRAME { $$=STYLE_NOFRAME; }
+ ;
+
+stylecombo: group1 { $$=$1; }
+ | group2 { $$=$1; }
+ | group1 group2 { $$=$1|$2; }
+ | group2 group1 { $$=$1|$2; }
+ ;
+
+styleline: STRING stylecombo NEWLINE newline_or_nada { AddStyleLine($1, $2); free($1); }
+ ;
+
+stylelist: styleline
+ | styleline stylelist
+ ;
+
+styles: STYLES LB {OpenStyles();} newline_or_nada stylelist RB {CloseStyles();}
+ ;
+
+atspot: { $$=AT_END; }
+ | ATSTART { $$=AT_START; }
+ | ATEND { $$=AT_END; }
+ ;
+
+sysmenuline: STRING STRING atspot NEWLINE newline_or_nada { AddSysMenuLine($1, $2, $3); free($1); free($2); }
+ ;
+
+sysmenulist: sysmenuline
+ | sysmenuline sysmenulist
+ ;
+
+sysmenu: SYSMENU LB NEWLINE {OpenSysMenu();} newline_or_nada sysmenulist RB {CloseSysMenu();}
+ ;
+
+forceexit: FORCEEXIT NEWLINE { pref.fForceExit = TRUE; }
+ ;
+
+silentexit: SILENTEXIT NEWLINE { pref.fSilentExit = TRUE; }
+ ;
+
+debug: DEBUGOUTPUT STRING NEWLINE { winDebug("LoadPreferences: %s\n", $2); free($2); }
+ ;
+
+
+%%
+/*
+ * Errors in parsing abort and print log messages
+ */
+static int
+yyerror (char *s)
+{
+ extern int yylineno; /* Handled by flex internally */
+
+ ErrorF("LoadPreferences: %s line %d\n", s, yylineno);
+ return 1;
+}
+
+/* Miscellaneous functions to store TOKENs into the structure */
+static void
+SetIconDirectory (char *path)
+{
+ strncpy (pref.iconDirectory, path, PATH_MAX);
+ pref.iconDirectory[PATH_MAX] = 0;
+}
+
+static void
+SetDefaultIcon (char *fname)
+{
+ strncpy (pref.defaultIconName, fname, NAME_MAX);
+ pref.defaultIconName[NAME_MAX] = 0;
+}
+
+static void
+SetTrayIcon (char *fname)
+{
+ strncpy (pref.trayIconName, fname, NAME_MAX);
+ pref.trayIconName[NAME_MAX] = 0;
+}
+
+static void
+SetRootMenu (char *menu)
+{
+ strncpy (pref.rootMenuName, menu, MENU_MAX);
+ pref.rootMenuName[MENU_MAX] = 0;
+}
+
+static void
+SetDefaultSysMenu (char *menu, int pos)
+{
+ strncpy (pref.defaultSysMenuName, menu, MENU_MAX);
+ pref.defaultSysMenuName[MENU_MAX] = 0;
+ pref.defaultSysMenuPos = pos;
+}
+
+static void
+OpenMenu (char *menuname)
+{
+ if (menu.menuItem) free(menu.menuItem);
+ menu.menuItem = NULL;
+ strncpy(menu.menuName, menuname, MENU_MAX);
+ menu.menuName[MENU_MAX] = 0;
+ menu.menuItems = 0;
+}
+
+static void
+AddMenuLine (char *text, MENUCOMMANDTYPE cmd, char *param)
+{
+ if (menu.menuItem==NULL)
+ menu.menuItem = (MENUITEM*)malloc(sizeof(MENUITEM));
+ else
+ menu.menuItem = (MENUITEM*)
+ realloc(menu.menuItem, sizeof(MENUITEM)*(menu.menuItems+1));
+
+ strncpy (menu.menuItem[menu.menuItems].text, text, MENU_MAX);
+ menu.menuItem[menu.menuItems].text[MENU_MAX] = 0;
+
+ menu.menuItem[menu.menuItems].cmd = cmd;
+
+ strncpy(menu.menuItem[menu.menuItems].param, param, PARAM_MAX);
+ menu.menuItem[menu.menuItems].param[PARAM_MAX] = 0;
+
+ menu.menuItem[menu.menuItems].commandID = 0;
+
+ menu.menuItems++;
+}
+
+static void
+CloseMenu (void)
+{
+ if (menu.menuItem==NULL || menu.menuItems==0)
+ {
+ ErrorF("LoadPreferences: Empty menu detected\n");
+ return;
+ }
+
+ if (pref.menuItems)
+ pref.menu = (MENUPARSED*)
+ realloc (pref.menu, (pref.menuItems+1)*sizeof(MENUPARSED));
+ else
+ pref.menu = (MENUPARSED*)malloc (sizeof(MENUPARSED));
+
+ memcpy (pref.menu+pref.menuItems, &menu, sizeof(MENUPARSED));
+ pref.menuItems++;
+
+ memset (&menu, 0, sizeof(MENUPARSED));
+}
+
+static void
+OpenIcons (void)
+{
+ if (pref.icon != NULL) {
+ winDebug("LoadPreferences: Redefining icon mappings\n");
+ free(pref.icon);
+ pref.icon = NULL;
+ }
+ pref.iconItems = 0;
+}
+
+static void
+AddIconLine (char *matchstr, char *iconfile)
+{
+ if (pref.icon==NULL)
+ pref.icon = (ICONITEM*)malloc(sizeof(ICONITEM));
+ else
+ pref.icon = (ICONITEM*)
+ realloc(pref.icon, sizeof(ICONITEM)*(pref.iconItems+1));
+
+ strncpy(pref.icon[pref.iconItems].match, matchstr, MENU_MAX);
+ pref.icon[pref.iconItems].match[MENU_MAX] = 0;
+
+ strncpy(pref.icon[pref.iconItems].iconFile, iconfile, PATH_MAX+NAME_MAX+1);
+ pref.icon[pref.iconItems].iconFile[PATH_MAX+NAME_MAX+1] = 0;
+
+ pref.icon[pref.iconItems].hicon = 0;
+
+ pref.iconItems++;
+}
+
+static void
+CloseIcons (void)
+{
+}
+
+static void
+OpenStyles (void)
+{
+ if (pref.style != NULL) {
+ winDebug("LoadPreferences: Redefining window style\n");
+ free(pref.style);
+ pref.style = NULL;
+ }
+ pref.styleItems = 0;
+}
+
+static void
+AddStyleLine (char *matchstr, unsigned long style)
+{
+ if (pref.style==NULL)
+ pref.style = (STYLEITEM*)malloc(sizeof(STYLEITEM));
+ else
+ pref.style = (STYLEITEM*)
+ realloc(pref.style, sizeof(STYLEITEM)*(pref.styleItems+1));
+
+ strncpy(pref.style[pref.styleItems].match, matchstr, MENU_MAX);
+ pref.style[pref.styleItems].match[MENU_MAX] = 0;
+
+ pref.style[pref.styleItems].type = style;
+
+ pref.styleItems++;
+}
+
+static void
+CloseStyles (void)
+{
+}
+
+static void
+OpenSysMenu (void)
+{
+ if (pref.sysMenu != NULL) {
+ winDebug("LoadPreferences: Redefining system menu\n");
+ free(pref.sysMenu);
+ pref.sysMenu = NULL;
+ }
+ pref.sysMenuItems = 0;
+}
+
+static void
+AddSysMenuLine (char *matchstr, char *menuname, int pos)
+{
+ if (pref.sysMenu==NULL)
+ pref.sysMenu = (SYSMENUITEM*)malloc(sizeof(SYSMENUITEM));
+ else
+ pref.sysMenu = (SYSMENUITEM*)
+ realloc(pref.sysMenu, sizeof(SYSMENUITEM)*(pref.sysMenuItems+1));
+
+ strncpy (pref.sysMenu[pref.sysMenuItems].match, matchstr, MENU_MAX);
+ pref.sysMenu[pref.sysMenuItems].match[MENU_MAX] = 0;
+
+ strncpy (pref.sysMenu[pref.sysMenuItems].menuName, menuname, MENU_MAX);
+ pref.sysMenu[pref.sysMenuItems].menuName[MENU_MAX] = 0;
+
+ pref.sysMenu[pref.sysMenuItems].menuPos = pos;
+
+ pref.sysMenuItems++;
+}
+
+static void
+CloseSysMenu (void)
+{
+}
+
diff --git a/xorg-server/hw/xwin/winpriv.c b/xorg-server/hw/xwin/winpriv.c deleted file mode 100644 index 29221cf2b..000000000 --- a/xorg-server/hw/xwin/winpriv.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Export window information for the Windows-OpenGL GLX implementation. - * - * Authors: Alexander Gottwald - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" -#include "winpriv.h" -#include "winwindow.h" - -void -winCreateWindowsWindow (WindowPtr pWin); -/** - * Return size and handles of a window. - * If pWin is NULL, then the information for the root window is requested. - */ -extern void winGetWindowInfo(WindowPtr pWin, winWindowInfoPtr pWinInfo) -{ - /* Sanity check */ - if (pWinInfo == NULL) - return; - - winDebug("%s:%d pWin=%p\n", __FUNCTION__, __LINE__, pWin); - - /* a real window was requested */ - if (pWin != NULL) - { - /* Initialize the size information */ - RECT rect = { - pWin->drawable.x, - pWin->drawable.y, - pWin->drawable.x + pWin->drawable.width, - pWin->drawable.y + pWin->drawable.height - }, rect_extends; - /* Get the window and screen privates */ - ScreenPtr pScreen = pWin->drawable.pScreen; - winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen); - winScreenInfoPtr pScreenInfo = NULL; - - rect_extends = rect; - OffsetRect(&rect_extends, -pWin->drawable.x, -pWin->drawable.y); - - if (pWinScreen == NULL) - { - ErrorF("winGetWindowInfo: screen has no privates\n"); - return; - } - - pWinInfo->hwnd = pWinScreen->hwndScreen; - pWinInfo->hrgn = NULL; - pWinInfo->rect = rect; - - - pScreenInfo = pWinScreen->pScreenInfo; -#ifdef XWIN_MULTIWINDOW - /* check for multiwindow mode */ - if (pScreenInfo->fMultiWindow) - { - winWindowPriv(pWin); - - if (pWinPriv == NULL) - { - ErrorF("winGetWindowInfo: window has no privates\n"); - return; - } - - if (pWinPriv->hWnd == NULL) - { - winCreateWindowsWindow(pWin); - } - if (pWinPriv->hWnd != NULL) { - - /* copy size and window handle */ - pWinInfo->rect = rect_extends; - pWinInfo->hwnd = pWinPriv->hWnd; - - /* Copy window region */ - if (pWinInfo->hrgn) - DeleteObject(pWinInfo->hrgn); - pWinInfo->hrgn = CreateRectRgn(0,0,0,0); - CombineRgn(pWinInfo->hrgn, pWinPriv->hRgn, pWinPriv->hRgn, - RGN_COPY); - } - - return; - } -#endif -#ifdef XWIN_MULTIWINDOWEXTWM - /* check for multiwindow external wm mode */ - if (pScreenInfo->fMWExtWM) - { - win32RootlessWindowPtr pRLWinPriv - = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); - - if (pRLWinPriv == NULL) { - ErrorF("winGetWindowInfo: window has no privates\n"); - return; - } - - if (pRLWinPriv->hWnd != NULL) - { - /* copy size and window handle */ - pWinInfo->rect = rect_extends; - pWinInfo->hwnd = pRLWinPriv->hWnd; - } - return; - } -#endif - } - else - { - RECT rect = {0, 0, 0, 0}; - ScreenPtr pScreen = g_ScreenInfo[0].pScreen; - winPrivScreenPtr pWinScreen = winGetScreenPriv(pScreen); - - pWinInfo->hwnd = NULL; - pWinInfo->hrgn = NULL; - pWinInfo->rect = rect; - - if (pWinScreen == NULL) - { - ErrorF("winGetWindowInfo: screen has no privates\n"); - return; - } - - ErrorF("winGetWindowInfo: returning root window\n"); - - pWinInfo->hwnd = pWinScreen->hwndScreen; - } - return; -} diff --git a/xorg-server/hw/xwin/winpriv.h b/xorg-server/hw/xwin/winpriv.h deleted file mode 100644 index d4505c83e..000000000 --- a/xorg-server/hw/xwin/winpriv.h +++ /dev/null @@ -1,15 +0,0 @@ -/* - * Export window information for the Windows-OpenGL GLX implementation. - * - * Authors: Alexander Gottwald - */ -#include <windows.h> - -typedef struct -{ - HWND hwnd; - HRGN hrgn; - RECT rect; -} winWindowInfoRec, *winWindowInfoPtr; - -extern void winGetWindowInfo(WindowPtr pWin, winWindowInfoPtr pWinInfo); diff --git a/xorg-server/hw/xwin/winprocarg.c b/xorg-server/hw/xwin/winprocarg.c index 159e53333..3cd9353db 100644 --- a/xorg-server/hw/xwin/winprocarg.c +++ b/xorg-server/hw/xwin/winprocarg.c @@ -1,1582 +1,1572 @@ -/* - -Copyright 1993, 1998 The Open Group -Copyright (C) Colin Harrison 2005-2008 - -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. - -*/ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#ifdef XVENDORNAME -#define VENDOR_STRING XVENDORNAME -#define VENDOR_CONTACT BUILDERADDR -#endif -#include <../xfree86/common/xorgVersion.h> -#include "win.h" -#include "winconfig.h" -#include "winprefs.h" -#include "winmsg.h" - -/* - * References to external symbols - */ - -extern int g_iNumScreens; -extern winScreenInfo g_ScreenInfo[]; -extern int g_iLastScreen; -extern Bool g_fInitializedDefaultScreens; -#ifdef XWIN_CLIPBOARD -extern Bool g_fUnicodeClipboard; -extern Bool g_fClipboard; -#endif -extern int g_iLogVerbose; -extern char * g_pszLogFile; -#ifdef RELOCATE_PROJECTROOT -extern Bool g_fLogFileChanged; -#endif -extern Bool g_fXdmcpEnabled; -extern Bool g_fAuthEnabled; -extern char * g_pszCommandLine; -extern Bool g_fKeyboardHookLL; -extern Bool g_fNoHelpMessageBox; -extern Bool g_fSoftwareCursor; -extern Bool g_fSilentDupError; - -/* globals required by callback function for monitor information */ -struct GetMonitorInfoData { - int requestedMonitor; - int monitorNum; - Bool bUserSpecifiedMonitor; - Bool bMonitorSpecifiedExists; - int monitorOffsetX; - int monitorOffsetY; - int monitorHeight; - int monitorWidth; -}; - -typedef wBOOL (*ENUMDISPLAYMONITORSPROC)(HDC,LPCRECT,MONITORENUMPROC,LPARAM); -ENUMDISPLAYMONITORSPROC _EnumDisplayMonitors; - -wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data); - -static Bool QueryMonitor(int index, struct GetMonitorInfoData *data) -{ - /* Load EnumDisplayMonitors from DLL */ - HMODULE user32; - FARPROC func; - user32 = LoadLibrary("user32.dll"); - if (user32 == NULL) - { - winW32Error(2, "Could not open user32.dll"); - return FALSE; - } - func = GetProcAddress(user32, "EnumDisplayMonitors"); - if (func == NULL) - { - winW32Error(2, "Could not resolve EnumDisplayMonitors: "); - return FALSE; - } - _EnumDisplayMonitors = (ENUMDISPLAYMONITORSPROC)func; - - /* prepare data */ - if (data == NULL) - return FALSE; - memset(data, 0, sizeof(*data)); - data->requestedMonitor = index; - - /* query information */ - _EnumDisplayMonitors(NULL, NULL, getMonitorInfo, (LPARAM) data); - - /* cleanup */ - FreeLibrary(user32); - return TRUE; -} - -/* - * Function prototypes - */ - -void -winLogCommandLine (int argc, char *argv[]); - -void -winLogVersionInfo (void); - -#ifdef DDXOSVERRORF -void OsVendorVErrorF (const char *pszFormat, va_list va_args); -#endif - -void -winInitializeDefaultScreens (void); - -/* - * Process arguments on the command line - */ - -void -winInitializeDefaultScreens (void) -{ - int i; - DWORD dwWidth, dwHeight; - - /* Bail out early if default screens have already been initialized */ - if (g_fInitializedDefaultScreens) - return; - - /* Zero the memory used for storing the screen info */ - ZeroMemory (g_ScreenInfo, MAXSCREENS * sizeof (winScreenInfo)); - - /* Get default width and height */ - /* - * NOTE: These defaults will cause the window to cover only - * the primary monitor in the case that we have multiple monitors. - */ - dwWidth = GetSystemMetrics (SM_CXSCREEN); - dwHeight = GetSystemMetrics (SM_CYSCREEN); - - winErrorFVerb (2, "winInitializeDefaultScreens - w %d h %d\n", - (int) dwWidth, (int) dwHeight); - - /* Set a default DPI, if no parameter was passed */ - if (monitorResolution == 0) - monitorResolution = WIN_DEFAULT_DPI; - - for (i = 0; i < MAXSCREENS; ++i) - { - g_ScreenInfo[i].dwScreen = i; - g_ScreenInfo[i].dwWidth = dwWidth; - g_ScreenInfo[i].dwHeight = dwHeight; - g_ScreenInfo[i].dwUserWidth = dwWidth; - g_ScreenInfo[i].dwUserHeight = dwHeight; - g_ScreenInfo[i].fUserGaveHeightAndWidth - = WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH; - g_ScreenInfo[i].fUserGavePosition = FALSE; - g_ScreenInfo[i].dwBPP = WIN_DEFAULT_BPP; - g_ScreenInfo[i].dwClipUpdatesNBoxes = WIN_DEFAULT_CLIP_UPDATES_NBOXES; -#ifdef XWIN_EMULATEPSEUDO - g_ScreenInfo[i].fEmulatePseudo = WIN_DEFAULT_EMULATE_PSEUDO; -#endif - g_ScreenInfo[i].dwRefreshRate = WIN_DEFAULT_REFRESH; - g_ScreenInfo[i].pfb = NULL; - g_ScreenInfo[i].fFullScreen = FALSE; - g_ScreenInfo[i].fDecoration = TRUE; -#ifdef XWIN_MULTIWINDOWEXTWM - g_ScreenInfo[i].fMWExtWM = FALSE; - g_ScreenInfo[i].fInternalWM = FALSE; -#endif - g_ScreenInfo[i].fRootless = FALSE; -#ifdef XWIN_MULTIWINDOW - g_ScreenInfo[i].fMultiWindow = FALSE; -#endif -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - g_ScreenInfo[i].fMultiMonitorOverride = FALSE; -#endif - g_ScreenInfo[i].fMultipleMonitors = FALSE; - g_ScreenInfo[i].fLessPointer = FALSE; - g_ScreenInfo[i].fScrollbars = FALSE; - g_ScreenInfo[i].fNoTrayIcon = FALSE; - g_ScreenInfo[i].iE3BTimeout = WIN_E3B_OFF; - g_ScreenInfo[i].dwWidth_mm = (dwWidth / WIN_DEFAULT_DPI) - * 25.4; - g_ScreenInfo[i].dwHeight_mm = (dwHeight / WIN_DEFAULT_DPI) - * 25.4; - g_ScreenInfo[i].fUseWinKillKey = WIN_DEFAULT_WIN_KILL; - g_ScreenInfo[i].fUseUnixKillKey = WIN_DEFAULT_UNIX_KILL; - g_ScreenInfo[i].fIgnoreInput = FALSE; - g_ScreenInfo[i].fExplicitScreen = FALSE; - } - - /* Signal that the default screens have been initialized */ - g_fInitializedDefaultScreens = TRUE; - - winErrorFVerb (2, "winInitializeDefaultScreens - Returning\n"); -} - -/* See Porting Layer Definition - p. 57 */ -/* - * INPUT - * argv: pointer to an array of null-terminated strings, one for - * each token in the X Server command line; the first token - * is 'XWin.exe', or similar. - * argc: a count of the number of tokens stored in argv. - * i: a zero-based index into argv indicating the current token being - * processed. - * - * OUTPUT - * return: return the number of tokens processed correctly. - * - * NOTE - * When looking for n tokens, check that i + n is less than argc. Or, - * you may check if i is greater than or equal to argc, in which case - * you should display the UseMsg () and return 0. - */ - -/* Check if enough arguments are given for the option */ -#define CHECK_ARGS(count) if (i + count >= argc) { UseMsg (); return 0; } - -/* Compare the current option with the string. */ -#define IS_OPTION(name) (strcmp (argv[i], name) == 0) - -int -ddxProcessArgument (int argc, char *argv[], int i) -{ - static Bool s_fBeenHere = FALSE; - - /* Initialize once */ - if (!s_fBeenHere) - { -#ifdef DDXOSVERRORF - /* - * This initialises our hook into VErrorF () for catching log messages - * that are generated before OsInit () is called. - */ - OsVendorVErrorFProc = OsVendorVErrorF; -#endif - - s_fBeenHere = TRUE; - - /* Initialize only if option is not -help */ - if (!IS_OPTION("-help") && !IS_OPTION("-h") && !IS_OPTION("--help") && - !IS_OPTION("-version") && !IS_OPTION("--version")) - { - - /* Log the version information */ - winLogVersionInfo (); - - /* Log the command line */ - winLogCommandLine (argc, argv); - - /* - * Initialize default screen settings. We have to do this before - * OsVendorInit () gets called, otherwise we will overwrite - * settings changed by parameters such as -fullscreen, etc. - */ - winErrorFVerb (2, "ddxProcessArgument - Initializing default " - "screens\n"); - winInitializeDefaultScreens (); - } - } - -#if CYGDEBUG - winDebug ("ddxProcessArgument - arg: %s\n", argv[i]); -#endif - - /* - * Look for the '-help' and similar options - */ - if (IS_OPTION ("-help") || IS_OPTION("-h") || IS_OPTION("--help")) - { - /* Reset logfile. We don't need that helpmessage in the logfile */ - g_pszLogFile = NULL; - g_fNoHelpMessageBox = TRUE; - UseMsg(); - exit (0); - return 1; - } - - if (IS_OPTION ("-version") || IS_OPTION("--version")) - { - /* Reset logfile. We don't need that versioninfo in the logfile */ - g_pszLogFile = NULL; - winLogVersionInfo (); - exit (0); - return 1; - } - - /* - * Look for the '-screen scr_num [width height]' argument - */ - if (IS_OPTION ("-screen")) - { - int iArgsProcessed = 1; - int nScreenNum; - int iWidth, iHeight, iX, iY; - int iMonitor; - -#if CYGDEBUG - winDebug ("ddxProcessArgument - screen - argc: %d i: %d\n", - argc, i); -#endif - - /* Display the usage message if the argument is malformed */ - if (i + 1 >= argc) - { - return 0; - } - - /* Grab screen number */ - nScreenNum = atoi (argv[i + 1]); - - /* Validate the specified screen number */ - if (nScreenNum < 0 || nScreenNum >= MAXSCREENS) - { - ErrorF ("ddxProcessArgument - screen - Invalid screen number %d\n", - nScreenNum); - UseMsg (); - return 0; - } - - /* look for @m where m is monitor number */ - if (i + 2 < argc - && 1 == sscanf(argv[i + 2], "@%d", (int *) &iMonitor)) - { - struct GetMonitorInfoData data; - if (!QueryMonitor(iMonitor, &data)) - { - ErrorF ("ddxProcessArgument - screen - " - "Querying monitors is not supported on NT4 and Win95\n"); - } else if (data.bMonitorSpecifiedExists == TRUE) - { - winErrorFVerb(2, "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor); - iArgsProcessed = 3; - g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE; - g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; - g_ScreenInfo[nScreenNum].dwWidth = data.monitorWidth; - g_ScreenInfo[nScreenNum].dwHeight = data.monitorHeight; - g_ScreenInfo[nScreenNum].dwUserWidth = data.monitorWidth; - g_ScreenInfo[nScreenNum].dwUserHeight = data.monitorHeight; - g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX; - g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY; - } - else - { - /* monitor does not exist, error out */ - ErrorF ("ddxProcessArgument - screen - Invalid monitor number %d\n", - iMonitor); - UseMsg (); - exit (0); - return 0; - } - } - - /* Look for 'WxD' or 'W D' */ - else if (i + 2 < argc - && 2 == sscanf (argv[i + 2], "%dx%d", - (int *) &iWidth, - (int *) &iHeight)) - { - winErrorFVerb (2, "ddxProcessArgument - screen - Found ``WxD'' arg\n"); - iArgsProcessed = 3; - g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE; - g_ScreenInfo[nScreenNum].dwWidth = iWidth; - g_ScreenInfo[nScreenNum].dwHeight = iHeight; - g_ScreenInfo[nScreenNum].dwUserWidth = iWidth; - g_ScreenInfo[nScreenNum].dwUserHeight = iHeight; - /* Look for WxD+X+Y */ - if (2 == sscanf (argv[i + 2], "%*dx%*d+%d+%d", - (int *) &iX, - (int *) &iY)) - { - winErrorFVerb (2, "ddxProcessArgument - screen - Found ``X+Y'' arg\n"); - g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; - g_ScreenInfo[nScreenNum].dwInitialX = iX; - g_ScreenInfo[nScreenNum].dwInitialY = iY; - - /* look for WxD+X+Y@m where m is monitor number. take X,Y to be offsets from monitor's root position */ - if (1 == sscanf (argv[i + 2], "%*dx%*d+%*d+%*d@%d", - (int *) &iMonitor)) - { - struct GetMonitorInfoData data; - if (!QueryMonitor(iMonitor, &data)) - { - ErrorF ("ddxProcessArgument - screen - " - "Querying monitors is not supported on NT4 and Win95\n"); - } else if (data.bMonitorSpecifiedExists == TRUE) - { - g_ScreenInfo[nScreenNum].dwInitialX += data.monitorOffsetX; - g_ScreenInfo[nScreenNum].dwInitialY += data.monitorOffsetY; - } - else - { - /* monitor does not exist, error out */ - ErrorF ("ddxProcessArgument - screen - Invalid monitor number %d\n", - iMonitor); - UseMsg (); - exit (0); - return 0; - } - - } - } - - /* look for WxD@m where m is monitor number */ - else if (1 == sscanf(argv[i + 2], "%*dx%*d@%d", - (int *) &iMonitor)) - { - struct GetMonitorInfoData data; - if (!QueryMonitor(iMonitor, &data)) - { - ErrorF ("ddxProcessArgument - screen - " - "Querying monitors is not supported on NT4 and Win95\n"); - } else if (data.bMonitorSpecifiedExists == TRUE) - { - winErrorFVerb (2, "ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor); - g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; - g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX; - g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY; - } - else - { - /* monitor does not exist, error out */ - ErrorF ("ddxProcessArgument - screen - Invalid monitor number %d\n", - iMonitor); - UseMsg (); - exit (0); - return 0; - } - - } - } - else if (i + 3 < argc - && 1 == sscanf (argv[i + 2], "%d", - (int *) &iWidth) - && 1 == sscanf (argv[i + 3], "%d", - (int *) &iHeight)) - { - winErrorFVerb (2, "ddxProcessArgument - screen - Found ``W D'' arg\n"); - iArgsProcessed = 4; - g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE; - g_ScreenInfo[nScreenNum].dwWidth = iWidth; - g_ScreenInfo[nScreenNum].dwHeight = iHeight; - g_ScreenInfo[nScreenNum].dwUserWidth = iWidth; - g_ScreenInfo[nScreenNum].dwUserHeight = iHeight; - if (i + 5 < argc - && 1 == sscanf (argv[i + 4], "%d", - (int *) &iX) - && 1 == sscanf (argv[i + 5], "%d", - (int *) &iY)) - { - winErrorFVerb (2, "ddxProcessArgument - screen - Found ``X Y'' arg\n"); - iArgsProcessed = 6; - g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE; - g_ScreenInfo[nScreenNum].dwInitialX = iX; - g_ScreenInfo[nScreenNum].dwInitialY = iY; - } - } - else - { - winErrorFVerb (2, "ddxProcessArgument - screen - Did not find size arg. " - "dwWidth: %d dwHeight: %d\n", - (int) g_ScreenInfo[nScreenNum].dwWidth, - (int) g_ScreenInfo[nScreenNum].dwHeight); - iArgsProcessed = 2; - g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE; - } - - /* Calculate the screen width and height in millimeters */ - if (g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth) - { - g_ScreenInfo[nScreenNum].dwWidth_mm - = (g_ScreenInfo[nScreenNum].dwWidth - / monitorResolution) * 25.4; - g_ScreenInfo[nScreenNum].dwHeight_mm - = (g_ScreenInfo[nScreenNum].dwHeight - / monitorResolution) * 25.4; - } - - /* Flag that this screen was explicity specified by the user */ - g_ScreenInfo[nScreenNum].fExplicitScreen = TRUE; - - /* - * Keep track of the last screen number seen, as parameters seen - * before a screen number apply to all screens, whereas parameters - * seen after a screen number apply to that screen number only. - */ - g_iLastScreen = nScreenNum; - - /* Keep a count of the number of screens */ - ++g_iNumScreens; - - return iArgsProcessed; - } - - /* - * Look for the '-engine n' argument - */ - if (IS_OPTION ("-engine")) - { - DWORD dwEngine = 0; - CARD8 c8OnBits = 0; - - /* Display the usage message if the argument is malformed */ - if (++i >= argc) - { - UseMsg (); - return 0; - } - - /* Grab the argument */ - dwEngine = atoi (argv[i]); - - /* Count the one bits in the engine argument */ - c8OnBits = winCountBits (dwEngine); - - /* Argument should only have a single bit on */ - if (c8OnBits != 1) - { - UseMsg (); - return 0; - } - - /* Is this parameter attached to a screen or global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - g_ScreenInfo[j].dwEnginePreferred = dwEngine; - } - } - else - { - /* Parameter is for a single screen */ - g_ScreenInfo[g_iLastScreen].dwEnginePreferred = dwEngine; - } - - /* Indicate that we have processed the argument */ - return 2; - } - - /* - * Look for the '-fullscreen' argument - */ - if (IS_OPTION ("-fullscreen")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - if (!g_ScreenInfo[j].fMultiMonitorOverride) - g_ScreenInfo[j].fMultipleMonitors = FALSE; -#endif - g_ScreenInfo[j].fFullScreen = TRUE; - } - } - else - { - /* Parameter is for a single screen */ -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride) - g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE; -#endif - g_ScreenInfo[g_iLastScreen].fFullScreen = TRUE; - } - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-lesspointer' argument - */ - if (IS_OPTION ("-lesspointer")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - g_ScreenInfo[j].fLessPointer = TRUE; - } - } - else - { - /* Parameter is for a single screen */ - g_ScreenInfo[g_iLastScreen].fLessPointer = TRUE; - } - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-nodecoration' argument - */ - if (IS_OPTION ("-nodecoration")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - if (!g_ScreenInfo[j].fMultiMonitorOverride) - g_ScreenInfo[j].fMultipleMonitors = FALSE; -#endif - g_ScreenInfo[j].fDecoration = FALSE; - } - } - else - { - /* Parameter is for a single screen */ -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride) - g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE; -#endif - g_ScreenInfo[g_iLastScreen].fDecoration = FALSE; - } - - /* Indicate that we have processed this argument */ - return 1; - } - -#ifdef XWIN_MULTIWINDOWEXTWM - /* - * Look for the '-mwextwm' argument - */ - if (IS_OPTION ("-mwextwm")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - if (!g_ScreenInfo[j].fMultiMonitorOverride) - g_ScreenInfo[j].fMultipleMonitors = TRUE; - g_ScreenInfo[j].fMWExtWM = TRUE; - } - } - else - { - /* Parameter is for a single screen */ - if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride) - g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE; - g_ScreenInfo[g_iLastScreen].fMWExtWM = TRUE; - } - - /* Indicate that we have processed this argument */ - return 1; - } - /* - * Look for the '-internalwm' argument - */ - if (IS_OPTION ("-internalwm")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - if (!g_ScreenInfo[j].fMultiMonitorOverride) - g_ScreenInfo[j].fMultipleMonitors = TRUE; - g_ScreenInfo[j].fMWExtWM = TRUE; - g_ScreenInfo[j].fInternalWM = TRUE; - } - } - else - { - /* Parameter is for a single screen */ - if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride) - g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE; - g_ScreenInfo[g_iLastScreen].fMWExtWM = TRUE; - g_ScreenInfo[g_iLastScreen].fInternalWM = TRUE; - } - - /* Indicate that we have processed this argument */ - return 1; - } -#endif - - /* - * Look for the '-rootless' argument - */ - if (IS_OPTION ("-rootless")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - if (!g_ScreenInfo[j].fMultiMonitorOverride) - g_ScreenInfo[j].fMultipleMonitors = FALSE; -#endif - g_ScreenInfo[j].fRootless = TRUE; - } - } - else - { - /* Parameter is for a single screen */ -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride) - g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE; -#endif - g_ScreenInfo[g_iLastScreen].fRootless = TRUE; - } - - /* Indicate that we have processed this argument */ - return 1; - } - -#ifdef XWIN_MULTIWINDOW - /* - * Look for the '-multiwindow' argument - */ - if (IS_OPTION ("-multiwindow")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - if (!g_ScreenInfo[j].fMultiMonitorOverride) - g_ScreenInfo[j].fMultipleMonitors = TRUE; -#endif - g_ScreenInfo[j].fMultiWindow = TRUE; - } - } - else - { - /* Parameter is for a single screen */ -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride) - g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE; -#endif - g_ScreenInfo[g_iLastScreen].fMultiWindow = TRUE; - } - - /* Indicate that we have processed this argument */ - return 1; - } -#endif - - /* - * Look for the '-multiplemonitors' argument - */ - if (IS_OPTION ("-multiplemonitors") - || IS_OPTION ("-multimonitors")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - g_ScreenInfo[j].fMultiMonitorOverride = TRUE; -#endif - g_ScreenInfo[j].fMultipleMonitors = TRUE; - } - } - else - { - /* Parameter is for a single screen */ -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride = TRUE; -#endif - g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE; - } - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-nomultiplemonitors' argument - */ - if (IS_OPTION ("-nomultiplemonitors") - || IS_OPTION ("-nomultimonitors")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - g_ScreenInfo[j].fMultiMonitorOverride = TRUE; -#endif - g_ScreenInfo[j].fMultipleMonitors = FALSE; - } - } - else - { - /* Parameter is for a single screen */ -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride = TRUE; -#endif - g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE; - } - - /* Indicate that we have processed this argument */ - return 1; - } - - - /* - * Look for the '-scrollbars' argument - */ - if (IS_OPTION ("-scrollbars")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - g_ScreenInfo[j].fScrollbars = TRUE; - } - } - else - { - /* Parameter is for a single screen */ - g_ScreenInfo[g_iLastScreen].fScrollbars = TRUE; - } - - /* Indicate that we have processed this argument */ - return 1; - } - - -#ifdef XWIN_CLIPBOARD - /* - * Look for the '-clipboard' argument - */ - if (IS_OPTION ("-clipboard")) - { - /* Now the default, we still accept the arg for backwards compatibility */ - g_fClipboard = TRUE; - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-noclipboard' argument - */ - if (IS_OPTION ("-noclipboard")) - { - g_fClipboard = FALSE; - - /* Indicate that we have processed this argument */ - return 1; - } -#endif - - - /* - * Look for the '-ignoreinput' argument - */ - if (IS_OPTION ("-ignoreinput")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - g_ScreenInfo[j].fIgnoreInput = TRUE; - } - } - else - { - /* Parameter is for a single screen */ - g_ScreenInfo[g_iLastScreen].fIgnoreInput = TRUE; - } - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-emulate3buttons' argument - */ - if (IS_OPTION ("-emulate3buttons")) - { - int iArgsProcessed = 1; - int iE3BTimeout = WIN_DEFAULT_E3B_TIME; - - /* Grab the optional timeout value */ - if (i + 1 < argc - && 1 == sscanf (argv[i + 1], "%d", - &iE3BTimeout)) - { - /* Indicate that we have processed the next argument */ - iArgsProcessed++; - } - else - { - /* - * sscanf () won't modify iE3BTimeout if it doesn't find - * the specified format; however, I want to be explicit - * about setting the default timeout in such cases to - * prevent some programs (me) from getting confused. - */ - iE3BTimeout = WIN_DEFAULT_E3B_TIME; - } - - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - g_ScreenInfo[j].iE3BTimeout = iE3BTimeout; - } - } - else - { - /* Parameter is for a single screen */ - g_ScreenInfo[g_iLastScreen].iE3BTimeout = iE3BTimeout; - } - - /* Indicate that we have processed this argument */ - return iArgsProcessed; - } - - /* - * Look for the '-depth n' argument - */ - if (IS_OPTION ("-depth")) - { - DWORD dwBPP = 0; - - /* Display the usage message if the argument is malformed */ - if (++i >= argc) - { - UseMsg (); - return 0; - } - - /* Grab the argument */ - dwBPP = atoi (argv[i]); - - /* Is this parameter attached to a screen or global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - g_ScreenInfo[j].dwBPP = dwBPP; - } - } - else - { - /* Parameter is for a single screen */ - g_ScreenInfo[g_iLastScreen].dwBPP = dwBPP; - } - - /* Indicate that we have processed the argument */ - return 2; - } - - /* - * Look for the '-refresh n' argument - */ - if (IS_OPTION ("-refresh")) - { - DWORD dwRefreshRate = 0; - - /* Display the usage message if the argument is malformed */ - if (++i >= argc) - { - UseMsg (); - return 0; - } - - /* Grab the argument */ - dwRefreshRate = atoi (argv[i]); - - /* Is this parameter attached to a screen or global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - g_ScreenInfo[j].dwRefreshRate = dwRefreshRate; - } - } - else - { - /* Parameter is for a single screen */ - g_ScreenInfo[g_iLastScreen].dwRefreshRate = dwRefreshRate; - } - - /* Indicate that we have processed the argument */ - return 2; - } - - /* - * Look for the '-clipupdates num_boxes' argument - */ - if (IS_OPTION ("-clipupdates")) - { - DWORD dwNumBoxes = 0; - - /* Display the usage message if the argument is malformed */ - if (++i >= argc) - { - UseMsg (); - return 0; - } - - /* Grab the argument */ - dwNumBoxes = atoi (argv[i]); - - /* Is this parameter attached to a screen or global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - g_ScreenInfo[j].dwClipUpdatesNBoxes = dwNumBoxes; - } - } - else - { - /* Parameter is for a single screen */ - g_ScreenInfo[g_iLastScreen].dwClipUpdatesNBoxes = dwNumBoxes; - } - - /* Indicate that we have processed the argument */ - return 2; - } - -#ifdef XWIN_EMULATEPSEUDO - /* - * Look for the '-emulatepseudo' argument - */ - if (IS_OPTION ("-emulatepseudo")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - g_ScreenInfo[j].fEmulatePseudo = TRUE; - } - } - else - { - /* Parameter is for a single screen */ - g_ScreenInfo[g_iLastScreen].fEmulatePseudo = TRUE; - } - - /* Indicate that we have processed this argument */ - return 1; - } -#endif - - /* - * Look for the '-nowinkill' argument - */ - if (IS_OPTION ("-nowinkill")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - g_ScreenInfo[j].fUseWinKillKey = FALSE; - } - } - else - { - /* Parameter is for a single screen */ - g_ScreenInfo[g_iLastScreen].fUseWinKillKey = FALSE; - } - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-winkill' argument - */ - if (IS_OPTION ("-winkill")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - g_ScreenInfo[j].fUseWinKillKey = TRUE; - } - } - else - { - /* Parameter is for a single screen */ - g_ScreenInfo[g_iLastScreen].fUseWinKillKey = TRUE; - } - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-nounixkill' argument - */ - if (IS_OPTION ("-nounixkill")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - g_ScreenInfo[j].fUseUnixKillKey = FALSE; - } - } - else - { - /* Parameter is for a single screen */ - g_ScreenInfo[g_iLastScreen].fUseUnixKillKey = FALSE; - } - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-unixkill' argument - */ - if (IS_OPTION ("-unixkill")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - g_ScreenInfo[j].fUseUnixKillKey = TRUE; - } - } - else - { - /* Parameter is for a single screen */ - g_ScreenInfo[g_iLastScreen].fUseUnixKillKey = TRUE; - } - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-notrayicon' argument - */ - if (IS_OPTION ("-notrayicon")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - g_ScreenInfo[j].fNoTrayIcon = TRUE; - } - } - else - { - /* Parameter is for a single screen */ - g_ScreenInfo[g_iLastScreen].fNoTrayIcon = TRUE; - } - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-trayicon' argument - */ - if (IS_OPTION ("-trayicon")) - { - /* Is this parameter attached to a screen or is it global? */ - if (-1 == g_iLastScreen) - { - int j; - - /* Parameter is for all screens */ - for (j = 0; j < MAXSCREENS; j++) - { - g_ScreenInfo[j].fNoTrayIcon = FALSE; - } - } - else - { - /* Parameter is for a single screen */ - g_ScreenInfo[g_iLastScreen].fNoTrayIcon = FALSE; - } - - /* Indicate that we have processed this argument */ - return 1; - } - - /* - * Look for the '-fp' argument - */ - if (IS_OPTION ("-fp")) - { - CHECK_ARGS (1); - g_cmdline.fontPath = argv[++i]; - return 0; /* Let DIX parse this again */ - } - - /* - * Look for the '-query' argument - */ - if (IS_OPTION ("-query")) - { - CHECK_ARGS (1); - g_fXdmcpEnabled = TRUE; - g_pszQueryHost = argv[++i]; - return 0; /* Let DIX parse this again */ - } - - /* - * Look for the '-auth' argument - */ - if (IS_OPTION ("-auth")) - { - g_fAuthEnabled = TRUE; - return 0; /* Let DIX parse this again */ - } - - /* - * Look for the '-indirect' or '-broadcast' arguments - */ - if (IS_OPTION ("-indirect") - || IS_OPTION ("-broadcast")) - { - g_fXdmcpEnabled = TRUE; - return 0; /* Let DIX parse this again */ - } - - /* - * Look for the '-config' argument - */ - if (IS_OPTION ("-config") - || IS_OPTION ("-xf86config")) - { - CHECK_ARGS (1); -#ifdef XWIN_XF86CONFIG - g_cmdline.configFile = argv[++i]; -#else - winMessageBoxF ("The %s option is not supported in this " - "release.\n" - "Ignoring this option and continuing.\n", - MB_ICONINFORMATION, - argv[i]); -#endif - return 2; - } - - /* - * Look for the '-configdir' argument - */ - if (IS_OPTION ("-configdir")) - { - CHECK_ARGS (1); -#ifdef XWIN_XF86CONFIG - g_cmdline.configDir = argv[++i]; -#else - winMessageBoxF ("The %s option is not supported in this " - "release.\n" - "Ignoring this option and continuing.\n", - MB_ICONINFORMATION, - argv[i]); -#endif - return 2; - } - - /* - * Look for the '-keyboard' argument - */ - if (IS_OPTION ("-keyboard")) - { -#ifdef XWIN_XF86CONFIG - CHECK_ARGS (1); - g_cmdline.keyboard = argv[++i]; -#else - winMessageBoxF ("The -keyboard option is not supported in this " - "release.\n" - "Ignoring this option and continuing.\n", - MB_ICONINFORMATION); -#endif - return 2; - } - - /* - * Look for the '-logfile' argument - */ - if (IS_OPTION ("-logfile")) - { - CHECK_ARGS (1); - g_pszLogFile = argv[++i]; -#ifdef RELOCATE_PROJECTROOT - g_fLogFileChanged = TRUE; -#endif - return 2; - } - - /* - * Look for the '-logverbose' argument - */ - if (IS_OPTION ("-logverbose")) - { - CHECK_ARGS (1); - g_iLogVerbose = atoi(argv[++i]); - return 2; - } - -#ifdef XWIN_CLIPBOARD - /* - * Look for the '-nounicodeclipboard' argument - */ - if (IS_OPTION ("-nounicodeclipboard")) - { - g_fUnicodeClipboard = FALSE; - /* Indicate that we have processed the argument */ - return 1; - } -#endif - - if (IS_OPTION ("-xkbrules")) - { - CHECK_ARGS (1); - g_cmdline.xkbRules = argv[++i]; - return 2; - } - if (IS_OPTION ("-xkbmodel")) - { - CHECK_ARGS (1); - g_cmdline.xkbModel = argv[++i]; - return 2; - } - if (IS_OPTION ("-xkblayout")) - { - CHECK_ARGS (1); - g_cmdline.xkbLayout = argv[++i]; - return 2; - } - if (IS_OPTION ("-xkbvariant")) - { - CHECK_ARGS (1); - g_cmdline.xkbVariant = argv[++i]; - return 2; - } - if (IS_OPTION ("-xkboptions")) - { - CHECK_ARGS (1); - g_cmdline.xkbOptions = argv[++i]; - return 2; - } - - if (IS_OPTION ("-keyhook")) - { - g_fKeyboardHookLL = TRUE; - return 1; - } - - if (IS_OPTION ("-nokeyhook")) - { - g_fKeyboardHookLL = FALSE; - return 1; - } - - if (IS_OPTION ("-swcursor")) - { - g_fSoftwareCursor = TRUE; - return 1; - } - - if (IS_OPTION ("-silent-dup-error")) - { - g_fSilentDupError = TRUE; - return 1; - } - return 0; -} - - -/* - * winLogCommandLine - Write entire command line to the log file - */ - -void -winLogCommandLine (int argc, char *argv[]) -{ - int i; - int iSize = 0; - int iCurrLen = 0; - -#define CHARS_PER_LINE 60 - - /* Bail if command line has already been logged */ - if (g_pszCommandLine) - return; - - /* Count how much memory is needed for concatenated command line */ - for (i = 0, iCurrLen = 0; i < argc; ++i) - if (argv[i]) - { - /* Adds two characters for lines that overflow */ - if ((strlen (argv[i]) < CHARS_PER_LINE - && iCurrLen + strlen (argv[i]) > CHARS_PER_LINE) - || strlen (argv[i]) > CHARS_PER_LINE) - { - iCurrLen = 0; - iSize += 2; - } - - /* Add space for item and trailing space */ - iSize += strlen (argv[i]) + 1; - - /* Update current line length */ - iCurrLen += strlen (argv[i]); - } - - /* Allocate memory for concatenated command line */ - g_pszCommandLine = malloc (iSize + 1); - if (!g_pszCommandLine) - FatalError ("winLogCommandLine - Could not allocate memory for " - "command line string. Exiting.\n"); - - /* Set first character to concatenated command line to null */ - g_pszCommandLine[0] = '\0'; - - /* Loop through all args */ - for (i = 0, iCurrLen = 0; i < argc; ++i) - { - /* Add a character for lines that overflow */ - if ((strlen (argv[i]) < CHARS_PER_LINE - && iCurrLen + strlen (argv[i]) > CHARS_PER_LINE) - || strlen (argv[i]) > CHARS_PER_LINE) - { - iCurrLen = 0; - - /* Add line break if it fits */ - strncat (g_pszCommandLine, "\n ", iSize - strlen (g_pszCommandLine)); - } - - strncat (g_pszCommandLine, argv[i], iSize - strlen (g_pszCommandLine)); - strncat (g_pszCommandLine, " ", iSize - strlen (g_pszCommandLine)); - - /* Save new line length */ - iCurrLen += strlen (argv[i]); - } - - ErrorF ("XWin was started with the following command line:\n\n" - "%s\n\n", g_pszCommandLine); -} - - -/* - * winLogVersionInfo - Log Cygwin/X version information - */ - -void -winLogVersionInfo (void) -{ - static Bool s_fBeenHere = FALSE; - - if (s_fBeenHere) - return; - s_fBeenHere = TRUE; - - ErrorF ("Welcome to the XWin X Server\n"); - ErrorF ("Vendor: %s\n", VENDOR_STRING); - ErrorF ("Release: %d.%d.%d.%d (%d)\n", XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH, XORG_VERSION_SNAP, XORG_VERSION_CURRENT); - ErrorF ("%s\n\n", BUILDERSTRING); - ErrorF ("Contact: %s\n", VENDOR_CONTACT); -} - -/* - * getMonitorInfo - callback function used to return information from the enumeration of monitors attached - */ - -wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data) -{ - struct GetMonitorInfoData* data = (struct GetMonitorInfoData*)_data; - // only get data for monitor number specified in <data> - data->monitorNum++; - if (data->monitorNum == data->requestedMonitor) - { - data->bMonitorSpecifiedExists = TRUE; - data->monitorOffsetX = rect->left; - data->monitorOffsetY = rect->top; - data->monitorHeight = rect->bottom - rect->top; - data->monitorWidth = rect->right - rect->left; - return FALSE; - } - return TRUE; -} +/*
+
+Copyright 1993, 1998 The Open Group
+Copyright (C) Colin Harrison 2005-2008
+
+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.
+
+*/
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#ifdef XVENDORNAME
+#define VENDOR_STRING XVENDORNAME
+#define VENDOR_CONTACT BUILDERADDR
+#endif
+#include <../xfree86/common/xorgVersion.h>
+#include "win.h"
+#include "winconfig.h"
+#include "winprefs.h"
+#include "winmsg.h"
+#define COMPILE_MULTIMON_STUBS
+#include <multimon.h>
+/*
+ * References to external symbols
+ */
+
+extern int g_iNumScreens;
+extern winScreenInfo g_ScreenInfo[];
+extern int g_iLastScreen;
+extern Bool g_fInitializedDefaultScreens;
+#ifdef XWIN_CLIPBOARD
+extern Bool g_fUnicodeClipboard;
+extern Bool g_fClipboard;
+#endif
+extern int g_iLogVerbose;
+extern const char * g_pszLogFile;
+#ifdef RELOCATE_PROJECTROOT
+extern Bool g_fLogFileChanged;
+#endif
+extern Bool g_fXdmcpEnabled;
+extern Bool g_fAuthEnabled;
+extern char * g_pszCommandLine;
+extern Bool g_fKeyboardHookLL;
+extern Bool g_fNoHelpMessageBox;
+extern Bool g_fSoftwareCursor;
+extern Bool g_fSilentDupError;
+extern Bool g_fNativeGl;
+
+/* globals required by callback function for monitor information */
+struct GetMonitorInfoData {
+ int requestedMonitor;
+ int monitorNum;
+ Bool bUserSpecifiedMonitor;
+ Bool bMonitorSpecifiedExists;
+ int monitorOffsetX;
+ int monitorOffsetY;
+ int monitorHeight;
+ int monitorWidth;
+};
+
+wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data);
+
+static Bool QueryMonitor(int index, struct GetMonitorInfoData *data)
+{
+ /* prepare data */
+ if (data == NULL)
+ return FALSE;
+ memset(data, 0, sizeof(*data));
+ data->requestedMonitor = index;
+
+ /* query information */
+ xEnumDisplayMonitors(NULL, NULL, getMonitorInfo, (LPARAM) data);
+
+ return TRUE;
+}
+
+/*
+ * Function prototypes
+ */
+
+void
+winLogCommandLine (int argc, char *argv[]);
+
+void
+winLogVersionInfo (void);
+
+#ifdef DDXOSVERRORF
+void OsVendorVErrorF (const char *pszFormat, va_list va_args);
+#endif
+
+void
+winInitializeDefaultScreens (void);
+
+/*
+ * Process arguments on the command line
+ */
+
+void
+winInitializeDefaultScreens (void)
+{
+ int i;
+ DWORD dwWidth, dwHeight;
+
+ /* Bail out early if default screens have already been initialized */
+ if (g_fInitializedDefaultScreens)
+ return;
+
+ /* Zero the memory used for storing the screen info */
+ ZeroMemory (g_ScreenInfo, MAXSCREENS * sizeof (winScreenInfo));
+
+ /* Get default width and height */
+ /*
+ * NOTE: These defaults will cause the window to cover only
+ * the primary monitor in the case that we have multiple monitors.
+ */
+ dwWidth = GetSystemMetrics (SM_CXSCREEN);
+ dwHeight = GetSystemMetrics (SM_CYSCREEN);
+
+ winDebug ("winInitializeDefaultScreens - w %d h %d\n",
+ (int) dwWidth, (int) dwHeight);
+
+ /* Set a default DPI, if no parameter was passed */
+ if (monitorResolution == 0)
+ monitorResolution = WIN_DEFAULT_DPI;
+
+ for (i = 0; i < MAXSCREENS; ++i)
+ {
+ g_ScreenInfo[i].dwScreen = i;
+ g_ScreenInfo[i].dwWidth = dwWidth;
+ g_ScreenInfo[i].dwHeight = dwHeight;
+ g_ScreenInfo[i].dwUserWidth = dwWidth;
+ g_ScreenInfo[i].dwUserHeight = dwHeight;
+ g_ScreenInfo[i].fUserGaveHeightAndWidth
+ = WIN_DEFAULT_USER_GAVE_HEIGHT_AND_WIDTH;
+ g_ScreenInfo[i].fUserGavePosition = FALSE;
+ g_ScreenInfo[i].dwBPP = WIN_DEFAULT_BPP;
+ g_ScreenInfo[i].dwClipUpdatesNBoxes = WIN_DEFAULT_CLIP_UPDATES_NBOXES;
+#ifdef XWIN_EMULATEPSEUDO
+ g_ScreenInfo[i].fEmulatePseudo = WIN_DEFAULT_EMULATE_PSEUDO;
+#endif
+ g_ScreenInfo[i].dwRefreshRate = WIN_DEFAULT_REFRESH;
+ g_ScreenInfo[i].pfb = NULL;
+ g_ScreenInfo[i].fFullScreen = FALSE;
+ g_ScreenInfo[i].fDecoration = TRUE;
+#ifdef XWIN_MULTIWINDOWEXTWM
+ g_ScreenInfo[i].fMWExtWM = FALSE;
+ g_ScreenInfo[i].fInternalWM = FALSE;
+#endif
+ g_ScreenInfo[i].fRootless = FALSE;
+#ifdef XWIN_MULTIWINDOW
+ g_ScreenInfo[i].fMultiWindow = FALSE;
+#endif
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ g_ScreenInfo[i].fMultiMonitorOverride = FALSE;
+#endif
+ g_ScreenInfo[i].fMultipleMonitors = FALSE;
+ g_ScreenInfo[i].fLessPointer = FALSE;
+ g_ScreenInfo[i].fScrollbars = FALSE;
+ g_ScreenInfo[i].fNoTrayIcon = FALSE;
+ g_ScreenInfo[i].iE3BTimeout = WIN_E3B_OFF;
+ g_ScreenInfo[i].dwWidth_mm = (dwWidth / WIN_DEFAULT_DPI)
+ * 25.4;
+ g_ScreenInfo[i].dwHeight_mm = (dwHeight / WIN_DEFAULT_DPI)
+ * 25.4;
+ g_ScreenInfo[i].fUseWinKillKey = WIN_DEFAULT_WIN_KILL;
+ g_ScreenInfo[i].fUseUnixKillKey = WIN_DEFAULT_UNIX_KILL;
+ g_ScreenInfo[i].fIgnoreInput = FALSE;
+ g_ScreenInfo[i].fExplicitScreen = FALSE;
+ }
+
+ /* Signal that the default screens have been initialized */
+ g_fInitializedDefaultScreens = TRUE;
+
+ winDebug ("winInitializeDefaultScreens - Returning\n");
+}
+
+/* See Porting Layer Definition - p. 57 */
+/*
+ * INPUT
+ * argv: pointer to an array of null-terminated strings, one for
+ * each token in the X Server command line; the first token
+ * is 'XWin.exe', or similar.
+ * argc: a count of the number of tokens stored in argv.
+ * i: a zero-based index into argv indicating the current token being
+ * processed.
+ *
+ * OUTPUT
+ * return: return the number of tokens processed correctly.
+ *
+ * NOTE
+ * When looking for n tokens, check that i + n is less than argc. Or,
+ * you may check if i is greater than or equal to argc, in which case
+ * you should display the UseMsg () and return 0.
+ */
+
+/* Check if enough arguments are given for the option */
+#define CHECK_ARGS(count) if (i + count >= argc) { UseMsg (); return 0; }
+
+/* Compare the current option with the string. */
+#define IS_OPTION(name) (strcmp (argv[i], name) == 0)
+
+int
+ddxProcessArgument (int argc, char *argv[], int i)
+{
+ static Bool s_fBeenHere = FALSE;
+
+ /* Initialize once */
+ if (!s_fBeenHere)
+ {
+#ifdef DDXOSVERRORF
+ /*
+ * This initialises our hook into VErrorF () for catching log messages
+ * that are generated before OsInit () is called.
+ */
+ OsVendorVErrorFProc = OsVendorVErrorF;
+#endif
+
+ s_fBeenHere = TRUE;
+
+ /* Initialize only if option is not -help */
+ if (!IS_OPTION("-help") && !IS_OPTION("-h") && !IS_OPTION("--help") &&
+ !IS_OPTION("-version") && !IS_OPTION("--version"))
+ {
+
+ /* Log the version information */
+ winLogVersionInfo ();
+
+ /* Log the command line */
+ winLogCommandLine (argc, argv);
+
+ /*
+ * Initialize default screen settings. We have to do this before
+ * OsVendorInit () gets called, otherwise we will overwrite
+ * settings changed by parameters such as -fullscreen, etc.
+ */
+ winDebug ("ddxProcessArgument - Initializing default "
+ "screens\n");
+ winInitializeDefaultScreens ();
+ }
+ }
+
+ winDebug ("ddxProcessArgument - arg: %s\n", argv[i]);
+
+ /*
+ * Look for the '-help' and similar options
+ */
+ if (IS_OPTION ("-help") || IS_OPTION("-h") || IS_OPTION("--help"))
+ {
+ /* Reset logfile. We don't need that helpmessage in the logfile */
+ g_pszLogFile = NULL;
+ g_fNoHelpMessageBox = TRUE;
+ UseMsg();
+ exit (0);
+ return 1;
+ }
+
+ if (IS_OPTION ("-version") || IS_OPTION("--version"))
+ {
+ /* Reset logfile. We don't need that versioninfo in the logfile */
+ g_pszLogFile = NULL;
+ winLogVersionInfo ();
+ exit (0);
+ return 1;
+ }
+
+ /*
+ * Look for the '-screen scr_num [width height]' argument
+ */
+ if (IS_OPTION ("-screen"))
+ {
+ int iArgsProcessed = 1;
+ int nScreenNum;
+ int iWidth, iHeight, iX, iY;
+ int iMonitor;
+
+ winDebug ("ddxProcessArgument - screen - argc: %d i: %d\n",
+ argc, i);
+
+ /* Display the usage message if the argument is malformed */
+ if (i + 1 >= argc)
+ {
+ return 0;
+ }
+
+ /* Grab screen number */
+ nScreenNum = atoi (argv[i + 1]);
+
+ /* Validate the specified screen number */
+ if (nScreenNum < 0 || nScreenNum >= MAXSCREENS)
+ {
+ ErrorF ("ddxProcessArgument - screen - Invalid screen number %d\n",
+ nScreenNum);
+ UseMsg ();
+ return 0;
+ }
+
+ /* look for @m where m is monitor number */
+ if (i + 2 < argc
+ && 1 == sscanf(argv[i + 2], "@%d", (int *) &iMonitor))
+ {
+ struct GetMonitorInfoData data;
+ if (!QueryMonitor(iMonitor, &data))
+ {
+ ErrorF ("ddxProcessArgument - screen - "
+ "Querying monitors is not supported on NT4 and Win95\n");
+ } else if (data.bMonitorSpecifiedExists == TRUE)
+ {
+ winDebug("ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor);
+ iArgsProcessed = 3;
+ g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE;
+ g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
+ g_ScreenInfo[nScreenNum].dwWidth = data.monitorWidth;
+ g_ScreenInfo[nScreenNum].dwHeight = data.monitorHeight;
+ g_ScreenInfo[nScreenNum].dwUserWidth = data.monitorWidth;
+ g_ScreenInfo[nScreenNum].dwUserHeight = data.monitorHeight;
+ g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX;
+ g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY;
+ }
+ else
+ {
+ /* monitor does not exist, error out */
+ ErrorF ("ddxProcessArgument - screen - Invalid monitor number %d\n",
+ iMonitor);
+ UseMsg ();
+ exit (0);
+ return 0;
+ }
+ }
+
+ /* Look for 'WxD' or 'W D' */
+ else if (i + 2 < argc
+ && 2 == sscanf (argv[i + 2], "%dx%d",
+ (int *) &iWidth,
+ (int *) &iHeight))
+ {
+ winDebug ("ddxProcessArgument - screen - Found ``WxD'' arg\n");
+ iArgsProcessed = 3;
+ g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE;
+ g_ScreenInfo[nScreenNum].dwWidth = iWidth;
+ g_ScreenInfo[nScreenNum].dwHeight = iHeight;
+ g_ScreenInfo[nScreenNum].dwUserWidth = iWidth;
+ g_ScreenInfo[nScreenNum].dwUserHeight = iHeight;
+ /* Look for WxD+X+Y */
+ if (2 == sscanf (argv[i + 2], "%*dx%*d+%d+%d",
+ (int *) &iX,
+ (int *) &iY))
+ {
+ winDebug("ddxProcessArgument - screen - Found ``X+Y'' arg\n");
+ g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
+ g_ScreenInfo[nScreenNum].dwInitialX = iX;
+ g_ScreenInfo[nScreenNum].dwInitialY = iY;
+
+ /* look for WxD+X+Y@m where m is monitor number. take X,Y to be offsets from monitor's root position */
+ if (1 == sscanf (argv[i + 2], "%*dx%*d+%*d+%*d@%d",
+ (int *) &iMonitor))
+ {
+ struct GetMonitorInfoData data;
+ if (!QueryMonitor(iMonitor, &data))
+ {
+ ErrorF ("ddxProcessArgument - screen - "
+ "Querying monitors is not supported on NT4 and Win95\n");
+ } else if (data.bMonitorSpecifiedExists == TRUE)
+ {
+ g_ScreenInfo[nScreenNum].dwInitialX += data.monitorOffsetX;
+ g_ScreenInfo[nScreenNum].dwInitialY += data.monitorOffsetY;
+ }
+ else
+ {
+ /* monitor does not exist, error out */
+ ErrorF ("ddxProcessArgument - screen - Invalid monitor number %d\n",
+ iMonitor);
+ UseMsg ();
+ exit (0);
+ return 0;
+ }
+
+ }
+ }
+
+ /* look for WxD@m where m is monitor number */
+ else if (1 == sscanf(argv[i + 2], "%*dx%*d@%d",
+ (int *) &iMonitor))
+ {
+ struct GetMonitorInfoData data;
+ if (!QueryMonitor(iMonitor, &data))
+ {
+ ErrorF ("ddxProcessArgument - screen - "
+ "Querying monitors is not supported on NT4 and Win95\n");
+ } else if (data.bMonitorSpecifiedExists == TRUE)
+ {
+ winDebug ("ddxProcessArgument - screen - Found Valid ``@Monitor'' = %d arg\n", iMonitor);
+ g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
+ g_ScreenInfo[nScreenNum].dwInitialX = data.monitorOffsetX;
+ g_ScreenInfo[nScreenNum].dwInitialY = data.monitorOffsetY;
+ }
+ else
+ {
+ /* monitor does not exist, error out */
+ ErrorF ("ddxProcessArgument - screen - Invalid monitor number %d\n",
+ iMonitor);
+ UseMsg ();
+ exit (0);
+ return 0;
+ }
+
+ }
+ }
+ else if (i + 3 < argc
+ && 1 == sscanf (argv[i + 2], "%d",
+ (int *) &iWidth)
+ && 1 == sscanf (argv[i + 3], "%d",
+ (int *) &iHeight))
+ {
+ winDebug ("ddxProcessArgument - screen - Found ``W D'' arg\n");
+ iArgsProcessed = 4;
+ g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = TRUE;
+ g_ScreenInfo[nScreenNum].dwWidth = iWidth;
+ g_ScreenInfo[nScreenNum].dwHeight = iHeight;
+ g_ScreenInfo[nScreenNum].dwUserWidth = iWidth;
+ g_ScreenInfo[nScreenNum].dwUserHeight = iHeight;
+ if (i + 5 < argc
+ && 1 == sscanf (argv[i + 4], "%d",
+ (int *) &iX)
+ && 1 == sscanf (argv[i + 5], "%d",
+ (int *) &iY))
+ {
+ winDebug ("ddxProcessArgument - screen - Found ``X Y'' arg\n");
+ iArgsProcessed = 6;
+ g_ScreenInfo[nScreenNum].fUserGavePosition = TRUE;
+ g_ScreenInfo[nScreenNum].dwInitialX = iX;
+ g_ScreenInfo[nScreenNum].dwInitialY = iY;
+ }
+ }
+ else
+ {
+ ErrorF ("ddxProcessArgument - screen - Did not find size arg. "
+ "dwWidth: %d dwHeight: %d\n",
+ (int) g_ScreenInfo[nScreenNum].dwWidth,
+ (int) g_ScreenInfo[nScreenNum].dwHeight);
+ iArgsProcessed = 2;
+ g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth = FALSE;
+ }
+
+ /* Calculate the screen width and height in millimeters */
+ if (g_ScreenInfo[nScreenNum].fUserGaveHeightAndWidth)
+ {
+ g_ScreenInfo[nScreenNum].dwWidth_mm
+ = (g_ScreenInfo[nScreenNum].dwWidth
+ / monitorResolution) * 25.4;
+ g_ScreenInfo[nScreenNum].dwHeight_mm
+ = (g_ScreenInfo[nScreenNum].dwHeight
+ / monitorResolution) * 25.4;
+ }
+
+ /* Flag that this screen was explicity specified by the user */
+ g_ScreenInfo[nScreenNum].fExplicitScreen = TRUE;
+
+ /*
+ * Keep track of the last screen number seen, as parameters seen
+ * before a screen number apply to all screens, whereas parameters
+ * seen after a screen number apply to that screen number only.
+ */
+ g_iLastScreen = nScreenNum;
+
+ /* Keep a count of the number of screens */
+ ++g_iNumScreens;
+
+ return iArgsProcessed;
+ }
+
+ /*
+ * Look for the '-engine n' argument
+ */
+ if (IS_OPTION ("-engine"))
+ {
+ DWORD dwEngine = 0;
+ CARD8 c8OnBits = 0;
+
+ /* Display the usage message if the argument is malformed */
+ if (++i >= argc)
+ {
+ UseMsg ();
+ return 0;
+ }
+
+ /* Grab the argument */
+ dwEngine = atoi (argv[i]);
+
+ /* Count the one bits in the engine argument */
+ c8OnBits = winCountBits (dwEngine);
+
+ /* Argument should only have a single bit on */
+ if (c8OnBits != 1)
+ {
+ UseMsg ();
+ return 0;
+ }
+
+ /* Is this parameter attached to a screen or global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].dwEnginePreferred = dwEngine;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].dwEnginePreferred = dwEngine;
+ }
+
+ /* Indicate that we have processed the argument */
+ return 2;
+ }
+
+ /*
+ * Look for the '-fullscreen' argument
+ */
+ if (IS_OPTION ("-fullscreen"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ if (!g_ScreenInfo[j].fMultiMonitorOverride)
+ g_ScreenInfo[j].fMultipleMonitors = FALSE;
+#endif
+ g_ScreenInfo[j].fFullScreen = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride)
+ g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE;
+#endif
+ g_ScreenInfo[g_iLastScreen].fFullScreen = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
+ * Look for the '-lesspointer' argument
+ */
+ if (IS_OPTION ("-lesspointer"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].fLessPointer = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].fLessPointer = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
+ * Look for the '-nodecoration' argument
+ */
+ if (IS_OPTION ("-nodecoration"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ if (!g_ScreenInfo[j].fMultiMonitorOverride)
+ g_ScreenInfo[j].fMultipleMonitors = FALSE;
+#endif
+ g_ScreenInfo[j].fDecoration = FALSE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride)
+ g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE;
+#endif
+ g_ScreenInfo[g_iLastScreen].fDecoration = FALSE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+ /*
+ * Look for the '-mwextwm' argument
+ */
+ if (IS_OPTION ("-mwextwm"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ if (!g_ScreenInfo[j].fMultiMonitorOverride)
+ g_ScreenInfo[j].fMultipleMonitors = TRUE;
+ g_ScreenInfo[j].fMWExtWM = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride)
+ g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE;
+ g_ScreenInfo[g_iLastScreen].fMWExtWM = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+ /*
+ * Look for the '-internalwm' argument
+ */
+ if (IS_OPTION ("-internalwm"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ if (!g_ScreenInfo[j].fMultiMonitorOverride)
+ g_ScreenInfo[j].fMultipleMonitors = TRUE;
+ g_ScreenInfo[j].fMWExtWM = TRUE;
+ g_ScreenInfo[j].fInternalWM = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride)
+ g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE;
+ g_ScreenInfo[g_iLastScreen].fMWExtWM = TRUE;
+ g_ScreenInfo[g_iLastScreen].fInternalWM = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+#endif
+
+ /*
+ * Look for the '-rootless' argument
+ */
+ if (IS_OPTION ("-rootless"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ if (!g_ScreenInfo[j].fMultiMonitorOverride)
+ g_ScreenInfo[j].fMultipleMonitors = FALSE;
+#endif
+ g_ScreenInfo[j].fRootless = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride)
+ g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE;
+#endif
+ g_ScreenInfo[g_iLastScreen].fRootless = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+#ifdef XWIN_MULTIWINDOW
+ /*
+ * Look for the '-multiwindow' argument
+ */
+ if (IS_OPTION ("-multiwindow"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ if (!g_ScreenInfo[j].fMultiMonitorOverride)
+ g_ScreenInfo[j].fMultipleMonitors = TRUE;
+#endif
+ g_ScreenInfo[j].fMultiWindow = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ if (!g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride)
+ g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE;
+#endif
+ g_ScreenInfo[g_iLastScreen].fMultiWindow = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+#endif
+
+ /*
+ * Look for the '-multiplemonitors' argument
+ */
+ if (IS_OPTION ("-multiplemonitors")
+ || IS_OPTION ("-multimonitors"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ g_ScreenInfo[j].fMultiMonitorOverride = TRUE;
+#endif
+ g_ScreenInfo[j].fMultipleMonitors = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride = TRUE;
+#endif
+ g_ScreenInfo[g_iLastScreen].fMultipleMonitors = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
+ * Look for the '-nomultiplemonitors' argument
+ */
+ if (IS_OPTION ("-nomultiplemonitors")
+ || IS_OPTION ("-nomultimonitors"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ g_ScreenInfo[j].fMultiMonitorOverride = TRUE;
+#endif
+ g_ScreenInfo[j].fMultipleMonitors = FALSE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ g_ScreenInfo[g_iLastScreen].fMultiMonitorOverride = TRUE;
+#endif
+ g_ScreenInfo[g_iLastScreen].fMultipleMonitors = FALSE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+
+ /*
+ * Look for the '-scrollbars' argument
+ */
+ if (IS_OPTION ("-scrollbars"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].fScrollbars = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].fScrollbars = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+
+#ifdef XWIN_CLIPBOARD
+ /*
+ * Look for the '-clipboard' argument
+ */
+ if (IS_OPTION ("-clipboard"))
+ {
+ /* Now the default, we still accept the arg for backwards compatibility */
+ g_fClipboard = TRUE;
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
+ * Look for the '-noclipboard' argument
+ */
+ if (IS_OPTION ("-noclipboard"))
+ {
+ g_fClipboard = FALSE;
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+#endif
+
+
+ /*
+ * Look for the '-ignoreinput' argument
+ */
+ if (IS_OPTION ("-ignoreinput"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].fIgnoreInput = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].fIgnoreInput = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
+ * Look for the '-emulate3buttons' argument
+ */
+ if (IS_OPTION ("-emulate3buttons"))
+ {
+ int iArgsProcessed = 1;
+ int iE3BTimeout = WIN_DEFAULT_E3B_TIME;
+
+ /* Grab the optional timeout value */
+ if (i + 1 < argc
+ && 1 == sscanf (argv[i + 1], "%d",
+ &iE3BTimeout))
+ {
+ /* Indicate that we have processed the next argument */
+ iArgsProcessed++;
+ }
+ else
+ {
+ /*
+ * sscanf () won't modify iE3BTimeout if it doesn't find
+ * the specified format; however, I want to be explicit
+ * about setting the default timeout in such cases to
+ * prevent some programs (me) from getting confused.
+ */
+ iE3BTimeout = WIN_DEFAULT_E3B_TIME;
+ }
+
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].iE3BTimeout = iE3BTimeout;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].iE3BTimeout = iE3BTimeout;
+ }
+
+ /* Indicate that we have processed this argument */
+ return iArgsProcessed;
+ }
+
+ /*
+ * Look for the '-depth n' argument
+ */
+ if (IS_OPTION ("-depth"))
+ {
+ DWORD dwBPP = 0;
+
+ /* Display the usage message if the argument is malformed */
+ if (++i >= argc)
+ {
+ UseMsg ();
+ return 0;
+ }
+
+ /* Grab the argument */
+ dwBPP = atoi (argv[i]);
+
+ /* Is this parameter attached to a screen or global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].dwBPP = dwBPP;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].dwBPP = dwBPP;
+ }
+
+ /* Indicate that we have processed the argument */
+ return 2;
+ }
+
+ /*
+ * Look for the '-refresh n' argument
+ */
+ if (IS_OPTION ("-refresh"))
+ {
+ DWORD dwRefreshRate = 0;
+
+ /* Display the usage message if the argument is malformed */
+ if (++i >= argc)
+ {
+ UseMsg ();
+ return 0;
+ }
+
+ /* Grab the argument */
+ dwRefreshRate = atoi (argv[i]);
+
+ /* Is this parameter attached to a screen or global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].dwRefreshRate = dwRefreshRate;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].dwRefreshRate = dwRefreshRate;
+ }
+
+ /* Indicate that we have processed the argument */
+ return 2;
+ }
+
+ /*
+ * Look for the '-clipupdates num_boxes' argument
+ */
+ if (IS_OPTION ("-clipupdates"))
+ {
+ DWORD dwNumBoxes = 0;
+
+ /* Display the usage message if the argument is malformed */
+ if (++i >= argc)
+ {
+ UseMsg ();
+ return 0;
+ }
+
+ /* Grab the argument */
+ dwNumBoxes = atoi (argv[i]);
+
+ /* Is this parameter attached to a screen or global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].dwClipUpdatesNBoxes = dwNumBoxes;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].dwClipUpdatesNBoxes = dwNumBoxes;
+ }
+
+ /* Indicate that we have processed the argument */
+ return 2;
+ }
+
+#ifdef XWIN_EMULATEPSEUDO
+ /*
+ * Look for the '-emulatepseudo' argument
+ */
+ if (IS_OPTION ("-emulatepseudo"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].fEmulatePseudo = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].fEmulatePseudo = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+#endif
+
+ /*
+ * Look for the '-nowinkill' argument
+ */
+ if (IS_OPTION ("-nowinkill"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].fUseWinKillKey = FALSE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].fUseWinKillKey = FALSE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
+ * Look for the '-winkill' argument
+ */
+ if (IS_OPTION ("-winkill"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].fUseWinKillKey = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].fUseWinKillKey = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
+ * Look for the '-nounixkill' argument
+ */
+ if (IS_OPTION ("-nounixkill"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].fUseUnixKillKey = FALSE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].fUseUnixKillKey = FALSE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
+ * Look for the '-unixkill' argument
+ */
+ if (IS_OPTION ("-unixkill"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].fUseUnixKillKey = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].fUseUnixKillKey = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
+ * Look for the '-notrayicon' argument
+ */
+ if (IS_OPTION ("-notrayicon"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].fNoTrayIcon = TRUE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].fNoTrayIcon = TRUE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
+ * Look for the '-trayicon' argument
+ */
+ if (IS_OPTION ("-trayicon"))
+ {
+ /* Is this parameter attached to a screen or is it global? */
+ if (-1 == g_iLastScreen)
+ {
+ int j;
+
+ /* Parameter is for all screens */
+ for (j = 0; j < MAXSCREENS; j++)
+ {
+ g_ScreenInfo[j].fNoTrayIcon = FALSE;
+ }
+ }
+ else
+ {
+ /* Parameter is for a single screen */
+ g_ScreenInfo[g_iLastScreen].fNoTrayIcon = FALSE;
+ }
+
+ /* Indicate that we have processed this argument */
+ return 1;
+ }
+
+ /*
+ * Look for the '-fp' argument
+ */
+ if (IS_OPTION ("-fp"))
+ {
+ CHECK_ARGS (1);
+ g_cmdline.fontPath = argv[++i];
+ return 0; /* Let DIX parse this again */
+ }
+
+ /*
+ * Look for the '-query' argument
+ */
+ if (IS_OPTION ("-query"))
+ {
+ CHECK_ARGS (1);
+ g_fXdmcpEnabled = TRUE;
+ g_pszQueryHost = argv[++i];
+ return 0; /* Let DIX parse this again */
+ }
+
+ /*
+ * Look for the '-auth' argument
+ */
+ if (IS_OPTION ("-auth"))
+ {
+ g_fAuthEnabled = TRUE;
+ return 0; /* Let DIX parse this again */
+ }
+
+ /*
+ * Look for the '-indirect' or '-broadcast' arguments
+ */
+ if (IS_OPTION ("-indirect")
+ || IS_OPTION ("-broadcast"))
+ {
+ g_fXdmcpEnabled = TRUE;
+ return 0; /* Let DIX parse this again */
+ }
+
+ /*
+ * Look for the '-config' argument
+ */
+ if (IS_OPTION ("-config")
+ || IS_OPTION ("-xf86config"))
+ {
+ CHECK_ARGS (1);
+#ifdef XWIN_XF86CONFIG
+ g_cmdline.configFile = argv[++i];
+#else
+ winMessageBoxF ("The %s option is not supported in this "
+ "release.\n"
+ "Ignoring this option and continuing.\n",
+ MB_ICONINFORMATION,
+ argv[i]);
+#endif
+ return 2;
+ }
+
+ /*
+ * Look for the '-configdir' argument
+ */
+ if (IS_OPTION ("-configdir"))
+ {
+ CHECK_ARGS (1);
+#ifdef XWIN_XF86CONFIG
+ g_cmdline.configDir = argv[++i];
+#else
+ winMessageBoxF ("The %s option is not supported in this "
+ "release.\n"
+ "Ignoring this option and continuing.\n",
+ MB_ICONINFORMATION,
+ argv[i]);
+#endif
+ return 2;
+ }
+
+ /*
+ * Look for the '-keyboard' argument
+ */
+ if (IS_OPTION ("-keyboard"))
+ {
+#ifdef XWIN_XF86CONFIG
+ CHECK_ARGS (1);
+ g_cmdline.keyboard = argv[++i];
+#else
+ winMessageBoxF ("The -keyboard option is not supported in this "
+ "release.\n"
+ "Ignoring this option and continuing.\n",
+ MB_ICONINFORMATION);
+#endif
+ return 2;
+ }
+
+ /*
+ * Look for the '-logfile' argument
+ */
+ if (IS_OPTION ("-logfile"))
+ {
+ CHECK_ARGS (1);
+ g_pszLogFile = argv[++i];
+#ifdef RELOCATE_PROJECTROOT
+ g_fLogFileChanged = TRUE;
+#endif
+ return 2;
+ }
+
+ /*
+ * Look for the '-logverbose' argument
+ */
+ if (IS_OPTION ("-logverbose"))
+ {
+ CHECK_ARGS (1);
+ g_iLogVerbose = atoi(argv[++i]);
+ return 2;
+ }
+
+#ifdef XWIN_CLIPBOARD
+ /*
+ * Look for the '-nounicodeclipboard' argument
+ */
+ if (IS_OPTION ("-nounicodeclipboard"))
+ {
+ g_fUnicodeClipboard = FALSE;
+ /* Indicate that we have processed the argument */
+ return 1;
+ }
+#endif
+
+ if (IS_OPTION ("-xkbrules"))
+ {
+ CHECK_ARGS (1);
+ g_cmdline.xkbRules = argv[++i];
+ return 2;
+ }
+ if (IS_OPTION ("-xkbmodel"))
+ {
+ CHECK_ARGS (1);
+ g_cmdline.xkbModel = argv[++i];
+ return 2;
+ }
+ if (IS_OPTION ("-xkblayout"))
+ {
+ CHECK_ARGS (1);
+ g_cmdline.xkbLayout = argv[++i];
+ return 2;
+ }
+ if (IS_OPTION ("-xkbvariant"))
+ {
+ CHECK_ARGS (1);
+ g_cmdline.xkbVariant = argv[++i];
+ return 2;
+ }
+ if (IS_OPTION ("-xkboptions"))
+ {
+ CHECK_ARGS (1);
+ g_cmdline.xkbOptions = argv[++i];
+ return 2;
+ }
+
+ if (IS_OPTION ("-keyhook"))
+ {
+ g_fKeyboardHookLL = TRUE;
+ return 1;
+ }
+
+ if (IS_OPTION ("-nokeyhook"))
+ {
+ g_fKeyboardHookLL = FALSE;
+ return 1;
+ }
+
+ if (IS_OPTION ("-swcursor"))
+ {
+ g_fSoftwareCursor = TRUE;
+ return 1;
+ }
+
+ if (IS_OPTION ("-silent-dup-error"))
+ {
+ g_fSilentDupError = TRUE;
+ return 1;
+ }
+
+ if (IS_OPTION("-wgl"))
+ {
+ g_fNativeGl = TRUE;
+ return 1;
+ }
+
+ if (IS_OPTION("-nowgl"))
+ {
+ g_fNativeGl = FALSE;
+ return 1;
+ }
+
+ return 0;
+}
+
+
+/*
+ * winLogCommandLine - Write entire command line to the log file
+ */
+
+void
+winLogCommandLine (int argc, char *argv[])
+{
+ int i;
+ int iSize = 0;
+ int iCurrLen = 0;
+
+#define CHARS_PER_LINE 60
+
+ /* Bail if command line has already been logged */
+ if (g_pszCommandLine)
+ return;
+
+ /* Count how much memory is needed for concatenated command line */
+ for (i = 0, iCurrLen = 0; i < argc; ++i)
+ if (argv[i])
+ {
+ /* Adds two characters for lines that overflow */
+ if ((strlen (argv[i]) < CHARS_PER_LINE
+ && iCurrLen + strlen (argv[i]) > CHARS_PER_LINE)
+ || strlen (argv[i]) > CHARS_PER_LINE)
+ {
+ iCurrLen = 0;
+ iSize += 2;
+ }
+
+ /* Add space for item and trailing space */
+ iSize += strlen (argv[i]) + 1;
+
+ /* Update current line length */
+ iCurrLen += strlen (argv[i]);
+ }
+
+ /* Allocate memory for concatenated command line */
+ g_pszCommandLine = malloc (iSize + 1);
+ if (!g_pszCommandLine)
+ FatalError ("winLogCommandLine - Could not allocate memory for "
+ "command line string. Exiting.\n");
+
+ /* Set first character to concatenated command line to null */
+ g_pszCommandLine[0] = '\0';
+
+ /* Loop through all args */
+ for (i = 0, iCurrLen = 0; i < argc; ++i)
+ {
+ /* Add a character for lines that overflow */
+ if ((strlen (argv[i]) < CHARS_PER_LINE
+ && iCurrLen + strlen (argv[i]) > CHARS_PER_LINE)
+ || strlen (argv[i]) > CHARS_PER_LINE)
+ {
+ iCurrLen = 0;
+
+ /* Add line break if it fits */
+ strncat (g_pszCommandLine, "\n ", iSize - strlen (g_pszCommandLine));
+ }
+
+ strncat (g_pszCommandLine, argv[i], iSize - strlen (g_pszCommandLine));
+ strncat (g_pszCommandLine, " ", iSize - strlen (g_pszCommandLine));
+
+ /* Save new line length */
+ iCurrLen += strlen (argv[i]);
+ }
+
+ winDebug ("XWin was started with the following command line:\n\n"
+ "%s\n\n", g_pszCommandLine);
+}
+
+
+/*
+ * winLogVersionInfo - Log Cygwin/X version information
+ */
+
+void
+winLogVersionInfo (void)
+{
+#ifdef WINDBG
+ static Bool s_fBeenHere = FALSE;
+
+ if (s_fBeenHere)
+ return;
+ s_fBeenHere = TRUE;
+
+ winDebug ("Welcome to the VcXsrv X Server\n");
+ winDebug ("Vendor: %s\n", VENDOR_STRING);
+ winDebug ("Release: %d.%d.%d.%d (%d)\n\n", XORG_VERSION_MAJOR, XORG_VERSION_MINOR, XORG_VERSION_PATCH, XORG_VERSION_SNAP, XORG_VERSION_CURRENT);
+ winDebug ("%s\n\n", BUILDERSTRING);
+ winDebug ("Contact: %s\n\n", VENDOR_CONTACT);
+#endif
+}
+/*
+ * getMonitorInfo - callback function used to return information from the enumeration of monitors attached
+ */
+
+wBOOL CALLBACK getMonitorInfo(HMONITOR hMonitor, HDC hdc, LPRECT rect, LPARAM _data)
+{
+ struct GetMonitorInfoData* data = (struct GetMonitorInfoData*)_data;
+ // only get data for monitor number specified in <data>
+ data->monitorNum++;
+ if (data->monitorNum == data->requestedMonitor)
+ {
+ data->bMonitorSpecifiedExists = TRUE;
+ data->monitorOffsetX = rect->left;
+ data->monitorOffsetY = rect->top;
+ data->monitorHeight = rect->bottom - rect->top;
+ data->monitorWidth = rect->right - rect->left;
+ return FALSE;
+ }
+ return TRUE;
+}
diff --git a/xorg-server/hw/xwin/winregistry.c b/xorg-server/hw/xwin/winregistry.c index 3571b14d7..898ed978b 100644 --- a/xorg-server/hw/xwin/winregistry.c +++ b/xorg-server/hw/xwin/winregistry.c @@ -55,11 +55,11 @@ winGetRegistryDWORD (HKEY hkey, char *pszRegistryKey) if (dwDisposition == REG_CREATED_NEW_KEY) { - ErrorF ("winGetRegistryDWORD - Created new key: %s\n", pszRegistryKey); + winDebug ("winGetRegistryDWORD - Created new key: %s\n", pszRegistryKey); } else if (dwDisposition == REG_OPENED_EXISTING_KEY) { - ErrorF ("winGetRegistryDWORD - Opened existing key: %s\n", + winDebug ("winGetRegistryDWORD - Opened existing key: %s\n", pszRegistryKey); } diff --git a/xorg-server/hw/xwin/winscrinit.c b/xorg-server/hw/xwin/winscrinit.c index 37ec27e08..db65a5eed 100644 --- a/xorg-server/hw/xwin/winscrinit.c +++ b/xorg-server/hw/xwin/winscrinit.c @@ -1,790 +1,777 @@ -/* - *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: Dakshinamurthy Karra - * Suhaib M Siddiqi - * Peter Busch - * Harold L Hunt II - * Kensuke Matsuzaki - */ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" -#include "winmsg.h" - - -#ifdef XWIN_MULTIWINDOWEXTWM -static RootlessFrameProcsRec -winMWExtWMProcs = { - winMWExtWMCreateFrame, - winMWExtWMDestroyFrame, - - winMWExtWMMoveFrame, - winMWExtWMResizeFrame, - winMWExtWMRestackFrame, - winMWExtWMReshapeFrame, - winMWExtWMUnmapFrame, - - winMWExtWMStartDrawing, - winMWExtWMStopDrawing, - winMWExtWMUpdateRegion, -#ifndef ROOTLESS_TRACK_DAMAGE - winMWExtWMDamageRects, -#endif - winMWExtWMRootlessSwitchWindow, - NULL,//winMWExtWMDoReorderWindow, - NULL,//winMWExtWMHideWindow, - NULL,//winMWExtWMUpdateColorMap, - - NULL,//winMWExtWMCopyBytes, - NULL,//winMWExtWMFillBytes, - NULL,//winMWExtWMCompositePixels, - winMWExtWMCopyWindow -}; -#endif - - -/* - * References to external symbols - */ - -extern Bool g_fSoftwareCursor; - - -/* - * Prototypes - */ - -Bool -winRandRInit (ScreenPtr pScreen); - - -/* - * Local functions - */ - -static Bool -winSaveScreen (ScreenPtr pScreen, int on); - - -/* - * Determine what type of screen we are initializing - * and call the appropriate procedure to intiailize - * that type of screen. - */ - -Bool -winScreenInit (int index, - ScreenPtr pScreen, - int argc, char **argv) -{ - winScreenInfoPtr pScreenInfo = &g_ScreenInfo[index]; - winPrivScreenPtr pScreenPriv; - HDC hdc; - -#if CYGDEBUG || YES - winDebug ("winScreenInit - dwWidth: %ld dwHeight: %ld\n", - pScreenInfo->dwWidth, pScreenInfo->dwHeight); -#endif - - /* Allocate privates for this screen */ - if (!winAllocatePrivates (pScreen)) - { - ErrorF ("winScreenInit - Couldn't allocate screen privates\n"); - return FALSE; - } - - /* Get a pointer to the privates structure that was allocated */ - pScreenPriv = winGetScreenPriv (pScreen); - - /* Save a pointer to this screen in the screen info structure */ - pScreenInfo->pScreen = pScreen; - - /* Save a pointer to the screen info in the screen privates structure */ - /* This allows us to get back to the screen info from a screen pointer */ - pScreenPriv->pScreenInfo = pScreenInfo; - - /* - * Determine which engine to use. - * - * NOTE: This is done once per screen because each screen possibly has - * a preferred engine specified on the command line. - */ - if (!winSetEngine (pScreen)) - { - ErrorF ("winScreenInit - winSetEngine () failed\n"); - return FALSE; - } - - /* Adjust the video mode for our engine type */ - if (!(*pScreenPriv->pwinAdjustVideoMode) (pScreen)) - { - ErrorF ("winScreenInit - winAdjustVideoMode () failed\n"); - return FALSE; - } - - /* Check for supported display depth */ - if (!(WIN_SUPPORTED_BPPS & (1 << (pScreenInfo->dwBPP - 1)))) - { - ErrorF ("winScreenInit - Unsupported display depth: %d\n" \ - "Change your Windows display depth to 15, 16, 24, or 32 bits " - "per pixel.\n", - (int) pScreenInfo->dwBPP); - ErrorF ("winScreenInit - Supported depths: %08x\n", - WIN_SUPPORTED_BPPS); -#if WIN_CHECK_DEPTH - return FALSE; -#endif - } - - /* - * Check that all monitors have the same display depth if we are using - * multiple monitors - */ - if (pScreenInfo->fMultipleMonitors - && !GetSystemMetrics (SM_SAMEDISPLAYFORMAT)) - { - ErrorF ("winScreenInit - Monitors do not all have same pixel format / " - "display depth.\n" - "Using primary display only.\n"); - pScreenInfo->fMultipleMonitors = FALSE; - } - - /* Create display window */ - if (!(*pScreenPriv->pwinCreateBoundingWindow) (pScreen)) - { - ErrorF ("winScreenInit - pwinCreateBoundingWindow () " - "failed\n"); - return FALSE; - } - - /* Get a device context */ - hdc = GetDC (pScreenPriv->hwndScreen); - - /* Store the initial height, width, and depth of the display */ - /* Are we using multiple monitors? */ - if (pScreenInfo->fMultipleMonitors) - { - pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN); - pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN); - - /* - * In this case, some of the defaults set in - * winInitializeDefaultScreens () are not correct ... - */ - if (!pScreenInfo->fUserGaveHeightAndWidth) - { - pScreenInfo->dwWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN); - pScreenInfo->dwHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN); - pScreenInfo->dwWidth_mm = (pScreenInfo->dwWidth / - WIN_DEFAULT_DPI) * 25.4; - pScreenInfo->dwHeight_mm = (pScreenInfo->dwHeight / - WIN_DEFAULT_DPI) * 25.4; - } - } - else - { - pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN); - pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN); - } - - /* Save the original bits per pixel */ - pScreenPriv->dwLastWindowsBitsPixel = GetDeviceCaps (hdc, BITSPIXEL); - - /* Release the device context */ - ReleaseDC (pScreenPriv->hwndScreen, hdc); - - /* Clear the visuals list */ - miClearVisualTypes (); - - /* Set the padded screen width */ - pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth, - pScreenInfo->dwBPP); - - /* Call the engine dependent screen initialization procedure */ - if (!((*pScreenPriv->pwinFinishScreenInit) (index, pScreen, argc, argv))) - { - ErrorF ("winScreenInit - winFinishScreenInit () failed\n"); - return FALSE; - } - - if (!g_fSoftwareCursor) - winInitCursor(pScreen); - else - winErrorFVerb(2, "winScreenInit - Using software cursor\n"); - - /* - Note the screen origin in a normalized coordinate space where (0,0) is at the top left - of the native virtual desktop area - */ - dixScreenOrigins[index].x = pScreenInfo->dwInitialX - GetSystemMetrics(SM_XVIRTUALSCREEN); - dixScreenOrigins[index].y = pScreenInfo->dwInitialY - GetSystemMetrics(SM_YVIRTUALSCREEN); - - ErrorF("Screen %d added at XINERAMA coordinate (%d,%d).\n", - index, dixScreenOrigins[index].x, dixScreenOrigins[index].y); - -#if CYGDEBUG || YES - winDebug ("winScreenInit - returning\n"); -#endif - - return TRUE; -} - -static Bool -winCreateScreenResources(ScreenPtr pScreen) -{ - winScreenPriv(pScreen); - Bool result; - - result = pScreenPriv->pwinCreateScreenResources(pScreen); - - /* Now the screen bitmap has been wrapped in a pixmap, - add that to the Shadow framebuffer */ - if (!shadowAdd(pScreen, pScreen->devPrivate, - pScreenPriv->pwinShadowUpdate, NULL, 0, 0)) - { - ErrorF ("winCreateScreenResources - shadowAdd () failed\n"); - return FALSE; - } - - return result; -} - -/* See Porting Layer Definition - p. 20 */ -Bool -winFinishScreenInitFB (int index, - ScreenPtr pScreen, - int argc, char **argv) -{ - winScreenPriv(pScreen); - winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - VisualPtr pVisual = NULL; - char *pbits = NULL; -#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) - int iReturn; -#endif - - /* Create framebuffer */ - if (!(*pScreenPriv->pwinAllocateFB) (pScreen)) - { - ErrorF ("winFinishScreenInitFB - Could not allocate framebuffer\n"); - return FALSE; - } - - /* - * Grab the number of bits that are used to represent color in each pixel. - */ - if (pScreenInfo->dwBPP == 8) - pScreenInfo->dwDepth = 8; - else - pScreenInfo->dwDepth = winCountBits (pScreenPriv->dwRedMask) - + winCountBits (pScreenPriv->dwGreenMask) - + winCountBits (pScreenPriv->dwBlueMask); - - winErrorFVerb (2, "winFinishScreenInitFB - Masks: %08x %08x %08x\n", - (unsigned int) pScreenPriv->dwRedMask, - (unsigned int) pScreenPriv->dwGreenMask, - (unsigned int) pScreenPriv->dwBlueMask); - - /* Init visuals */ - if (!(*pScreenPriv->pwinInitVisuals) (pScreen)) - { - ErrorF ("winFinishScreenInitFB - winInitVisuals failed\n"); - return FALSE; - } - - /* Setup a local variable to point to the framebuffer */ - pbits = pScreenInfo->pfb; - - /* Apparently we need this for the render extension */ - miSetPixmapDepths (); - - /* Start fb initialization */ - if (!fbSetupScreen (pScreen, - pScreenInfo->pfb, - pScreenInfo->dwWidth, pScreenInfo->dwHeight, - monitorResolution, monitorResolution, - pScreenInfo->dwStride, - pScreenInfo->dwBPP)) - { - ErrorF ("winFinishScreenInitFB - fbSetupScreen failed\n"); - return FALSE; - } - - /* Override default colormap routines if visual class is dynamic */ - if (pScreenInfo->dwDepth == 8 - && (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI - || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL - && pScreenInfo->fFullScreen) - || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD - && pScreenInfo->fFullScreen))) - { - winSetColormapFunctions (pScreen); - - /* - * NOTE: Setting whitePixel to 255 causes Magic 7.1 to allocate its - * own colormap, as it cannot allocate 7 planes in the default - * colormap. Setting whitePixel to 1 allows Magic to get 7 - * planes in the default colormap, so it doesn't create its - * own colormap. This latter situation is highly desireable, - * as it keeps the Magic window viewable when switching to - * other X clients that use the default colormap. - */ - pScreen->blackPixel = 0; - pScreen->whitePixel = 1; - } - - /* Place our save screen function */ - pScreen->SaveScreen = winSaveScreen; - - /* Finish fb initialization */ - if (!fbFinishScreenInit (pScreen, - pScreenInfo->pfb, - pScreenInfo->dwWidth, pScreenInfo->dwHeight, - monitorResolution, monitorResolution, - pScreenInfo->dwStride, - pScreenInfo->dwBPP)) - { - ErrorF ("winFinishScreenInitFB - fbFinishScreenInit failed\n"); - return FALSE; - } - - /* Save a pointer to the root visual */ - for (pVisual = pScreen->visuals; - pVisual->vid != pScreen->rootVisual; - pVisual++); - pScreenPriv->pRootVisual = pVisual; - - /* - * Setup points to the block and wakeup handlers. Pass a pointer - * to the current screen as pWakeupdata. - */ - pScreen->BlockHandler = winBlockHandler; - pScreen->WakeupHandler = winWakeupHandler; - pScreen->blockData = pScreen; - pScreen->wakeupData = pScreen; - -#ifdef RENDER - /* Render extension initialization, calls miPictureInit */ - if (!fbPictureInit (pScreen, NULL, 0)) - { - ErrorF ("winFinishScreenInitFB - fbPictureInit () failed\n"); - return FALSE; - } -#endif - -#ifdef RANDR - /* Initialize resize and rotate support */ - if (!winRandRInit (pScreen)) - { - ErrorF ("winFinishScreenInitFB - winRandRInit () failed\n"); - return FALSE; - } -#endif - - /* - * Backing store support should reduce network traffic and increase - * performance. - */ - miInitializeBackingStore (pScreen); - - /* KDrive does miDCInitialize right after miInitializeBackingStore */ - /* Setup the cursor routines */ -#if CYGDEBUG - winDebug ("winFinishScreenInitFB - Calling miDCInitialize ()\n"); -#endif - miDCInitialize (pScreen, &g_winPointerCursorFuncs); - - /* KDrive does winCreateDefColormap right after miDCInitialize */ - /* Create a default colormap */ -#if CYGDEBUG - winDebug ("winFinishScreenInitFB - Calling winCreateDefColormap ()\n"); -#endif - if (!winCreateDefColormap (pScreen)) - { - ErrorF ("winFinishScreenInitFB - Could not create colormap\n"); - return FALSE; - } - - /* Initialize the shadow framebuffer layer */ - if ((pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI - || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD - || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL) -#ifdef XWIN_MULTIWINDOWEXTWM - && !pScreenInfo->fMWExtWM -#endif - ) - { -#if CYGDEBUG - winDebug ("winFinishScreenInitFB - Calling shadowSetup ()\n"); -#endif - if (!shadowSetup(pScreen)) - { - ErrorF ("winFinishScreenInitFB - shadowSetup () failed\n"); - return FALSE; - } - - /* Wrap CreateScreenResources so we can add the screen pixmap - to the Shadow framebuffer after it's been created */ - pScreenPriv->pwinCreateScreenResources = pScreen->CreateScreenResources; - pScreen->CreateScreenResources = winCreateScreenResources; - } - -#ifdef XWIN_MULTIWINDOWEXTWM - /* Handle multi-window external window manager mode */ - if (pScreenInfo->fMWExtWM) - { - winDebug ("winScreenInit - MultiWindowExtWM - Calling RootlessInit\n"); - - RootlessInit(pScreen, &winMWExtWMProcs); - - winDebug ("winScreenInit - MultiWindowExtWM - RootlessInit returned\n"); - - rootless_CopyBytes_threshold = 0; - rootless_FillBytes_threshold = 0; - rootless_CompositePixels_threshold = 0; - /* FIXME: How many? Profiling needed? */ - rootless_CopyWindow_threshold = 1; - - winWindowsWMExtensionInit (); - } -#endif - - /* Handle rootless mode */ - if (pScreenInfo->fRootless) - { - /* Define the WRAP macro temporarily for local use */ -#define WRAP(a) \ - if (pScreen->a) { \ - pScreenPriv->a = pScreen->a; \ - } else { \ - ErrorF("null screen fn " #a "\n"); \ - pScreenPriv->a = NULL; \ - } - - /* Save a pointer to each lower-level window procedure */ - WRAP(CreateWindow); - WRAP(DestroyWindow); - WRAP(RealizeWindow); - WRAP(UnrealizeWindow); - WRAP(PositionWindow); - WRAP(ChangeWindowAttributes); - WRAP(SetShape); - - /* Assign rootless window procedures to be top level procedures */ - pScreen->CreateWindow = winCreateWindowRootless; - pScreen->DestroyWindow = winDestroyWindowRootless; - pScreen->PositionWindow = winPositionWindowRootless; - /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesRootless;*/ - pScreen->RealizeWindow = winMapWindowRootless; - pScreen->UnrealizeWindow = winUnmapWindowRootless; - pScreen->SetShape = winSetShapeRootless; - - /* Undefine the WRAP macro, as it is not needed elsewhere */ -#undef WRAP - } - - -#ifdef XWIN_MULTIWINDOW - /* Handle multi window mode */ - else if (pScreenInfo->fMultiWindow) - { - /* Define the WRAP macro temporarily for local use */ -#define WRAP(a) \ - if (pScreen->a) { \ - pScreenPriv->a = pScreen->a; \ - } else { \ - ErrorF("null screen fn " #a "\n"); \ - pScreenPriv->a = NULL; \ - } - - /* Save a pointer to each lower-level window procedure */ - WRAP(CreateWindow); - WRAP(DestroyWindow); - WRAP(RealizeWindow); - WRAP(UnrealizeWindow); - WRAP(PositionWindow); - WRAP(ChangeWindowAttributes); - WRAP(ReparentWindow); - WRAP(RestackWindow); - WRAP(ResizeWindow); - WRAP(MoveWindow); - WRAP(CopyWindow); - WRAP(SetShape); - - /* Assign multi-window window procedures to be top level procedures */ - pScreen->CreateWindow = winCreateWindowMultiWindow; - pScreen->DestroyWindow = winDestroyWindowMultiWindow; - pScreen->PositionWindow = winPositionWindowMultiWindow; - /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesMultiWindow;*/ - pScreen->RealizeWindow = winMapWindowMultiWindow; - pScreen->UnrealizeWindow = winUnmapWindowMultiWindow; - pScreen->ReparentWindow = winReparentWindowMultiWindow; - pScreen->RestackWindow = winRestackWindowMultiWindow; - pScreen->ResizeWindow = winResizeWindowMultiWindow; - pScreen->MoveWindow = winMoveWindowMultiWindow; - pScreen->CopyWindow = winCopyWindowMultiWindow; - pScreen->SetShape = winSetShapeMultiWindow; - - /* Undefine the WRAP macro, as it is not needed elsewhere */ -#undef WRAP - } -#endif - - /* Wrap either fb's or shadow's CloseScreen with our CloseScreen */ - pScreenPriv->CloseScreen = pScreen->CloseScreen; - pScreen->CloseScreen = pScreenPriv->pwinCloseScreen; - -#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW) - /* Create a mutex for modules in separate threads to wait for */ - iReturn = pthread_mutex_init (&pScreenPriv->pmServerStarted, NULL); - if (iReturn != 0) - { - ErrorF ("winFinishScreenInitFB - pthread_mutex_init () failed: %d\n", - iReturn); - return FALSE; - } - - /* Own the mutex for modules in separate threads */ - iReturn = pthread_mutex_lock (&pScreenPriv->pmServerStarted); - if (iReturn != 0) - { - ErrorF ("winFinishScreenInitFB - pthread_mutex_lock () failed: %d\n", - iReturn); - return FALSE; - } - - /* Set the ServerStarted flag to false */ - pScreenPriv->fServerStarted = FALSE; -#endif - -#ifdef XWIN_MULTIWINDOWEXTWM - pScreenPriv->fRestacking = FALSE; -#endif - -#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM) - if (FALSE -#ifdef XWIN_MULTIWINDOW - || pScreenInfo->fMultiWindow -#endif -#ifdef XWIN_MULTIWINDOWEXTWM - || pScreenInfo->fInternalWM -#endif - ) - { -#if CYGDEBUG || YES - winDebug ("winFinishScreenInitFB - Calling winInitWM.\n"); -#endif - - /* Initialize multi window mode */ - if (!winInitWM (&pScreenPriv->pWMInfo, - &pScreenPriv->ptWMProc, - &pScreenPriv->ptXMsgProc, - &pScreenPriv->pmServerStarted, - pScreenInfo->dwScreen, - (HWND)&pScreenPriv->hwndScreen, -#ifdef XWIN_MULTIWINDOWEXTWM - pScreenInfo->fInternalWM || -#endif - FALSE)) - { - ErrorF ("winFinishScreenInitFB - winInitWM () failed.\n"); - return FALSE; - } - } -#endif - - /* Tell the server that we are enabled */ - pScreenPriv->fEnabled = TRUE; - - /* Tell the server that we have a valid depth */ - pScreenPriv->fBadDepth = FALSE; - -#if CYGDEBUG || YES - winDebug ("winFinishScreenInitFB - returning\n"); -#endif - - return TRUE; -} - -#ifdef XWIN_NATIVEGDI -/* See Porting Layer Definition - p. 20 */ - -Bool -winFinishScreenInitNativeGDI (int index, - ScreenPtr pScreen, - int argc, char **argv) -{ - winScreenPriv(pScreen); - winScreenInfoPtr pScreenInfo = &g_ScreenInfo[index]; - VisualPtr pVisuals = NULL; - DepthPtr pDepths = NULL; - VisualID rootVisual = 0; - int nVisuals = 0, nDepths = 0, nRootDepth = 0; - - /* Ignore user input (mouse, keyboard) */ - pScreenInfo->fIgnoreInput = FALSE; - - /* Get device contexts for the screen and shadow bitmap */ - pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); - if (pScreenPriv->hdcScreen == NULL) - FatalError ("winFinishScreenInitNativeGDI - Couldn't get a DC\n"); - - /* Init visuals */ - if (!(*pScreenPriv->pwinInitVisuals) (pScreen)) - { - ErrorF ("winFinishScreenInitNativeGDI - pwinInitVisuals failed\n"); - return FALSE; - } - - /* Initialize the mi visuals */ - if (!miInitVisuals (&pVisuals, &pDepths, &nVisuals, &nDepths, &nRootDepth, - &rootVisual, - ((unsigned long)1 << (pScreenInfo->dwDepth - 1)), 8, - TrueColor)) - { - ErrorF ("winFinishScreenInitNativeGDI - miInitVisuals () failed\n"); - return FALSE; - } - - /* Initialize the CloseScreen procedure pointer */ - pScreen->CloseScreen = NULL; - - /* Initialize the mi code */ - if (!miScreenInit (pScreen, - NULL, /* No framebuffer */ - pScreenInfo->dwWidth, pScreenInfo->dwHeight, - monitorResolution, monitorResolution, - pScreenInfo->dwStride, - nRootDepth, nDepths, pDepths, rootVisual, - nVisuals, pVisuals)) - { - ErrorF ("winFinishScreenInitNativeGDI - miScreenInit failed\n"); - return FALSE; - } - - pScreen->defColormap = FakeClientID(0); - - /* - * Register our block and wakeup handlers; these procedures - * process messages in our Windows message queue; specifically, - * they process mouse and keyboard input. - */ - pScreen->BlockHandler = winBlockHandler; - pScreen->WakeupHandler = winWakeupHandler; - pScreen->blockData = pScreen; - pScreen->wakeupData = pScreen; - - /* Place our save screen function */ - pScreen->SaveScreen = winSaveScreen; - - /* Pixmaps */ - pScreen->CreatePixmap = winCreatePixmapNativeGDI; - pScreen->DestroyPixmap = winDestroyPixmapNativeGDI; - - /* Other Screen Routines */ - pScreen->QueryBestSize = winQueryBestSizeNativeGDI; - pScreen->SaveScreen = winSaveScreen; - pScreen->GetImage = miGetImage; - pScreen->GetSpans = winGetSpansNativeGDI; - - /* Window Procedures */ - pScreen->CreateWindow = winCreateWindowNativeGDI; - pScreen->DestroyWindow = winDestroyWindowNativeGDI; - pScreen->PositionWindow = winPositionWindowNativeGDI; - /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesNativeGDI;*/ - pScreen->RealizeWindow = winMapWindowNativeGDI; - pScreen->UnrealizeWindow = winUnmapWindowNativeGDI; - - /* Paint window */ - pScreen->CopyWindow = winCopyWindowNativeGDI; - - /* Fonts */ - pScreen->RealizeFont = winRealizeFontNativeGDI; - pScreen->UnrealizeFont = winUnrealizeFontNativeGDI; - - /* GC */ - pScreen->CreateGC = winCreateGCNativeGDI; - - /* Colormap Routines */ - pScreen->CreateColormap = miInitializeColormap; - pScreen->DestroyColormap = (DestroyColormapProcPtr) (void (*)(void)) NoopDDA; - pScreen->InstallColormap = miInstallColormap; - pScreen->UninstallColormap = miUninstallColormap; - pScreen->ListInstalledColormaps = miListInstalledColormaps; - pScreen->StoreColors = (StoreColorsProcPtr) (void (*)(void)) NoopDDA; - pScreen->ResolveColor = miResolveColor; - - /* Bitmap */ - pScreen->BitmapToRegion = winPixmapToRegionNativeGDI; - - ErrorF ("winFinishScreenInitNativeGDI - calling miDCInitialize\n"); - - /* Set the default white and black pixel positions */ - pScreen->whitePixel = pScreen->blackPixel = (Pixel) 0; - - /* Initialize the cursor */ - if (!miDCInitialize (pScreen, &g_winPointerCursorFuncs)) - { - ErrorF ("winFinishScreenInitNativeGDI - miDCInitialize failed\n"); - return FALSE; - } - - /* Create a default colormap */ - if (!miCreateDefColormap (pScreen)) - { - ErrorF ("winFinishScreenInitNativeGDI - miCreateDefColormap () " - "failed\n"); - return FALSE; - } - - ErrorF ("winFinishScreenInitNativeGDI - miCreateDefColormap () " - "returned\n"); - - /* mi doesn't use a CloseScreen procedure, so no need to wrap */ - pScreen->CloseScreen = pScreenPriv->pwinCloseScreen; - - /* Tell the server that we are enabled */ - pScreenPriv->fEnabled = TRUE; - - ErrorF ("winFinishScreenInitNativeGDI - Successful addition of " - "screen %08x\n", - (unsigned int) pScreen); - - return TRUE; -} -#endif - - -/* See Porting Layer Definition - p. 33 */ -static Bool -winSaveScreen (ScreenPtr pScreen, int on) -{ - return TRUE; -} +/*
+ *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: Dakshinamurthy Karra
+ * Suhaib M Siddiqi
+ * Peter Busch
+ * Harold L Hunt II
+ * Kensuke Matsuzaki
+ */
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+#include "winmsg.h"
+
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+static RootlessFrameProcsRec
+winMWExtWMProcs = {
+ winMWExtWMCreateFrame,
+ winMWExtWMDestroyFrame,
+
+ winMWExtWMMoveFrame,
+ winMWExtWMResizeFrame,
+ winMWExtWMRestackFrame,
+ winMWExtWMReshapeFrame,
+ winMWExtWMUnmapFrame,
+
+ winMWExtWMStartDrawing,
+ winMWExtWMStopDrawing,
+ winMWExtWMUpdateRegion,
+#ifndef ROOTLESS_TRACK_DAMAGE
+ winMWExtWMDamageRects,
+#endif
+ winMWExtWMRootlessSwitchWindow,
+ NULL,//winMWExtWMDoReorderWindow,
+ NULL,//winMWExtWMHideWindow,
+ NULL,//winMWExtWMUpdateColorMap,
+
+ NULL,//winMWExtWMCopyBytes,
+ NULL,//winMWExtWMFillBytes,
+ NULL,//winMWExtWMCompositePixels,
+ winMWExtWMCopyWindow
+};
+#endif
+
+
+/*
+ * References to external symbols
+ */
+
+extern Bool g_fSoftwareCursor;
+
+
+/*
+ * Prototypes
+ */
+
+Bool
+winRandRInit (ScreenPtr pScreen);
+
+
+/*
+ * Local functions
+ */
+
+static Bool
+winSaveScreen (ScreenPtr pScreen, int on);
+
+
+/*
+ * Determine what type of screen we are initializing
+ * and call the appropriate procedure to intiailize
+ * that type of screen.
+ */
+
+Bool
+winScreenInit (int index,
+ ScreenPtr pScreen,
+ int argc, char **argv)
+{
+ winScreenInfoPtr pScreenInfo = &g_ScreenInfo[index];
+ winPrivScreenPtr pScreenPriv;
+ HDC hdc;
+
+ winDebug ("winScreenInit - dwWidth: %ld dwHeight: %ld\n",
+ pScreenInfo->dwWidth, pScreenInfo->dwHeight);
+
+ /* Allocate privates for this screen */
+ if (!winAllocatePrivates (pScreen))
+ {
+ ErrorF ("winScreenInit - Couldn't allocate screen privates\n");
+ return FALSE;
+ }
+
+ /* Get a pointer to the privates structure that was allocated */
+ pScreenPriv = winGetScreenPriv (pScreen);
+
+ /* Save a pointer to this screen in the screen info structure */
+ pScreenInfo->pScreen = pScreen;
+
+ /* Save a pointer to the screen info in the screen privates structure */
+ /* This allows us to get back to the screen info from a screen pointer */
+ pScreenPriv->pScreenInfo = pScreenInfo;
+
+ /*
+ * Determine which engine to use.
+ *
+ * NOTE: This is done once per screen because each screen possibly has
+ * a preferred engine specified on the command line.
+ */
+ if (!winSetEngine (pScreen))
+ {
+ ErrorF ("winScreenInit - winSetEngine () failed\n");
+ return FALSE;
+ }
+
+ /* Adjust the video mode for our engine type */
+ if (pScreenPriv->pwinAdjustVideoMode && !(*pScreenPriv->pwinAdjustVideoMode) (pScreen))
+ {
+ ErrorF ("winScreenInit - winAdjustVideoMode () failed\n");
+ return FALSE;
+ }
+
+ /* Check for supported display depth */
+ if (!(WIN_SUPPORTED_BPPS & (1 << (pScreenInfo->dwBPP - 1))))
+ {
+ ErrorF ("winScreenInit - Unsupported display depth: %d\n" \
+ "Change your Windows display depth to 15, 16, 24, or 32 bits "
+ "per pixel.\n",
+ (int) pScreenInfo->dwBPP);
+ ErrorF ("winScreenInit - Supported depths: %08x\n",
+ WIN_SUPPORTED_BPPS);
+#if WIN_CHECK_DEPTH
+ return FALSE;
+#endif
+ }
+
+ /*
+ * Check that all monitors have the same display depth if we are using
+ * multiple monitors
+ */
+ if (pScreenInfo->fMultipleMonitors
+ && !GetSystemMetrics (SM_SAMEDISPLAYFORMAT))
+ {
+ ErrorF ("winScreenInit - Monitors do not all have same pixel format / "
+ "display depth.\n"
+ "Using primary display only.\n");
+ pScreenInfo->fMultipleMonitors = FALSE;
+ }
+
+ /* Create display window */
+ if (pScreenPriv->pwinCreateBoundingWindow && !(*pScreenPriv->pwinCreateBoundingWindow) (pScreen))
+ {
+ ErrorF ("winScreenInit - pwinCreateBoundingWindow () "
+ "failed\n");
+ return FALSE;
+ }
+
+ /* Get a device context */
+ hdc = GetDC (pScreenPriv->hwndScreen);
+
+ /* Store the initial height, width, and depth of the display */
+ /* Are we using multiple monitors? */
+ if (pScreenInfo->fMultipleMonitors)
+ {
+ pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+
+ /*
+ * In this case, some of the defaults set in
+ * winInitializeDefaultScreens () are not correct ...
+ */
+ if (!pScreenInfo->fUserGaveHeightAndWidth)
+ {
+ pScreenInfo->dwWidth = GetSystemMetrics (SM_CXVIRTUALSCREEN);
+ pScreenInfo->dwHeight = GetSystemMetrics (SM_CYVIRTUALSCREEN);
+ pScreenInfo->dwWidth_mm = (pScreenInfo->dwWidth /
+ WIN_DEFAULT_DPI) * 25.4;
+ pScreenInfo->dwHeight_mm = (pScreenInfo->dwHeight /
+ WIN_DEFAULT_DPI) * 25.4;
+ }
+ }
+ else
+ {
+ pScreenPriv->dwLastWindowsWidth = GetSystemMetrics (SM_CXSCREEN);
+ pScreenPriv->dwLastWindowsHeight = GetSystemMetrics (SM_CYSCREEN);
+ }
+
+ /* Save the original bits per pixel */
+ pScreenPriv->dwLastWindowsBitsPixel = GetDeviceCaps (hdc, BITSPIXEL);
+
+ /* Release the device context */
+ ReleaseDC (pScreenPriv->hwndScreen, hdc);
+
+ /* Clear the visuals list */
+ miClearVisualTypes ();
+
+ /* Set the padded screen width */
+ pScreenInfo->dwPaddedWidth = PixmapBytePad (pScreenInfo->dwWidth,
+ pScreenInfo->dwBPP);
+
+ /* Call the engine dependent screen initialization procedure */
+ if (pScreenPriv->pwinFinishScreenInit && !((*pScreenPriv->pwinFinishScreenInit) (index, pScreen, argc, argv)))
+ {
+ ErrorF ("winScreenInit - winFinishScreenInit () failed\n");
+ return FALSE;
+ }
+
+ if (!g_fSoftwareCursor)
+ winInitCursor(pScreen);
+#ifdef WINDBG
+ else
+ winDebug("winScreenInit - Using software cursor\n");
+#endif
+
+ /*
+ Note the screen origin in a normalized coordinate space where (0,0) is at the top left
+ of the native virtual desktop area
+ */
+ dixScreenOrigins[index].x = pScreenInfo->dwInitialX - GetSystemMetrics(SM_XVIRTUALSCREEN);
+ dixScreenOrigins[index].y = pScreenInfo->dwInitialY - GetSystemMetrics(SM_YVIRTUALSCREEN);
+
+ winDebug("Screen %d added at XINERAMA coordinate (%d,%d).\n",
+ index, dixScreenOrigins[index].x, dixScreenOrigins[index].y);
+ winDebug ("winScreenInit - returning\n");
+
+ return TRUE;
+}
+
+static Bool
+winCreateScreenResources(ScreenPtr pScreen)
+{
+ winScreenPriv(pScreen);
+ Bool result;
+
+ result = pScreenPriv->pwinCreateScreenResources(pScreen);
+
+ /* Now the screen bitmap has been wrapped in a pixmap,
+ add that to the Shadow framebuffer */
+ if (!shadowAdd(pScreen, pScreen->devPrivate,
+ pScreenPriv->pwinShadowUpdate, NULL, 0, 0))
+ {
+ ErrorF ("winCreateScreenResources - shadowAdd () failed\n");
+ return FALSE;
+ }
+
+ return result;
+}
+
+/* See Porting Layer Definition - p. 20 */
+Bool
+winFinishScreenInitFB (int index,
+ ScreenPtr pScreen,
+ int argc, char **argv)
+{
+ winScreenPriv(pScreen);
+ winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo;
+ VisualPtr pVisual = NULL;
+ char *pbits = NULL;
+#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
+ int iReturn;
+#endif
+
+ /* Create framebuffer */
+ if (!(*pScreenPriv->pwinAllocateFB) (pScreen))
+ {
+ ErrorF ("winFinishScreenInitFB - Could not allocate framebuffer\n");
+ return FALSE;
+ }
+
+ /*
+ * Grab the number of bits that are used to represent color in each pixel.
+ */
+ if (pScreenInfo->dwBPP == 8)
+ pScreenInfo->dwDepth = 8;
+ else
+ pScreenInfo->dwDepth = winCountBits (pScreenPriv->dwRedMask)
+ + winCountBits (pScreenPriv->dwGreenMask)
+ + winCountBits (pScreenPriv->dwBlueMask);
+
+ winDebug ("winFinishScreenInitFB - Masks: %08x %08x %08x\n",
+ (unsigned int) pScreenPriv->dwRedMask,
+ (unsigned int) pScreenPriv->dwGreenMask,
+ (unsigned int) pScreenPriv->dwBlueMask);
+
+ /* Init visuals */
+ if (!(*pScreenPriv->pwinInitVisuals) (pScreen))
+ {
+ ErrorF ("winFinishScreenInitFB - winInitVisuals failed\n");
+ return FALSE;
+ }
+
+ /* Setup a local variable to point to the framebuffer */
+ pbits = pScreenInfo->pfb;
+
+ /* Apparently we need this for the render extension */
+ miSetPixmapDepths ();
+
+ /* Start fb initialization */
+ if (!fbSetupScreen (pScreen,
+ pScreenInfo->pfb,
+ pScreenInfo->dwWidth, pScreenInfo->dwHeight,
+ monitorResolution, monitorResolution,
+ pScreenInfo->dwStride,
+ pScreenInfo->dwBPP))
+ {
+ ErrorF ("winFinishScreenInitFB - fbSetupScreen failed\n");
+ return FALSE;
+ }
+
+ /* Override default colormap routines if visual class is dynamic */
+ if (pScreenInfo->dwDepth == 8
+ && (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI
+ || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL
+ && pScreenInfo->fFullScreen)
+ || (pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
+ && pScreenInfo->fFullScreen)))
+ {
+ winSetColormapFunctions (pScreen);
+
+ /*
+ * NOTE: Setting whitePixel to 255 causes Magic 7.1 to allocate its
+ * own colormap, as it cannot allocate 7 planes in the default
+ * colormap. Setting whitePixel to 1 allows Magic to get 7
+ * planes in the default colormap, so it doesn't create its
+ * own colormap. This latter situation is highly desireable,
+ * as it keeps the Magic window viewable when switching to
+ * other X clients that use the default colormap.
+ */
+ pScreen->blackPixel = 0;
+ pScreen->whitePixel = 1;
+ }
+
+ /* Place our save screen function */
+ pScreen->SaveScreen = winSaveScreen;
+
+ /* Finish fb initialization */
+ if (!fbFinishScreenInit (pScreen,
+ pScreenInfo->pfb,
+ pScreenInfo->dwWidth, pScreenInfo->dwHeight,
+ monitorResolution, monitorResolution,
+ pScreenInfo->dwStride,
+ pScreenInfo->dwBPP))
+ {
+ ErrorF ("winFinishScreenInitFB - fbFinishScreenInit failed\n");
+ return FALSE;
+ }
+
+ /* Save a pointer to the root visual */
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != pScreen->rootVisual;
+ pVisual++);
+ pScreenPriv->pRootVisual = pVisual;
+
+ /*
+ * Setup points to the block and wakeup handlers. Pass a pointer
+ * to the current screen as pWakeupdata.
+ */
+ pScreen->BlockHandler = winBlockHandler;
+ pScreen->WakeupHandler = winWakeupHandler;
+ pScreen->blockData = pScreen;
+ pScreen->wakeupData = pScreen;
+
+#ifdef RENDER
+ /* Render extension initialization, calls miPictureInit */
+ if (!fbPictureInit (pScreen, NULL, 0))
+ {
+ ErrorF ("winFinishScreenInitFB - fbPictureInit () failed\n");
+ return FALSE;
+ }
+#endif
+
+#ifdef RANDR
+ /* Initialize resize and rotate support */
+ if (!winRandRInit (pScreen))
+ {
+ ErrorF ("winFinishScreenInitFB - winRandRInit () failed\n");
+ return FALSE;
+ }
+#endif
+
+ /*
+ * Backing store support should reduce network traffic and increase
+ * performance.
+ */
+ miInitializeBackingStore (pScreen);
+
+ /* KDrive does miDCInitialize right after miInitializeBackingStore */
+ /* Setup the cursor routines */
+ winDebug ("winFinishScreenInitFB - Calling miDCInitialize ()\n");
+ miDCInitialize (pScreen, &g_winPointerCursorFuncs);
+
+ /* KDrive does winCreateDefColormap right after miDCInitialize */
+ /* Create a default colormap */
+ winDebug ("winFinishScreenInitFB - Calling winCreateDefColormap ()\n");
+ if (!winCreateDefColormap (pScreen))
+ {
+ ErrorF ("winFinishScreenInitFB - Could not create colormap\n");
+ return FALSE;
+ }
+
+ /* Initialize the shadow framebuffer layer */
+ if ((pScreenInfo->dwEngine == WIN_SERVER_SHADOW_GDI
+ || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DD
+ || pScreenInfo->dwEngine == WIN_SERVER_SHADOW_DDNL)
+#ifdef XWIN_MULTIWINDOWEXTWM
+ && !pScreenInfo->fMWExtWM
+#endif
+ )
+ {
+ winDebug ("winFinishScreenInitFB - Calling shadowSetup ()\n");
+ if (!shadowSetup(pScreen))
+ {
+ ErrorF ("winFinishScreenInitFB - shadowSetup () failed\n");
+ return FALSE;
+ }
+
+ /* Wrap CreateScreenResources so we can add the screen pixmap
+ to the Shadow framebuffer after it's been created */
+ pScreenPriv->pwinCreateScreenResources = pScreen->CreateScreenResources;
+ pScreen->CreateScreenResources = winCreateScreenResources;
+ }
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+ /* Handle multi-window external window manager mode */
+ if (pScreenInfo->fMWExtWM)
+ {
+ winDebug ("winScreenInit - MultiWindowExtWM - Calling RootlessInit\n");
+
+ RootlessInit(pScreen, &winMWExtWMProcs);
+
+ winDebug ("winScreenInit - MultiWindowExtWM - RootlessInit returned\n");
+
+ rootless_CopyBytes_threshold = 0;
+ rootless_FillBytes_threshold = 0;
+ rootless_CompositePixels_threshold = 0;
+ /* FIXME: How many? Profiling needed? */
+ rootless_CopyWindow_threshold = 1;
+
+ winWindowsWMExtensionInit ();
+ }
+#endif
+
+ /* Handle rootless mode */
+ if (pScreenInfo->fRootless)
+ {
+ /* Define the WRAP macro temporarily for local use */
+#define WRAP(a) \
+ if (pScreen->a) { \
+ pScreenPriv->a = pScreen->a; \
+ } else { \
+ ErrorF("null screen fn " #a "\n"); \
+ pScreenPriv->a = NULL; \
+ }
+
+ /* Save a pointer to each lower-level window procedure */
+ WRAP(CreateWindow);
+ WRAP(DestroyWindow);
+ WRAP(RealizeWindow);
+ WRAP(UnrealizeWindow);
+ WRAP(PositionWindow);
+ WRAP(ChangeWindowAttributes);
+ WRAP(SetShape);
+
+ /* Assign rootless window procedures to be top level procedures */
+ pScreen->CreateWindow = winCreateWindowRootless;
+ pScreen->DestroyWindow = winDestroyWindowRootless;
+ pScreen->PositionWindow = winPositionWindowRootless;
+ /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesRootless;*/
+ pScreen->RealizeWindow = winMapWindowRootless;
+ pScreen->UnrealizeWindow = winUnmapWindowRootless;
+ pScreen->SetShape = winSetShapeRootless;
+
+ /* Undefine the WRAP macro, as it is not needed elsewhere */
+#undef WRAP
+ }
+
+
+#ifdef XWIN_MULTIWINDOW
+ /* Handle multi window mode */
+ else if (pScreenInfo->fMultiWindow)
+ {
+ /* Define the WRAP macro temporarily for local use */
+#define WRAP(a) \
+ if (pScreen->a) { \
+ pScreenPriv->a = pScreen->a; \
+ } else { \
+ ErrorF("null screen fn " #a "\n"); \
+ pScreenPriv->a = NULL; \
+ }
+
+ /* Save a pointer to each lower-level window procedure */
+ WRAP(CreateWindow);
+ WRAP(DestroyWindow);
+ WRAP(RealizeWindow);
+ WRAP(UnrealizeWindow);
+ WRAP(PositionWindow);
+ WRAP(ChangeWindowAttributes);
+ WRAP(ReparentWindow);
+ WRAP(RestackWindow);
+ WRAP(ResizeWindow);
+ WRAP(MoveWindow);
+ WRAP(CopyWindow);
+ WRAP(SetShape);
+
+ /* Assign multi-window window procedures to be top level procedures */
+ pScreen->CreateWindow = winCreateWindowMultiWindow;
+ pScreen->DestroyWindow = winDestroyWindowMultiWindow;
+ pScreen->PositionWindow = winPositionWindowMultiWindow;
+ /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesMultiWindow;*/
+ pScreen->RealizeWindow = winMapWindowMultiWindow;
+ pScreen->UnrealizeWindow = winUnmapWindowMultiWindow;
+ pScreen->ReparentWindow = winReparentWindowMultiWindow;
+ pScreen->RestackWindow = winRestackWindowMultiWindow;
+ pScreen->ResizeWindow = winResizeWindowMultiWindow;
+ pScreen->MoveWindow = winMoveWindowMultiWindow;
+ pScreen->CopyWindow = winCopyWindowMultiWindow;
+ pScreen->SetShape = winSetShapeMultiWindow;
+
+ /* Undefine the WRAP macro, as it is not needed elsewhere */
+#undef WRAP
+ }
+#endif
+
+ /* Wrap either fb's or shadow's CloseScreen with our CloseScreen */
+ pScreenPriv->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = pScreenPriv->pwinCloseScreen;
+
+#if defined(XWIN_CLIPBOARD) || defined(XWIN_MULTIWINDOW)
+ /* Create a mutex for modules in separate threads to wait for */
+ iReturn = pthread_mutex_init (&pScreenPriv->pmServerStarted, NULL);
+ if (iReturn != 0)
+ {
+ ErrorF ("winFinishScreenInitFB - pthread_mutex_init () failed: %d\n",
+ iReturn);
+ return FALSE;
+ }
+
+ /* Own the mutex for modules in separate threads */
+ iReturn = pthread_mutex_lock (&pScreenPriv->pmServerStarted);
+ if (iReturn != 0)
+ {
+ ErrorF ("winFinishScreenInitFB - pthread_mutex_lock () failed: %d\n",
+ iReturn);
+ return FALSE;
+ }
+
+ /* Set the ServerStarted flag to false */
+ pScreenPriv->fServerStarted = FALSE;
+#endif
+
+#ifdef XWIN_MULTIWINDOWEXTWM
+ pScreenPriv->fRestacking = FALSE;
+#endif
+
+#if defined(XWIN_MULTIWINDOW) || defined(XWIN_MULTIWINDOWEXTWM)
+ if (FALSE
+#ifdef XWIN_MULTIWINDOW
+ || pScreenInfo->fMultiWindow
+#endif
+#ifdef XWIN_MULTIWINDOWEXTWM
+ || pScreenInfo->fInternalWM
+#endif
+ )
+ {
+ winDebug ("winFinishScreenInitFB - Calling winInitWM.\n");
+
+ /* Initialize multi window mode */
+ if (!winInitWM (&pScreenPriv->pWMInfo,
+ &pScreenPriv->ptWMProc,
+ &pScreenPriv->ptXMsgProc,
+ &pScreenPriv->pmServerStarted,
+ pScreenInfo->dwScreen,
+ (HWND)&pScreenPriv->hwndScreen,
+#ifdef XWIN_MULTIWINDOWEXTWM
+ pScreenInfo->fInternalWM ||
+#endif
+ FALSE))
+ {
+ ErrorF ("winFinishScreenInitFB - winInitWM () failed.\n");
+ return FALSE;
+ }
+ }
+#endif
+
+ /* Tell the server that we are enabled */
+ pScreenPriv->fEnabled = TRUE;
+
+ /* Tell the server that we have a valid depth */
+ pScreenPriv->fBadDepth = FALSE;
+
+ winDebug ("winFinishScreenInitFB - returning\n");
+
+ return TRUE;
+}
+
+#ifdef XWIN_NATIVEGDI
+/* See Porting Layer Definition - p. 20 */
+
+Bool
+winFinishScreenInitNativeGDI (int index,
+ ScreenPtr pScreen,
+ int argc, char **argv)
+{
+ winScreenPriv(pScreen);
+ winScreenInfoPtr pScreenInfo = &g_ScreenInfo[index];
+ VisualPtr pVisuals = NULL;
+ DepthPtr pDepths = NULL;
+ VisualID rootVisual = 0;
+ int nVisuals = 0, nDepths = 0, nRootDepth = 0;
+
+ /* Ignore user input (mouse, keyboard) */
+ pScreenInfo->fIgnoreInput = FALSE;
+
+ /* Get device contexts for the screen and shadow bitmap */
+ pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen);
+ if (pScreenPriv->hdcScreen == NULL)
+ FatalError ("winFinishScreenInitNativeGDI - Couldn't get a DC\n");
+
+ /* Init visuals */
+ if (!(*pScreenPriv->pwinInitVisuals) (pScreen))
+ {
+ ErrorF ("winFinishScreenInitNativeGDI - pwinInitVisuals failed\n");
+ return FALSE;
+ }
+
+ /* Initialize the mi visuals */
+ if (!miInitVisuals (&pVisuals, &pDepths, &nVisuals, &nDepths, &nRootDepth,
+ &rootVisual,
+ ((unsigned long)1 << (pScreenInfo->dwDepth - 1)), 8,
+ TrueColor))
+ {
+ ErrorF ("winFinishScreenInitNativeGDI - miInitVisuals () failed\n");
+ return FALSE;
+ }
+
+ /* Initialize the CloseScreen procedure pointer */
+ pScreen->CloseScreen = NULL;
+
+ /* Initialize the mi code */
+ if (!miScreenInit (pScreen,
+ NULL, /* No framebuffer */
+ pScreenInfo->dwWidth, pScreenInfo->dwHeight,
+ monitorResolution, monitorResolution,
+ pScreenInfo->dwStride,
+ nRootDepth, nDepths, pDepths, rootVisual,
+ nVisuals, pVisuals))
+ {
+ ErrorF ("winFinishScreenInitNativeGDI - miScreenInit failed\n");
+ return FALSE;
+ }
+
+ pScreen->defColormap = FakeClientID(0);
+
+ /*
+ * Register our block and wakeup handlers; these procedures
+ * process messages in our Windows message queue; specifically,
+ * they process mouse and keyboard input.
+ */
+ pScreen->BlockHandler = winBlockHandler;
+ pScreen->WakeupHandler = winWakeupHandler;
+ pScreen->blockData = pScreen;
+ pScreen->wakeupData = pScreen;
+
+ /* Place our save screen function */
+ pScreen->SaveScreen = winSaveScreen;
+
+ /* Pixmaps */
+ pScreen->CreatePixmap = winCreatePixmapNativeGDI;
+ pScreen->DestroyPixmap = winDestroyPixmapNativeGDI;
+
+ /* Other Screen Routines */
+ pScreen->QueryBestSize = winQueryBestSizeNativeGDI;
+ pScreen->SaveScreen = winSaveScreen;
+ pScreen->GetImage = miGetImage;
+ pScreen->GetSpans = winGetSpansNativeGDI;
+
+ /* Window Procedures */
+ pScreen->CreateWindow = winCreateWindowNativeGDI;
+ pScreen->DestroyWindow = winDestroyWindowNativeGDI;
+ pScreen->PositionWindow = winPositionWindowNativeGDI;
+ /*pScreen->ChangeWindowAttributes = winChangeWindowAttributesNativeGDI;*/
+ pScreen->RealizeWindow = winMapWindowNativeGDI;
+ pScreen->UnrealizeWindow = winUnmapWindowNativeGDI;
+
+ /* Paint window */
+ pScreen->CopyWindow = winCopyWindowNativeGDI;
+
+ /* Fonts */
+ pScreen->RealizeFont = winRealizeFontNativeGDI;
+ pScreen->UnrealizeFont = winUnrealizeFontNativeGDI;
+
+ /* GC */
+ pScreen->CreateGC = winCreateGCNativeGDI;
+
+ /* Colormap Routines */
+ pScreen->CreateColormap = miInitializeColormap;
+ pScreen->DestroyColormap = (DestroyColormapProcPtr) (void (*)(void)) NoopDDA;
+ pScreen->InstallColormap = miInstallColormap;
+ pScreen->UninstallColormap = miUninstallColormap;
+ pScreen->ListInstalledColormaps = miListInstalledColormaps;
+ pScreen->StoreColors = (StoreColorsProcPtr) (void (*)(void)) NoopDDA;
+ pScreen->ResolveColor = miResolveColor;
+
+ /* Bitmap */
+ pScreen->BitmapToRegion = winPixmapToRegionNativeGDI;
+
+ winDebug ("winFinishScreenInitNativeGDI - calling miDCInitialize\n");
+
+ /* Set the default white and black pixel positions */
+ pScreen->whitePixel = pScreen->blackPixel = (Pixel) 0;
+
+ /* Initialize the cursor */
+ if (!miDCInitialize (pScreen, &g_winPointerCursorFuncs))
+ {
+ ErrorF ("winFinishScreenInitNativeGDI - miDCInitialize failed\n");
+ return FALSE;
+ }
+
+ /* Create a default colormap */
+ if (!miCreateDefColormap (pScreen))
+ {
+ ErrorF ("winFinishScreenInitNativeGDI - miCreateDefColormap () "
+ "failed\n");
+ return FALSE;
+ }
+
+ winDebug ("winFinishScreenInitNativeGDI - miCreateDefColormap () "
+ "returned\n");
+
+ /* mi doesn't use a CloseScreen procedure, so no need to wrap */
+ pScreen->CloseScreen = pScreenPriv->pwinCloseScreen;
+
+ /* Tell the server that we are enabled */
+ pScreenPriv->fEnabled = TRUE;
+
+ winDebug ("winFinishScreenInitNativeGDI - Successful addition of "
+ "screen %08x\n",
+ (unsigned int) pScreen);
+
+ return TRUE;
+}
+#endif
+
+
+/* See Porting Layer Definition - p. 33 */
+static Bool
+winSaveScreen (ScreenPtr pScreen, int on)
+{
+ return TRUE;
+}
diff --git a/xorg-server/hw/xwin/winshaddd.c b/xorg-server/hw/xwin/winshaddd.c index 833444177..0ef4bd432 100644 --- a/xorg-server/hw/xwin/winshaddd.c +++ b/xorg-server/hw/xwin/winshaddd.c @@ -42,16 +42,18 @@ */ extern HWND g_hDlgExit; -extern char *g_pszLogFile; +extern const char *g_pszLogFile; /* * FIXME: Headers are broken, DEFINE_GUID doesn't work correctly, * so we have to redefine it here. */ +#ifndef _MSC_VER #ifdef DEFINE_GUID #undef DEFINE_GUID #define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} #endif /* DEFINE_GUID */ +#endif /* @@ -147,9 +149,7 @@ winCreatePrimarySurfaceShadowDD (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug ("winCreatePrimarySurfaceShadowDD - Created primary surface\n"); -#endif /* * Attach a clipper to the primary surface that will clip our blits to our @@ -165,10 +165,8 @@ winCreatePrimarySurfaceShadowDD (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug ("winCreatePrimarySurfaceShadowDD - Attached clipper to " "primary surface\n"); -#endif /* Everything was correct */ return TRUE; @@ -185,7 +183,7 @@ winReleasePrimarySurfaceShadowDD (ScreenPtr pScreen) { winScreenPriv(pScreen); - ErrorF ("winReleasePrimarySurfaceShadowDD - Hello\n"); + winDebug ("winReleasePrimarySurfaceShadowDD - Hello\n"); /* Release the primary surface and clipper, if they exist */ if (pScreenPriv->pddsPrimary) @@ -197,14 +195,14 @@ winReleasePrimarySurfaceShadowDD (ScreenPtr pScreen) IDirectDrawSurface2_SetClipper (pScreenPriv->pddsPrimary, NULL); - ErrorF ("winReleasePrimarySurfaceShadowDD - Detached clipper\n"); + winDebug ("winReleasePrimarySurfaceShadowDD - Detached clipper\n"); /* Release the primary surface */ IDirectDrawSurface2_Release (pScreenPriv->pddsPrimary); pScreenPriv->pddsPrimary = NULL; } - ErrorF ("winReleasePrimarySurfaceShadowDD - Released primary surface\n"); + winDebug ("winReleasePrimarySurfaceShadowDD - Released primary surface\n"); return TRUE; } @@ -227,9 +225,7 @@ winAllocateFBShadowDD (ScreenPtr pScreen) DDSURFACEDESC ddsd; DDSURFACEDESC *pddsdShadow = NULL; -#if CYGDEBUG winDebug ("winAllocateFBShadowDD\n"); -#endif /* Create a clipper */ ddrval = (*g_fpDirectDrawCreateClipper) (0, @@ -242,9 +238,7 @@ winAllocateFBShadowDD (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug ("winAllocateFBShadowDD - Created a clipper\n"); -#endif /* Get a device context for the screen */ pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); @@ -261,9 +255,7 @@ winAllocateFBShadowDD (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug ("winAllocateFBShadowDD - Attached clipper to window\n"); -#endif /* Create a DirectDraw object, store the address at lpdd */ ddrval = (*g_fpDirectDrawCreate) (NULL, &pScreenPriv->pdd, NULL); @@ -274,9 +266,7 @@ winAllocateFBShadowDD (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug ("winAllocateFBShadowDD () - Created and initialized DD\n"); -#endif /* Get a DirectDraw2 interface pointer */ ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, @@ -359,7 +349,7 @@ winAllocateFBShadowDD (ScreenPtr pScreen) || pScreenInfo->dwBPP != GetDeviceCaps (hdc, BITSPIXEL) || pScreenInfo->dwRefreshRate != 0)) { - ErrorF ("winAllocateFBShadowDD - Changing video mode\n"); + winDebug ("winAllocateFBShadowDD - Changing video mode\n"); /* Change the video mode to the mode requested, and use the driver default refresh rate on failure */ ddrval = IDirectDraw2_SetDisplayMode (pScreenPriv->pdd2, @@ -391,7 +381,7 @@ winAllocateFBShadowDD (ScreenPtr pScreen) } else { - ErrorF ("winAllocateFBShadowDD - Not changing video mode\n"); + winDebug ("winAllocateFBShadowDD - Not changing video mode\n"); } /* Release our DC */ @@ -448,9 +438,7 @@ winAllocateFBShadowDD (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug ("winAllocateFBShadowDD - Created shadow\n"); -#endif /* Allocate a DD surface description for our screen privates */ pddsdShadow = pScreenPriv->pddsdShadow = malloc (sizeof (DDSURFACEDESC)); @@ -463,9 +451,7 @@ winAllocateFBShadowDD (ScreenPtr pScreen) ZeroMemory (pddsdShadow, sizeof (*pddsdShadow)); pddsdShadow->dwSize = sizeof (*pddsdShadow); -#if CYGDEBUG winDebug ("winAllocateFBShadowDD - Locking shadow\n"); -#endif /* Lock the shadow surface */ ddrval = IDirectDrawSurface2_Lock (pScreenPriv->pddsShadow, @@ -480,9 +466,7 @@ winAllocateFBShadowDD (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug ("winAllocateFBShadowDD - Locked shadow\n"); -#endif /* We don't know how to deal with anything other than RGB */ if (!(pddsdShadow->ddpfPixelFormat.dwFlags & DDPF_RGB)) @@ -503,9 +487,7 @@ winAllocateFBShadowDD (ScreenPtr pScreen) pScreenPriv->dwGreenMask = pddsdShadow->ddpfPixelFormat.u3.dwGBitMask; pScreenPriv->dwBlueMask = pddsdShadow->ddpfPixelFormat.u4.dwBBitMask; -#if CYGDEBUG winDebug ("winAllocateFBShadowDD - Returning\n"); -#endif return TRUE; } @@ -646,6 +628,7 @@ winShadowUpdateDD (ScreenPtr pScreen, /* Has our memory pointer changed? */ if (pScreenInfo->pfb != pScreenPriv->pddsdShadow->lpSurface) { + extern const char *g_pszLogFile; ErrorF ("winShadowUpdateDD - Memory location of the shadow " "surface has changed, trying to update the root window " "pixmap header to point to the new address. If you get " @@ -687,9 +670,7 @@ winCloseScreenShadowDD (int nIndex, ScreenPtr pScreen) winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; Bool fReturn; -#if CYGDEBUG winDebug ("winCloseScreenShadowDD - Freeing screen resources\n"); -#endif /* Flag that the screen is closed */ pScreenPriv->fClosed = TRUE; @@ -813,7 +794,7 @@ winInitVisualsShadowDD (ScreenPtr pScreen) else pScreenPriv->dwBitsPerRGB = dwBlueBits; - ErrorF ("winInitVisualsShadowDD - Masks %08x %08x %08x BPRGB %d d %d " + winDebug ("winInitVisualsShadowDD - Masks %08x %08x %08x BPRGB %d d %d " "bpp %d\n", (unsigned int) pScreenPriv->dwRedMask, (unsigned int) pScreenPriv->dwGreenMask, @@ -932,9 +913,7 @@ winInitVisualsShadowDD (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug ("winInitVisualsShadowDD - Returning\n"); -#endif return TRUE; } @@ -967,7 +946,7 @@ winAdjustVideoModeShadowDD (ScreenPtr pScreen) if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) { /* No -depth parameter passed, let the user know the depth being used */ - ErrorF ("winAdjustVideoModeShadowDD - Using Windows display " + winDebug ("winAdjustVideoModeShadowDD - Using Windows display " "depth of %d bits per pixel\n", (int) dwBPP); /* Use GDI's depth */ @@ -977,13 +956,13 @@ winAdjustVideoModeShadowDD (ScreenPtr pScreen) && pScreenInfo->dwBPP != dwBPP) { /* FullScreen, and GDI depth differs from -depth parameter */ - ErrorF ("winAdjustVideoModeShadowDD - FullScreen, using command line " + winDebug ("winAdjustVideoModeShadowDD - FullScreen, using command line " "bpp: %d\n", (int) pScreenInfo->dwBPP); } else if (dwBPP != pScreenInfo->dwBPP) { /* Windowed, and GDI depth differs from -depth parameter */ - ErrorF ("winAdjustVideoModeShadowDD - Windowed, command line bpp: " + winDebug ("winAdjustVideoModeShadowDD - Windowed, command line bpp: " "%d, using bpp: %d\n", (int) pScreenInfo->dwBPP, (int) dwBPP); /* We'll use GDI's depth */ @@ -1379,10 +1358,8 @@ winDestroyColormapShadowDD (ColormapPtr pColormap) */ if (pColormap->flags & IsDefault) { -#if CYGDEBUG winDebug ("winDestroyColormapShadowDD - Destroying default " "colormap\n"); -#endif /* * FIXME: Walk the list of all screens, popping the default diff --git a/xorg-server/hw/xwin/winshadddnl.c b/xorg-server/hw/xwin/winshadddnl.c index ef5c21469..b8d6222ac 100644 --- a/xorg-server/hw/xwin/winshadddnl.c +++ b/xorg-server/hw/xwin/winshadddnl.c @@ -48,10 +48,12 @@ extern HWND g_hDlgExit; * FIXME: Headers are broken, DEFINE_GUID doesn't work correctly, * so we have to redefine it here. */ +#ifndef _MSC_VER #ifdef DEFINE_GUID #undef DEFINE_GUID #define DEFINE_GUID(n,l,w1,w2,b1,b2,b3,b4,b5,b6,b7,b8) const GUID n GUID_SECT = {l,w1,w2,{b1,b2,b3,b4,b5,b6,b7,b8}} #endif /* DEFINE_GUID */ +#endif /* * FIXME: Headers are broken, IID_IDirectDraw4 has to be defined @@ -161,9 +163,7 @@ winCreatePrimarySurfaceShadowDDNL (ScreenPtr pScreen) return FALSE; } -#if 1 winDebug ("winCreatePrimarySurfaceShadowDDNL - Created primary surface\n"); -#endif /* Attach our clipper to our primary surface handle */ ddrval = IDirectDrawSurface4_SetClipper (pScreenPriv->pddsPrimary4, @@ -176,10 +176,8 @@ winCreatePrimarySurfaceShadowDDNL (ScreenPtr pScreen) return FALSE; } -#if 1 winDebug ("winCreatePrimarySurfaceShadowDDNL - Attached clipper to primary " "surface\n"); -#endif /* Everything was correct */ return TRUE; @@ -239,10 +237,8 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen) char *lpSurface = NULL; DDPIXELFORMAT ddpfPrimary; -#if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - w %d h %d d %d\n", pScreenInfo->dwWidth, pScreenInfo->dwHeight, pScreenInfo->dwDepth); -#endif /* Allocate memory for our shadow surface */ lpSurface = malloc (pScreenInfo->dwPaddedWidth * pScreenInfo->dwHeight); @@ -269,9 +265,7 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Created a clipper\n"); -#endif /* Get a device context for the screen */ pScreenPriv->hdcScreen = GetDC (pScreenPriv->hwndScreen); @@ -288,9 +282,7 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Attached clipper to window\n"); -#endif /* Create a DirectDraw object, store the address at lpdd */ ddrval = (*g_fpDirectDrawCreate) (NULL, @@ -304,9 +296,7 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Created and initialized DD\n"); -#endif /* Get a DirectDraw4 interface pointer */ ddrval = IDirectDraw_QueryInterface (pScreenPriv->pdd, @@ -464,14 +454,12 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Primary masks: %08x %08x %08x " "dwRGBBitCount: %d\n", ddpfPrimary.u2.dwRBitMask, ddpfPrimary.u3.dwGBitMask, ddpfPrimary.u4.dwBBitMask, ddpfPrimary.u1.dwRGBBitCount); -#endif /* Describe the shadow surface to be created */ /* @@ -508,19 +496,15 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG || YES winDebug ("winAllocateFBShadowDDNL - Created shadow pitch: %d\n", (int) ddsdShadow.u1.lPitch); -#endif /* Grab the pitch from the surface desc */ pScreenInfo->dwStride = (ddsdShadow.u1.lPitch * 8) / pScreenInfo->dwBPP; -#if CYGDEBUG || YES winDebug ("winAllocateFBShadowDDNL - Created shadow stride: %d\n", (int) pScreenInfo->dwStride); -#endif /* Save the pointer to our surface memory */ pScreenInfo->pfb = lpSurface; @@ -530,9 +514,7 @@ winAllocateFBShadowDDNL (ScreenPtr pScreen) pScreenPriv->dwGreenMask = ddsdShadow.u4.ddpfPixelFormat.u3.dwGBitMask; pScreenPriv->dwBlueMask = ddsdShadow.u4.ddpfPixelFormat.u4.dwBBitMask; -#if CYGDEBUG winDebug ("winAllocateFBShadowDDNL - Returning\n"); -#endif return TRUE; } @@ -696,11 +678,9 @@ winShadowUpdateDDNL (ScreenPtr pScreen, DeleteObject (hrgnCombined); hrgnCombined = NULL; -#if CYGDEBUG winDebug ("winShadowUpdateDDNL - be x1 %d y1 %d x2 %d y2 %d\n", pBoxExtents->x1, pBoxExtents->y1, pBoxExtents->x2, pBoxExtents->y2); -#endif /* Calculating a bounding box for the source is easy */ rcSrc.left = pBoxExtents->x1; @@ -741,9 +721,7 @@ winCloseScreenShadowDDNL (int nIndex, ScreenPtr pScreen) winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; Bool fReturn; -#if CYGDEBUG winDebug ("winCloseScreenShadowDDNL - Freeing screen resources\n"); -#endif /* Flag that the screen is closed */ pScreenPriv->fClosed = TRUE; @@ -987,9 +965,7 @@ winInitVisualsShadowDDNL (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug ("winInitVisualsShadowDDNL - Returning\n"); -#endif return TRUE; } @@ -1022,7 +998,7 @@ winAdjustVideoModeShadowDDNL (ScreenPtr pScreen) if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) { /* No -depth parameter passed, let the user know the depth being used */ - winErrorFVerb (2, "winAdjustVideoModeShadowDDNL - Using Windows display " + winDebug ("winAdjustVideoModeShadowDDNL - Using Windows display " "depth of %d bits per pixel\n", (int) dwBPP); /* Use GDI's depth */ @@ -1032,13 +1008,13 @@ winAdjustVideoModeShadowDDNL (ScreenPtr pScreen) && pScreenInfo->dwBPP != dwBPP) { /* FullScreen, and GDI depth differs from -depth parameter */ - winErrorFVerb (2, "winAdjustVideoModeShadowDDNL - FullScreen, using command " + winDebug ("winAdjustVideoModeShadowDDNL - FullScreen, using command " "line bpp: %d\n", (int) pScreenInfo->dwBPP); } else if (dwBPP != pScreenInfo->dwBPP) { /* Windowed, and GDI depth differs from -depth parameter */ - winErrorFVerb (2, "winAdjustVideoModeShadowDDNL - Windowed, command line " + winDebug ("winAdjustVideoModeShadowDDNL - Windowed, command line " "bpp: %d, using bpp: %d\n", (int) pScreenInfo->dwBPP, (int) dwBPP); @@ -1050,7 +1026,7 @@ winAdjustVideoModeShadowDDNL (ScreenPtr pScreen) if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP >= WIN_DIB_MAXIMUM_SIZE) { - winErrorFVerb (1, "winAdjustVideoModeShadowDDNL - Requested DirectDraw surface " + ErrorF ("winAdjustVideoModeShadowDDNL - Requested DirectDraw surface " "will be larger than %d MB. The surface may fail to be " "allocated on Windows 95, 98, or Me, due to a %d MB limit in " "DIB size. This limit does not apply to Windows NT/2000, and " @@ -1134,7 +1110,7 @@ winBltExposedRegionsShadowDDNL (ScreenPtr pScreen) if (ddrval == DDERR_SURFACELOST) { /* Surface was lost */ - winErrorFVerb (1, "winBltExposedRegionsShadowDDNL - " + ErrorF ("winBltExposedRegionsShadowDDNL - " "IDirectDrawSurface4_Blt reported that the primary " "surface was lost, trying to restore, retry: %d\n", i + 1); @@ -1164,7 +1140,7 @@ winBltExposedRegionsShadowDDNL (ScreenPtr pScreen) else if (FAILED (ddrval)) { fReturn = FALSE; - winErrorFVerb (1, "winBltExposedRegionsShadowDDNL - " + ErrorF ("winBltExposedRegionsShadowDDNL - " "IDirectDrawSurface4_Blt failed, but surface not " "lost: %08x %d\n", (unsigned int) ddrval, (int) ddrval); @@ -1392,9 +1368,7 @@ winDestroyColormapShadowDDNL (ColormapPtr pColormap) */ if (pColormap->flags & IsDefault) { -#if CYGDEBUG winDebug ("winDestroyColormapShadowDDNL - Destroying default colormap\n"); -#endif /* * FIXME: Walk the list of all screens, popping the default diff --git a/xorg-server/hw/xwin/winshadgdi.c b/xorg-server/hw/xwin/winshadgdi.c index d38e4f76b..fbc15abb3 100644 --- a/xorg-server/hw/xwin/winshadgdi.c +++ b/xorg-server/hw/xwin/winshadgdi.c @@ -109,7 +109,7 @@ winQueryScreenDIBFormat (ScreenPtr pScreen, BITMAPINFOHEADER *pbmih) { winScreenPriv(pScreen); HBITMAP hbmp; -#if CYGDEBUG +#ifdef WINDBG LPDWORD pdw = NULL; #endif @@ -138,7 +138,7 @@ winQueryScreenDIBFormat (ScreenPtr pScreen, BITMAPINFOHEADER *pbmih) return FALSE; } -#if CYGDEBUG +#ifdef WINDBG /* Get a pointer to bitfields */ pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); @@ -199,7 +199,7 @@ winQueryRGBBitsAndMasks (ScreenPtr pScreen) if (GetDeviceCaps (pScreenPriv->hdcScreen, PLANES) * GetDeviceCaps (pScreenPriv->hdcScreen, BITSPIXEL) == 24) { - ErrorF ("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) " + winDebug ("winQueryRGBBitsAndMasks - GetDeviceCaps (BITSPIXEL) " "returned 24 for the screen. Using default 24bpp masks.\n"); /* 8 bits per primary color */ @@ -228,7 +228,7 @@ winQueryRGBBitsAndMasks (ScreenPtr pScreen) /* Get a pointer to bitfields */ pdw = (DWORD*) ((CARD8*)pbmih + sizeof (BITMAPINFOHEADER)); -#if CYGDEBUG +#ifdef WINDBG winDebug ("%s - Masks: %08x %08x %08x\n", __FUNCTION__, pdw[0], pdw[1], pdw[2]); winDebug ("%s - Bitmap: %dx%d %d bpp %d planes\n", __FUNCTION__, @@ -372,7 +372,7 @@ winAllocateFBShadowGDI (ScreenPtr pScreen) pbmih->biWidth = pScreenInfo->dwWidth; pbmih->biHeight = -pScreenInfo->dwHeight; - ErrorF ("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d " + winDebug ("winAllocateFBShadowGDI - Creating DIB with width: %d height: %d " "depth: %d\n", (int) pbmih->biWidth, (int) -pbmih->biHeight, pbmih->biBitCount); @@ -385,14 +385,12 @@ winAllocateFBShadowGDI (ScreenPtr pScreen) 0); if (pScreenPriv->hbmpShadow == NULL || pScreenInfo->pfb == NULL) { - winW32Error (2, "winAllocateFBShadowGDI - CreateDIBSection failed:"); + winW32Error ("winAllocateFBShadowGDI - CreateDIBSection failed:"); return FALSE; } else { -#if CYGDEBUG winDebug ("winAllocateFBShadowGDI - Shadow buffer allocated\n"); -#endif } /* Get information about the bitmap that was allocated */ @@ -400,22 +398,18 @@ winAllocateFBShadowGDI (ScreenPtr pScreen) sizeof (dibsection), &dibsection); -#if CYGDEBUG || YES /* Print information about bitmap allocated */ winDebug ("winAllocateFBShadowGDI - Dibsection width: %d height: %d " "depth: %d size image: %d\n", (int) dibsection.dsBmih.biWidth, (int) dibsection.dsBmih.biHeight, dibsection.dsBmih.biBitCount, (int) dibsection.dsBmih.biSizeImage); -#endif /* Select the shadow bitmap into the shadow DC */ SelectObject (pScreenPriv->hdcShadow, pScreenPriv->hbmpShadow); -#if CYGDEBUG winDebug ("winAllocateFBShadowGDI - Attempting a shadow blit\n"); -#endif /* Do a test blit from the shadow to the screen, I think */ fReturn = BitBlt (pScreenPriv->hdcScreen, @@ -426,21 +420,15 @@ winAllocateFBShadowGDI (ScreenPtr pScreen) SRCCOPY); if (fReturn) { -#if CYGDEBUG winDebug ("winAllocateFBShadowGDI - Shadow blit success\n"); -#endif } else { - winW32Error (2, "winAllocateFBShadowGDI - Shadow blit failure\n"); -#if 0 - return FALSE; -#else + winW32Error ("winAllocateFBShadowGDI - Shadow blit failure\n"); /* ago: ignore this error. The blit fails with wine, but does not * cause any problems later. */ fReturn = TRUE; -#endif } /* Look for height weirdness */ @@ -454,10 +442,8 @@ winAllocateFBShadowGDI (ScreenPtr pScreen) / dibsection.dsBmih.biHeight) * 8) / pScreenInfo->dwBPP; -#if CYGDEBUG || YES winDebug ("winAllocateFBShadowGDI - Created shadow stride: %d\n", (int) pScreenInfo->dwStride); -#endif /* See if the shadow bitmap will be larger than the DIB size limit */ if (pScreenInfo->dwWidth * pScreenInfo->dwHeight * pScreenInfo->dwBPP @@ -524,15 +510,17 @@ winShadowUpdateGDI (ScreenPtr pScreen, if (dwBox != 1) { ++s_dwNonUnitRegions; - ErrorF ("winShadowUpdatGDI - dwBox: %d\n", dwBox); + winDebug ("winShadowUpdatGDI - dwBox: %d\n", dwBox); } if ((s_dwTotalUpdates % 100) == 0) - ErrorF ("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d " + { + winDebug ("winShadowUpdateGDI - %d%% non-unity regions, avg boxes: %d " "nu: %d tu: %d\n", (s_dwNonUnitRegions * 100) / s_dwTotalUpdates, s_dwTotalBoxes / s_dwTotalUpdates, s_dwNonUnitRegions, s_dwTotalUpdates); + } #endif /* XWIN_UPDATESTATS */ /* @@ -625,9 +613,7 @@ winCloseScreenShadowGDI (int nIndex, ScreenPtr pScreen) winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; Bool fReturn; -#if CYGDEBUG winDebug ("winCloseScreenShadowGDI - Freeing screen resources\n"); -#endif /* Flag that the screen is closed */ pScreenPriv->fClosed = TRUE; @@ -700,7 +686,7 @@ winInitVisualsShadowGDI (ScreenPtr pScreen) winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; /* Display debugging information */ - ErrorF ("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d " + winDebug ("winInitVisualsShadowGDI - Masks %08x %08x %08x BPRGB %d d %d " "bpp %d\n", (unsigned int) pScreenPriv->dwRedMask, (unsigned int) pScreenPriv->dwGreenMask, @@ -816,9 +802,7 @@ winInitVisualsShadowGDI (ScreenPtr pScreen) return FALSE; } -#if CYGDEBUG winDebug ("winInitVisualsShadowGDI - Returning\n"); -#endif return TRUE; } @@ -852,7 +836,7 @@ winAdjustVideoModeShadowGDI (ScreenPtr pScreen) if (pScreenInfo->dwBPP == WIN_DEFAULT_BPP) { /* No -depth parameter passed, let the user know the depth being used */ - ErrorF ("winAdjustVideoModeShadowGDI - Using Windows display " + winDebug ("winAdjustVideoModeShadowGDI - Using Windows display " "depth of %d bits per pixel\n", (int) dwBPP); /* Use GDI's depth */ @@ -861,7 +845,7 @@ winAdjustVideoModeShadowGDI (ScreenPtr pScreen) else if (dwBPP != pScreenInfo->dwBPP) { /* Warn user if GDI depth is different than -depth parameter */ - ErrorF ("winAdjustVideoModeShadowGDI - Command line bpp: %d, "\ + winDebug ("winAdjustVideoModeShadowGDI - Command line bpp: %d, "\ "using bpp: %d\n", (int) pScreenInfo->dwBPP, (int) dwBPP); /* We'll use GDI's depth */ @@ -1010,17 +994,13 @@ winRealizeInstalledPaletteShadowGDI (ScreenPtr pScreen) winScreenPriv(pScreen); winPrivCmapPtr pCmapPriv = NULL; -#if CYGDEBUG winDebug ("winRealizeInstalledPaletteShadowGDI\n"); -#endif /* Don't do anything if there is not a colormap */ if (pScreenPriv->pcmapInstalled == NULL) { -#if CYGDEBUG winDebug ("winRealizeInstalledPaletteShadowGDI - No colormap " "installed\n"); -#endif return TRUE; } @@ -1247,10 +1227,8 @@ winDestroyColormapShadowGDI (ColormapPtr pColormap) */ if (pColormap->flags & IsDefault) { -#if CYGDEBUG winDebug ("winDestroyColormapShadowGDI - Destroying default " "colormap\n"); -#endif /* * FIXME: Walk the list of all screens, popping the default diff --git a/xorg-server/hw/xwin/wintrayicon.c b/xorg-server/hw/xwin/wintrayicon.c index 895b47caf..7750932b4 100644 --- a/xorg-server/hw/xwin/wintrayicon.c +++ b/xorg-server/hw/xwin/wintrayicon.c @@ -36,35 +36,43 @@ #include <shellapi.h> #include "winprefs.h" +static NOTIFYICONDATA nid; /* * Initialize the tray icon */ void -winInitNotifyIcon (winPrivScreenPtr pScreenPriv) +winInitNotifyIcon (winPrivScreenPtr pScreenPriv, Bool Modify) { winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; - NOTIFYICONDATA nid = {0}; + char HostName[256]; - nid.cbSize = sizeof (NOTIFYICONDATA); - nid.hWnd = pScreenPriv->hwndScreen; - nid.uID = pScreenInfo->dwScreen; - nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; - nid.uCallbackMessage = WM_TRAYICON; - nid.hIcon = winTaskbarIcon (); + if (!Modify) + { + nid.cbSize = sizeof (NOTIFYICONDATA); + nid.hWnd = pScreenPriv->hwndScreen; + nid.uID = pScreenInfo->dwScreen; + nid.uFlags = NIF_ICON | NIF_MESSAGE | NIF_TIP; + nid.uCallbackMessage = WM_TRAYICON; + nid.hIcon = winTaskbarIcon (); + + /* Save handle to the icon so it can be freed later */ + pScreenPriv->hiconNotifyIcon = nid.hIcon; + } - /* Save handle to the icon so it can be freed later */ - pScreenPriv->hiconNotifyIcon = nid.hIcon; + gethostname(HostName,256); /* Set display and screen-specific tooltip text */ snprintf (nid.szTip, sizeof (nid.szTip), - PROJECT_NAME " Server:%s.%d", + PROJECT_NAME " Server - %s:%s.%d - %d clients", + HostName, display, - (int) pScreenInfo->dwScreen); + (int) pScreenInfo->dwScreen, + pScreenPriv->iConnectedClients); /* Add the tray icon */ - if (!Shell_NotifyIcon (NIM_ADD, &nid)) + if (!Shell_NotifyIcon ((Modify) ? NIM_MODIFY : NIM_ADD, &nid)) ErrorF ("winInitNotifyIcon - Shell_NotifyIcon Failed\n"); } @@ -79,10 +87,6 @@ winDeleteNotifyIcon (winPrivScreenPtr pScreenPriv) winScreenInfo *pScreenInfo = pScreenPriv->pScreenInfo; NOTIFYICONDATA nid = {0}; -#if 0 - ErrorF ("winDeleteNotifyIcon\n"); -#endif - nid.cbSize = sizeof (NOTIFYICONDATA); nid.hWnd = pScreenPriv->hwndScreen; nid.uID = pScreenInfo->dwScreen; @@ -119,6 +123,17 @@ winHandleIconMessage (HWND hwnd, UINT message, switch (lParam) { + case WM_MOUSEMOVE: + { + static int PrevNrClients; + int NrClients=GetLiveClients(pScreenPriv); + if (NrClients!=PrevNrClients) + { + PrevNrClients=NrClients; + winInitNotifyIcon (pScreenPriv, TRUE); + } + } + break; case WM_LBUTTONUP: /* Restack and bring all windows to top */ SetForegroundWindow (hwnd); diff --git a/xorg-server/hw/xwin/winvalargs.c b/xorg-server/hw/xwin/winvalargs.c index 038e097a5..1c9b17fde 100644 --- a/xorg-server/hw/xwin/winvalargs.c +++ b/xorg-server/hw/xwin/winvalargs.c @@ -75,7 +75,7 @@ winValidateArgs (void) if (g_ScreenInfo[i].fExplicitScreen) iMaxConsecutiveScreen = i + 1; } - winErrorFVerb (2, "winValidateArgs - g_iNumScreens: %d " + winDebug ("winValidateArgs - g_iNumScreens: %d " "iMaxConsecutiveScreen: %d\n", g_iNumScreens, iMaxConsecutiveScreen); if (g_iNumScreens < iMaxConsecutiveScreen) diff --git a/xorg-server/hw/xwin/winwin32rootless.c b/xorg-server/hw/xwin/winwin32rootless.c index c225a4495..f76363e43 100644 --- a/xorg-server/hw/xwin/winwin32rootless.c +++ b/xorg-server/hw/xwin/winwin32rootless.c @@ -323,9 +323,7 @@ winMWExtWMCreateFrame (RootlessWindowPtr pFrame, ScreenPtr pScreen, fResult = FALSE; } -#if CYGMULTIWINDOW_DEBUG winDebug ("winMWExtWMCreateFrame - ShowWindow\n"); -#endif //ShowWindow (pRLWinPriv->hWnd, SW_SHOWNOACTIVATE); g_fNoConfigureWindow = FALSE; @@ -799,9 +797,7 @@ winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow) SRCCOPY); if (fReturn) { -#if CYGMULTIWINDOW_DEBUG winDebug ("winMWExtWMStartDrawing - Shadow blit success\n"); -#endif } else { @@ -822,10 +818,8 @@ winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow) pRLWinPriv->dwWidthBytes = dibsection.dsBm.bmWidthBytes; -#if CYGMULTIWINDOW_DEBUG winDebug ("winMWExtWMStartDrawing - bytesPerRow: %d\n", (unsigned int)dibsection.dsBm.bmWidthBytes); -#endif /* Free the old shadow bitmap */ DeleteObject (pRLWinPriv->hdcShadow); @@ -835,22 +829,18 @@ winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow) pRLWinPriv->hbmpShadow = hbmpNew; pRLWinPriv->fResized = FALSE; -#if CYGMULTIWINDOW_DEBUG && FALSE winDebug ("winMWExtWMStartDrawing - 0x%08x %d\n", (unsigned int)pRLWinPriv->pfb, (unsigned int)dibsection.dsBm.bmWidthBytes); -#endif } } else { ErrorF ("winMWExtWMStartDrawing - Already window was destroyed \n"); } -#if CYGMULTIWINDOW_DEBUG winDebug ("winMWExtWMStartDrawing - done (0x%08x) 0x%08x %d\n", (int) pRLWinPriv, (unsigned int)pRLWinPriv->pfb, (unsigned int)pRLWinPriv->dwWidthBytes); -#endif *pixelData = pRLWinPriv->pfb; *bytesPerRow = pRLWinPriv->dwWidthBytes; } @@ -858,77 +848,12 @@ winMWExtWMStartDrawing (RootlessFrameID wid, char **pixelData, int *bytesPerRow) void winMWExtWMStopDrawing (RootlessFrameID wid, Bool fFlush) { -#if 0 - win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; - BLENDFUNCTION bfBlend; - SIZE szWin; - POINT ptSrc; -#if CYGMULTIWINDOW_DEBUG || TRUE - winDebug ("winMWExtWMStopDrawing (%08x)\n", pRLWinPriv); -#endif - szWin.cx = pRLWinPriv->dwWidth; - szWin.cy = pRLWinPriv->dwHeight; - ptSrc.x = 0; - ptSrc.y = 0; - bfBlend.BlendOp = AC_SRC_OVER; - bfBlend.BlendFlags = 0; - bfBlend.SourceConstantAlpha = 255; - bfBlend.AlphaFormat = AC_SRC_ALPHA; - - if (!UpdateLayeredWindow (pRLWinPriv->hWnd, - NULL, NULL, &szWin, - pRLWinPriv->hdcShadow, &ptSrc, - 0, &bfBlend, ULW_ALPHA)) - { - ErrorF ("winMWExtWMStopDrawing - UpdateLayeredWindow failed\n"); - } -#endif } void winMWExtWMUpdateRegion (RootlessFrameID wid, RegionPtr pDamage) { win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; -#if 0 - BLENDFUNCTION bfBlend; - SIZE szWin; - POINT ptSrc; -#endif -#if CYGMULTIWINDOW_DEBUG && 0 - winDebug ("winMWExtWMUpdateRegion (%08x)\n", pRLWinPriv); -#endif -#if 0 - szWin.cx = pRLWinPriv->dwWidth; - szWin.cy = pRLWinPriv->dwHeight; - ptSrc.x = 0; - ptSrc.y = 0; - bfBlend.BlendOp = AC_SRC_OVER; - bfBlend.BlendFlags = 0; - bfBlend.SourceConstantAlpha = 255; - bfBlend.AlphaFormat = AC_SRC_ALPHA; - - if (!UpdateLayeredWindow (pRLWinPriv->hWnd, - NULL, NULL, &szWin, - pRLWinPriv->hdcShadow, &ptSrc, - 0, &bfBlend, ULW_ALPHA)) - { - LPVOID lpMsgBuf; - - /* Display a fancy error message */ - FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | - FORMAT_MESSAGE_FROM_SYSTEM | - FORMAT_MESSAGE_IGNORE_INSERTS, - NULL, - GetLastError (), - MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), - (LPTSTR) &lpMsgBuf, - 0, NULL); - - ErrorF ("winMWExtWMUpdateRegion - UpdateLayeredWindow failed: %s\n", - (LPSTR)lpMsgBuf); - LocalFree (lpMsgBuf); - } -#endif if (!g_fNoConfigureWindow) UpdateWindow (pRLWinPriv->hWnd); } @@ -938,10 +863,8 @@ winMWExtWMDamageRects (RootlessFrameID wid, int nCount, const BoxRec *pRects, { win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; const BoxRec *pEnd; -#if CYGMULTIWINDOW_DEBUG && 0 winDebug ("winMWExtWMDamageRects (%08x, %d, %08x, %d, %d)\n", pRLWinPriv, nCount, pRects, shift_x, shift_y); -#endif for (pEnd = pRects + nCount; pRects < pEnd; pRects++) { RECT rcDmg; @@ -958,10 +881,8 @@ void winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin) { win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) pFrame->wid; -#if CYGMULTIWINDOW_DEBUG winDebug ("winMWExtWMRootlessSwitchWindow (%08x) %08x\n", (int) pRLWinPriv, (int) pRLWinPriv->hWnd); -#endif pRLWinPriv->pFrame = pFrame; pRLWinPriv->fResized = TRUE; @@ -974,26 +895,6 @@ winMWExtWMRootlessSwitchWindow (RootlessWindowPtr pFrame, WindowPtr oldWin) DeleteProperty (serverClient, oldWin, AtmWindowsWmNativeHwnd ()); winMWExtWMSetNativeProperty (pFrame); -#if CYGMULTIWINDOW_DEBUG -#if 0 - { - WindowPtr pWin2 = NULL; - win32RootlessWindowPtr pRLWinPriv2 = NULL; - - /* Check if the Windows window property for our X window pointer is valid */ - if ((pWin2 = (WindowPtr)GetProp (pRLWinPriv->hWnd, WIN_WINDOW_PROP)) != NULL) - { - pRLWinPriv2 = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin2, FALSE); - } - winDebug ("winMWExtWMSwitchFrame2 (%08x) %08x\n", - pRLWinPriv2, pRLWinPriv2->hWnd); - if (pRLWinPriv != pRLWinPriv2 || pRLWinPriv->hWnd != pRLWinPriv2->hWnd) - { - winDebug ("Error param missmatch\n"); - } - } -#endif -#endif } void @@ -1001,18 +902,14 @@ winMWExtWMCopyBytes (unsigned int width, unsigned int height, const void *src, unsigned int srcRowBytes, void *dst, unsigned int dstRowBytes) { -#if CYGMULTIWINDOW_DEBUG winDebug ("winMWExtWMCopyBytes - Not implemented\n"); -#endif } void winMWExtWMFillBytes (unsigned int width, unsigned int height, unsigned int value, void *dst, unsigned int dstRowBytes) { -#if CYGMULTIWINDOW_DEBUG winDebug ("winMWExtWMFillBytes - Not implemented\n"); -#endif } int @@ -1021,9 +918,7 @@ winMWExtWMCompositePixels (unsigned int width, unsigned int height, unsigned int void *mask, unsigned int maskRowBytes, void *dst[2], unsigned int dstRowBytes[2]) { -#if CYGMULTIWINDOW_DEBUG winDebug ("winMWExtWMCompositePixels - Not implemented\n"); -#endif return 0; } @@ -1035,21 +930,17 @@ winMWExtWMCopyWindow (RootlessFrameID wid, int nDstRects, const BoxRec *pDstRect win32RootlessWindowPtr pRLWinPriv = (win32RootlessWindowPtr) wid; const BoxRec *pEnd; RECT rcDmg; -#if CYGMULTIWINDOW_DEBUG winDebug ("winMWExtWMCopyWindow (%08x, %d, %08x, %d, %d)\n", (int) pRLWinPriv, nDstRects, (int) pDstRects, nDx, nDy); -#endif for (pEnd = pDstRects + nDstRects; pDstRects < pEnd; pDstRects++) { -#if CYGMULTIWINDOW_DEBUG winDebug ("BitBlt (%d, %d, %d, %d) (%d, %d)\n", pDstRects->x1, pDstRects->y1, pDstRects->x2 - pDstRects->x1, pDstRects->y2 - pDstRects->y1, pDstRects->x1 + nDx, pDstRects->y1 + nDy); -#endif if (!BitBlt (pRLWinPriv->hdcShadow, pDstRects->x1, pDstRects->y1, @@ -1069,9 +960,7 @@ winMWExtWMCopyWindow (RootlessFrameID wid, int nDstRects, const BoxRec *pDstRect InvalidateRect (pRLWinPriv->hWnd, &rcDmg, FALSE); } -#if CYGMULTIWINDOW_DEBUG winDebug ("winMWExtWMCopyWindow - done\n"); -#endif } diff --git a/xorg-server/hw/xwin/winwin32rootlesswndproc.c b/xorg-server/hw/xwin/winwin32rootlesswndproc.c index 4d7afee42..71979456d 100644 --- a/xorg-server/hw/xwin/winwin32rootlesswndproc.c +++ b/xorg-server/hw/xwin/winwin32rootlesswndproc.c @@ -441,7 +441,6 @@ winMWExtWMWindowProc (HWND hwnd, UINT message, wmMsg.iHeight = pRLWinPriv->pFrame->height; fWMMsgInitialized = TRUE; -#if CYGDEBUG winDebugWin32Message("winMWExtWMWindowProc", hwnd, message, wParam, lParam); winDebug ("\thWnd %08X\n", hwnd); @@ -450,7 +449,6 @@ winMWExtWMWindowProc (HWND hwnd, UINT message, winDebug ("\thwndScreen %08X\n", hwndScreen); winDebug ("winMWExtWMWindowProc (%08x) %08x %08x %08x\n", pRLWinPriv, message, wParam, lParam); -#endif } /* Branch on message type */ switch (message) @@ -784,9 +782,7 @@ winMWExtWMWindowProc (HWND hwnd, UINT message, return 0; case WM_ERASEBKGND: -#if CYGDEBUG winDebug ("winMWExtWMWindowProc - WM_ERASEBKGND\n"); -#endif /* * Pretend that we did erase the background but we don't care, * since we repaint the entire region anyhow @@ -1324,11 +1320,11 @@ winMWExtWMWindowProc (HWND hwnd, UINT message, break; case WM_MANAGE: - ErrorF ("winMWExtWMWindowProc - WM_MANAGE\n"); + winDebug ("winMWExtWMWindowProc - WM_MANAGE\n"); break; case WM_UNMANAGE: - ErrorF ("winMWExtWMWindowProc - WM_UNMANAGE\n"); + winDebug ("winMWExtWMWindowProc - WM_UNMANAGE\n"); break; default: diff --git a/xorg-server/hw/xwin/winwindow.c b/xorg-server/hw/xwin/winwindow.c index 0e75a2c6a..6f22a5a6e 100644 --- a/xorg-server/hw/xwin/winwindow.c +++ b/xorg-server/hw/xwin/winwindow.c @@ -58,13 +58,12 @@ winReshapeRootless (WindowPtr pWin); Bool winCreateWindowNativeGDI (WindowPtr pWin) { + Bool fResult; ScreenPtr pScreen = pWin->drawable.pScreen; winWindowPriv(pWin); winScreenPriv(pScreen); -#if CYGDEBUG - winTrace ("winCreateWindowNativeGDI (%p)\n", pWin); -#endif + winDebug ("winCreateWindowNativeGDI (%p)\n", pWin); WIN_UNWRAP(CreateWindow); fResult = (*pScreen->CreateWindow) (pWin); @@ -85,9 +84,7 @@ winDestroyWindowNativeGDI (WindowPtr pWin) winWindowPriv(pWin); winScreenPriv(pScreen); -#if CYGDEBUG - winTrace ("winDestroyWindowNativeGDI (%p)\n", pWin); -#endif + winDebug ("winDestroyWindowNativeGDI (%p)\n", pWin); WIN_UNWRAP(DestroyWindow); fResult = (*pScreen->DestroyWindow)(pWin); @@ -108,9 +105,7 @@ winPositionWindowNativeGDI (WindowPtr pWin, int x, int y) winWindowPriv(pWin); winScreenPriv(pScreen); -#if CYGDEBUG - winTrace ("winPositionWindowNativeGDI (%p)\n", pWin); -#endif + winDebug ("winPositionWindowNativeGDI (%p)\n", pWin); WIN_UNWRAP(PositionWindow); fResult = (*pScreen->PositionWindow)(pWin, x, y); @@ -139,10 +134,6 @@ winCopyWindowNativeGDI (WindowPtr pWin, ScreenPtr pScreen = pWin->drawable.pScreen; winScreenPriv(pScreen); -#if 0 - ErrorF ("winCopyWindow\n"); -#endif - /* Get a pointer to the root window */ pwinRoot = WindowTable[pWin->drawable.pScreen->myNum]; @@ -182,19 +173,9 @@ winCopyWindowNativeGDI (WindowPtr pWin, pBoxDst = REGION_RECTS(prgnDst); ppt = pptSrc; -#if 0 - ErrorF ("winCopyWindow - x1\tx2\ty1\ty2\tx\ty\n"); -#endif - /* BitBlt each source to the destination point */ for (i = nbox; --i >= 0; pBoxDst++, ppt++) { -#if 0 - ErrorF ("winCopyWindow - %d\t%d\t%d\t%d\t%d\t%d\n", - pBoxDst->x1, pBoxDst->x2, pBoxDst->y1, pBoxDst->y2, - ppt->x, ppt->y); -#endif - BitBlt (pScreenPriv->hdcScreen, pBoxDst->x1, pBoxDst->y1, pBoxDst->x2 - pBoxDst->x1, pBoxDst->y2 - pBoxDst->y1, @@ -220,9 +201,7 @@ winChangeWindowAttributesNativeGDI (WindowPtr pWin, unsigned long mask) winWindowPriv(pWin); winScreenPriv(pScreen); -#if CYGDEBUG - winTrace ("winChangeWindowAttributesNativeGDI (%p)\n", pWin); -#endif + winDebug ("winChangeWindowAttributesNativeGDI (%p)\n", pWin); WIN_UNWRAP(ChangeWindowAttributes); fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask); @@ -248,9 +227,7 @@ winUnmapWindowNativeGDI (WindowPtr pWin) winWindowPriv(pWin); winScreenPriv(pScreen); -#if CYGDEBUG - winTrace ("winUnmapWindowNativeGDI (%p)\n", pWin); -#endif + winDebug ("winUnmapWindowNativeGDI (%p)\n", pWin); WIN_UNWRAP(UnrealizeWindow); fResult = (*pScreen->UnrealizeWindow)(pWin); @@ -272,9 +249,7 @@ winMapWindowNativeGDI (WindowPtr pWin) winWindowPriv(pWin); winScreenPriv(pScreen); -#if CYGDEBUG - winTrace ("winMapWindowNativeGDI (%p)\n", pWin); -#endif + winDebug ("winMapWindowNativeGDI (%p)\n", pWin); WIN_UNWRAP(RealizeWindow); fResult = (*pScreen->RealizeWindow)(pWin); @@ -297,9 +272,7 @@ winCreateWindowRootless (WindowPtr pWin) winWindowPriv(pWin); winScreenPriv(pScreen); -#if CYGDEBUG - winTrace ("winCreateWindowRootless (%p)\n", pWin); -#endif + winDebug ("winCreateWindowRootless (%p)\n", pWin); WIN_UNWRAP(CreateWindow); fResult = (*pScreen->CreateWindow) (pWin); @@ -322,9 +295,7 @@ winDestroyWindowRootless (WindowPtr pWin) winWindowPriv(pWin); winScreenPriv(pScreen); -#if CYGDEBUG - winTrace ("winDestroyWindowRootless (%p)\n", pWin); -#endif + winDebug ("winDestroyWindowRootless (%p)\n", pWin); WIN_UNWRAP(DestroyWindow); fResult = (*pScreen->DestroyWindow)(pWin); @@ -352,10 +323,7 @@ winPositionWindowRootless (WindowPtr pWin, int x, int y) ScreenPtr pScreen = pWin->drawable.pScreen; winScreenPriv(pScreen); - -#if CYGDEBUG - winTrace ("winPositionWindowRootless (%p)\n", pWin); -#endif + winDebug ("winPositionWindowRootless (%p)\n", pWin); WIN_UNWRAP(PositionWindow); fResult = (*pScreen->PositionWindow)(pWin, x, y); @@ -377,9 +345,7 @@ winChangeWindowAttributesRootless (WindowPtr pWin, unsigned long mask) ScreenPtr pScreen = pWin->drawable.pScreen; winScreenPriv(pScreen); -#if CYGDEBUG - winTrace ("winChangeWindowAttributesRootless (%p)\n", pWin); -#endif + winDebug ("winChangeWindowAttributesRootless (%p)\n", pWin); WIN_UNWRAP(ChangeWindowAttributes); fResult = (*pScreen->ChangeWindowAttributes)(pWin, mask); @@ -403,9 +369,7 @@ winUnmapWindowRootless (WindowPtr pWin) winWindowPriv(pWin); winScreenPriv(pScreen); -#if CYGDEBUG - winTrace ("winUnmapWindowRootless (%p)\n", pWin); -#endif + winDebug ("winUnmapWindowRootless (%p)\n", pWin); WIN_UNWRAP(UnrealizeWindow); fResult = (*pScreen->UnrealizeWindow)(pWin); @@ -434,9 +398,7 @@ winMapWindowRootless (WindowPtr pWin) ScreenPtr pScreen = pWin->drawable.pScreen; winScreenPriv(pScreen); -#if CYGDEBUG - winTrace ("winMapWindowRootless (%p)\n", pWin); -#endif + winDebug ("winMapWindowRootless (%p)\n", pWin); WIN_UNWRAP(RealizeWindow); fResult = (*pScreen->RealizeWindow)(pWin); @@ -456,9 +418,7 @@ winSetShapeRootless (WindowPtr pWin) ScreenPtr pScreen = pWin->drawable.pScreen; winScreenPriv(pScreen); -#if CYGDEBUG - winTrace ("winSetShapeRootless (%p)\n", pWin); -#endif + winDebug ("winSetShapeRootless (%p)\n", pWin); WIN_UNWRAP(SetShape); (*pScreen->SetShape)(pWin); @@ -487,9 +447,7 @@ winAddRgn (WindowPtr pWin, pointer data) /* If pWin is not Root */ if (pWin->parent != NULL) { -#if CYGDEBUG winDebug ("winAddRgn ()\n"); -#endif if (pWin->mapped) { iBorder = wBorderWidth (pWin); @@ -504,8 +462,8 @@ winAddRgn (WindowPtr pWin, pointer data) if (hRgnWin == NULL) { - ErrorF ("winAddRgn - CreateRectRgn () failed\n"); - ErrorF (" Rect %d %d %d %d\n", + winDebug ("winAddRgn - CreateRectRgn () failed\n"); + winDebug (" Rect %d %d %d %d\n", iX, iY, iX + iWidth, iY + iHeight); } @@ -570,9 +528,7 @@ winReshapeRootless (WindowPtr pWin) HRGN hRgn, hRgnRect; winWindowPriv(pWin); -#if CYGDEBUG winDebug ("winReshapeRootless ()\n"); -#endif /* Bail if the window is the root window */ if (pWin->parent == NULL) diff --git a/xorg-server/hw/xwin/winwindow.h b/xorg-server/hw/xwin/winwindow.h index cf2f93f0a..cbe483a93 100644 --- a/xorg-server/hw/xwin/winwindow.h +++ b/xorg-server/hw/xwin/winwindow.h @@ -41,29 +41,23 @@ /* Constant strings */ #ifndef PROJECT_NAME -# define PROJECT_NAME "Cygwin/X" +# define PROJECT_NAME "VcXsrv" #endif -#define EXECUTABLE_NAME "XWin" -#define WINDOW_CLASS "cygwin/x" -#define WINDOW_TITLE PROJECT_NAME ":%s.%d" -#define WINDOW_TITLE_XDMCP "%s:%s.%d" -#define WIN_SCR_PROP "cyg_screen_prop rl" -#define WINDOW_CLASS_X "cygwin/x X rl" +#define EXECUTABLE_NAME "VcXsrv" +#define WINDOW_CLASS "VcXsrv/x" +#define WINDOW_TITLE PROJECT_NAME " Server - %s:%s.%d" +#define WINDOW_TITLE_XDMCP PROJECT_NAME " Server - %s:%s.%d" +#define WIN_SCR_PROP "vcxsrv_screen_prop rl" +#define WINDOW_CLASS_X "vcxsrv/x X rl" #define WINDOW_TITLE_X PROJECT_NAME " X" -#define WIN_WINDOW_PROP "cyg_window_prop_rl" +#define WIN_WINDOW_PROP "vcxsrv_window_prop_rl" #ifdef HAS_DEVWINDOWS # define WIN_MSG_QUEUE_FNAME "/dev/windows" #endif -#define WIN_WID_PROP "cyg_wid_prop_rl" -#define WIN_NEEDMANAGE_PROP "cyg_override_redirect_prop_rl" -#ifndef CYGMULTIWINDOW_DEBUG -#define CYGMULTIWINDOW_DEBUG NO -#endif -#ifndef CYGWINDOWING_DEBUG -#define CYGWINDOWING_DEBUG NO -#endif +#define WIN_WID_PROP "vcxsrv_wid_prop_rl" +#define WIN_NEEDMANAGE_PROP "vcxsrv_override_redirect_prop_rl" -#define XMING_SIGNATURE 0x12345678L +#define VCXSRV_SIGNATURE 0xdeaddeadL typedef struct _winPrivScreenRec *winPrivScreenPtr; @@ -77,6 +71,8 @@ typedef struct DWORD dwDummy; HRGN hRgn; HWND hWnd; + BOOL GlCtxWnd; + BOOL PixelFormatSet; winPrivScreenPtr pScreenPriv; Bool fXKilled; diff --git a/xorg-server/hw/xwin/winwindowswm.c b/xorg-server/hw/xwin/winwindowswm.c index 34368246a..7b6cfbb37 100644 --- a/xorg-server/hw/xwin/winwindowswm.c +++ b/xorg-server/hw/xwin/winwindowswm.c @@ -1,655 +1,630 @@ -/* WindowsWM extension is based on AppleWM extension */ -/************************************************************************** - -Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved. -Copyright (c) 2003 Torrey T. Lyons. 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, sub license, 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 PRECISION INSIGHT AND/OR ITS 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. - -**************************************************************************/ - -#ifdef HAVE_XWIN_CONFIG_H -#include <xwin-config.h> -#endif -#include "win.h" - -#include "misc.h" -#include "dixstruct.h" -#include "extnsionst.h" -#include "colormapst.h" -#include "cursorstr.h" -#include "scrnintstr.h" -#include "servermd.h" -#include "swaprep.h" -#define _WINDOWSWM_SERVER_ -#include <X11/extensions/windowswmstr.h> -#include "protocol-versions.h" - -static int WMErrorBase; - -static DISPATCH_PROC(ProcWindowsWMDispatch); -static DISPATCH_PROC(SProcWindowsWMDispatch); - -static unsigned char WMReqCode = 0; -static int WMEventBase = 0; - -static RESTYPE ClientType, eventResourceType; /* resource types for event masks */ -static XID eventResource; - -/* Currently selected events */ -static unsigned int eventMask = 0; - -static int WMFreeClient (pointer data, XID id); -static int WMFreeEvents (pointer data, XID id); -static void SNotifyEvent(xWindowsWMNotifyEvent *from, xWindowsWMNotifyEvent *to); - -typedef struct _WMEvent *WMEventPtr; -typedef struct _WMEvent { - WMEventPtr next; - ClientPtr client; - XID clientResource; - unsigned int mask; -} WMEventRec; - -static inline BoxRec -make_box (int x, int y, int w, int h) -{ - BoxRec r; - r.x1 = x; - r.y1 = y; - r.x2 = x + w; - r.y2 = y + h; - return r; -} - -void -winWindowsWMExtensionInit () -{ - ExtensionEntry* extEntry; - - ClientType = CreateNewResourceType(WMFreeClient, "WMClient"); - eventResourceType = CreateNewResourceType(WMFreeEvents, "WMEvent"); - eventResource = FakeClientID(0); - - if (ClientType && eventResourceType && - (extEntry = AddExtension(WINDOWSWMNAME, - WindowsWMNumberEvents, - WindowsWMNumberErrors, - ProcWindowsWMDispatch, - SProcWindowsWMDispatch, - NULL, - StandardMinorOpcode))) - { - WMReqCode = (unsigned char)extEntry->base; - WMErrorBase = extEntry->errorBase; - WMEventBase = extEntry->eventBase; - EventSwapVector[WMEventBase] = (EventSwapPtr) SNotifyEvent; - } -} - -static int -ProcWindowsWMQueryVersion(register ClientPtr client) -{ - xWindowsWMQueryVersionReply rep; - register int n; - - REQUEST_SIZE_MATCH(xWindowsWMQueryVersionReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.majorVersion = SERVER_WINDOWSWM_MAJOR_VERSION; - rep.minorVersion = SERVER_WINDOWSWM_MINOR_VERSION; - rep.patchVersion = SERVER_WINDOWSWM_PATCH_VERSION; - if (client->swapped) - { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length, n); - } - WriteToClient(client, sizeof(xWindowsWMQueryVersionReply), (char *)&rep); - return (client->noClientException); -} - - -/* events */ - -static inline void -updateEventMask (WMEventPtr *pHead) -{ - WMEventPtr pCur; - - eventMask = 0; - for (pCur = *pHead; pCur != NULL; pCur = pCur->next) - eventMask |= pCur->mask; -} - -/*ARGSUSED*/ -static int -WMFreeClient (pointer data, XID id) -{ - WMEventPtr pEvent; - WMEventPtr *pHead, pCur, pPrev; - - pEvent = (WMEventPtr) data; - dixLookupResourceByType((pointer) &pHead, eventResource, eventResourceType, - NullClient, DixUnknownAccess); - if (pHead) - { - pPrev = 0; - for (pCur = *pHead; pCur && pCur != pEvent; pCur=pCur->next) - pPrev = pCur; - if (pCur) - { - if (pPrev) - pPrev->next = pEvent->next; - else - *pHead = pEvent->next; - } - updateEventMask (pHead); - } - xfree ((pointer) pEvent); - return 1; -} - -/*ARGSUSED*/ -static int -WMFreeEvents (pointer data, XID id) -{ - WMEventPtr *pHead, pCur, pNext; - - pHead = (WMEventPtr *) data; - for (pCur = *pHead; pCur; pCur = pNext) - { - pNext = pCur->next; - FreeResource (pCur->clientResource, ClientType); - xfree ((pointer) pCur); - } - xfree ((pointer) pHead); - eventMask = 0; - return 1; -} - -static int -ProcWindowsWMSelectInput (register ClientPtr client) -{ - REQUEST(xWindowsWMSelectInputReq); - WMEventPtr pEvent, pNewEvent, *pHead; - XID clientResource; - - REQUEST_SIZE_MATCH (xWindowsWMSelectInputReq); - dixLookupResourceByType((pointer) &pHead, eventResource, eventResourceType, client, DixWriteAccess); - if (stuff->mask != 0) - { - if (pHead) - { - /* check for existing entry. */ - for (pEvent = *pHead; pEvent; pEvent = pEvent->next) - { - if (pEvent->client == client) - { - pEvent->mask = stuff->mask; - updateEventMask (pHead); - return Success; - } - } - } - - /* build the entry */ - pNewEvent = (WMEventPtr) xalloc (sizeof (WMEventRec)); - if (!pNewEvent) - return BadAlloc; - pNewEvent->next = 0; - pNewEvent->client = client; - pNewEvent->mask = stuff->mask; - /* - * add a resource that will be deleted when - * the client goes away - */ - clientResource = FakeClientID (client->index); - pNewEvent->clientResource = clientResource; - if (!AddResource (clientResource, ClientType, (pointer)pNewEvent)) - return BadAlloc; - /* - * create a resource to contain a pointer to the list - * of clients selecting input. This must be indirect as - * the list may be arbitrarily rearranged which cannot be - * done through the resource database. - */ - if (!pHead) - { - pHead = (WMEventPtr *) xalloc (sizeof (WMEventPtr)); - if (!pHead || - !AddResource (eventResource, eventResourceType, (pointer)pHead)) - { - FreeResource (clientResource, RT_NONE); - return BadAlloc; - } - *pHead = 0; - } - pNewEvent->next = *pHead; - *pHead = pNewEvent; - updateEventMask (pHead); - } - else if (stuff->mask == 0) - { - /* delete the interest */ - if (pHead) - { - pNewEvent = 0; - for (pEvent = *pHead; pEvent; pEvent = pEvent->next) - { - if (pEvent->client == client) - break; - pNewEvent = pEvent; - } - if (pEvent) - { - FreeResource (pEvent->clientResource, ClientType); - if (pNewEvent) - pNewEvent->next = pEvent->next; - else - *pHead = pEvent->next; - xfree (pEvent); - updateEventMask (pHead); - } - } - } - else - { - client->errorValue = stuff->mask; - return BadValue; - } - return Success; -} - -/* - * deliver the event - */ - -void -winWindowsWMSendEvent (int type, unsigned int mask, int which, int arg, - Window window, int x, int y, int w, int h) -{ - WMEventPtr *pHead, pEvent; - ClientPtr client; - xWindowsWMNotifyEvent se; -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winWindowsWMSendEvent %d %d %d %d, %d %d - %d %d\n", - type, mask, which, arg, x, y, w, h); -#endif - dixLookupResourceByType((pointer) &pHead, eventResource, eventResourceType, - NullClient, DixUnknownAccess); - if (!pHead) - return; - for (pEvent = *pHead; pEvent; pEvent = pEvent->next) - { - client = pEvent->client; -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winWindowsWMSendEvent - x%08x\n", (int) client); -#endif - if ((pEvent->mask & mask) == 0 - || client == serverClient || client->clientGone) - { - continue; - } -#if CYGMULTIWINDOW_DEBUG - ErrorF ("winWindowsWMSendEvent - send\n"); -#endif - se.type = type + WMEventBase; - se.kind = which; - se.window = window; - se.arg = arg; - se.x = x; - se.y = y; - se.w = w; - se.h = h; - se.sequenceNumber = client->sequence; - se.time = currentTime.milliseconds; - WriteEventsToClient (client, 1, (xEvent *) &se); - } -} - -/* Safe to call from any thread. */ -unsigned int -WindowsWMSelectedEvents (void) -{ - return eventMask; -} - - -/* general utility functions */ - -static int -ProcWindowsWMDisableUpdate (register ClientPtr client) -{ - REQUEST_SIZE_MATCH(xWindowsWMDisableUpdateReq); - - //winDisableUpdate(); - - return (client->noClientException); -} - -static int -ProcWindowsWMReenableUpdate (register ClientPtr client) -{ - REQUEST_SIZE_MATCH(xWindowsWMReenableUpdateReq); - - //winEnableUpdate(); - - return (client->noClientException); -} - - -/* window functions */ - -static int -ProcWindowsWMSetFrontProcess (register ClientPtr client) -{ - REQUEST_SIZE_MATCH(xWindowsWMSetFrontProcessReq); - - //QuartzMessageMainThread(kWindowsSetFrontProcess, NULL, 0); - - return (client->noClientException); -} - - -/* frame functions */ - -static int -ProcWindowsWMFrameGetRect (register ClientPtr client) -{ - xWindowsWMFrameGetRectReply rep; - BoxRec ir; - RECT rcNew; - REQUEST(xWindowsWMFrameGetRectReq); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("ProcWindowsWMFrameGetRect %d %d\n", - (sizeof(xWindowsWMFrameGetRectReq) >> 2), (int) client->req_len); -#endif - - REQUEST_SIZE_MATCH(xWindowsWMFrameGetRectReq); - rep.type = X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - - ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih); - - if (stuff->frame_rect != 0) - { - ErrorF ("ProcWindowsWMFrameGetRect - stuff->frame_rect != 0\n"); - return BadValue; - } - - /* Store the origin, height, and width in a rectangle structure */ - SetRect (&rcNew, stuff->ix, stuff->iy, - stuff->ix + stuff->iw, stuff->iy + stuff->ih); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("ProcWindowsWMFrameGetRect - %d %d %d %d\n", - stuff->ix, stuff->iy, stuff->ix + stuff->iw, stuff->iy + stuff->ih); -#endif - - /* - * Calculate the required size of the Windows window rectangle, - * given the size of the Windows window client area. - */ - AdjustWindowRectEx (&rcNew, stuff->frame_style, FALSE, stuff->frame_style_ex); - rep.x = rcNew.left; - rep.y = rcNew.top; - rep.w = rcNew.right - rcNew.left; - rep.h = rcNew.bottom - rcNew.top; -#if CYGMULTIWINDOW_DEBUG - ErrorF ("ProcWindowsWMFrameGetRect - %d %d %d %d\n", - rep.x, rep.y, rep.w, rep.h); -#endif - - WriteToClient(client, sizeof(xWindowsWMFrameGetRectReply), (char *)&rep); - return (client->noClientException); -} - - -static int -ProcWindowsWMFrameDraw (register ClientPtr client) -{ - REQUEST(xWindowsWMFrameDrawReq); - WindowPtr pWin; - win32RootlessWindowPtr pRLWinPriv; - RECT rcNew; - int nCmdShow, rc; - RegionRec newShape; - ScreenPtr pScreen; - - REQUEST_SIZE_MATCH (xWindowsWMFrameDrawReq); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("ProcWindowsWMFrameDraw\n"); -#endif - rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); - if (rc != Success) - return rc; -#if CYGMULTIWINDOW_DEBUG - ErrorF ("ProcWindowsWMFrameDraw - Window found\n"); -#endif - - pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, TRUE); - if (pRLWinPriv == 0) return BadWindow; - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("ProcWindowsWMFrameDraw - HWND 0x%08x 0x%08x 0x%08x\n", - (int) pRLWinPriv->hWnd, (int) stuff->frame_style, - (int) stuff->frame_style_ex); - ErrorF ("ProcWindowsWMFrameDraw - %d %d %d %d\n", - stuff->ix, stuff->iy, stuff->iw, stuff->ih); -#endif - - /* Store the origin, height, and width in a rectangle structure */ - SetRect (&rcNew, stuff->ix, stuff->iy, - stuff->ix + stuff->iw, stuff->iy + stuff->ih); - - /* - * Calculate the required size of the Windows window rectangle, - * given the size of the Windows window client area. - */ - AdjustWindowRectEx (&rcNew, stuff->frame_style, FALSE, stuff->frame_style_ex); - - /* Set the window extended style flags */ - if (!SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, stuff->frame_style_ex)) - { - return BadValue; - } - - /* Set the window standard style flags */ - if (!SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, stuff->frame_style)) - { - return BadValue; - } - - /* Flush the window style */ - if (!SetWindowPos (pRLWinPriv->hWnd, NULL, - rcNew.left, rcNew.top, - rcNew.right - rcNew.left, rcNew.bottom - rcNew.top, - SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE)) - { - return BadValue; - } - if (!IsWindowVisible(pRLWinPriv->hWnd)) - nCmdShow = SW_HIDE; - else - nCmdShow = SW_SHOWNA; - - ShowWindow (pRLWinPriv->hWnd, nCmdShow); - - winMWExtWMUpdateIcon (pWin->drawable.id); - - if (wBoundingShape(pWin) != NULL) - { - pScreen = pWin->drawable.pScreen; - /* wBoundingShape is relative to *inner* origin of window. - Translate by borderWidth to get the outside-relative position. */ - - REGION_NULL(pScreen, &newShape); - REGION_COPY(pScreen, &newShape, wBoundingShape(pWin)); - REGION_TRANSLATE(pScreen, &newShape, pWin->borderWidth, pWin->borderWidth); - winMWExtWMReshapeFrame (pRLWinPriv, &newShape); - REGION_UNINIT(pScreen, &newShape); - } -#if CYGMULTIWINDOW_DEBUG - ErrorF ("ProcWindowsWMFrameDraw - done\n"); -#endif - - return (client->noClientException); -} - -static int -ProcWindowsWMFrameSetTitle( - register ClientPtr client - ) -{ - unsigned int title_length, title_max; - unsigned char *title_bytes; - REQUEST(xWindowsWMFrameSetTitleReq); - WindowPtr pWin; - win32RootlessWindowPtr pRLWinPriv; - int rc; - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("ProcWindowsWMFrameSetTitle\n"); -#endif - - REQUEST_AT_LEAST_SIZE(xWindowsWMFrameSetTitleReq); - - rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess); - if (rc != Success) - return rc; -#if CYGMULTIWINDOW_DEBUG - ErrorF ("ProcWindowsWMFrameSetTitle - Window found\n"); -#endif - - title_length = stuff->title_length; - title_max = (stuff->length << 2) - sizeof(xWindowsWMFrameSetTitleReq); - - if (title_max < title_length) - return BadValue; - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("ProcWindowsWMFrameSetTitle - length is valid\n"); -#endif - - title_bytes = malloc (title_length+1); - strncpy (title_bytes, (unsigned char *) &stuff[1], title_length); - title_bytes[title_length] = '\0'; - - pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE); - - if (pRLWinPriv == 0) - { - free (title_bytes); - return BadWindow; - } - - /* Flush the window style */ - SetWindowText (pRLWinPriv->hWnd, title_bytes); - - free (title_bytes); - -#if CYGMULTIWINDOW_DEBUG - ErrorF ("ProcWindowsWMFrameSetTitle - done\n"); -#endif - - return (client->noClientException); -} - - -/* dispatch */ - -static int -ProcWindowsWMDispatch (register ClientPtr client) -{ - REQUEST(xReq); - - switch (stuff->data) - { - case X_WindowsWMQueryVersion: - return ProcWindowsWMQueryVersion(client); - } - - if (!LocalClient(client)) - return WMErrorBase + WindowsWMClientNotLocal; - - switch (stuff->data) - { - case X_WindowsWMSelectInput: - return ProcWindowsWMSelectInput(client); - case X_WindowsWMDisableUpdate: - return ProcWindowsWMDisableUpdate(client); - case X_WindowsWMReenableUpdate: - return ProcWindowsWMReenableUpdate(client); - case X_WindowsWMSetFrontProcess: - return ProcWindowsWMSetFrontProcess(client); - case X_WindowsWMFrameGetRect: - return ProcWindowsWMFrameGetRect(client); - case X_WindowsWMFrameDraw: - return ProcWindowsWMFrameDraw(client); - case X_WindowsWMFrameSetTitle: - return ProcWindowsWMFrameSetTitle(client); - default: - return BadRequest; - } -} - -static void -SNotifyEvent (xWindowsWMNotifyEvent *from, xWindowsWMNotifyEvent *to) -{ - to->type = from->type; - to->kind = from->kind; - cpswaps (from->sequenceNumber, to->sequenceNumber); - cpswapl (from->window, to->window); - cpswapl (from->time, to->time); - cpswapl (from->arg, to->arg); -} - -static int -SProcWindowsWMQueryVersion (register ClientPtr client) -{ - register int n; - REQUEST(xWindowsWMQueryVersionReq); - swaps(&stuff->length, n); - return ProcWindowsWMQueryVersion(client); -} - -static int -SProcWindowsWMDispatch (register ClientPtr client) -{ - REQUEST(xReq); - - /* It is bound to be non-local when there is byte swapping */ - if (!LocalClient(client)) - return WMErrorBase + WindowsWMClientNotLocal; - - /* only local clients are allowed WM access */ - switch (stuff->data) - { - case X_WindowsWMQueryVersion: - return SProcWindowsWMQueryVersion(client); - default: - return BadRequest; - } -} +/* WindowsWM extension is based on AppleWM extension */
+/**************************************************************************
+
+Copyright (c) 2002 Apple Computer, Inc. All Rights Reserved.
+Copyright (c) 2003 Torrey T. Lyons. 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, sub license, 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 PRECISION INSIGHT AND/OR ITS 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.
+
+**************************************************************************/
+
+#ifdef HAVE_XWIN_CONFIG_H
+#include <xwin-config.h>
+#endif
+#include "win.h"
+
+#include "misc.h"
+#include "dixstruct.h"
+#include "extnsionst.h"
+#include "colormapst.h"
+#include "cursorstr.h"
+#include "scrnintstr.h"
+#include "servermd.h"
+#include "swaprep.h"
+#define _WINDOWSWM_SERVER_
+#include <X11/extensions/windowswmstr.h>
+#include "protocol-versions.h"
+
+static int WMErrorBase;
+
+static DISPATCH_PROC(ProcWindowsWMDispatch);
+static DISPATCH_PROC(SProcWindowsWMDispatch);
+
+static unsigned char WMReqCode = 0;
+static int WMEventBase = 0;
+
+static RESTYPE ClientType, eventResourceType; /* resource types for event masks */
+static XID eventResource;
+
+/* Currently selected events */
+static unsigned int eventMask = 0;
+
+static int WMFreeClient (pointer data, XID id);
+static int WMFreeEvents (pointer data, XID id);
+static void SNotifyEvent(xWindowsWMNotifyEvent *from, xWindowsWMNotifyEvent *to);
+
+typedef struct _WMEvent *WMEventPtr;
+typedef struct _WMEvent {
+ WMEventPtr next;
+ ClientPtr client;
+ XID clientResource;
+ unsigned int mask;
+} WMEventRec;
+
+static inline BoxRec
+make_box (int x, int y, int w, int h)
+{
+ BoxRec r;
+ r.x1 = x;
+ r.y1 = y;
+ r.x2 = x + w;
+ r.y2 = y + h;
+ return r;
+}
+
+void
+winWindowsWMExtensionInit ()
+{
+ ExtensionEntry* extEntry;
+
+ ClientType = CreateNewResourceType(WMFreeClient, "WMClient");
+ eventResourceType = CreateNewResourceType(WMFreeEvents, "WMEvent");
+ eventResource = FakeClientID(0);
+
+ if (ClientType && eventResourceType &&
+ (extEntry = AddExtension(WINDOWSWMNAME,
+ WindowsWMNumberEvents,
+ WindowsWMNumberErrors,
+ ProcWindowsWMDispatch,
+ SProcWindowsWMDispatch,
+ NULL,
+ StandardMinorOpcode)))
+ {
+ WMReqCode = (unsigned char)extEntry->base;
+ WMErrorBase = extEntry->errorBase;
+ WMEventBase = extEntry->eventBase;
+ EventSwapVector[WMEventBase] = (EventSwapPtr) SNotifyEvent;
+ }
+}
+
+static int
+ProcWindowsWMQueryVersion(register ClientPtr client)
+{
+ xWindowsWMQueryVersionReply rep;
+ register int n;
+
+ REQUEST_SIZE_MATCH(xWindowsWMQueryVersionReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.majorVersion = SERVER_WINDOWSWM_MAJOR_VERSION;
+ rep.minorVersion = SERVER_WINDOWSWM_MINOR_VERSION;
+ rep.patchVersion = SERVER_WINDOWSWM_PATCH_VERSION;
+ if (client->swapped)
+ {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length, n);
+ }
+ WriteToClient(client, sizeof(xWindowsWMQueryVersionReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+
+/* events */
+
+static inline void
+updateEventMask (WMEventPtr *pHead)
+{
+ WMEventPtr pCur;
+
+ eventMask = 0;
+ for (pCur = *pHead; pCur != NULL; pCur = pCur->next)
+ eventMask |= pCur->mask;
+}
+
+/*ARGSUSED*/
+static int
+WMFreeClient (pointer data, XID id)
+{
+ WMEventPtr pEvent;
+ WMEventPtr *pHead, pCur, pPrev;
+
+ pEvent = (WMEventPtr) data;
+ dixLookupResourceByType((pointer) &pHead, eventResource, eventResourceType,
+ NullClient, DixUnknownAccess);
+ if (pHead)
+ {
+ pPrev = 0;
+ for (pCur = *pHead; pCur && pCur != pEvent; pCur=pCur->next)
+ pPrev = pCur;
+ if (pCur)
+ {
+ if (pPrev)
+ pPrev->next = pEvent->next;
+ else
+ *pHead = pEvent->next;
+ }
+ updateEventMask (pHead);
+ }
+ xfree ((pointer) pEvent);
+ return 1;
+}
+
+/*ARGSUSED*/
+static int
+WMFreeEvents (pointer data, XID id)
+{
+ WMEventPtr *pHead, pCur, pNext;
+
+ pHead = (WMEventPtr *) data;
+ for (pCur = *pHead; pCur; pCur = pNext)
+ {
+ pNext = pCur->next;
+ FreeResource (pCur->clientResource, ClientType);
+ xfree ((pointer) pCur);
+ }
+ xfree ((pointer) pHead);
+ eventMask = 0;
+ return 1;
+}
+
+static int
+ProcWindowsWMSelectInput (register ClientPtr client)
+{
+ REQUEST(xWindowsWMSelectInputReq);
+ WMEventPtr pEvent, pNewEvent, *pHead;
+ XID clientResource;
+
+ REQUEST_SIZE_MATCH (xWindowsWMSelectInputReq);
+ dixLookupResourceByType((pointer) &pHead, eventResource, eventResourceType, client, DixWriteAccess);
+ if (stuff->mask != 0)
+ {
+ if (pHead)
+ {
+ /* check for existing entry. */
+ for (pEvent = *pHead; pEvent; pEvent = pEvent->next)
+ {
+ if (pEvent->client == client)
+ {
+ pEvent->mask = stuff->mask;
+ updateEventMask (pHead);
+ return Success;
+ }
+ }
+ }
+
+ /* build the entry */
+ pNewEvent = (WMEventPtr) xalloc (sizeof (WMEventRec));
+ if (!pNewEvent)
+ return BadAlloc;
+ pNewEvent->next = 0;
+ pNewEvent->client = client;
+ pNewEvent->mask = stuff->mask;
+ /*
+ * add a resource that will be deleted when
+ * the client goes away
+ */
+ clientResource = FakeClientID (client->index);
+ pNewEvent->clientResource = clientResource;
+ if (!AddResource (clientResource, ClientType, (pointer)pNewEvent))
+ return BadAlloc;
+ /*
+ * create a resource to contain a pointer to the list
+ * of clients selecting input. This must be indirect as
+ * the list may be arbitrarily rearranged which cannot be
+ * done through the resource database.
+ */
+ if (!pHead)
+ {
+ pHead = (WMEventPtr *) xalloc (sizeof (WMEventPtr));
+ if (!pHead ||
+ !AddResource (eventResource, eventResourceType, (pointer)pHead))
+ {
+ FreeResource (clientResource, RT_NONE);
+ return BadAlloc;
+ }
+ *pHead = 0;
+ }
+ pNewEvent->next = *pHead;
+ *pHead = pNewEvent;
+ updateEventMask (pHead);
+ }
+ else if (stuff->mask == 0)
+ {
+ /* delete the interest */
+ if (pHead)
+ {
+ pNewEvent = 0;
+ for (pEvent = *pHead; pEvent; pEvent = pEvent->next)
+ {
+ if (pEvent->client == client)
+ break;
+ pNewEvent = pEvent;
+ }
+ if (pEvent)
+ {
+ FreeResource (pEvent->clientResource, ClientType);
+ if (pNewEvent)
+ pNewEvent->next = pEvent->next;
+ else
+ *pHead = pEvent->next;
+ xfree (pEvent);
+ updateEventMask (pHead);
+ }
+ }
+ }
+ else
+ {
+ client->errorValue = stuff->mask;
+ return BadValue;
+ }
+ return Success;
+}
+
+/*
+ * deliver the event
+ */
+
+void
+winWindowsWMSendEvent (int type, unsigned int mask, int which, int arg,
+ Window window, int x, int y, int w, int h)
+{
+ WMEventPtr *pHead, pEvent;
+ ClientPtr client;
+ xWindowsWMNotifyEvent se;
+ winDebug ("winWindowsWMSendEvent %d %d %d %d, %d %d - %d %d\n",
+ type, mask, which, arg, x, y, w, h);
+ dixLookupResourceByType((pointer) &pHead, eventResource, eventResourceType,
+ NullClient, DixUnknownAccess);
+ if (!pHead)
+ return;
+ for (pEvent = *pHead; pEvent; pEvent = pEvent->next)
+ {
+ client = pEvent->client;
+ winDebug ("winWindowsWMSendEvent - x%08x\n", (int) client);
+ if ((pEvent->mask & mask) == 0
+ || client == serverClient || client->clientGone)
+ {
+ continue;
+ }
+ winDebug ("winWindowsWMSendEvent - send\n");
+
+ se.type = type + WMEventBase;
+ se.kind = which;
+ se.window = window;
+ se.arg = arg;
+ se.x = x;
+ se.y = y;
+ se.w = w;
+ se.h = h;
+ se.sequenceNumber = client->sequence;
+ se.time = currentTime.milliseconds;
+ WriteEventsToClient (client, 1, (xEvent *) &se);
+ }
+}
+
+/* Safe to call from any thread. */
+unsigned int
+WindowsWMSelectedEvents (void)
+{
+ return eventMask;
+}
+
+
+/* general utility functions */
+
+static int
+ProcWindowsWMDisableUpdate (register ClientPtr client)
+{
+ REQUEST_SIZE_MATCH(xWindowsWMDisableUpdateReq);
+
+ //winDisableUpdate();
+
+ return (client->noClientException);
+}
+
+static int
+ProcWindowsWMReenableUpdate (register ClientPtr client)
+{
+ REQUEST_SIZE_MATCH(xWindowsWMReenableUpdateReq);
+
+ //winEnableUpdate();
+
+ return (client->noClientException);
+}
+
+
+/* window functions */
+
+static int
+ProcWindowsWMSetFrontProcess (register ClientPtr client)
+{
+ REQUEST_SIZE_MATCH(xWindowsWMSetFrontProcessReq);
+
+ //QuartzMessageMainThread(kWindowsSetFrontProcess, NULL, 0);
+
+ return (client->noClientException);
+}
+
+
+/* frame functions */
+
+static int
+ProcWindowsWMFrameGetRect (register ClientPtr client)
+{
+ xWindowsWMFrameGetRectReply rep;
+ BoxRec ir;
+ RECT rcNew;
+ REQUEST(xWindowsWMFrameGetRectReq);
+
+ winDebug ("ProcWindowsWMFrameGetRect %d %d\n",
+ (sizeof(xWindowsWMFrameGetRectReq) >> 2), (int) client->req_len);
+
+ REQUEST_SIZE_MATCH(xWindowsWMFrameGetRectReq);
+ rep.type = X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+
+ ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih);
+
+ if (stuff->frame_rect != 0)
+ {
+ ErrorF ("ProcWindowsWMFrameGetRect - stuff->frame_rect != 0\n");
+ return BadValue;
+ }
+
+ /* Store the origin, height, and width in a rectangle structure */
+ SetRect (&rcNew, stuff->ix, stuff->iy,
+ stuff->ix + stuff->iw, stuff->iy + stuff->ih);
+
+ winDebug ("ProcWindowsWMFrameGetRect - %d %d %d %d\n",
+ stuff->ix, stuff->iy, stuff->ix + stuff->iw, stuff->iy + stuff->ih);
+
+ /*
+ * Calculate the required size of the Windows window rectangle,
+ * given the size of the Windows window client area.
+ */
+ AdjustWindowRectEx (&rcNew, stuff->frame_style, FALSE, stuff->frame_style_ex);
+ rep.x = rcNew.left;
+ rep.y = rcNew.top;
+ rep.w = rcNew.right - rcNew.left;
+ rep.h = rcNew.bottom - rcNew.top;
+ winDebug ("ProcWindowsWMFrameGetRect - %d %d %d %d\n",
+ rep.x, rep.y, rep.w, rep.h);
+
+ WriteToClient(client, sizeof(xWindowsWMFrameGetRectReply), (char *)&rep);
+ return (client->noClientException);
+}
+
+
+static int
+ProcWindowsWMFrameDraw (register ClientPtr client)
+{
+ REQUEST(xWindowsWMFrameDrawReq);
+ WindowPtr pWin;
+ win32RootlessWindowPtr pRLWinPriv;
+ RECT rcNew;
+ int nCmdShow, rc;
+ RegionRec newShape;
+ ScreenPtr pScreen;
+
+ REQUEST_SIZE_MATCH (xWindowsWMFrameDrawReq);
+
+ winDebug ("ProcWindowsWMFrameDraw\n");
+
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
+ if (rc != Success)
+ return rc;
+
+ winDebug ("ProcWindowsWMFrameDraw - Window found\n");
+
+ pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, TRUE);
+ if (pRLWinPriv == 0) return BadWindow;
+
+ winDebug ("ProcWindowsWMFrameDraw - HWND 0x%08x 0x%08x 0x%08x\n",
+ (int) pRLWinPriv->hWnd, (int) stuff->frame_style,
+ (int) stuff->frame_style_ex);
+ winDebug ("ProcWindowsWMFrameDraw - %d %d %d %d\n",
+ stuff->ix, stuff->iy, stuff->iw, stuff->ih);
+
+ /* Store the origin, height, and width in a rectangle structure */
+ SetRect (&rcNew, stuff->ix, stuff->iy,
+ stuff->ix + stuff->iw, stuff->iy + stuff->ih);
+
+ /*
+ * Calculate the required size of the Windows window rectangle,
+ * given the size of the Windows window client area.
+ */
+ AdjustWindowRectEx (&rcNew, stuff->frame_style, FALSE, stuff->frame_style_ex);
+
+ /* Set the window extended style flags */
+ if (!SetWindowLongPtr (pRLWinPriv->hWnd, GWL_EXSTYLE, stuff->frame_style_ex))
+ {
+ return BadValue;
+ }
+
+ /* Set the window standard style flags */
+ if (!SetWindowLongPtr (pRLWinPriv->hWnd, GWL_STYLE, stuff->frame_style))
+ {
+ return BadValue;
+ }
+
+ /* Flush the window style */
+ if (!SetWindowPos (pRLWinPriv->hWnd, NULL,
+ rcNew.left, rcNew.top,
+ rcNew.right - rcNew.left, rcNew.bottom - rcNew.top,
+ SWP_NOZORDER | SWP_FRAMECHANGED | SWP_NOACTIVATE))
+ {
+ return BadValue;
+ }
+ if (!IsWindowVisible(pRLWinPriv->hWnd))
+ nCmdShow = SW_HIDE;
+ else
+ nCmdShow = SW_SHOWNA;
+
+ ShowWindow (pRLWinPriv->hWnd, nCmdShow);
+
+ winMWExtWMUpdateIcon (pWin->drawable.id);
+
+ if (wBoundingShape(pWin) != NULL)
+ {
+ pScreen = pWin->drawable.pScreen;
+ /* wBoundingShape is relative to *inner* origin of window.
+ Translate by borderWidth to get the outside-relative position. */
+
+ REGION_NULL(pScreen, &newShape);
+ REGION_COPY(pScreen, &newShape, wBoundingShape(pWin));
+ REGION_TRANSLATE(pScreen, &newShape, pWin->borderWidth, pWin->borderWidth);
+ winMWExtWMReshapeFrame (pRLWinPriv, &newShape);
+ REGION_UNINIT(pScreen, &newShape);
+ }
+ winDebug ("ProcWindowsWMFrameDraw - done\n");
+
+ return (client->noClientException);
+}
+
+static int
+ProcWindowsWMFrameSetTitle(
+ register ClientPtr client
+ )
+{
+ unsigned int title_length, title_max;
+ unsigned char *title_bytes;
+ REQUEST(xWindowsWMFrameSetTitleReq);
+ WindowPtr pWin;
+ win32RootlessWindowPtr pRLWinPriv;
+ int rc;
+
+ winDebug ("ProcWindowsWMFrameSetTitle\n");
+
+ REQUEST_AT_LEAST_SIZE(xWindowsWMFrameSetTitleReq);
+
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixReadAccess);
+ if (rc != Success)
+ return rc;
+ winDebug ("ProcWindowsWMFrameSetTitle - Window found\n");
+
+ title_length = stuff->title_length;
+ title_max = (stuff->length << 2) - sizeof(xWindowsWMFrameSetTitleReq);
+
+ if (title_max < title_length)
+ return BadValue;
+
+ winDebug ("ProcWindowsWMFrameSetTitle - length is valid\n");
+
+ title_bytes = malloc (title_length+1);
+ strncpy (title_bytes, (unsigned char *) &stuff[1], title_length);
+ title_bytes[title_length] = '\0';
+
+ pRLWinPriv = (win32RootlessWindowPtr) RootlessFrameForWindow (pWin, FALSE);
+
+ if (pRLWinPriv == 0)
+ {
+ free (title_bytes);
+ return BadWindow;
+ }
+
+ /* Flush the window style */
+ SetWindowText (pRLWinPriv->hWnd, title_bytes);
+
+ free (title_bytes);
+
+ winDebug ("ProcWindowsWMFrameSetTitle - done\n");
+
+ return (client->noClientException);
+}
+
+
+/* dispatch */
+
+static int
+ProcWindowsWMDispatch (register ClientPtr client)
+{
+ REQUEST(xReq);
+
+ switch (stuff->data)
+ {
+ case X_WindowsWMQueryVersion:
+ return ProcWindowsWMQueryVersion(client);
+ }
+
+ if (!LocalClient(client))
+ return WMErrorBase + WindowsWMClientNotLocal;
+
+ switch (stuff->data)
+ {
+ case X_WindowsWMSelectInput:
+ return ProcWindowsWMSelectInput(client);
+ case X_WindowsWMDisableUpdate:
+ return ProcWindowsWMDisableUpdate(client);
+ case X_WindowsWMReenableUpdate:
+ return ProcWindowsWMReenableUpdate(client);
+ case X_WindowsWMSetFrontProcess:
+ return ProcWindowsWMSetFrontProcess(client);
+ case X_WindowsWMFrameGetRect:
+ return ProcWindowsWMFrameGetRect(client);
+ case X_WindowsWMFrameDraw:
+ return ProcWindowsWMFrameDraw(client);
+ case X_WindowsWMFrameSetTitle:
+ return ProcWindowsWMFrameSetTitle(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static void
+SNotifyEvent (xWindowsWMNotifyEvent *from, xWindowsWMNotifyEvent *to)
+{
+ to->type = from->type;
+ to->kind = from->kind;
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswapl (from->window, to->window);
+ cpswapl (from->time, to->time);
+ cpswapl (from->arg, to->arg);
+}
+
+static int
+SProcWindowsWMQueryVersion (register ClientPtr client)
+{
+ register int n;
+ REQUEST(xWindowsWMQueryVersionReq);
+ swaps(&stuff->length, n);
+ return ProcWindowsWMQueryVersion(client);
+}
+
+static int
+SProcWindowsWMDispatch (register ClientPtr client)
+{
+ REQUEST(xReq);
+
+ /* It is bound to be non-local when there is byte swapping */
+ if (!LocalClient(client))
+ return WMErrorBase + WindowsWMClientNotLocal;
+
+ /* only local clients are allowed WM access */
+ switch (stuff->data)
+ {
+ case X_WindowsWMQueryVersion:
+ return SProcWindowsWMQueryVersion(client);
+ default:
+ return BadRequest;
+ }
+}
diff --git a/xorg-server/hw/xwin/winwndproc.c b/xorg-server/hw/xwin/winwndproc.c index 5e8451082..73ca16bc5 100644 --- a/xorg-server/hw/xwin/winwndproc.c +++ b/xorg-server/hw/xwin/winwndproc.c @@ -42,6 +42,10 @@ #include "winmsg.h" #include "inputstr.h" +#ifndef XKB_IN_SERVER +#define XKB_IN_SERVER +#endif +#include <xkbsrv.h> /* * Global variables */ @@ -82,9 +86,7 @@ winWindowProc (HWND hwnd, UINT message, int iScanCode; int i; -#if CYGDEBUG winDebugWin32Message("winWindowProc", hwnd, message, wParam, lParam); -#endif /* Watch for server regeneration */ if (g_ulServerGeneration != s_ulServerGeneration) @@ -97,9 +99,7 @@ winWindowProc (HWND hwnd, UINT message, if ((s_pScreenPriv == NULL || hwnd != s_hwndLastPrivates) && (s_pScreenPriv = GetProp (hwnd, WIN_SCR_PROP)) != NULL) { -#if CYGDEBUG winDebug ("winWindowProc - Setting privates handle\n"); -#endif s_pScreenInfo = s_pScreenPriv->pScreenInfo; s_pScreen = s_pScreenInfo->pScreen; s_hwndLastPrivates = hwnd; @@ -120,9 +120,7 @@ winWindowProc (HWND hwnd, UINT message, s_pScreenPriv); case WM_CREATE: -#if CYGDEBUG winDebug ("winWindowProc - WM_CREATE\n"); -#endif /* * Add a property to our display window that references @@ -155,7 +153,7 @@ winWindowProc (HWND hwnd, UINT message, s_pScreenPriv->hwndScreen = hwnd; - winInitNotifyIcon (s_pScreenPriv); + winInitNotifyIcon (s_pScreenPriv,FALSE); } return 0; @@ -191,13 +189,13 @@ winWindowProc (HWND hwnd, UINT message, break; } - ErrorF ("winWindowProc - WM_DISPLAYCHANGE - orig bpp: %d, last bpp: %d, " + winDebug ("winWindowProc - WM_DISPLAYCHANGE - orig bpp: %d, last bpp: %d, " "new bpp: %d\n", (int) s_pScreenInfo->dwBPP, (int) s_pScreenPriv->dwLastWindowsBitsPixel, wParam); - ErrorF ("winWindowProc - WM_DISPLAYCHANGE - new width: %d " + winDebug ("winWindowProc - WM_DISPLAYCHANGE - new width: %d " "new height: %d\n", LOWORD (lParam), HIWORD (lParam)); @@ -237,7 +235,7 @@ winWindowProc (HWND hwnd, UINT message, )) { /* Cannot display the visual until the depth is restored */ - ErrorF ("winWindowProc - Disruptive change in depth\n"); + winDebug ("winWindowProc - Disruptive change in depth\n"); /* Display Exit dialog */ winDisplayDepthChangeDialog (s_pScreenPriv); @@ -270,25 +268,19 @@ winWindowProc (HWND hwnd, UINT message, * relevant to the current engine (e.g., Shadow GDI). */ -#if CYGDEBUG winDebug ("winWindowProc - WM_DISPLAYCHANGE - Dimensions changed\n"); -#endif /* Release the old primary surface */ (*s_pScreenPriv->pwinReleasePrimarySurface) (s_pScreen); -#if CYGDEBUG winDebug ("winWindowProc - WM_DISPLAYCHANGE - Released " "primary surface\n"); -#endif /* Create the new primary surface */ (*s_pScreenPriv->pwinCreatePrimarySurface) (s_pScreen); -#if CYGDEBUG winDebug ("winWindowProc - WM_DISPLAYCHANGE - Recreated " "primary surface\n"); -#endif #if 0 /* Multi-Window mode uses RandR for resizes */ @@ -300,10 +292,8 @@ winWindowProc (HWND hwnd, UINT message, } else { -#if CYGDEBUG winDebug ("winWindowProc - WM_DISPLAYCHANGE - Dimensions did not " "change\n"); -#endif } /* Store the new display dimensions and depth */ @@ -331,9 +321,7 @@ winWindowProc (HWND hwnd, UINT message, RECT rcWindow; int iWidth, iHeight; -#if CYGDEBUG winDebug ("winWindowProc - WM_SIZE\n"); -#endif /* Break if we do not use scrollbars */ if (!s_pScreenInfo->fScrollbars @@ -369,7 +357,7 @@ winWindowProc (HWND hwnd, UINT message, iWidth = rcWindow.right - rcWindow.left; iHeight = rcWindow.bottom - rcWindow.top; - ErrorF ("winWindowProc - WM_SIZE - window w: %d h: %d, " + winDebug ("winWindowProc - WM_SIZE - window w: %d h: %d, " "new client area w: %d h: %d\n", iWidth, iHeight, LOWORD (lParam), HIWORD (lParam)); @@ -433,9 +421,7 @@ winWindowProc (HWND hwnd, UINT message, SCROLLINFO si; int iVertPos; -#if CYGDEBUG winDebug ("winWindowProc - WM_VSCROLL\n"); -#endif /* Get vertical scroll bar info */ si.cbSize = sizeof (si); @@ -518,9 +504,7 @@ winWindowProc (HWND hwnd, UINT message, SCROLLINFO si; int iHorzPos; -#if CYGDEBUG winDebug ("winWindowProc - WM_HSCROLL\n"); -#endif /* Get horizontal scroll bar info */ si.cbSize = sizeof (si); @@ -604,10 +588,8 @@ winWindowProc (HWND hwnd, UINT message, int iCaptionHeight; int iBorderHeight, iBorderWidth; -#if CYGDEBUG winDebug ("winWindowProc - WM_GETMINMAXINFO - pScreenInfo: %08x\n", s_pScreenInfo); -#endif /* Can't do anything without screen info */ if (s_pScreenInfo == NULL @@ -650,9 +632,7 @@ winWindowProc (HWND hwnd, UINT message, return 0; case WM_ERASEBKGND: -#if CYGDEBUG winDebug ("winWindowProc - WM_ERASEBKGND\n"); -#endif /* * Pretend that we did erase the background but we don't care, * the application uses the full window estate. This avoids some @@ -661,9 +641,7 @@ winWindowProc (HWND hwnd, UINT message, return TRUE; case WM_PAINT: -#if CYGDEBUG winDebug ("winWindowProc - WM_PAINT\n"); -#endif /* Only paint if we have privates and the server is enabled */ if (s_pScreenPriv == NULL || !s_pScreenPriv->fEnabled @@ -684,9 +662,7 @@ winWindowProc (HWND hwnd, UINT message, case WM_PALETTECHANGED: { -#if CYGDEBUG winDebug ("winWindowProc - WM_PALETTECHANGED\n"); -#endif /* * Don't process if we don't have privates or a colormap, * or if we have an invalid depth. @@ -954,9 +930,7 @@ winWindowProc (HWND hwnd, UINT message, case WM_MOUSEWHEEL: if (s_pScreenPriv == NULL || s_pScreenInfo->fIgnoreInput) break; -#if CYGDEBUG winDebug ("winWindowProc - WM_MOUSEWHEEL\n"); -#endif winMouseWheel (s_pScreen, GET_WHEEL_DELTA_WPARAM(wParam)); break; @@ -1014,7 +988,7 @@ winWindowProc (HWND hwnd, UINT message, * user enters Alt + F4 and is surprised when the application * quits. */ - ErrorF ("winWindowProc - WM_*KEYDOWN - Closekey hit, quitting\n"); + winDebug ("winWindowProc - WM_*KEYDOWN - Closekey hit, quitting\n"); /* Display Exit dialog */ winDisplayExitDialog (s_pScreenPriv); @@ -1107,7 +1081,7 @@ winWindowProc (HWND hwnd, UINT message, /* TODO: Override display of window when we have a bad depth */ if (LOWORD(wParam) != WA_INACTIVE && s_pScreenPriv->fBadDepth) { - ErrorF ("winWindowProc - WM_ACTIVATE - Bad depth, trying " + winDebug ("winWindowProc - WM_ACTIVATE - Bad depth, trying " "to override window activation\n"); /* Minimize the window */ @@ -1129,9 +1103,7 @@ winWindowProc (HWND hwnd, UINT message, return 0; } -#if CYGDEBUG winDebug ("winWindowProc - WM_ACTIVATE\n"); -#endif /* * Focus is being changed to another window. @@ -1157,9 +1129,7 @@ winWindowProc (HWND hwnd, UINT message, || s_pScreenInfo->fIgnoreInput) break; -#if CYGDEBUG || TRUE winDebug ("winWindowProc - WM_ACTIVATEAPP\n"); -#endif /* Activate or deactivate */ s_pScreenPriv->fActive = wParam; @@ -1247,7 +1217,7 @@ winWindowProc (HWND hwnd, UINT message, #ifdef XWIN_MULTIWINDOWEXTWM case WM_MANAGE: - ErrorF ("winWindowProc - WM_MANAGE\n"); + winDebug ("winWindowProc - WM_MANAGE\n"); s_pScreenInfo->fAnotherWMRunning = FALSE; if (s_pScreenInfo->fInternalWM) @@ -1258,7 +1228,7 @@ winWindowProc (HWND hwnd, UINT message, break; case WM_UNMANAGE: - ErrorF ("winWindowProc - WM_UNMANAGE\n"); + winDebug ("winWindowProc - WM_UNMANAGE\n"); s_pScreenInfo->fAnotherWMRunning = TRUE; if (s_pScreenInfo->fInternalWM) @@ -1272,7 +1242,7 @@ winWindowProc (HWND hwnd, UINT message, default: if(message == s_uTaskbarRestart) { - winInitNotifyIcon (s_pScreenPriv); + winInitNotifyIcon (s_pScreenPriv,FALSE); } break; } diff --git a/xorg-server/hw/xwin/xlaunch/Makefile b/xorg-server/hw/xwin/xlaunch/Makefile deleted file mode 100644 index f7cf923df..000000000 --- a/xorg-server/hw/xwin/xlaunch/Makefile +++ /dev/null @@ -1,79 +0,0 @@ -# -# Copyright (c) 2005 Alexander Gottwald -# -# 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 ABOVE LISTED COPYRIGHT HOLDER(S) 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(s) of the above copyright -# holders shall not be used in advertising or otherwise to promote the sale, -# use or other dealings in this Software without prior written authorization. -# -WINDRES=windres - -TARGET=mingw -#DEBUG_FLAGS=-D_DEBUG - -OS_FLAGS_mingw=-mno-cygwin -OS_FLAGS=$(OS_FLAGS_$(TARGET)) $(DEBUG_FLAGS) - -X11_DIR_$(TARGET)=/usr/X11R6 -X11_DIR_mingw=../../../../../exports -X11_DIR=$(X11_DIR_$(TARGET)) -X11_INCLUDE=-I$(X11_DIR)/include -X11_LIBDIR=-L$(X11_DIR)/lib -X11_LIBS_$(TARGET)=-lX11 -X11_LIBS_mingw=-lX11 -lwsock32 -X11_LIBS=$(X11_LIBS_$(TARGET)) - -PROGRAMFILES:=$(shell cygpath -u $(PROGRAMFILES)) -#MSXML_DIR=$(PROGRAMFILES)/MSXML 4.0 -MSXML_DIR=$(PROGRAMFILES)/Microsoft XML Parser SDK -MSXML_INCLUDE="-I$(MSXML_DIR)/inc" -MSXML_LIBDIR="-L$(MSXML_DIR)/lib" -MSXML_LIBS= - - -CXXFLAGS=-g $(OS_FLAGS) $(X11_INCLUDE) $(MSXML_INCLUDE) -LDFLAGS=-mwindows $(X11_LIBDIR) $(MSXML_LIBDIR) -LIBS=-lcomctl32 -lole32 -loleaut32 $(X11_LIBS) $(MSXML_LIBS) -all:xlaunch.exe -%.res: %.rc - $(WINDRES) -O coff -o $@ $< - -WINDOW_PARTS=window util dialog wizard -WINDOW_OBJECTS=$(foreach file,$(WINDOW_PARTS),window/$(file).o) - -RESOURCES_IMAGES=resources/multiwindow.bmp resources/fullscreen.bmp \ - resources/windowed.bmp resources/nodecoration.bmp - -resources/resources.res: resources/resources.rc resources/resources.h \ - resources/images.rc resources/dialog.rc resources/strings.rc \ - $(RESOURCES_IMAGES) -xlaunch.exe: $(WINDOW_OBJECTS) main.o config.o resources/resources.res - $(CXX) $(CXXFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS) - - -window/dialog.o: window/dialog.cc window/dialog.h window/window.h window/util.h -window/frame.o: window/frame.cc window/frame.h window/window.h -window/util.o: window/util.cc window/util.h -window/window.o: window/window.cc window/window.h window/util.h -window/wizard.o: window/wizard.cc window/wizard.h window/dialog.h \ - window/window.h window/util.h -main.o: main.cc window/util.h window/wizard.h window/dialog.h \ - window/window.h resources/resources.h config.h -config.o: config.cc config.h diff --git a/xorg-server/hw/xwin/xlaunch/config.h b/xorg-server/hw/xwin/xlaunch/config.h index f0aed3cf1..8017ffb55 100644 --- a/xorg-server/hw/xwin/xlaunch/config.h +++ b/xorg-server/hw/xwin/xlaunch/config.h @@ -22,39 +22,60 @@ * Except as contained in this notice, the name(s) of the above copyright * holders shall not be used in advertising or otherwise to promote the sale, * use or other dealings in this Software without prior written authorization. + * + * Authors: Alexander Gottwald, Colin Harrison */ #ifndef __CONFIG_H__ #define __CONFIG_H__ +#define UNICODE +#define _UNICODE + +#define PROG_NUMBER 10 +#define HOST_NUMBER 10 +#define MAX_MESSAGE 256 +#define MAX_CAPTION 128 +#include <windows.h> #include <string> +#include <vector> struct CConfig { enum {MultiWindow, Fullscreen, Windowed, Nodecoration} window; enum {NoClient, StartProgram, XDMCP} client; + enum {NoXClient, Local, PuTTY, OpenSSH} clientstart; bool local; std::string display; std::string protocol; + std::string protocol_path; std::string program; + std::vector<std::string> progs; + bool compress; std::string host; std::string user; + std::string password; + bool password_save; + bool password_start; bool broadcast; bool indirect; std::string xdmcp_host; + std::vector<std::string> xhosts; bool clipboard; + bool no_access_control; + std::string font_server; std::string extra_params; + std::string extra_ssh; #ifdef _DEBUG - CConfig() : window(MultiWindow), client(StartProgram), local(false), display("1"), - protocol("Putty"), program("xterm"), host("lupus"), user("ago"), - broadcast(false), indirect(false), xdmcp_host("lupus"), - clipboard(true), extra_params() {}; + CConfig() : window(MultiWindow), client(NoClient), clientstart(NoXClient), display("1"), #else - CConfig() : window(MultiWindow), client(StartProgram), local(false), display("0"), - protocol("Putty"), program("xterm"), host(""), user(""), - broadcast(true), indirect(false), xdmcp_host(""), - clipboard(true), extra_params() {}; + CConfig() : window(MultiWindow), client(NoClient), clientstart(NoXClient), display("0"), #endif - void Load(const char* filename); - void Save(const char* filename); + local(false), protocol(""), + protocol_path(""), program("xeyes"), progs(PROG_NUMBER), compress(false), host(""), user("ago"), + password(""), password_save(false), password_start(false), broadcast(false), + indirect(false), xdmcp_host(""), xhosts(HOST_NUMBER), clipboard(true), no_access_control(false), + font_server(), extra_params(), extra_ssh() {}; + void Load(const char * filename); + void Save(const char * filename); }; #endif diff --git a/xorg-server/hw/xwin/xlaunch/main.cc b/xorg-server/hw/xwin/xlaunch/main.cc index 2247d3aaf..ad84f6a10 100644 --- a/xorg-server/hw/xwin/xlaunch/main.cc +++ b/xorg-server/hw/xwin/xlaunch/main.cc @@ -34,6 +34,9 @@ #include <X11/Xlib.h> +#ifdef _MSC_VER +#define snprintf _snprintf +#endif /// @brief Send WM_ENDSESSION to all program windows. /// This will shutdown the started xserver BOOL CALLBACK KillWindowsProc(HWND hwnd, LPARAM lParam) @@ -69,7 +72,9 @@ class CMyWizard : public CWizard config.Load(filename); } catch (std::runtime_error &e) { - printf("Fehler: %s\n", e.what()); + char Message[255]; + sprintf(Message,"Failure: %s\n", e.what()); + MessageBox(NULL,Message,"Exception",MB_OK); } } @@ -108,7 +113,10 @@ class CMyWizard : public CWizard } // Check for valid input if (config.display.empty()) + { + MessageBox(hwndDlg,"Please fill in a display number.","Error",MB_OK); SetWindowLong(hwndDlg, DWL_MSGRESULT, -1); + } else SetWindowLong(hwndDlg, DWL_MSGRESULT, IDD_CLIENTS); return TRUE; @@ -354,7 +362,9 @@ class CMyWizard : public CWizard config.Save(ofn.lpstrFile); } catch (std::runtime_error &e) { - printf("Fehler: %s\n", e.what()); + char Message[255]; + sprintf(Message,"Failure: %s\n", e.what()); + MessageBox(NULL,Message,"Exception",MB_OK); } } } @@ -489,7 +499,7 @@ class CMyWizard : public CWizard return NULL; } - /// @brief Do the actual start of Xming and clients + /// @brief Do the actual start of VCXsrv and clients void StartUp() { std::string buffer; @@ -499,13 +509,8 @@ class CMyWizard : public CWizard std::string display_id = ":" + config.display; std::string display = "localhost" + display_id + ":0"; -#ifdef _DEBUG - // Debug only: Switch to Xming installation directory - SetCurrentDirectory("C:\\Programme\\Xming"); -#endif - - // Build Xming commandline - buffer = "Xming " + display_id + " "; + // Build Xsrv commandline + buffer = "vcxsrv " + display_id + " "; switch (config.window) { case CConfig::MultiWindow: @@ -577,7 +582,7 @@ class CMyWizard : public CWizard sic.cb = sizeof(sic); ZeroMemory( &pic, sizeof(pic) ); - // Start Xming process. + // Start VCXsrv process. #ifdef _DEBUG printf("%s\n", buffer.c_str()); #endif @@ -627,7 +632,7 @@ class CMyWizard : public CWizard #ifdef _DEBUG printf("killing process!\n"); #endif - // Check if Xming is still running + // Check if Xsrv is still running DWORD exitcode; GetExitCodeProcess(pi.hProcess, &exitcode); unsigned counter = 0; @@ -636,7 +641,7 @@ class CMyWizard : public CWizard if (++counter > 10) TerminateProcess(pi.hProcess, (DWORD)-1); else - // Shutdown Xming (the soft way!) + // Shutdown Xsrv (the soft way!) EnumThreadWindows(pi.dwThreadId, KillWindowsProc, 0); Sleep(500); GetExitCodeProcess(pi.hProcess, &exitcode); @@ -690,7 +695,9 @@ int main(int argc, char **argv) return 0; } catch (std::runtime_error &e) { - printf("Fehler: %s\n", e.what()); + char Message[255]; + sprintf(Message,"Failure: %s\n", e.what()); + MessageBox(NULL,Message,"Exception",MB_OK); return -1; } } diff --git a/xorg-server/hw/xwin/xlaunch/makefile b/xorg-server/hw/xwin/xlaunch/makefile new file mode 100644 index 000000000..63b37dd1b --- /dev/null +++ b/xorg-server/hw/xwin/xlaunch/makefile @@ -0,0 +1,32 @@ +INCLUDELIBFILES = window\$(OBJDIR)\window.lib \
+ $(MHMAKECONF)\libx11\src\$(OBJDIR)\libx11.lib \
+ $(MHMAKECONF)\libxcb\src\$(OBJDIR)\libxcb.lib \
+ $(MHMAKECONF)\libxau\$(OBJDIR)\libxau.lib \
+ $(MHMAKECONF)\libx11\src\xlibi18n\$(OBJDIR)\libi18n.lib \
+ $(MHMAKECONF)\libx11\modules\lc\xlocale\$(OBJDIR)\libxlocale.lib \
+ $(MHMAKECONF)\libx11\modules\lc\utf8\$(OBJDIR)\libxlcUTF8Load.lib \
+ $(MHMAKECONF)\libx11\modules\lc\gen\$(OBJDIR)\liblcGenConvLoad.lib \
+ $(MHMAKECONF)\libx11\modules\lc\def\$(OBJDIR)\libxlcDef.lib \
+ $(MHMAKECONF)\libx11\src\xkb\$(OBJDIR)\libxkb.lib \
+ $(MHMAKECONF)\libx11\modules\im\ximcp\$(OBJDIR)\libximcp.lib \
+ $(MHMAKECONF)\libx11\modules\om\generic\$(OBJDIR)\libxomGeneric.lib
+
+CSRCS=config.cc main.cc
+
+WINAPP = xlaunch
+
+RESOURCES = resources.rc
+
+$(OBJDIR)\%.res : resources\%.rc
+ $(RC) $(RCFLAGS) $(RCDEFINES:%=-d "%") $(RCINCLUDES:%=-i %) -Fo$(relpath $@) $<
+
+LIBDIRS=$(dir $(INCLUDELIBFILES))
+
+load_makefile $(LIBDIRS:%$(OBJDIR)\=%makefile MAKESERVER=$(MAKESERVER) DEBUG=$(DEBUG);)
+
+ifeq ($(DEBUG),1)
+LINKLIBS += $(MHMAKECONF)\pthreads\pthreadVC2d.lib
+else
+LINKLIBS += $(MHMAKECONF)\pthreads\pthreadVC2.lib
+endif
+
diff --git a/xorg-server/hw/xwin/xlaunch/resources/dialog.rc b/xorg-server/hw/xwin/xlaunch/resources/dialog.rc index 8b00df4ef..f029c8a17 100644 --- a/xorg-server/hw/xwin/xlaunch/resources/dialog.rc +++ b/xorg-server/hw/xwin/xlaunch/resources/dialog.rc @@ -104,7 +104,7 @@ BEGIN LTEXT STR_CLIPBOARD_DESC,IDC_CLIPBOARD_DESC,19,28,280,27 LTEXT STR_EXTRA_PARAMS_DESC,IDC_EXTRA_PARAMS_DESC,7,56,280,10 - EDITTEXT IDC_EXTRA_PARAMS,7,70,128,12 + EDITTEXT IDC_EXTRA_PARAMS,7,70,300,12, WS_BORDER | WS_TABSTOP | ES_AUTOHSCROLL END IDD_FINISH DIALOGEX 0, 0, 317, 143 diff --git a/xorg-server/hw/xwin/xlaunch/resources/resources.h b/xorg-server/hw/xwin/xlaunch/resources/resources.h index 470005192..15e733844 100644 --- a/xorg-server/hw/xwin/xlaunch/resources/resources.h +++ b/xorg-server/hw/xwin/xlaunch/resources/resources.h @@ -35,6 +35,8 @@ #define IDD_FONTPATH 106
#define IDD_CLIPBOARD 107
+#define IDI_XLAUNCH 108
+
#define IDS_DISPLAY_TITLE 300
#define IDS_DISPLAY_SUBTITLE 301
#define IDS_CLIENTS_TITLE 302
diff --git a/xorg-server/hw/xwin/xlaunch/resources/resources.rc b/xorg-server/hw/xwin/xlaunch/resources/resources.rc index 07fd52f32..e3df4610a 100644 --- a/xorg-server/hw/xwin/xlaunch/resources/resources.rc +++ b/xorg-server/hw/xwin/xlaunch/resources/resources.rc @@ -28,3 +28,5 @@ #include "resources.h" #include "images.rc" #include "dialog.rc" + +IDI_XLAUNCH ICON "..\\..\\X.ico" diff --git a/xorg-server/hw/xwin/xlaunch/resources/strings.rc b/xorg-server/hw/xwin/xlaunch/resources/strings.rc index 5a9cd281b..94db96659 100644 --- a/xorg-server/hw/xwin/xlaunch/resources/strings.rc +++ b/xorg-server/hw/xwin/xlaunch/resources/strings.rc @@ -60,15 +60,15 @@ #define STR_CAPTION_CLIPBOARD "Clipboard settings" #define STR_CLIPBOARD "Clipboard" #define STR_CLIPBOARD_DESC "Start the integrated clipboard manager" -#define STR_EXTRA_PARAMS_DESC "Additional parameters for Xming" +#define STR_EXTRA_PARAMS_DESC "Additional parameters for VcXsrv" #define STR_CAPTION_FINISH "Finish configuration" -#define STR_FINISH_DESC "Configuration is complete. Clish Finish to start Xming." +#define STR_FINISH_DESC "Configuration is complete. Clish Finish to start VcXsrv." #define STR_FINISH_SAVE_DESC "You may also save the configuration for later use." #define STR_FINISH_SAVE "Save configuration" #define STR_DISPLAY_TITLE "Select display settings" -#define STR_DISPLAY_SUBTITLE "Choose how Xming display programs" +#define STR_DISPLAY_SUBTITLE "Choose how VcXsrv display programs" #define STR_CLIENTS_TITLE "Select how to start clients" #define STR_CLIENTS_SUBTITLE "" #define STR_PROGRAM_TITLE "Specify the program to start" diff --git a/xorg-server/hw/xwin/xlaunch/window/makefile b/xorg-server/hw/xwin/xlaunch/window/makefile new file mode 100644 index 000000000..18a33e728 --- /dev/null +++ b/xorg-server/hw/xwin/xlaunch/window/makefile @@ -0,0 +1,4 @@ +CSRCS=dialog.cc util.cc window.cc wizard.cc
+
+LIBRARY = window
+
diff --git a/xorg-server/hw/xwin/xlaunch/window/util.cc b/xorg-server/hw/xwin/xlaunch/window/util.cc index fb7e87297..6f768348e 100644 --- a/xorg-server/hw/xwin/xlaunch/window/util.cc +++ b/xorg-server/hw/xwin/xlaunch/window/util.cc @@ -25,6 +25,8 @@ */ #include "util.h" +const char * MessageDebug::notify_names[NOTIFY_NAMES_LEN]; + std::string win32_error::message(DWORD errorcode) { LPVOID lpMsgBuf; diff --git a/xorg-server/hw/xwin/xlaunch/window/util.h b/xorg-server/hw/xwin/xlaunch/window/util.h index cd21da657..a1196b115 100644 --- a/xorg-server/hw/xwin/xlaunch/window/util.h +++ b/xorg-server/hw/xwin/xlaunch/window/util.h @@ -28,7 +28,7 @@ #include <windows.h> #include <stdexcept> - +#include <string> class win32_error : public std::runtime_error { @@ -39,7 +39,7 @@ class win32_error : public std::runtime_error }; #define MESSAGE_NAMES_LEN 1024 -#define NOTIFY_NAMES_LEN 0 +#define NOTIFY_NAMES_LEN 1 class MessageDebug { protected: diff --git a/xorg-server/hw/xwin/xlaunch/window/wizard.h b/xorg-server/hw/xwin/xlaunch/window/wizard.h index a2361c51c..c576cc093 100644 --- a/xorg-server/hw/xwin/xlaunch/window/wizard.h +++ b/xorg-server/hw/xwin/xlaunch/window/wizard.h @@ -29,7 +29,6 @@ #include "dialog.h"
#include <vector>
-#define _WIN32_IE 0x0500
#include <prsht.h>
class CWizard : public CBaseDialog
diff --git a/xorg-server/include/dixstruct.h b/xorg-server/include/dixstruct.h index 696b793ff..acfbe46ca 100644 --- a/xorg-server/include/dixstruct.h +++ b/xorg-server/include/dixstruct.h @@ -94,7 +94,7 @@ typedef struct _Client { Bool swapped; ReplySwapPtr pSwapReplyFunc; XID errorValue; - int sequence; + unsigned short sequence; //MH int closeDownMode; int clientGone; int noClientException; /* this client died or needs to be diff --git a/xorg-server/include/eventstr.h b/xorg-server/include/eventstr.h index 79685c1a6..6a3410c19 100644 --- a/xorg-server/include/eventstr.h +++ b/xorg-server/include/eventstr.h @@ -1,246 +1,246 @@ -/* - * Copyright © 2009 Red Hat, Inc. - * - * 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. - * - */ - -#ifndef EVENTSTR_H -#define EVENTSTR_H - -#include <events.h> -/** - * @file events.h - * This file describes the event structures used internally by the X - * server during event generation and event processing. - * - * When are internal events used? - * Events from input devices are stored as internal events in the EQ and - * processed as internal events until late in the processing cycle. Only then - * do they switch to their respective wire events. - */ - -/** - * Event types. Used exclusively internal to the server, not visible on the - * protocol. - * - * Note: Keep KeyPress to Motion aligned with the core events. - * Keep ET_Raw* in the same order as KeyPress - Motion - */ -enum EventType { - ET_KeyPress = 2, - ET_KeyRelease, - ET_ButtonPress, - ET_ButtonRelease, - ET_Motion, - ET_Enter, - ET_Leave, - ET_FocusIn, - ET_FocusOut, - ET_ProximityIn, - ET_ProximityOut, - ET_DeviceChanged, - ET_Hierarchy, - ET_DGAEvent, - ET_RawKeyPress, - ET_RawKeyRelease, - ET_RawButtonPress, - ET_RawButtonRelease, - ET_RawMotion, - ET_XQuartz, - ET_Internal = 0xFF /* First byte */ -}; - -#define CHECKEVENT(ev) if (ev && ((InternalEvent*)(ev))->any.header != 0xFF) \ - FatalError("Wrong event type %d.\n", \ - ((InternalEvent*)(ev))->any.header); - -/** - * Used for ALL input device events internal in the server until - * copied into the matching protocol event. - * - * Note: We only use the device id because the DeviceIntPtr may become invalid while - * the event is in the EQ. - */ -struct _DeviceEvent -{ - unsigned char header; /**< Always ET_Internal */ - enum EventType type; /**< One of EventType */ - int length; /**< Length in bytes */ - Time time; /**< Time in ms */ - int deviceid; /**< Device to post this event for */ - int sourceid; /**< The physical source device */ - union { - uint32_t button; /**< Button number */ - uint32_t key; /**< Key code */ - } detail; - uint16_t root_x; /**< Pos relative to root window in integral data */ - float root_x_frac; /**< Pos relative to root window in frac part */ - uint16_t root_y; /**< Pos relative to root window in integral part */ - float root_y_frac; /**< Pos relative to root window in frac part */ - uint8_t buttons[(MAX_BUTTONS + 7)/8]; /**< Button mask */ - struct { - uint8_t mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */ - uint8_t mode[(MAX_VALUATORS + 7)/8]; /**< Valuator mode (Abs or Rel)*/ - uint32_t data[MAX_VALUATORS]; /**< Valuator data */ - int32_t data_frac[MAX_VALUATORS]; /**< Fractional part for data */ - } valuators; - struct { - uint32_t base; /**< XKB base modifiers */ - uint32_t latched; /**< XKB latched modifiers */ - uint32_t locked; /**< XKB locked modifiers */ - uint32_t effective;/**< XKB effective modifiers */ - } mods; - struct { - uint8_t base; /**< XKB base group */ - uint8_t latched; /**< XKB latched group */ - uint8_t locked; /**< XKB locked group */ - uint8_t effective;/**< XKB effective group */ - } group; - Window root; /**< Root window of the event */ - int corestate; /**< Core key/button state BEFORE the event */ - int key_repeat; /**< Internally-generated key repeat event */ -}; - - -/* Flags used in DeviceChangedEvent to signal if the slave has changed */ -#define DEVCHANGE_SLAVE_SWITCH 0x2 -/* Flags used in DeviceChangedEvent to signal whether the event was a - * pointer event or a keyboard event */ -#define DEVCHANGE_POINTER_EVENT 0x4 -#define DEVCHANGE_KEYBOARD_EVENT 0x8 -/* device capabilities changed */ -#define DEVCHANGE_DEVICE_CHANGE 0x10 - -/** - * Sent whenever a device's capabilities have changed. - */ -struct _DeviceChangedEvent -{ - unsigned char header; /**< Always ET_Internal */ - enum EventType type; /**< ET_DeviceChanged */ - int length; /**< Length in bytes */ - Time time; /**< Time in ms */ - int deviceid; /**< Device whose capabilities have changed */ - int flags; /**< Mask of ::HAS_NEW_SLAVE, - ::POINTER_EVENT, ::KEYBOARD_EVENT */ - int masterid; /**< MD when event was generated */ - int sourceid; /**< The device that caused the change */ - - struct { - int num_buttons; /**< Number of buttons */ - Atom names[MAX_BUTTONS];/**< Button names */ - } buttons; - - int num_valuators; /**< Number of axes */ - struct { - uint32_t min; /**< Minimum value */ - uint32_t max; /**< Maximum value */ - /* FIXME: frac parts of min/max */ - uint32_t resolution; /**< Resolution counts/m */ - uint8_t mode; /**< Relative or Absolute */ - Atom name; /**< Axis name */ - } valuators[MAX_VALUATORS]; - - struct { - int min_keycode; - int max_keycode; - } keys; -}; - -#if XFreeXDGA -/** - * DGAEvent, used by DGA to intercept and emulate input events. - */ -struct _DGAEvent -{ - unsigned char header; /**< Always ET_Internal */ - enum EventType type; /**< ET_DGAEvent */ - int length; /**< Length in bytes */ - Time time; /**< Time in ms */ - int subtype; /**< KeyPress, KeyRelease, ButtonPress, - ButtonRelease, MotionNotify */ - int detail; /**< Relative x coordinate */ - int dx; /**< Relative x coordinate */ - int dy; /**< Relative y coordinate */ - int screen; /**< Screen number this event applies to */ - uint16_t state; /**< Core modifier/button state */ -}; -#endif - -/** - * Raw event, contains the data as posted by the device. - */ -struct _RawDeviceEvent -{ - unsigned char header; /**< Always ET_Internal */ - enum EventType type; /**< ET_Raw */ - int length; /**< Length in bytes */ - Time time; /**< Time in ms */ - int deviceid; /**< Device to post this event for */ - int sourceid; /**< The physical source device */ - union { - uint32_t button; /**< Button number */ - uint32_t key; /**< Key code */ - } detail; - struct { - uint8_t mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */ - int32_t data[MAX_VALUATORS]; /**< Valuator data */ - int32_t data_frac[MAX_VALUATORS]; /**< Fractional part for data */ - int32_t data_raw[MAX_VALUATORS]; /**< Valuator data as posted */ - int32_t data_raw_frac[MAX_VALUATORS];/**< Fractional part for data_raw */ - } valuators; -}; - -#ifdef XQUARTZ -#define XQUARTZ_EVENT_MAXARGS 5 -struct _XQuartzEvent { - unsigned char header; /**< Always ET_Internal */ - enum EventType type; /**< Always ET_XQuartz */ - int length; /**< Length in bytes */ - Time time; /**< Time in ms. */ - int subtype; /**< Subtype defined by XQuartz DDX */ - uint32_t data[XQUARTZ_EVENT_MAXARGS]; /**< Up to 5 32bit values passed to handler */ -}; -#endif - -/** - * Event type used inside the X server for input event - * processing. - */ -union _InternalEvent { - struct { - unsigned char header; /**< Always ET_Internal */ - enum EventType type; /**< One of ET_* */ - int length; /**< Length in bytes */ - Time time; /**< Time in ms. */ - } any; - DeviceEvent device_event; - DeviceChangedEvent changed_event; -#if XFreeXDGA - DGAEvent dga_event; -#endif - RawDeviceEvent raw_event; -#ifdef XQUARTZ - XQuartzEvent xquartz_event; -#endif -}; - -#endif +/*
+ * Copyright © 2009 Red Hat, Inc.
+ *
+ * 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.
+ *
+ */
+
+#ifndef EVENTSTR_H
+#define EVENTSTR_H
+
+#include <events.h>
+/**
+ * @file events.h
+ * This file describes the event structures used internally by the X
+ * server during event generation and event processing.
+ *
+ * When are internal events used?
+ * Events from input devices are stored as internal events in the EQ and
+ * processed as internal events until late in the processing cycle. Only then
+ * do they switch to their respective wire events.
+ */
+
+/**
+ * Event types. Used exclusively internal to the server, not visible on the
+ * protocol.
+ *
+ * Note: Keep KeyPress to Motion aligned with the core events.
+ * Keep ET_Raw* in the same order as KeyPress - Motion
+ */
+enum EventType {
+ ET_KeyPress = 2,
+ ET_KeyRelease,
+ ET_ButtonPress,
+ ET_ButtonRelease,
+ ET_Motion,
+ ET_Enter,
+ ET_Leave,
+ ET_FocusIn,
+ ET_FocusOut,
+ ET_ProximityIn,
+ ET_ProximityOut,
+ ET_DeviceChanged,
+ ET_Hierarchy,
+ ET_DGAEvent,
+ ET_RawKeyPress,
+ ET_RawKeyRelease,
+ ET_RawButtonPress,
+ ET_RawButtonRelease,
+ ET_RawMotion,
+ ET_XQuartz,
+ ET_Internal = 0xFF /* First byte */
+};
+
+#define CHECKEVENT(ev) if (ev && ((InternalEvent*)(ev))->any.header != 0xFF) \
+ FatalError("Wrong event type %d.\n", \
+ ((InternalEvent*)(ev))->any.header);
+
+/**
+ * Used for ALL input device events internal in the server until
+ * copied into the matching protocol event.
+ *
+ * Note: We only use the device id because the DeviceIntPtr may become invalid while
+ * the event is in the EQ.
+ */
+struct _DeviceEvent
+{
+ unsigned char header; /**< Always ET_Internal */
+ enum EventType type; /**< One of EventType */
+ int length; /**< Length in bytes */
+ Time time; /**< Time in ms */
+ int deviceid; /**< Device to post this event for */
+ int sourceid; /**< The physical source device */
+ union {
+ uint32_t button; /**< Button number */
+ uint32_t key; /**< Key code */
+ } detail;
+ int16_t root_x; /**< Pos relative to root window in integral data */
+ float root_x_frac; /**< Pos relative to root window in frac part */
+ int16_t root_y; /**< Pos relative to root window in integral part */
+ float root_y_frac; /**< Pos relative to root window in frac part */
+ uint8_t buttons[(MAX_BUTTONS + 7)/8]; /**< Button mask */
+ struct {
+ uint8_t mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */
+ uint8_t mode[(MAX_VALUATORS + 7)/8]; /**< Valuator mode (Abs or Rel)*/
+ int32_t data[MAX_VALUATORS]; /**< Valuator data */
+ int32_t data_frac[MAX_VALUATORS]; /**< Fractional part for data */
+ } valuators;
+ struct {
+ uint32_t base; /**< XKB base modifiers */
+ uint32_t latched; /**< XKB latched modifiers */
+ uint32_t locked; /**< XKB locked modifiers */
+ uint32_t effective;/**< XKB effective modifiers */
+ } mods;
+ struct {
+ uint8_t base; /**< XKB base group */
+ uint8_t latched; /**< XKB latched group */
+ uint8_t locked; /**< XKB locked group */
+ uint8_t effective;/**< XKB effective group */
+ } group;
+ Window root; /**< Root window of the event */
+ int corestate; /**< Core key/button state BEFORE the event */
+ int key_repeat; /**< Internally-generated key repeat event */
+};
+
+
+/* Flags used in DeviceChangedEvent to signal if the slave has changed */
+#define DEVCHANGE_SLAVE_SWITCH 0x2
+/* Flags used in DeviceChangedEvent to signal whether the event was a
+ * pointer event or a keyboard event */
+#define DEVCHANGE_POINTER_EVENT 0x4
+#define DEVCHANGE_KEYBOARD_EVENT 0x8
+/* device capabilities changed */
+#define DEVCHANGE_DEVICE_CHANGE 0x10
+
+/**
+ * Sent whenever a device's capabilities have changed.
+ */
+struct _DeviceChangedEvent
+{
+ unsigned char header; /**< Always ET_Internal */
+ enum EventType type; /**< ET_DeviceChanged */
+ int length; /**< Length in bytes */
+ Time time; /**< Time in ms */
+ int deviceid; /**< Device whose capabilities have changed */
+ int flags; /**< Mask of ::HAS_NEW_SLAVE,
+ ::POINTER_EVENT, ::KEYBOARD_EVENT */
+ int masterid; /**< MD when event was generated */
+ int sourceid; /**< The device that caused the change */
+
+ struct {
+ int num_buttons; /**< Number of buttons */
+ Atom names[MAX_BUTTONS];/**< Button names */
+ } buttons;
+
+ int num_valuators; /**< Number of axes */
+ struct {
+ uint32_t min; /**< Minimum value */
+ uint32_t max; /**< Maximum value */
+ /* FIXME: frac parts of min/max */
+ uint32_t resolution; /**< Resolution counts/m */
+ uint8_t mode; /**< Relative or Absolute */
+ Atom name; /**< Axis name */
+ } valuators[MAX_VALUATORS];
+
+ struct {
+ int min_keycode;
+ int max_keycode;
+ } keys;
+};
+
+#if XFreeXDGA
+/**
+ * DGAEvent, used by DGA to intercept and emulate input events.
+ */
+struct _DGAEvent
+{
+ unsigned char header; /**< Always ET_Internal */
+ enum EventType type; /**< ET_DGAEvent */
+ int length; /**< Length in bytes */
+ Time time; /**< Time in ms */
+ int subtype; /**< KeyPress, KeyRelease, ButtonPress,
+ ButtonRelease, MotionNotify */
+ int detail; /**< Relative x coordinate */
+ int dx; /**< Relative x coordinate */
+ int dy; /**< Relative y coordinate */
+ int screen; /**< Screen number this event applies to */
+ uint16_t state; /**< Core modifier/button state */
+};
+#endif
+
+/**
+ * Raw event, contains the data as posted by the device.
+ */
+struct _RawDeviceEvent
+{
+ unsigned char header; /**< Always ET_Internal */
+ enum EventType type; /**< ET_Raw */
+ int length; /**< Length in bytes */
+ Time time; /**< Time in ms */
+ int deviceid; /**< Device to post this event for */
+ int sourceid; /**< The physical source device */
+ union {
+ uint32_t button; /**< Button number */
+ uint32_t key; /**< Key code */
+ } detail;
+ struct {
+ uint8_t mask[(MAX_VALUATORS + 7)/8]; /**< Valuator mask */
+ int32_t data[MAX_VALUATORS]; /**< Valuator data */
+ int32_t data_frac[MAX_VALUATORS]; /**< Fractional part for data */
+ int32_t data_raw[MAX_VALUATORS]; /**< Valuator data as posted */
+ int32_t data_raw_frac[MAX_VALUATORS];/**< Fractional part for data_raw */
+ } valuators;
+};
+
+#ifdef XQUARTZ
+#define XQUARTZ_EVENT_MAXARGS 5
+struct _XQuartzEvent {
+ unsigned char header; /**< Always ET_Internal */
+ enum EventType type; /**< Always ET_XQuartz */
+ int length; /**< Length in bytes */
+ Time time; /**< Time in ms. */
+ int subtype; /**< Subtype defined by XQuartz DDX */
+ uint32_t data[XQUARTZ_EVENT_MAXARGS]; /**< Up to 5 32bit values passed to handler */
+};
+#endif
+
+/**
+ * Event type used inside the X server for input event
+ * processing.
+ */
+union _InternalEvent {
+ struct {
+ unsigned char header; /**< Always ET_Internal */
+ enum EventType type; /**< One of ET_* */
+ int length; /**< Length in bytes */
+ Time time; /**< Time in ms. */
+ } any;
+ DeviceEvent device_event;
+ DeviceChangedEvent changed_event;
+#if XFreeXDGA
+ DGAEvent dga_event;
+#endif
+ RawDeviceEvent raw_event;
+#ifdef XQUARTZ
+ XQuartzEvent xquartz_event;
+#endif
+};
+
+#endif
diff --git a/xorg-server/include/globals.h b/xorg-server/include/globals.h index 52c19a490..6aadb8bdf 100644 --- a/xorg-server/include/globals.h +++ b/xorg-server/include/globals.h @@ -41,9 +41,7 @@ extern _X_EXPORT Bool DPMSCapableFlag; extern _X_EXPORT Bool PanoramiXExtensionDisabledHack; #endif -#ifdef COMPOSITE extern _X_EXPORT Bool noCompositeExtension; -#endif #ifdef DAMAGE extern _X_EXPORT Bool noDamageExtension; diff --git a/xorg-server/include/input.h b/xorg-server/include/input.h index 8561308b3..36de5044d 100644 --- a/xorg-server/include/input.h +++ b/xorg-server/include/input.h @@ -1,548 +1,548 @@ -/************************************************************ - -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. - -********************************************************/ - -#ifndef INPUT_H -#define INPUT_H - -#include "misc.h" -#include "screenint.h" -#include <X11/Xmd.h> -#include <X11/Xproto.h> -#include <stdint.h> -#include "window.h" /* for WindowPtr */ -#include "xkbrules.h" -#include "events.h" - -#define DEVICE_INIT 0 -#define DEVICE_ON 1 -#define DEVICE_OFF 2 -#define DEVICE_CLOSE 3 - -#define POINTER_RELATIVE (1 << 1) -#define POINTER_ABSOLUTE (1 << 2) -#define POINTER_ACCELERATE (1 << 3) -#define POINTER_SCREEN (1 << 4) /* Data in screen coordinates */ - -/*int constants for pointer acceleration schemes*/ -#define PtrAccelNoOp 0 -#define PtrAccelPredictable 1 -#define PtrAccelLightweight 2 -#define PtrAccelDefault PtrAccelPredictable - -#define MAX_VALUATORS 36 -/* Maximum number of valuators, divided by six, rounded up, to get number - * of events. */ -#define MAX_VALUATOR_EVENTS 6 -#define MAX_BUTTONS 256 /* completely arbitrarily chosen */ - -#define NO_AXIS_LIMITS -1 - -#define MAP_LENGTH 256 -#define DOWN_LENGTH 32 /* 256/8 => number of bytes to hold 256 bits */ -#define NullGrab ((GrabPtr)NULL) -#define PointerRootWin ((WindowPtr)PointerRoot) -#define NoneWin ((WindowPtr)None) -#define NullDevice ((DevicePtr)NULL) - -#ifndef FollowKeyboard -#define FollowKeyboard 3 -#endif -#ifndef FollowKeyboardWin -#define FollowKeyboardWin ((WindowPtr) FollowKeyboard) -#endif -#ifndef RevertToFollowKeyboard -#define RevertToFollowKeyboard 3 -#endif - -typedef unsigned long Leds; -typedef struct _OtherClients *OtherClientsPtr; -typedef struct _InputClients *InputClientsPtr; -typedef struct _DeviceIntRec *DeviceIntPtr; -typedef struct _ClassesRec *ClassesPtr; -typedef union _GrabMask GrabMask; - -typedef struct _EventList { - xEvent* event; - int evlen; /* length of allocated memory for event in bytes. This is not - the actual length of the event. The event's actual length is - 32 for standard events or 32 + - ((xGenericEvent*)event)->length * 4 for GenericEvents. - For events in the EQ, the length is - ((InternalEvent*)event)->u.any.length */ -} EventList, *EventListPtr; - -/* The DIX stores incoming input events in this list */ -extern EventListPtr InputEventList; -extern int InputEventListLen; - -typedef int (*DeviceProc)( - DeviceIntPtr /*device*/, - int /*what*/); - -typedef void (*ProcessInputProc)( - InternalEvent * /*event*/, - DeviceIntPtr /*device*/); - -typedef Bool (*DeviceHandleProc)( - DeviceIntPtr /*device*/, - void* /*data*/ - ); - -typedef void (*DeviceUnwrapProc)( - DeviceIntPtr /*device*/, - DeviceHandleProc /*proc*/, - void* /*data*/ - ); - -/* pointer acceleration handling */ -typedef void (*PointerAccelSchemeProc)( - DeviceIntPtr /*pDev*/, - int /*first_valuator*/, - int /*num_valuators*/, - int* /*valuators*/, - int /*evtime*/); - -typedef void (*DeviceCallbackProc)( - DeviceIntPtr /*pDev*/); - -typedef struct _DeviceRec { - pointer devicePrivate; - ProcessInputProc processInputProc; /* current */ - ProcessInputProc realInputProc; /* deliver */ - ProcessInputProc enqueueInputProc; /* enqueue */ - Bool on; /* used by DDX to keep state */ -} DeviceRec, *DevicePtr; - -typedef struct { - int click, bell, bell_pitch, bell_duration; - Bool autoRepeat; - unsigned char autoRepeats[32]; - Leds leds; - unsigned char id; -} KeybdCtrl; - -typedef struct { - KeySym *map; - KeyCode minKeyCode, - maxKeyCode; - int mapWidth; -} KeySymsRec, *KeySymsPtr; - -typedef struct { - int num, den, threshold; - unsigned char id; -} PtrCtrl; - -typedef struct { - int resolution, min_value, max_value; - int integer_displayed; - unsigned char id; -} IntegerCtrl; - -typedef struct { - int max_symbols, num_symbols_supported; - int num_symbols_displayed; - KeySym *symbols_supported; - KeySym *symbols_displayed; - unsigned char id; -} StringCtrl; - -typedef struct { - int percent, pitch, duration; - unsigned char id; -} BellCtrl; - -typedef struct { - Leds led_values; - Mask led_mask; - unsigned char id; -} LedCtrl; - -extern _X_EXPORT KeybdCtrl defaultKeyboardControl; -extern _X_EXPORT PtrCtrl defaultPointerControl; - -typedef struct _InputOption { - char *key; - char *value; - struct _InputOption *next; -} InputOption; - -typedef struct _InputAttributes { - char *product; - char *vendor; - char *device; - char **tags; /* null-terminated */ - uint32_t flags; -} InputAttributes; - -#define ATTR_KEYBOARD (1<<0) -#define ATTR_POINTER (1<<1) -#define ATTR_JOYSTICK (1<<2) -#define ATTR_TABLET (1<<3) -#define ATTR_TOUCHPAD (1<<4) -#define ATTR_TOUCHSCREEN (1<<5) - -/* Key has been run through all input processing and events sent to clients. */ -#define KEY_PROCESSED 1 -/* Key has not been fully processed, no events have been sent. */ -#define KEY_POSTED 2 - -extern void set_key_down(DeviceIntPtr pDev, int key_code, int type); -extern void set_key_up(DeviceIntPtr pDev, int key_code, int type); -extern int key_is_down(DeviceIntPtr pDev, int key_code, int type); - -extern void InitCoreDevices(void); -extern void InitXTestDevices(void); - -extern _X_EXPORT DeviceIntPtr AddInputDevice( - ClientPtr /*client*/, - DeviceProc /*deviceProc*/, - Bool /*autoStart*/); - -extern _X_EXPORT Bool EnableDevice( - DeviceIntPtr /*device*/, - BOOL /* sendevent */); - -extern _X_EXPORT Bool ActivateDevice( - DeviceIntPtr /*device*/, - BOOL /* sendevent */); - -extern _X_EXPORT Bool DisableDevice( - DeviceIntPtr /*device*/, - BOOL /* sendevent */); - -extern int InitAndStartDevices(void); - -extern void CloseDownDevices(void); - -extern void UndisplayDevices(void); - -extern _X_EXPORT int RemoveDevice( - DeviceIntPtr /*dev*/, - BOOL /* sendevent */); - -extern _X_EXPORT int NumMotionEvents(void); - -extern void RegisterPointerDevice( - DeviceIntPtr /*device*/); - -extern void RegisterKeyboardDevice( - DeviceIntPtr /*device*/); - -extern _X_EXPORT int dixLookupDevice( - DeviceIntPtr * /* dev */, - int /* id */, - ClientPtr /* client */, - Mask /* access_mode */); - -extern _X_EXPORT void QueryMinMaxKeyCodes( - KeyCode* /*minCode*/, - KeyCode* /*maxCode*/); - -extern _X_EXPORT Bool SetKeySymsMap( - KeySymsPtr /*dst*/, - KeySymsPtr /*src*/); - -extern _X_EXPORT Bool InitButtonClassDeviceStruct( - DeviceIntPtr /*device*/, - int /*numButtons*/, - Atom* /* labels */, - CARD8* /*map*/); - -extern _X_EXPORT Bool InitValuatorClassDeviceStruct( - DeviceIntPtr /*device*/, - int /*numAxes*/, - Atom* /* labels */, - int /*numMotionEvents*/, - int /*mode*/); - -extern _X_EXPORT Bool InitPointerAccelerationScheme( - DeviceIntPtr /*dev*/, - int /*scheme*/); - -extern _X_EXPORT Bool InitAbsoluteClassDeviceStruct( - DeviceIntPtr /*device*/); - -extern _X_EXPORT Bool InitFocusClassDeviceStruct( - DeviceIntPtr /*device*/); - -typedef void (*BellProcPtr)( - int /*percent*/, - DeviceIntPtr /*device*/, - pointer /*ctrl*/, - int); - -typedef void (*KbdCtrlProcPtr)( - DeviceIntPtr /*device*/, - KeybdCtrl * /*ctrl*/); - -typedef void (*PtrCtrlProcPtr)( - DeviceIntPtr /*device*/, - PtrCtrl * /*ctrl*/); - -extern _X_EXPORT Bool InitPtrFeedbackClassDeviceStruct( - DeviceIntPtr /*device*/, - PtrCtrlProcPtr /*controlProc*/); - -typedef void (*StringCtrlProcPtr)( - DeviceIntPtr /*device*/, - StringCtrl * /*ctrl*/); - -extern _X_EXPORT Bool InitStringFeedbackClassDeviceStruct( - DeviceIntPtr /*device*/, - StringCtrlProcPtr /*controlProc*/, - int /*max_symbols*/, - int /*num_symbols_supported*/, - KeySym* /*symbols*/); - -typedef void (*BellCtrlProcPtr)( - DeviceIntPtr /*device*/, - BellCtrl * /*ctrl*/); - -extern _X_EXPORT Bool InitBellFeedbackClassDeviceStruct( - DeviceIntPtr /*device*/, - BellProcPtr /*bellProc*/, - BellCtrlProcPtr /*controlProc*/); - -typedef void (*LedCtrlProcPtr)( - DeviceIntPtr /*device*/, - LedCtrl * /*ctrl*/); - -extern _X_EXPORT Bool InitLedFeedbackClassDeviceStruct( - DeviceIntPtr /*device*/, - LedCtrlProcPtr /*controlProc*/); - -typedef void (*IntegerCtrlProcPtr)( - DeviceIntPtr /*device*/, - IntegerCtrl * /*ctrl*/); - - -extern _X_EXPORT Bool InitIntegerFeedbackClassDeviceStruct( - DeviceIntPtr /*device*/, - IntegerCtrlProcPtr /*controlProc*/); - -extern _X_EXPORT Bool InitPointerDeviceStruct( - DevicePtr /*device*/, - CARD8* /*map*/, - int /*numButtons*/, - Atom* /* btn_labels */, - PtrCtrlProcPtr /*controlProc*/, - int /*numMotionEvents*/, - int /*numAxes*/, - Atom* /* axes_labels */); - -extern _X_EXPORT Bool InitKeyboardDeviceStruct( - DeviceIntPtr /*device*/, - XkbRMLVOSet * /*rmlvo*/, - BellProcPtr /*bellProc*/, - KbdCtrlProcPtr /*controlProc*/); - -extern int ApplyPointerMapping( - DeviceIntPtr /* pDev */, - CARD8 * /* map */, - int /* len */, - ClientPtr /* client */); - -extern Bool BadDeviceMap( - BYTE* /*buff*/, - int /*length*/, - unsigned /*low*/, - unsigned /*high*/, - XID* /*errval*/); - -extern void NoteLedState( - DeviceIntPtr /*keybd*/, - int /*led*/, - Bool /*on*/); - -extern void MaybeStopHint( - DeviceIntPtr /*device*/, - ClientPtr /*client*/); - -extern void ProcessPointerEvent( - InternalEvent* /* ev */, - DeviceIntPtr /*mouse*/); - -extern void ProcessKeyboardEvent( - InternalEvent* /*ev*/, - DeviceIntPtr /*keybd*/); - -extern Bool LegalModifier( - unsigned int /*key*/, - DeviceIntPtr /*pDev*/); - -extern _X_EXPORT void ProcessInputEvents(void); - -extern _X_EXPORT void InitInput( - int /*argc*/, - char ** /*argv*/); -extern _X_EXPORT void CloseInput(void); - -extern _X_EXPORT int GetMaximumEventsNum(void); - -extern _X_EXPORT int GetEventList(EventListPtr* list); -extern _X_EXPORT EventListPtr InitEventList(int num_events); -extern _X_EXPORT void FreeEventList(EventListPtr list, int num_events); - -extern void CreateClassesChangedEvent(EventListPtr event, - DeviceIntPtr master, - DeviceIntPtr slave, - int type); -extern int GetPointerEvents( - EventListPtr events, - DeviceIntPtr pDev, - int type, - int buttons, - int flags, - int first_valuator, - int num_valuators, - int *valuators); - -extern int GetKeyboardEvents( - EventListPtr events, - DeviceIntPtr pDev, - int type, - int key_code); - -extern int GetKeyboardValuatorEvents( - EventListPtr events, - DeviceIntPtr pDev, - int type, - int key_code, - int first_valuator, - int num_valuator, - int *valuators); - -extern int GetProximityEvents( - EventListPtr events, - DeviceIntPtr pDev, - int type, - int first_valuator, - int num_valuators, - int *valuators); - -extern void PostSyntheticMotion( - DeviceIntPtr pDev, - int x, - int y, - int screen, - unsigned long time); - -extern _X_EXPORT int GetMotionHistorySize( - void); - -extern _X_EXPORT void AllocateMotionHistory( - DeviceIntPtr pDev); - -extern _X_EXPORT int GetMotionHistory( - DeviceIntPtr pDev, - xTimecoord **buff, - unsigned long start, - unsigned long stop, - ScreenPtr pScreen, - BOOL core); - -extern int AttachDevice(ClientPtr client, - DeviceIntPtr slave, - DeviceIntPtr master); - -extern _X_EXPORT DeviceIntPtr GetPairedDevice(DeviceIntPtr kbd); -extern DeviceIntPtr GetMaster(DeviceIntPtr dev, int type); - -extern int AllocDevicePair(ClientPtr client, - char* name, - DeviceIntPtr* ptr, - DeviceIntPtr* keybd, - DeviceProc ptr_proc, - DeviceProc keybd_proc, - Bool master); -extern void DeepCopyDeviceClasses(DeviceIntPtr from, - DeviceIntPtr to, - DeviceChangedEvent *dce); - -/* Helper functions. */ -extern int generate_modkeymap(ClientPtr client, DeviceIntPtr dev, - KeyCode **modkeymap, int *max_keys_per_mod); -extern int change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *map, - int max_keys_per_mod); -extern int AllocXTestDevice(ClientPtr client, - char* name, - DeviceIntPtr* ptr, - DeviceIntPtr* keybd, - DeviceIntPtr master_ptr, - DeviceIntPtr master_keybd); -extern BOOL IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master); -extern DeviceIntPtr GetXTestDevice(DeviceIntPtr master); -extern void SendDevicePresenceEvent(int deviceid, int type); - -/* misc event helpers */ -extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event); -extern Mask GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev); -void FixUpEventFromWindow(DeviceIntPtr pDev, - xEvent *xE, - WindowPtr pWin, - Window child, - Bool calcChild); - -/* Implemented by the DDX. */ -extern _X_EXPORT int NewInputDeviceRequest( - InputOption *options, - InputAttributes *attrs, - DeviceIntPtr *dev); -extern _X_EXPORT void DeleteInputDeviceRequest( - DeviceIntPtr dev); - -extern _X_EXPORT void DDXRingBell( - int volume, - int pitch, - int duration); - -/* Set to TRUE by default - os/utils.c sets it to FALSE on user request, - xfixes/cursor.c uses it to determine if the cursor is enabled */ -extern Bool EnableCursor; - -#endif /* INPUT_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.
+
+********************************************************/
+
+#ifndef INPUT_H
+#define INPUT_H
+
+#include "misc.h"
+#include "screenint.h"
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include <stdint.h>
+#include "window.h" /* for WindowPtr */
+#include "xkbrules.h"
+#include "events.h"
+
+#define DEVICE_INIT 0
+#define DEVICE_ON 1
+#define DEVICE_OFF 2
+#define DEVICE_CLOSE 3
+
+#define POINTER_RELATIVE (1 << 1)
+#define POINTER_ABSOLUTE (1 << 2)
+#define POINTER_ACCELERATE (1 << 3)
+#define POINTER_SCREEN (1 << 4) /* Data in screen coordinates */
+
+/*int constants for pointer acceleration schemes*/
+#define PtrAccelNoOp 0
+#define PtrAccelPredictable 1
+#define PtrAccelLightweight 2
+#define PtrAccelDefault PtrAccelPredictable
+
+#define MAX_VALUATORS 36
+/* Maximum number of valuators, divided by six, rounded up, to get number
+ * of events. */
+#define MAX_VALUATOR_EVENTS 6
+#define MAX_BUTTONS 256 /* completely arbitrarily chosen */
+
+#define NO_AXIS_LIMITS -1
+
+#define MAP_LENGTH 256
+#define DOWN_LENGTH 32 /* 256/8 => number of bytes to hold 256 bits */
+#define NullGrab ((GrabPtr)NULL)
+#define PointerRootWin ((WindowPtr)PointerRoot)
+#define NoneWin ((WindowPtr)None)
+#define NullDevice ((DevicePtr)NULL)
+
+#ifndef FollowKeyboard
+#define FollowKeyboard 3
+#endif
+#ifndef FollowKeyboardWin
+#define FollowKeyboardWin ((WindowPtr) FollowKeyboard)
+#endif
+#ifndef RevertToFollowKeyboard
+#define RevertToFollowKeyboard 3
+#endif
+
+typedef unsigned long Leds;
+typedef struct _OtherClients *OtherClientsPtr;
+typedef struct _InputClients *InputClientsPtr;
+typedef struct _DeviceIntRec *DeviceIntPtr;
+typedef struct _ClassesRec *ClassesPtr;
+typedef union _GrabMask GrabMask;
+
+typedef struct _EventList {
+ xEvent* event;
+ int evlen; /* length of allocated memory for event in bytes. This is not
+ the actual length of the event. The event's actual length is
+ 32 for standard events or 32 +
+ ((xGenericEvent*)event)->length * 4 for GenericEvents.
+ For events in the EQ, the length is
+ ((InternalEvent*)event)->u.any.length */
+} EventList, *EventListPtr;
+
+/* The DIX stores incoming input events in this list */
+extern EventListPtr InputEventList;
+extern int InputEventListLen;
+
+typedef int (*DeviceProc)(
+ DeviceIntPtr /*device*/,
+ int /*what*/);
+
+typedef void (*ProcessInputProc)(
+ InternalEvent * /*event*/,
+ DeviceIntPtr /*device*/);
+
+typedef Bool (*DeviceHandleProc)(
+ DeviceIntPtr /*device*/,
+ void* /*data*/
+ );
+
+typedef void (*DeviceUnwrapProc)(
+ DeviceIntPtr /*device*/,
+ DeviceHandleProc /*proc*/,
+ void* /*data*/
+ );
+
+/* pointer acceleration handling */
+typedef void (*PointerAccelSchemeProc)(
+ DeviceIntPtr /*pDev*/,
+ int /*first_valuator*/,
+ int /*num_valuators*/,
+ int* /*valuators*/,
+ int /*evtime*/);
+
+typedef void (*DeviceCallbackProc)(
+ DeviceIntPtr /*pDev*/);
+
+typedef struct _DeviceRec {
+ pointer devicePrivate;
+ ProcessInputProc processInputProc; /* current */
+ ProcessInputProc realInputProc; /* deliver */
+ ProcessInputProc enqueueInputProc; /* enqueue */
+ Bool on; /* used by DDX to keep state */
+} DeviceRec, *DevicePtr;
+
+typedef struct {
+ int click, bell, bell_pitch, bell_duration;
+ Bool autoRepeat;
+ unsigned char autoRepeats[32];
+ Leds leds;
+ unsigned char id;
+} KeybdCtrl;
+
+typedef struct {
+ KeySym *map;
+ KeyCode minKeyCode,
+ maxKeyCode;
+ int mapWidth;
+} KeySymsRec, *KeySymsPtr;
+
+typedef struct {
+ int num, den, threshold;
+ unsigned char id;
+} PtrCtrl;
+
+typedef struct {
+ int resolution, min_value, max_value;
+ int integer_displayed;
+ unsigned char id;
+} IntegerCtrl;
+
+typedef struct {
+ int max_symbols, num_symbols_supported;
+ int num_symbols_displayed;
+ KeySym *symbols_supported;
+ KeySym *symbols_displayed;
+ unsigned char id;
+} StringCtrl;
+
+typedef struct {
+ int percent, pitch, duration;
+ unsigned char id;
+} BellCtrl;
+
+typedef struct {
+ Leds led_values;
+ Mask led_mask;
+ unsigned char id;
+} LedCtrl;
+
+extern _X_EXPORT KeybdCtrl defaultKeyboardControl;
+extern _X_EXPORT PtrCtrl defaultPointerControl;
+
+typedef struct _InputOption {
+ char *key;
+ char *value;
+ struct _InputOption *next;
+} InputOption;
+
+typedef struct _InputAttributes {
+ char *product;
+ char *vendor;
+ char *device;
+ char **tags; /* null-terminated */
+ uint32_t flags;
+} InputAttributes;
+
+#define ATTR_KEYBOARD (1<<0)
+#define ATTR_POINTER (1<<1)
+#define ATTR_JOYSTICK (1<<2)
+#define ATTR_TABLET (1<<3)
+#define ATTR_TOUCHPAD (1<<4)
+#define ATTR_TOUCHSCREEN (1<<5)
+
+/* Key has been run through all input processing and events sent to clients. */
+#define KEY_PROCESSED 1
+/* Key has not been fully processed, no events have been sent. */
+#define KEY_POSTED 2
+
+extern void set_key_down(DeviceIntPtr pDev, int key_code, int type);
+extern void set_key_up(DeviceIntPtr pDev, int key_code, int type);
+extern int key_is_down(DeviceIntPtr pDev, int key_code, int type);
+
+extern void InitCoreDevices(void);
+extern void InitXTestDevices(void);
+
+extern _X_EXPORT DeviceIntPtr AddInputDevice(
+ ClientPtr /*client*/,
+ DeviceProc /*deviceProc*/,
+ Bool /*autoStart*/);
+
+extern _X_EXPORT Bool EnableDevice(
+ DeviceIntPtr /*device*/,
+ BOOL /* sendevent */);
+
+extern _X_EXPORT Bool ActivateDevice(
+ DeviceIntPtr /*device*/,
+ BOOL /* sendevent */);
+
+extern _X_EXPORT Bool DisableDevice(
+ DeviceIntPtr /*device*/,
+ BOOL /* sendevent */);
+
+extern int InitAndStartDevices(void);
+
+extern void CloseDownDevices(void);
+
+extern void UndisplayDevices(void);
+
+extern _X_EXPORT int RemoveDevice(
+ DeviceIntPtr /*dev*/,
+ BOOL /* sendevent */);
+
+extern _X_EXPORT int NumMotionEvents(void);
+
+extern void RegisterPointerDevice(
+ DeviceIntPtr /*device*/);
+
+extern void RegisterKeyboardDevice(
+ DeviceIntPtr /*device*/);
+
+extern _X_EXPORT int dixLookupDevice(
+ DeviceIntPtr * /* dev */,
+ int /* id */,
+ ClientPtr /* client */,
+ Mask /* access_mode */);
+
+extern _X_EXPORT void QueryMinMaxKeyCodes(
+ KeyCode* /*minCode*/,
+ KeyCode* /*maxCode*/);
+
+extern _X_EXPORT Bool SetKeySymsMap(
+ KeySymsPtr /*dst*/,
+ KeySymsPtr /*src*/);
+
+extern _X_EXPORT Bool InitButtonClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ int /*numButtons*/,
+ Atom* /* labels */,
+ CARD8* /*map*/);
+
+extern _X_EXPORT Bool InitValuatorClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ int /*numAxes*/,
+ Atom* /* labels */,
+ int /*numMotionEvents*/,
+ int /*mode*/);
+
+extern _X_EXPORT Bool InitPointerAccelerationScheme(
+ DeviceIntPtr /*dev*/,
+ int /*scheme*/);
+
+extern _X_EXPORT Bool InitAbsoluteClassDeviceStruct(
+ DeviceIntPtr /*device*/);
+
+extern _X_EXPORT Bool InitFocusClassDeviceStruct(
+ DeviceIntPtr /*device*/);
+
+typedef void (*BellProcPtr)(
+ int /*percent*/,
+ DeviceIntPtr /*device*/,
+ pointer /*ctrl*/,
+ int);
+
+typedef void (*KbdCtrlProcPtr)(
+ DeviceIntPtr /*device*/,
+ KeybdCtrl * /*ctrl*/);
+
+typedef void (*PtrCtrlProcPtr)(
+ DeviceIntPtr /*device*/,
+ PtrCtrl * /*ctrl*/);
+
+extern _X_EXPORT Bool InitPtrFeedbackClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ PtrCtrlProcPtr /*controlProc*/);
+
+typedef void (*StringCtrlProcPtr)(
+ DeviceIntPtr /*device*/,
+ StringCtrl * /*ctrl*/);
+
+extern _X_EXPORT Bool InitStringFeedbackClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ StringCtrlProcPtr /*controlProc*/,
+ int /*max_symbols*/,
+ int /*num_symbols_supported*/,
+ KeySym* /*symbols*/);
+
+typedef void (*BellCtrlProcPtr)(
+ DeviceIntPtr /*device*/,
+ BellCtrl * /*ctrl*/);
+
+extern _X_EXPORT Bool InitBellFeedbackClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ BellProcPtr /*bellProc*/,
+ BellCtrlProcPtr /*controlProc*/);
+
+typedef void (*LedCtrlProcPtr)(
+ DeviceIntPtr /*device*/,
+ LedCtrl * /*ctrl*/);
+
+extern _X_EXPORT Bool InitLedFeedbackClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ LedCtrlProcPtr /*controlProc*/);
+
+typedef void (*IntegerCtrlProcPtr)(
+ DeviceIntPtr /*device*/,
+ IntegerCtrl * /*ctrl*/);
+
+
+extern _X_EXPORT Bool InitIntegerFeedbackClassDeviceStruct(
+ DeviceIntPtr /*device*/,
+ IntegerCtrlProcPtr /*controlProc*/);
+
+extern _X_EXPORT Bool InitPointerDeviceStruct(
+ DevicePtr /*device*/,
+ CARD8* /*map*/,
+ int /*numButtons*/,
+ Atom* /* btn_labels */,
+ PtrCtrlProcPtr /*controlProc*/,
+ int /*numMotionEvents*/,
+ int /*numAxes*/,
+ Atom* /* axes_labels */);
+
+extern _X_EXPORT Bool InitKeyboardDeviceStruct(
+ DeviceIntPtr /*device*/,
+ XkbRMLVOSet * /*rmlvo*/,
+ BellProcPtr /*bellProc*/,
+ KbdCtrlProcPtr /*controlProc*/);
+
+extern int ApplyPointerMapping(
+ DeviceIntPtr /* pDev */,
+ CARD8 * /* map */,
+ int /* len */,
+ ClientPtr /* client */);
+
+extern Bool BadDeviceMap(
+ BYTE* /*buff*/,
+ int /*length*/,
+ unsigned /*low*/,
+ unsigned /*high*/,
+ XID* /*errval*/);
+
+extern void NoteLedState(
+ DeviceIntPtr /*keybd*/,
+ int /*led*/,
+ Bool /*on*/);
+
+extern void MaybeStopHint(
+ DeviceIntPtr /*device*/,
+ ClientPtr /*client*/);
+
+extern void ProcessPointerEvent(
+ InternalEvent* /* ev */,
+ DeviceIntPtr /*mouse*/);
+
+extern void ProcessKeyboardEvent(
+ InternalEvent* /*ev*/,
+ DeviceIntPtr /*keybd*/);
+
+extern Bool LegalModifier(
+ unsigned int /*key*/,
+ DeviceIntPtr /*pDev*/);
+
+extern _X_EXPORT void ProcessInputEvents(void);
+
+extern _X_EXPORT void InitInput(
+ int /*argc*/,
+ char ** /*argv*/);
+extern _X_EXPORT void CloseInput(void);
+
+extern _X_EXPORT int GetMaximumEventsNum(void);
+
+extern _X_EXPORT int GetEventList(EventListPtr* list);
+extern _X_EXPORT EventListPtr InitEventList(int num_events);
+extern _X_EXPORT void FreeEventList(EventListPtr list, int num_events);
+
+extern void CreateClassesChangedEvent(EventListPtr event,
+ DeviceIntPtr master,
+ DeviceIntPtr slave,
+ int type);
+extern int GetPointerEvents(
+ EventListPtr events,
+ DeviceIntPtr pDev,
+ int type,
+ int buttons,
+ int flags,
+ int first_valuator,
+ int num_valuators,
+ int *valuators);
+
+extern int GetKeyboardEvents(
+ EventListPtr events,
+ DeviceIntPtr pDev,
+ int type,
+ int key_code);
+
+extern int GetKeyboardValuatorEvents(
+ EventListPtr events,
+ DeviceIntPtr pDev,
+ int type,
+ int key_code,
+ int first_valuator,
+ int num_valuator,
+ int *valuators);
+
+extern int GetProximityEvents(
+ EventListPtr events,
+ DeviceIntPtr pDev,
+ int type,
+ int first_valuator,
+ int num_valuators,
+ int *valuators);
+
+extern void PostSyntheticMotion(
+ DeviceIntPtr pDev,
+ int x,
+ int y,
+ int screen,
+ unsigned long time);
+
+extern _X_EXPORT int GetMotionHistorySize(
+ void);
+
+extern _X_EXPORT void AllocateMotionHistory(
+ DeviceIntPtr pDev);
+
+extern _X_EXPORT int GetMotionHistory(
+ DeviceIntPtr pDev,
+ xTimecoord **buff,
+ unsigned long start,
+ unsigned long stop,
+ ScreenPtr pScreen,
+ BOOL core);
+
+extern int AttachDevice(ClientPtr client,
+ DeviceIntPtr slave,
+ DeviceIntPtr master);
+
+extern _X_EXPORT DeviceIntPtr GetPairedDevice(DeviceIntPtr kbd);
+extern DeviceIntPtr GetMaster(DeviceIntPtr dev, int type);
+
+extern int AllocDevicePair(ClientPtr client,
+ char* name,
+ DeviceIntPtr* ptr,
+ DeviceIntPtr* keybd,
+ DeviceProc ptr_proc,
+ DeviceProc keybd_proc,
+ Bool master);
+extern void DeepCopyDeviceClasses(DeviceIntPtr from,
+ DeviceIntPtr to,
+ DeviceChangedEvent *dce);
+
+/* Helper functions. */
+extern int generate_modkeymap(ClientPtr client, DeviceIntPtr dev,
+ KeyCode **modkeymap, int *max_keys_per_mod);
+extern int change_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *map,
+ int max_keys_per_mod);
+extern int AllocXTestDevice(ClientPtr client,
+ char* name,
+ DeviceIntPtr* ptr,
+ DeviceIntPtr* keybd,
+ DeviceIntPtr master_ptr,
+ DeviceIntPtr master_keybd);
+extern BOOL IsXTestDevice(DeviceIntPtr dev, DeviceIntPtr master);
+extern DeviceIntPtr GetXTestDevice(DeviceIntPtr master);
+extern void SendDevicePresenceEvent(int deviceid, int type);
+
+/* misc event helpers */
+extern Mask GetEventFilter(DeviceIntPtr dev, xEvent *event);
+extern Mask GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev);
+void FixUpEventFromWindow(DeviceIntPtr pDev,
+ xEvent *xE,
+ WindowPtr pWin,
+ Window child,
+ Bool calcChild);
+
+/* Implemented by the DDX. */
+extern _X_EXPORT int NewInputDeviceRequest(
+ InputOption *options,
+ InputAttributes *attrs,
+ DeviceIntPtr *dev);
+extern _X_EXPORT void DeleteInputDeviceRequest(
+ DeviceIntPtr dev);
+
+extern _X_EXPORT void DDXRingBell(
+ int volume,
+ int pitch,
+ int duration);
+
+/* Set to TRUE by default - os/utils.c sets it to FALSE on user request,
+ xfixes/cursor.c uses it to determine if the cursor is enabled */
+extern Bool EnableCursor;
+
+#endif /* INPUT_H */
diff --git a/xorg-server/include/misc.h b/xorg-server/include/misc.h index 62d813e0c..1cdb38fc4 100644 --- a/xorg-server/include/misc.h +++ b/xorg-server/include/misc.h @@ -166,9 +166,9 @@ typedef struct _xReq *xReqPtr; #include <math.h> #undef MAXSHORT -#define MAXSHORT SHRT_MAX +#define MAXSHORT 32767 #undef MINSHORT -#define MINSHORT SHRT_MIN +#define MINSHORT -32768 #undef MAXINT #define MAXINT INT_MAX #undef MININT @@ -185,7 +185,7 @@ typedef struct _xReq *xReqPtr; * @param bits The minimum number of bits needed. * @return The number of bytes needed to hold bits. */ -static inline int +static __inline int bits_to_bytes(const int bits) { return ((bits + 7) >> 3); } @@ -195,7 +195,7 @@ bits_to_bytes(const int bits) { * @param bytes The minimum number of bytes needed. * @return The number of 4-byte units needed to hold bytes. */ -static inline int +static __inline int bytes_to_int32(const int bytes) { return (((bytes) + 3) >> 2); } @@ -205,7 +205,7 @@ bytes_to_int32(const int 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 +static __inline int pad_to_int32(const int bytes) { return (((bytes) + 3) & ~3); } diff --git a/xorg-server/include/os.h b/xorg-server/include/os.h index dad1af787..68b679998 100644 --- a/xorg-server/include/os.h +++ b/xorg-server/include/os.h @@ -114,6 +114,8 @@ extern _X_EXPORT int WriteToClient(ClientPtr /*who*/, int /*count*/, const void* extern _X_EXPORT void ResetOsBuffers(void); +extern _X_EXPORT int TransIsListening(char *protocol); + extern _X_EXPORT void InitConnectionLimits(void); extern _X_EXPORT void NotifyParentProcess(void); @@ -526,4 +528,8 @@ extern _X_EXPORT void LogPrintMarkers(void); extern _X_EXPORT void xorg_backtrace(void); +#ifdef _MSC_VER +#define snprintf _snprintf +#endif + #endif /* OS_H */ diff --git a/xorg-server/include/pixmapstr.h b/xorg-server/include/pixmapstr.h index 702faf0ac..8002b170a 100644 --- a/xorg-server/include/pixmapstr.h +++ b/xorg-server/include/pixmapstr.h @@ -76,10 +76,8 @@ typedef struct _Pixmap { int refcnt; int devKind; /* This is the pitch of the pixmap, typically width*bpp/8. */ DevUnion devPrivate; /* When !NULL, devPrivate.ptr points to the raw pixel data. */ -#ifdef COMPOSITE short screen_x; short screen_y; -#endif unsigned usage_hint; /* see CREATE_PIXMAP_USAGE_* */ } PixmapRec; diff --git a/xorg-server/include/scrnintstr.h b/xorg-server/include/scrnintstr.h index ab50e7a32..2299504c7 100644 --- a/xorg-server/include/scrnintstr.h +++ b/xorg-server/include/scrnintstr.h @@ -68,7 +68,7 @@ typedef struct _Visual { VisualID vid; short class; short bitsPerRGBValue; - short ColormapEntries; + long ColormapEntries; short nplanes;/* = log2 (ColormapEntries). This does not * imply that the screen has this many planes. * it may have more or fewer */ @@ -438,6 +438,10 @@ typedef void (* MarkUnrealizedWindowProcPtr)( WindowPtr /*pWin*/, Bool /*fromConfigure*/); +#ifdef CreateWindow +#undef CreateWindow +#endif + typedef Bool (* DeviceCursorInitializeProcPtr)( DeviceIntPtr /* pDev */, ScreenPtr /* pScreen */); diff --git a/xorg-server/include/servermd.h b/xorg-server/include/servermd.h index e1d644e00..c851d19bc 100644 --- a/xorg-server/include/servermd.h +++ b/xorg-server/include/servermd.h @@ -269,6 +269,12 @@ SOFTWARE. #define GLYPHPADBYTES 4 #endif /* linux/s390 */ +#ifdef WIN32 +#define IMAGE_BYTE_ORDER LSBFirst +#define BITMAP_BIT_ORDER LSBFirst +#define GLYPHPADBYTES 4 +#endif + /* size of buffer to use with GetImage, measured in bytes. There's obviously * a trade-off between the amount of heap used and the number of times the * ddx routine has to be called. diff --git a/xorg-server/include/site.h b/xorg-server/include/site.h index b13421231..4ec75edd3 100644 --- a/xorg-server/include/site.h +++ b/xorg-server/include/site.h @@ -52,7 +52,7 @@ SOFTWARE. * server executable. */ #ifndef VENDOR_STRING -#define VENDOR_STRING "The X.Org Foundation" +#define VENDOR_STRING "HC-Consult" #endif /* @@ -61,7 +61,7 @@ SOFTWARE. * by the vendor. */ #ifndef VENDOR_RELEASE -#define VENDOR_RELEASE 6600 +#define VENDOR_RELEASE XORG_VERSION_CURRENT #endif /* diff --git a/xorg-server/include/version-config.h b/xorg-server/include/version-config.h new file mode 100644 index 000000000..b8d482ce8 --- /dev/null +++ b/xorg-server/include/version-config.h @@ -0,0 +1,16 @@ +/* version-config.h.in: not generated */ + +#ifndef VERSION_CONFIG_H +#define VERSION_CONFIG_H + +/* Vendor man version */ +#undef VENDOR_MAN_VERSION + +/* Vendor name */ +#define VENDOR_NAME "HC-Consult" + +/* Vendor release */ +#define VENDOR_RELEASE XORG_VERSION_CURRENT + +#endif /* VERSION_CONFIG_H */ + diff --git a/xorg-server/include/windowstr.h b/xorg-server/include/windowstr.h index 96bee9b93..94e04ead2 100644 --- a/xorg-server/include/windowstr.h +++ b/xorg-server/include/windowstr.h @@ -141,7 +141,7 @@ typedef struct _Window { RegionRec borderSize; DDXPointRec origin; /* position relative to parent */ unsigned short borderWidth; - unsigned short deliverableEvents; /* all masks from all clients */ + unsigned long deliverableEvents; /* all masks from all clients */ Mask eventMask; /* mask from the creating client */ PixUnion background; PixUnion border; diff --git a/xorg-server/include/xkb-config.h b/xorg-server/include/xkb-config.h new file mode 100644 index 000000000..9f7dac59e --- /dev/null +++ b/xorg-server/include/xkb-config.h @@ -0,0 +1,36 @@ +/* include/xkb-config.h. Generated from xkb-config.h.in by configure. */ +/* xkb-config.h.in: not at all generated. -*- c -*- + * + */ + +#ifndef _XKB_CONFIG_H_ +#define _XKB_CONFIG_H_ + +/* Default set of XKB rules. */ +#define XKB_DFLT_RULES "xorg" + +/* Default XKB model. */ +#define XKB_DFLT_MODEL "pc104" + +/* Default XKB layout. */ +#define XKB_DFLT_LAYOUT "us" + +/* Default XKB variant. */ +#define XKB_DFLT_VARIANT "" + +/* Default XKB options. */ +#define XKB_DFLT_OPTIONS "" + +/* Path to XKB definitions. */ +#define XKB_BASE_DIRECTORY "xkbdata" + +/* Path to xkbcomp. */ +#define XKB_BIN_DIRECTORY "." + +/* XKB output dir for compiled keymaps. */ +#define XKM_OUTPUT_DIR "xkbdata/compiled/" + +/* Do not have `strcasecmp'. */ +/* #undef NEED_STRCASECMP */ + +#endif /* _XKB_CONFIG_H_ */ diff --git a/xorg-server/include/xkbsrv.h b/xorg-server/include/xkbsrv.h index 278ff769d..4b0b3a9a1 100644 --- a/xorg-server/include/xkbsrv.h +++ b/xorg-server/include/xkbsrv.h @@ -1,985 +1,985 @@ -/************************************************************ -Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - -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 Silicon Graphics not be -used in advertising or publicity pertaining to distribution -of the software without specific prior written permission. -Silicon Graphics makes no representation about the suitability -of this software for any purpose. It is provided "as is" -without any express or implied warranty. - -SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON -GRAPHICS 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 _XKBSRV_H_ -#define _XKBSRV_H_ - -#define XkbAllocClientMap SrvXkbAllocClientMap -#define XkbAllocServerMap SrvXkbAllocServerMap -#define XkbChangeTypesOfKey SrvXkbChangeTypesOfKey -#define XkbCopyKeyTypes SrvXkbCopyKeyTypes -#define XkbFreeClientMap SrvXkbFreeClientMap -#define XkbFreeServerMap SrvXkbFreeServerMap -#define XkbKeyTypesForCoreSymbols SrvXkbKeyTypesForCoreSymbols -#define XkbApplyCompatMapToKey SrvXkbApplyCompatMapToKey -#define XkbResizeKeyActions SrvXkbResizeKeyActions -#define XkbResizeKeySyms SrvXkbResizeKeySyms -#define XkbResizeKeyType SrvXkbResizeKeyType -#define XkbAllocCompatMap SrvXkbAllocCompatMap -#define XkbAllocControls SrvXkbAllocControls -#define XkbAllocIndicatorMaps SrvXkbAllocIndicatorMaps -#define XkbAllocKeyboard SrvXkbAllocKeyboard -#define XkbAllocNames SrvXkbAllocNames -#define XkbFreeCompatMap SrvXkbFreeCompatMap -#define XkbFreeKeyboard SrvXkbFreeKeyboard -#define XkbFreeNames SrvXkbFreeNames -#define XkbLatchModifiers SrvXkbLatchModifiers -#define XkbLatchGroup SrvXkbLatchGroup -#define XkbVirtualModsToReal SrvXkbVirtualModsToReal -#define XkbChangeKeycodeRange SrvXkbChangeKeycodeRange -#define XkbApplyVirtualModChanges SrvXkbApplyVirtualModChanges - -#include <X11/extensions/XKBproto.h> -#include "xkbstr.h" -#include "xkbrules.h" -#include "inputstr.h" -#include "events.h" - -typedef struct _XkbInterest { - DeviceIntPtr dev; - ClientPtr client; - XID resource; - struct _XkbInterest * next; - CARD16 extDevNotifyMask; - CARD16 stateNotifyMask; - CARD16 namesNotifyMask; - CARD32 ctrlsNotifyMask; - CARD8 compatNotifyMask; - BOOL bellNotifyMask; - BOOL actionMessageMask; - CARD16 accessXNotifyMask; - CARD32 iStateNotifyMask; - CARD32 iMapNotifyMask; - CARD16 altSymsNotifyMask; - CARD32 autoCtrls; - CARD32 autoCtrlValues; -} XkbInterestRec,*XkbInterestPtr; - -typedef struct _XkbRadioGroup { - CARD8 flags; - CARD8 nMembers; - CARD8 dfltDown; - CARD8 currentDown; - CARD8 members[XkbRGMaxMembers]; -} XkbRadioGroupRec, *XkbRadioGroupPtr; - -typedef struct _XkbEventCause { - CARD8 kc; - CARD8 event; - CARD8 mjr; - CARD8 mnr; - ClientPtr client; -} XkbEventCauseRec,*XkbEventCausePtr; -#define XkbSetCauseKey(c,k,e) { (c)->kc= (k),(c)->event= (e),\ - (c)->mjr= (c)->mnr= 0; \ - (c)->client= NULL; } -#define XkbSetCauseReq(c,j,n,cl) { (c)->kc= (c)->event= 0,\ - (c)->mjr= (j),(c)->mnr= (n);\ - (c)->client= (cl); } -#define XkbSetCauseCoreReq(c,e,cl) XkbSetCauseReq(c,e,0,cl) -#define XkbSetCauseXkbReq(c,e,cl) XkbSetCauseReq(c,XkbReqCode,e,cl) -#define XkbSetCauseUnknown(c) XkbSetCauseKey(c,0,0) - -#define _OFF_TIMER 0 -#define _KRG_WARN_TIMER 1 -#define _KRG_TIMER 2 -#define _SK_TIMEOUT_TIMER 3 -#define _ALL_TIMEOUT_TIMER 4 - -#define _BEEP_NONE 0 -#define _BEEP_FEATURE_ON 1 -#define _BEEP_FEATURE_OFF 2 -#define _BEEP_FEATURE_CHANGE 3 -#define _BEEP_SLOW_WARN 4 -#define _BEEP_SLOW_PRESS 5 -#define _BEEP_SLOW_ACCEPT 6 -#define _BEEP_SLOW_REJECT 7 -#define _BEEP_SLOW_RELEASE 8 -#define _BEEP_STICKY_LATCH 9 -#define _BEEP_STICKY_LOCK 10 -#define _BEEP_STICKY_UNLOCK 11 -#define _BEEP_LED_ON 12 -#define _BEEP_LED_OFF 13 -#define _BEEP_LED_CHANGE 14 -#define _BEEP_BOUNCE_REJECT 15 - -typedef struct _XkbFilter { - CARD16 keycode; - CARD8 what; - CARD8 active; - CARD8 filterOthers; - CARD32 priv; - XkbAction upAction; - int (*filter)( - struct _XkbSrvInfo* /* xkbi */, - struct _XkbFilter * /* filter */, - unsigned /* keycode */, - XkbAction * /* action */ - ); - struct _XkbFilter *next; -} XkbFilterRec,*XkbFilterPtr; - -typedef struct _XkbSrvInfo { - XkbStateRec prev_state; - XkbStateRec state; - XkbDescPtr desc; - - DeviceIntPtr device; - KbdCtrlProcPtr kbdProc; - - XkbRadioGroupPtr radioGroups; - CARD8 nRadioGroups; - CARD8 clearMods; - CARD8 setMods; - INT16 groupChange; - - CARD16 dfltPtrDelta; - - double mouseKeysCurve; - double mouseKeysCurveFactor; - INT16 mouseKeysDX; - INT16 mouseKeysDY; - CARD8 mouseKeysFlags; - Bool mouseKeysAccel; - CARD8 mouseKeysCounter; - - CARD8 lockedPtrButtons; - CARD8 shiftKeyCount; - KeyCode mouseKey; - KeyCode inactiveKey; - KeyCode slowKey; - KeyCode repeatKey; - CARD8 krgTimerActive; - CARD8 beepType; - CARD8 beepCount; - - CARD32 flags; - CARD32 lastPtrEventTime; - CARD32 lastShiftEventTime; - OsTimerPtr beepTimer; - OsTimerPtr mouseKeyTimer; - OsTimerPtr slowKeysTimer; - OsTimerPtr bounceKeysTimer; - OsTimerPtr repeatKeyTimer; - OsTimerPtr krgTimer; - - int szFilters; - XkbFilterPtr filters; -} XkbSrvInfoRec, *XkbSrvInfoPtr; - -#define XkbSLI_IsDefault (1L<<0) -#define XkbSLI_HasOwnState (1L<<1) - -typedef struct _XkbSrvLedInfo { - CARD16 flags; - CARD16 class; - CARD16 id; - union { - KbdFeedbackPtr kf; - LedFeedbackPtr lf; - } fb; - - CARD32 physIndicators; - CARD32 autoState; - CARD32 explicitState; - CARD32 effectiveState; - - CARD32 mapsPresent; - CARD32 namesPresent; - XkbIndicatorMapPtr maps; - Atom * names; - - CARD32 usesBase; - CARD32 usesLatched; - CARD32 usesLocked; - CARD32 usesEffective; - CARD32 usesCompat; - CARD32 usesControls; - - CARD32 usedComponents; -} XkbSrvLedInfoRec, *XkbSrvLedInfoPtr; - -/* - * Settings for xkbClientFlags field (used by DIX) - * These flags _must_ not overlap with XkbPCF_* - */ -#define _XkbClientInitialized (1<<15) - -#define _XkbWantsDetectableAutoRepeat(c)\ - ((c)->xkbClientFlags&XkbPCF_DetectableAutoRepeatMask) - -/* - * Settings for flags field - */ -#define _XkbStateNotifyInProgress (1<<0) - -typedef struct -{ - ProcessInputProc processInputProc; - /* If processInputProc is set to something different than realInputProc, - * UNWRAP and COND_WRAP will not touch processInputProc and update only - * realInputProc. This ensures that - * processInputProc == (frozen ? EnqueueEvent : realInputProc) - * - * WRAP_PROCESS_INPUT_PROC should only be called during initialization, - * since it may destroy this invariant. - */ - ProcessInputProc realInputProc; - DeviceUnwrapProc unwrapProc; -} xkbDeviceInfoRec, *xkbDeviceInfoPtr; - -#define WRAP_PROCESS_INPUT_PROC(device, oldprocs, proc, unwrapproc) \ - device->public.processInputProc = proc; \ - oldprocs->processInputProc = \ - oldprocs->realInputProc = device->public.realInputProc; \ - device->public.realInputProc = proc; \ - oldprocs->unwrapProc = device->unwrapProc; \ - device->unwrapProc = unwrapproc; - -#define COND_WRAP_PROCESS_INPUT_PROC(device, oldprocs, proc, unwrapproc) \ - if (device->public.processInputProc == device->public.realInputProc)\ - device->public.processInputProc = proc; \ - oldprocs->processInputProc = \ - oldprocs->realInputProc = device->public.realInputProc; \ - device->public.realInputProc = proc; \ - oldprocs->unwrapProc = device->unwrapProc; \ - device->unwrapProc = unwrapproc; - -#define UNWRAP_PROCESS_INPUT_PROC(device, oldprocs, backupproc) \ - backupproc = device->public.realInputProc; \ - if (device->public.processInputProc == device->public.realInputProc)\ - device->public.processInputProc = oldprocs->realInputProc; \ - device->public.realInputProc = oldprocs->realInputProc; \ - device->unwrapProc = oldprocs->unwrapProc; - -extern DevPrivateKey xkbDevicePrivateKey; -#define XKBDEVICEINFO(dev) ((xkbDeviceInfoPtr)dixLookupPrivate(&(dev)->devPrivates, xkbDevicePrivateKey)) - -extern void xkbUnwrapProc(DeviceIntPtr, DeviceHandleProc, pointer); - -/***====================================================================***/ - - -/***====================================================================***/ - -#define XkbAX_KRGMask (XkbSlowKeysMask|XkbBounceKeysMask) -#define XkbAllFilteredEventsMask \ - (XkbAccessXKeysMask|XkbRepeatKeysMask|XkbMouseKeysAccelMask|XkbAX_KRGMask) - -/***====================================================================***/ - -extern _X_EXPORT int XkbReqCode; -extern _X_EXPORT int XkbEventBase; -extern _X_EXPORT int XkbKeyboardErrorCode; -extern _X_EXPORT char * XkbBaseDirectory; -extern _X_EXPORT char * XkbBinDirectory; - -extern _X_EXPORT CARD32 xkbDebugFlags; - -#define _XkbLibError(c,l,d) /* Epoch fail */ -#define _XkbErrCode2(a,b) ((XID)((((unsigned int)(a))<<24)|((b)&0xffffff))) -#define _XkbErrCode3(a,b,c) _XkbErrCode2(a,(((unsigned int)(b))<<16)|(c)) -#define _XkbErrCode4(a,b,c,d) _XkbErrCode3(a,b,((((unsigned int)(c))<<8)|(d))) - -extern _X_EXPORT int DeviceKeyPress,DeviceKeyRelease,DeviceMotionNotify; -extern _X_EXPORT int DeviceButtonPress,DeviceButtonRelease; - -#define Status int - -extern _X_EXPORT void XkbUseMsg( - void -); - -extern _X_EXPORT int XkbProcessArguments( - int /* argc */, - char ** /* argv */, - int /* i */ -); - -extern _X_EXPORT void XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc); - -extern _X_EXPORT void XkbFreeCompatMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - Bool /* freeMap */ -); - -extern _X_EXPORT void XkbFreeNames( - XkbDescPtr /* xkb */, - unsigned int /* which */, - Bool /* freeMap */ -); - -extern _X_EXPORT int _XkbLookupAnyDevice( - DeviceIntPtr *pDev, - int id, - ClientPtr client, - Mask access_mode, - int *xkb_err -); - -extern _X_EXPORT int _XkbLookupKeyboard( - DeviceIntPtr *pDev, - int id, - ClientPtr client, - Mask access_mode, - int *xkb_err -); - -extern _X_EXPORT int _XkbLookupBellDevice( - DeviceIntPtr *pDev, - int id, - ClientPtr client, - Mask access_mode, - int *xkb_err -); - -extern _X_EXPORT int _XkbLookupLedDevice( - DeviceIntPtr *pDev, - int id, - ClientPtr client, - Mask access_mode, - int *xkb_err -); - -extern _X_EXPORT int _XkbLookupButtonDevice( - DeviceIntPtr *pDev, - int id, - ClientPtr client, - Mask access_mode, - int *xkb_err -); - -extern _X_EXPORT XkbDescPtr XkbAllocKeyboard( - void -); - -extern _X_EXPORT Status XkbAllocClientMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - unsigned int /* nTypes */ -); - -extern _X_EXPORT Status XkbAllocServerMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - unsigned int /* nNewActions */ -); - -extern _X_EXPORT void XkbFreeClientMap( - XkbDescPtr /* xkb */, - unsigned int /* what */, - Bool /* freeMap */ -); - -extern _X_EXPORT void XkbFreeServerMap( - XkbDescPtr /* xkb */, - unsigned int /* what */, - Bool /* freeMap */ -); - -extern _X_EXPORT Status XkbAllocIndicatorMaps( - XkbDescPtr /* xkb */ -); - -extern _X_EXPORT Status XkbAllocCompatMap( - XkbDescPtr /* xkb */, - unsigned int /* which */, - unsigned int /* nInterpret */ -); - -extern _X_EXPORT Status XkbAllocNames( - XkbDescPtr /* xkb */, - unsigned int /* which */, - int /* nTotalRG */, - int /* nTotalAliases */ -); - -extern _X_EXPORT Status XkbAllocControls( - XkbDescPtr /* xkb */, - unsigned int /* which*/ -); - -extern _X_EXPORT Status XkbCopyKeyTypes( - XkbKeyTypePtr /* from */, - XkbKeyTypePtr /* into */, - int /* num_types */ -); - -extern _X_EXPORT Status XkbResizeKeyType( - XkbDescPtr /* xkb */, - int /* type_ndx */, - int /* map_count */, - Bool /* want_preserve */, - int /* new_num_lvls */ -); - -extern _X_EXPORT void XkbFreeKeyboard( - XkbDescPtr /* xkb */, - unsigned int /* which */, - Bool /* freeDesc */ -); - -extern _X_EXPORT void XkbSetActionKeyMods( - XkbDescPtr /* xkb */, - XkbAction * /* act */, - unsigned int /* mods */ -); - -extern _X_EXPORT unsigned int XkbMaskForVMask( - XkbDescPtr /* xkb */, - unsigned int /* vmask */ -); - -extern _X_EXPORT Bool XkbVirtualModsToReal( - XkbDescPtr /* xkb */, - unsigned int /* virtua_mask */, - unsigned int * /* mask_rtrn */ -); - -extern _X_EXPORT unsigned int XkbAdjustGroup( - int /* group */, - XkbControlsPtr /* ctrls */ -); - -extern _X_EXPORT KeySym *XkbResizeKeySyms( - XkbDescPtr /* xkb */, - int /* key */, - int /* needed */ -); - -extern _X_EXPORT XkbAction *XkbResizeKeyActions( - XkbDescPtr /* xkb */, - int /* key */, - int /* needed */ -); - -extern _X_EXPORT void XkbUpdateKeyTypesFromCore( - DeviceIntPtr /* pXDev */, - KeySymsPtr /* syms */, - KeyCode /* first */, - CARD8 /* num */, - XkbChangesPtr /* pChanges */ -); - -extern _X_EXPORT void XkbUpdateDescActions( - XkbDescPtr /* xkb */, - KeyCode /* first */, - CARD8 /* num */, - XkbChangesPtr /* changes */ -); - -extern _X_EXPORT void XkbUpdateActions( - DeviceIntPtr /* pXDev */, - KeyCode /* first */, - CARD8 /* num */, - XkbChangesPtr /* pChanges */, - unsigned int * /* needChecksRtrn */, - XkbEventCausePtr /* cause */ -); - -extern _X_EXPORT KeySymsPtr XkbGetCoreMap( - DeviceIntPtr /* keybd */ -); - -extern _X_EXPORT void XkbApplyMappingChange( - DeviceIntPtr /* pXDev */, - KeySymsPtr /* map */, - KeyCode /* firstKey */, - CARD8 /* num */, - CARD8 * /* modmap */, - ClientPtr /* client */ -); - -extern _X_EXPORT void XkbSetIndicators( - DeviceIntPtr /* pXDev */, - CARD32 /* affect */, - CARD32 /* values */, - XkbEventCausePtr /* cause */ -); - -extern _X_EXPORT void XkbUpdateIndicators( - DeviceIntPtr /* keybd */, - CARD32 /* changed */, - Bool /* check_edevs */, - XkbChangesPtr /* pChanges */, - XkbEventCausePtr /* cause */ -); - -extern _X_EXPORT XkbSrvLedInfoPtr XkbAllocSrvLedInfo( - DeviceIntPtr /* dev */, - KbdFeedbackPtr /* kf */, - LedFeedbackPtr /* lf */, - unsigned int /* needed_parts */ -); - -extern _X_EXPORT XkbSrvLedInfoPtr XkbCopySrvLedInfo( - DeviceIntPtr /* dev */, - XkbSrvLedInfoPtr /* src */, - KbdFeedbackPtr /* kf */, - LedFeedbackPtr /* lf */ -); - - -extern _X_EXPORT XkbSrvLedInfoPtr XkbFindSrvLedInfo( - DeviceIntPtr /* dev */, - unsigned int /* class */, - unsigned int /* id */, - unsigned int /* needed_parts */ -); - -extern _X_EXPORT void XkbApplyLedNameChanges( - DeviceIntPtr /* dev */, - XkbSrvLedInfoPtr /* sli */, - unsigned int /* changed_names */, - xkbExtensionDeviceNotify * /* ed */, - XkbChangesPtr /* changes */, - XkbEventCausePtr /* cause */ -); - -extern _X_EXPORT void XkbApplyLedMapChanges( - DeviceIntPtr /* dev */, - XkbSrvLedInfoPtr /* sli */, - unsigned int /* changed_maps */, - xkbExtensionDeviceNotify * /* ed */, - XkbChangesPtr /* changes */, - XkbEventCausePtr /* cause */ -); - -extern _X_EXPORT void XkbApplyLedStateChanges( - DeviceIntPtr /* dev */, - XkbSrvLedInfoPtr /* sli */, - unsigned int /* changed_leds */, - xkbExtensionDeviceNotify * /* ed */, - XkbChangesPtr /* changes */, - XkbEventCausePtr /* cause */ -); - -extern _X_EXPORT void XkbFlushLedEvents( - DeviceIntPtr /* dev */, - DeviceIntPtr /* kbd */, - XkbSrvLedInfoPtr /* sli */, - xkbExtensionDeviceNotify * /* ed */, - XkbChangesPtr /* changes */, - XkbEventCausePtr /* cause */ -); - -extern _X_EXPORT unsigned int XkbIndicatorsToUpdate( - DeviceIntPtr /* dev */, - unsigned long /* state_changes */, - Bool /* enabled_ctrl_changes */ -); - -extern _X_EXPORT void XkbComputeDerivedState( - XkbSrvInfoPtr /* xkbi */ -); - -extern _X_EXPORT void XkbCheckSecondaryEffects( - XkbSrvInfoPtr /* xkbi */, - unsigned int /* which */, - XkbChangesPtr /* changes */, - XkbEventCausePtr /* cause */ -); - -extern _X_EXPORT void XkbCheckIndicatorMaps( - DeviceIntPtr /* dev */, - XkbSrvLedInfoPtr /* sli */, - unsigned int /* which */ -); - -extern _X_EXPORT unsigned int XkbStateChangedFlags( - XkbStatePtr /* old */, - XkbStatePtr /* new */ -); - -extern _X_EXPORT void XkbSendStateNotify( - DeviceIntPtr /* kbd */, - xkbStateNotify * /* pSN */ -); - -extern _X_EXPORT void XkbSendMapNotify( - DeviceIntPtr /* kbd */, - xkbMapNotify * /* ev */ -); - -extern _X_EXPORT int XkbComputeControlsNotify( - DeviceIntPtr /* kbd */, - XkbControlsPtr /* old */, - XkbControlsPtr /* new */, - xkbControlsNotify * /* pCN */, - Bool /* forceCtrlProc */ -); - -extern _X_EXPORT void XkbSendControlsNotify( - DeviceIntPtr /* kbd */, - xkbControlsNotify * /* ev */ -); - -extern _X_EXPORT void XkbSendCompatMapNotify( - DeviceIntPtr /* kbd */, - xkbCompatMapNotify * /* ev */ -); - -extern _X_EXPORT void XkbHandleBell( - BOOL /* force */, - BOOL /* eventOnly */, - DeviceIntPtr /* kbd */, - CARD8 /* percent */, - pointer /* ctrl */, - CARD8 /* class */, - Atom /* name */, - WindowPtr /* pWin */, - ClientPtr /* pClient */ -); - -extern _X_EXPORT void XkbSendAccessXNotify( - DeviceIntPtr /* kbd */, - xkbAccessXNotify * /* pEv */ -); - -extern _X_EXPORT void XkbSendNamesNotify( - DeviceIntPtr /* kbd */, - xkbNamesNotify * /* ev */ -); - -extern _X_EXPORT void XkbSendActionMessage( - DeviceIntPtr /* kbd */, - xkbActionMessage * /* ev */ -); - -extern _X_EXPORT void XkbSendExtensionDeviceNotify( - DeviceIntPtr /* kbd */, - ClientPtr /* client */, - xkbExtensionDeviceNotify * /* ev */ -); - -extern _X_EXPORT void XkbSendNotification( - DeviceIntPtr /* kbd */, - XkbChangesPtr /* pChanges */, - XkbEventCausePtr /* cause */ -); - -extern _X_EXPORT void XkbProcessKeyboardEvent( - DeviceEvent* /* event */, - DeviceIntPtr /* keybd */ -); - -extern _X_EXPORT void XkbHandleActions( - DeviceIntPtr /* dev */, - DeviceIntPtr /* kbd */, - DeviceEvent* /* event */ -); - -extern _X_EXPORT Bool XkbEnableDisableControls( - XkbSrvInfoPtr /* xkbi */, - unsigned long /* change */, - unsigned long /* newValues */, - XkbChangesPtr /* changes */, - XkbEventCausePtr /* cause */ -); - -extern _X_EXPORT void AccessXInit( - DeviceIntPtr /* dev */ -); - -extern _X_EXPORT Bool AccessXFilterPressEvent( - DeviceEvent* /* event */, - DeviceIntPtr /* keybd */ -); - -extern _X_EXPORT Bool AccessXFilterReleaseEvent( - DeviceEvent* /* event */, - DeviceIntPtr /* keybd */ -); - -extern _X_EXPORT void AccessXCancelRepeatKey( - XkbSrvInfoPtr /* xkbi */, - KeyCode /* key */ -); - -extern _X_EXPORT void AccessXComputeCurveFactor( - XkbSrvInfoPtr /* xkbi */, - XkbControlsPtr /* ctrls */ -); - -extern _X_EXPORT XkbInterestPtr XkbFindClientResource( - DevicePtr /* inDev */, - ClientPtr /* client */ -); - -extern _X_EXPORT XkbInterestPtr XkbAddClientResource( - DevicePtr /* inDev */, - ClientPtr /* client */, - XID /* id */ -); - -extern _X_EXPORT int XkbRemoveResourceClient( - DevicePtr /* inDev */, - XID /* id */ -); - -extern _X_EXPORT int XkbDDXAccessXBeep( - DeviceIntPtr /* dev */, - unsigned int /* what */, - unsigned int /* which */ -); - -extern _X_EXPORT int XkbDDXUsesSoftRepeat( - DeviceIntPtr /* dev */ -); - -extern _X_EXPORT void XkbDDXKeybdCtrlProc( - DeviceIntPtr /* dev */, - KeybdCtrl * /* ctrl */ -); - -extern _X_EXPORT void XkbDDXChangeControls( - DeviceIntPtr /* dev */, - XkbControlsPtr /* old */, - XkbControlsPtr /* new */ -); - -extern _X_EXPORT void XkbDDXUpdateDeviceIndicators( - DeviceIntPtr /* dev */, - XkbSrvLedInfoPtr /* sli */, - CARD32 /* newState */ -); - -extern _X_EXPORT void XkbDDXFakePointerMotion( - unsigned int /* flags */, - int /* x */, - int /* y */ -); - -extern _X_EXPORT void XkbDDXFakeDeviceButton( - DeviceIntPtr /* dev */, - Bool /* press */, - int /* button */ -); - -extern _X_EXPORT int XkbDDXTerminateServer( - DeviceIntPtr /* dev */, - KeyCode /* key */, - XkbAction * /* act */ -); - -extern _X_EXPORT int XkbDDXSwitchScreen( - DeviceIntPtr /* dev */, - KeyCode /* key */, - XkbAction * /* act */ -); - -extern _X_EXPORT int XkbDDXPrivate( - DeviceIntPtr /* dev */, - KeyCode /* key */, - XkbAction * /* act */ -); - -extern _X_EXPORT void XkbDisableComputedAutoRepeats( - DeviceIntPtr /* pXDev */, - unsigned int /* key */ -); - -extern _X_EXPORT void XkbSetRepeatKeys( - DeviceIntPtr /* pXDev */, - int /* key */, - int /* onoff */ -); - -extern _X_EXPORT int XkbLatchModifiers( - DeviceIntPtr /* pXDev */, - CARD8 /* mask */, - CARD8 /* latches */ -); - -extern _X_EXPORT int XkbLatchGroup( - DeviceIntPtr /* pXDev */, - int /* group */ -); - -extern _X_EXPORT void XkbClearAllLatchesAndLocks( - DeviceIntPtr /* dev */, - XkbSrvInfoPtr /* xkbi */, - Bool /* genEv */, - XkbEventCausePtr /* cause */ -); - -extern _X_EXPORT void XkbGetRulesDflts( - XkbRMLVOSet * /* rmlvo */ -); - -extern _X_EXPORT void XkbFreeRMLVOSet( - XkbRMLVOSet * /* rmlvo */, - Bool /* freeRMLVO */ -); - -extern _X_EXPORT void XkbSetRulesDflts( - XkbRMLVOSet * /* rmlvo */ -); - -extern _X_EXPORT void XkbDeleteRulesDflts( - void -); - -extern _X_EXPORT int SProcXkbDispatch( - ClientPtr /* client */ -); - -extern _X_EXPORT XkbGeometryPtr XkbLookupNamedGeometry( - DeviceIntPtr /* dev */, - Atom /* name */, - Bool * /* shouldFree */ -); - -extern _X_EXPORT char * _XkbDupString( - const char * /* str */ -); - -extern _X_EXPORT void XkbConvertCase( - KeySym /* sym */, - KeySym * /* lower */, - KeySym * /* upper */ -); - -extern _X_EXPORT Status XkbChangeKeycodeRange( - XkbDescPtr /* xkb */, - int /* minKC */, - int /* maxKC */, - XkbChangesPtr /* changes */ -); - -extern _X_EXPORT void XkbFreeSrvLedInfo( - XkbSrvLedInfoPtr /* sli */ -); - -extern _X_EXPORT void XkbFreeInfo( - XkbSrvInfoPtr /* xkbi */ -); - -extern _X_EXPORT Status XkbChangeTypesOfKey( - XkbDescPtr /* xkb */, - int /* key */, - int /* nGroups */, - unsigned int /* groups */, - int * /* newTypesIn */, - XkbMapChangesPtr /* changes */ -); - -extern _X_EXPORT int XkbKeyTypesForCoreSymbols( - XkbDescPtr /* xkb */, - int /* map_width */, - KeySym * /* core_syms */, - unsigned int /* protected */, - int * /* types_inout */, - KeySym * /* xkb_syms_rtrn */ -); - -extern _X_EXPORT Bool XkbApplyCompatMapToKey( - XkbDescPtr /* xkb */, - KeyCode /* key */, - XkbChangesPtr /* changes */ -); - -extern _X_EXPORT Bool XkbApplyVirtualModChanges( - XkbDescPtr /* xkb */, - unsigned int /* changed */, - XkbChangesPtr /* changes */ -); - -extern _X_EXPORT void XkbSendNewKeyboardNotify( - DeviceIntPtr /* kbd */, - xkbNewKeyboardNotify * /* pNKN */ -); - -extern Bool XkbCopyKeymap( - XkbDescPtr /* dst */, - XkbDescPtr /* src */); - -extern Bool XkbCopyDeviceKeymap( - DeviceIntPtr /* dst */, - DeviceIntPtr /* src */); - -extern void XkbFilterEvents( - ClientPtr /* pClient */, - int /* nEvents */, - xEvent* /* xE */); - -extern int XkbGetEffectiveGroup( - XkbSrvInfoPtr /* xkbi */, - XkbStatePtr /* xkbstate */, - CARD8 /* keycode */); - -#include "xkbfile.h" -#include "xkbrules.h" - -#define _XkbListKeycodes 0 -#define _XkbListTypes 1 -#define _XkbListCompat 2 -#define _XkbListSymbols 3 -#define _XkbListGeometry 4 -#define _XkbListNumComponents 5 - -typedef struct _XkbSrvListInfo { - int szPool; - int nPool; - char * pool; - - int maxRtrn; - int nTotal; - - char * pattern[_XkbListNumComponents]; - int nFound[_XkbListNumComponents]; -} XkbSrvListInfoRec,*XkbSrvListInfoPtr; - -extern _X_EXPORT Status XkbDDXList( - DeviceIntPtr /* dev */, - XkbSrvListInfoPtr /* listing */, - ClientPtr /* client */ -); - -extern _X_EXPORT unsigned int XkbDDXLoadKeymapByNames( - DeviceIntPtr /* keybd */, - XkbComponentNamesPtr /* names */, - unsigned int /* want */, - unsigned int /* need */, - XkbDescPtr * /* finfoRtrn */, - char * /* keymapNameRtrn */, - int /* keymapNameRtrnLen */ -); - -extern _X_EXPORT Bool XkbDDXNamesFromRules( - DeviceIntPtr /* keybd */, - char * /* rules */, - XkbRF_VarDefsPtr /* defs */, - XkbComponentNamesPtr /* names */ -); - -extern _X_EXPORT XkbDescPtr XkbCompileKeymap( - DeviceIntPtr /* dev */, - XkbRMLVOSet * /* rmlvo */ -); - -#endif /* _XKBSRV_H_ */ +/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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 _XKBSRV_H_
+#define _XKBSRV_H_
+
+#define XkbAllocClientMap SrvXkbAllocClientMap
+#define XkbAllocServerMap SrvXkbAllocServerMap
+#define XkbChangeTypesOfKey SrvXkbChangeTypesOfKey
+#define XkbCopyKeyTypes SrvXkbCopyKeyTypes
+#define XkbFreeClientMap SrvXkbFreeClientMap
+#define XkbFreeServerMap SrvXkbFreeServerMap
+#define XkbKeyTypesForCoreSymbols SrvXkbKeyTypesForCoreSymbols
+#define XkbApplyCompatMapToKey SrvXkbApplyCompatMapToKey
+#define XkbResizeKeyActions SrvXkbResizeKeyActions
+#define XkbResizeKeySyms SrvXkbResizeKeySyms
+#define XkbResizeKeyType SrvXkbResizeKeyType
+#define XkbAllocCompatMap SrvXkbAllocCompatMap
+#define XkbAllocControls SrvXkbAllocControls
+#define XkbAllocIndicatorMaps SrvXkbAllocIndicatorMaps
+#define XkbAllocKeyboard SrvXkbAllocKeyboard
+#define XkbAllocNames SrvXkbAllocNames
+#define XkbFreeCompatMap SrvXkbFreeCompatMap
+#define XkbFreeKeyboard SrvXkbFreeKeyboard
+#define XkbFreeNames SrvXkbFreeNames
+#define XkbLatchModifiers SrvXkbLatchModifiers
+#define XkbLatchGroup SrvXkbLatchGroup
+#define XkbVirtualModsToReal SrvXkbVirtualModsToReal
+#define XkbChangeKeycodeRange SrvXkbChangeKeycodeRange
+#define XkbApplyVirtualModChanges SrvXkbApplyVirtualModChanges
+
+#include <X11/extensions/XKBproto.h>
+#include "xkbstr.h"
+#include "xkbrules.h"
+#include "inputstr.h"
+#include "events.h"
+
+typedef struct _XkbInterest {
+ DeviceIntPtr dev;
+ ClientPtr client;
+ XID resource;
+ struct _XkbInterest * next;
+ CARD16 extDevNotifyMask;
+ CARD16 stateNotifyMask;
+ CARD16 namesNotifyMask;
+ CARD32 ctrlsNotifyMask;
+ CARD8 compatNotifyMask;
+ BOOL bellNotifyMask;
+ BOOL actionMessageMask;
+ CARD16 accessXNotifyMask;
+ CARD32 iStateNotifyMask;
+ CARD32 iMapNotifyMask;
+ CARD16 altSymsNotifyMask;
+ CARD32 autoCtrls;
+ CARD32 autoCtrlValues;
+} XkbInterestRec,*XkbInterestPtr;
+
+typedef struct _XkbRadioGroup {
+ CARD8 flags;
+ CARD8 nMembers;
+ CARD8 dfltDown;
+ CARD8 currentDown;
+ CARD8 members[XkbRGMaxMembers];
+} XkbRadioGroupRec, *XkbRadioGroupPtr;
+
+typedef struct _XkbEventCause {
+ CARD8 kc;
+ CARD8 event;
+ CARD8 mjr;
+ CARD8 mnr;
+ ClientPtr client;
+} XkbEventCauseRec,*XkbEventCausePtr;
+#define XkbSetCauseKey(c,k,e) { (c)->kc= (k),(c)->event= (e),\
+ (c)->mjr= (c)->mnr= 0; \
+ (c)->client= NULL; }
+#define XkbSetCauseReq(c,j,n,cl) { (c)->kc= (c)->event= 0,\
+ (c)->mjr= (j),(c)->mnr= (n);\
+ (c)->client= (cl); }
+#define XkbSetCauseCoreReq(c,e,cl) XkbSetCauseReq(c,e,0,cl)
+#define XkbSetCauseXkbReq(c,e,cl) XkbSetCauseReq(c,XkbReqCode,e,cl)
+#define XkbSetCauseUnknown(c) XkbSetCauseKey(c,0,0)
+
+#define _OFF_TIMER 0
+#define _KRG_WARN_TIMER 1
+#define _KRG_TIMER 2
+#define _SK_TIMEOUT_TIMER 3
+#define _ALL_TIMEOUT_TIMER 4
+
+#define _BEEP_NONE 0
+#define _BEEP_FEATURE_ON 1
+#define _BEEP_FEATURE_OFF 2
+#define _BEEP_FEATURE_CHANGE 3
+#define _BEEP_SLOW_WARN 4
+#define _BEEP_SLOW_PRESS 5
+#define _BEEP_SLOW_ACCEPT 6
+#define _BEEP_SLOW_REJECT 7
+#define _BEEP_SLOW_RELEASE 8
+#define _BEEP_STICKY_LATCH 9
+#define _BEEP_STICKY_LOCK 10
+#define _BEEP_STICKY_UNLOCK 11
+#define _BEEP_LED_ON 12
+#define _BEEP_LED_OFF 13
+#define _BEEP_LED_CHANGE 14
+#define _BEEP_BOUNCE_REJECT 15
+
+typedef struct _XkbFilter {
+ CARD16 keycode;
+ CARD8 what;
+ CARD8 active;
+ CARD8 filterOthers;
+ CARD32 priv;
+ XkbAction upAction;
+ int (*filter)(
+ struct _XkbSrvInfo* /* xkbi */,
+ struct _XkbFilter * /* filter */,
+ unsigned /* keycode */,
+ XkbAction * /* action */
+ );
+ struct _XkbFilter *next;
+} XkbFilterRec,*XkbFilterPtr;
+
+typedef struct _XkbSrvInfo {
+ XkbStateRec prev_state;
+ XkbStateRec state;
+ XkbDescPtr desc;
+
+ DeviceIntPtr device;
+ KbdCtrlProcPtr kbdProc;
+
+ XkbRadioGroupPtr radioGroups;
+ CARD8 nRadioGroups;
+ CARD8 clearMods;
+ CARD8 setMods;
+ INT16 groupChange;
+
+ CARD16 dfltPtrDelta;
+
+ double mouseKeysCurve;
+ double mouseKeysCurveFactor;
+ INT16 mouseKeysDX;
+ INT16 mouseKeysDY;
+ CARD8 mouseKeysFlags;
+ Bool mouseKeysAccel;
+ CARD8 mouseKeysCounter;
+
+ CARD8 lockedPtrButtons;
+ CARD8 shiftKeyCount;
+ KeyCode mouseKey;
+ KeyCode inactiveKey;
+ KeyCode slowKey;
+ KeyCode repeatKey;
+ CARD8 krgTimerActive;
+ CARD8 beepType;
+ CARD8 beepCount;
+
+ CARD32 flags;
+ CARD32 lastPtrEventTime;
+ CARD32 lastShiftEventTime;
+ OsTimerPtr beepTimer;
+ OsTimerPtr mouseKeyTimer;
+ OsTimerPtr slowKeysTimer;
+ OsTimerPtr bounceKeysTimer;
+ OsTimerPtr repeatKeyTimer;
+ OsTimerPtr krgTimer;
+
+ int szFilters;
+ XkbFilterPtr filters;
+} XkbSrvInfoRec, *XkbSrvInfoPtr;
+
+#define XkbSLI_IsDefault (1L<<0)
+#define XkbSLI_HasOwnState (1L<<1)
+
+typedef struct _XkbSrvLedInfo {
+ CARD16 flags;
+ CARD16 class;
+ CARD16 id;
+ union {
+ KbdFeedbackPtr kf;
+ LedFeedbackPtr lf;
+ } fb;
+
+ CARD32 physIndicators;
+ CARD32 autoState;
+ CARD32 explicitState;
+ CARD32 effectiveState;
+
+ CARD32 mapsPresent;
+ CARD32 namesPresent;
+ XkbIndicatorMapPtr maps;
+ Atom * names;
+
+ CARD32 usesBase;
+ CARD32 usesLatched;
+ CARD32 usesLocked;
+ CARD32 usesEffective;
+ CARD32 usesCompat;
+ CARD32 usesControls;
+
+ CARD32 usedComponents;
+} XkbSrvLedInfoRec, *XkbSrvLedInfoPtr;
+
+/*
+ * Settings for xkbClientFlags field (used by DIX)
+ * These flags _must_ not overlap with XkbPCF_*
+ */
+#define _XkbClientInitialized (1<<15)
+
+#define _XkbWantsDetectableAutoRepeat(c)\
+ ((c)->xkbClientFlags&XkbPCF_DetectableAutoRepeatMask)
+
+/*
+ * Settings for flags field
+ */
+#define _XkbStateNotifyInProgress (1<<0)
+
+typedef struct
+{
+ ProcessInputProc processInputProc;
+ /* If processInputProc is set to something different than realInputProc,
+ * UNWRAP and COND_WRAP will not touch processInputProc and update only
+ * realInputProc. This ensures that
+ * processInputProc == (frozen ? EnqueueEvent : realInputProc)
+ *
+ * WRAP_PROCESS_INPUT_PROC should only be called during initialization,
+ * since it may destroy this invariant.
+ */
+ ProcessInputProc realInputProc;
+ DeviceUnwrapProc unwrapProc;
+} xkbDeviceInfoRec, *xkbDeviceInfoPtr;
+
+#define WRAP_PROCESS_INPUT_PROC(device, oldprocs, proc, unwrapproc) \
+ device->public.processInputProc = proc; \
+ oldprocs->processInputProc = \
+ oldprocs->realInputProc = device->public.realInputProc; \
+ device->public.realInputProc = proc; \
+ oldprocs->unwrapProc = device->unwrapProc; \
+ device->unwrapProc = unwrapproc;
+
+#define COND_WRAP_PROCESS_INPUT_PROC(device, oldprocs, proc, unwrapproc) \
+ if (device->public.processInputProc == device->public.realInputProc)\
+ device->public.processInputProc = proc; \
+ oldprocs->processInputProc = \
+ oldprocs->realInputProc = device->public.realInputProc; \
+ device->public.realInputProc = proc; \
+ oldprocs->unwrapProc = device->unwrapProc; \
+ device->unwrapProc = unwrapproc;
+
+#define UNWRAP_PROCESS_INPUT_PROC(device, oldprocs, backupproc) \
+ backupproc = device->public.realInputProc; \
+ if (device->public.processInputProc == device->public.realInputProc)\
+ device->public.processInputProc = oldprocs->realInputProc; \
+ device->public.realInputProc = oldprocs->realInputProc; \
+ device->unwrapProc = oldprocs->unwrapProc;
+
+extern DevPrivateKey xkbDevicePrivateKey;
+#define XKBDEVICEINFO(dev) ((xkbDeviceInfoPtr)dixLookupPrivate(&(dev)->devPrivates, xkbDevicePrivateKey))
+
+extern void xkbUnwrapProc(DeviceIntPtr, DeviceHandleProc, pointer);
+
+/***====================================================================***/
+
+
+/***====================================================================***/
+
+#define XkbAX_KRGMask (XkbSlowKeysMask|XkbBounceKeysMask)
+#define XkbAllFilteredEventsMask \
+ (XkbAccessXKeysMask|XkbRepeatKeysMask|XkbMouseKeysAccelMask|XkbAX_KRGMask)
+
+/***====================================================================***/
+
+extern _X_EXPORT int XkbReqCode;
+extern _X_EXPORT int XkbEventBase;
+extern _X_EXPORT int XkbKeyboardErrorCode;
+extern _X_EXPORT const char * XkbBaseDirectory;
+extern _X_EXPORT const char * XkbBinDirectory;
+
+extern _X_EXPORT CARD32 xkbDebugFlags;
+
+#define _XkbLibError(c,l,d) /* Epoch fail */
+#define _XkbErrCode2(a,b) ((XID)((((unsigned int)(a))<<24)|((b)&0xffffff)))
+#define _XkbErrCode3(a,b,c) _XkbErrCode2(a,(((unsigned int)(b))<<16)|(c))
+#define _XkbErrCode4(a,b,c,d) _XkbErrCode3(a,b,((((unsigned int)(c))<<8)|(d)))
+
+extern _X_EXPORT int DeviceKeyPress,DeviceKeyRelease,DeviceMotionNotify;
+extern _X_EXPORT int DeviceButtonPress,DeviceButtonRelease;
+
+#define Status int
+
+extern _X_EXPORT void XkbUseMsg(
+ void
+);
+
+extern _X_EXPORT int XkbProcessArguments(
+ int /* argc */,
+ char ** /* argv */,
+ int /* i */
+);
+
+extern _X_EXPORT void XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc);
+
+extern _X_EXPORT void XkbFreeCompatMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ Bool /* freeMap */
+);
+
+extern _X_EXPORT void XkbFreeNames(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ Bool /* freeMap */
+);
+
+extern _X_EXPORT int _XkbLookupAnyDevice(
+ DeviceIntPtr *pDev,
+ int id,
+ ClientPtr client,
+ Mask access_mode,
+ int *xkb_err
+);
+
+extern _X_EXPORT int _XkbLookupKeyboard(
+ DeviceIntPtr *pDev,
+ int id,
+ ClientPtr client,
+ Mask access_mode,
+ int *xkb_err
+);
+
+extern _X_EXPORT int _XkbLookupBellDevice(
+ DeviceIntPtr *pDev,
+ int id,
+ ClientPtr client,
+ Mask access_mode,
+ int *xkb_err
+);
+
+extern _X_EXPORT int _XkbLookupLedDevice(
+ DeviceIntPtr *pDev,
+ int id,
+ ClientPtr client,
+ Mask access_mode,
+ int *xkb_err
+);
+
+extern _X_EXPORT int _XkbLookupButtonDevice(
+ DeviceIntPtr *pDev,
+ int id,
+ ClientPtr client,
+ Mask access_mode,
+ int *xkb_err
+);
+
+extern _X_EXPORT XkbDescPtr XkbAllocKeyboard(
+ void
+);
+
+extern _X_EXPORT Status XkbAllocClientMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ unsigned int /* nTypes */
+);
+
+extern _X_EXPORT Status XkbAllocServerMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ unsigned int /* nNewActions */
+);
+
+extern _X_EXPORT void XkbFreeClientMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* what */,
+ Bool /* freeMap */
+);
+
+extern _X_EXPORT void XkbFreeServerMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* what */,
+ Bool /* freeMap */
+);
+
+extern _X_EXPORT Status XkbAllocIndicatorMaps(
+ XkbDescPtr /* xkb */
+);
+
+extern _X_EXPORT Status XkbAllocCompatMap(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ unsigned int /* nInterpret */
+);
+
+extern _X_EXPORT Status XkbAllocNames(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ int /* nTotalRG */,
+ int /* nTotalAliases */
+);
+
+extern _X_EXPORT Status XkbAllocControls(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which*/
+);
+
+extern _X_EXPORT Status XkbCopyKeyTypes(
+ XkbKeyTypePtr /* from */,
+ XkbKeyTypePtr /* into */,
+ int /* num_types */
+);
+
+extern _X_EXPORT Status XkbResizeKeyType(
+ XkbDescPtr /* xkb */,
+ int /* type_ndx */,
+ int /* map_count */,
+ Bool /* want_preserve */,
+ int /* new_num_lvls */
+);
+
+extern _X_EXPORT void XkbFreeKeyboard(
+ XkbDescPtr /* xkb */,
+ unsigned int /* which */,
+ Bool /* freeDesc */
+);
+
+extern _X_EXPORT void XkbSetActionKeyMods(
+ XkbDescPtr /* xkb */,
+ XkbAction * /* act */,
+ unsigned int /* mods */
+);
+
+extern _X_EXPORT unsigned int XkbMaskForVMask(
+ XkbDescPtr /* xkb */,
+ unsigned int /* vmask */
+);
+
+extern _X_EXPORT Bool XkbVirtualModsToReal(
+ XkbDescPtr /* xkb */,
+ unsigned int /* virtua_mask */,
+ unsigned int * /* mask_rtrn */
+);
+
+extern _X_EXPORT unsigned int XkbAdjustGroup(
+ int /* group */,
+ XkbControlsPtr /* ctrls */
+);
+
+extern _X_EXPORT KeySym *XkbResizeKeySyms(
+ XkbDescPtr /* xkb */,
+ int /* key */,
+ int /* needed */
+);
+
+extern _X_EXPORT XkbAction *XkbResizeKeyActions(
+ XkbDescPtr /* xkb */,
+ int /* key */,
+ int /* needed */
+);
+
+extern _X_EXPORT void XkbUpdateKeyTypesFromCore(
+ DeviceIntPtr /* pXDev */,
+ KeySymsPtr /* syms */,
+ KeyCode /* first */,
+ CARD8 /* num */,
+ XkbChangesPtr /* pChanges */
+);
+
+extern _X_EXPORT void XkbUpdateDescActions(
+ XkbDescPtr /* xkb */,
+ KeyCode /* first */,
+ CARD8 /* num */,
+ XkbChangesPtr /* changes */
+);
+
+extern _X_EXPORT void XkbUpdateActions(
+ DeviceIntPtr /* pXDev */,
+ KeyCode /* first */,
+ CARD8 /* num */,
+ XkbChangesPtr /* pChanges */,
+ unsigned int * /* needChecksRtrn */,
+ XkbEventCausePtr /* cause */
+);
+
+extern _X_EXPORT KeySymsPtr XkbGetCoreMap(
+ DeviceIntPtr /* keybd */
+);
+
+extern _X_EXPORT void XkbApplyMappingChange(
+ DeviceIntPtr /* pXDev */,
+ KeySymsPtr /* map */,
+ KeyCode /* firstKey */,
+ CARD8 /* num */,
+ CARD8 * /* modmap */,
+ ClientPtr /* client */
+);
+
+extern _X_EXPORT void XkbSetIndicators(
+ DeviceIntPtr /* pXDev */,
+ CARD32 /* affect */,
+ CARD32 /* values */,
+ XkbEventCausePtr /* cause */
+);
+
+extern _X_EXPORT void XkbUpdateIndicators(
+ DeviceIntPtr /* keybd */,
+ CARD32 /* changed */,
+ Bool /* check_edevs */,
+ XkbChangesPtr /* pChanges */,
+ XkbEventCausePtr /* cause */
+);
+
+extern _X_EXPORT XkbSrvLedInfoPtr XkbAllocSrvLedInfo(
+ DeviceIntPtr /* dev */,
+ KbdFeedbackPtr /* kf */,
+ LedFeedbackPtr /* lf */,
+ unsigned int /* needed_parts */
+);
+
+extern _X_EXPORT XkbSrvLedInfoPtr XkbCopySrvLedInfo(
+ DeviceIntPtr /* dev */,
+ XkbSrvLedInfoPtr /* src */,
+ KbdFeedbackPtr /* kf */,
+ LedFeedbackPtr /* lf */
+);
+
+
+extern _X_EXPORT XkbSrvLedInfoPtr XkbFindSrvLedInfo(
+ DeviceIntPtr /* dev */,
+ unsigned int /* class */,
+ unsigned int /* id */,
+ unsigned int /* needed_parts */
+);
+
+extern _X_EXPORT void XkbApplyLedNameChanges(
+ DeviceIntPtr /* dev */,
+ XkbSrvLedInfoPtr /* sli */,
+ unsigned int /* changed_names */,
+ xkbExtensionDeviceNotify * /* ed */,
+ XkbChangesPtr /* changes */,
+ XkbEventCausePtr /* cause */
+);
+
+extern _X_EXPORT void XkbApplyLedMapChanges(
+ DeviceIntPtr /* dev */,
+ XkbSrvLedInfoPtr /* sli */,
+ unsigned int /* changed_maps */,
+ xkbExtensionDeviceNotify * /* ed */,
+ XkbChangesPtr /* changes */,
+ XkbEventCausePtr /* cause */
+);
+
+extern _X_EXPORT void XkbApplyLedStateChanges(
+ DeviceIntPtr /* dev */,
+ XkbSrvLedInfoPtr /* sli */,
+ unsigned int /* changed_leds */,
+ xkbExtensionDeviceNotify * /* ed */,
+ XkbChangesPtr /* changes */,
+ XkbEventCausePtr /* cause */
+);
+
+extern _X_EXPORT void XkbFlushLedEvents(
+ DeviceIntPtr /* dev */,
+ DeviceIntPtr /* kbd */,
+ XkbSrvLedInfoPtr /* sli */,
+ xkbExtensionDeviceNotify * /* ed */,
+ XkbChangesPtr /* changes */,
+ XkbEventCausePtr /* cause */
+);
+
+extern _X_EXPORT unsigned int XkbIndicatorsToUpdate(
+ DeviceIntPtr /* dev */,
+ unsigned long /* state_changes */,
+ Bool /* enabled_ctrl_changes */
+);
+
+extern _X_EXPORT void XkbComputeDerivedState(
+ XkbSrvInfoPtr /* xkbi */
+);
+
+extern _X_EXPORT void XkbCheckSecondaryEffects(
+ XkbSrvInfoPtr /* xkbi */,
+ unsigned int /* which */,
+ XkbChangesPtr /* changes */,
+ XkbEventCausePtr /* cause */
+);
+
+extern _X_EXPORT void XkbCheckIndicatorMaps(
+ DeviceIntPtr /* dev */,
+ XkbSrvLedInfoPtr /* sli */,
+ unsigned int /* which */
+);
+
+extern _X_EXPORT unsigned int XkbStateChangedFlags(
+ XkbStatePtr /* old */,
+ XkbStatePtr /* new */
+);
+
+extern _X_EXPORT void XkbSendStateNotify(
+ DeviceIntPtr /* kbd */,
+ xkbStateNotify * /* pSN */
+);
+
+extern _X_EXPORT void XkbSendMapNotify(
+ DeviceIntPtr /* kbd */,
+ xkbMapNotify * /* ev */
+);
+
+extern _X_EXPORT int XkbComputeControlsNotify(
+ DeviceIntPtr /* kbd */,
+ XkbControlsPtr /* old */,
+ XkbControlsPtr /* new */,
+ xkbControlsNotify * /* pCN */,
+ Bool /* forceCtrlProc */
+);
+
+extern _X_EXPORT void XkbSendControlsNotify(
+ DeviceIntPtr /* kbd */,
+ xkbControlsNotify * /* ev */
+);
+
+extern _X_EXPORT void XkbSendCompatMapNotify(
+ DeviceIntPtr /* kbd */,
+ xkbCompatMapNotify * /* ev */
+);
+
+extern _X_EXPORT void XkbHandleBell(
+ BOOL /* force */,
+ BOOL /* eventOnly */,
+ DeviceIntPtr /* kbd */,
+ CARD8 /* percent */,
+ pointer /* ctrl */,
+ CARD8 /* class */,
+ Atom /* name */,
+ WindowPtr /* pWin */,
+ ClientPtr /* pClient */
+);
+
+extern _X_EXPORT void XkbSendAccessXNotify(
+ DeviceIntPtr /* kbd */,
+ xkbAccessXNotify * /* pEv */
+);
+
+extern _X_EXPORT void XkbSendNamesNotify(
+ DeviceIntPtr /* kbd */,
+ xkbNamesNotify * /* ev */
+);
+
+extern _X_EXPORT void XkbSendActionMessage(
+ DeviceIntPtr /* kbd */,
+ xkbActionMessage * /* ev */
+);
+
+extern _X_EXPORT void XkbSendExtensionDeviceNotify(
+ DeviceIntPtr /* kbd */,
+ ClientPtr /* client */,
+ xkbExtensionDeviceNotify * /* ev */
+);
+
+extern _X_EXPORT void XkbSendNotification(
+ DeviceIntPtr /* kbd */,
+ XkbChangesPtr /* pChanges */,
+ XkbEventCausePtr /* cause */
+);
+
+extern _X_EXPORT void XkbProcessKeyboardEvent(
+ DeviceEvent* /* event */,
+ DeviceIntPtr /* keybd */
+);
+
+extern _X_EXPORT void XkbHandleActions(
+ DeviceIntPtr /* dev */,
+ DeviceIntPtr /* kbd */,
+ DeviceEvent* /* event */
+);
+
+extern _X_EXPORT Bool XkbEnableDisableControls(
+ XkbSrvInfoPtr /* xkbi */,
+ unsigned long /* change */,
+ unsigned long /* newValues */,
+ XkbChangesPtr /* changes */,
+ XkbEventCausePtr /* cause */
+);
+
+extern _X_EXPORT void AccessXInit(
+ DeviceIntPtr /* dev */
+);
+
+extern _X_EXPORT Bool AccessXFilterPressEvent(
+ DeviceEvent* /* event */,
+ DeviceIntPtr /* keybd */
+);
+
+extern _X_EXPORT Bool AccessXFilterReleaseEvent(
+ DeviceEvent* /* event */,
+ DeviceIntPtr /* keybd */
+);
+
+extern _X_EXPORT void AccessXCancelRepeatKey(
+ XkbSrvInfoPtr /* xkbi */,
+ KeyCode /* key */
+);
+
+extern _X_EXPORT void AccessXComputeCurveFactor(
+ XkbSrvInfoPtr /* xkbi */,
+ XkbControlsPtr /* ctrls */
+);
+
+extern _X_EXPORT XkbInterestPtr XkbFindClientResource(
+ DevicePtr /* inDev */,
+ ClientPtr /* client */
+);
+
+extern _X_EXPORT XkbInterestPtr XkbAddClientResource(
+ DevicePtr /* inDev */,
+ ClientPtr /* client */,
+ XID /* id */
+);
+
+extern _X_EXPORT int XkbRemoveResourceClient(
+ DevicePtr /* inDev */,
+ XID /* id */
+);
+
+extern _X_EXPORT int XkbDDXAccessXBeep(
+ DeviceIntPtr /* dev */,
+ unsigned int /* what */,
+ unsigned int /* which */
+);
+
+extern _X_EXPORT int XkbDDXUsesSoftRepeat(
+ DeviceIntPtr /* dev */
+);
+
+extern _X_EXPORT void XkbDDXKeybdCtrlProc(
+ DeviceIntPtr /* dev */,
+ KeybdCtrl * /* ctrl */
+);
+
+extern _X_EXPORT void XkbDDXChangeControls(
+ DeviceIntPtr /* dev */,
+ XkbControlsPtr /* old */,
+ XkbControlsPtr /* new */
+);
+
+extern _X_EXPORT void XkbDDXUpdateDeviceIndicators(
+ DeviceIntPtr /* dev */,
+ XkbSrvLedInfoPtr /* sli */,
+ CARD32 /* newState */
+);
+
+extern _X_EXPORT void XkbDDXFakePointerMotion(
+ unsigned int /* flags */,
+ int /* x */,
+ int /* y */
+);
+
+extern _X_EXPORT void XkbDDXFakeDeviceButton(
+ DeviceIntPtr /* dev */,
+ Bool /* press */,
+ int /* button */
+);
+
+extern _X_EXPORT int XkbDDXTerminateServer(
+ DeviceIntPtr /* dev */,
+ KeyCode /* key */,
+ XkbAction * /* act */
+);
+
+extern _X_EXPORT int XkbDDXSwitchScreen(
+ DeviceIntPtr /* dev */,
+ KeyCode /* key */,
+ XkbAction * /* act */
+);
+
+extern _X_EXPORT int XkbDDXPrivate(
+ DeviceIntPtr /* dev */,
+ KeyCode /* key */,
+ XkbAction * /* act */
+);
+
+extern _X_EXPORT void XkbDisableComputedAutoRepeats(
+ DeviceIntPtr /* pXDev */,
+ unsigned int /* key */
+);
+
+extern _X_EXPORT void XkbSetRepeatKeys(
+ DeviceIntPtr /* pXDev */,
+ int /* key */,
+ int /* onoff */
+);
+
+extern _X_EXPORT int XkbLatchModifiers(
+ DeviceIntPtr /* pXDev */,
+ CARD8 /* mask */,
+ CARD8 /* latches */
+);
+
+extern _X_EXPORT int XkbLatchGroup(
+ DeviceIntPtr /* pXDev */,
+ int /* group */
+);
+
+extern _X_EXPORT void XkbClearAllLatchesAndLocks(
+ DeviceIntPtr /* dev */,
+ XkbSrvInfoPtr /* xkbi */,
+ Bool /* genEv */,
+ XkbEventCausePtr /* cause */
+);
+
+extern _X_EXPORT void XkbGetRulesDflts(
+ XkbRMLVOSet * /* rmlvo */
+);
+
+extern _X_EXPORT void XkbFreeRMLVOSet(
+ XkbRMLVOSet * /* rmlvo */,
+ Bool /* freeRMLVO */
+);
+
+extern _X_EXPORT void XkbSetRulesDflts(
+ XkbRMLVOSet * /* rmlvo */
+);
+
+extern _X_EXPORT void XkbDeleteRulesDflts(
+ void
+);
+
+extern _X_EXPORT int SProcXkbDispatch(
+ ClientPtr /* client */
+);
+
+extern _X_EXPORT XkbGeometryPtr XkbLookupNamedGeometry(
+ DeviceIntPtr /* dev */,
+ Atom /* name */,
+ Bool * /* shouldFree */
+);
+
+extern _X_EXPORT char * _XkbDupString(
+ const char * /* str */
+);
+
+extern _X_EXPORT void XkbConvertCase(
+ KeySym /* sym */,
+ KeySym * /* lower */,
+ KeySym * /* upper */
+);
+
+extern _X_EXPORT Status XkbChangeKeycodeRange(
+ XkbDescPtr /* xkb */,
+ int /* minKC */,
+ int /* maxKC */,
+ XkbChangesPtr /* changes */
+);
+
+extern _X_EXPORT void XkbFreeSrvLedInfo(
+ XkbSrvLedInfoPtr /* sli */
+);
+
+extern _X_EXPORT void XkbFreeInfo(
+ XkbSrvInfoPtr /* xkbi */
+);
+
+extern _X_EXPORT Status XkbChangeTypesOfKey(
+ XkbDescPtr /* xkb */,
+ int /* key */,
+ int /* nGroups */,
+ unsigned int /* groups */,
+ int * /* newTypesIn */,
+ XkbMapChangesPtr /* changes */
+);
+
+extern _X_EXPORT int XkbKeyTypesForCoreSymbols(
+ XkbDescPtr /* xkb */,
+ int /* map_width */,
+ KeySym * /* core_syms */,
+ unsigned int /* protected */,
+ int * /* types_inout */,
+ KeySym * /* xkb_syms_rtrn */
+);
+
+extern _X_EXPORT Bool XkbApplyCompatMapToKey(
+ XkbDescPtr /* xkb */,
+ KeyCode /* key */,
+ XkbChangesPtr /* changes */
+);
+
+extern _X_EXPORT Bool XkbApplyVirtualModChanges(
+ XkbDescPtr /* xkb */,
+ unsigned int /* changed */,
+ XkbChangesPtr /* changes */
+);
+
+extern _X_EXPORT void XkbSendNewKeyboardNotify(
+ DeviceIntPtr /* kbd */,
+ xkbNewKeyboardNotify * /* pNKN */
+);
+
+extern Bool XkbCopyKeymap(
+ XkbDescPtr /* dst */,
+ XkbDescPtr /* src */);
+
+extern Bool XkbCopyDeviceKeymap(
+ DeviceIntPtr /* dst */,
+ DeviceIntPtr /* src */);
+
+extern void XkbFilterEvents(
+ ClientPtr /* pClient */,
+ int /* nEvents */,
+ xEvent* /* xE */);
+
+extern int XkbGetEffectiveGroup(
+ XkbSrvInfoPtr /* xkbi */,
+ XkbStatePtr /* xkbstate */,
+ CARD8 /* keycode */);
+
+#include "xkbfile.h"
+#include "xkbrules.h"
+
+#define _XkbListKeycodes 0
+#define _XkbListTypes 1
+#define _XkbListCompat 2
+#define _XkbListSymbols 3
+#define _XkbListGeometry 4
+#define _XkbListNumComponents 5
+
+typedef struct _XkbSrvListInfo {
+ int szPool;
+ int nPool;
+ char * pool;
+
+ int maxRtrn;
+ int nTotal;
+
+ char * pattern[_XkbListNumComponents];
+ int nFound[_XkbListNumComponents];
+} XkbSrvListInfoRec,*XkbSrvListInfoPtr;
+
+extern _X_EXPORT Status XkbDDXList(
+ DeviceIntPtr /* dev */,
+ XkbSrvListInfoPtr /* listing */,
+ ClientPtr /* client */
+);
+
+extern _X_EXPORT unsigned int XkbDDXLoadKeymapByNames(
+ DeviceIntPtr /* keybd */,
+ XkbComponentNamesPtr /* names */,
+ unsigned int /* want */,
+ unsigned int /* need */,
+ XkbDescPtr * /* finfoRtrn */,
+ char * /* keymapNameRtrn */,
+ int /* keymapNameRtrnLen */
+);
+
+extern _X_EXPORT Bool XkbDDXNamesFromRules(
+ DeviceIntPtr /* keybd */,
+ char * /* rules */,
+ XkbRF_VarDefsPtr /* defs */,
+ XkbComponentNamesPtr /* names */
+);
+
+extern _X_EXPORT XkbDescPtr XkbCompileKeymap(
+ DeviceIntPtr /* dev */,
+ XkbRMLVOSet * /* rmlvo */
+);
+
+#endif /* _XKBSRV_H_ */
diff --git a/xorg-server/include/xwin-config.h b/xorg-server/include/xwin-config.h new file mode 100644 index 000000000..645a6cead --- /dev/null +++ b/xorg-server/include/xwin-config.h @@ -0,0 +1,37 @@ +/* + * xwin-config.h.in + * + * This file has all defines used in the xwin ddx + * + */ +#include <dix-config.h> + +/* Winsock networking */ +#define HAS_WINSOCK + +/* Cygwin has /dev/windows for signaling new win32 messages */ +// let's should this for now #define HAS_DEVWINDOWS 1 + +/* Switch on debug messages */ +/* #undef CYGDEBUG */ +/* #undef CYGWINDOWING_DEBUG */ +/* #undef CYGMULTIWINDOW_DEBUG */ + +/* Define to 1 if unsigned long is 64 bits. */ +/* #undef _XSERVER64 */ + +/* Do we require our own snprintf? */ +/* #undef NEED_SNPRINTF */ + +/* Short vendor name */ +#define XVENDORNAMESHORT "VcXsrv" + +/* Vendor web address for support */ +#define __VENDORDWEBSUPPORT__ "http://www.hc-consult.be/" + +/* Default log location */ +#define DEFAULT_LOGDIR "." + +/* Location of system.XWinrc */ +#define SYSCONFDIR "." + diff --git a/xorg-server/installer/genruntimeinclude.py b/xorg-server/installer/genruntimeinclude.py new file mode 100644 index 000000000..b346770eb --- /dev/null +++ b/xorg-server/installer/genruntimeinclude.py @@ -0,0 +1,82 @@ +PublicToken="1fc8b3b9a1e18e3b"
+
+Template=r"""!define MSVC_PUBLICTOKEN "<PUBLICTOKEN>"
+!define MSVC_VERSION "<VERSION>"
+!define MSVCR90_DLL "<WINSXSDIR>\x86_Microsoft.VC90.CRT_${MSVC_PUBLICTOKEN}_9.0.${MSVC_VERSION}_<SUFFIX>\msvcr90.dll"
+!define MSVCM90_DLL "<WINSXSDIR>\x86_Microsoft.VC90.CRT_${MSVC_PUBLICTOKEN}_9.0.${MSVC_VERSION}_<SUFFIX>\msvcm90.dll"
+!define MSVCP90_DLL "<WINSXSDIR>\x86_Microsoft.VC90.CRT_${MSVC_PUBLICTOKEN}_9.0.${MSVC_VERSION}_<SUFFIX>\msvcp90.dll"
+!define MSVC_CAT "<WINSXSDIR>\manifests\x86_Microsoft.VC90.CRT_${MSVC_PUBLICTOKEN}_9.0.${MSVC_VERSION}_<SUFFIX>.cat"
+!define MSVC_MANIFEST_PART "x86_Microsoft.VC90.CRT_${MSVC_PUBLICTOKEN}_9.0.${MSVC_VERSION}_<SUFFIX>.manifest"
+!define MSVC_MANIFEST "<WINSXSDIR>\manifests\${MSVC_MANIFEST_PART}"
+
+!define MSVC_VERSION_D "<VERSION>"
+!define MSVCR90_DLL_D "<WINSXSDIR>\x86_Microsoft.VC90.DebugCRT_${MSVC_PUBLICTOKEN}_9.0.${MSVC_VERSION_D}_<DSUFFIX>\msvcr90d.dll"
+!define MSVCM90_DLL_D "<WINSXSDIR>\x86_Microsoft.VC90.DebugCRT_${MSVC_PUBLICTOKEN}_9.0.${MSVC_VERSION_D}_<DSUFFIX>\msvcm90d.dll"
+!define MSVCP90_DLL_D "<WINSXSDIR>\x86_Microsoft.VC90.DebugCRT_${MSVC_PUBLICTOKEN}_9.0.${MSVC_VERSION_D}_<DSUFFIX>\msvcp90d.dll"
+!define MSVC_CAT_D "<WINSXSDIR>\manifests\x86_Microsoft.VC90.DebugCRT_${MSVC_PUBLICTOKEN}_9.0.${MSVC_VERSION_D}_<DSUFFIX>.cat"
+!define MSVC_MANIFEST_PART_D "x86_Microsoft.VC90.DebugCRT_${MSVC_PUBLICTOKEN}_9.0.${MSVC_VERSION_D}_<DSUFFIX>.manifest"
+!define MSVC_MANIFEST_D "<WINSXSDIR>\manifests\${MSVC_MANIFEST_PART_D}"
+"""
+
+import glob,re,sys,os
+
+Files=glob.glob(r"c:\windows\winsxs\x86_Microsoft.VC90.CRT_%s_9.0.*"%PublicToken)
+DebugFiles=glob.glob(r"c:\windows\winsxs\x86_Microsoft.VC90.DebugCRT_%s_9.0.*"%PublicToken)
+
+SearchRe=re.compile(r"c:\\windows\\winsxs\\x86_Microsoft\.VC90\.CRT_%s_9\.0\.([0-9]+)\.([0-9]+)_(.*)"%PublicToken,re.I)
+DebugSearchRe=re.compile(r"c:\\windows\\winsxs\\x86_Microsoft\.VC90\.DebugCRT_%s_9\.0\.([0-9]+)\.([0-9]+)_(.*)"%PublicToken,re.I)
+
+# Release Dlls
+MajorVersion=0
+MinorVersion=0
+LatestFile=None
+#Now Select the one with the latest version
+for File in Files:
+ # Extract version
+ Search=SearchRe.search(File)
+ Major=int(Search.group(1))
+ Minor=int(Search.group(2))
+ if Major>MajorVersion:
+ MajorVersion=Major
+ MinorVersion=Minor
+ LatestFile=File
+ Suffix=Search.group(3)
+ elif Major==MajorVersion and Minor>MinorVersion:
+ MinorVersion=Minor
+ LatestFile=File
+ Suffix=Search.group(3)
+
+
+Template=re.sub("<VERSION>","%d.%d"%(MajorVersion,MinorVersion),Template)
+Template=re.sub("<SUFFIX>",Suffix,Template)
+
+# Debug dlls
+MajorVersion=0
+MinorVersion=0
+LatestFile=None
+#Now Select the one with the latest version
+for File in DebugFiles:
+ # Extract version
+ Search=DebugSearchRe.search(File)
+ Major=int(Search.group(1))
+ Minor=int(Search.group(2))
+ if Major>MajorVersion:
+ MajorVersion=Major
+ MinorVersion=Minor
+ LatestFile=File
+ Suffix=Search.group(3)
+ elif Major==MajorVersion and Minor>MinorVersion:
+ MinorVersion=Minor
+ LatestFile=File
+ Suffix=Search.group(3)
+
+
+Template=re.sub("<DVERSION>","%d.%d"%(MajorVersion,MinorVersion),Template)
+Template=re.sub("<DSUFFIX>",Suffix,Template)
+
+# Adjust common stuff
+Template=re.sub("<PUBLICTOKEN>",PublicToken,Template)
+WinSxsDir=os.path.join(os.getenv("systemroot"),"WinSxS")
+Template=re.sub("<WINSXSDIR>",WinSxsDir,Template)
+
+open("runtime","w").write(Template)
diff --git a/xorg-server/installer/packageall.bat b/xorg-server/installer/packageall.bat new file mode 100644 index 000000000..b68ffdfa1 --- /dev/null +++ b/xorg-server/installer/packageall.bat @@ -0,0 +1,3 @@ +if exist vcxsrv.*.installer.exe del vcxsrv.*.installer.exe
+python genruntimeinclude.py
+"C:\Program Files\NSIS\makensis.exe" vcxsrv.nsi
\ No newline at end of file diff --git a/xorg-server/installer/vcxsrv.nsi b/xorg-server/installer/vcxsrv.nsi new file mode 100644 index 000000000..174549981 --- /dev/null +++ b/xorg-server/installer/vcxsrv.nsi @@ -0,0 +1,258 @@ +/* This file is part of vcxsrv.
+ *
+ * Copyright (C) 2009 Marc Haesen
+ *
+ * vcxsrv is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * vcxsrv is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with vcxsrv. If not, see <http://www.gnu.org/licenses/>.
+*/
+;--------------------------------
+
+; The name of the installer
+Name "VcXsrv"
+
+; The file to write
+OutFile "vcxsrv.1.7.99.6.installer.exe"
+
+; The default installation directory
+InstallDir $PROGRAMFILES\VcXsrv
+
+; Registry key to check for directory (so if you install again, it will
+; overwrite the old one automatically)
+InstallDirRegKey HKLM "Software\VcXsrv" "Install_Dir"
+
+; Request application privileges for Windows Vista
+RequestExecutionLevel admin
+
+;--------------------------------
+InstType "Full"
+InstType "Minimal"
+
+; Pages
+
+Page components
+Page directory
+Page instfiles
+
+UninstPage uninstConfirm
+UninstPage instfiles
+
+SetPluginUnload alwaysoff
+; ShowInstDetails show
+XPStyle on
+
+!define FUSION_REFCOUNT_UNINSTALL_SUBKEY_GUID {8cedc215-ac4b-488b-93c0-a50a49cb2fb8}
+
+!include runtime
+
+;--------------------------------
+
+; The stuff to install
+Section "VcXsrv (required)"
+
+ SectionIn RO
+ SectionIn 1 2
+
+ ; Set output path to the installation directory.
+ SetOutPath $INSTDIR
+
+ ; Remove old opengl32.dll file if it extits
+ IfFileExists "$INSTDIR\opengl32.dll" 0 +2
+ Delete "$INSTDIR\opengl32.dll"
+
+ ; Put files there
+ File "..\obj\servrelease\vcxsrv.exe"
+ File "..\obj\servdebug\vcxsrv_dbg.exe"
+ File "..\obj\servdebug\vcxsrv_dbg.pdb"
+ File "..\protocol.txt"
+ File "..\system.XWinrc"
+ File "..\..\xkbcomp\obj\release\xkbcomp.exe"
+ File "..\..\apps\xcalc\obj\release\xcalc.exe"
+ File "..\xcalc"
+ File "..\xcalc-color"
+ File "..\..\apps\xclock\obj\release\xclock.exe"
+ File "..\..\apps\xwininfo\obj\release\xwininfo.exe"
+ File "..\XKeysymDB"
+ File "..\XErrorDB"
+ File "..\hw\xwin\xlaunch\obj\release\xlaunch.exe"
+ File "..\..\tools\plink\obj\release\plink.exe"
+ File "..\swrast_dri.dll"
+ File "..\swrast_dri_dbg.dll"
+ SetOutPath $INSTDIR\fonts
+ File /r "..\fonts\*.*"
+ SetOutPath $INSTDIR\xkbdata
+ File /r "..\xkbdata\*.*"
+ SetOutPath $INSTDIR\locale
+ File /r "..\locale\*.*"
+
+ ; Write the installation path into the registry
+ WriteRegStr HKLM SOFTWARE\VcXsrv "Install_Dir" "$INSTDIR"
+
+ ; Write the uninstall keys for Windows
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\VcXsrv" "DisplayName" "VcXsrv"
+ WriteRegStr HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\VcXsrv" "UninstallString" '"$INSTDIR\uninstall.exe"'
+ WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\VcXsrv" "NoModify" 1
+ WriteRegDWORD HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\VcXsrv" "NoRepair" 1
+ WriteUninstaller "uninstall.exe"
+
+ ; Register the xlaunch file extension
+ WriteRegStr HKCR ".xlaunch" "" "XLaunchFile"
+ WriteRegStr HKCR "XLaunchFile" "" "XLaunch Configuration"
+ WriteRegStr HKCR "XLaunchFile\DefaultIcon" "" "$INSTDIR\xlaunch.exe,0"
+ WriteRegStr HKCR "XLaunchFile\shell\open\command" "" '"$INSTDIR\XLaunch.exe" -run "%1"'
+ WriteRegStr HKCR "XLaunchFile\shell\open\ddeexec\Application" "" "XLaunch"
+ WriteRegStr HKCR "XLaunchFile\shell\open\ddeexec\Topic" "" "System"
+ WriteRegStr HKCR "XLaunchFile\shell\edit\command" "" '"$INSTDIR\XLaunch.exe" -load "%1"'
+ WriteRegStr HKCR "XLaunchFile\shell\edit\ddeexec\Application" "" "XLaunch"
+ WriteRegStr HKCR "XLaunchFile\shell\edit\ddeexec\Topic" "" "System"
+ WriteRegStr HKCR "XLaunchFile\shell\Validate\command" "" '"$INSTDIR\XLaunch.exe" -validate "%1"'
+ WriteRegStr HKCR "XLaunchFile\shell\Validate\ddeexec\Application" "" "XLaunch"
+ WriteRegStr HKCR "XLaunchFile\shell\Validate\ddeexec\Topic" "" "System"
+
+ InitPluginsDir
+ SetOutPath $PLUGINSDIR
+ File "${MSVCR90_DLL}"
+ File "${MSVCM90_DLL}"
+ File "${MSVCP90_DLL}"
+ File "${MSVC_CAT}"
+ File "${MSVC_MANIFEST}"
+ File "${MSVCR90_DLL_D}"
+ File "${MSVCM90_DLL_D}"
+ File "${MSVCP90_DLL_D}"
+ File "${MSVC_CAT_D}"
+ File "${MSVC_MANIFEST_D}"
+ DetailPrint "Installing CRT assembly..."
+ System::Call "sxs::CreateAssemblyCache(*i .r0, i 0) i.r1"
+ StrCmp $1 0 0 fail
+ # Fill a FUSION_INSTALL_REFERENCE.
+ # fir.cbSize = sizeof(FUSION_INSTALL_REFERENCE) == 32
+ # fir.dwFlags = 0
+ # fir.guidScheme = FUSION_REFCOUNT_UNINSTALL_SUBKEY_GUID
+ # fir.szIdentifier = "nsissxs"
+ # fir.szNonCanonicalData = 0
+ System::Call "*(i 32, i 0, i 2364391957, i 1217113163, i 178634899, i 3090139977, w 'nsissxs', w '') i.s"
+ Pop $2
+ # IAssemblyCache::InstallAssembly(0, manifestPath, fir)
+ System::Call "$0->7(i 0, w '$PLUGINSDIR\${MSVC_MANIFEST_PART}', i r2) i.r1"
+ StrCmp $1 0 0 failcrt
+ System::Call "$0->7(i 0, w '$PLUGINSDIR\${MSVC_MANIFEST_PART_D}', i r2) i.r1"
+ StrCmp $1 0 0 faildebugcrt
+ System::Free $2
+ System::Call "$0->2()"
+ Goto end
+
+fail:
+ DetailPrint "CreateAssemblyCache failed."
+ DetailPrint $1
+ Goto end
+
+failcrt:
+ DetailPrint "InstallAssembly CRT failed."
+ DetailPrint $1
+ Goto end
+faildebugcrt:
+ DetailPrint "InstallAssembly Debug CRT failed."
+ DetailPrint $1
+ Goto end
+end:
+SectionEnd
+
+; Optional section (can be disabled by the user)
+Section "Start Menu Shortcuts"
+ SectionIn 1
+
+ SetOutPath $INSTDIR
+ CreateDirectory "$SMPROGRAMS\VcXsrv"
+ CreateShortCut "$SMPROGRAMS\VcXsrv\Uninstall VcXsrv.lnk" "$INSTDIR\uninstall.exe" "" "$INSTDIR\uninstall.exe" 0
+ CreateShortCut "$SMPROGRAMS\VcXsrv\VcXsrv.lnk" "$INSTDIR\vcxsrv.exe" " :1 -ac -terminate -lesspointer -multiwindow -clipboard +kb" "$INSTDIR\vcxsrv.exe" 0
+ CreateShortCut "$SMPROGRAMS\VcXsrv\XLaunch.lnk" "$INSTDIR\xlaunch.exe" "" "$INSTDIR\xlaunch.exe" 0
+
+SectionEnd
+
+; Optional section (can be disabled by the user)
+Section "Desktop Shortcuts"
+ SectionIn 1
+
+ SetOutPath $INSTDIR
+ CreateShortCut "$DESKTOP\VcXsrv.lnk" "$INSTDIR\vcxsrv.exe" " :1 -ac -terminate -lesspointer -multiwindow -clipboard +kb" "$INSTDIR\vcxsrv.exe" 0
+ CreateShortCut "$DESKTOP\XLaunch.lnk" "$INSTDIR\xlaunch.exe" "" "$INSTDIR\xlaunch.exe" 0
+
+SectionEnd
+
+;--------------------------------
+
+; Uninstaller
+
+Section "Uninstall"
+
+ ; Remove registry keys
+ DeleteRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\VcXsrv"
+ DeleteRegKey HKLM SOFTWARE\VcXsrv
+
+ ; Register the xlaunch file extension
+ DeleteRegKey HKCR ".xlaunch"
+ DeleteRegKey HKCR "XLaunchFile"
+
+ ; Remove files and uninstaller
+ Delete "$INSTDIR\vcxsrv.exe"
+ Delete "$INSTDIR\uninstall.exe"
+ Delete "$INSTDIR\protocol.txt"
+ Delete "$INSTDIR\system.XWinrc"
+ Delete "$INSTDIR\xkbcomp.exe"
+ Delete "$INSTDIR\XKeysymDB"
+ Delete "$INSTDIR\XErrorDB"
+ Delete "$INSTDIR\xlaunch.exe"
+
+ RMDir /r "$INSTDIR\fonts"
+ RMDir /r "$INSTDIR\xkbdata"
+ RMDir /r "$INSTDIR\locale"
+
+ ; Remove shortcuts, if any
+ Delete "$SMPROGRAMS\VcXsrv\*.*"
+ Delete "$DESKTOP\VcXsrv.lnk"
+ Delete "$DESKTOP\XLaunch.lnk"
+
+ ; Remove directories used
+ RMDir "$SMPROGRAMS\VcXsrv"
+ RMDir "$INSTDIR"
+
+; Currently disable uninstalling the run-time; because sometimes it is removing
+; the run-time although other applications are using them
+; DetailPrint "Removing CRT assembly..."
+; System::Call "sxs::CreateAssemblyCache(*i .r0, i 0) i.r1"
+; StrCmp $1 0 0 fail
+; System::Call "*(i 32, i 0, i 2364391957, i 1217113163, i 178634899, i 3090139977, w 'nsissxs', w '') i.s"
+; Pop $2
+; System::Call "$0->3(i 0, w 'Microsoft.VC90.CRT,version=$\"9.0.${MSVC_VERSION}$\",type=$\"win32$\",processorArchitecture=$\"x86$\",publicKeyToken=$\"${MSVC_PUBLICTOKEN}$\"', i r2, *i . r3) i.r1"
+; StrCmp $1 0 0 failcrt
+; System::Call "$0->3(i 0, w 'Microsoft.VC90.DebugCRT,version=$\"9.0.${MSVC_VERSION_D}$\",type=$\"win32$\",processorArchitecture=$\"x86$\",publicKeyToken=$\"${MSVC_PUBLICTOKEN}$\"', i r2, *i . r3) i.r1"
+; StrCmp $1 0 0 faildebugcrt
+; DetailPrint "Disposition returned is $3"
+; System::Free $2
+; System::Call "$0->2()"
+; Goto end
+; fail:
+; DetailPrint "CreateAssemblyCache failed."
+; DetailPrint $1
+; Goto end
+; failcrt:
+; DetailPrint "UninstallAssembly CRT failed."
+; DetailPrint $1
+; Goto end
+; faildebugcrt:
+; DetailPrint "UninstallAssembly Debug CRT failed."
+; DetailPrint $1
+; Goto end
+;end:
+
+SectionEnd
+
diff --git a/xorg-server/makefile b/xorg-server/makefile new file mode 100644 index 000000000..daf05f19e --- /dev/null +++ b/xorg-server/makefile @@ -0,0 +1,144 @@ +ifneq ($(MAKESERVER),1) +$(error Please specify MAKESERVER=1 on the command line or as environment variable) +endif + +INCLUDELIBFILES = \ + composite\$(OBJDIR)\libcomposite.lib \ + config\$(OBJDIR)\libconfig.lib \ + damageext\$(OBJDIR)\libdamageext.lib \ + dbe\$(OBJDIR)\libdbe.lib \ + dix\$(OBJDIR)\libdix.lib \ + fb\$(OBJDIR)\libfb.lib \ + glx\$(OBJDIR)\libglx.lib \ + hw\xwin\$(OBJDIR)\libxwin.lib \ + hw\xwin\glx\$(OBJDIR)\libwinglx.lib \ + mi\$(OBJDIR)\libmi.lib \ + miext\damage\$(OBJDIR)\libdamage.lib \ + miext\shadow\$(OBJDIR)\libshadow.lib \ + os\$(OBJDIR)\libos.lib \ + randr\$(OBJDIR)\librandr.lib \ + record\$(OBJDIR)\librecord.lib \ + Xext\$(OBJDIR)\libxext.lib \ + xfixes\$(OBJDIR)\libxfixes.lib \ + Xi\$(OBJDIR)\libxi.lib \ + xkb\$(OBJDIR)\libxkb.lib \ + render\$(OBJDIR)\librender.lib \ + $(MHMAKECONF)\libxau\$(OBJDIR)\libxau.lib \ + $(MHMAKECONF)\libxdmcp\$(OBJDIR)\libxdmcp.lib \ + $(MHMAKECONF)\libXfont\src\util\$(OBJDIR)\libutil.lib \ + $(MHMAKECONF)\libXfont\src\fc\$(OBJDIR)\libfc.lib \ + $(MHMAKECONF)\libXfont\src\fontfile\$(OBJDIR)\libfontfile.lib \ + $(MHMAKECONF)\libXfont\src\builtins\$(OBJDIR)\libbuiltins.lib \ + $(MHMAKECONF)\libXfont\src\bitmap\$(OBJDIR)\libbitmap.lib \ + $(MHMAKECONF)\pixman\pixman\$(OBJDIR)\libpixman-1.lib \ + $(MHMAKECONF)\libx11\modules\im\ximcp\$(OBJDIR)\libximcp.lib \ + $(MHMAKECONF)\libx11\src\xlibi18n\$(OBJDIR)\libi18n.lib \ + $(MHMAKECONF)\libx11\src\$(OBJDIR)\libx11.lib \ + $(MHMAKECONF)\libx11\src\xcms\$(OBJDIR)\libxcms.lib \ + $(MHMAKECONF)\libxcb\src\$(OBJDIR)\libxcb.lib \ + $(MHMAKECONF)\libx11\src\xkb\$(OBJDIR)\libxkb.lib \ + $(MHMAKECONF)\libx11\modules\om\generic\$(OBJDIR)\libxomGeneric.lib \ + $(MHMAKECONF)\libx11\modules\lc\utf8\$(OBJDIR)\libxlcUTF8Load.lib \ + $(MHMAKECONF)\libx11\modules\lc\def\$(OBJDIR)\libxlcDef.lib \ + $(MHMAKECONF)\libx11\modules\lc\gen\$(OBJDIR)\liblcGenConvLoad.lib \ + $(MHMAKECONF)\zlib\$(OBJDIR)\libz.lib \ + $(MHMAKECONF)\libx11\modules\lc\xlocale\$(OBJDIR)\libxlocale.lib \ + $(MHMAKECONF)\libfontenc\src\$(OBJDIR)\libfontenc.lib \ + $(MHMAKECONF)\libxfont\src\freetype\$(OBJDIR)\libft.lib \ + $(MHMAKECONF)\libxfont\src\stubs\$(OBJDIR)\libstubs.lib \ + $(MHMAKECONF)\libxinerama\src\$(OBJDIR)\libxinerama.lib + +LIBDIRS=$(dir $(INCLUDELIBFILES)) + +load_makefile $(LIBDIRS:%$(OBJDIR)\=%makefile MAKESERVER=$(MAKESERVER) DEBUG=$(DEBUG);) + +OBJS = dix\$(OBJDIR)\main.obj + +ifeq ($(DEBUG),1) +TTYAPP=vcxsrv_dbg +APP:=$(TTYAPP) + +LINKLIBS += $(MHMAKECONF)\openssl\out32_d\libeay32.lib \ + $(MHMAKECONF)\freetype\lib\freetype200b8MT_D.lib \ + $(MHMAKECONF)\pthreads\pthreadVC2d.lib + +$(OBJDIR)\$(TTYAPP).exe: $(LINKLIBS) + +else +WINAPP=vcxsrv +APP:=$(WINAPP) + +LINKLIBS += $(MHMAKECONF)\openssl\out32\libeay32.lib \ + $(MHMAKECONF)\freetype\lib\freetype200b8MT.lib \ + $(MHMAKECONF)\pthreads\pthreadVC2.lib + +endif + +RCINCLUDES += include hw\xwin $(MHMAKECONF)\include $(MHMAKECONF) + +XWin.rc: hw\xwin\XWin.rc + copy $< $@ + +RESOURCES = XWin.rc + +$(OBJDIR)\$(APP).exe: $(LINKLIBS) + +XKeysymDB: ..\libX11\src\XKeysymDB + copy $< $@ + +XErrorDB: ..\libX11\src\XErrorDB + copy $< $@ + +%.exe: $(OBJDIR)\%.exe + copy $< $@ + +load_makefile hw\xwin\xlaunch\makefile MAKESERVER=0 DEBUG=0 +xlaunch.exe: hw\xwin\xlaunch\obj\release\xlaunch.exe + copy $< $@ + +load_makefile ..\xkbcomp\makefile MAKESERVER=0 DEBUG=0 +xkbcomp.exe: ..\xkbcomp\obj\release\xkbcomp.exe + copy $< $@ + +%: ..\apps\xcalc\%.ad + copy $< $@ + +load_makefile ..\apps\xcalc\makefile MAKESERVER=0 DEBUG=0 +xcalc.exe: ..\apps\xcalc\obj\release\xcalc.exe XCalc XCalc-color + copy $< $@ + +load_makefile ..\apps\xclock\makefile MAKESERVER=0 DEBUG=0 +xclock.exe: ..\apps\xclock\obj\release\xclock.exe + copy $< $@ + +load_makefile ..\apps\xwininfo\makefile MAKESERVER=0 DEBUG=0 +xwininfo.exe: ..\apps\xwininfo\obj\release\xwininfo.exe + copy $< $@ + +load_makefile ..\tools\plink\makefile MAKESERVER=0 DEBUG=0 +plink.exe: ..\tools\plink\obj\release\plink.exe + copy $< $@ + +load_makefile ..\libX11\nls\makefile MAKESERVER=0 DEBUG=0 +load_makefile fonts.src\makefile MAKESERVER=0 DEBUG=0 +load_makefile xkbdata.src\makefile MAKESERVER=0 DEBUG=0 + +all: $(APP).exe xlaunch.exe xkbcomp.exe protocol.txt XKeysymDB XErrorDB \ + ..\libX11\nls\all fonts.src\all xkbdata.src\all plink.exe xclock.exe xcalc.exe \ + xwininfo.exe swrast_dri.dll swrast_dri_dbg.dll + + +load_makefile ..\mesalib\windows\VC8\mesa\makefile MAKESERVER=0 DEBUG=0 +swrast_dri.dll: ..\mesalib\windows\VC8\mesa\Release\swrast_dri.dll + copy $< $@ + +swrast_dri_dbg.dll: ..\mesalib\windows\VC8\mesa\Debug\swrast_dri.dll + copy $< $@ + +mesaopengl32.dll: ..\mesalib\lib\mesaopengl32.dll + copy $< $@ + +protocol.txt: dix\protocol.txt + copy $< $@ + + diff --git a/xorg-server/mi/makefile b/xorg-server/mi/makefile new file mode 100644 index 000000000..bff870d6e --- /dev/null +++ b/xorg-server/mi/makefile @@ -0,0 +1,42 @@ +CSRCS=miarc.c \ + mibank.c \ + mibitblt.c \ + mibstore.c \ + micmap.c \ + micopy.c \ + micursor.c \ + midash.c \ + midispcur.c \ + mieq.c \ + miexpose.c \ + mifillarc.c \ + mifillrct.c \ + mifpolycon.c \ + migc.c \ + miglblt.c \ + mioverlay.c \ + mipointer.c \ + mipoly.c \ + mipolycon.c \ + mipolygen.c \ + mipolypnt.c \ + mipolyrect.c \ + mipolyseg.c \ + mipolytext.c \ + mipolyutil.c \ + mipushpxl.c \ + miregion.c \ + miscrinit.c \ + mispans.c \ + misprite.c \ + mivaltree.c \ + miwideline.c \ + miwindow.c \ + mizerarc.c \ + mizerclip.c \ + mizerline.c \ + miinitext.c + +LIBRARY=libmi + + diff --git a/xorg-server/mi/miarc.c b/xorg-server/mi/miarc.c index 5fd1a678a..4a4a05dc0 100644 --- a/xorg-server/mi/miarc.c +++ b/xorg-server/mi/miarc.c @@ -64,6 +64,10 @@ SOFTWARE. #include "mifillarc.h" #include <X11/Xfuncproto.h> +#ifdef _MSC_VER +#define hypot _hypot +#endif + static double miDsin(double a); static double miDcos(double a); static double miDasin(double v); diff --git a/xorg-server/mi/micmap.c b/xorg-server/mi/micmap.c index e832be7fa..5a1e60a16 100644 --- a/xorg-server/mi/micmap.c +++ b/xorg-server/mi/micmap.c @@ -1,667 +1,678 @@ -/* - * Copyright © 1987 Sun Microsystems, 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 (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. - */ - -/* - * This is based on cfbcmap.c. The functions here are useful independently - * of cfb, which is the reason for including them here. How "mi" these - * are may be debatable. - */ - - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <X11/X.h> -#include <X11/Xproto.h> -#include "scrnintstr.h" -#include "colormapst.h" -#include "resource.h" -#include "globals.h" -#include "micmap.h" - -ColormapPtr miInstalledMaps[MAXSCREENS]; - -int -miListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps) -{ - if (miInstalledMaps[pScreen->myNum]) { - *pmaps = miInstalledMaps[pScreen->myNum]->mid; - return (1); - } - return 0; -} - -void -miInstallColormap(ColormapPtr pmap) -{ - int index = pmap->pScreen->myNum; - ColormapPtr oldpmap = miInstalledMaps[index]; - - if(pmap != oldpmap) - { - /* Uninstall pInstalledMap. No hardware changes required, just - * notify all interested parties. */ - if(oldpmap != (ColormapPtr)None) - WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid); - /* Install pmap */ - miInstalledMaps[index] = pmap; - WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid); - - } -} - -void -miUninstallColormap(ColormapPtr pmap) -{ - int index = pmap->pScreen->myNum; - ColormapPtr curpmap = miInstalledMaps[index]; - - if(pmap == curpmap) - { - if (pmap->mid != pmap->pScreen->defColormap) - { - dixLookupResourceByType((pointer *)&curpmap, - pmap->pScreen->defColormap, - RT_COLORMAP, serverClient, - DixUseAccess); - (*pmap->pScreen->InstallColormap)(curpmap); - } - } -} - -void -miResolveColor(unsigned short *pred, unsigned short *pgreen, - unsigned short *pblue, VisualPtr pVisual) -{ - int shift = 16 - pVisual->bitsPerRGBValue; - unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1; - - if ((pVisual->class | DynamicClass) == GrayScale) - { - /* rescale to gray then rgb bits */ - *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100; - *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim; - } - else - { - /* rescale to rgb bits */ - *pred = ((*pred >> shift) * 65535) / lim; - *pgreen = ((*pgreen >> shift) * 65535) / lim; - *pblue = ((*pblue >> shift) * 65535) / lim; - } -} - -Bool -miInitializeColormap(ColormapPtr pmap) -{ - unsigned i; - VisualPtr pVisual; - unsigned lim, maxent, shift; - - pVisual = pmap->pVisual; - lim = (1 << pVisual->bitsPerRGBValue) - 1; - shift = 16 - pVisual->bitsPerRGBValue; - maxent = pVisual->ColormapEntries - 1; - if (pVisual->class == TrueColor) - { - unsigned limr, limg, limb; - - limr = pVisual->redMask >> pVisual->offsetRed; - limg = pVisual->greenMask >> pVisual->offsetGreen; - limb = pVisual->blueMask >> pVisual->offsetBlue; - for(i = 0; i <= maxent; i++) - { - /* rescale to [0..65535] then rgb bits */ - pmap->red[i].co.local.red = - ((((i * 65535) / limr) >> shift) * 65535) / lim; - pmap->green[i].co.local.green = - ((((i * 65535) / limg) >> shift) * 65535) / lim; - pmap->blue[i].co.local.blue = - ((((i * 65535) / limb) >> shift) * 65535) / lim; - } - } - else if (pVisual->class == StaticColor) - { - unsigned limr, limg, limb; - - limr = pVisual->redMask >> pVisual->offsetRed; - limg = pVisual->greenMask >> pVisual->offsetGreen; - limb = pVisual->blueMask >> pVisual->offsetBlue; - for(i = 0; i <= maxent; i++) - { - /* rescale to [0..65535] then rgb bits */ - pmap->red[i].co.local.red = - ((((((i & pVisual->redMask) >> pVisual->offsetRed) - * 65535) / limr) >> shift) * 65535) / lim; - pmap->red[i].co.local.green = - ((((((i & pVisual->greenMask) >> pVisual->offsetGreen) - * 65535) / limg) >> shift) * 65535) / lim; - pmap->red[i].co.local.blue = - ((((((i & pVisual->blueMask) >> pVisual->offsetBlue) - * 65535) / limb) >> shift) * 65535) / lim; - } - } - else if (pVisual->class == StaticGray) - { - for(i = 0; i <= maxent; i++) - { - /* rescale to [0..65535] then rgb bits */ - pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift) - * 65535) / lim; - pmap->red[i].co.local.green = pmap->red[i].co.local.red; - pmap->red[i].co.local.blue = pmap->red[i].co.local.red; - } - } - return TRUE; -} - -/* When simulating DirectColor on PseudoColor hardware, multiple - entries of the colormap must be updated - */ - -#define AddElement(mask) { \ - pixel = red | green | blue; \ - for (i = 0; i < nresult; i++) \ - if (outdefs[i].pixel == pixel) \ - break; \ - if (i == nresult) \ - { \ - nresult++; \ - outdefs[i].pixel = pixel; \ - outdefs[i].flags = 0; \ - } \ - outdefs[i].flags |= (mask); \ - outdefs[i].red = pmap->red[red >> pVisual->offsetRed].co.local.red; \ - outdefs[i].green = pmap->green[green >> pVisual->offsetGreen].co.local.green; \ - outdefs[i].blue = pmap->blue[blue >> pVisual->offsetBlue].co.local.blue; \ -} - -int -miExpandDirectColors(ColormapPtr pmap, int ndef, xColorItem *indefs, - xColorItem *outdefs) -{ - int red, green, blue; - int maxred, maxgreen, maxblue; - int stepred, stepgreen, stepblue; - VisualPtr pVisual; - int pixel; - int nresult; - int i; - - pVisual = pmap->pVisual; - - stepred = 1 << pVisual->offsetRed; - stepgreen = 1 << pVisual->offsetGreen; - stepblue = 1 << pVisual->offsetBlue; - maxred = pVisual->redMask; - maxgreen = pVisual->greenMask; - maxblue = pVisual->blueMask; - nresult = 0; - for (;ndef--; indefs++) - { - if (indefs->flags & DoRed) - { - red = indefs->pixel & pVisual->redMask; - for (green = 0; green <= maxgreen; green += stepgreen) - { - for (blue = 0; blue <= maxblue; blue += stepblue) - { - AddElement (DoRed) - } - } - } - if (indefs->flags & DoGreen) - { - green = indefs->pixel & pVisual->greenMask; - for (red = 0; red <= maxred; red += stepred) - { - for (blue = 0; blue <= maxblue; blue += stepblue) - { - AddElement (DoGreen) - } - } - } - if (indefs->flags & DoBlue) - { - blue = indefs->pixel & pVisual->blueMask; - for (red = 0; red <= maxred; red += stepred) - { - for (green = 0; green <= maxgreen; green += stepgreen) - { - AddElement (DoBlue) - } - } - } - } - return nresult; -} - -Bool -miCreateDefColormap(ScreenPtr pScreen) -{ -/* - * In the following sources PC X server vendors may want to delete - * "_not_tog" from "#ifdef WIN32_not_tog" - */ -#ifdef WIN32_not_tog - /* - * these are the MS-Windows desktop colors, adjusted for X's 16-bit - * color specifications. - */ - static xColorItem citems[] = { - { 0, 0, 0, 0, 0, 0 }, - { 1, 0x8000, 0, 0, 0, 0 }, - { 2, 0, 0x8000, 0, 0, 0 }, - { 3, 0x8000, 0x8000, 0, 0, 0 }, - { 4, 0, 0, 0x8000, 0, 0 }, - { 5, 0x8000, 0, 0x8000, 0, 0 }, - { 6, 0, 0x8000, 0x8000, 0, 0 }, - { 7, 0xc000, 0xc000, 0xc000, 0, 0 }, - { 8, 0xc000, 0xdc00, 0xc000, 0, 0 }, - { 9, 0xa600, 0xca00, 0xf000, 0, 0 }, - { 246, 0xff00, 0xfb00, 0xf000, 0, 0 }, - { 247, 0xa000, 0xa000, 0xa400, 0, 0 }, - { 248, 0x8000, 0x8000, 0x8000, 0, 0 }, - { 249, 0xff00, 0, 0, 0, 0 }, - { 250, 0, 0xff00, 0, 0, 0 }, - { 251, 0xff00, 0xff00, 0, 0, 0 }, - { 252, 0, 0, 0xff00, 0, 0 }, - { 253, 0xff00, 0, 0xff00, 0, 0 }, - { 254, 0, 0xff00, 0xff00, 0, 0 }, - { 255, 0xff00, 0xff00, 0xff00, 0, 0 } - }; -#define NUM_DESKTOP_COLORS sizeof citems / sizeof citems[0] - int i; -#else - unsigned short zero = 0, ones = 0xFFFF; -#endif - Pixel wp, bp; - VisualPtr pVisual; - ColormapPtr cmap; - int alloctype; - - for (pVisual = pScreen->visuals; - pVisual->vid != pScreen->rootVisual; - pVisual++) - ; - - if (pScreen->rootDepth == 1 || (pVisual->class & DynamicClass)) - alloctype = AllocNone; - else - alloctype = AllocAll; - - if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap, - alloctype, 0) != Success) - return FALSE; - - if (pScreen->rootDepth > 1) { - wp = pScreen->whitePixel; - bp = pScreen->blackPixel; -#ifdef WIN32_not_tog - for (i = 0; i < NUM_DESKTOP_COLORS; i++) { - if (AllocColor (cmap, - &citems[i].red, &citems[i].green, &citems[i].blue, - &citems[i].pixel, 0) != Success) - return FALSE; - } -#else - if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) != - Success) || - (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) != - Success)) - return FALSE; - pScreen->whitePixel = wp; - pScreen->blackPixel = bp; -#endif - } - - (*pScreen->InstallColormap)(cmap); - return TRUE; -} - -/* - * Default true color bitmasks, should be overridden by - * driver - */ - -#define _RZ(d) ((d + 2) / 3) -#define _RS(d) 0 -#define _RM(d) ((1 << _RZ(d)) - 1) -#define _GZ(d) ((d - _RZ(d) + 1) / 2) -#define _GS(d) _RZ(d) -#define _GM(d) (((1 << _GZ(d)) - 1) << _GS(d)) -#define _BZ(d) (d - _RZ(d) - _GZ(d)) -#define _BS(d) (_RZ(d) + _GZ(d)) -#define _BM(d) (((1 << _BZ(d)) - 1) << _BS(d)) -#define _CE(d) (1 << _RZ(d)) - -typedef struct _miVisuals { - struct _miVisuals *next; - int depth; - int bitsPerRGB; - int visuals; - int count; - int preferredCVC; - Pixel redMask, greenMask, blueMask; -} miVisualsRec, *miVisualsPtr; - -static int miVisualPriority[] = { - PseudoColor, GrayScale, StaticColor, TrueColor, DirectColor, StaticGray -}; - -#define NUM_PRIORITY 6 - -static miVisualsPtr miVisuals; - -void -miClearVisualTypes(void) -{ - miVisualsPtr v; - - while ((v = miVisuals)) { - miVisuals = v->next; - xfree(v); - } -} - - -Bool -miSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB, - int preferredCVC, - Pixel redMask, Pixel greenMask, Pixel blueMask) -{ - miVisualsPtr new, *prev, v; - int count; - - new = xalloc (sizeof *new); - if (!new) - return FALSE; - if (!redMask || !greenMask || !blueMask) - { - redMask = _RM(depth); - greenMask = _GM(depth); - blueMask = _BM(depth); - } - new->next = 0; - new->depth = depth; - new->visuals = visuals; - new->bitsPerRGB = bitsPerRGB; - new->preferredCVC = preferredCVC; - new->redMask = redMask; - new->greenMask = greenMask; - new->blueMask = blueMask; - count = (visuals >> 1) & 033333333333; - count = visuals - count - ((count >> 1) & 033333333333); - count = (((count + (count >> 3)) & 030707070707) % 077); /* HAKMEM 169 */ - new->count = count; - for (prev = &miVisuals; (v = *prev); prev = &v->next); - *prev = new; - return TRUE; -} - -Bool -miSetVisualTypes(int depth, int visuals, int bitsPerRGB, int preferredCVC) -{ - return miSetVisualTypesAndMasks (depth, visuals, bitsPerRGB, - preferredCVC, 0, 0, 0); -} - -int -miGetDefaultVisualMask(int depth) -{ - if (depth > MAX_PSEUDO_DEPTH) - return LARGE_VISUALS; - else if (depth >= MIN_TRUE_DEPTH) - return ALL_VISUALS; - else if (depth == 1) - return StaticGrayMask; - else - return SMALL_VISUALS; -} - -static Bool -miVisualTypesSet (int depth) -{ - miVisualsPtr visuals; - - for (visuals = miVisuals; visuals; visuals = visuals->next) - if (visuals->depth == depth) - return TRUE; - return FALSE; -} - -Bool -miSetPixmapDepths (void) -{ - int d, f; - - /* Add any unlisted depths from the pixmap formats */ - for (f = 0; f < screenInfo.numPixmapFormats; f++) - { - d = screenInfo.formats[f].depth; - if (!miVisualTypesSet (d)) - { - if (!miSetVisualTypes (d, 0, 0, -1)) - return FALSE; - } - } - return TRUE; -} - -/* - * Distance to least significant one bit - */ -static int -maskShift (Pixel p) -{ - int s; - - if (!p) return 0; - s = 0; - while (!(p & 1)) - { - s++; - p >>= 1; - } - return s; -} - -/* - * Given a list of formats for a screen, create a list - * of visuals and depths for the screen which corespond to - * the set which can be used with this version of cfb. - */ - -Bool -miInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp, - int *ndepthp, int *rootDepthp, VisualID *defaultVisp, - unsigned long sizes, int bitsPerRGB, int preferredVis) - -{ - int i, j = 0, k; - VisualPtr visual; - DepthPtr depth; - VisualID *vid; - int d, b; - int f; - int ndepth, nvisual; - int nvtype; - int vtype; - miVisualsPtr visuals, nextVisuals; - int *preferredCVCs, *prefp; - int first_depth; - - /* none specified, we'll guess from pixmap formats */ - if (!miVisuals) - { - for (f = 0; f < screenInfo.numPixmapFormats; f++) - { - d = screenInfo.formats[f].depth; - b = screenInfo.formats[f].bitsPerPixel; - if (sizes & (1 << (b - 1))) - vtype = miGetDefaultVisualMask(d); - else - vtype = 0; - if (!miSetVisualTypes (d, vtype, bitsPerRGB, -1)) - return FALSE; - } - } - nvisual = 0; - ndepth = 0; - for (visuals = miVisuals; visuals; visuals = nextVisuals) - { - nextVisuals = visuals->next; - ndepth++; - nvisual += visuals->count; - } - depth = xalloc (ndepth * sizeof (DepthRec)); - visual = xalloc (nvisual * sizeof (VisualRec)); - preferredCVCs = xalloc(ndepth * sizeof(int)); - if (!depth || !visual || !preferredCVCs) - { - xfree (depth); - xfree (visual); - xfree (preferredCVCs); - return FALSE; - } - *depthp = depth; - *visualp = visual; - *ndepthp = ndepth; - *nvisualp = nvisual; - prefp = preferredCVCs; - for (visuals = miVisuals; visuals; visuals = nextVisuals) - { - nextVisuals = visuals->next; - d = visuals->depth; - vtype = visuals->visuals; - nvtype = visuals->count; - *prefp = visuals->preferredCVC; - prefp++; - vid = NULL; - if (nvtype) - { - vid = xalloc (nvtype * sizeof (VisualID)); - if (!vid) { - xfree(preferredCVCs); - return FALSE; - } - } - depth->depth = d; - depth->numVids = nvtype; - depth->vids = vid; - depth++; - for (i = 0; i < NUM_PRIORITY; i++) { - if (! (vtype & (1 << miVisualPriority[i]))) - continue; - visual->class = miVisualPriority[i]; - visual->bitsPerRGBValue = visuals->bitsPerRGB; - visual->ColormapEntries = 1 << d; - visual->nplanes = d; - visual->vid = *vid = FakeClientID (0); - switch (visual->class) { - case PseudoColor: - case GrayScale: - case StaticGray: - visual->redMask = 0; - visual->greenMask = 0; - visual->blueMask = 0; - visual->offsetRed = 0; - visual->offsetGreen = 0; - visual->offsetBlue = 0; - break; - case DirectColor: - case TrueColor: - visual->ColormapEntries = _CE(d); - /* fall through */ - case StaticColor: - visual->redMask = visuals->redMask; - visual->greenMask = visuals->greenMask; - visual->blueMask = visuals->blueMask; - visual->offsetRed = maskShift (visuals->redMask); - visual->offsetGreen = maskShift (visuals->greenMask); - visual->offsetBlue = maskShift (visuals->blueMask); - } - vid++; - visual++; - } - xfree (visuals); - } - miVisuals = NULL; - visual = *visualp; - depth = *depthp; - - /* - * if we did not supplyied by a preferred visual class - * check if there is a preferred class in one of the depth - * structures - if there is, we want to start looking for the - * default visual/depth from that depth. - */ - first_depth = 0; - if (preferredVis < 0 && defaultColorVisualClass < 0 ) { - for (i = 0; i < ndepth; i++) { - if (preferredCVCs[i] >= 0) { - first_depth = i; - break; - } - } - } - - for (i = first_depth; i < ndepth; i++) - { - int prefColorVisualClass = -1; - - if (defaultColorVisualClass >= 0) - prefColorVisualClass = defaultColorVisualClass; - else if (preferredVis >= 0) - prefColorVisualClass = preferredVis; - else if (preferredCVCs[i] >= 0) - prefColorVisualClass = preferredCVCs[i]; - - if (*rootDepthp && *rootDepthp != depth[i].depth) - continue; - - for (j = 0; j < depth[i].numVids; j++) - { - for (k = 0; k < nvisual; k++) - if (visual[k].vid == depth[i].vids[j]) - break; - if (k == nvisual) - continue; - if (prefColorVisualClass < 0 || - visual[k].class == prefColorVisualClass) - break; - } - if (j != depth[i].numVids) - break; - } - if (i == ndepth) { - i = 0; - j = 0; - } - *rootDepthp = depth[i].depth; - *defaultVisp = depth[i].vids[j]; - xfree(preferredCVCs); - - return TRUE; -} +/*
+ * Copyright © 1987 Sun Microsystems, 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 (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.
+ */
+
+/*
+ * This is based on cfbcmap.c. The functions here are useful independently
+ * of cfb, which is the reason for including them here. How "mi" these
+ * are may be debatable.
+ */
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "scrnintstr.h"
+#include "colormapst.h"
+#include "resource.h"
+#include "globals.h"
+#include "micmap.h"
+
+ColormapPtr miInstalledMaps[MAXSCREENS];
+
+int
+miListInstalledColormaps(ScreenPtr pScreen, Colormap *pmaps)
+{
+ if (miInstalledMaps[pScreen->myNum]) {
+ *pmaps = miInstalledMaps[pScreen->myNum]->mid;
+ return (1);
+ }
+ return 0;
+}
+
+void
+miInstallColormap(ColormapPtr pmap)
+{
+ int index = pmap->pScreen->myNum;
+ ColormapPtr oldpmap = miInstalledMaps[index];
+
+ if(pmap != oldpmap)
+ {
+ /* Uninstall pInstalledMap. No hardware changes required, just
+ * notify all interested parties. */
+ if(oldpmap != (ColormapPtr)None)
+ WalkTree(pmap->pScreen, TellLostMap, (char *)&oldpmap->mid);
+ /* Install pmap */
+ miInstalledMaps[index] = pmap;
+ WalkTree(pmap->pScreen, TellGainedMap, (char *)&pmap->mid);
+
+ }
+}
+
+void
+miUninstallColormap(ColormapPtr pmap)
+{
+ int index = pmap->pScreen->myNum;
+ ColormapPtr curpmap = miInstalledMaps[index];
+
+ if(pmap == curpmap)
+ {
+ if (pmap->mid != pmap->pScreen->defColormap)
+ {
+ dixLookupResourceByType((pointer *)&curpmap,
+ pmap->pScreen->defColormap,
+ RT_COLORMAP, serverClient,
+ DixUseAccess);
+ (*pmap->pScreen->InstallColormap)(curpmap);
+ }
+ }
+}
+
+void
+miResolveColor(unsigned short *pred, unsigned short *pgreen,
+ unsigned short *pblue, VisualPtr pVisual)
+{
+ int shift = 16 - pVisual->bitsPerRGBValue;
+ unsigned lim = (1 << pVisual->bitsPerRGBValue) - 1;
+
+ if ((pVisual->class | DynamicClass) == GrayScale)
+ {
+ /* rescale to gray then rgb bits */
+ *pred = (30L * *pred + 59L * *pgreen + 11L * *pblue) / 100;
+ *pblue = *pgreen = *pred = ((*pred >> shift) * 65535) / lim;
+ }
+ else
+ {
+ /* rescale to rgb bits */
+ *pred = ((*pred >> shift) * 65535) / lim;
+ *pgreen = ((*pgreen >> shift) * 65535) / lim;
+ *pblue = ((*pblue >> shift) * 65535) / lim;
+ }
+}
+
+Bool
+miInitializeColormap(ColormapPtr pmap)
+{
+ unsigned i;
+ VisualPtr pVisual;
+ unsigned lim, maxent, shift;
+
+ pVisual = pmap->pVisual;
+ lim = (1 << pVisual->bitsPerRGBValue) - 1;
+ shift = 16 - pVisual->bitsPerRGBValue;
+ maxent = pVisual->ColormapEntries - 1;
+ if (pVisual->class == TrueColor)
+ {
+ unsigned limr, limg, limb;
+
+ limr = pVisual->redMask >> pVisual->offsetRed;
+ for(i = 0; i <= min(limr,maxent); i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->red[i].co.local.red =
+ ((((i * 65535) / limr) >> shift) * 65535) / lim;
+ }
+ for(; i <= maxent; i++) pmap->red[i].co.local.red = 65535;
+ limg = pVisual->greenMask >> pVisual->offsetGreen;
+ for(i = 0; i <= min(limg,maxent); i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->green[i].co.local.green =
+ ((((i * 65535) / limg) >> shift) * 65535) / lim;
+ }
+ for(; i <= maxent; i++) pmap->green[i].co.local.green = 65535;
+ limb = pVisual->blueMask >> pVisual->offsetBlue;
+ for(i = 0; i <= min(limb,maxent); i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->blue[i].co.local.blue =
+ ((((i * 65535) / limb) >> shift) * 65535) / lim;
+ }
+ for(; i <= maxent; i++) pmap->blue[i].co.local.blue = 65535;
+ }
+ else if (pVisual->class == StaticColor)
+ {
+ unsigned limr, limg, limb;
+
+ limr = pVisual->redMask >> pVisual->offsetRed;
+ limg = pVisual->greenMask >> pVisual->offsetGreen;
+ limb = pVisual->blueMask >> pVisual->offsetBlue;
+ for(i = 0; i <= maxent; i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->red[i].co.local.red =
+ ((((((i & pVisual->redMask) >> pVisual->offsetRed)
+ * 65535) / limr) >> shift) * 65535) / lim;
+ pmap->red[i].co.local.green =
+ ((((((i & pVisual->greenMask) >> pVisual->offsetGreen)
+ * 65535) / limg) >> shift) * 65535) / lim;
+ pmap->red[i].co.local.blue =
+ ((((((i & pVisual->blueMask) >> pVisual->offsetBlue)
+ * 65535) / limb) >> shift) * 65535) / lim;
+ }
+ }
+ else if (pVisual->class == StaticGray)
+ {
+ for(i = 0; i <= maxent; i++)
+ {
+ /* rescale to [0..65535] then rgb bits */
+ pmap->red[i].co.local.red = ((((i * 65535) / maxent) >> shift)
+ * 65535) / lim;
+ pmap->red[i].co.local.green = pmap->red[i].co.local.red;
+ pmap->red[i].co.local.blue = pmap->red[i].co.local.red;
+ }
+ }
+ return TRUE;
+}
+
+/* When simulating DirectColor on PseudoColor hardware, multiple
+ entries of the colormap must be updated
+ */
+
+#define AddElement(mask) { \
+ pixel = red | green | blue; \
+ for (i = 0; i < nresult; i++) \
+ if (outdefs[i].pixel == pixel) \
+ break; \
+ if (i == nresult) \
+ { \
+ nresult++; \
+ outdefs[i].pixel = pixel; \
+ outdefs[i].flags = 0; \
+ } \
+ outdefs[i].flags |= (mask); \
+ outdefs[i].red = pmap->red[red >> pVisual->offsetRed].co.local.red; \
+ outdefs[i].green = pmap->green[green >> pVisual->offsetGreen].co.local.green; \
+ outdefs[i].blue = pmap->blue[blue >> pVisual->offsetBlue].co.local.blue; \
+}
+
+int
+miExpandDirectColors(ColormapPtr pmap, int ndef, xColorItem *indefs,
+ xColorItem *outdefs)
+{
+ int red, green, blue;
+ int maxred, maxgreen, maxblue;
+ int stepred, stepgreen, stepblue;
+ VisualPtr pVisual;
+ int pixel;
+ int nresult;
+ int i;
+
+ pVisual = pmap->pVisual;
+
+ stepred = 1 << pVisual->offsetRed;
+ stepgreen = 1 << pVisual->offsetGreen;
+ stepblue = 1 << pVisual->offsetBlue;
+ maxred = pVisual->redMask;
+ maxgreen = pVisual->greenMask;
+ maxblue = pVisual->blueMask;
+ nresult = 0;
+ for (;ndef--; indefs++)
+ {
+ if (indefs->flags & DoRed)
+ {
+ red = indefs->pixel & pVisual->redMask;
+ for (green = 0; green <= maxgreen; green += stepgreen)
+ {
+ for (blue = 0; blue <= maxblue; blue += stepblue)
+ {
+ AddElement (DoRed)
+ }
+ }
+ }
+ if (indefs->flags & DoGreen)
+ {
+ green = indefs->pixel & pVisual->greenMask;
+ for (red = 0; red <= maxred; red += stepred)
+ {
+ for (blue = 0; blue <= maxblue; blue += stepblue)
+ {
+ AddElement (DoGreen)
+ }
+ }
+ }
+ if (indefs->flags & DoBlue)
+ {
+ blue = indefs->pixel & pVisual->blueMask;
+ for (red = 0; red <= maxred; red += stepred)
+ {
+ for (green = 0; green <= maxgreen; green += stepgreen)
+ {
+ AddElement (DoBlue)
+ }
+ }
+ }
+ }
+ return nresult;
+}
+
+Bool
+miCreateDefColormap(ScreenPtr pScreen)
+{
+/*
+ * In the following sources PC X server vendors may want to delete
+ * "_not_tog" from "#ifdef WIN32_not_tog"
+ */
+#ifdef WIN32_not_tog
+ /*
+ * these are the MS-Windows desktop colors, adjusted for X's 16-bit
+ * color specifications.
+ */
+ static xColorItem citems[] = {
+ { 0, 0, 0, 0, 0, 0 },
+ { 1, 0x8000, 0, 0, 0, 0 },
+ { 2, 0, 0x8000, 0, 0, 0 },
+ { 3, 0x8000, 0x8000, 0, 0, 0 },
+ { 4, 0, 0, 0x8000, 0, 0 },
+ { 5, 0x8000, 0, 0x8000, 0, 0 },
+ { 6, 0, 0x8000, 0x8000, 0, 0 },
+ { 7, 0xc000, 0xc000, 0xc000, 0, 0 },
+ { 8, 0xc000, 0xdc00, 0xc000, 0, 0 },
+ { 9, 0xa600, 0xca00, 0xf000, 0, 0 },
+ { 246, 0xff00, 0xfb00, 0xf000, 0, 0 },
+ { 247, 0xa000, 0xa000, 0xa400, 0, 0 },
+ { 248, 0x8000, 0x8000, 0x8000, 0, 0 },
+ { 249, 0xff00, 0, 0, 0, 0 },
+ { 250, 0, 0xff00, 0, 0, 0 },
+ { 251, 0xff00, 0xff00, 0, 0, 0 },
+ { 252, 0, 0, 0xff00, 0, 0 },
+ { 253, 0xff00, 0, 0xff00, 0, 0 },
+ { 254, 0, 0xff00, 0xff00, 0, 0 },
+ { 255, 0xff00, 0xff00, 0xff00, 0, 0 }
+ };
+#define NUM_DESKTOP_COLORS sizeof citems / sizeof citems[0]
+ int i;
+#else
+ unsigned short zero = 0, ones = 0xFFFF;
+#endif
+ Pixel wp, bp;
+ VisualPtr pVisual;
+ ColormapPtr cmap;
+ int alloctype;
+
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != pScreen->rootVisual;
+ pVisual++)
+ ;
+
+ if (pScreen->rootDepth == 1 || (pVisual->class & DynamicClass))
+ alloctype = AllocNone;
+ else
+ alloctype = AllocAll;
+
+ if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap,
+ alloctype, 0) != Success)
+ return FALSE;
+
+ if (pScreen->rootDepth > 1) {
+ wp = pScreen->whitePixel;
+ bp = pScreen->blackPixel;
+#ifdef WIN32_not_tog
+ for (i = 0; i < NUM_DESKTOP_COLORS; i++) {
+ if (AllocColor (cmap,
+ &citems[i].red, &citems[i].green, &citems[i].blue,
+ &citems[i].pixel, 0) != Success)
+ return FALSE;
+ }
+#else
+ if ((AllocColor(cmap, &ones, &ones, &ones, &wp, 0) !=
+ Success) ||
+ (AllocColor(cmap, &zero, &zero, &zero, &bp, 0) !=
+ Success))
+ return FALSE;
+ pScreen->whitePixel = wp;
+ pScreen->blackPixel = bp;
+#endif
+ }
+
+ (*pScreen->InstallColormap)(cmap);
+ return TRUE;
+}
+
+/*
+ * Default true color bitmasks, should be overridden by
+ * driver
+ */
+
+#define _RZ(d) ((d + 2) / 3)
+#define _RS(d) 0
+#define _RM(d) ((1 << _RZ(d)) - 1)
+#define _GZ(d) ((d - _RZ(d) + 1) / 2)
+#define _GS(d) _RZ(d)
+#define _GM(d) (((1 << _GZ(d)) - 1) << _GS(d))
+#define _BZ(d) (d - _RZ(d) - _GZ(d))
+#define _BS(d) (_RZ(d) + _GZ(d))
+#define _BM(d) (((1 << _BZ(d)) - 1) << _BS(d))
+#define _CE(d) (1 << _RZ(d))
+
+typedef struct _miVisuals {
+ struct _miVisuals *next;
+ int depth;
+ int bitsPerRGB;
+ int visuals;
+ int count;
+ int preferredCVC;
+ Pixel redMask, greenMask, blueMask;
+} miVisualsRec, *miVisualsPtr;
+
+static int miVisualPriority[] = {
+ PseudoColor, GrayScale, StaticColor, TrueColor, DirectColor, StaticGray
+};
+
+#define NUM_PRIORITY 6
+
+static miVisualsPtr miVisuals;
+
+void
+miClearVisualTypes(void)
+{
+ miVisualsPtr v;
+
+ while ((v = miVisuals)) {
+ miVisuals = v->next;
+ xfree(v);
+ }
+}
+
+
+Bool
+miSetVisualTypesAndMasks(int depth, int visuals, int bitsPerRGB,
+ int preferredCVC,
+ Pixel redMask, Pixel greenMask, Pixel blueMask)
+{
+ miVisualsPtr new, *prev, v;
+ int count;
+
+ new = xalloc (sizeof *new);
+ if (!new)
+ return FALSE;
+ if (!redMask || !greenMask || !blueMask)
+ {
+ redMask = _RM(depth);
+ greenMask = _GM(depth);
+ blueMask = _BM(depth);
+ }
+ new->next = 0;
+ new->depth = depth;
+ new->visuals = visuals;
+ new->bitsPerRGB = bitsPerRGB;
+ new->preferredCVC = preferredCVC;
+ new->redMask = redMask;
+ new->greenMask = greenMask;
+ new->blueMask = blueMask;
+ count = (visuals >> 1) & 033333333333;
+ count = visuals - count - ((count >> 1) & 033333333333);
+ count = (((count + (count >> 3)) & 030707070707) % 077); /* HAKMEM 169 */
+ new->count = count;
+ for (prev = &miVisuals; (v = *prev); prev = &v->next);
+ *prev = new;
+ return TRUE;
+}
+
+Bool
+miSetVisualTypes(int depth, int visuals, int bitsPerRGB, int preferredCVC)
+{
+ return miSetVisualTypesAndMasks (depth, visuals, bitsPerRGB,
+ preferredCVC, 0, 0, 0);
+}
+
+int
+miGetDefaultVisualMask(int depth)
+{
+ if (depth > MAX_PSEUDO_DEPTH)
+ return LARGE_VISUALS;
+ else if (depth >= MIN_TRUE_DEPTH)
+ return ALL_VISUALS;
+ else if (depth == 1)
+ return StaticGrayMask;
+ else
+ return SMALL_VISUALS;
+}
+
+static Bool
+miVisualTypesSet (int depth)
+{
+ miVisualsPtr visuals;
+
+ for (visuals = miVisuals; visuals; visuals = visuals->next)
+ if (visuals->depth == depth)
+ return TRUE;
+ return FALSE;
+}
+
+Bool
+miSetPixmapDepths (void)
+{
+ int d, f;
+
+ /* Add any unlisted depths from the pixmap formats */
+ for (f = 0; f < screenInfo.numPixmapFormats; f++)
+ {
+ d = screenInfo.formats[f].depth;
+ if (!miVisualTypesSet (d))
+ {
+ if (!miSetVisualTypes (d, 0, 0, -1))
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+/*
+ * Distance to least significant one bit
+ */
+static int
+maskShift (Pixel p)
+{
+ int s;
+
+ if (!p) return 0;
+ s = 0;
+ while (!(p & 1))
+ {
+ s++;
+ p >>= 1;
+ }
+ return s;
+}
+
+/*
+ * Given a list of formats for a screen, create a list
+ * of visuals and depths for the screen which corespond to
+ * the set which can be used with this version of cfb.
+ */
+
+Bool
+miInitVisuals(VisualPtr *visualp, DepthPtr *depthp, int *nvisualp,
+ int *ndepthp, int *rootDepthp, VisualID *defaultVisp,
+ unsigned long sizes, int bitsPerRGB, int preferredVis)
+
+{
+ int i, j = 0, k;
+ VisualPtr visual;
+ DepthPtr depth;
+ VisualID *vid;
+ int d, b;
+ int f;
+ int ndepth, nvisual;
+ int nvtype;
+ int vtype;
+ miVisualsPtr visuals, nextVisuals;
+ int *preferredCVCs, *prefp;
+ int first_depth;
+
+ /* none specified, we'll guess from pixmap formats */
+ if (!miVisuals)
+ {
+ for (f = 0; f < screenInfo.numPixmapFormats; f++)
+ {
+ d = screenInfo.formats[f].depth;
+ b = screenInfo.formats[f].bitsPerPixel;
+ if (sizes & (1 << (b - 1)))
+ vtype = miGetDefaultVisualMask(d);
+ else
+ vtype = 0;
+ if (!miSetVisualTypes (d, vtype, bitsPerRGB, -1))
+ return FALSE;
+ }
+ }
+ nvisual = 0;
+ ndepth = 0;
+ for (visuals = miVisuals; visuals; visuals = nextVisuals)
+ {
+ nextVisuals = visuals->next;
+ ndepth++;
+ nvisual += visuals->count;
+ }
+ depth = xalloc (ndepth * sizeof (DepthRec));
+ visual = xalloc (nvisual * sizeof (VisualRec));
+ preferredCVCs = xalloc(ndepth * sizeof(int));
+ if (!depth || !visual || !preferredCVCs)
+ {
+ xfree (depth);
+ xfree (visual);
+ xfree (preferredCVCs);
+ return FALSE;
+ }
+ *depthp = depth;
+ *visualp = visual;
+ *ndepthp = ndepth;
+ *nvisualp = nvisual;
+ prefp = preferredCVCs;
+ for (visuals = miVisuals; visuals; visuals = nextVisuals)
+ {
+ nextVisuals = visuals->next;
+ d = visuals->depth;
+ vtype = visuals->visuals;
+ nvtype = visuals->count;
+ *prefp = visuals->preferredCVC;
+ prefp++;
+ vid = NULL;
+ if (nvtype)
+ {
+ vid = xalloc (nvtype * sizeof (VisualID));
+ if (!vid) {
+ xfree(preferredCVCs);
+ return FALSE;
+ }
+ }
+ depth->depth = d;
+ depth->numVids = nvtype;
+ depth->vids = vid;
+ depth++;
+ for (i = 0; i < NUM_PRIORITY; i++) {
+ if (! (vtype & (1 << miVisualPriority[i])))
+ continue;
+ visual->class = miVisualPriority[i];
+ visual->bitsPerRGBValue = visuals->bitsPerRGB;
+ visual->ColormapEntries = 1 << d;
+ visual->nplanes = d;
+ visual->vid = *vid = FakeClientID (0);
+ switch (visual->class) {
+ case PseudoColor:
+ case GrayScale:
+ case StaticGray:
+ visual->redMask = 0;
+ visual->greenMask = 0;
+ visual->blueMask = 0;
+ visual->offsetRed = 0;
+ visual->offsetGreen = 0;
+ visual->offsetBlue = 0;
+ break;
+ case DirectColor:
+ case TrueColor:
+ visual->ColormapEntries = _CE(d);
+ /* fall through */
+ case StaticColor:
+ visual->redMask = visuals->redMask;
+ visual->greenMask = visuals->greenMask;
+ visual->blueMask = visuals->blueMask;
+ visual->offsetRed = maskShift (visuals->redMask);
+ visual->offsetGreen = maskShift (visuals->greenMask);
+ visual->offsetBlue = maskShift (visuals->blueMask);
+ }
+ vid++;
+ visual++;
+ }
+ xfree (visuals);
+ }
+ miVisuals = NULL;
+ visual = *visualp;
+ depth = *depthp;
+
+ /*
+ * if we did not supplyied by a preferred visual class
+ * check if there is a preferred class in one of the depth
+ * structures - if there is, we want to start looking for the
+ * default visual/depth from that depth.
+ */
+ first_depth = 0;
+ if (preferredVis < 0 && defaultColorVisualClass < 0 ) {
+ for (i = 0; i < ndepth; i++) {
+ if (preferredCVCs[i] >= 0) {
+ first_depth = i;
+ break;
+ }
+ }
+ }
+
+ for (i = first_depth; i < ndepth; i++)
+ {
+ int prefColorVisualClass = -1;
+
+ if (defaultColorVisualClass >= 0)
+ prefColorVisualClass = defaultColorVisualClass;
+ else if (preferredVis >= 0)
+ prefColorVisualClass = preferredVis;
+ else if (preferredCVCs[i] >= 0)
+ prefColorVisualClass = preferredCVCs[i];
+
+ if (*rootDepthp && *rootDepthp != depth[i].depth)
+ continue;
+
+ for (j = 0; j < depth[i].numVids; j++)
+ {
+ for (k = 0; k < nvisual; k++)
+ if (visual[k].vid == depth[i].vids[j])
+ break;
+ if (k == nvisual)
+ continue;
+ if (prefColorVisualClass < 0 ||
+ visual[k].class == prefColorVisualClass)
+ break;
+ }
+ if (j != depth[i].numVids)
+ break;
+ }
+ if (i == ndepth) {
+ i = 0;
+ j = 0;
+ }
+ *rootDepthp = depth[i].depth;
+ *defaultVisp = depth[i].vids[j];
+ xfree(preferredCVCs);
+
+ return TRUE;
+}
diff --git a/xorg-server/mi/micoord.h b/xorg-server/mi/micoord.h index e6d814fc8..fe4adac56 100644 --- a/xorg-server/mi/micoord.h +++ b/xorg-server/mi/micoord.h @@ -55,14 +55,14 @@ #endif #if IMAGE_BYTE_ORDER == MSBFirst -#define intToCoord(i,x,y) (((x) = GetHighWord(i)), ((y) = (int) ((short) (i)))) +#define intToCoord(i,x,y) (((x) = GetHighWord(i)), ((y) = (int) ((short) ((i)&0xffff)))) #define coordToInt(x,y) (((x) << 16) | ((y) & 0xffff)) #define intToX(i) (GetHighWord(i)) -#define intToY(i) ((int) ((short) i)) +#define intToY(i) ((int) ((short) ((i)&0xffff))) #else -#define intToCoord(i,x,y) (((x) = (int) ((short) (i))), ((y) = GetHighWord(i))) +#define intToCoord(i,x,y) (((x) = (int) ((short) ((i)&0xffff))), ((y) = GetHighWord(i))) #define coordToInt(x,y) (((y) << 16) | ((x) & 0xffff)) -#define intToX(i) ((int) ((short) (i))) +#define intToX(i) ((int) ((short) ((i)&0xffff))) #define intToY(i) (GetHighWord(i)) #endif diff --git a/xorg-server/mi/mieq.c b/xorg-server/mi/mieq.c index 9b6d0c901..2d5f23ea6 100644 --- a/xorg-server/mi/mieq.c +++ b/xorg-server/mi/mieq.c @@ -439,10 +439,13 @@ mieqProcessInputEvents(void) evlen = e->events->evlen; if(evlen > event_size) + { + event_size=evlen; event = xrealloc(event, evlen); + if (!event) + FatalError("[mi] No memory left for event processing.\n"); + } - if (!event) - FatalError("[mi] No memory left for event processing.\n"); memcpy(event, e->events->event, evlen); diff --git a/xorg-server/mi/miinitext.c b/xorg-server/mi/miinitext.c index 2a67fd371..4e58c49af 100644 --- a/xorg-server/mi/miinitext.c +++ b/xorg-server/mi/miinitext.c @@ -490,7 +490,10 @@ InitExtensions(int argc, char *argv[]) #ifdef GLXEXT if (serverGeneration == 1) + { GlxPushProvider(&__glXDRISWRastProvider); + glxWinPushNativeProvider(); + } if (!noGlxExtension) GlxExtensionInit(); #endif } diff --git a/xorg-server/mi/mioverlay.c b/xorg-server/mi/mioverlay.c index e0aa88017..0577e8c9f 100644 --- a/xorg-server/mi/mioverlay.c +++ b/xorg-server/mi/mioverlay.c @@ -3,6 +3,10 @@ #include <dix-config.h> #endif +#ifdef CreateWindow +#undef CreateWindow +#endif + #include <X11/X.h> #include "scrnintstr.h" #include "validate.h" diff --git a/xorg-server/mi/misprite.c b/xorg-server/mi/misprite.c index 2ec67827e..714c42944 100644 --- a/xorg-server/mi/misprite.c +++ b/xorg-server/mi/misprite.c @@ -502,7 +502,7 @@ miSpriteSourceValidate (DrawablePtr pDrawable, int x, int y, int width, if (DevHasCursor(pDev)) { pCursorInfo = MISPRITE(pDev); - if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && + if (pCursorInfo && pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && ORG_OVERLAP(&pCursorInfo->saved, pDrawable->x, pDrawable->y, x, y, width, height)) { @@ -539,7 +539,7 @@ miSpriteCopyWindow (WindowPtr pWindow, DDXPointRec ptOldOrg, RegionPtr prgnSrc) /* * Damage will take care of destination check */ - if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && + if (pCursorInfo && pCursorInfo->isUp && pCursorInfo->pScreen == pScreen && miRectIn(prgnSrc, &pCursorInfo->saved) != rgnOUT) { SPRITE_DEBUG (("CopyWindow remove\n")); @@ -622,9 +622,12 @@ miSpriteInstallColormap (ColormapPtr pMap) if (DevHasCursor(pDev)) { pCursorInfo = MISPRITE(pDev); - pCursorInfo->checkPixels = TRUE; - if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) - miSpriteRemoveCursor(pDev, pScreen); + if (pCursorInfo) + { + pCursorInfo->checkPixels = TRUE; + if (pCursorInfo->isUp && pCursorInfo->pScreen == pScreen) + miSpriteRemoveCursor(pDev, pScreen); + } } } diff --git a/xorg-server/mi/miwideline.c b/xorg-server/mi/miwideline.c index 210a6251e..838b06c68 100644 --- a/xorg-server/mi/miwideline.c +++ b/xorg-server/mi/miwideline.c @@ -45,6 +45,10 @@ from The Open Group. #include <math.h> #undef _XOPEN_SOURCE #endif +#ifdef _MSC_VER +#define hypot _hypot +#endif + #include <X11/X.h> #include "windowstr.h" #include "gcstruct.h" diff --git a/xorg-server/miext/damage/damage.c b/xorg-server/miext/damage/damage.c index b7ec92a5b..c2317178e 100644 --- a/xorg-server/miext/damage/damage.c +++ b/xorg-server/miext/damage/damage.c @@ -2140,7 +2140,7 @@ DamageRegionRendered (DrawablePtr pDrawable, DamagePtr pDamage, RegionPtr pOldDa /* This call is very odd, i'm leaving it intact for API sake, but please don't use it. */ void DamageDamageRegion (DrawablePtr pDrawable, - RegionPtr pRegion) + const RegionPtr pRegion) { damageRegionAppend (pDrawable, pRegion, FALSE, -1); diff --git a/xorg-server/miext/damage/makefile b/xorg-server/miext/damage/makefile new file mode 100644 index 000000000..e58f4a883 --- /dev/null +++ b/xorg-server/miext/damage/makefile @@ -0,0 +1,7 @@ +LIBRARY = libdamage + +#INCLUDES = -I$(srcdir)/../cw -I$(top_srcdir)/hw/xfree86/os-support + +CSRCS =damage.c + + diff --git a/xorg-server/miext/rootless/makefile b/xorg-server/miext/rootless/makefile new file mode 100644 index 000000000..4ad30b75e --- /dev/null +++ b/xorg-server/miext/rootless/makefile @@ -0,0 +1,9 @@ +LIBRARY=librootless + +CSRCS = \ + rootlessCommon.c \ + rootlessGC.c \ + rootlessScreen.c \ + rootlessValTree.c +# rootlessWindow.c + diff --git a/xorg-server/miext/rootless/rootlessCommon.c b/xorg-server/miext/rootless/rootlessCommon.c index 39a3eed0f..b96422b76 100644 --- a/xorg-server/miext/rootless/rootlessCommon.c +++ b/xorg-server/miext/rootless/rootlessCommon.c @@ -147,7 +147,7 @@ void RootlessStartDrawing(WindowPtr pWindow) WindowPtr top = TopLevelParent(pWindow); RootlessWindowRec *winRec; PixmapPtr curPixmap; - + if (top == NULL) return; winRec = WINREC(top); diff --git a/xorg-server/miext/rootless/rootlessGC.c b/xorg-server/miext/rootless/rootlessGC.c index 0bd314d46..5167f0ebe 100644 --- a/xorg-server/miext/rootless/rootlessGC.c +++ b/xorg-server/miext/rootless/rootlessGC.c @@ -49,6 +49,9 @@ #include "rootlessCommon.h" +#ifdef _MSC_VER +#define inline __inline +#endif // GC functions static void RootlessValidateGC(GCPtr pGC, unsigned long changes, diff --git a/xorg-server/miext/rootless/rootlessWindow.c b/xorg-server/miext/rootless/rootlessWindow.c index 53209565d..53028b5c1 100644 --- a/xorg-server/miext/rootless/rootlessWindow.c +++ b/xorg-server/miext/rootless/rootlessWindow.c @@ -51,6 +51,12 @@ extern Bool no_configure_window; #include "rootlessCommon.h" #include "rootlessWindow.h" +#ifdef _MSC_VER +#define inline __inline +#include "xplugin.h" +extern int darwinMainScreenX, darwinMainScreenY; +#endif + #ifdef ROOTLESS_GLOBAL_COORDS #define SCREEN_TO_GLOBAL_X \ (dixScreenOrigins[pScreen->myNum].x + rootlessGlobalOffsetX) @@ -72,6 +78,7 @@ extern Bool no_configure_window; return atom; \ } + DEFINE_ATOM_HELPER (xa_native_window_id, "_NATIVE_WINDOW_ID") static Bool windows_hidden; diff --git a/xorg-server/miext/rootless/xplugin.h b/xorg-server/miext/rootless/xplugin.h new file mode 100644 index 000000000..7fdf6006e --- /dev/null +++ b/xorg-server/miext/rootless/xplugin.h @@ -0,0 +1,592 @@ +/* Xplugin.h -- windowing API for rootless X11 server + $Id$ + + Copyright (c) 2002 Apple Computer, 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 ABOVE LISTED COPYRIGHT + HOLDER(S) 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(s) of the above + copyright holders shall not be used in advertising or otherwise to + promote the sale, use or other dealings in this Software without + prior written authorization. + + Note that these interfaces are provided solely for the use of the + X11 server. Any other uses are unsupported and strongly discouraged. */ +/* $XFree86: xc/programs/Xserver/hw/darwin/quartz/xpr/Xplugin.h,v 1.2 2003/05/02 00:08:49 torrey Exp $ */ + +#ifndef XPLUGIN_H +#define XPLUGIN_H 1 + +#include <stdint.h> + +/* By default we use the X server definition of BoxRec to define xp_box, + so that the compiler can silently convert between the two. But if + XP_NO_X_HEADERS is defined, we'll define it ourselves. */ + +#ifndef XP_NO_X_HEADERS +# include "miscstruct.h" + typedef BoxRec xp_box; +#else + struct xp_box_struct { + short x1, y1, x2, y2; + }; + typedef struct xp_box_struct xp_box; +#endif + +typedef unsigned int xp_resource_id; +typedef xp_resource_id xp_window_id; +typedef xp_resource_id xp_surface_id; +typedef unsigned int xp_client_id; +typedef unsigned int xp_request_type; +typedef int xp_error; +typedef int xp_bool; + + +/* Error codes that the functions declared here may return. They all + numerically match their X equivalents, i.e. the XP_ can be dropped + if <X11/X.h> has been included. */ + +enum xp_error_enum { + XP_Success = 0, + XP_BadRequest = 1, + XP_BadValue = 2, + XP_BadWindow = 3, + XP_BadMatch = 8, + XP_BadAccess = 10, + XP_BadImplementation = 17, +}; + + +/* Event types generated by the plugin. */ + +enum xp_event_type_enum { + /* The global display configuration changed somehow. */ + XP_EVENT_DISPLAY_CHANGED = 1 << 0, + + /* A window changed state. Argument is xp_window_state_event */ + XP_EVENT_WINDOW_STATE_CHANGED = 1 << 1, + + /* An async request encountered an error. Argument is of type + xp_async_error_event */ + XP_EVENT_ASYNC_ERROR = 1 << 2, + + /* Sent when a surface is destroyed as a side effect of destroying + a window. Arg is of type xp_surface_id. */ + XP_EVENT_SURFACE_DESTROYED = 1 << 3, + + /* Sent when any GL contexts pointing at the given surface need to + call xp_update_gl_context () to refresh their state (because the + window moved or was resized. Arg is of type xp_surface_id. */ + XP_EVENT_SURFACE_CHANGED = 1 << 4, + + /* Sent when a window has been moved. Arg is of type xp_window_id. */ + XP_EVENT_WINDOW_MOVED = 1 << 5, +}; + +/* Function type used to receive events. */ + +typedef void (xp_event_fun) (unsigned int type, const void *arg, + unsigned int arg_size, void *user_data); + + +/* Operation types. Used when reporting errors asynchronously. */ + +enum xp_request_type_enum { + XP_REQUEST_NIL = 0, + XP_REQUEST_DESTROY_WINDOW = 1, + XP_REQUEST_CONFIGURE_WINDOW = 2, + XP_REQUEST_FLUSH_WINDOW = 3, + XP_REQUEST_COPY_WINDOW = 4, + XP_REQUEST_UNLOCK_WINDOW = 5, + XP_REQUEST_DISABLE_UPDATE = 6, + XP_REQUEST_REENABLE_UPDATE = 7, + XP_REQUEST_HIDE_CURSOR = 8, + XP_REQUEST_SHOW_CURSOR = 9, + XP_REQUEST_FRAME_DRAW = 10, +}; + +/* Structure used to report an error asynchronously. Passed as the "arg" + of an XP_EVENT_ASYNC_ERROR event. */ + +struct xp_async_error_event_struct { + xp_request_type request_type; + xp_resource_id id; + xp_error error; +}; + +typedef struct xp_async_error_event_struct xp_async_error_event; + + +/* Possible window states. */ + +enum xp_window_state_enum { + /* The window is not in the global list of possibly-visible windows. */ + XP_WINDOW_STATE_OFFSCREEN = 1 << 0, + + /* Parts of the window may be obscured by other windows. */ + XP_WINDOW_STATE_OBSCURED = 1 << 1, +}; + +/* Structure passed as argument of an XP_EVENT_WINDOW_STATE_CHANGED event. */ + +struct xp_window_state_event_struct { + xp_window_id id; + unsigned int state; +}; + +typedef struct xp_window_state_event_struct xp_window_state_event; + + +/* Function type used to supply a colormap for indexed drawables. */ + +typedef xp_error (xp_colormap_fun) (void *data, int first_color, + int n_colors, uint32_t *colors); + + +/* Window attributes structure. Used when creating and configuring windows. + Also used when configuring surfaces attached to windows. Functions that + take one of these structures also take a bit mask defining which + fields are set to meaningful values. */ + +enum xp_window_changes_enum { + XP_ORIGIN = 1 << 0, + XP_SIZE = 1 << 1, + XP_BOUNDS = XP_ORIGIN | XP_SIZE, + XP_SHAPE = 1 << 2, + XP_STACKING = 1 << 3, + XP_DEPTH = 1 << 4, + XP_COLORMAP = 1 << 5, + XP_WINDOW_LEVEL = 1 << 6, +}; + +struct xp_window_changes_struct { + /* XP_ORIGIN */ + int x, y; + + /* XP_SIZE */ + unsigned int width, height; + int bit_gravity; /* how to resize the backing store */ + + /* XP_SHAPE */ + int shape_nrects; /* -1 = remove shape */ + xp_box *shape_rects; + int shape_tx, shape_ty; /* translation for shape */ + + /* XP_STACKING */ + int stack_mode; + xp_window_id sibling; /* may be zero; in ABOVE/BELOW modes + it may specify a relative window */ + /* XP_DEPTH, window-only */ + unsigned int depth; + + /* XP_COLORMAP, window-only */ + xp_colormap_fun *colormap; + void *colormap_data; + + /* XP_WINDOW_LEVEL, window-only */ + int window_level; +}; + +typedef struct xp_window_changes_struct xp_window_changes; + +/* Values for bit_gravity field */ + +enum xp_bit_gravity_enum { + XP_GRAVITY_NONE = 0, /* no gravity, fill everything */ + XP_GRAVITY_NORTH_WEST = 1, /* anchor to top-left corner */ + XP_GRAVITY_NORTH_EAST = 2, /* anchor to top-right corner */ + XP_GRAVITY_SOUTH_EAST = 3, /* anchor to bottom-right corner */ + XP_GRAVITY_SOUTH_WEST = 4, /* anchor to bottom-left corner */ +}; + +/* Values for stack_mode field */ + +enum xp_window_stack_mode_enum { + XP_UNMAPPED = 0, /* remove the window */ + XP_MAPPED_ABOVE = 1, /* display the window on top */ + XP_MAPPED_BELOW = 2, /* display the window at bottom */ +}; + +/* Data formats for depth field and composite functions */ + +enum xp_depth_enum { + XP_DEPTH_NIL = 0, /* null source when compositing */ + XP_DEPTH_ARGB8888, + XP_DEPTH_RGB555, + XP_DEPTH_A8, /* for masks when compositing */ + XP_DEPTH_INDEX8, +}; + +/* Options that may be passed to the xp_init () function. */ + +enum xp_init_options_enum { + /* Don't mark that this process can be in the foreground. */ + XP_IN_BACKGROUND = 1 << 0, + + /* Deliver background pointer events to this process. */ + XP_BACKGROUND_EVENTS = 1 << 1, +}; + + + +/* Miscellaneous functions */ + +/* Initialize the plugin library. Only the copy/fill/composite functions + may be called without having previously called xp_init () */ + +extern xp_error xp_init (unsigned int options); + +/* Sets the current set of requested notifications to MASK. When any of + these arrive, CALLBACK will be invoked with CALLBACK-DATA. Note that + calling this function cancels any previously requested notifications + that aren't set in MASK. */ + +extern xp_error xp_select_events (unsigned int mask, + xp_event_fun *callback, + void *callback_data); + +/* Waits for all initiated operations to complete. */ + +extern xp_error xp_synchronize (void); + +/* Causes any display update initiated through the plugin libary to be + queued until update is reenabled. Note that calls to these functions + nest. */ + +extern xp_error xp_disable_update (void); +extern xp_error xp_reenable_update (void); + + + +/* Cursor functions. */ + +/* Installs the specified cursor. ARGB-DATA should point to 32-bit + premultiplied big-endian ARGB data. The HOT-X,HOT-Y parameters + specify the offset to the cursor's hot spot from its top-left + corner. */ + +extern xp_error xp_set_cursor (unsigned int width, unsigned int height, + unsigned int hot_x, unsigned int hot_y, + const uint32_t *argb_data, + unsigned int rowbytes); + +/* Hide and show the cursor if it's owned by the current process. Calls + to these functions nest. */ + +extern xp_error xp_hide_cursor (void); +extern xp_error xp_show_cursor (void); + + + +/* Window functions. */ + +/* Create a new window as defined by MASK and VALUES. MASK must contain + XP_BOUNDS or an error is raised. The id of the newly created window + is stored in *RET-ID if this function returns XP_Success. */ + +extern xp_error xp_create_window (unsigned int mask, + const xp_window_changes *values, + xp_window_id *ret_id); + +/* Destroys the window identified by ID. */ + +extern xp_error xp_destroy_window (xp_window_id id); + +/* Reconfigures the given window according to MASK and VALUES. */ + +extern xp_error xp_configure_window (xp_window_id id, unsigned int mask, + const xp_window_changes *values); + + +/* Returns true if NATIVE-ID is a window created by the plugin library. + If so and RET-ID is non-null, stores the id of the window in *RET-ID. */ + +extern xp_bool xp_lookup_native_window (unsigned int native_id, + xp_window_id *ret_id); + +/* If ID names a window created by the plugin library, stores it's native + window id in *RET-NATIVE-ID. */ + +extern xp_error xp_get_native_window (xp_window_id id, + unsigned int *ret_native_id); + + +/* Locks the rectangle IN-RECT (or, if null, the entire window) of the + given window's backing store. Any other non-null parameters are filled + in as follows: + + DEPTH = format of returned data. Currently either XP_DEPTH_ARGB8888 + or XP_DEPTH_RGB565 (possibly with 8 bit planar alpha). Data is + always stored in native byte order. + + BITS[0] = pointer to top-left pixel of locked color data + BITS[1] = pointer to top-left of locked alpha data, or null if window + has no alpha. If the alpha data is meshed, then BITS[1] = BITS[0]. + + ROWBYTES[0,1] = size in bytes of each row of color,alpha data + + OUT-RECT = rectangle specifying the current position and size of the + locked region relative to the window origin. + + Note that an error is raised when trying to lock an already locked + window. While the window is locked, the only operations that may + be performed on it are to modify, access or flush its marked region. */ + +extern xp_error xp_lock_window (xp_window_id id, + const xp_box *in_rect, + unsigned int *depth, + void *bits[2], + unsigned int rowbytes[2], + xp_box *out_rect); + +/* Mark that the region specified by SHAPE-NRECTS, SHAPE-RECTS, + SHAPE-TX, and SHAPE-TY in the specified window has been updated, and + will need to subsequently be redisplayed. */ + +extern xp_error xp_mark_window (xp_window_id id, int shape_nrects, + const xp_box *shape_rects, + int shape_tx, int shape_ty); + +/* Unlocks the specified window. If FLUSH is true, then any marked + regions are immediately redisplayed. Note that it's an error to + unlock an already unlocked window. */ + +extern xp_error xp_unlock_window (xp_window_id id, xp_bool flush); + +/* If anything is marked in the given window for redisplay, do it now. */ + +extern xp_error xp_flush_window (xp_window_id id); + +/* Moves the contents of the region DX,DY pixels away from that specified + by DST_RECTS and DST_NRECTS in the window with SRC-ID to the + destination region in the window DST-ID. Note that currently source + and destination windows must be the same. */ + +extern xp_error xp_copy_window (xp_window_id src_id, xp_window_id dst_id, + int dst_nrects, const xp_box *dst_rects, + int dx, int dy); + +/* Returns true if the given window has any regions marked for + redisplay. */ + +extern xp_bool xp_is_window_marked (xp_window_id id); + +/* If successful returns a superset of the region marked for update in + the given window. Use xp_free_region () to release the returned data. */ + +extern xp_error xp_get_marked_shape (xp_window_id id, + int *ret_nrects, xp_box **ret_rects); + +extern void xp_free_shape (int nrects, xp_box *rects); + +/* Searches for the first window below ABOVE-ID containing the point X,Y, + and returns it's window id in *RET-ID. If no window is found, *RET-ID + is set to zero. If ABOVE-ID is zero, finds the topmost window + containing the given point. */ + +extern xp_error xp_find_window (int x, int y, xp_window_id above_id, + xp_window_id *ret_id); + +/* Returns the current origin and size of the window ID in *BOUNDS-RET if + successful. */ +extern xp_error xp_get_window_bounds (xp_window_id id, xp_box *bounds_ret); + + + +/* Window surface functions. */ + +/* Create a new VRAM surface on the specified window. If successful, + returns the identifier of the new surface in *RET-SID. */ + +extern xp_error xp_create_surface (xp_window_id id, xp_surface_id *ret_sid); + +/* Destroys the specified surface. */ + +extern xp_error xp_destroy_surface (xp_surface_id sid); + +/* Reconfigures the specified surface as defined by MASK and VALUES. + Note that specifying XP_DEPTH is an error. */ + +extern xp_error xp_configure_surface (xp_surface_id sid, unsigned int mask, + const xp_window_changes *values); + +/* If successful, places the client identifier of the current process + in *RET-CLIENT. */ + +extern xp_error xp_get_client_id (xp_client_id *ret_client); + +/* Given a valid window,surface combination created by the current + process, attempts to allow the specified external client access + to that surface. If successful, returns two integers in RET-KEY + which the client can use to import the surface into their process. */ + +extern xp_error xp_export_surface (xp_window_id wid, xp_surface_id sid, + xp_client_id client, + unsigned int ret_key[2]); + +/* Given a two integer key returned from xp_export_surface (), tries + to import the surface into the current process. If successful the + local surface identifier is stored in *SID-RET. */ + +extern xp_error xp_import_surface (const unsigned int key[2], + xp_surface_id *sid_ret); + +/* If successful, stores the number of surfaces attached to the + specified window in *RET. */ + +extern xp_error xp_get_window_surface_count (xp_window_id id, + unsigned int *ret); + +/* Attaches the CGLContextObj CGL-CTX to the specified surface. */ + +extern xp_error xp_attach_gl_context (void *cgl_ctx, xp_surface_id sid); + +/* Updates the CGLContextObj CGL-CTX to reflect any recent changes to + the surface it's attached to. */ + +extern xp_error xp_update_gl_context (void *cgl_ctx); + + + +/* Window frame functions. */ + +/* Possible arguments to xp_frame_get_rect (). */ + +enum xp_frame_rect_enum { + XP_FRAME_RECT_TITLEBAR = 1, + XP_FRAME_RECT_TRACKING = 2, + XP_FRAME_RECT_GROWBOX = 3, +}; + +/* Classes of window frame. */ + +enum xp_frame_class_enum { + XP_FRAME_CLASS_DOCUMENT = 1 << 0, + XP_FRAME_CLASS_DIALOG = 1 << 1, + XP_FRAME_CLASS_MODAL_DIALOG = 1 << 2, + XP_FRAME_CLASS_SYSTEM_MODAL_DIALOG = 1 << 3, + XP_FRAME_CLASS_UTILITY = 1 << 4, + XP_FRAME_CLASS_TOOLBAR = 1 << 5, + XP_FRAME_CLASS_MENU = 1 << 6, + XP_FRAME_CLASS_SPLASH = 1 << 7, + XP_FRAME_CLASS_BORDERLESS = 1 << 8, +}; + +/* Attributes of window frames. */ + +enum xp_frame_attr_enum { + XP_FRAME_ACTIVE = 0x0001, + XP_FRAME_URGENT = 0x0002, + XP_FRAME_TITLE = 0x0004, + XP_FRAME_PRELIGHT = 0x0008, + XP_FRAME_SHADED = 0x0010, + XP_FRAME_CLOSE_BOX = 0x0100, + XP_FRAME_COLLAPSE = 0x0200, + XP_FRAME_ZOOM = 0x0400, + XP_FRAME_ANY_BUTTON = 0x0700, + XP_FRAME_CLOSE_BOX_CLICKED = 0x0800, + XP_FRAME_COLLAPSE_BOX_CLICKED = 0x1000, + XP_FRAME_ZOOM_BOX_CLICKED = 0x2000, + XP_FRAME_ANY_CLICKED = 0x3800, + XP_FRAME_GROW_BOX = 0x4000, +}; + +#define XP_FRAME_ATTR_IS_SET(a,b) (((a) & (b)) == (b)) +#define XP_FRAME_ATTR_IS_CLICKED(a,m) ((a) & ((m) << 3)) +#define XP_FRAME_ATTR_SET_CLICKED(a,m) ((a) |= ((m) << 3)) +#define XP_FRAME_ATTR_UNSET_CLICKED(a,m) ((a) &= ~((m) << 3)) + +#define XP_FRAME_POINTER_ATTRS (XP_FRAME_PRELIGHT \ + | XP_FRAME_ANY_BUTTON \ + | XP_FRAME_ANY_CLICKED) + +extern xp_error xp_frame_get_rect (int type, int class, const xp_box *outer, + const xp_box *inner, xp_box *ret); +extern xp_error xp_frame_hit_test (int class, int x, int y, + const xp_box *outer, + const xp_box *inner, int *ret); +extern xp_error xp_frame_draw (xp_window_id wid, int class, unsigned int attr, + const xp_box *outer, const xp_box *inner, + unsigned int title_len, + const unsigned char *title_bytes); + + + +/* Memory manipulation functions. */ + +enum xp_composite_op_enum { + XP_COMPOSITE_SRC = 0, + XP_COMPOSITE_OVER, +}; + +#define XP_COMPOSITE_FUNCTION(op, src_depth, mask_depth, dest_depth) \ + (((op) << 24) | ((src_depth) << 16) \ + | ((mask_depth) << 8) | ((dest_depth) << 0)) + +#define XP_COMPOSITE_FUNCTION_OP(f) (((f) >> 24) & 255) +#define XP_COMPOSITE_FUNCTION_SRC_DEPTH(f) (((f) >> 16) & 255) +#define XP_COMPOSITE_FUNCTION_MASK_DEPTH(f) (((f) >> 8) & 255) +#define XP_COMPOSITE_FUNCTION_DEST_DEPTH(f) (((f) >> 0) & 255) + +/* Composite WIDTH by HEIGHT pixels from source and mask to destination + using a specified function (if source and destination overlap, + undefined behavior results). + + For SRC and DEST, the first element of the array is the color data. If + the second element is non-null it implies that there is alpha data + (which may be meshed or planar). Data without alpha is assumed to be + opaque. + + Passing a null SRC-ROWBYTES pointer implies that the data SRC points + to is a single element. + + Operations that are not supported will return XP_BadImplementation. */ + +extern xp_error xp_composite_pixels (unsigned int width, unsigned int height, + unsigned int function, + void *src[2], unsigned int src_rowbytes[2], + void *mask, unsigned int mask_rowbytes, + void *dest[2], unsigned int dest_rowbytes[2]); + +/* Fill HEIGHT rows of data starting at DST. Each row will have WIDTH + bytes filled with the 32-bit pattern VALUE. Each row is DST-ROWBYTES + wide in total. */ + +extern void xp_fill_bytes (unsigned int width, + unsigned int height, uint32_t value, + void *dst, unsigned int dst_rowbytes); + +/* Copy HEIGHT rows of bytes from SRC to DST. Each row will have WIDTH + bytes copied. SRC and DST may overlap, and the right thing will happen. */ + +extern void xp_copy_bytes (unsigned int width, unsigned int height, + const void *src, unsigned int src_rowbytes, + void *dst, unsigned int dst_rowbytes); + +/* Suggestions for the minimum number of bytes or pixels for which it + makes sense to use some of the xp_ functions */ + +extern unsigned int xp_fill_bytes_threshold, xp_copy_bytes_threshold, + xp_composite_area_threshold, xp_scroll_area_threshold; + + +#endif /* XPLUGIN_H */ + diff --git a/xorg-server/miext/shadow/makefile b/xorg-server/miext/shadow/makefile new file mode 100644 index 000000000..0a84b506c --- /dev/null +++ b/xorg-server/miext/shadow/makefile @@ -0,0 +1,25 @@ +LIBRARY = libshadow + +#INCLUDES = -I$(top_srcdir)/hw/xfree86/os-support + +CSRCS = shadow.c \ + shalloc.c \ + shpacked.c \ + shplanar8.c \ + shplanar.c \ + shrot16pack_180.c \ + shrot16pack_270.c \ + shrot16pack_270YX.c \ + shrot16pack_90.c \ + shrot16pack_90YX.c \ + shrot16pack.c \ + shrot32pack_180.c \ + shrot32pack_270.c \ + shrot32pack_90.c \ + shrot32pack.c \ + shrot8pack_180.c \ + shrot8pack_270.c \ + shrot8pack_90.c \ + shrot8pack.c \ + shrotate.c + diff --git a/xorg-server/os/WaitFor.c b/xorg-server/os/WaitFor.c index dfe85e515..7199680cd 100644 --- a/xorg-server/os/WaitFor.c +++ b/xorg-server/os/WaitFor.c @@ -209,6 +209,12 @@ WaitForSomething(int *pClientsReady) wt = &waittime; } } + if (!wt) + { + wt = &waittime; + waittime.tv_sec = 0; + waittime.tv_usec = 100; + } XFD_COPYSET(&AllSockets, &LastSelectMask); } SmartScheduleStopTimer (); diff --git a/xorg-server/os/connection.c b/xorg-server/os/connection.c index 3ff93bbb6..39f1dae87 100644 --- a/xorg-server/os/connection.c +++ b/xorg-server/os/connection.c @@ -67,6 +67,9 @@ SOFTWARE. #ifdef WIN32 #include <X11/Xwinsock.h> +#ifdef _DEBUG +#define DEBUG +#endif #endif #include <X11/X.h> #include <X11/Xproto.h> @@ -111,6 +114,10 @@ SOFTWARE. #include "dixstruct.h" #include "xace.h" +#ifdef _MSC_VER +typedef int pid_t; +#endif + #define Pid_t pid_t #ifdef DNETCONN @@ -270,6 +277,23 @@ lookup_trans_conn (int fd) return (NULL); } +int +TransIsListening(char *protocol) +{ + /* look for this transport in the list of listeners */ + int i; + for (i = 0; i < ListenTransCount; i++) + { + if (!strcmp(protocol, ListenTransConns[i]->transptr->TransName)) + { + return 1; + } + } + + return 0; +} + + /* Set MaxClients and lastfdesc, and allocate ConnectionTranslation */ void @@ -1033,6 +1057,10 @@ CloseDownConnection(ClientPtr client) { OsCommPtr oc = (OsCommPtr)client->osPrivate; +#ifdef DEBUG + ErrorF("CloseDownConnection: client index = %d, socket fd = %d\n", + client->index, oc->fd); +#endif if (oc->output && oc->output->count) FlushClient(client, oc, (char *)NULL, 0); #ifdef XDMCP diff --git a/xorg-server/os/io.c b/xorg-server/os/io.c index 64b64ae75..beccdf5b1 100644 --- a/xorg-server/os/io.c +++ b/xorg-server/os/io.c @@ -913,6 +913,7 @@ FlushClient(ClientPtr who, OsCommPtr oc, const void *__extraBuf, int extraCount) /* If we've arrived here, then the client is stuffed to the gills and not ready to accept more. Make a note of it and buffer the rest. */ + errno=0; FD_SET(connection, &ClientsWriteBlocked); AnyClientsWriteBlocked = TRUE; diff --git a/xorg-server/os/log.c b/xorg-server/os/log.c index 20cd74af6..02267638f 100644 --- a/xorg-server/os/log.c +++ b/xorg-server/os/log.c @@ -95,8 +95,14 @@ OR PERFORMANCE OF THIS SOFTWARE. #ifdef WIN32
#include <process.h>
+#ifndef _MSC_VER
#define getpid(x) _getpid(x)
#endif
+#endif
+
+#ifdef _MSC_VER
+#define S_ISREG(m) (((m)&_S_IFMT) == _S_IFREG)
+#endif
#ifdef XF86BIGFONT
#define _XF86BIGFONT_SERVER_
@@ -256,7 +262,7 @@ LogSetParameter(LogParameter param, int value) void
LogVWrite(int verb, const char *f, va_list args)
{
- static char tmpBuffer[1024];
+ char tmpBuffer[1024];
int len = 0;
static Bool newline = TRUE;
@@ -273,7 +279,8 @@ LogVWrite(int verb, const char *f, va_list args) * stream(s).
*/
if (verb < 0 || logFileVerbosity >= verb || logVerbosity >= verb) {
- vsnprintf(tmpBuffer, sizeof(tmpBuffer), f, args);
+ vsnprintf(tmpBuffer, sizeof(tmpBuffer)-1, f, args);
+ tmpBuffer[sizeof(tmpBuffer)-1]=0;
len = strlen(tmpBuffer);
}
newline = (tmpBuffer[len-1] == '\n');
diff --git a/xorg-server/os/makefile b/xorg-server/os/makefile new file mode 100644 index 000000000..e7a286970 --- /dev/null +++ b/xorg-server/os/makefile @@ -0,0 +1,36 @@ +ifeq ($(DEBUG),1)
+DEFINES += XSERVER_DTRACE
+endif
+
+SECURERPC_SRCS = rpcauth.c
+XDMCP_SRCS = xdmcp.c
+STRLCAT_SRCS = strlcat.c strlcpy.c
+XORG_SRCS = log.c
+
+CSRCS = \
+ WaitFor.c \
+ access.c \
+ auth.c \
+ backtrace.c \
+ connection.c \
+ io.c \
+ mitauth.c \
+ oscolor.c \
+ osinit.c \
+ utils.c \
+ strcasecmp.c \
+ strcasestr.c \
+ xdmauth.c \
+ xsha1.c \
+ xstrans.c \
+ xprintf.c \
+ $(XORG_SRCS)
+
+CSRCS += $(SECURERPC_SRCS)
+
+CSRCS += $(XDMCP_SRCS)
+
+CSRCS += $(STRLCAT_SRCS)
+
+LIBRARY=libos
+
diff --git a/xorg-server/os/oscolor.c b/xorg-server/os/oscolor.c index 7f6b93880..4e1513f53 100644 --- a/xorg-server/os/oscolor.c +++ b/xorg-server/os/oscolor.c @@ -49,6 +49,10 @@ SOFTWARE. #include <dix-config.h> #endif +#ifdef _MSC_VER +#define strncasecmp _strnicmp +#endif + #include <X11/keysym.h> #include "os.h" diff --git a/xorg-server/os/osinit.c b/xorg-server/os/osinit.c index e8fcd4540..23a45e5b7 100644 --- a/xorg-server/os/osinit.c +++ b/xorg-server/os/osinit.c @@ -166,6 +166,7 @@ OsInit(void) char fname[PATH_MAX]; if (!been_here) { +#ifndef _MSC_VER struct sigaction act, oact; int i; int siglist[] = { SIGSEGV, SIGQUIT, SIGILL, SIGFPE, SIGBUS, @@ -215,7 +216,7 @@ OsInit(void) int failure_signal = SIGQUIT; dlinfo(RTLD_SELF, RTLD_DI_SETSIGNAL, &failure_signal); #endif - +#endif #if !defined(__SCO__) && !defined(__CYGWIN__) && !defined(__UNIXWARE__) fclose(stdin); fclose(stdout); @@ -254,8 +255,10 @@ OsInit(void) #endif } +#ifndef _MSC_VER if (getpgrp () == 0) setpgid (0, 0); +#endif #ifdef RLIMIT_DATA if (limitDataSpace >= 0) diff --git a/xorg-server/os/utils.c b/xorg-server/os/utils.c index 79399fa53..b5015b2c9 100644 --- a/xorg-server/os/utils.c +++ b/xorg-server/os/utils.c @@ -217,6 +217,9 @@ static char *dev_tty_from_init = NULL; /* since we need to parse it anyway */ OsSigHandlerPtr OsSignal(int sig, OsSigHandlerPtr handler) { +#ifdef X_NOT_POSIX + return signal(sig, handler); +#else struct sigaction act, oact; sigemptyset(&act.sa_mask); @@ -227,6 +230,7 @@ OsSignal(int sig, OsSigHandlerPtr handler) if (sigaction(sig, &act, &oact)) perror("sigaction"); return oact.sa_handler; +#endif } /* @@ -252,7 +256,7 @@ OsSignal(int sig, OsSigHandlerPtr handler) #endif static Bool StillLocking = FALSE; -static char LockFile[PATH_MAX]; +static char szLockFile[PATH_MAX]; static Bool nolock = FALSE; /* @@ -264,26 +268,34 @@ static Bool nolock = FALSE; void LockServer(void) { +#if defined(WIN32) && !defined(__CYGWIN__) + char MutexName[100]; + sprintf(MutexName, "Global\\VcXsrv_Mutex_%d\n", getpid()); + if (!CreateMutex(NULL,TRUE,MutexName) || GetLastError()== ERROR_ALREADY_EXISTS) + { + FatalError("Server is already active for display %d\n", atoi(display)); + } +#else + char port[20]; char tmp[PATH_MAX], pid_str[12]; int lfd, i, haslock, l_pid, t; char *tmppath = NULL; int len; - char port[20]; if (nolock) return; /* * Path names */ tmppath = LOCK_DIR; - sprintf(port, "%d", atoi(display)); + len = strlen(LOCK_PREFIX) > strlen(LOCK_TMP_PREFIX) ? strlen(LOCK_PREFIX) : strlen(LOCK_TMP_PREFIX); len += strlen(tmppath) + strlen(port) + strlen(LOCK_SUFFIX) + 1; - if (len > sizeof(LockFile)) + if (len > sizeof(szLockFile)) FatalError("Display name `%s' is too long\n", port); (void)sprintf(tmp, "%s" LOCK_TMP_PREFIX "%s" LOCK_SUFFIX, tmppath, port); - (void)sprintf(LockFile, "%s" LOCK_PREFIX "%s" LOCK_SUFFIX, tmppath, port); + (void)sprintf(szLockFile, "%s" LOCK_PREFIX "%s" LOCK_SUFFIX, tmppath, port); /* * Create a temporary file containing our PID. Attempt three times @@ -325,7 +337,7 @@ LockServer(void) i = 0; haslock = 0; while ((!haslock) && (i++ < 3)) { - haslock = (link(tmp,LockFile) == 0); + haslock = (link(tmp,szLockFile) == 0); if (haslock) { /* * We're done. @@ -336,17 +348,17 @@ LockServer(void) /* * Read the pid from the existing file */ - lfd = open(LockFile, O_RDONLY); + lfd = open(szLockFile, O_RDONLY); if (lfd < 0) { unlink(tmp); - FatalError("Can't read lock file %s\n", LockFile); + FatalError("Can't read lock file %s\n", szLockFile); } pid_str[0] = '\0'; if (read(lfd, pid_str, 11) != 11) { /* * Bogus lock file. */ - unlink(LockFile); + unlink(szLockFile); close(lfd); continue; } @@ -363,7 +375,7 @@ LockServer(void) /* * Stale lock file. */ - unlink(LockFile); + unlink(szLockFile); continue; } else if (((t < 0) && (errno == EPERM)) || (t == 0)) { @@ -373,14 +385,15 @@ LockServer(void) unlink(tmp); FatalError("Server is already active for display %s\n%s %s\n%s\n", port, "\tIf this server is no longer running, remove", - LockFile, "\tand start again."); + szLockFile, "\tand start again."); } } } unlink(tmp); if (!haslock) - FatalError("Could not create server lock file: %s\n", LockFile); + FatalError("Could not create server lock file: %s\n", szLockFile); StillLocking = FALSE; +#endif } /* @@ -394,7 +407,7 @@ UnlockServer(void) if (!StillLocking){ - (void) unlink(LockFile); + (void) unlink(szLockFile); } } @@ -1181,7 +1194,7 @@ XNFstrdup(const char *s) } -#ifdef SIGVTALRM +#if defined(SIGVTALRM) && !defined(__CYGWIN__) #define SMART_SCHEDULE_POSSIBLE #endif @@ -1619,6 +1632,7 @@ Fclose(pointer iop) */ /* Consider LD* variables insecure? */ +#ifndef _MSC_VER #ifndef REMOVE_ENV_LD #define REMOVE_ENV_LD 1 #endif @@ -1627,6 +1641,7 @@ Fclose(pointer iop) #ifndef REMOVE_LONG_ENV #define REMOVE_LONG_ENV 1 #endif +#endif /* * Disallow stdout or stderr as pipes? It's possible to block the X server @@ -1657,7 +1672,7 @@ Fclose(pointer iop) #endif #define MAX_ARG_LENGTH 128 -#define MAX_ENV_LENGTH 256 +#define MAX_ENV_LENGTH 2048 #define MAX_ENV_PATH_LENGTH 2048 /* Limit for *PATH and TERMCAP */ #if USE_ISPRINT diff --git a/xorg-server/os/xprintf.c b/xorg-server/os/xprintf.c index 07eaa1f58..bf70661ac 100644 --- a/xorg-server/os/xprintf.c +++ b/xorg-server/os/xprintf.c @@ -39,7 +39,9 @@ # ifdef __va_copy # define va_copy __va_copy # else +# ifndef _MSC_VER # error "no working va_copy was found" +# endif # endif #endif @@ -48,11 +50,16 @@ Xvprintf(const char *format, va_list va) { char *ret; int size; + +#ifdef _MSC_VER + size = vsnprintf(NULL, 0, format, va); +#else va_list va2; va_copy(va2, va); size = vsnprintf(NULL, 0, format, va2); va_end(va2); +#endif ret = (char *)Xalloc(size + 1); if (ret == NULL) @@ -78,11 +85,16 @@ XNFvprintf(const char *format, va_list va) { char *ret; int size; + +#ifdef _MSC_VER + size = vsnprintf(NULL, 0, format, va); +#else va_list va2; va_copy(va2, va); size = vsnprintf(NULL, 0, format, va2); va_end(va2); +#endif ret = (char *)XNFalloc(size + 1); if (ret == NULL) diff --git a/xorg-server/os/xstrans.c b/xorg-server/os/xstrans.c index c086e225b..dd75ab53e 100644 --- a/xorg-server/os/xstrans.c +++ b/xorg-server/os/xstrans.c @@ -5,4 +5,8 @@ #define TRANS_REOPEN #define TRANS_SERVER #define XSERV_t +#ifndef TCPCONN +#define TCPCONN +#endif + #include <X11/Xtrans/transport.c> diff --git a/xorg-server/randr/makefile b/xorg-server/randr/makefile new file mode 100644 index 000000000..f72a32e9b --- /dev/null +++ b/xorg-server/randr/makefile @@ -0,0 +1,17 @@ +LIBRARY=librandr
+
+CSRCS = \
+ rrxinerama.c \
+ mirandr.c \
+ randr.c \
+ rrcrtc.c \
+ rrdispatch.c \
+ rrinfo.c \
+ rrmode.c \
+ rroutput.c \
+ rrpointer.c \
+ rrproperty.c \
+ rrscreen.c \
+ rrsdispatch.c \
+ rrtransform.c
+
diff --git a/xorg-server/randr/rrcrtc.c b/xorg-server/randr/rrcrtc.c index a9eb2d262..526354611 100644 --- a/xorg-server/randr/rrcrtc.c +++ b/xorg-server/randr/rrcrtc.c @@ -541,7 +541,7 @@ RRModeGetScanoutSize (RRModePtr mode, PictTransformPtr transform, void RRCrtcGetScanoutSize(RRCrtcPtr crtc, int *width, int *height) { - return RRModeGetScanoutSize (crtc->mode, &crtc->transform, width, height); + RRModeGetScanoutSize (crtc->mode, &crtc->transform, width, height); } /* diff --git a/xorg-server/randr/rroutput.c b/xorg-server/randr/rroutput.c index 3a1b8bbea..79e16f0e8 100644 --- a/xorg-server/randr/rroutput.c +++ b/xorg-server/randr/rroutput.c @@ -23,6 +23,11 @@ #include "randrstr.h" +/* From render.h */ +#ifndef SubPixelUnknown +#define SubPixelUnknown 0 +#endif + RESTYPE RROutputType; /* diff --git a/xorg-server/randr/rrscreen.c b/xorg-server/randr/rrscreen.c index 630ff5742..e88a42816 100644 --- a/xorg-server/randr/rrscreen.c +++ b/xorg-server/randr/rrscreen.c @@ -23,6 +23,11 @@ #include "randrstr.h" static const int padlength[4] = {0, 3, 2, 1}; +/* From render.h */ +#ifndef SubPixelUnknown +#define SubPixelUnknown 0 +#endif + static CARD16 RR10CurrentSizeID (ScreenPtr pScreen); diff --git a/xorg-server/record/makefile b/xorg-server/record/makefile new file mode 100644 index 000000000..1cef2de18 --- /dev/null +++ b/xorg-server/record/makefile @@ -0,0 +1,4 @@ +CSRCS = record.c set.c + +LIBRARY=librecord + diff --git a/xorg-server/render/makefile b/xorg-server/render/makefile new file mode 100644 index 000000000..dfd905a7c --- /dev/null +++ b/xorg-server/render/makefile @@ -0,0 +1,16 @@ +
+LIBRARY=librender
+
+CSRCS = \
+ animcur.c \
+ filter.c \
+ glyph.c \
+ matrix.c \
+ miindex.c \
+ mipict.c \
+ mirect.c \
+ mitrap.c \
+ mitri.c \
+ picture.c \
+ render.c \
+ renderedge.c
diff --git a/xorg-server/render/mipict.c b/xorg-server/render/mipict.c index b5dfcb2ba..3dc04a88a 100644 --- a/xorg-server/render/mipict.c +++ b/xorg-server/render/mipict.c @@ -266,7 +266,7 @@ miChangePictureFilter (PicturePtr pPicture, #define BOUND(v) (INT16) ((v) < MINSHORT ? MINSHORT : (v) > MAXSHORT ? MAXSHORT : (v)) -static inline pixman_bool_t +static __inline pixman_bool_t miClipPictureReg (pixman_region16_t * pRegion, pixman_region16_t * pClip, int dx, diff --git a/xorg-server/startmulti.bat b/xorg-server/startmulti.bat new file mode 100644 index 000000000..6b989d2aa --- /dev/null +++ b/xorg-server/startmulti.bat @@ -0,0 +1 @@ +vcxsrv :1 -ac -terminate -lesspointer -multiwindow -xkblayout be -xkbmodel pc105 -clipboard -logverbose 4
diff --git a/xorg-server/startxdmcp.bat b/xorg-server/startxdmcp.bat new file mode 100644 index 000000000..b2af85f53 --- /dev/null +++ b/xorg-server/startxdmcp.bat @@ -0,0 +1,2 @@ +vcxsrv :1 -query 192.168.37.20 -clipboard -ac -xkblayout be -xkbmodel pc105 -logverbose 4 -once
+
diff --git a/xorg-server/system.XWinrc b/xorg-server/system.XWinrc new file mode 100644 index 000000000..15935f4e5 --- /dev/null +++ b/xorg-server/system.XWinrc @@ -0,0 +1,124 @@ +# XWin Server Resource File - EXAMPLE +# Earle F. Philhower, III + +# Place in ~/.XWinrc or in /etc/X11/system.XWinrc + +# Keywords are case insensitive, comments legal pretty much anywhere +# you can have an end-of-line + +# Comments begin with "#" or "//" and go to the end-of-line + +# Paths to commands are **cygwin** based (i.e. /usr/local/bin/xcalc) + +# Paths to icons are **WINDOWS** based (i.e. c:\windows\icons) + +# Menus are defined as... +# MENU <name> { +# <Menu Text> EXEC <command> +# ^^ This command will have any "%display%" +# string replaced with the proper display +# variable (i.e. 127.0.0.1:<display>.0) +# or <Menu Text> MENU <name-of-some-prior-defined-menu> +# or <Menu Text> ALWAYSONTOP +# ^^ Sets the window to display above all others +# or <Menu Text> RELOAD +# ^^ Causes ~/.XWinrc or the system.XWinrc file +# to be reloaded and icons and menus regenerated +# or SEPARATOR +# ... +# } + +# Set the taskmar menu with +# ROOTMENU <name-of-some-prior-defined-menu> + +# If you want a menu to be applied to all popup window's system menu +# DEFAULTSYSMENU <name-of-some-prior-defined-menu> <atstart|atend> + +# To choose a specific menu for a specific WM_CLASS or WM_NAME use ... +# SYSMENU { +# <class-or-name-of-window> <name-of-prior-defined-menu> <atstart|atend> +# ... +# } + +# When specifying an ICONFILE in the following commands several different +# formats are allowed: +# 1. Name of a regular Windows .ico format file +# (ex: "cygwin.ico", "apple.ico") +# 2. Name and index into a Windows .DLL +# (ex: "c:\windows\system32\shell32.dll,4" gives the default folder icon +# "c:\windows\system32\shell32.dll,5" gives the floppy drive icon) +# 3. Index into XWin.EXE internal ICON resource +# (ex: ",101" is the 1st icon inside XWin.exe) + +# To define where ICO files live (** Windows path**) +# ICONDIRECTORY <windows-path i.e. c:\cygwin\usr\icons> +# NOTE: If you specify a fully qualified path to an ICON below +# (i.e. "c:\xxx" or "d:\xxxx") +# this ICONDIRECTORY will not be prepended + +# To change the taskbar icon use... +# TRAYICON <name-of-windows-ico-file-in-icondirectory> + +# To define a replacement for the standard X icon for apps w/o specified icons +# DEFAULTICON <name-of-windows-ico-file-in-icondirectory> + +# To define substitute icons on a per-window basis use... +# ICONS { +# <class-or-name-of-window> <icon-file-name.ico> +# ... +# } +# In the case where multiple matches occur, the first listed in the ICONS +# section will be chosen. + +# To disable exit confirmation dialog add the line containing SilentExit + +# DEBUG <string> prints out the string to the XWin.log file + +// Below are just some silly menus to demonstrate writing your +// own configuration file. + +// Make some menus... +menu apps { + xcalc exec "xcalc" + xclock exec "xclock" + xwininfo exec "xwininfo -pause" +} + +menu root { +// Comments fit here, too... + "Reload system.XWinrc" RELOAD + "Applications" menu apps + Separator +} + +menu aot { + Separator + "Always on Top" alwaysontop +} + +menu xtermspecial { + "Emacs" exec "emacs" + "Always on Top" alwaysontop + Separator +} + +RootMenu root + +DefaultSysMenu aot atend + +SysMenu { + "xterm" xtermspecial atstart +} + +# IconDirectory "c:\winnt\" + +# DefaultIcon "reinstall.ico" + +# Icons { +# "xterm" "uninstall.ico" +# } + +# SilentExit + +# DEBUG "Done parsing the configuration file..." + diff --git a/xorg-server/vcxsrv.sln b/xorg-server/vcxsrv.sln new file mode 100644 index 000000000..948ecfc63 --- /dev/null +++ b/xorg-server/vcxsrv.sln @@ -0,0 +1,16 @@ +
+Microsoft Visual Studio Solution File, Format Version 10.00
+# Visual C++ Express 2008
+Project("{8BC9CEB9-8B4A-11D0-8D11-00A0C91BC942}") = "vcxsrv.exe", "vcxsrv.exe", "{0A7F2844-C7BA-43E2-B7AE-48070F7AA1A7}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Default = Debug|Default
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {0A7F2844-C7BA-43E2-B7AE-48070F7AA1A7}.Debug|Default.ActiveCfg = Debug
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/xorg-server/xfixes/cursor.c b/xorg-server/xfixes/cursor.c index 1471a58d1..9fa2e85d1 100644 --- a/xorg-server/xfixes/cursor.c +++ b/xorg-server/xfixes/cursor.c @@ -1,1103 +1,1105 @@ -/* - * Copyright © 2006 Sun Microsystems, 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 (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. - * - * Copyright © 2002 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 <dix-config.h> -#endif - -#include "xfixesint.h" -#include "scrnintstr.h" -#include "cursorstr.h" -#include "dixevents.h" -#include "servermd.h" -#include "inputstr.h" -#include "windowstr.h" -#include "xace.h" - -static RESTYPE CursorClientType; -static RESTYPE CursorHideCountType; -static RESTYPE CursorWindowType; -static CursorPtr CursorCurrent[MAXDEVICES]; -static CursorPtr pInvisibleCursor = NULL; - -static int CursorScreenPrivateKeyIndex; -static DevPrivateKey CursorScreenPrivateKey = &CursorScreenPrivateKeyIndex; - -static void deleteCursorHideCountsForScreen (ScreenPtr pScreen); - -#define VERIFY_CURSOR(pCursor, cursor, client, access) \ - do { \ - int err; \ - err = dixLookupResourceByType((pointer *) &pCursor, cursor, \ - RT_CURSOR, client, access); \ - if (err == BadValue) { \ - client->errorValue = cursor; \ - return BadCursor; \ - } else if (err != Success) { \ - client->errorValue = cursor; \ - return err; \ - } \ - } while (0) - -/* - * There is a global list of windows selecting for cursor events - */ - -typedef struct _CursorEvent *CursorEventPtr; - -typedef struct _CursorEvent { - CursorEventPtr next; - CARD32 eventMask; - ClientPtr pClient; - WindowPtr pWindow; - XID clientResource; -} CursorEventRec; - -static CursorEventPtr cursorEvents; - -/* - * Each screen has a list of clients which have requested - * that the cursor be hid, and the number of times each - * client has requested. -*/ - -typedef struct _CursorHideCountRec *CursorHideCountPtr; - -typedef struct _CursorHideCountRec { - CursorHideCountPtr pNext; - ClientPtr pClient; - ScreenPtr pScreen; - int hideCount; - XID resource; -} CursorHideCountRec; - -/* - * Wrap DisplayCursor to catch cursor change events - */ - -typedef struct _CursorScreen { - DisplayCursorProcPtr DisplayCursor; - CloseScreenProcPtr CloseScreen; - CursorHideCountPtr pCursorHideCounts; -} CursorScreenRec, *CursorScreenPtr; - -#define GetCursorScreen(s) ((CursorScreenPtr)dixLookupPrivate(&(s)->devPrivates, CursorScreenPrivateKey)) -#define GetCursorScreenIfSet(s) GetCursorScreen(s) -#define SetCursorScreen(s,p) dixSetPrivate(&(s)->devPrivates, CursorScreenPrivateKey, p) -#define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func) -#define Unwrap(as,s,elt,backup) (((backup) = (s)->elt), (s)->elt = (as)->elt) - -/* The cursor doesn't show up until the first XDefineCursor() */ -static Bool CursorVisible = FALSE; - -Bool EnableCursor = TRUE; - -static Bool -CursorDisplayCursor (DeviceIntPtr pDev, - ScreenPtr pScreen, - CursorPtr pCursor) -{ - CursorScreenPtr cs = GetCursorScreen(pScreen); - Bool ret; - DisplayCursorProcPtr backupProc; - - Unwrap (cs, pScreen, DisplayCursor, backupProc); - - /* - * Have to check ConnectionInfo to distinguish client requests from - * initial root window setup. Not a great way to do it, I admit. - */ - if (ConnectionInfo) - CursorVisible = EnableCursor; - - if (cs->pCursorHideCounts != NULL || !CursorVisible) { - ret = ((*pScreen->RealizeCursor)(pDev, pScreen, pInvisibleCursor) && - (*pScreen->DisplayCursor) (pDev, pScreen, pInvisibleCursor)); - } else { - ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor); - } - - if (pCursor != CursorCurrent[pDev->id]) - { - CursorEventPtr e; - - CursorCurrent[pDev->id] = pCursor; - for (e = cursorEvents; e; e = e->next) - { - if ((e->eventMask & XFixesDisplayCursorNotifyMask) && - !e->pClient->clientGone) - { - xXFixesCursorNotifyEvent ev; - ev.type = XFixesEventBase + XFixesCursorNotify; - ev.subtype = XFixesDisplayCursorNotify; - ev.sequenceNumber = e->pClient->sequence; - ev.window = e->pWindow->drawable.id; - ev.cursorSerial = pCursor->serialNumber; - ev.timestamp = currentTime.milliseconds; - ev.name = pCursor->name; - WriteEventsToClient (e->pClient, 1, (xEvent *) &ev); - } - } - } - Wrap (cs, pScreen, DisplayCursor, backupProc); - - return ret; -} - -static Bool -CursorCloseScreen (int index, ScreenPtr pScreen) -{ - CursorScreenPtr cs = GetCursorScreen (pScreen); - Bool ret; - CloseScreenProcPtr close_proc; - DisplayCursorProcPtr display_proc; - - Unwrap (cs, pScreen, CloseScreen, close_proc); - Unwrap (cs, pScreen, DisplayCursor, display_proc); - deleteCursorHideCountsForScreen(pScreen); - ret = (*pScreen->CloseScreen) (index, pScreen); - xfree (cs); - return ret; -} - -#define CursorAllEvents (XFixesDisplayCursorNotifyMask) - -static int -XFixesSelectCursorInput (ClientPtr pClient, - WindowPtr pWindow, - CARD32 eventMask) -{ - CursorEventPtr *prev, e; - pointer val; - int rc; - - for (prev = &cursorEvents; (e = *prev); prev = &e->next) - { - if (e->pClient == pClient && - e->pWindow == pWindow) - { - break; - } - } - if (!eventMask) - { - if (e) - { - FreeResource (e->clientResource, 0); - } - return Success; - } - if (!e) - { - e = (CursorEventPtr) xalloc (sizeof (CursorEventRec)); - if (!e) - return BadAlloc; - - e->next = 0; - e->pClient = pClient; - e->pWindow = pWindow; - e->clientResource = FakeClientID(pClient->index); - - /* - * Add a resource hanging from the window to - * catch window destroy - */ - rc = dixLookupResourceByType( &val, pWindow->drawable.id, - CursorWindowType, serverClient, - DixGetAttrAccess); - if (rc != Success) - if (!AddResource (pWindow->drawable.id, CursorWindowType, - (pointer) pWindow)) - { - xfree (e); - return BadAlloc; - } - - if (!AddResource (e->clientResource, CursorClientType, (pointer) e)) - return BadAlloc; - - *prev = e; - } - e->eventMask = eventMask; - return Success; -} - -int -ProcXFixesSelectCursorInput (ClientPtr client) -{ - REQUEST (xXFixesSelectCursorInputReq); - WindowPtr pWin; - int rc; - - REQUEST_SIZE_MATCH (xXFixesSelectCursorInputReq); - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) - return rc; - if (stuff->eventMask & ~CursorAllEvents) - { - client->errorValue = stuff->eventMask; - return( BadValue ); - } - return XFixesSelectCursorInput (client, pWin, stuff->eventMask); -} - -static int -GetBit (unsigned char *line, int x) -{ - 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 (*line & mask) - return 1; - return 0; -} - -int -SProcXFixesSelectCursorInput (ClientPtr client) -{ - register int n; - REQUEST(xXFixesSelectCursorInputReq); - - swaps(&stuff->length, n); - swapl(&stuff->window, n); - swapl(&stuff->eventMask, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -void -SXFixesCursorNotifyEvent (xXFixesCursorNotifyEvent *from, - xXFixesCursorNotifyEvent *to) -{ - to->type = from->type; - cpswaps (from->sequenceNumber, to->sequenceNumber); - cpswapl (from->window, to->window); - cpswapl (from->cursorSerial, to->cursorSerial); - cpswapl (from->timestamp, to->timestamp); - cpswapl (from->name, to->name); -} - -static void -CopyCursorToImage (CursorPtr pCursor, CARD32 *image) -{ - int width = pCursor->bits->width; - int height = pCursor->bits->height; - int npixels = width * height; - -#ifdef ARGB_CURSOR - if (pCursor->bits->argb) - memcpy (image, pCursor->bits->argb, npixels * sizeof (CARD32)); - else -#endif - { - unsigned char *srcLine = pCursor->bits->source; - unsigned char *mskLine = pCursor->bits->mask; - int stride = BitmapBytePad (width); - int x, y; - CARD32 fg, bg; - - fg = (0xff000000 | - ((pCursor->foreRed & 0xff00) << 8) | - (pCursor->foreGreen & 0xff00) | - (pCursor->foreBlue >> 8)); - bg = (0xff000000 | - ((pCursor->backRed & 0xff00) << 8) | - (pCursor->backGreen & 0xff00) | - (pCursor->backBlue >> 8)); - for (y = 0; y < height; y++) - { - for (x = 0; x < width; x++) - { - if (GetBit (mskLine, x)) - { - if (GetBit (srcLine, x)) - *image++ = fg; - else - *image++ = bg; - } - else - *image++ = 0; - } - srcLine += stride; - mskLine += stride; - } - } -} - -int -ProcXFixesGetCursorImage (ClientPtr client) -{ -/* REQUEST(xXFixesGetCursorImageReq); */ - xXFixesGetCursorImageReply *rep; - CursorPtr pCursor; - CARD32 *image; - int npixels, width, height, rc, x, y; - - REQUEST_SIZE_MATCH(xXFixesGetCursorImageReq); - pCursor = CursorCurrent[PickPointer(client)->id]; - if (!pCursor) - return BadCursor; - rc = XaceHook(XACE_RESOURCE_ACCESS, client, pCursor->id, RT_CURSOR, - pCursor, RT_NONE, NULL, DixReadAccess); - if (rc != Success) - return rc; - GetSpritePosition (PickPointer(client), &x, &y); - width = pCursor->bits->width; - height = pCursor->bits->height; - npixels = width * height; - rep = xalloc (sizeof (xXFixesGetCursorImageReply) + - npixels * sizeof (CARD32)); - if (!rep) - return BadAlloc; - - rep->type = X_Reply; - rep->sequenceNumber = client->sequence; - rep->length = npixels; - rep->width = width; - rep->height = height; - rep->x = x; - rep->y = y; - rep->xhot = pCursor->bits->xhot; - rep->yhot = pCursor->bits->yhot; - rep->cursorSerial = pCursor->serialNumber; - - image = (CARD32 *) (rep + 1); - CopyCursorToImage (pCursor, image); - if (client->swapped) - { - int n; - swaps (&rep->sequenceNumber, n); - swapl (&rep->length, n); - swaps (&rep->x, n); - swaps (&rep->y, n); - swaps (&rep->width, n); - swaps (&rep->height, n); - swaps (&rep->xhot, n); - swaps (&rep->yhot, n); - swapl (&rep->cursorSerial, n); - SwapLongs (image, npixels); - } - WriteToClient(client, sizeof (xXFixesGetCursorImageReply) + - (npixels << 2), (char *) rep); - xfree (rep); - return client->noClientException; -} - -int -SProcXFixesGetCursorImage (ClientPtr client) -{ - int n; - REQUEST(xXFixesGetCursorImageReq); - swaps (&stuff->length, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesSetCursorName (ClientPtr client) -{ - CursorPtr pCursor; - char *tchar; - REQUEST(xXFixesSetCursorNameReq); - Atom atom; - - REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq); - VERIFY_CURSOR(pCursor, stuff->cursor, client, DixSetAttrAccess); - tchar = (char *) &stuff[1]; - atom = MakeAtom (tchar, stuff->nbytes, TRUE); - if (atom == BAD_RESOURCE) - return BadAlloc; - - pCursor->name = atom; - return(client->noClientException); -} - -int -SProcXFixesSetCursorName (ClientPtr client) -{ - int n; - REQUEST(xXFixesSetCursorNameReq); - - swaps (&stuff->length, n); - REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq); - swapl (&stuff->cursor, n); - swaps (&stuff->nbytes, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesGetCursorName (ClientPtr client) -{ - CursorPtr pCursor; - xXFixesGetCursorNameReply reply; - REQUEST(xXFixesGetCursorNameReq); - const char *str; - int len; - - REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq); - VERIFY_CURSOR(pCursor, stuff->cursor, client, DixGetAttrAccess); - if (pCursor->name) - str = NameForAtom (pCursor->name); - else - str = ""; - len = strlen (str); - - reply.type = X_Reply; - reply.length = bytes_to_int32(len); - reply.sequenceNumber = client->sequence; - reply.atom = pCursor->name; - reply.nbytes = len; - if (client->swapped) - { - int n; - swaps (&reply.sequenceNumber, n); - swapl (&reply.length, n); - swapl (&reply.atom, n); - swaps (&reply.nbytes, n); - } - WriteReplyToClient(client, sizeof(xXFixesGetCursorNameReply), &reply); - WriteToClient(client, len, str); - - return(client->noClientException); -} - -int -SProcXFixesGetCursorName (ClientPtr client) -{ - int n; - REQUEST(xXFixesGetCursorNameReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq); - swapl (&stuff->cursor, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesGetCursorImageAndName (ClientPtr client) -{ -/* REQUEST(xXFixesGetCursorImageAndNameReq); */ - xXFixesGetCursorImageAndNameReply *rep; - CursorPtr pCursor; - CARD32 *image; - int npixels; - const char *name; - int nbytes, nbytesRound; - int width, height; - int rc, x, y; - - REQUEST_SIZE_MATCH(xXFixesGetCursorImageAndNameReq); - pCursor = CursorCurrent[PickPointer(client)->id]; - if (!pCursor) - return BadCursor; - rc = XaceHook(XACE_RESOURCE_ACCESS, client, pCursor->id, RT_CURSOR, - pCursor, RT_NONE, NULL, DixReadAccess|DixGetAttrAccess); - if (rc != Success) - return rc; - GetSpritePosition (PickPointer(client), &x, &y); - width = pCursor->bits->width; - height = pCursor->bits->height; - npixels = width * height; - name = pCursor->name ? NameForAtom (pCursor->name) : ""; - nbytes = strlen (name); - nbytesRound = pad_to_int32(nbytes); - rep = xalloc (sizeof (xXFixesGetCursorImageAndNameReply) + - npixels * sizeof (CARD32) + nbytesRound); - if (!rep) - return BadAlloc; - - rep->type = X_Reply; - rep->sequenceNumber = client->sequence; - rep->length = npixels + bytes_to_int32(nbytesRound); - rep->width = width; - rep->height = height; - rep->x = x; - rep->y = y; - rep->xhot = pCursor->bits->xhot; - rep->yhot = pCursor->bits->yhot; - rep->cursorSerial = pCursor->serialNumber; - rep->cursorName = pCursor->name; - rep->nbytes = nbytes; - - image = (CARD32 *) (rep + 1); - CopyCursorToImage (pCursor, image); - memcpy ((image + npixels), name, nbytes); - if (client->swapped) - { - int n; - swaps (&rep->sequenceNumber, n); - swapl (&rep->length, n); - swaps (&rep->x, n); - swaps (&rep->y, n); - swaps (&rep->width, n); - swaps (&rep->height, n); - swaps (&rep->xhot, n); - swaps (&rep->yhot, n); - swapl (&rep->cursorSerial, n); - swapl (&rep->cursorName, n); - swaps (&rep->nbytes, n); - SwapLongs (image, npixels); - } - WriteToClient(client, sizeof (xXFixesGetCursorImageAndNameReply) + - (npixels << 2) + nbytesRound, (char *) rep); - xfree (rep); - return client->noClientException; -} - -int -SProcXFixesGetCursorImageAndName (ClientPtr client) -{ - int n; - REQUEST(xXFixesGetCursorImageAndNameReq); - swaps (&stuff->length, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -/* - * Find every cursor reference in the system, ask testCursor - * whether it should be replaced with a reference to pCursor. - */ - -typedef Bool (*TestCursorFunc) (CursorPtr pOld, pointer closure); - -typedef struct { - RESTYPE type; - TestCursorFunc testCursor; - CursorPtr pNew; - pointer closure; -} ReplaceCursorLookupRec, *ReplaceCursorLookupPtr; - -static const RESTYPE CursorRestypes[] = { - RT_WINDOW, RT_PASSIVEGRAB, RT_CURSOR -}; - -#define NUM_CURSOR_RESTYPES (sizeof (CursorRestypes) / sizeof (CursorRestypes[0])) - -static Bool -ReplaceCursorLookup (pointer value, XID id, pointer closure) -{ - ReplaceCursorLookupPtr rcl = (ReplaceCursorLookupPtr) closure; - WindowPtr pWin; - GrabPtr pGrab; - CursorPtr pCursor = 0, *pCursorRef = 0; - XID cursor = 0; - - switch (rcl->type) { - case RT_WINDOW: - pWin = (WindowPtr) value; - if (pWin->optional) - { - pCursorRef = &pWin->optional->cursor; - pCursor = *pCursorRef; - } - break; - case RT_PASSIVEGRAB: - pGrab = (GrabPtr) value; - pCursorRef = &pGrab->cursor; - pCursor = *pCursorRef; - break; - case RT_CURSOR: - pCursorRef = 0; - pCursor = (CursorPtr) value; - cursor = id; - break; - } - if (pCursor && pCursor != rcl->pNew) - { - if ((*rcl->testCursor) (pCursor, rcl->closure)) - { - rcl->pNew->refcnt++; - /* either redirect reference or update resource database */ - if (pCursorRef) - *pCursorRef = rcl->pNew; - else - ChangeResourceValue (id, RT_CURSOR, rcl->pNew); - FreeCursor (pCursor, cursor); - } - } - return FALSE; /* keep walking */ -} - -static void -ReplaceCursor (CursorPtr pCursor, - TestCursorFunc testCursor, - pointer closure) -{ - int clientIndex; - int resIndex; - ReplaceCursorLookupRec rcl; - - /* - * Cursors exist only in the resource database, windows and grabs. - * All of these are always pointed at by the resource database. Walk - * the whole thing looking for cursors - */ - rcl.testCursor = testCursor; - rcl.pNew = pCursor; - rcl.closure = closure; - - /* for each client */ - for (clientIndex = 0; clientIndex < currentMaxClients; clientIndex++) - { - if (!clients[clientIndex]) - continue; - for (resIndex = 0; resIndex < NUM_CURSOR_RESTYPES; resIndex++) - { - rcl.type = CursorRestypes[resIndex]; - /* - * This function walks the entire client resource database - */ - LookupClientResourceComplex (clients[clientIndex], - rcl.type, - ReplaceCursorLookup, - (pointer) &rcl); - } - } - /* this "knows" that WindowHasNewCursor doesn't depend on it's argument */ - WindowHasNewCursor (WindowTable[0]); -} - -static Bool -TestForCursor (CursorPtr pCursor, pointer closure) -{ - return (pCursor == (CursorPtr) closure); -} - -int -ProcXFixesChangeCursor (ClientPtr client) -{ - CursorPtr pSource, pDestination; - REQUEST(xXFixesChangeCursorReq); - - REQUEST_SIZE_MATCH(xXFixesChangeCursorReq); - VERIFY_CURSOR (pSource, stuff->source, client, - DixReadAccess|DixGetAttrAccess); - VERIFY_CURSOR (pDestination, stuff->destination, client, - DixWriteAccess|DixSetAttrAccess); - - ReplaceCursor (pSource, TestForCursor, (pointer) pDestination); - return (client->noClientException); -} - -int -SProcXFixesChangeCursor (ClientPtr client) -{ - int n; - REQUEST(xXFixesChangeCursorReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH(xXFixesChangeCursorReq); - swapl (&stuff->source, n); - swapl (&stuff->destination, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -static Bool -TestForCursorName (CursorPtr pCursor, pointer closure) -{ - Atom *pName = closure; - return (pCursor->name == *pName); -} - -int -ProcXFixesChangeCursorByName (ClientPtr client) -{ - CursorPtr pSource; - Atom name; - char *tchar; - REQUEST(xXFixesChangeCursorByNameReq); - - REQUEST_FIXED_SIZE(xXFixesChangeCursorByNameReq, stuff->nbytes); - VERIFY_CURSOR(pSource, stuff->source, client, - DixReadAccess|DixGetAttrAccess); - tchar = (char *) &stuff[1]; - name = MakeAtom (tchar, stuff->nbytes, FALSE); - if (name) - ReplaceCursor (pSource, TestForCursorName, &name); - return (client->noClientException); -} - -int -SProcXFixesChangeCursorByName (ClientPtr client) -{ - int n; - REQUEST(xXFixesChangeCursorByNameReq); - - swaps (&stuff->length, n); - REQUEST_AT_LEAST_SIZE (xXFixesChangeCursorByNameReq); - swapl (&stuff->source, n); - swaps (&stuff->nbytes, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -/* - * Routines for manipulating the per-screen hide counts list. - * This list indicates which clients have requested cursor hiding - * for that screen. - */ - -/* Return the screen's hide-counts list element for the given client */ -static CursorHideCountPtr -findCursorHideCount (ClientPtr pClient, ScreenPtr pScreen) -{ - CursorScreenPtr cs = GetCursorScreen(pScreen); - CursorHideCountPtr pChc; - - for (pChc = cs->pCursorHideCounts; pChc != NULL; pChc = pChc->pNext) { - if (pChc->pClient == pClient) { - return pChc; - } - } - - return NULL; -} - -static int -createCursorHideCount (ClientPtr pClient, ScreenPtr pScreen) -{ - CursorScreenPtr cs = GetCursorScreen(pScreen); - CursorHideCountPtr pChc; - - pChc = (CursorHideCountPtr) xalloc(sizeof(CursorHideCountRec)); - if (pChc == NULL) { - return BadAlloc; - } - pChc->pClient = pClient; - pChc->pScreen = pScreen; - pChc->hideCount = 1; - pChc->resource = FakeClientID(pClient->index); - pChc->pNext = cs->pCursorHideCounts; - cs->pCursorHideCounts = pChc; - - /* - * Create a resource for this element so it can be deleted - * when the client goes away. - */ - if (!AddResource (pChc->resource, CursorHideCountType, - (pointer) pChc)) { - xfree(pChc); - return BadAlloc; - } - - return Success; -} - -/* - * Delete the given hide-counts list element from its screen list. - */ -static void -deleteCursorHideCount (CursorHideCountPtr pChcToDel, ScreenPtr pScreen) -{ - CursorScreenPtr cs = GetCursorScreen(pScreen); - CursorHideCountPtr pChc, pNext; - CursorHideCountPtr pChcLast = NULL; - - pChc = cs->pCursorHideCounts; - while (pChc != NULL) { - pNext = pChc->pNext; - if (pChc == pChcToDel) { - xfree(pChc); - if (pChcLast == NULL) { - cs->pCursorHideCounts = pNext; - } else { - pChcLast->pNext = pNext; - } - return; - } - pChcLast = pChc; - pChc = pNext; - } -} - -/* - * Delete all the hide-counts list elements for this screen. - */ -static void -deleteCursorHideCountsForScreen (ScreenPtr pScreen) -{ - CursorScreenPtr cs = GetCursorScreen(pScreen); - CursorHideCountPtr pChc, pTmp; - - pChc = cs->pCursorHideCounts; - while (pChc != NULL) { - pTmp = pChc->pNext; - FreeResource(pChc->resource, 0); - pChc = pTmp; - } - cs->pCursorHideCounts = NULL; -} - -int -ProcXFixesHideCursor (ClientPtr client) -{ - WindowPtr pWin; - CursorHideCountPtr pChc; - REQUEST(xXFixesHideCursorReq); - int ret; - - REQUEST_SIZE_MATCH (xXFixesHideCursorReq); - - ret = dixLookupResourceByType((pointer *)&pWin, stuff->window, RT_WINDOW, - client, DixGetAttrAccess); - if (ret != Success) { - client->errorValue = stuff->window; - return (ret == BadValue) ? BadWindow : ret; - } - - /* - * Has client hidden the cursor before on this screen? - * If so, just increment the count. - */ - - pChc = findCursorHideCount(client, pWin->drawable.pScreen); - if (pChc != NULL) { - pChc->hideCount++; - return client->noClientException; - } - - /* - * This is the first time this client has hid the cursor - * for this screen. - */ - ret = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen, - DixHideAccess); - if (ret != Success) - return ret; - - ret = createCursorHideCount(client, pWin->drawable.pScreen); - - if (ret == Success) { - DeviceIntPtr dev; - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (IsMaster(dev) && IsPointerDevice(dev)) - CursorDisplayCursor(dev, pWin->drawable.pScreen, CursorCurrent[dev->id]); - } - } - - return ret; -} - -int -SProcXFixesHideCursor (ClientPtr client) -{ - int n; - REQUEST(xXFixesHideCursorReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH (xXFixesHideCursorReq); - swapl (&stuff->window, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -int -ProcXFixesShowCursor (ClientPtr client) -{ - WindowPtr pWin; - CursorHideCountPtr pChc; - int rc; - REQUEST(xXFixesShowCursorReq); - - REQUEST_SIZE_MATCH (xXFixesShowCursorReq); - - rc = dixLookupResourceByType((pointer *)&pWin, stuff->window, RT_WINDOW, - client, DixGetAttrAccess); - if (rc != Success) { - client->errorValue = stuff->window; - return (rc == BadValue) ? BadWindow : rc; - } - - /* - * Has client hidden the cursor on this screen? - * If not, generate an error. - */ - pChc = findCursorHideCount(client, pWin->drawable.pScreen); - if (pChc == NULL) { - return BadMatch; - } - - rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen, - DixShowAccess); - if (rc != Success) - return rc; - - pChc->hideCount--; - if (pChc->hideCount <= 0) { - FreeResource(pChc->resource, 0); - } - - return (client->noClientException); -} - -int -SProcXFixesShowCursor (ClientPtr client) -{ - int n; - REQUEST(xXFixesShowCursorReq); - - swaps (&stuff->length, n); - REQUEST_SIZE_MATCH (xXFixesShowCursorReq); - swapl (&stuff->window, n); - return (*ProcXFixesVector[stuff->xfixesReqType]) (client); -} - -static int -CursorFreeClient (pointer data, XID id) -{ - CursorEventPtr old = (CursorEventPtr) data; - CursorEventPtr *prev, e; - - for (prev = &cursorEvents; (e = *prev); prev = &e->next) - { - if (e == old) - { - *prev = e->next; - xfree (e); - break; - } - } - return 1; -} - -static int -CursorFreeHideCount (pointer data, XID id) -{ - CursorHideCountPtr pChc = (CursorHideCountPtr) data; - ScreenPtr pScreen = pChc->pScreen; - DeviceIntPtr dev; - - deleteCursorHideCount(pChc, pChc->pScreen); - for (dev = inputInfo.devices; dev; dev = dev->next) - { - if (IsMaster(dev) && IsPointerDevice(dev)) - CursorDisplayCursor(dev, pScreen, CursorCurrent[dev->id]); - } - - return 1; -} - -static int -CursorFreeWindow (pointer data, XID id) -{ - WindowPtr pWindow = (WindowPtr) data; - CursorEventPtr e, next; - - for (e = cursorEvents; e; e = next) - { - next = e->next; - if (e->pWindow == pWindow) - { - FreeResource (e->clientResource, 0); - } - } - return 1; -} - -static CursorPtr -createInvisibleCursor (void) -{ - CursorPtr pCursor; - unsigned char *psrcbits, *pmaskbits; - CursorMetricRec cm; - - psrcbits = (unsigned char *) xcalloc(4, 1); - pmaskbits = (unsigned char *) xcalloc(4, 1); - if (psrcbits == NULL || pmaskbits == NULL) { - return NULL; - } - - cm.width = 1; - cm.height = 1; - cm.xhot = 0; - cm.yhot = 0; - - AllocARGBCursor(psrcbits, pmaskbits, - NULL, &cm, - 0, 0, 0, - 0, 0, 0, - &pCursor, serverClient, (XID)0); - - return pCursor; -} - -Bool -XFixesCursorInit (void) -{ - int i; - - if (party_like_its_1989) - CursorVisible = EnableCursor; - - for (i = 0; i < screenInfo.numScreens; i++) - { - ScreenPtr pScreen = screenInfo.screens[i]; - CursorScreenPtr cs; - - cs = (CursorScreenPtr) xalloc (sizeof (CursorScreenRec)); - if (!cs) - return FALSE; - Wrap (cs, pScreen, CloseScreen, CursorCloseScreen); - Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor); - cs->pCursorHideCounts = NULL; - SetCursorScreen (pScreen, cs); - } - CursorClientType = CreateNewResourceType(CursorFreeClient, - "XFixesCursorClient"); - CursorHideCountType = CreateNewResourceType(CursorFreeHideCount, - "XFixesCursorHideCount"); - CursorWindowType = CreateNewResourceType(CursorFreeWindow, - "XFixesCursorWindow"); - - if (pInvisibleCursor == NULL) { - pInvisibleCursor = createInvisibleCursor(); - if (pInvisibleCursor == NULL) { - return BadAlloc; - } - } - - return CursorClientType && CursorHideCountType && CursorWindowType; -} - +/*
+ * Copyright © 2006 Sun Microsystems, 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 (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.
+ *
+ * Copyright © 2002 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 <dix-config.h>
+#else
+#define XFIXES
+#endif
+
+#include "xfixesint.h"
+#include "scrnintstr.h"
+#include "cursorstr.h"
+#include "dixevents.h"
+#include "servermd.h"
+#include "inputstr.h"
+#include "windowstr.h"
+#include "xace.h"
+
+static RESTYPE CursorClientType;
+static RESTYPE CursorHideCountType;
+static RESTYPE CursorWindowType;
+static CursorPtr CursorCurrent[MAXDEVICES];
+static CursorPtr pInvisibleCursor = NULL;
+
+static int CursorScreenPrivateKeyIndex;
+static DevPrivateKey CursorScreenPrivateKey = &CursorScreenPrivateKeyIndex;
+
+static void deleteCursorHideCountsForScreen (ScreenPtr pScreen);
+
+#define VERIFY_CURSOR(pCursor, cursor, client, access) \
+ do { \
+ int err; \
+ err = dixLookupResourceByType((pointer *) &pCursor, cursor, \
+ RT_CURSOR, client, access); \
+ if (err == BadValue) { \
+ client->errorValue = cursor; \
+ return BadCursor; \
+ } else if (err != Success) { \
+ client->errorValue = cursor; \
+ return err; \
+ } \
+ } while (0)
+
+/*
+ * There is a global list of windows selecting for cursor events
+ */
+
+typedef struct _CursorEvent *CursorEventPtr;
+
+typedef struct _CursorEvent {
+ CursorEventPtr next;
+ CARD32 eventMask;
+ ClientPtr pClient;
+ WindowPtr pWindow;
+ XID clientResource;
+} CursorEventRec;
+
+static CursorEventPtr cursorEvents;
+
+/*
+ * Each screen has a list of clients which have requested
+ * that the cursor be hid, and the number of times each
+ * client has requested.
+*/
+
+typedef struct _CursorHideCountRec *CursorHideCountPtr;
+
+typedef struct _CursorHideCountRec {
+ CursorHideCountPtr pNext;
+ ClientPtr pClient;
+ ScreenPtr pScreen;
+ int hideCount;
+ XID resource;
+} CursorHideCountRec;
+
+/*
+ * Wrap DisplayCursor to catch cursor change events
+ */
+
+typedef struct _CursorScreen {
+ DisplayCursorProcPtr DisplayCursor;
+ CloseScreenProcPtr CloseScreen;
+ CursorHideCountPtr pCursorHideCounts;
+} CursorScreenRec, *CursorScreenPtr;
+
+#define GetCursorScreen(s) ((CursorScreenPtr)dixLookupPrivate(&(s)->devPrivates, CursorScreenPrivateKey))
+#define GetCursorScreenIfSet(s) GetCursorScreen(s)
+#define SetCursorScreen(s,p) dixSetPrivate(&(s)->devPrivates, CursorScreenPrivateKey, p)
+#define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func)
+#define Unwrap(as,s,elt,backup) (((backup) = (s)->elt), (s)->elt = (as)->elt)
+
+/* The cursor doesn't show up until the first XDefineCursor() */
+static Bool CursorVisible = FALSE;
+
+Bool EnableCursor = TRUE;
+
+static Bool
+CursorDisplayCursor (DeviceIntPtr pDev,
+ ScreenPtr pScreen,
+ CursorPtr pCursor)
+{
+ CursorScreenPtr cs = GetCursorScreen(pScreen);
+ Bool ret;
+ DisplayCursorProcPtr backupProc;
+
+ Unwrap (cs, pScreen, DisplayCursor, backupProc);
+
+ /*
+ * Have to check ConnectionInfo to distinguish client requests from
+ * initial root window setup. Not a great way to do it, I admit.
+ */
+ if (ConnectionInfo)
+ CursorVisible = EnableCursor;
+
+ if (cs->pCursorHideCounts != NULL || !CursorVisible) {
+ ret = ((*pScreen->RealizeCursor)(pDev, pScreen, pInvisibleCursor) &&
+ (*pScreen->DisplayCursor) (pDev, pScreen, pInvisibleCursor));
+ } else {
+ ret = (*pScreen->DisplayCursor) (pDev, pScreen, pCursor);
+ }
+
+ if (pCursor != CursorCurrent[pDev->id])
+ {
+ CursorEventPtr e;
+
+ CursorCurrent[pDev->id] = pCursor;
+ for (e = cursorEvents; e; e = e->next)
+ {
+ if ((e->eventMask & XFixesDisplayCursorNotifyMask) &&
+ !e->pClient->clientGone)
+ {
+ xXFixesCursorNotifyEvent ev;
+ ev.type = XFixesEventBase + XFixesCursorNotify;
+ ev.subtype = XFixesDisplayCursorNotify;
+ ev.sequenceNumber = e->pClient->sequence;
+ ev.window = e->pWindow->drawable.id;
+ ev.cursorSerial = pCursor->serialNumber;
+ ev.timestamp = currentTime.milliseconds;
+ ev.name = pCursor->name;
+ WriteEventsToClient (e->pClient, 1, (xEvent *) &ev);
+ }
+ }
+ }
+ Wrap (cs, pScreen, DisplayCursor, backupProc);
+
+ return ret;
+}
+
+static Bool
+CursorCloseScreen (int index, ScreenPtr pScreen)
+{
+ CursorScreenPtr cs = GetCursorScreen (pScreen);
+ Bool ret;
+ CloseScreenProcPtr close_proc;
+ DisplayCursorProcPtr display_proc;
+
+ Unwrap (cs, pScreen, CloseScreen, close_proc);
+ Unwrap (cs, pScreen, DisplayCursor, display_proc);
+ deleteCursorHideCountsForScreen(pScreen);
+ ret = (*pScreen->CloseScreen) (index, pScreen);
+ xfree (cs);
+ return ret;
+}
+
+#define CursorAllEvents (XFixesDisplayCursorNotifyMask)
+
+static int
+XFixesSelectCursorInput (ClientPtr pClient,
+ WindowPtr pWindow,
+ CARD32 eventMask)
+{
+ CursorEventPtr *prev, e;
+ pointer val;
+ int rc;
+
+ for (prev = &cursorEvents; (e = *prev); prev = &e->next)
+ {
+ if (e->pClient == pClient &&
+ e->pWindow == pWindow)
+ {
+ break;
+ }
+ }
+ if (!eventMask)
+ {
+ if (e)
+ {
+ FreeResource (e->clientResource, 0);
+ }
+ return Success;
+ }
+ if (!e)
+ {
+ e = (CursorEventPtr) xalloc (sizeof (CursorEventRec));
+ if (!e)
+ return BadAlloc;
+
+ e->next = 0;
+ e->pClient = pClient;
+ e->pWindow = pWindow;
+ e->clientResource = FakeClientID(pClient->index);
+
+ /*
+ * Add a resource hanging from the window to
+ * catch window destroy
+ */
+ rc = dixLookupResourceByType( &val, pWindow->drawable.id,
+ CursorWindowType, serverClient,
+ DixGetAttrAccess);
+ if (rc != Success)
+ if (!AddResource (pWindow->drawable.id, CursorWindowType,
+ (pointer) pWindow))
+ {
+ xfree (e);
+ return BadAlloc;
+ }
+
+ if (!AddResource (e->clientResource, CursorClientType, (pointer) e))
+ return BadAlloc;
+
+ *prev = e;
+ }
+ e->eventMask = eventMask;
+ return Success;
+}
+
+int
+ProcXFixesSelectCursorInput (ClientPtr client)
+{
+ REQUEST (xXFixesSelectCursorInputReq);
+ WindowPtr pWin;
+ int rc;
+
+ REQUEST_SIZE_MATCH (xXFixesSelectCursorInputReq);
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ if (stuff->eventMask & ~CursorAllEvents)
+ {
+ client->errorValue = stuff->eventMask;
+ return( BadValue );
+ }
+ return XFixesSelectCursorInput (client, pWin, stuff->eventMask);
+}
+
+static int
+GetBit (unsigned char *line, int x)
+{
+ 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 (*line & mask)
+ return 1;
+ return 0;
+}
+
+int
+SProcXFixesSelectCursorInput (ClientPtr client)
+{
+ register int n;
+ REQUEST(xXFixesSelectCursorInputReq);
+
+ swaps(&stuff->length, n);
+ swapl(&stuff->window, n);
+ swapl(&stuff->eventMask, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+void
+SXFixesCursorNotifyEvent (xXFixesCursorNotifyEvent *from,
+ xXFixesCursorNotifyEvent *to)
+{
+ to->type = from->type;
+ cpswaps (from->sequenceNumber, to->sequenceNumber);
+ cpswapl (from->window, to->window);
+ cpswapl (from->cursorSerial, to->cursorSerial);
+ cpswapl (from->timestamp, to->timestamp);
+ cpswapl (from->name, to->name);
+}
+
+static void
+CopyCursorToImage (CursorPtr pCursor, CARD32 *image)
+{
+ int width = pCursor->bits->width;
+ int height = pCursor->bits->height;
+ int npixels = width * height;
+
+#ifdef ARGB_CURSOR
+ if (pCursor->bits->argb)
+ memcpy (image, pCursor->bits->argb, npixels * sizeof (CARD32));
+ else
+#endif
+ {
+ unsigned char *srcLine = pCursor->bits->source;
+ unsigned char *mskLine = pCursor->bits->mask;
+ int stride = BitmapBytePad (width);
+ int x, y;
+ CARD32 fg, bg;
+
+ fg = (0xff000000 |
+ ((pCursor->foreRed & 0xff00) << 8) |
+ (pCursor->foreGreen & 0xff00) |
+ (pCursor->foreBlue >> 8));
+ bg = (0xff000000 |
+ ((pCursor->backRed & 0xff00) << 8) |
+ (pCursor->backGreen & 0xff00) |
+ (pCursor->backBlue >> 8));
+ for (y = 0; y < height; y++)
+ {
+ for (x = 0; x < width; x++)
+ {
+ if (GetBit (mskLine, x))
+ {
+ if (GetBit (srcLine, x))
+ *image++ = fg;
+ else
+ *image++ = bg;
+ }
+ else
+ *image++ = 0;
+ }
+ srcLine += stride;
+ mskLine += stride;
+ }
+ }
+}
+
+int
+ProcXFixesGetCursorImage (ClientPtr client)
+{
+/* REQUEST(xXFixesGetCursorImageReq); */
+ xXFixesGetCursorImageReply *rep;
+ CursorPtr pCursor;
+ CARD32 *image;
+ int npixels, width, height, rc, x, y;
+
+ REQUEST_SIZE_MATCH(xXFixesGetCursorImageReq);
+ pCursor = CursorCurrent[PickPointer(client)->id];
+ if (!pCursor)
+ return BadCursor;
+ rc = XaceHook(XACE_RESOURCE_ACCESS, client, pCursor->id, RT_CURSOR,
+ pCursor, RT_NONE, NULL, DixReadAccess);
+ if (rc != Success)
+ return rc;
+ GetSpritePosition (PickPointer(client), &x, &y);
+ width = pCursor->bits->width;
+ height = pCursor->bits->height;
+ npixels = width * height;
+ rep = xalloc (sizeof (xXFixesGetCursorImageReply) +
+ npixels * sizeof (CARD32));
+ if (!rep)
+ return BadAlloc;
+
+ rep->type = X_Reply;
+ rep->sequenceNumber = client->sequence;
+ rep->length = npixels;
+ rep->width = width;
+ rep->height = height;
+ rep->x = x;
+ rep->y = y;
+ rep->xhot = pCursor->bits->xhot;
+ rep->yhot = pCursor->bits->yhot;
+ rep->cursorSerial = pCursor->serialNumber;
+
+ image = (CARD32 *) (rep + 1);
+ CopyCursorToImage (pCursor, image);
+ if (client->swapped)
+ {
+ int n;
+ swaps (&rep->sequenceNumber, n);
+ swapl (&rep->length, n);
+ swaps (&rep->x, n);
+ swaps (&rep->y, n);
+ swaps (&rep->width, n);
+ swaps (&rep->height, n);
+ swaps (&rep->xhot, n);
+ swaps (&rep->yhot, n);
+ swapl (&rep->cursorSerial, n);
+ SwapLongs (image, npixels);
+ }
+ WriteToClient(client, sizeof (xXFixesGetCursorImageReply) +
+ (npixels << 2), (char *) rep);
+ xfree (rep);
+ return client->noClientException;
+}
+
+int
+SProcXFixesGetCursorImage (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesGetCursorImageReq);
+ swaps (&stuff->length, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesSetCursorName (ClientPtr client)
+{
+ CursorPtr pCursor;
+ char *tchar;
+ REQUEST(xXFixesSetCursorNameReq);
+ Atom atom;
+
+ REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq);
+ VERIFY_CURSOR(pCursor, stuff->cursor, client, DixSetAttrAccess);
+ tchar = (char *) &stuff[1];
+ atom = MakeAtom (tchar, stuff->nbytes, TRUE);
+ if (atom == BAD_RESOURCE)
+ return BadAlloc;
+
+ pCursor->name = atom;
+ return(client->noClientException);
+}
+
+int
+SProcXFixesSetCursorName (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesSetCursorNameReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq);
+ swapl (&stuff->cursor, n);
+ swaps (&stuff->nbytes, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesGetCursorName (ClientPtr client)
+{
+ CursorPtr pCursor;
+ xXFixesGetCursorNameReply reply;
+ REQUEST(xXFixesGetCursorNameReq);
+ const char *str;
+ int len;
+
+ REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq);
+ VERIFY_CURSOR(pCursor, stuff->cursor, client, DixGetAttrAccess);
+ if (pCursor->name)
+ str = NameForAtom (pCursor->name);
+ else
+ str = "";
+ len = strlen (str);
+
+ reply.type = X_Reply;
+ reply.length = bytes_to_int32(len);
+ reply.sequenceNumber = client->sequence;
+ reply.atom = pCursor->name;
+ reply.nbytes = len;
+ if (client->swapped)
+ {
+ int n;
+ swaps (&reply.sequenceNumber, n);
+ swapl (&reply.length, n);
+ swapl (&reply.atom, n);
+ swaps (&reply.nbytes, n);
+ }
+ WriteReplyToClient(client, sizeof(xXFixesGetCursorNameReply), &reply);
+ WriteToClient(client, len, str);
+
+ return(client->noClientException);
+}
+
+int
+SProcXFixesGetCursorName (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesGetCursorNameReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq);
+ swapl (&stuff->cursor, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesGetCursorImageAndName (ClientPtr client)
+{
+/* REQUEST(xXFixesGetCursorImageAndNameReq); */
+ xXFixesGetCursorImageAndNameReply *rep;
+ CursorPtr pCursor;
+ CARD32 *image;
+ int npixels;
+ const char *name;
+ int nbytes, nbytesRound;
+ int width, height;
+ int rc, x, y;
+
+ REQUEST_SIZE_MATCH(xXFixesGetCursorImageAndNameReq);
+ pCursor = CursorCurrent[PickPointer(client)->id];
+ if (!pCursor)
+ return BadCursor;
+ rc = XaceHook(XACE_RESOURCE_ACCESS, client, pCursor->id, RT_CURSOR,
+ pCursor, RT_NONE, NULL, DixReadAccess|DixGetAttrAccess);
+ if (rc != Success)
+ return rc;
+ GetSpritePosition (PickPointer(client), &x, &y);
+ width = pCursor->bits->width;
+ height = pCursor->bits->height;
+ npixels = width * height;
+ name = pCursor->name ? NameForAtom (pCursor->name) : "";
+ nbytes = strlen (name);
+ nbytesRound = pad_to_int32(nbytes);
+ rep = xalloc (sizeof (xXFixesGetCursorImageAndNameReply) +
+ npixels * sizeof (CARD32) + nbytesRound);
+ if (!rep)
+ return BadAlloc;
+
+ rep->type = X_Reply;
+ rep->sequenceNumber = client->sequence;
+ rep->length = npixels + bytes_to_int32(nbytesRound);
+ rep->width = width;
+ rep->height = height;
+ rep->x = x;
+ rep->y = y;
+ rep->xhot = pCursor->bits->xhot;
+ rep->yhot = pCursor->bits->yhot;
+ rep->cursorSerial = pCursor->serialNumber;
+ rep->cursorName = pCursor->name;
+ rep->nbytes = nbytes;
+
+ image = (CARD32 *) (rep + 1);
+ CopyCursorToImage (pCursor, image);
+ memcpy ((image + npixels), name, nbytes);
+ if (client->swapped)
+ {
+ int n;
+ swaps (&rep->sequenceNumber, n);
+ swapl (&rep->length, n);
+ swaps (&rep->x, n);
+ swaps (&rep->y, n);
+ swaps (&rep->width, n);
+ swaps (&rep->height, n);
+ swaps (&rep->xhot, n);
+ swaps (&rep->yhot, n);
+ swapl (&rep->cursorSerial, n);
+ swapl (&rep->cursorName, n);
+ swaps (&rep->nbytes, n);
+ SwapLongs (image, npixels);
+ }
+ WriteToClient(client, sizeof (xXFixesGetCursorImageAndNameReply) +
+ (npixels << 2) + nbytesRound, (char *) rep);
+ xfree (rep);
+ return client->noClientException;
+}
+
+int
+SProcXFixesGetCursorImageAndName (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesGetCursorImageAndNameReq);
+ swaps (&stuff->length, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+/*
+ * Find every cursor reference in the system, ask testCursor
+ * whether it should be replaced with a reference to pCursor.
+ */
+
+typedef Bool (*TestCursorFunc) (CursorPtr pOld, pointer closure);
+
+typedef struct {
+ RESTYPE type;
+ TestCursorFunc testCursor;
+ CursorPtr pNew;
+ pointer closure;
+} ReplaceCursorLookupRec, *ReplaceCursorLookupPtr;
+
+static const RESTYPE CursorRestypes[] = {
+ RT_WINDOW, RT_PASSIVEGRAB, RT_CURSOR
+};
+
+#define NUM_CURSOR_RESTYPES (sizeof (CursorRestypes) / sizeof (CursorRestypes[0]))
+
+static Bool
+ReplaceCursorLookup (pointer value, XID id, pointer closure)
+{
+ ReplaceCursorLookupPtr rcl = (ReplaceCursorLookupPtr) closure;
+ WindowPtr pWin;
+ GrabPtr pGrab;
+ CursorPtr pCursor = 0, *pCursorRef = 0;
+ XID cursor = 0;
+
+ switch (rcl->type) {
+ case RT_WINDOW:
+ pWin = (WindowPtr) value;
+ if (pWin->optional)
+ {
+ pCursorRef = &pWin->optional->cursor;
+ pCursor = *pCursorRef;
+ }
+ break;
+ case RT_PASSIVEGRAB:
+ pGrab = (GrabPtr) value;
+ pCursorRef = &pGrab->cursor;
+ pCursor = *pCursorRef;
+ break;
+ case RT_CURSOR:
+ pCursorRef = 0;
+ pCursor = (CursorPtr) value;
+ cursor = id;
+ break;
+ }
+ if (pCursor && pCursor != rcl->pNew)
+ {
+ if ((*rcl->testCursor) (pCursor, rcl->closure))
+ {
+ rcl->pNew->refcnt++;
+ /* either redirect reference or update resource database */
+ if (pCursorRef)
+ *pCursorRef = rcl->pNew;
+ else
+ ChangeResourceValue (id, RT_CURSOR, rcl->pNew);
+ FreeCursor (pCursor, cursor);
+ }
+ }
+ return FALSE; /* keep walking */
+}
+
+static void
+ReplaceCursor (CursorPtr pCursor,
+ TestCursorFunc testCursor,
+ pointer closure)
+{
+ int clientIndex;
+ int resIndex;
+ ReplaceCursorLookupRec rcl;
+
+ /*
+ * Cursors exist only in the resource database, windows and grabs.
+ * All of these are always pointed at by the resource database. Walk
+ * the whole thing looking for cursors
+ */
+ rcl.testCursor = testCursor;
+ rcl.pNew = pCursor;
+ rcl.closure = closure;
+
+ /* for each client */
+ for (clientIndex = 0; clientIndex < currentMaxClients; clientIndex++)
+ {
+ if (!clients[clientIndex])
+ continue;
+ for (resIndex = 0; resIndex < NUM_CURSOR_RESTYPES; resIndex++)
+ {
+ rcl.type = CursorRestypes[resIndex];
+ /*
+ * This function walks the entire client resource database
+ */
+ LookupClientResourceComplex (clients[clientIndex],
+ rcl.type,
+ ReplaceCursorLookup,
+ (pointer) &rcl);
+ }
+ }
+ /* this "knows" that WindowHasNewCursor doesn't depend on it's argument */
+ WindowHasNewCursor (WindowTable[0]);
+}
+
+static Bool
+TestForCursor (CursorPtr pCursor, pointer closure)
+{
+ return (pCursor == (CursorPtr) closure);
+}
+
+int
+ProcXFixesChangeCursor (ClientPtr client)
+{
+ CursorPtr pSource, pDestination;
+ REQUEST(xXFixesChangeCursorReq);
+
+ REQUEST_SIZE_MATCH(xXFixesChangeCursorReq);
+ VERIFY_CURSOR (pSource, stuff->source, client,
+ DixReadAccess|DixGetAttrAccess);
+ VERIFY_CURSOR (pDestination, stuff->destination, client,
+ DixWriteAccess|DixSetAttrAccess);
+
+ ReplaceCursor (pSource, TestForCursor, (pointer) pDestination);
+ return (client->noClientException);
+}
+
+int
+SProcXFixesChangeCursor (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesChangeCursorReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH(xXFixesChangeCursorReq);
+ swapl (&stuff->source, n);
+ swapl (&stuff->destination, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+static Bool
+TestForCursorName (CursorPtr pCursor, pointer closure)
+{
+ Atom *pName = closure;
+ return (pCursor->name == *pName);
+}
+
+int
+ProcXFixesChangeCursorByName (ClientPtr client)
+{
+ CursorPtr pSource;
+ Atom name;
+ char *tchar;
+ REQUEST(xXFixesChangeCursorByNameReq);
+
+ REQUEST_FIXED_SIZE(xXFixesChangeCursorByNameReq, stuff->nbytes);
+ VERIFY_CURSOR(pSource, stuff->source, client,
+ DixReadAccess|DixGetAttrAccess);
+ tchar = (char *) &stuff[1];
+ name = MakeAtom (tchar, stuff->nbytes, FALSE);
+ if (name)
+ ReplaceCursor (pSource, TestForCursorName, &name);
+ return (client->noClientException);
+}
+
+int
+SProcXFixesChangeCursorByName (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesChangeCursorByNameReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_AT_LEAST_SIZE (xXFixesChangeCursorByNameReq);
+ swapl (&stuff->source, n);
+ swaps (&stuff->nbytes, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+/*
+ * Routines for manipulating the per-screen hide counts list.
+ * This list indicates which clients have requested cursor hiding
+ * for that screen.
+ */
+
+/* Return the screen's hide-counts list element for the given client */
+static CursorHideCountPtr
+findCursorHideCount (ClientPtr pClient, ScreenPtr pScreen)
+{
+ CursorScreenPtr cs = GetCursorScreen(pScreen);
+ CursorHideCountPtr pChc;
+
+ for (pChc = cs->pCursorHideCounts; pChc != NULL; pChc = pChc->pNext) {
+ if (pChc->pClient == pClient) {
+ return pChc;
+ }
+ }
+
+ return NULL;
+}
+
+static int
+createCursorHideCount (ClientPtr pClient, ScreenPtr pScreen)
+{
+ CursorScreenPtr cs = GetCursorScreen(pScreen);
+ CursorHideCountPtr pChc;
+
+ pChc = (CursorHideCountPtr) xalloc(sizeof(CursorHideCountRec));
+ if (pChc == NULL) {
+ return BadAlloc;
+ }
+ pChc->pClient = pClient;
+ pChc->pScreen = pScreen;
+ pChc->hideCount = 1;
+ pChc->resource = FakeClientID(pClient->index);
+ pChc->pNext = cs->pCursorHideCounts;
+ cs->pCursorHideCounts = pChc;
+
+ /*
+ * Create a resource for this element so it can be deleted
+ * when the client goes away.
+ */
+ if (!AddResource (pChc->resource, CursorHideCountType,
+ (pointer) pChc)) {
+ xfree(pChc);
+ return BadAlloc;
+ }
+
+ return Success;
+}
+
+/*
+ * Delete the given hide-counts list element from its screen list.
+ */
+static void
+deleteCursorHideCount (CursorHideCountPtr pChcToDel, ScreenPtr pScreen)
+{
+ CursorScreenPtr cs = GetCursorScreen(pScreen);
+ CursorHideCountPtr pChc, pNext;
+ CursorHideCountPtr pChcLast = NULL;
+
+ pChc = cs->pCursorHideCounts;
+ while (pChc != NULL) {
+ pNext = pChc->pNext;
+ if (pChc == pChcToDel) {
+ xfree(pChc);
+ if (pChcLast == NULL) {
+ cs->pCursorHideCounts = pNext;
+ } else {
+ pChcLast->pNext = pNext;
+ }
+ return;
+ }
+ pChcLast = pChc;
+ pChc = pNext;
+ }
+}
+
+/*
+ * Delete all the hide-counts list elements for this screen.
+ */
+static void
+deleteCursorHideCountsForScreen (ScreenPtr pScreen)
+{
+ CursorScreenPtr cs = GetCursorScreen(pScreen);
+ CursorHideCountPtr pChc, pTmp;
+
+ pChc = cs->pCursorHideCounts;
+ while (pChc != NULL) {
+ pTmp = pChc->pNext;
+ FreeResource(pChc->resource, 0);
+ pChc = pTmp;
+ }
+ cs->pCursorHideCounts = NULL;
+}
+
+int
+ProcXFixesHideCursor (ClientPtr client)
+{
+ WindowPtr pWin;
+ CursorHideCountPtr pChc;
+ REQUEST(xXFixesHideCursorReq);
+ int ret;
+
+ REQUEST_SIZE_MATCH (xXFixesHideCursorReq);
+
+ ret = dixLookupResourceByType((pointer *)&pWin, stuff->window, RT_WINDOW,
+ client, DixGetAttrAccess);
+ if (ret != Success) {
+ client->errorValue = stuff->window;
+ return (ret == BadValue) ? BadWindow : ret;
+ }
+
+ /*
+ * Has client hidden the cursor before on this screen?
+ * If so, just increment the count.
+ */
+
+ pChc = findCursorHideCount(client, pWin->drawable.pScreen);
+ if (pChc != NULL) {
+ pChc->hideCount++;
+ return client->noClientException;
+ }
+
+ /*
+ * This is the first time this client has hid the cursor
+ * for this screen.
+ */
+ ret = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen,
+ DixHideAccess);
+ if (ret != Success)
+ return ret;
+
+ ret = createCursorHideCount(client, pWin->drawable.pScreen);
+
+ if (ret == Success) {
+ DeviceIntPtr dev;
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (IsMaster(dev) && IsPointerDevice(dev))
+ CursorDisplayCursor(dev, pWin->drawable.pScreen, CursorCurrent[dev->id]);
+ }
+ }
+
+ return ret;
+}
+
+int
+SProcXFixesHideCursor (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesHideCursorReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xXFixesHideCursorReq);
+ swapl (&stuff->window, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+int
+ProcXFixesShowCursor (ClientPtr client)
+{
+ WindowPtr pWin;
+ CursorHideCountPtr pChc;
+ int rc;
+ REQUEST(xXFixesShowCursorReq);
+
+ REQUEST_SIZE_MATCH (xXFixesShowCursorReq);
+
+ rc = dixLookupResourceByType((pointer *)&pWin, stuff->window, RT_WINDOW,
+ client, DixGetAttrAccess);
+ if (rc != Success) {
+ client->errorValue = stuff->window;
+ return (rc == BadValue) ? BadWindow : rc;
+ }
+
+ /*
+ * Has client hidden the cursor on this screen?
+ * If not, generate an error.
+ */
+ pChc = findCursorHideCount(client, pWin->drawable.pScreen);
+ if (pChc == NULL) {
+ return BadMatch;
+ }
+
+ rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen,
+ DixShowAccess);
+ if (rc != Success)
+ return rc;
+
+ pChc->hideCount--;
+ if (pChc->hideCount <= 0) {
+ FreeResource(pChc->resource, 0);
+ }
+
+ return (client->noClientException);
+}
+
+int
+SProcXFixesShowCursor (ClientPtr client)
+{
+ int n;
+ REQUEST(xXFixesShowCursorReq);
+
+ swaps (&stuff->length, n);
+ REQUEST_SIZE_MATCH (xXFixesShowCursorReq);
+ swapl (&stuff->window, n);
+ return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
+}
+
+static int
+CursorFreeClient (pointer data, XID id)
+{
+ CursorEventPtr old = (CursorEventPtr) data;
+ CursorEventPtr *prev, e;
+
+ for (prev = &cursorEvents; (e = *prev); prev = &e->next)
+ {
+ if (e == old)
+ {
+ *prev = e->next;
+ xfree (e);
+ break;
+ }
+ }
+ return 1;
+}
+
+static int
+CursorFreeHideCount (pointer data, XID id)
+{
+ CursorHideCountPtr pChc = (CursorHideCountPtr) data;
+ ScreenPtr pScreen = pChc->pScreen;
+ DeviceIntPtr dev;
+
+ deleteCursorHideCount(pChc, pChc->pScreen);
+ for (dev = inputInfo.devices; dev; dev = dev->next)
+ {
+ if (IsMaster(dev) && IsPointerDevice(dev))
+ CursorDisplayCursor(dev, pScreen, CursorCurrent[dev->id]);
+ }
+
+ return 1;
+}
+
+static int
+CursorFreeWindow (pointer data, XID id)
+{
+ WindowPtr pWindow = (WindowPtr) data;
+ CursorEventPtr e, next;
+
+ for (e = cursorEvents; e; e = next)
+ {
+ next = e->next;
+ if (e->pWindow == pWindow)
+ {
+ FreeResource (e->clientResource, 0);
+ }
+ }
+ return 1;
+}
+
+static CursorPtr
+createInvisibleCursor (void)
+{
+ CursorPtr pCursor;
+ unsigned char *psrcbits, *pmaskbits;
+ CursorMetricRec cm;
+
+ psrcbits = (unsigned char *) xcalloc(4, 1);
+ pmaskbits = (unsigned char *) xcalloc(4, 1);
+ if (psrcbits == NULL || pmaskbits == NULL) {
+ return NULL;
+ }
+
+ cm.width = 1;
+ cm.height = 1;
+ cm.xhot = 0;
+ cm.yhot = 0;
+
+ AllocARGBCursor(psrcbits, pmaskbits,
+ NULL, &cm,
+ 0, 0, 0,
+ 0, 0, 0,
+ &pCursor, serverClient, (XID)0);
+
+ return pCursor;
+}
+
+Bool
+XFixesCursorInit (void)
+{
+ int i;
+
+ if (party_like_its_1989)
+ CursorVisible = EnableCursor;
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ {
+ ScreenPtr pScreen = screenInfo.screens[i];
+ CursorScreenPtr cs;
+
+ cs = (CursorScreenPtr) xalloc (sizeof (CursorScreenRec));
+ if (!cs)
+ return FALSE;
+ Wrap (cs, pScreen, CloseScreen, CursorCloseScreen);
+ Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor);
+ cs->pCursorHideCounts = NULL;
+ SetCursorScreen (pScreen, cs);
+ }
+ CursorClientType = CreateNewResourceType(CursorFreeClient,
+ "XFixesCursorClient");
+ CursorHideCountType = CreateNewResourceType(CursorFreeHideCount,
+ "XFixesCursorHideCount");
+ CursorWindowType = CreateNewResourceType(CursorFreeWindow,
+ "XFixesCursorWindow");
+
+ if (pInvisibleCursor == NULL) {
+ pInvisibleCursor = createInvisibleCursor();
+ if (pInvisibleCursor == NULL) {
+ return BadAlloc;
+ }
+ }
+
+ return CursorClientType && CursorHideCountType && CursorWindowType;
+}
+
diff --git a/xorg-server/xfixes/makefile b/xorg-server/xfixes/makefile new file mode 100644 index 000000000..73df36c4e --- /dev/null +++ b/xorg-server/xfixes/makefile @@ -0,0 +1,9 @@ +CSRCS = cursor.c \ + region.c \ + saveset.c \ + select.c \ + xfixes.c + +LIBRARY=libxfixes + + diff --git a/xorg-server/xkb/ddxList.c b/xorg-server/xkb/ddxList.c index e212ea3b5..421a2eae7 100644 --- a/xorg-server/xkb/ddxList.c +++ b/xorg-server/xkb/ddxList.c @@ -214,7 +214,12 @@ char tmpname[PATH_MAX]; } buf = xalloc(PATH_MAX * sizeof(char)); if (!buf) - return BadAlloc; + { +#ifdef WIN32 + unlink(tmpname); +#endif + return BadAlloc; + } while ((status==Success)&&((tmp=fgets(buf,PATH_MAX,in))!=NULL)) { unsigned flags; register unsigned int i; diff --git a/xorg-server/xkb/ddxLoad.c b/xorg-server/xkb/ddxLoad.c index 4ccdddaf0..bf7adb8e1 100644 --- a/xorg-server/xkb/ddxLoad.c +++ b/xorg-server/xkb/ddxLoad.c @@ -266,6 +266,10 @@ XkbDDXCompileKeymapByNames( XkbDescPtr xkb, } if (buf != NULL) xfree (buf); +#ifdef WIN32 + /* remove the temporary file */ + unlink(tmpname); +#endif return TRUE; } else diff --git a/xorg-server/xkb/makefile b/xorg-server/xkb/makefile new file mode 100644 index 000000000..643ea4d50 --- /dev/null +++ b/xorg-server/xkb/makefile @@ -0,0 +1,44 @@ +DEFINES += HAVE_XKB_CONFIG_H + +DDX_SRCS = \ + ddxBeep.c \ + ddxCtrls.c \ + ddxFakeMtn.c \ + ddxLEDs.c \ + ddxLoad.c \ + ddxList.c \ + ddxDevBtn.c + +DIX_SRCS = \ + xkb.c \ + xkbUtils.c \ + xkbEvents.c \ + xkbAccessX.c \ + xkbSwap.c \ + xkbLEDs.c \ + xkbInit.c \ + xkbActions.c \ + xkbPrKeyEv.c + +# this should be replaced by a common library or something, ideally -d +XKBFILE_SRCS = \ + maprules.c \ + xkmread.c \ + xkbtext.c \ + xkbfmisc.c \ + xkbout.c + +X11_SRCS = \ + XKBMisc.c \ + XKBAlloc.c \ + XKBGAlloc.c \ + XKBMAlloc.c + +# ends up unused... +# XI_SRCS = xkbPrOtherEv.c + +CSRCS = $(DDX_SRCS) $(DIX_SRCS) $(XI_SRCS) $(XKBFILE_SRCS) \ + $(X11_SRCS) ddxVT.c ddxPrivate.c ddxKillSrv.c + +LIBRARY=libxkb + diff --git a/xorg-server/xkb/xkb.c b/xorg-server/xkb/xkb.c index 29052bf13..666d50f8e 100644 --- a/xorg-server/xkb/xkb.c +++ b/xorg-server/xkb/xkb.c @@ -1,6721 +1,6723 @@ -/************************************************************ -Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - -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 Silicon Graphics not be -used in advertising or publicity pertaining to distribution -of the software without specific prior written permission. -Silicon Graphics makes no representation about the suitability -of this software for any purpose. It is provided "as is" -without any express or implied warranty. - -SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON -GRAPHICS 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 <dix-config.h> -#endif - -#include <stdio.h> -#include <X11/X.h> -#include <X11/Xproto.h> -#include "misc.h" -#include "inputstr.h" -#define XKBSRV_NEED_FILE_FUNCS -#include <xkbsrv.h> -#include "extnsionst.h" -#include "xace.h" -#include "xkb.h" -#include "protocol-versions.h" - -#include <X11/extensions/XI.h> -#include <X11/extensions/XKMformat.h> - -int XkbEventBase; -static int XkbErrorBase; -int XkbReqCode; -int XkbKeyboardErrorCode; -CARD32 xkbDebugFlags = 0; -static CARD32 xkbDebugCtrls = 0; - -static RESTYPE RT_XKBCLIENT; - -/***====================================================================***/ - -#define CHK_DEVICE(dev, id, client, access_mode, lf) {\ - int why;\ - int rc = lf(&(dev), id, client, access_mode, &why);\ - if (rc != Success) {\ - client->errorValue = _XkbErrCode2(why, id);\ - return rc;\ - }\ -} - -#define CHK_KBD_DEVICE(dev, id, client, mode) \ - CHK_DEVICE(dev, id, client, mode, _XkbLookupKeyboard) -#define CHK_LED_DEVICE(dev, id, client, mode) \ - CHK_DEVICE(dev, id, client, mode, _XkbLookupLedDevice) -#define CHK_BELL_DEVICE(dev, id, client, mode) \ - CHK_DEVICE(dev, id, client, mode, _XkbLookupBellDevice) -#define CHK_ANY_DEVICE(dev, id, client, mode) \ - CHK_DEVICE(dev, id, client, mode, _XkbLookupAnyDevice) - -#define CHK_ATOM_ONLY2(a,ev,er) {\ - if (((a)==None)||(!ValidAtom((a)))) {\ - (ev)= (XID)(a);\ - return er;\ - }\ -} -#define CHK_ATOM_ONLY(a) \ - CHK_ATOM_ONLY2(a,client->errorValue,BadAtom) - -#define CHK_ATOM_OR_NONE3(a,ev,er,ret) {\ - if (((a)!=None)&&(!ValidAtom((a)))) {\ - (ev)= (XID)(a);\ - (er)= BadAtom;\ - return ret;\ - }\ -} -#define CHK_ATOM_OR_NONE2(a,ev,er) {\ - if (((a)!=None)&&(!ValidAtom((a)))) {\ - (ev)= (XID)(a);\ - return er;\ - }\ -} -#define CHK_ATOM_OR_NONE(a) \ - CHK_ATOM_OR_NONE2(a,client->errorValue,BadAtom) - -#define CHK_MASK_LEGAL3(err,mask,legal,ev,er,ret) {\ - if ((mask)&(~(legal))) { \ - (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\ - (er)= BadValue;\ - return ret;\ - }\ -} -#define CHK_MASK_LEGAL2(err,mask,legal,ev,er) {\ - if ((mask)&(~(legal))) { \ - (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\ - return er;\ - }\ -} -#define CHK_MASK_LEGAL(err,mask,legal) \ - CHK_MASK_LEGAL2(err,mask,legal,client->errorValue,BadValue) - -#define CHK_MASK_MATCH(err,affect,value) {\ - if ((value)&(~(affect))) { \ - client->errorValue= _XkbErrCode2((err),((value)&(~(affect))));\ - return BadMatch;\ - }\ -} -#define CHK_MASK_OVERLAP(err,m1,m2) {\ - if ((m1)&(m2)) { \ - client->errorValue= _XkbErrCode2((err),((m1)&(m2)));\ - return BadMatch;\ - }\ -} -#define CHK_KEY_RANGE2(err,first,num,x,ev,er) {\ - if (((unsigned)(first)+(num)-1)>(x)->max_key_code) {\ - (ev)=_XkbErrCode4(err,(first),(num),(x)->max_key_code);\ - return er;\ - }\ - else if ( (first)<(x)->min_key_code ) {\ - (ev)=_XkbErrCode3(err+1,(first),xkb->min_key_code);\ - return er;\ - }\ -} -#define CHK_KEY_RANGE(err,first,num,x) \ - CHK_KEY_RANGE2(err,first,num,x,client->errorValue,BadValue) - -#define CHK_REQ_KEY_RANGE2(err,first,num,r,ev,er) {\ - if (((unsigned)(first)+(num)-1)>(r)->maxKeyCode) {\ - (ev)=_XkbErrCode4(err,(first),(num),(r)->maxKeyCode);\ - return er;\ - }\ - else if ( (first)<(r)->minKeyCode ) {\ - (ev)=_XkbErrCode3(err+1,(first),(r)->minKeyCode);\ - return er;\ - }\ -} -#define CHK_REQ_KEY_RANGE(err,first,num,r) \ - CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue) - -/***====================================================================***/ - -int -ProcXkbUseExtension(ClientPtr client) -{ - REQUEST(xkbUseExtensionReq); - xkbUseExtensionReply rep; - register int n; - int supported; - - REQUEST_SIZE_MATCH(xkbUseExtensionReq); - if (stuff->wantedMajor != SERVER_XKB_MAJOR_VERSION) { - /* pre-release version 0.65 is compatible with 1.00 */ - supported= ((SERVER_XKB_MAJOR_VERSION==1)&& - (stuff->wantedMajor==0)&&(stuff->wantedMinor==65)); - } - else supported = 1; - - if ((supported) && (!(client->xkbClientFlags&_XkbClientInitialized))) { - client->xkbClientFlags= _XkbClientInitialized; - client->vMajor= stuff->wantedMajor; - client->vMinor= stuff->wantedMinor; - } - else if (xkbDebugFlags&0x1) { - ErrorF("[xkb] Rejecting client %d (0x%lx) (wants %d.%02d, have %d.%02d)\n", - client->index, - (long)client->clientAsMask, - stuff->wantedMajor,stuff->wantedMinor, - SERVER_XKB_MAJOR_VERSION,SERVER_XKB_MINOR_VERSION); - } - memset(&rep, 0, sizeof(xkbUseExtensionReply)); - rep.type = X_Reply; - rep.supported = supported; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.serverMajor = SERVER_XKB_MAJOR_VERSION; - rep.serverMinor = SERVER_XKB_MINOR_VERSION; - if ( client->swapped ) { - swaps(&rep.sequenceNumber, n); - swaps(&rep.serverMajor, n); - swaps(&rep.serverMinor, n); - } - WriteToClient(client,SIZEOF(xkbUseExtensionReply), (char *)&rep); - return client->noClientException; -} - -/***====================================================================***/ - -int -ProcXkbSelectEvents(ClientPtr client) -{ - unsigned legal; - DeviceIntPtr dev; - XkbInterestPtr masks; - REQUEST(xkbSelectEventsReq); - - REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixUseAccess); - - if (((stuff->affectWhich&XkbMapNotifyMask)!=0)&&(stuff->affectMap)) { - client->mapNotifyMask&= ~stuff->affectMap; - client->mapNotifyMask|= (stuff->affectMap&stuff->map); - } - if ((stuff->affectWhich&(~XkbMapNotifyMask))==0) - return client->noClientException; - - masks = XkbFindClientResource((DevicePtr)dev,client); - if (!masks){ - XID id = FakeClientID(client->index); - AddResource(id,RT_XKBCLIENT,dev); - masks= XkbAddClientResource((DevicePtr)dev,client,id); - } - if (masks) { - union { - CARD8 *c8; - CARD16 *c16; - CARD32 *c32; - } from,to; - register unsigned bit,ndx,maskLeft,dataLeft,size; - - from.c8= (CARD8 *)&stuff[1]; - dataLeft= (stuff->length*4)-SIZEOF(xkbSelectEventsReq); - maskLeft= (stuff->affectWhich&(~XkbMapNotifyMask)); - for (ndx=0,bit=1; (maskLeft!=0); ndx++, bit<<=1) { - if ((bit&maskLeft)==0) - continue; - maskLeft&= ~bit; - switch (ndx) { - case XkbNewKeyboardNotify: - to.c16= &client->newKeyboardNotifyMask; - legal= XkbAllNewKeyboardEventsMask; - size= 2; - break; - case XkbStateNotify: - to.c16= &masks->stateNotifyMask; - legal= XkbAllStateEventsMask; - size= 2; - break; - case XkbControlsNotify: - to.c32= &masks->ctrlsNotifyMask; - legal= XkbAllControlEventsMask; - size= 4; - break; - case XkbIndicatorStateNotify: - to.c32= &masks->iStateNotifyMask; - legal= XkbAllIndicatorEventsMask; - size= 4; - break; - case XkbIndicatorMapNotify: - to.c32= &masks->iMapNotifyMask; - legal= XkbAllIndicatorEventsMask; - size= 4; - break; - case XkbNamesNotify: - to.c16= &masks->namesNotifyMask; - legal= XkbAllNameEventsMask; - size= 2; - break; - case XkbCompatMapNotify: - to.c8= &masks->compatNotifyMask; - legal= XkbAllCompatMapEventsMask; - size= 1; - break; - case XkbBellNotify: - to.c8= &masks->bellNotifyMask; - legal= XkbAllBellEventsMask; - size= 1; - break; - case XkbActionMessage: - to.c8= &masks->actionMessageMask; - legal= XkbAllActionMessagesMask; - size= 1; - break; - case XkbAccessXNotify: - to.c16= &masks->accessXNotifyMask; - legal= XkbAllAccessXEventsMask; - size= 2; - break; - case XkbExtensionDeviceNotify: - to.c16= &masks->extDevNotifyMask; - legal= XkbAllExtensionDeviceEventsMask; - size= 2; - break; - default: - client->errorValue = _XkbErrCode2(33,bit); - return BadValue; - } - - if (stuff->clear&bit) { - if (size==2) to.c16[0]= 0; - else if (size==4) to.c32[0]= 0; - else to.c8[0]= 0; - } - else if (stuff->selectAll&bit) { - if (size==2) to.c16[0]= ~0; - else if (size==4) to.c32[0]= ~0; - else to.c8[0]= ~0; - } - else { - if (dataLeft<(size*2)) - return BadLength; - if (size==2) { - CHK_MASK_MATCH(ndx,from.c16[0],from.c16[1]); - CHK_MASK_LEGAL(ndx,from.c16[0],legal); - to.c16[0]&= ~from.c16[0]; - to.c16[0]|= (from.c16[0]&from.c16[1]); - } - else if (size==4) { - CHK_MASK_MATCH(ndx,from.c32[0],from.c32[1]); - CHK_MASK_LEGAL(ndx,from.c32[0],legal); - to.c32[0]&= ~from.c32[0]; - to.c32[0]|= (from.c32[0]&from.c32[1]); - } - else { - CHK_MASK_MATCH(ndx,from.c8[0],from.c8[1]); - CHK_MASK_LEGAL(ndx,from.c8[0],legal); - to.c8[0]&= ~from.c8[0]; - to.c8[0]|= (from.c8[0]&from.c8[1]); - size= 2; - } - from.c8+= (size*2); - dataLeft-= (size*2); - } - } - if (dataLeft>2) { - ErrorF("[xkb] Extra data (%d bytes) after SelectEvents\n",dataLeft); - return BadLength; - } - return client->noClientException; - } - return BadAlloc; -} - -/***====================================================================***/ -/** - * Ring a bell on the given device for the given client. - */ -static int -_XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin, - int bellClass, int bellID, int pitch, int duration, - int percent, int forceSound, int eventOnly, Atom name) -{ - int base; - pointer ctrl; - int oldPitch, oldDuration; - int newPercent; - - if (bellClass == KbdFeedbackClass) { - KbdFeedbackPtr k; - if (bellID==XkbDfltXIId) - k= dev->kbdfeed; - else { - for (k=dev->kbdfeed; k; k=k->next) { - if (k->ctrl.id == bellID) - break; - } - } - if (!k) { - client->errorValue = _XkbErrCode2(0x5,bellID); - return BadValue; - } - base = k->ctrl.bell; - ctrl = (pointer) &(k->ctrl); - oldPitch= k->ctrl.bell_pitch; - oldDuration= k->ctrl.bell_duration; - if (pitch!=0) { - if (pitch==-1) - k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch; - else k->ctrl.bell_pitch= pitch; - } - if (duration!=0) { - if (duration==-1) - k->ctrl.bell_duration= defaultKeyboardControl.bell_duration; - else k->ctrl.bell_duration= duration; - } - } - else if (bellClass == BellFeedbackClass) { - BellFeedbackPtr b; - if (bellID==XkbDfltXIId) - b= dev->bell; - else { - for (b=dev->bell; b; b=b->next) { - if (b->ctrl.id == bellID) - break; - } - } - if (!b) { - client->errorValue = _XkbErrCode2(0x6,bellID); - return BadValue; - } - base = b->ctrl.percent; - ctrl = (pointer) &(b->ctrl); - oldPitch= b->ctrl.pitch; - oldDuration= b->ctrl.duration; - if (pitch!=0) { - if (pitch==-1) - b->ctrl.pitch= defaultKeyboardControl.bell_pitch; - else b->ctrl.pitch= pitch; - } - if (duration!=0) { - if (duration==-1) - b->ctrl.duration= defaultKeyboardControl.bell_duration; - else b->ctrl.duration= duration; - } - } - else { - client->errorValue = _XkbErrCode2(0x7, bellClass); - return BadValue; - } - - newPercent = (base * percent)/100; - if (percent < 0) - newPercent = base + newPercent; - else newPercent = base - newPercent + percent; - - XkbHandleBell(forceSound, eventOnly, - dev, newPercent, ctrl, bellClass, - name, pWin, client); - if ((pitch!=0)||(duration!=0)) { - if (bellClass == KbdFeedbackClass) { - KbdFeedbackPtr k; - k= (KbdFeedbackPtr)ctrl; - if (pitch!=0) - k->ctrl.bell_pitch= oldPitch; - if (duration!=0) - k->ctrl.bell_duration= oldDuration; - } - else { - BellFeedbackPtr b; - b= (BellFeedbackPtr)ctrl; - if (pitch!=0) - b->ctrl.pitch= oldPitch; - if (duration!=0) - b->ctrl.duration= oldDuration; - } - } - - return Success; -} - -int -ProcXkbBell(ClientPtr client) -{ - REQUEST(xkbBellReq); - DeviceIntPtr dev; - WindowPtr pWin; - int rc; - - REQUEST_SIZE_MATCH(xkbBellReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_BELL_DEVICE(dev, stuff->deviceSpec, client, DixBellAccess); - CHK_ATOM_OR_NONE(stuff->name); - - /* device-independent checks request for sane values */ - if ((stuff->forceSound)&&(stuff->eventOnly)) { - client->errorValue=_XkbErrCode3(0x1,stuff->forceSound,stuff->eventOnly); - return BadMatch; - } - if (stuff->percent < -100 || stuff->percent > 100) { - client->errorValue = _XkbErrCode2(0x2,stuff->percent); - return BadValue; - } - if (stuff->duration<-1) { - client->errorValue = _XkbErrCode2(0x3,stuff->duration); - return BadValue; - } - if (stuff->pitch<-1) { - client->errorValue = _XkbErrCode2(0x4,stuff->pitch); - return BadValue; - } - - if (stuff->bellClass == XkbDfltXIClass) { - if (dev->kbdfeed!=NULL) - stuff->bellClass= KbdFeedbackClass; - else stuff->bellClass= BellFeedbackClass; - } - - if (stuff->window!=None) { - rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); - if (rc != Success) { - client->errorValue= stuff->window; - return rc; - } - } - else pWin= NULL; - - /* Client wants to ring a bell on the core keyboard? - Ring the bell on the core keyboard (which does nothing, but if that - fails the client is screwed anyway), and then on all extension devices. - Fail if the core keyboard fails but not the extension devices. this - may cause some keyboards to ding and others to stay silent. Fix - your client to use explicit keyboards to avoid this. - - dev is the device the client requested. - */ - rc = _XkbBell(client, dev, pWin, stuff->bellClass, stuff->bellID, - stuff->pitch, stuff->duration, stuff->percent, - stuff->forceSound, stuff->eventOnly, stuff->name); - - if ((rc == Success) && ((stuff->deviceSpec == XkbUseCoreKbd) || - (stuff->deviceSpec == XkbUseCorePtr))) - { - DeviceIntPtr other; - for (other = inputInfo.devices; other; other = other->next) - { - if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev)) - { - rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixBellAccess); - if (rc == Success) - _XkbBell(client, other, pWin, stuff->bellClass, - stuff->bellID, stuff->pitch, stuff->duration, - stuff->percent, stuff->forceSound, - stuff->eventOnly, stuff->name); - } - } - rc = Success; /* reset to success, that's what we got for the VCK */ - } - - return rc; -} - -/***====================================================================***/ - -int -ProcXkbGetState(ClientPtr client) -{ - REQUEST(xkbGetStateReq); - DeviceIntPtr dev; - xkbGetStateReply rep; - XkbStateRec *xkb; - - REQUEST_SIZE_MATCH(xkbGetStateReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); - - xkb= &dev->key->xkbInfo->state; - bzero(&rep,sizeof(xkbGetStateReply)); - rep.type= X_Reply; - rep.sequenceNumber= client->sequence; - rep.length = 0; - rep.deviceID = dev->id; - rep.mods = XkbStateFieldFromRec(xkb) & 0xff; - rep.baseMods = xkb->base_mods; - rep.lockedMods = xkb->locked_mods; - rep.latchedMods = xkb->latched_mods; - rep.group = xkb->group; - rep.baseGroup = xkb->base_group; - rep.latchedGroup = xkb->latched_group; - rep.lockedGroup = xkb->locked_group; - rep.compatState = xkb->compat_state; - rep.ptrBtnState = xkb->ptr_buttons; - if (client->swapped) { - register int n; - swaps(&rep.sequenceNumber,n); - swaps(&rep.ptrBtnState,n); - } - WriteToClient(client, SIZEOF(xkbGetStateReply), (char *)&rep); - return client->noClientException; -} - -/***====================================================================***/ - -int -ProcXkbLatchLockState(ClientPtr client) -{ - int status; - DeviceIntPtr dev, tmpd; - XkbStateRec oldState,*newState; - CARD16 changed; - xkbStateNotify sn; - XkbEventCauseRec cause; - - REQUEST(xkbLatchLockStateReq); - REQUEST_SIZE_MATCH(xkbLatchLockStateReq); - - if (!(client->xkbClientFlags & _XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); - CHK_MASK_MATCH(0x01, stuff->affectModLocks, stuff->modLocks); - CHK_MASK_MATCH(0x01, stuff->affectModLatches, stuff->modLatches); - - status = Success; - - for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { - if ((tmpd == dev) || (!IsMaster(tmpd) && tmpd->u.master == dev)) { - if (!tmpd->key || !tmpd->key->xkbInfo) - continue; - - oldState = tmpd->key->xkbInfo->state; - newState = &tmpd->key->xkbInfo->state; - if (stuff->affectModLocks) { - newState->locked_mods &= ~stuff->affectModLocks; - newState->locked_mods |= (stuff->affectModLocks & stuff->modLocks); - } - if (status == Success && stuff->lockGroup) - newState->locked_group = stuff->groupLock; - if (status == Success && stuff->affectModLatches) - status = XkbLatchModifiers(tmpd, stuff->affectModLatches, - stuff->modLatches); - if (status == Success && stuff->latchGroup) - status = XkbLatchGroup(tmpd, stuff->groupLatch); - - if (status != Success) - return status; - - XkbComputeDerivedState(tmpd->key->xkbInfo); - - changed = XkbStateChangedFlags(&oldState, newState); - if (changed) { - sn.keycode = 0; - sn.eventType = 0; - sn.requestMajor = XkbReqCode; - sn.requestMinor = X_kbLatchLockState; - sn.changed = changed; - XkbSendStateNotify(tmpd, &sn); - changed = XkbIndicatorsToUpdate(tmpd, changed, FALSE); - if (changed) { - XkbSetCauseXkbReq(&cause, X_kbLatchLockState, client); - XkbUpdateIndicators(tmpd, changed, TRUE, NULL, &cause); - } - } - } - } - - return client->noClientException; -} - -/***====================================================================***/ - -int -ProcXkbGetControls(ClientPtr client) -{ - xkbGetControlsReply rep; - XkbControlsPtr xkb; - DeviceIntPtr dev; - register int n; - - REQUEST(xkbGetControlsReq); - REQUEST_SIZE_MATCH(xkbGetControlsReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); - - xkb = dev->key->xkbInfo->desc->ctrls; - rep.type = X_Reply; - rep.length = bytes_to_int32(SIZEOF(xkbGetControlsReply)- - SIZEOF(xGenericReply)); - rep.sequenceNumber = client->sequence; - rep.deviceID = ((DeviceIntPtr)dev)->id; - rep.numGroups = xkb->num_groups; - rep.groupsWrap = xkb->groups_wrap; - rep.internalMods = xkb->internal.mask; - rep.ignoreLockMods = xkb->ignore_lock.mask; - rep.internalRealMods = xkb->internal.real_mods; - rep.ignoreLockRealMods = xkb->ignore_lock.real_mods; - rep.internalVMods = xkb->internal.vmods; - rep.ignoreLockVMods = xkb->ignore_lock.vmods; - rep.enabledCtrls = xkb->enabled_ctrls; - rep.repeatDelay = xkb->repeat_delay; - rep.repeatInterval = xkb->repeat_interval; - rep.slowKeysDelay = xkb->slow_keys_delay; - rep.debounceDelay = xkb->debounce_delay; - rep.mkDelay = xkb->mk_delay; - rep.mkInterval = xkb->mk_interval; - rep.mkTimeToMax = xkb->mk_time_to_max; - rep.mkMaxSpeed = xkb->mk_max_speed; - rep.mkCurve = xkb->mk_curve; - rep.mkDfltBtn = xkb->mk_dflt_btn; - rep.axTimeout = xkb->ax_timeout; - rep.axtCtrlsMask = xkb->axt_ctrls_mask; - rep.axtCtrlsValues = xkb->axt_ctrls_values; - rep.axtOptsMask = xkb->axt_opts_mask; - rep.axtOptsValues = xkb->axt_opts_values; - rep.axOptions = xkb->ax_options; - memcpy(rep.perKeyRepeat,xkb->per_key_repeat,XkbPerKeyBitArraySize); - if (client->swapped) { - swaps(&rep.sequenceNumber, n); - swapl(&rep.length,n); - swaps(&rep.internalVMods, n); - swaps(&rep.ignoreLockVMods, n); - swapl(&rep.enabledCtrls, n); - swaps(&rep.repeatDelay, n); - swaps(&rep.repeatInterval, n); - swaps(&rep.slowKeysDelay, n); - swaps(&rep.debounceDelay, n); - swaps(&rep.mkDelay, n); - swaps(&rep.mkInterval, n); - swaps(&rep.mkTimeToMax, n); - swaps(&rep.mkMaxSpeed, n); - swaps(&rep.mkCurve, n); - swaps(&rep.axTimeout, n); - swapl(&rep.axtCtrlsMask, n); - swapl(&rep.axtCtrlsValues, n); - swaps(&rep.axtOptsMask, n); - swaps(&rep.axtOptsValues, n); - swaps(&rep.axOptions, n); - } - WriteToClient(client, SIZEOF(xkbGetControlsReply), (char *)&rep); - return(client->noClientException); -} - -int -ProcXkbSetControls(ClientPtr client) -{ - DeviceIntPtr dev, tmpd; - XkbSrvInfoPtr xkbi; - XkbControlsPtr ctrl; - XkbControlsRec new,old; - xkbControlsNotify cn; - XkbEventCauseRec cause; - XkbSrvLedInfoPtr sli; - - REQUEST(xkbSetControlsReq); - REQUEST_SIZE_MATCH(xkbSetControlsReq); - - if (!(client->xkbClientFlags & _XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); - CHK_MASK_LEGAL(0x01, stuff->changeCtrls, XkbAllControlsMask); - - for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { - if (!tmpd->key || !tmpd->key->xkbInfo) - continue; - if ((tmpd == dev) || (!IsMaster(tmpd) && tmpd->u.master == dev)) { - xkbi = tmpd->key->xkbInfo; - ctrl = xkbi->desc->ctrls; - new = *ctrl; - XkbSetCauseXkbReq(&cause, X_kbSetControls, client); - - if (stuff->changeCtrls & XkbInternalModsMask) { - CHK_MASK_MATCH(0x02, stuff->affectInternalMods, - stuff->internalMods); - CHK_MASK_MATCH(0x03, stuff->affectInternalVMods, - stuff->internalVMods); - - new.internal.real_mods &= ~(stuff->affectInternalMods); - new.internal.real_mods |= (stuff->affectInternalMods & - stuff->internalMods); - new.internal.vmods &= ~(stuff->affectInternalVMods); - new.internal.vmods |= (stuff->affectInternalVMods & - stuff->internalVMods); - new.internal.mask = new.internal.real_mods | - XkbMaskForVMask(xkbi->desc, - new.internal.vmods); - } - - if (stuff->changeCtrls & XkbIgnoreLockModsMask) { - CHK_MASK_MATCH(0x4, stuff->affectIgnoreLockMods, - stuff->ignoreLockMods); - CHK_MASK_MATCH(0x5, stuff->affectIgnoreLockVMods, - stuff->ignoreLockVMods); - - new.ignore_lock.real_mods &= ~(stuff->affectIgnoreLockMods); - new.ignore_lock.real_mods |= (stuff->affectIgnoreLockMods & - stuff->ignoreLockMods); - new.ignore_lock.vmods &= ~(stuff->affectIgnoreLockVMods); - new.ignore_lock.vmods |= (stuff->affectIgnoreLockVMods & - stuff->ignoreLockVMods); - new.ignore_lock.mask = new.ignore_lock.real_mods | - XkbMaskForVMask(xkbi->desc, - new.ignore_lock.vmods); - } - - CHK_MASK_MATCH(0x06, stuff->affectEnabledCtrls, - stuff->enabledCtrls); - if (stuff->affectEnabledCtrls) { - CHK_MASK_LEGAL(0x07, stuff->affectEnabledCtrls, - XkbAllBooleanCtrlsMask); - - new.enabled_ctrls &= ~(stuff->affectEnabledCtrls); - new.enabled_ctrls |= (stuff->affectEnabledCtrls & - stuff->enabledCtrls); - } - - if (stuff->changeCtrls & XkbRepeatKeysMask) { - if (stuff->repeatDelay < 1 || stuff->repeatInterval < 1) { - client->errorValue = _XkbErrCode3(0x08, stuff->repeatDelay, - stuff->repeatInterval); - return BadValue; - } - - new.repeat_delay = stuff->repeatDelay; - new.repeat_interval = stuff->repeatInterval; - } - - if (stuff->changeCtrls & XkbSlowKeysMask) { - if (stuff->slowKeysDelay < 1) { - client->errorValue = _XkbErrCode2(0x09, - stuff->slowKeysDelay); - return BadValue; - } - - new.slow_keys_delay = stuff->slowKeysDelay; - } - - if (stuff->changeCtrls & XkbBounceKeysMask) { - if (stuff->debounceDelay < 1) { - client->errorValue = _XkbErrCode2(0x0A, - stuff->debounceDelay); - return BadValue; - } - - new.debounce_delay = stuff->debounceDelay; - } - - if (stuff->changeCtrls & XkbMouseKeysMask) { - if (stuff->mkDfltBtn > XkbMaxMouseKeysBtn) { - client->errorValue = _XkbErrCode2(0x0B, stuff->mkDfltBtn); - return BadValue; - } - - new.mk_dflt_btn = stuff->mkDfltBtn; - } - - if (stuff->changeCtrls & XkbMouseKeysAccelMask) { - if (stuff->mkDelay < 1 || stuff->mkInterval < 1 || - stuff->mkTimeToMax < 1 || stuff->mkMaxSpeed < 1 || - stuff->mkCurve < -1000) { - client->errorValue = _XkbErrCode2(0x0C,0); - return BadValue; - } - - new.mk_delay = stuff->mkDelay; - new.mk_interval = stuff->mkInterval; - new.mk_time_to_max = stuff->mkTimeToMax; - new.mk_max_speed = stuff->mkMaxSpeed; - new.mk_curve = stuff->mkCurve; - AccessXComputeCurveFactor(xkbi, &new); - } - - if (stuff->changeCtrls & XkbGroupsWrapMask) { - unsigned act, num; - - act = XkbOutOfRangeGroupAction(stuff->groupsWrap); - switch (act) { - case XkbRedirectIntoRange: - num = XkbOutOfRangeGroupNumber(stuff->groupsWrap); - if (num >= new.num_groups) { - client->errorValue = _XkbErrCode3(0x0D, new.num_groups, - num); - return BadValue; - } - case XkbWrapIntoRange: - case XkbClampIntoRange: - break; - default: - client->errorValue = _XkbErrCode2(0x0E, act); - return BadValue; - } - - new.groups_wrap= stuff->groupsWrap; - } - - CHK_MASK_LEGAL(0x0F, stuff->axOptions, XkbAX_AllOptionsMask); - if (stuff->changeCtrls & XkbAccessXKeysMask) { - new.ax_options = stuff->axOptions & XkbAX_AllOptionsMask; - } - else { - if (stuff->changeCtrls & XkbStickyKeysMask) { - new.ax_options &= ~(XkbAX_SKOptionsMask); - new.ax_options |= (stuff->axOptions & XkbAX_SKOptionsMask); - } - - if (stuff->changeCtrls & XkbAccessXFeedbackMask) { - new.ax_options &= ~(XkbAX_FBOptionsMask); - new.ax_options |= (stuff->axOptions & XkbAX_FBOptionsMask); - } - } - - if (stuff->changeCtrls & XkbAccessXTimeoutMask) { - if (stuff->axTimeout < 1) { - client->errorValue = _XkbErrCode2(0x10, stuff->axTimeout); - return BadValue; - } - CHK_MASK_MATCH(0x11, stuff->axtCtrlsMask, - stuff->axtCtrlsValues); - CHK_MASK_LEGAL(0x12, stuff->axtCtrlsMask, - XkbAllBooleanCtrlsMask); - CHK_MASK_MATCH(0x13, stuff->axtOptsMask, stuff->axtOptsValues); - CHK_MASK_LEGAL(0x14, stuff->axtOptsMask, XkbAX_AllOptionsMask); - new.ax_timeout = stuff->axTimeout; - new.axt_ctrls_mask = stuff->axtCtrlsMask; - new.axt_ctrls_values = (stuff->axtCtrlsValues & - stuff->axtCtrlsMask); - new.axt_opts_mask = stuff->axtOptsMask; - new.axt_opts_values = (stuff->axtOptsValues & - stuff->axtOptsMask); - } - - if (stuff->changeCtrls & XkbPerKeyRepeatMask) - memcpy(new.per_key_repeat, stuff->perKeyRepeat, - XkbPerKeyBitArraySize); - - old= *ctrl; - *ctrl= new; - XkbDDXChangeControls(tmpd, &old, ctrl); - - if (XkbComputeControlsNotify(tmpd, &old, ctrl, &cn, FALSE)) { - cn.keycode = 0; - cn.eventType = 0; - cn.requestMajor = XkbReqCode; - cn.requestMinor = X_kbSetControls; - XkbSendControlsNotify(tmpd, &cn); - } - - sli = XkbFindSrvLedInfo(tmpd, XkbDfltXIClass, XkbDfltXIId, 0); - if (sli) - XkbUpdateIndicators(tmpd, sli->usesControls, TRUE, NULL, - &cause); - - /* If sticky keys were disabled, clear all locks and latches */ - if ((old.enabled_ctrls & XkbStickyKeysMask) && - !(ctrl->enabled_ctrls & XkbStickyKeysMask)) - XkbClearAllLatchesAndLocks(tmpd, xkbi, TRUE, &cause); - } - } - - return client->noClientException; -} - -/***====================================================================***/ - -static int -XkbSizeKeyTypes(XkbDescPtr xkb,xkbGetMapReply *rep) -{ - XkbKeyTypeRec *type; - unsigned i,len; - - len= 0; - if (((rep->present&XkbKeyTypesMask)==0)||(rep->nTypes<1)|| - (!xkb)||(!xkb->map)||(!xkb->map->types)) { - rep->present&= ~XkbKeyTypesMask; - rep->firstType= rep->nTypes= 0; - return 0; - } - type= &xkb->map->types[rep->firstType]; - for (i=0;i<rep->nTypes;i++,type++){ - len+= SIZEOF(xkbKeyTypeWireDesc); - if (type->map_count>0) { - len+= (type->map_count*SIZEOF(xkbKTMapEntryWireDesc)); - if (type->preserve) - len+= (type->map_count*SIZEOF(xkbModsWireDesc)); - } - } - return len; -} - -static char * -XkbWriteKeyTypes( XkbDescPtr xkb, - xkbGetMapReply * rep, - char * buf, - ClientPtr client) -{ - XkbKeyTypePtr type; - unsigned i; - xkbKeyTypeWireDesc *wire; - - type= &xkb->map->types[rep->firstType]; - for (i=0;i<rep->nTypes;i++,type++) { - register unsigned n; - wire= (xkbKeyTypeWireDesc *)buf; - wire->mask = type->mods.mask; - wire->realMods = type->mods.real_mods; - wire->virtualMods = type->mods.vmods; - wire->numLevels = type->num_levels; - wire->nMapEntries = type->map_count; - wire->preserve = (type->preserve!=NULL); - if (client->swapped) { - register int n; - swaps(&wire->virtualMods,n); - } - - buf= (char *)&wire[1]; - if (wire->nMapEntries>0) { - xkbKTMapEntryWireDesc * wire; - XkbKTMapEntryPtr entry; - wire= (xkbKTMapEntryWireDesc *)buf; - entry= type->map; - for (n=0;n<type->map_count;n++,wire++,entry++) { - wire->active= entry->active; - wire->mask= entry->mods.mask; - wire->level= entry->level; - wire->realMods= entry->mods.real_mods; - wire->virtualMods= entry->mods.vmods; - if (client->swapped) { - register int n; - swaps(&wire->virtualMods,n); - } - } - buf= (char *)wire; - if (type->preserve!=NULL) { - xkbModsWireDesc * pwire; - XkbModsPtr preserve; - pwire= (xkbModsWireDesc *)buf; - preserve= type->preserve; - for (n=0;n<type->map_count;n++,pwire++,preserve++) { - pwire->mask= preserve->mask; - pwire->realMods= preserve->real_mods; - pwire->virtualMods= preserve->vmods; - if (client->swapped) { - register int n; - swaps(&pwire->virtualMods,n); - } - } - buf= (char *)pwire; - } - } - } - return buf; -} - -static int -XkbSizeKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep) -{ - XkbSymMapPtr symMap; - unsigned i,len; - unsigned nSyms,nSymsThisKey; - - if (((rep->present&XkbKeySymsMask)==0)||(rep->nKeySyms<1)|| - (!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)) { - rep->present&= ~XkbKeySymsMask; - rep->firstKeySym= rep->nKeySyms= 0; - rep->totalSyms= 0; - return 0; - } - len= rep->nKeySyms*SIZEOF(xkbSymMapWireDesc); - symMap = &xkb->map->key_sym_map[rep->firstKeySym]; - for (i=nSyms=0;i<rep->nKeySyms;i++,symMap++) { - if (symMap->offset!=0) { - nSymsThisKey= XkbNumGroups(symMap->group_info)*symMap->width; - nSyms+= nSymsThisKey; - } - } - len+= nSyms*4; - rep->totalSyms= nSyms; - return len; -} - -static int -XkbSizeVirtualMods(XkbDescPtr xkb,xkbGetMapReply *rep) -{ -register unsigned i,nMods,bit; - - if (((rep->present&XkbVirtualModsMask)==0)||(rep->virtualMods==0)|| - (!xkb)||(!xkb->server)) { - rep->present&= ~XkbVirtualModsMask; - rep->virtualMods= 0; - return 0; - } - for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { - if (rep->virtualMods&bit) - nMods++; - } - return XkbPaddedSize(nMods); -} - -static char * -XkbWriteKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client) -{ -register KeySym * pSym; -XkbSymMapPtr symMap; -xkbSymMapWireDesc * outMap; -register unsigned i; - - symMap = &xkb->map->key_sym_map[rep->firstKeySym]; - for (i=0;i<rep->nKeySyms;i++,symMap++) { - outMap = (xkbSymMapWireDesc *)buf; - outMap->ktIndex[0] = symMap->kt_index[0]; - outMap->ktIndex[1] = symMap->kt_index[1]; - outMap->ktIndex[2] = symMap->kt_index[2]; - outMap->ktIndex[3] = symMap->kt_index[3]; - outMap->groupInfo = symMap->group_info; - outMap->width= symMap->width; - outMap->nSyms = symMap->width*XkbNumGroups(symMap->group_info); - buf= (char *)&outMap[1]; - if (outMap->nSyms==0) - continue; - - pSym = &xkb->map->syms[symMap->offset]; - memcpy((char *)buf,(char *)pSym,outMap->nSyms*4); - if (client->swapped) { - register int n,nSyms= outMap->nSyms; - swaps(&outMap->nSyms,n); - while (nSyms-->0) { - swapl(buf,n); - buf+= 4; - } - } - else buf+= outMap->nSyms*4; - } - return buf; -} - -static int -XkbSizeKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep) -{ - unsigned i,len,nActs; - register KeyCode firstKey; - - if (((rep->present&XkbKeyActionsMask)==0)||(rep->nKeyActs<1)|| - (!xkb)||(!xkb->server)||(!xkb->server->key_acts)) { - rep->present&= ~XkbKeyActionsMask; - rep->firstKeyAct= rep->nKeyActs= 0; - rep->totalActs= 0; - return 0; - } - firstKey= rep->firstKeyAct; - for (nActs=i=0;i<rep->nKeyActs;i++) { - if (xkb->server->key_acts[i+firstKey]!=0) - nActs+= XkbKeyNumActions(xkb,i+firstKey); - } - len= XkbPaddedSize(rep->nKeyActs)+(nActs*SIZEOF(xkbActionWireDesc)); - rep->totalActs= nActs; - return len; -} - -static char * -XkbWriteKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, - ClientPtr client) -{ - unsigned i; - CARD8 * numDesc; - XkbAnyAction * actDesc; - - numDesc = (CARD8 *)buf; - for (i=0;i<rep->nKeyActs;i++) { - if (xkb->server->key_acts[i+rep->firstKeyAct]==0) - numDesc[i] = 0; - else numDesc[i] = XkbKeyNumActions(xkb,(i+rep->firstKeyAct)); - } - buf+= XkbPaddedSize(rep->nKeyActs); - - actDesc = (XkbAnyAction *)buf; - for (i=0;i<rep->nKeyActs;i++) { - if (xkb->server->key_acts[i+rep->firstKeyAct]!=0) { - unsigned int num; - num = XkbKeyNumActions(xkb,(i+rep->firstKeyAct)); - memcpy((char *)actDesc, - (char*)XkbKeyActionsPtr(xkb,(i+rep->firstKeyAct)), - num*SIZEOF(xkbActionWireDesc)); - actDesc+= num; - } - } - buf = (char *)actDesc; - return buf; -} - -static int -XkbSizeKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep) -{ - unsigned i,len,nBhvr; - XkbBehavior * bhv; - - if (((rep->present&XkbKeyBehaviorsMask)==0)||(rep->nKeyBehaviors<1)|| - (!xkb)||(!xkb->server)||(!xkb->server->behaviors)) { - rep->present&= ~XkbKeyBehaviorsMask; - rep->firstKeyBehavior= rep->nKeyBehaviors= 0; - rep->totalKeyBehaviors= 0; - return 0; - } - bhv= &xkb->server->behaviors[rep->firstKeyBehavior]; - for (nBhvr=i=0;i<rep->nKeyBehaviors;i++,bhv++) { - if (bhv->type!=XkbKB_Default) - nBhvr++; - } - len= nBhvr*SIZEOF(xkbBehaviorWireDesc); - rep->totalKeyBehaviors= nBhvr; - return len; -} - -static char * -XkbWriteKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, - ClientPtr client) -{ - unsigned i; - xkbBehaviorWireDesc *wire; - XkbBehavior *pBhvr; - - wire = (xkbBehaviorWireDesc *)buf; - pBhvr= &xkb->server->behaviors[rep->firstKeyBehavior]; - for (i=0;i<rep->nKeyBehaviors;i++,pBhvr++) { - if (pBhvr->type!=XkbKB_Default) { - wire->key= i+rep->firstKeyBehavior; - wire->type= pBhvr->type; - wire->data= pBhvr->data; - wire++; - } - } - buf = (char *)wire; - return buf; -} - -static int -XkbSizeExplicit(XkbDescPtr xkb,xkbGetMapReply *rep) -{ - unsigned i,len,nRtrn; - - if (((rep->present&XkbExplicitComponentsMask)==0)||(rep->nKeyExplicit<1)|| - (!xkb)||(!xkb->server)||(!xkb->server->explicit)) { - rep->present&= ~XkbExplicitComponentsMask; - rep->firstKeyExplicit= rep->nKeyExplicit= 0; - rep->totalKeyExplicit= 0; - return 0; - } - for (nRtrn=i=0;i<rep->nKeyExplicit;i++) { - if (xkb->server->explicit[i+rep->firstKeyExplicit]!=0) - nRtrn++; - } - rep->totalKeyExplicit= nRtrn; - len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero explicit component */ - return len; -} - -static char * -XkbWriteExplicit(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client) -{ -unsigned i; -char * start; -unsigned char * pExp; - - start= buf; - pExp= &xkb->server->explicit[rep->firstKeyExplicit]; - for (i=0;i<rep->nKeyExplicit;i++,pExp++) { - if (*pExp!=0) { - *buf++= i+rep->firstKeyExplicit; - *buf++= *pExp; - } - } - i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */ - return buf+i; -} - -static int -XkbSizeModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep) -{ - unsigned i,len,nRtrn; - - if (((rep->present&XkbModifierMapMask)==0)||(rep->nModMapKeys<1)|| - (!xkb)||(!xkb->map)||(!xkb->map->modmap)) { - rep->present&= ~XkbModifierMapMask; - rep->firstModMapKey= rep->nModMapKeys= 0; - rep->totalModMapKeys= 0; - return 0; - } - for (nRtrn=i=0;i<rep->nModMapKeys;i++) { - if (xkb->map->modmap[i+rep->firstModMapKey]!=0) - nRtrn++; - } - rep->totalModMapKeys= nRtrn; - len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero modmap component */ - return len; -} - -static char * -XkbWriteModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, - ClientPtr client) -{ -unsigned i; -char * start; -unsigned char * pMap; - - start= buf; - pMap= &xkb->map->modmap[rep->firstModMapKey]; - for (i=0;i<rep->nModMapKeys;i++,pMap++) { - if (*pMap!=0) { - *buf++= i+rep->firstModMapKey; - *buf++= *pMap; - } - } - i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */ - return buf+i; -} - -static int -XkbSizeVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep) -{ - unsigned i,len,nRtrn; - - if (((rep->present&XkbVirtualModMapMask)==0)||(rep->nVModMapKeys<1)|| - (!xkb)||(!xkb->server)||(!xkb->server->vmodmap)) { - rep->present&= ~XkbVirtualModMapMask; - rep->firstVModMapKey= rep->nVModMapKeys= 0; - rep->totalVModMapKeys= 0; - return 0; - } - for (nRtrn=i=0;i<rep->nVModMapKeys;i++) { - if (xkb->server->vmodmap[i+rep->firstVModMapKey]!=0) - nRtrn++; - } - rep->totalVModMapKeys= nRtrn; - len= nRtrn*SIZEOF(xkbVModMapWireDesc); - return len; -} - -static char * -XkbWriteVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf, - ClientPtr client) -{ -unsigned i; -xkbVModMapWireDesc * wire; -unsigned short * pMap; - - wire= (xkbVModMapWireDesc *)buf; - pMap= &xkb->server->vmodmap[rep->firstVModMapKey]; - for (i=0;i<rep->nVModMapKeys;i++,pMap++) { - if (*pMap!=0) { - wire->key= i+rep->firstVModMapKey; - wire->vmods= *pMap; - wire++; - } - } - return (char *)wire; -} - -static Status -XkbComputeGetMapReplySize(XkbDescPtr xkb,xkbGetMapReply *rep) -{ -int len; - - rep->minKeyCode= xkb->min_key_code; - rep->maxKeyCode= xkb->max_key_code; - len= XkbSizeKeyTypes(xkb,rep); - len+= XkbSizeKeySyms(xkb,rep); - len+= XkbSizeKeyActions(xkb,rep); - len+= XkbSizeKeyBehaviors(xkb,rep); - len+= XkbSizeVirtualMods(xkb,rep); - len+= XkbSizeExplicit(xkb,rep); - len+= XkbSizeModifierMap(xkb,rep); - len+= XkbSizeVirtualModMap(xkb,rep); - rep->length+= (len/4); - return Success; -} - -static int -XkbSendMap(ClientPtr client,XkbDescPtr xkb,xkbGetMapReply *rep) -{ -unsigned i,len; -char *desc,*start; - - len= (rep->length*4)-(SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply)); - start= desc= xcalloc(1, len); - if (!start) - return BadAlloc; - if ( rep->nTypes>0 ) - desc = XkbWriteKeyTypes(xkb,rep,desc,client); - if ( rep->nKeySyms>0 ) - desc = XkbWriteKeySyms(xkb,rep,desc,client); - if ( rep->nKeyActs>0 ) - desc = XkbWriteKeyActions(xkb,rep,desc,client); - if ( rep->totalKeyBehaviors>0 ) - desc = XkbWriteKeyBehaviors(xkb,rep,desc,client); - if ( rep->virtualMods ) { - register int sz,bit; - for (i=sz=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { - if (rep->virtualMods&bit) { - desc[sz++]= xkb->server->vmods[i]; - } - } - desc+= XkbPaddedSize(sz); - } - if ( rep->totalKeyExplicit>0 ) - desc= XkbWriteExplicit(xkb,rep,desc,client); - if ( rep->totalModMapKeys>0 ) - desc= XkbWriteModifierMap(xkb,rep,desc,client); - if ( rep->totalVModMapKeys>0 ) - desc= XkbWriteVirtualModMap(xkb,rep,desc,client); - if ((desc-start)!=(len)) { - ErrorF("[xkb] BOGUS LENGTH in write keyboard desc, expected %d, got %ld\n", - len, (unsigned long)(desc-start)); - } - if (client->swapped) { - register int n; - swaps(&rep->sequenceNumber,n); - swapl(&rep->length,n); - swaps(&rep->present,n); - swaps(&rep->totalSyms,n); - swaps(&rep->totalActs,n); - } - WriteToClient(client, (i=SIZEOF(xkbGetMapReply)), (char *)rep); - WriteToClient(client, len, start); - xfree((char *)start); - return client->noClientException; -} - -int -ProcXkbGetMap(ClientPtr client) -{ - DeviceIntPtr dev; - xkbGetMapReply rep; - XkbDescRec *xkb; - int n,status; - - REQUEST(xkbGetMapReq); - REQUEST_SIZE_MATCH(xkbGetMapReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); - CHK_MASK_OVERLAP(0x01,stuff->full,stuff->partial); - CHK_MASK_LEGAL(0x02,stuff->full,XkbAllMapComponentsMask); - CHK_MASK_LEGAL(0x03,stuff->partial,XkbAllMapComponentsMask); - - xkb= dev->key->xkbInfo->desc; - bzero(&rep,sizeof(xkbGetMapReply)); - rep.type= X_Reply; - rep.sequenceNumber= client->sequence; - rep.length = (SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2; - rep.deviceID = dev->id; - rep.present = stuff->partial|stuff->full; - rep.minKeyCode = xkb->min_key_code; - rep.maxKeyCode = xkb->max_key_code; - if ( stuff->full&XkbKeyTypesMask ) { - rep.firstType = 0; - rep.nTypes = xkb->map->num_types; - } - else if (stuff->partial&XkbKeyTypesMask) { - if (((unsigned)stuff->firstType+stuff->nTypes)>xkb->map->num_types) { - client->errorValue = _XkbErrCode4(0x04,xkb->map->num_types, - stuff->firstType,stuff->nTypes); - return BadValue; - } - rep.firstType = stuff->firstType; - rep.nTypes = stuff->nTypes; - } - else rep.nTypes = 0; - rep.totalTypes = xkb->map->num_types; - - n= XkbNumKeys(xkb); - if ( stuff->full&XkbKeySymsMask ) { - rep.firstKeySym = xkb->min_key_code; - rep.nKeySyms = n; - } - else if (stuff->partial&XkbKeySymsMask) { - CHK_KEY_RANGE(0x05,stuff->firstKeySym,stuff->nKeySyms,xkb); - rep.firstKeySym = stuff->firstKeySym; - rep.nKeySyms = stuff->nKeySyms; - } - else rep.nKeySyms = 0; - rep.totalSyms= 0; - - if ( stuff->full&XkbKeyActionsMask ) { - rep.firstKeyAct= xkb->min_key_code; - rep.nKeyActs= n; - } - else if (stuff->partial&XkbKeyActionsMask) { - CHK_KEY_RANGE(0x07,stuff->firstKeyAct,stuff->nKeyActs,xkb); - rep.firstKeyAct= stuff->firstKeyAct; - rep.nKeyActs= stuff->nKeyActs; - } - else rep.nKeyActs= 0; - rep.totalActs= 0; - - if ( stuff->full&XkbKeyBehaviorsMask ) { - rep.firstKeyBehavior = xkb->min_key_code; - rep.nKeyBehaviors = n; - } - else if (stuff->partial&XkbKeyBehaviorsMask) { - CHK_KEY_RANGE(0x09,stuff->firstKeyBehavior,stuff->nKeyBehaviors,xkb); - rep.firstKeyBehavior= stuff->firstKeyBehavior; - rep.nKeyBehaviors= stuff->nKeyBehaviors; - } - else rep.nKeyBehaviors = 0; - rep.totalKeyBehaviors= 0; - - if (stuff->full&XkbVirtualModsMask) - rep.virtualMods= ~0; - else if (stuff->partial&XkbVirtualModsMask) - rep.virtualMods= stuff->virtualMods; - - if (stuff->full&XkbExplicitComponentsMask) { - rep.firstKeyExplicit= xkb->min_key_code; - rep.nKeyExplicit= n; - } - else if (stuff->partial&XkbExplicitComponentsMask) { - CHK_KEY_RANGE(0x0B,stuff->firstKeyExplicit,stuff->nKeyExplicit,xkb); - rep.firstKeyExplicit= stuff->firstKeyExplicit; - rep.nKeyExplicit= stuff->nKeyExplicit; - } - else rep.nKeyExplicit = 0; - rep.totalKeyExplicit= 0; - - if (stuff->full&XkbModifierMapMask) { - rep.firstModMapKey= xkb->min_key_code; - rep.nModMapKeys= n; - } - else if (stuff->partial&XkbModifierMapMask) { - CHK_KEY_RANGE(0x0D,stuff->firstModMapKey,stuff->nModMapKeys,xkb); - rep.firstModMapKey= stuff->firstModMapKey; - rep.nModMapKeys= stuff->nModMapKeys; - } - else rep.nModMapKeys = 0; - rep.totalModMapKeys= 0; - - if (stuff->full&XkbVirtualModMapMask) { - rep.firstVModMapKey= xkb->min_key_code; - rep.nVModMapKeys= n; - } - else if (stuff->partial&XkbVirtualModMapMask) { - CHK_KEY_RANGE(0x0F,stuff->firstVModMapKey,stuff->nVModMapKeys,xkb); - rep.firstVModMapKey= stuff->firstVModMapKey; - rep.nVModMapKeys= stuff->nVModMapKeys; - } - else rep.nVModMapKeys = 0; - rep.totalVModMapKeys= 0; - - if ((status=XkbComputeGetMapReplySize(xkb,&rep))!=Success) - return status; - return XkbSendMap(client,xkb,&rep); -} - -/***====================================================================***/ - -static int -CheckKeyTypes( ClientPtr client, - XkbDescPtr xkb, - xkbSetMapReq * req, - xkbKeyTypeWireDesc **wireRtrn, - int * nMapsRtrn, - CARD8 * mapWidthRtrn) -{ -unsigned nMaps; -register unsigned i,n; -register CARD8 * map; -register xkbKeyTypeWireDesc *wire = *wireRtrn; - - if (req->firstType>((unsigned)xkb->map->num_types)) { - *nMapsRtrn = _XkbErrCode3(0x01,req->firstType,xkb->map->num_types); - return 0; - } - if (req->flags&XkbSetMapResizeTypes) { - nMaps = req->firstType+req->nTypes; - if (nMaps<XkbNumRequiredTypes) { /* canonical types must be there */ - *nMapsRtrn= _XkbErrCode4(0x02,req->firstType,req->nTypes,4); - return 0; - } - } - else if (req->present&XkbKeyTypesMask) { - nMaps = xkb->map->num_types; - if ((req->firstType+req->nTypes)>nMaps) { - *nMapsRtrn = req->firstType+req->nTypes; - return 0; - } - } - else { - *nMapsRtrn = xkb->map->num_types; - for (i=0;i<xkb->map->num_types;i++) { - mapWidthRtrn[i] = xkb->map->types[i].num_levels; - } - return 1; - } - - for (i=0;i<req->firstType;i++) { - mapWidthRtrn[i] = xkb->map->types[i].num_levels; - } - for (i=0;i<req->nTypes;i++) { - unsigned width; - if (client->swapped) { - register int s; - swaps(&wire->virtualMods,s); - } - n= i+req->firstType; - width= wire->numLevels; - if (width<1) { - *nMapsRtrn= _XkbErrCode3(0x04,n,width); - return 0; - } - else if ((n==XkbOneLevelIndex)&&(width!=1)) { /* must be width 1 */ - *nMapsRtrn= _XkbErrCode3(0x05,n,width); - return 0; - } - else if ((width!=2)&& - ((n==XkbTwoLevelIndex)||(n==XkbKeypadIndex)|| - (n==XkbAlphabeticIndex))) { - /* TWO_LEVEL, ALPHABETIC and KEYPAD must be width 2 */ - *nMapsRtrn= _XkbErrCode3(0x05,n,width); - return 0; - } - if (wire->nMapEntries>0) { - xkbKTSetMapEntryWireDesc * mapWire; - xkbModsWireDesc * preWire; - mapWire= (xkbKTSetMapEntryWireDesc *)&wire[1]; - preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries]; - for (n=0;n<wire->nMapEntries;n++) { - if (client->swapped) { - register int s; - swaps(&mapWire[n].virtualMods,s); - } - if (mapWire[n].realMods&(~wire->realMods)) { - *nMapsRtrn= _XkbErrCode4(0x06,n,mapWire[n].realMods, - wire->realMods); - return 0; - } - if (mapWire[n].virtualMods&(~wire->virtualMods)) { - *nMapsRtrn= _XkbErrCode3(0x07,n,mapWire[n].virtualMods); - return 0; - } - if (mapWire[n].level>=wire->numLevels) { - *nMapsRtrn= _XkbErrCode4(0x08,n,wire->numLevels, - mapWire[n].level); - return 0; - } - if (wire->preserve) { - if (client->swapped) { - register int s; - swaps(&preWire[n].virtualMods,s); - } - if (preWire[n].realMods&(~mapWire[n].realMods)) { - *nMapsRtrn= _XkbErrCode4(0x09,n,preWire[n].realMods, - mapWire[n].realMods); - return 0; - } - if (preWire[n].virtualMods&(~mapWire[n].virtualMods)) { - *nMapsRtrn=_XkbErrCode3(0x0a,n,preWire[n].virtualMods); - return 0; - } - } - } - if (wire->preserve) - map= (CARD8 *)&preWire[wire->nMapEntries]; - else map= (CARD8 *)&mapWire[wire->nMapEntries]; - } - else map= (CARD8 *)&wire[1]; - mapWidthRtrn[i+req->firstType] = wire->numLevels; - wire= (xkbKeyTypeWireDesc *)map; - } - for (i=req->firstType+req->nTypes;i<nMaps;i++) { - mapWidthRtrn[i] = xkb->map->types[i].num_levels; - } - *nMapsRtrn = nMaps; - *wireRtrn = wire; - return 1; -} - -static int -CheckKeySyms( ClientPtr client, - XkbDescPtr xkb, - xkbSetMapReq * req, - int nTypes, - CARD8 * mapWidths, - CARD16 * symsPerKey, - xkbSymMapWireDesc ** wireRtrn, - int * errorRtrn) -{ -register unsigned i; -XkbSymMapPtr map; -xkbSymMapWireDesc* wire = *wireRtrn; - - if (!(XkbKeySymsMask&req->present)) - return 1; - CHK_REQ_KEY_RANGE2(0x11,req->firstKeySym,req->nKeySyms,req,(*errorRtrn),0); - map = &xkb->map->key_sym_map[xkb->min_key_code]; - for (i=xkb->min_key_code;i<(unsigned)req->firstKeySym;i++,map++) { - register int g,ng,w; - ng= XkbNumGroups(map->group_info); - for (w=g=0;g<ng;g++) { - if (map->kt_index[g]>=(unsigned)nTypes) { - *errorRtrn = _XkbErrCode4(0x13,i,g,map->kt_index[g]); - return 0; - } - if (mapWidths[map->kt_index[g]]>w) - w= mapWidths[map->kt_index[g]]; - } - symsPerKey[i] = w*ng; - } - for (i=0;i<req->nKeySyms;i++) { - KeySym *pSyms; - register unsigned nG; - if (client->swapped) { - swaps(&wire->nSyms,nG); - } - nG = XkbNumGroups(wire->groupInfo); - if (nG>XkbNumKbdGroups) { - *errorRtrn = _XkbErrCode3(0x14,i+req->firstKeySym,nG); - return 0; - } - if (nG>0) { - register int g,w; - for (g=w=0;g<nG;g++) { - if (wire->ktIndex[g]>=(unsigned)nTypes) { - *errorRtrn= _XkbErrCode4(0x15,i+req->firstKeySym,g, - wire->ktIndex[g]); - return 0; - } - if (mapWidths[wire->ktIndex[g]]>w) - w= mapWidths[wire->ktIndex[g]]; - } - if (wire->width!=w) { - *errorRtrn= _XkbErrCode3(0x16,i+req->firstKeySym,wire->width); - return 0; - } - w*= nG; - symsPerKey[i+req->firstKeySym] = w; - if (w!=wire->nSyms) { - *errorRtrn=_XkbErrCode4(0x16,i+req->firstKeySym,wire->nSyms,w); - return 0; - } - } - else if (wire->nSyms!=0) { - *errorRtrn = _XkbErrCode3(0x17,i+req->firstKeySym,wire->nSyms); - return 0; - } - pSyms = (KeySym *)&wire[1]; - wire = (xkbSymMapWireDesc *)&pSyms[wire->nSyms]; - } - - map = &xkb->map->key_sym_map[i]; - for (;i<=(unsigned)xkb->max_key_code;i++,map++) { - register int g,nG,w; - nG= XkbKeyNumGroups(xkb,i); - for (w=g=0;g<nG;g++) { - if (map->kt_index[g]>=(unsigned)nTypes) { - *errorRtrn = _XkbErrCode4(0x18,i,g,map->kt_index[g]); - return 0; - } - if (mapWidths[map->kt_index[g]]>w) - w= mapWidths[map->kt_index[g]]; - } - symsPerKey[i] = w*nG; - } - *wireRtrn = wire; - return 1; -} - -static int -CheckKeyActions( XkbDescPtr xkb, - xkbSetMapReq * req, - int nTypes, - CARD8 * mapWidths, - CARD16 * symsPerKey, - CARD8 ** wireRtrn, - int * nActsRtrn) -{ -int nActs; -CARD8 * wire = *wireRtrn; -register unsigned i; - - if (!(XkbKeyActionsMask&req->present)) - return 1; - CHK_REQ_KEY_RANGE2(0x21,req->firstKeyAct,req->nKeyActs,req,(*nActsRtrn),0); - for (nActs=i=0;i<req->nKeyActs;i++) { - if (wire[0]!=0) { - if (wire[0]==symsPerKey[i+req->firstKeyAct]) - nActs+= wire[0]; - else { - *nActsRtrn= _XkbErrCode3(0x23,i+req->firstKeyAct,wire[0]); - return 0; - } - } - wire++; - } - if (req->nKeyActs%4) - wire+= 4-(req->nKeyActs%4); - *wireRtrn = (CARD8 *)(((XkbAnyAction *)wire)+nActs); - *nActsRtrn = nActs; - return 1; -} - -static int -CheckKeyBehaviors( XkbDescPtr xkb, - xkbSetMapReq * req, - xkbBehaviorWireDesc ** wireRtrn, - int * errorRtrn) -{ -register xkbBehaviorWireDesc * wire = *wireRtrn; -register XkbServerMapPtr server = xkb->server; -register unsigned i; -unsigned first,last; - - if (((req->present&XkbKeyBehaviorsMask)==0)||(req->nKeyBehaviors<1)) { - req->present&= ~XkbKeyBehaviorsMask; - req->nKeyBehaviors= 0; - return 1; - } - first= req->firstKeyBehavior; - last= req->firstKeyBehavior+req->nKeyBehaviors-1; - if (first<req->minKeyCode) { - *errorRtrn = _XkbErrCode3(0x31,first,req->minKeyCode); - return 0; - } - if (last>req->maxKeyCode) { - *errorRtrn = _XkbErrCode3(0x32,last,req->maxKeyCode); - return 0; - } - - for (i=0;i<req->totalKeyBehaviors;i++,wire++) { - if ((wire->key<first)||(wire->key>last)) { - *errorRtrn = _XkbErrCode4(0x33,first,last,wire->key); - return 0; - } - if ((wire->type&XkbKB_Permanent)&& - ((server->behaviors[wire->key].type!=wire->type)|| - (server->behaviors[wire->key].data!=wire->data))) { - *errorRtrn = _XkbErrCode3(0x33,wire->key,wire->type); - return 0; - } - if ((wire->type==XkbKB_RadioGroup)&& - ((wire->data&(~XkbKB_RGAllowNone))>XkbMaxRadioGroups)) { - *errorRtrn= _XkbErrCode4(0x34,wire->key,wire->data, - XkbMaxRadioGroups); - return 0; - } - if ((wire->type==XkbKB_Overlay1)||(wire->type==XkbKB_Overlay2)) { - CHK_KEY_RANGE2(0x35,wire->key,1,xkb,*errorRtrn,0); - } - } - *wireRtrn = wire; - return 1; -} - -static int -CheckVirtualMods( XkbDescRec * xkb, - xkbSetMapReq * req, - CARD8 ** wireRtrn, - int * errorRtrn) -{ -register CARD8 *wire = *wireRtrn; -register unsigned i,nMods,bit; - - if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0)) - return 1; - for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { - if (req->virtualMods&bit) - nMods++; - } - *wireRtrn= (wire+XkbPaddedSize(nMods)); - return 1; -} - -static int -CheckKeyExplicit( XkbDescPtr xkb, - xkbSetMapReq * req, - CARD8 ** wireRtrn, - int * errorRtrn) -{ -register CARD8 * wire = *wireRtrn; -CARD8 * start; -register unsigned i; -int first,last; - - if (((req->present&XkbExplicitComponentsMask)==0)||(req->nKeyExplicit<1)) { - req->present&= ~XkbExplicitComponentsMask; - req->nKeyExplicit= 0; - return 1; - } - first= req->firstKeyExplicit; - last= first+req->nKeyExplicit-1; - if (first<req->minKeyCode) { - *errorRtrn = _XkbErrCode3(0x51,first,req->minKeyCode); - return 0; - } - if (last>req->maxKeyCode) { - *errorRtrn = _XkbErrCode3(0x52,last,req->maxKeyCode); - return 0; - } - start= wire; - for (i=0;i<req->totalKeyExplicit;i++,wire+=2) { - if ((wire[0]<first)||(wire[0]>last)) { - *errorRtrn = _XkbErrCode4(0x53,first,last,wire[0]); - return 0; - } - if (wire[1]&(~XkbAllExplicitMask)) { - *errorRtrn= _XkbErrCode3(0x52,~XkbAllExplicitMask,wire[1]); - return 0; - } - } - wire+= XkbPaddedSize(wire-start)-(wire-start); - *wireRtrn= wire; - return 1; -} - -static int -CheckModifierMap(XkbDescPtr xkb,xkbSetMapReq *req,CARD8 **wireRtrn,int *errRtrn) -{ -register CARD8 * wire = *wireRtrn; -CARD8 * start; -register unsigned i; -int first,last; - - if (((req->present&XkbModifierMapMask)==0)||(req->nModMapKeys<1)) { - req->present&= ~XkbModifierMapMask; - req->nModMapKeys= 0; - return 1; - } - first= req->firstModMapKey; - last= first+req->nModMapKeys-1; - if (first<req->minKeyCode) { - *errRtrn = _XkbErrCode3(0x61,first,req->minKeyCode); - return 0; - } - if (last>req->maxKeyCode) { - *errRtrn = _XkbErrCode3(0x62,last,req->maxKeyCode); - return 0; - } - start= wire; - for (i=0;i<req->totalModMapKeys;i++,wire+=2) { - if ((wire[0]<first)||(wire[0]>last)) { - *errRtrn = _XkbErrCode4(0x63,first,last,wire[0]); - return 0; - } - } - wire+= XkbPaddedSize(wire-start)-(wire-start); - *wireRtrn= wire; - return 1; -} - -static int -CheckVirtualModMap( XkbDescPtr xkb, - xkbSetMapReq *req, - xkbVModMapWireDesc **wireRtrn, - int *errRtrn) -{ -register xkbVModMapWireDesc * wire = *wireRtrn; -register unsigned i; -int first,last; - - if (((req->present&XkbVirtualModMapMask)==0)||(req->nVModMapKeys<1)) { - req->present&= ~XkbVirtualModMapMask; - req->nVModMapKeys= 0; - return 1; - } - first= req->firstVModMapKey; - last= first+req->nVModMapKeys-1; - if (first<req->minKeyCode) { - *errRtrn = _XkbErrCode3(0x71,first,req->minKeyCode); - return 0; - } - if (last>req->maxKeyCode) { - *errRtrn = _XkbErrCode3(0x72,last,req->maxKeyCode); - return 0; - } - for (i=0;i<req->totalVModMapKeys;i++,wire++) { - if ((wire->key<first)||(wire->key>last)) { - *errRtrn = _XkbErrCode4(0x73,first,last,wire->key); - return 0; - } - } - *wireRtrn= wire; - return 1; -} - -static char * -SetKeyTypes( XkbDescPtr xkb, - xkbSetMapReq * req, - xkbKeyTypeWireDesc * wire, - XkbChangesPtr changes) -{ -register unsigned i; -unsigned first,last; -CARD8 *map; - - if ((unsigned)(req->firstType+req->nTypes)>xkb->map->size_types) { - i= req->firstType+req->nTypes; - if (XkbAllocClientMap(xkb,XkbKeyTypesMask,i)!=Success) { - return NULL; - } - } - if ((unsigned)(req->firstType+req->nTypes)>xkb->map->num_types) - xkb->map->num_types= req->firstType+req->nTypes; - - for (i=0;i<req->nTypes;i++) { - XkbKeyTypePtr pOld; - register unsigned n; - - if (XkbResizeKeyType(xkb,i+req->firstType,wire->nMapEntries, - wire->preserve,wire->numLevels)!=Success) { - return NULL; - } - pOld = &xkb->map->types[i+req->firstType]; - map = (CARD8 *)&wire[1]; - - pOld->mods.real_mods = wire->realMods; - pOld->mods.vmods= wire->virtualMods; - pOld->num_levels = wire->numLevels; - pOld->map_count= wire->nMapEntries; - - pOld->mods.mask= pOld->mods.real_mods| - XkbMaskForVMask(xkb,pOld->mods.vmods); - - if (wire->nMapEntries) { - xkbKTSetMapEntryWireDesc *mapWire; - xkbModsWireDesc *preWire; - unsigned tmp; - mapWire= (xkbKTSetMapEntryWireDesc *)map; - preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries]; - for (n=0;n<wire->nMapEntries;n++) { - pOld->map[n].active= 1; - pOld->map[n].mods.mask= mapWire[n].realMods; - pOld->map[n].mods.real_mods= mapWire[n].realMods; - pOld->map[n].mods.vmods= mapWire[n].virtualMods; - pOld->map[n].level= mapWire[n].level; - if (mapWire[n].virtualMods!=0) { - tmp= XkbMaskForVMask(xkb,mapWire[n].virtualMods); - pOld->map[n].active= (tmp!=0); - pOld->map[n].mods.mask|= tmp; - } - if (wire->preserve) { - pOld->preserve[n].real_mods= preWire[n].realMods; - pOld->preserve[n].vmods= preWire[n].virtualMods; - tmp= XkbMaskForVMask(xkb,preWire[n].virtualMods); - pOld->preserve[n].mask= preWire[n].realMods|tmp; - } - } - if (wire->preserve) - map= (CARD8 *)&preWire[wire->nMapEntries]; - else map= (CARD8 *)&mapWire[wire->nMapEntries]; - } - else map= (CARD8 *)&wire[1]; - wire = (xkbKeyTypeWireDesc *)map; - } - first= req->firstType; - last= first+req->nTypes-1; /* last changed type */ - if (changes->map.changed&XkbKeyTypesMask) { - int oldLast; - oldLast= changes->map.first_type+changes->map.num_types-1; - if (changes->map.first_type<first) - first= changes->map.first_type; - if (oldLast>last) - last= oldLast; - } - changes->map.changed|= XkbKeyTypesMask; - changes->map.first_type = first; - changes->map.num_types = (last-first)+1; - return (char *)wire; -} - -static char * -SetKeySyms( ClientPtr client, - XkbDescPtr xkb, - xkbSetMapReq * req, - xkbSymMapWireDesc * wire, - XkbChangesPtr changes, - DeviceIntPtr dev) -{ -register unsigned i,s; -XkbSymMapPtr oldMap; -KeySym * newSyms; -KeySym * pSyms; -unsigned first,last; - - oldMap = &xkb->map->key_sym_map[req->firstKeySym]; - for (i=0;i<req->nKeySyms;i++,oldMap++) { - pSyms = (KeySym *)&wire[1]; - if (wire->nSyms>0) { - newSyms = XkbResizeKeySyms(xkb,i+req->firstKeySym,wire->nSyms); - for (s=0;s<wire->nSyms;s++) { - newSyms[s]= pSyms[s]; - } - if (client->swapped) { - int n; - for (s=0;s<wire->nSyms;s++) { - swapl(&newSyms[s],n); - } - } - } - oldMap->kt_index[0] = wire->ktIndex[0]; - oldMap->kt_index[1] = wire->ktIndex[1]; - oldMap->kt_index[2] = wire->ktIndex[2]; - oldMap->kt_index[3] = wire->ktIndex[3]; - oldMap->group_info = wire->groupInfo; - oldMap->width = wire->width; - wire= (xkbSymMapWireDesc *)&pSyms[wire->nSyms]; - } - first= req->firstKeySym; - last= first+req->nKeySyms-1; - if (changes->map.changed&XkbKeySymsMask) { - int oldLast= (changes->map.first_key_sym+changes->map.num_key_syms-1); - if (changes->map.first_key_sym<first) - first= changes->map.first_key_sym; - if (oldLast>last) - last= oldLast; - } - changes->map.changed|= XkbKeySymsMask; - changes->map.first_key_sym = first; - changes->map.num_key_syms = (last-first+1); - - s= 0; - for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) { - if (XkbKeyNumGroups(xkb,i)>s) - s= XkbKeyNumGroups(xkb,i); - } - if (s!=xkb->ctrls->num_groups) { - xkbControlsNotify cn; - XkbControlsRec old; - cn.keycode= 0; - cn.eventType= 0; - cn.requestMajor= XkbReqCode; - cn.requestMinor= X_kbSetMap; - old= *xkb->ctrls; - xkb->ctrls->num_groups= s; - if (XkbComputeControlsNotify(dev,&old,xkb->ctrls,&cn,FALSE)) - XkbSendControlsNotify(dev,&cn); - } - return (char *)wire; -} - -static char * -SetKeyActions( XkbDescPtr xkb, - xkbSetMapReq * req, - CARD8 * wire, - XkbChangesPtr changes) -{ -register unsigned i,first,last; -CARD8 * nActs = wire; -XkbAction * newActs; - - wire+= XkbPaddedSize(req->nKeyActs); - for (i=0;i<req->nKeyActs;i++) { - if (nActs[i]==0) - xkb->server->key_acts[i+req->firstKeyAct]= 0; - else { - newActs= XkbResizeKeyActions(xkb,i+req->firstKeyAct,nActs[i]); - memcpy((char *)newActs,(char *)wire, - nActs[i]*SIZEOF(xkbActionWireDesc)); - wire+= nActs[i]*SIZEOF(xkbActionWireDesc); - } - } - first= req->firstKeyAct; - last= (first+req->nKeyActs-1); - if (changes->map.changed&XkbKeyActionsMask) { - int oldLast; - oldLast= changes->map.first_key_act+changes->map.num_key_acts-1; - if (changes->map.first_key_act<first) - first= changes->map.first_key_act; - if (oldLast>last) - last= oldLast; - } - changes->map.changed|= XkbKeyActionsMask; - changes->map.first_key_act= first; - changes->map.num_key_acts= (last-first+1); - return (char *)wire; -} - -static char * -SetKeyBehaviors( XkbSrvInfoPtr xkbi, - xkbSetMapReq *req, - xkbBehaviorWireDesc *wire, - XkbChangesPtr changes) -{ -register unsigned i; -int maxRG = -1; -XkbDescPtr xkb = xkbi->desc; -XkbServerMapPtr server = xkb->server; -unsigned first,last; - - first= req->firstKeyBehavior; - last= req->firstKeyBehavior+req->nKeyBehaviors-1; - bzero(&server->behaviors[first],req->nKeyBehaviors*sizeof(XkbBehavior)); - for (i=0;i<req->totalKeyBehaviors;i++) { - if ((server->behaviors[wire->key].type&XkbKB_Permanent)==0) { - server->behaviors[wire->key].type= wire->type; - server->behaviors[wire->key].data= wire->data; - if ((wire->type==XkbKB_RadioGroup)&&(((int)wire->data)>maxRG)) - maxRG= wire->data + 1; - } - wire++; - } - - if (maxRG>(int)xkbi->nRadioGroups) { - int sz = maxRG*sizeof(XkbRadioGroupRec); - if (xkbi->radioGroups) - xkbi->radioGroups= xrealloc(xkbi->radioGroups,sz); - else xkbi->radioGroups= xcalloc(1, sz); - if (xkbi->radioGroups) { - if (xkbi->nRadioGroups) - bzero(&xkbi->radioGroups[xkbi->nRadioGroups], - (maxRG-xkbi->nRadioGroups)*sizeof(XkbRadioGroupRec)); - xkbi->nRadioGroups= maxRG; - } - else xkbi->nRadioGroups= 0; - /* should compute members here */ - } - if (changes->map.changed&XkbKeyBehaviorsMask) { - unsigned oldLast; - oldLast= changes->map.first_key_behavior+ - changes->map.num_key_behaviors-1; - if (changes->map.first_key_behavior<req->firstKeyBehavior) - first= changes->map.first_key_behavior; - if (oldLast>last) - last= oldLast; - } - changes->map.changed|= XkbKeyBehaviorsMask; - changes->map.first_key_behavior = first; - changes->map.num_key_behaviors = (last-first+1); - return (char *)wire; -} - -static char * -SetVirtualMods(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire, - XkbChangesPtr changes) -{ -register int i,bit,nMods; -XkbServerMapPtr srv = xkbi->desc->server; - - if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0)) - return (char *)wire; - for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) { - if (req->virtualMods&bit) { - if (srv->vmods[i]!=wire[nMods]) { - changes->map.changed|= XkbVirtualModsMask; - changes->map.vmods|= bit; - srv->vmods[i]= wire[nMods]; - } - nMods++; - } - } - return (char *)(wire+XkbPaddedSize(nMods)); -} - -static char * -SetKeyExplicit(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire, - XkbChangesPtr changes) -{ -register unsigned i,first,last; -XkbServerMapPtr xkb = xkbi->desc->server; -CARD8 * start; - - start= wire; - first= req->firstKeyExplicit; - last= req->firstKeyExplicit+req->nKeyExplicit-1; - bzero(&xkb->explicit[first],req->nKeyExplicit); - for (i=0;i<req->totalKeyExplicit;i++,wire+= 2) { - xkb->explicit[wire[0]]= wire[1]; - } - if (first>0) { - if (changes->map.changed&XkbExplicitComponentsMask) { - int oldLast; - oldLast= changes->map.first_key_explicit+ - changes->map.num_key_explicit-1; - if (changes->map.first_key_explicit<first) - first= changes->map.first_key_explicit; - if (oldLast>last) - last= oldLast; - } - changes->map.first_key_explicit= first; - changes->map.num_key_explicit= (last-first)+1; - } - wire+= XkbPaddedSize(wire-start)-(wire-start); - return (char *)wire; -} - -static char * -SetModifierMap( XkbSrvInfoPtr xkbi, - xkbSetMapReq * req, - CARD8 * wire, - XkbChangesPtr changes) -{ -register unsigned i,first,last; -XkbClientMapPtr xkb = xkbi->desc->map; -CARD8 * start; - - start= wire; - first= req->firstModMapKey; - last= req->firstModMapKey+req->nModMapKeys-1; - bzero(&xkb->modmap[first],req->nModMapKeys); - for (i=0;i<req->totalModMapKeys;i++,wire+= 2) { - xkb->modmap[wire[0]]= wire[1]; - } - if (first>0) { - if (changes->map.changed&XkbModifierMapMask) { - int oldLast; - oldLast= changes->map.first_modmap_key+ - changes->map.num_modmap_keys-1; - if (changes->map.first_modmap_key<first) - first= changes->map.first_modmap_key; - if (oldLast>last) - last= oldLast; - } - changes->map.first_modmap_key= first; - changes->map.num_modmap_keys= (last-first)+1; - } - wire+= XkbPaddedSize(wire-start)-(wire-start); - return (char *)wire; -} - -static char * -SetVirtualModMap( XkbSrvInfoPtr xkbi, - xkbSetMapReq * req, - xkbVModMapWireDesc * wire, - XkbChangesPtr changes) -{ -register unsigned i,first,last; -XkbServerMapPtr srv = xkbi->desc->server; - - first= req->firstVModMapKey; - last= req->firstVModMapKey+req->nVModMapKeys-1; - bzero(&srv->vmodmap[first],req->nVModMapKeys*sizeof(unsigned short)); - for (i=0;i<req->totalVModMapKeys;i++,wire++) { - srv->vmodmap[wire->key]= wire->vmods; - } - if (first>0) { - if (changes->map.changed&XkbVirtualModMapMask) { - int oldLast; - oldLast= changes->map.first_vmodmap_key+ - changes->map.num_vmodmap_keys-1; - if (changes->map.first_vmodmap_key<first) - first= changes->map.first_vmodmap_key; - if (oldLast>last) - last= oldLast; - } - changes->map.first_vmodmap_key= first; - changes->map.num_vmodmap_keys= (last-first)+1; - } - return (char *)wire; -} - -/** - * Check if the given request can be applied to the given device but don't - * actually do anything.. - */ -static int -_XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char* values) -{ - XkbSrvInfoPtr xkbi; - XkbDescPtr xkb; - int error; - int nTypes = 0, nActions; - CARD8 mapWidths[XkbMaxLegalKeyCode + 1]; - CARD16 symsPerKey[XkbMaxLegalKeyCode + 1]; - - xkbi= dev->key->xkbInfo; - xkb = xkbi->desc; - - if ((xkb->min_key_code != req->minKeyCode)|| - (xkb->max_key_code != req->maxKeyCode)) { - if (client->vMajor!=1) { /* pre 1.0 versions of Xlib have a bug */ - req->minKeyCode= xkb->min_key_code; - req->maxKeyCode= xkb->max_key_code; - } - else { - if (!XkbIsLegalKeycode(req->minKeyCode)) { - client->errorValue = _XkbErrCode3(2, req->minKeyCode, req->maxKeyCode); - return BadValue; - } - if (req->minKeyCode > req->maxKeyCode) { - client->errorValue = _XkbErrCode3(3, req->minKeyCode, req->maxKeyCode); - return BadMatch; - } - } - } - - if ((req->present & XkbKeyTypesMask) && - (!CheckKeyTypes(client,xkb,req,(xkbKeyTypeWireDesc **)&values, - &nTypes,mapWidths))) { - client->errorValue = nTypes; - return BadValue; - } - if ((req->present & XkbKeySymsMask) && - (!CheckKeySyms(client,xkb,req,nTypes,mapWidths,symsPerKey, - (xkbSymMapWireDesc **)&values,&error))) { - client->errorValue = error; - return BadValue; - } - - if ((req->present & XkbKeyActionsMask) && - (!CheckKeyActions(xkb,req,nTypes,mapWidths,symsPerKey, - (CARD8 **)&values,&nActions))) { - client->errorValue = nActions; - return BadValue; - } - - if ((req->present & XkbKeyBehaviorsMask) && - (!CheckKeyBehaviors(xkb,req,(xkbBehaviorWireDesc**)&values,&error))) { - client->errorValue = error; - return BadValue; - } - - if ((req->present & XkbVirtualModsMask) && - (!CheckVirtualMods(xkb,req,(CARD8 **)&values,&error))) { - client->errorValue= error; - return BadValue; - } - if ((req->present&XkbExplicitComponentsMask) && - (!CheckKeyExplicit(xkb,req,(CARD8 **)&values,&error))) { - client->errorValue= error; - return BadValue; - } - if ((req->present&XkbModifierMapMask) && - (!CheckModifierMap(xkb,req,(CARD8 **)&values,&error))) { - client->errorValue= error; - return BadValue; - } - if ((req->present&XkbVirtualModMapMask) && - (!CheckVirtualModMap(xkb,req,(xkbVModMapWireDesc **)&values,&error))) { - client->errorValue= error; - return BadValue; - } - - if (((values-((char *)req))/4)!= req->length) { - ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after check)\n"); - client->errorValue = values-((char *)&req[1]); - return BadLength; - } - - return Success; -} - -/** - * Apply the given request on the given device. - */ -static int -_XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char *values) -{ - XkbEventCauseRec cause; - XkbChangesRec change; - Bool sentNKN; - XkbSrvInfoPtr xkbi; - XkbDescPtr xkb; - - xkbi= dev->key->xkbInfo; - xkb = xkbi->desc; - - XkbSetCauseXkbReq(&cause,X_kbSetMap,client); - bzero(&change, sizeof(change)); - sentNKN = FALSE; - if ((xkb->min_key_code!=req->minKeyCode)|| - (xkb->max_key_code!=req->maxKeyCode)) { - Status status; - xkbNewKeyboardNotify nkn; - nkn.deviceID = nkn.oldDeviceID = dev->id; - nkn.oldMinKeyCode = xkb->min_key_code; - nkn.oldMaxKeyCode = xkb->max_key_code; - status= XkbChangeKeycodeRange(xkb, req->minKeyCode, - req->maxKeyCode, &change); - if (status != Success) - return status; /* oh-oh. what about the other keyboards? */ - nkn.minKeyCode = xkb->min_key_code; - nkn.maxKeyCode = xkb->max_key_code; - nkn.requestMajor = XkbReqCode; - nkn.requestMinor = X_kbSetMap; - nkn.changed = XkbNKN_KeycodesMask; - XkbSendNewKeyboardNotify(dev,&nkn); - sentNKN = TRUE; - } - - if (req->present&XkbKeyTypesMask) { - values = SetKeyTypes(xkb,req,(xkbKeyTypeWireDesc *)values,&change); - if (!values) goto allocFailure; - } - if (req->present&XkbKeySymsMask) { - values = SetKeySyms(client,xkb,req,(xkbSymMapWireDesc *)values,&change,dev); - if (!values) goto allocFailure; - } - if (req->present&XkbKeyActionsMask) { - values = SetKeyActions(xkb,req,(CARD8 *)values,&change); - if (!values) goto allocFailure; - } - if (req->present&XkbKeyBehaviorsMask) { - values= SetKeyBehaviors(xkbi,req,(xkbBehaviorWireDesc *)values,&change); - if (!values) goto allocFailure; - } - if (req->present&XkbVirtualModsMask) - values= SetVirtualMods(xkbi,req,(CARD8 *)values,&change); - if (req->present&XkbExplicitComponentsMask) - values= SetKeyExplicit(xkbi,req,(CARD8 *)values,&change); - if (req->present&XkbModifierMapMask) - values= SetModifierMap(xkbi,req,(CARD8 *)values,&change); - if (req->present&XkbVirtualModMapMask) - values= SetVirtualModMap(xkbi,req,(xkbVModMapWireDesc *)values,&change); - if (((values-((char *)req))/4)!=req->length) { - ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after set)\n"); - client->errorValue = values-((char *)&req[1]); - return BadLength; - } - if (req->flags&XkbSetMapRecomputeActions) { - KeyCode first,last,firstMM,lastMM; - if (change.map.num_key_syms>0) { - first= change.map.first_key_sym; - last= first+change.map.num_key_syms-1; - } - else first= last= 0; - if (change.map.num_modmap_keys>0) { - firstMM= change.map.first_modmap_key; - lastMM= first+change.map.num_modmap_keys-1; - } - else firstMM= lastMM= 0; - if ((last>0) && (lastMM>0)) { - if (firstMM<first) - first= firstMM; - if (lastMM>last) - last= lastMM; - } - else if (lastMM>0) { - first= firstMM; - last= lastMM; - } - if (last>0) { - unsigned check= 0; - XkbUpdateActions(dev,first,(last-first+1),&change,&check,&cause); - if (check) - XkbCheckSecondaryEffects(xkbi,check,&change,&cause); - } - } - if (!sentNKN) - XkbSendNotification(dev,&change,&cause); - - return Success; -allocFailure: - return BadAlloc; -} - - -int -ProcXkbSetMap(ClientPtr client) -{ - DeviceIntPtr dev; - char * tmp; - int rc; - - REQUEST(xkbSetMapReq); - REQUEST_AT_LEAST_SIZE(xkbSetMapReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); - CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask); - - tmp = (char *)&stuff[1]; - - /* Check if we can to the SetMap on the requested device. If this - succeeds, do the same thing for all extension devices (if needed). - If any of them fails, fail. */ - rc = _XkbSetMapChecks(client, dev, stuff, tmp); - - if (rc != Success) - return rc; - - if (stuff->deviceSpec == XkbUseCoreKbd) - { - DeviceIntPtr other; - for (other = inputInfo.devices; other; other = other->next) - { - if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev)) - { - rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); - if (rc == Success) - { - rc = _XkbSetMapChecks(client, other, stuff, tmp); - if (rc != Success) - return rc; - } - } - } - } - - /* We know now that we will succed with the SetMap. In theory anyway. */ - rc = _XkbSetMap(client, dev, stuff, tmp); - if (rc != Success) - return rc; - - if (stuff->deviceSpec == XkbUseCoreKbd) - { - DeviceIntPtr other; - for (other = inputInfo.devices; other; other = other->next) - { - if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev)) - { - rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); - if (rc == Success) - _XkbSetMap(client, other, stuff, tmp); - /* ignore rc. if the SetMap failed although the check above - reported true there isn't much we can do. we still need to - set all other devices, hoping that at least they stay in - sync. */ - } - } - } - - return client->noClientException; -} - -/***====================================================================***/ - -static Status -XkbComputeGetCompatMapReplySize( XkbCompatMapPtr compat, - xkbGetCompatMapReply * rep) -{ -unsigned size,nGroups; - - nGroups= 0; - if (rep->groups!=0) { - register int i,bit; - for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { - if (rep->groups&bit) - nGroups++; - } - } - size= nGroups*SIZEOF(xkbModsWireDesc); - size+= (rep->nSI*SIZEOF(xkbSymInterpretWireDesc)); - rep->length= size/4; - return Success; -} - -static int -XkbSendCompatMap( ClientPtr client, - XkbCompatMapPtr compat, - xkbGetCompatMapReply * rep) -{ -char * data; -int size; - - size= rep->length*4; - if (size>0) { - data = xalloc(size); - if (data) { - register unsigned i,bit; - xkbModsWireDesc * grp; - XkbSymInterpretPtr sym= &compat->sym_interpret[rep->firstSI]; - xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data; - for (i=0;i<rep->nSI;i++,sym++,wire++) { - wire->sym= sym->sym; - wire->mods= sym->mods; - wire->match= sym->match; - wire->virtualMod= sym->virtual_mod; - wire->flags= sym->flags; - memcpy((char*)&wire->act,(char*)&sym->act,sz_xkbActionWireDesc); - if (client->swapped) { - register int n; - swapl(&wire->sym,n); - } - } - if (rep->groups) { - grp = (xkbModsWireDesc *)wire; - for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { - if (rep->groups&bit) { - grp->mask= compat->groups[i].mask; - grp->realMods= compat->groups[i].real_mods; - grp->virtualMods= compat->groups[i].vmods; - if (client->swapped) { - register int n; - swaps(&grp->virtualMods,n); - } - grp++; - } - } - wire= (xkbSymInterpretWireDesc*)grp; - } - } - else return BadAlloc; - } - else data= NULL; - - if (client->swapped) { - register int n; - swaps(&rep->sequenceNumber,n); - swapl(&rep->length,n); - swaps(&rep->firstSI,n); - swaps(&rep->nSI,n); - swaps(&rep->nTotalSI,n); - } - - WriteToClient(client, SIZEOF(xkbGetCompatMapReply), (char *)rep); - if (data) { - WriteToClient(client, size, data); - xfree((char *)data); - } - return client->noClientException; -} - -int -ProcXkbGetCompatMap(ClientPtr client) -{ - xkbGetCompatMapReply rep; - DeviceIntPtr dev; - XkbDescPtr xkb; - XkbCompatMapPtr compat; - - REQUEST(xkbGetCompatMapReq); - REQUEST_SIZE_MATCH(xkbGetCompatMapReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); - - xkb = dev->key->xkbInfo->desc; - compat= xkb->compat; - - rep.type = X_Reply; - rep.deviceID = dev->id; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.firstSI = stuff->firstSI; - rep.nSI = stuff->nSI; - if (stuff->getAllSI) { - rep.firstSI = 0; - rep.nSI = compat->num_si; - } - else if ((((unsigned)stuff->nSI)>0)&& - ((unsigned)(stuff->firstSI+stuff->nSI-1)>=compat->num_si)) { - client->errorValue = _XkbErrCode2(0x05,compat->num_si); - return BadValue; - } - rep.nTotalSI = compat->num_si; - rep.groups= stuff->groups; - XkbComputeGetCompatMapReplySize(compat,&rep); - return XkbSendCompatMap(client,compat,&rep); -} - -/** - * Apply the given request on the given device. - * If dryRun is TRUE, then value checks are performed, but the device isn't - * modified. - */ -static int -_XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev, - xkbSetCompatMapReq *req, char* data, BOOL dryRun) -{ - XkbSrvInfoPtr xkbi; - XkbDescPtr xkb; - XkbCompatMapPtr compat; - int nGroups; - unsigned i,bit; - - xkbi = dev->key->xkbInfo; - xkb = xkbi->desc; - compat = xkb->compat; - - if ((req->nSI>0)||(req->truncateSI)) { - xkbSymInterpretWireDesc *wire; - if (req->firstSI>compat->num_si) { - client->errorValue = _XkbErrCode2(0x02,compat->num_si); - return BadValue; - } - wire= (xkbSymInterpretWireDesc *)data; - wire+= req->nSI; - data = (char *)wire; - } - - nGroups= 0; - if (req->groups!=0) { - for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) { - if ( req->groups&bit ) - nGroups++; - } - } - data+= nGroups*SIZEOF(xkbModsWireDesc); - if (((data-((char *)req))/4)!=req->length) { - return BadLength; - } - - /* Done all the checks we can do */ - if (dryRun) - return Success; - - data = (char *)&req[1]; - if (req->nSI>0) { - xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data; - XkbSymInterpretPtr sym; - if ((unsigned)(req->firstSI+req->nSI)>compat->num_si) { - compat->num_si= req->firstSI+req->nSI; - compat->sym_interpret= xrealloc(compat->sym_interpret, - compat->num_si * sizeof(XkbSymInterpretRec)); - if (!compat->sym_interpret) { - compat->num_si= 0; - return BadAlloc; - } - } - else if (req->truncateSI) { - compat->num_si = req->firstSI+req->nSI; - } - sym = &compat->sym_interpret[req->firstSI]; - for (i=0;i<req->nSI;i++,wire++,sym++) { - if (client->swapped) { - int n; - swapl(&wire->sym,n); - } - sym->sym= wire->sym; - sym->mods= wire->mods; - sym->match= wire->match; - sym->flags= wire->flags; - sym->virtual_mod= wire->virtualMod; - memcpy((char *)&sym->act,(char *)&wire->act, - SIZEOF(xkbActionWireDesc)); - } - data = (char *)wire; - } - else if (req->truncateSI) { - compat->num_si = req->firstSI; - } - - if (req->groups!=0) { - unsigned i, bit; - xkbModsWireDesc *wire = (xkbModsWireDesc *)data; - for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) { - if (req->groups & bit) { - if (client->swapped) { - int n; - swaps(&wire->virtualMods,n); - } - compat->groups[i].mask= wire->realMods; - compat->groups[i].real_mods= wire->realMods; - compat->groups[i].vmods= wire->virtualMods; - if (wire->virtualMods!=0) { - unsigned tmp; - tmp= XkbMaskForVMask(xkb,wire->virtualMods); - compat->groups[i].mask|= tmp; - } - data+= SIZEOF(xkbModsWireDesc); - wire= (xkbModsWireDesc *)data; - } - } - } - i= XkbPaddedSize((data-((char *)req))); - if ((i/4)!=req->length) { - ErrorF("[xkb] Internal length error on read in _XkbSetCompatMap\n"); - return BadLength; - } - - if (dev->xkb_interest) { - xkbCompatMapNotify ev; - ev.deviceID = dev->id; - ev.changedGroups = req->groups; - ev.firstSI = req->firstSI; - ev.nSI = req->nSI; - ev.nTotalSI = compat->num_si; - XkbSendCompatMapNotify(dev,&ev); - } - - if (req->recomputeActions) { - XkbChangesRec change; - unsigned check; - XkbEventCauseRec cause; - - XkbSetCauseXkbReq(&cause,X_kbSetCompatMap,client); - bzero(&change,sizeof(XkbChangesRec)); - XkbUpdateActions(dev,xkb->min_key_code,XkbNumKeys(xkb),&change,&check, - &cause); - if (check) - XkbCheckSecondaryEffects(xkbi,check,&change,&cause); - XkbSendNotification(dev,&change,&cause); - } - return Success; -} - -int -ProcXkbSetCompatMap(ClientPtr client) -{ - DeviceIntPtr dev; - char *data; - int rc; - - REQUEST(xkbSetCompatMapReq); - REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); - - data = (char *)&stuff[1]; - - /* check first using a dry-run */ - rc = _XkbSetCompatMap(client, dev, stuff, data, TRUE); - if (rc != Success) - return rc; - if (stuff->deviceSpec == XkbUseCoreKbd) - { - DeviceIntPtr other; - for (other = inputInfo.devices; other; other = other->next) - { - if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev)) - { - rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); - if (rc == Success) - { - /* dry-run */ - rc = _XkbSetCompatMap(client, other, stuff, data, TRUE); - if (rc != Success) - return rc; - } - } - } - } - - /* Yay, the dry-runs succeed. Let's apply */ - rc = _XkbSetCompatMap(client, dev, stuff, data, FALSE); - if (rc != Success) - return rc; - if (stuff->deviceSpec == XkbUseCoreKbd) - { - DeviceIntPtr other; - for (other = inputInfo.devices; other; other = other->next) - { - if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev)) - { - rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); - if (rc == Success) - { - rc = _XkbSetCompatMap(client, other, stuff, data, FALSE); - if (rc != Success) - return rc; - } - } - } - } - - return client->noClientException; -} - -/***====================================================================***/ - -int -ProcXkbGetIndicatorState(ClientPtr client) -{ - xkbGetIndicatorStateReply rep; - XkbSrvLedInfoPtr sli; - DeviceIntPtr dev; - register int i; - - REQUEST(xkbGetIndicatorStateReq); - REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess); - - sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, - XkbXI_IndicatorStateMask); - if (!sli) - return BadAlloc; - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.deviceID = dev->id; - rep.state = sli->effectiveState; - - if (client->swapped) { - swaps(&rep.sequenceNumber,i); - swapl(&rep.state,i); - } - WriteToClient(client, SIZEOF(xkbGetIndicatorStateReply), (char *)&rep); - return client->noClientException; -} - -/***====================================================================***/ - -static Status -XkbComputeGetIndicatorMapReplySize( - XkbIndicatorPtr indicators, - xkbGetIndicatorMapReply *rep) -{ -register int i,bit; -int nIndicators; - - rep->realIndicators = indicators->phys_indicators; - for (i=nIndicators=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { - if (rep->which&bit) - nIndicators++; - } - rep->length = (nIndicators*SIZEOF(xkbIndicatorMapWireDesc))/4; - return Success; -} - -static int -XkbSendIndicatorMap( ClientPtr client, - XkbIndicatorPtr indicators, - xkbGetIndicatorMapReply * rep) -{ -int length; -CARD8 * map; -register int i; -register unsigned bit; - - length = rep->length*4; - if (length>0) { - CARD8 *to; - to= map= xalloc(length); - if (map) { - xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *)to; - for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { - if (rep->which&bit) { - wire->flags= indicators->maps[i].flags; - wire->whichGroups= indicators->maps[i].which_groups; - wire->groups= indicators->maps[i].groups; - wire->whichMods= indicators->maps[i].which_mods; - wire->mods= indicators->maps[i].mods.mask; - wire->realMods= indicators->maps[i].mods.real_mods; - wire->virtualMods= indicators->maps[i].mods.vmods; - wire->ctrls= indicators->maps[i].ctrls; - if (client->swapped) { - register int n; - swaps(&wire->virtualMods,n); - swapl(&wire->ctrls,n); - } - wire++; - } - } - to = (CARD8 *)wire; - if ((to-map)!=length) { - client->errorValue = _XkbErrCode2(0xff,length); - return BadLength; - } - } - else return BadAlloc; - } - else map = NULL; - if (client->swapped) { - swaps(&rep->sequenceNumber,i); - swapl(&rep->length,i); - swapl(&rep->which,i); - swapl(&rep->realIndicators,i); - } - WriteToClient(client, SIZEOF(xkbGetIndicatorMapReply), (char *)rep); - if (map) { - WriteToClient(client, length, (char *)map); - xfree((char *)map); - } - return client->noClientException; -} - -int -ProcXkbGetIndicatorMap(ClientPtr client) -{ -xkbGetIndicatorMapReply rep; -DeviceIntPtr dev; -XkbDescPtr xkb; -XkbIndicatorPtr leds; - - REQUEST(xkbGetIndicatorMapReq); - REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); - - xkb= dev->key->xkbInfo->desc; - leds= xkb->indicators; - - rep.type = X_Reply; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.deviceID = dev->id; - rep.which = stuff->which; - XkbComputeGetIndicatorMapReplySize(leds,&rep); - return XkbSendIndicatorMap(client,leds,&rep); -} - -/** - * Apply the given map to the given device. Which specifies which components - * to apply. - */ -static int -_XkbSetIndicatorMap(ClientPtr client, DeviceIntPtr dev, - int which, xkbIndicatorMapWireDesc *desc) -{ - XkbSrvInfoPtr xkbi; - XkbSrvLedInfoPtr sli; - XkbEventCauseRec cause; - int i, bit; - - xkbi = dev->key->xkbInfo; - - sli= XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId, - XkbXI_IndicatorMapsMask); - if (!sli) - return BadAlloc; - - for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) { - if (which & bit) { - sli->maps[i].flags = desc->flags; - sli->maps[i].which_groups = desc->whichGroups; - sli->maps[i].groups = desc->groups; - sli->maps[i].which_mods = desc->whichMods; - sli->maps[i].mods.mask = desc->mods; - sli->maps[i].mods.real_mods = desc->mods; - sli->maps[i].mods.vmods= desc->virtualMods; - sli->maps[i].ctrls = desc->ctrls; - if (desc->virtualMods!=0) { - unsigned tmp; - tmp= XkbMaskForVMask(xkbi->desc,desc->virtualMods); - sli->maps[i].mods.mask= desc->mods|tmp; - } - desc++; - } - } - - XkbSetCauseXkbReq(&cause,X_kbSetIndicatorMap,client); - XkbApplyLedMapChanges(dev,sli,which,NULL,NULL,&cause); - - return Success; -} - -int -ProcXkbSetIndicatorMap(ClientPtr client) -{ - int i, bit; - int nIndicators; - DeviceIntPtr dev; - xkbIndicatorMapWireDesc *from; - int rc; - - REQUEST(xkbSetIndicatorMapReq); - REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); - - if (stuff->which==0) - return client->noClientException; - - for (nIndicators=i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { - if (stuff->which&bit) - nIndicators++; - } - if (stuff->length!=((SIZEOF(xkbSetIndicatorMapReq)+ - (nIndicators*SIZEOF(xkbIndicatorMapWireDesc)))/4)) { - return BadLength; - } - - from = (xkbIndicatorMapWireDesc *)&stuff[1]; - for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { - if (stuff->which&bit) { - if (client->swapped) { - int n; - swaps(&from->virtualMods,n); - swapl(&from->ctrls,n); - } - CHK_MASK_LEGAL(i,from->whichGroups,XkbIM_UseAnyGroup); - CHK_MASK_LEGAL(i,from->whichMods,XkbIM_UseAnyMods); - from++; - } - } - - from = (xkbIndicatorMapWireDesc *)&stuff[1]; - rc = _XkbSetIndicatorMap(client, dev, stuff->which, from); - if (rc != Success) - return rc; - - if (stuff->deviceSpec == XkbUseCoreKbd) - { - DeviceIntPtr other; - for (other = inputInfo.devices; other; other = other->next) - { - if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev)) - { - rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess); - if (rc == Success) - _XkbSetIndicatorMap(client, other, stuff->which, from); - } - } - } - - return Success; -} - -/***====================================================================***/ - -int -ProcXkbGetNamedIndicator(ClientPtr client) -{ - DeviceIntPtr dev; - xkbGetNamedIndicatorReply rep; - register int i = 0; - XkbSrvLedInfoPtr sli; - XkbIndicatorMapPtr map = NULL; - - REQUEST(xkbGetNamedIndicatorReq); - REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess); - CHK_ATOM_ONLY(stuff->indicator); - - sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID,0); - if (!sli) - return BadAlloc; - - i= 0; - map= NULL; - if ((sli->names)&&(sli->maps)) { - for (i=0;i<XkbNumIndicators;i++) { - if (stuff->indicator==sli->names[i]) { - map= &sli->maps[i]; - break; - } - } - } - - rep.type= X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.deviceID = dev->id; - rep.indicator= stuff->indicator; - if (map!=NULL) { - rep.found= TRUE; - rep.on= ((sli->effectiveState&(1<<i))!=0); - rep.realIndicator= ((sli->physIndicators&(1<<i))!=0); - rep.ndx= i; - rep.flags= map->flags; - rep.whichGroups= map->which_groups; - rep.groups= map->groups; - rep.whichMods= map->which_mods; - rep.mods= map->mods.mask; - rep.realMods= map->mods.real_mods; - rep.virtualMods= map->mods.vmods; - rep.ctrls= map->ctrls; - rep.supported= TRUE; - } - else { - rep.found= FALSE; - rep.on= FALSE; - rep.realIndicator= FALSE; - rep.ndx= XkbNoIndicator; - rep.flags= 0; - rep.whichGroups= 0; - rep.groups= 0; - rep.whichMods= 0; - rep.mods= 0; - rep.realMods= 0; - rep.virtualMods= 0; - rep.ctrls= 0; - rep.supported= TRUE; - } - if ( client->swapped ) { - register int n; - swapl(&rep.length,n); - swaps(&rep.sequenceNumber,n); - swapl(&rep.indicator,n); - swaps(&rep.virtualMods,n); - swapl(&rep.ctrls,n); - } - - WriteToClient(client,SIZEOF(xkbGetNamedIndicatorReply), (char *)&rep); - return client->noClientException; -} - - -/** - * Find the IM on the device. - * Returns the map, or NULL if the map doesn't exist. - * If the return value is NULL, led_return is undefined. Otherwise, led_return - * is set to the led index of the map. - */ -static XkbIndicatorMapPtr -_XkbFindNamedIndicatorMap(XkbSrvLedInfoPtr sli, Atom indicator, - int *led_return) -{ - XkbIndicatorMapPtr map; - - /* search for the right indicator */ - map = NULL; - if (sli->names && sli->maps) { - int led; - - for (led = 0; (led < XkbNumIndicators) && (map == NULL); led++) { - if (sli->names[led] == indicator) { - map= &sli->maps[led]; - *led_return = led; - break; - } - } - } - - return map; -} - -/** - * Creates an indicator map on the device. If dryRun is TRUE, it only checks - * if creation is possible, but doesn't actually create it. - */ -static int -_XkbCreateIndicatorMap(DeviceIntPtr dev, Atom indicator, - int ledClass, int ledID, - XkbIndicatorMapPtr *map_return, int *led_return, - Bool dryRun) -{ - XkbSrvLedInfoPtr sli; - XkbIndicatorMapPtr map; - int led; - - sli = XkbFindSrvLedInfo(dev, ledClass, ledID, XkbXI_IndicatorsMask); - if (!sli) - return BadAlloc; - - map = _XkbFindNamedIndicatorMap(sli, indicator, &led); - - if (!map) - { - /* find first unused indicator maps and assign the name to it */ - for (led = 0, map = NULL; (led < XkbNumIndicators) && (map == NULL); led++) { - if ((sli->names) && (sli->maps) && (sli->names[led] == None) && - (!XkbIM_InUse(&sli->maps[led]))) - { - map = &sli->maps[led]; - if (!dryRun) - sli->names[led] = indicator; - break; - } - } - } - - if (!map) - return BadAlloc; - - *led_return = led; - *map_return = map; - return Success; -} - -static int -_XkbSetNamedIndicator(ClientPtr client, DeviceIntPtr dev, - xkbSetNamedIndicatorReq *stuff) -{ - unsigned int extDevReason; - unsigned int statec, namec, mapc; - XkbSrvLedInfoPtr sli; - int led = 0; - XkbIndicatorMapPtr map; - DeviceIntPtr kbd; - XkbEventCauseRec cause; - xkbExtensionDeviceNotify ed; - XkbChangesRec changes; - int rc; - - rc = _XkbCreateIndicatorMap(dev, stuff->indicator, stuff->ledClass, - stuff->ledID, &map, &led, FALSE); - if (rc != Success || !map) /* oh-oh */ - return rc; - - sli = XkbFindSrvLedInfo(dev, stuff->ledClass, stuff->ledID, - XkbXI_IndicatorsMask); - if (!sli) - return BadAlloc; - - namec = mapc = statec = 0; - extDevReason = 0; - - namec |= (1<<led); - sli->namesPresent |= ((stuff->indicator != None) ? (1 << led) : 0); - extDevReason |= XkbXI_IndicatorNamesMask; - - if (stuff->setMap) { - map->flags = stuff->flags; - map->which_groups = stuff->whichGroups; - map->groups = stuff->groups; - map->which_mods = stuff->whichMods; - map->mods.mask = stuff->realMods; - map->mods.real_mods = stuff->realMods; - map->mods.vmods= stuff->virtualMods; - map->ctrls = stuff->ctrls; - mapc|= (1<<led); - } - - if ((stuff->setState) && ((map->flags & XkbIM_NoExplicit) == 0)) - { - if (stuff->on) sli->explicitState |= (1<<led); - else sli->explicitState &= ~(1<<led); - statec |= ((sli->effectiveState ^ sli->explicitState) & (1 << led)); - } - - bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify)); - bzero((char *)&changes,sizeof(XkbChangesRec)); - XkbSetCauseXkbReq(&cause,X_kbSetNamedIndicator,client); - if (namec) - XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause); - if (mapc) - XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause); - if (statec) - XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause); - - kbd = dev; - if ((sli->flags&XkbSLI_HasOwnState)==0) - kbd = inputInfo.keyboard; - XkbFlushLedEvents(dev, kbd, sli, &ed, &changes, &cause); - - return Success; -} - -int -ProcXkbSetNamedIndicator(ClientPtr client) -{ - int rc; - DeviceIntPtr dev; - int led = 0; - XkbIndicatorMapPtr map; - - REQUEST(xkbSetNamedIndicatorReq); - REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess); - CHK_ATOM_ONLY(stuff->indicator); - CHK_MASK_LEGAL(0x10,stuff->whichGroups,XkbIM_UseAnyGroup); - CHK_MASK_LEGAL(0x11,stuff->whichMods,XkbIM_UseAnyMods); - - /* Dry-run for checks */ - rc = _XkbCreateIndicatorMap(dev, stuff->indicator, - stuff->ledClass, stuff->ledID, - &map, &led, TRUE); - if (rc != Success || !map) /* couldn't be created or didn't exist */ - return rc; - - if (stuff->deviceSpec == XkbUseCoreKbd || - stuff->deviceSpec == XkbUseCorePtr) - { - DeviceIntPtr other; - for (other = inputInfo.devices; other; other = other->next) - { - if ((other != dev) && !IsMaster(other) && (other->u.master == dev) && - (other->kbdfeed || other->leds) && - (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success)) - { - rc = _XkbCreateIndicatorMap(other, stuff->indicator, - stuff->ledClass, stuff->ledID, - &map, &led, TRUE); - if (rc != Success || !map) - return rc; - } - } - } - - /* All checks passed, let's do it */ - rc = _XkbSetNamedIndicator(client, dev, stuff); - if (rc != Success) - return rc; - - if (stuff->deviceSpec == XkbUseCoreKbd || - stuff->deviceSpec == XkbUseCorePtr) - { - DeviceIntPtr other; - for (other = inputInfo.devices; other; other = other->next) - { - if ((other != dev) && !IsMaster(other) && (other->u.master == dev) && - (other->kbdfeed || other->leds) && - (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success)) - { - _XkbSetNamedIndicator(client, other, stuff); - } - } - } - - return client->noClientException; -} - -/***====================================================================***/ - -static CARD32 -_XkbCountAtoms(Atom *atoms,int maxAtoms,int *count) -{ -register unsigned int i,bit,nAtoms; -register CARD32 atomsPresent; - - for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) { - if (atoms[i]!=None) { - atomsPresent|= bit; - nAtoms++; - } - } - if (count) - *count= nAtoms; - return atomsPresent; -} - -static char * -_XkbWriteAtoms(char *wire,Atom *atoms,int maxAtoms,int swap) -{ -register unsigned int i; -Atom *atm; - - atm = (Atom *)wire; - for (i=0;i<maxAtoms;i++) { - if (atoms[i]!=None) { - *atm= atoms[i]; - if (swap) { - register int n; - swapl(atm,n); - } - atm++; - } - } - return (char *)atm; -} - -static Status -XkbComputeGetNamesReplySize(XkbDescPtr xkb,xkbGetNamesReply *rep) -{ -register unsigned which,length; -register int i; - - rep->minKeyCode= xkb->min_key_code; - rep->maxKeyCode= xkb->max_key_code; - which= rep->which; - length= 0; - if (xkb->names!=NULL) { - if (which&XkbKeycodesNameMask) length++; - if (which&XkbGeometryNameMask) length++; - if (which&XkbSymbolsNameMask) length++; - if (which&XkbPhysSymbolsNameMask) length++; - if (which&XkbTypesNameMask) length++; - if (which&XkbCompatNameMask) length++; - } - else which&= ~XkbComponentNamesMask; - - if (xkb->map!=NULL) { - if (which&XkbKeyTypeNamesMask) - length+= xkb->map->num_types; - rep->nTypes= xkb->map->num_types; - if (which&XkbKTLevelNamesMask) { - XkbKeyTypePtr pType = xkb->map->types; - int nKTLevels = 0; - - length+= XkbPaddedSize(xkb->map->num_types)/4; - for (i=0;i<xkb->map->num_types;i++,pType++) { - if (pType->level_names!=NULL) - nKTLevels+= pType->num_levels; - } - rep->nKTLevels= nKTLevels; - length+= nKTLevels; - } - } - else { - rep->nTypes= 0; - rep->nKTLevels= 0; - which&= ~(XkbKeyTypeNamesMask|XkbKTLevelNamesMask); - } - - rep->minKeyCode= xkb->min_key_code; - rep->maxKeyCode= xkb->max_key_code; - rep->indicators= 0; - rep->virtualMods= 0; - rep->groupNames= 0; - if (xkb->names!=NULL) { - if (which&XkbIndicatorNamesMask) { - int nLeds; - rep->indicators= - _XkbCountAtoms(xkb->names->indicators,XkbNumIndicators,&nLeds); - length+= nLeds; - if (nLeds==0) - which&= ~XkbIndicatorNamesMask; - } - - if (which&XkbVirtualModNamesMask) { - int nVMods; - rep->virtualMods= - _XkbCountAtoms(xkb->names->vmods,XkbNumVirtualMods,&nVMods); - length+= nVMods; - if (nVMods==0) - which&= ~XkbVirtualModNamesMask; - } - - if (which&XkbGroupNamesMask) { - int nGroups; - rep->groupNames= - _XkbCountAtoms(xkb->names->groups,XkbNumKbdGroups,&nGroups); - length+= nGroups; - if (nGroups==0) - which&= ~XkbGroupNamesMask; - } - - if ((which&XkbKeyNamesMask)&&(xkb->names->keys)) - length+= rep->nKeys; - else which&= ~XkbKeyNamesMask; - - if ((which&XkbKeyAliasesMask)&& - (xkb->names->key_aliases)&&(xkb->names->num_key_aliases>0)) { - rep->nKeyAliases= xkb->names->num_key_aliases; - length+= rep->nKeyAliases*2; - } - else { - which&= ~XkbKeyAliasesMask; - rep->nKeyAliases= 0; - } - - if ((which&XkbRGNamesMask)&&(xkb->names->num_rg>0)) - length+= xkb->names->num_rg; - else which&= ~XkbRGNamesMask; - } - else { - which&= ~(XkbIndicatorNamesMask|XkbVirtualModNamesMask); - which&= ~(XkbGroupNamesMask|XkbKeyNamesMask|XkbKeyAliasesMask); - which&= ~XkbRGNamesMask; - } - - rep->length= length; - rep->which= which; - return Success; -} - -static int -XkbSendNames(ClientPtr client,XkbDescPtr xkb,xkbGetNamesReply *rep) -{ -register unsigned i,length,which; -char * start; -char * desc; -register int n; - - length= rep->length*4; - which= rep->which; - if (client->swapped) { - swaps(&rep->sequenceNumber,n); - swapl(&rep->length,n); - swapl(&rep->which,n); - swaps(&rep->virtualMods,n); - swapl(&rep->indicators,n); - } - - start = desc = xalloc(length); - if ( !start ) - return BadAlloc; - if (xkb->names) { - if (which&XkbKeycodesNameMask) { - *((CARD32 *)desc)= xkb->names->keycodes; - if (client->swapped) { - swapl(desc,n); - } - desc+= 4; - } - if (which&XkbGeometryNameMask) { - *((CARD32 *)desc)= xkb->names->geometry; - if (client->swapped) { - swapl(desc,n); - } - desc+= 4; - } - if (which&XkbSymbolsNameMask) { - *((CARD32 *)desc)= xkb->names->symbols; - if (client->swapped) { - swapl(desc,n); - } - desc+= 4; - } - if (which&XkbPhysSymbolsNameMask) { - register CARD32 *atm= (CARD32 *)desc; - atm[0]= (CARD32)xkb->names->phys_symbols; - if (client->swapped) { - swapl(&atm[0],n); - } - desc+= 4; - } - if (which&XkbTypesNameMask) { - *((CARD32 *)desc)= (CARD32)xkb->names->types; - if (client->swapped) { - swapl(desc,n); - } - desc+= 4; - } - if (which&XkbCompatNameMask) { - *((CARD32 *)desc)= (CARD32)xkb->names->compat; - if (client->swapped) { - swapl(desc,n); - } - desc+= 4; - } - if (which&XkbKeyTypeNamesMask) { - register CARD32 *atm= (CARD32 *)desc; - register XkbKeyTypePtr type= xkb->map->types; - - for (i=0;i<xkb->map->num_types;i++,atm++,type++) { - *atm= (CARD32)type->name; - if (client->swapped) { - swapl(atm,n); - } - } - desc= (char *)atm; - } - if (which&XkbKTLevelNamesMask && xkb->map) { - XkbKeyTypePtr type = xkb->map->types; - register CARD32 *atm; - for (i=0;i<rep->nTypes;i++,type++) { - *desc++ = type->num_levels; - } - desc+= XkbPaddedSize(rep->nTypes)-rep->nTypes; - - atm= (CARD32 *)desc; - type = xkb->map->types; - for (i=0;i<xkb->map->num_types;i++,type++) { - register unsigned l; - if (type->level_names) { - for (l=0;l<type->num_levels;l++,atm++) { - *atm= type->level_names[l]; - if (client->swapped) { - swapl(atm,n); - } - } - desc+= type->num_levels*4; - } - } - } - if (which&XkbIndicatorNamesMask) { - desc= _XkbWriteAtoms(desc,xkb->names->indicators,XkbNumIndicators, - client->swapped); - } - if (which&XkbVirtualModNamesMask) { - desc= _XkbWriteAtoms(desc,xkb->names->vmods,XkbNumVirtualMods, - client->swapped); - } - if (which&XkbGroupNamesMask) { - desc= _XkbWriteAtoms(desc,xkb->names->groups,XkbNumKbdGroups, - client->swapped); - } - if (which&XkbKeyNamesMask) { - for (i=0;i<rep->nKeys;i++,desc+= sizeof(XkbKeyNameRec)) { - *((XkbKeyNamePtr)desc)= xkb->names->keys[i+rep->firstKey]; - } - } - if (which&XkbKeyAliasesMask) { - XkbKeyAliasPtr pAl; - pAl= xkb->names->key_aliases; - for (i=0;i<rep->nKeyAliases;i++,pAl++,desc+=2*XkbKeyNameLength) { - *((XkbKeyAliasPtr)desc)= *pAl; - } - } - if ((which&XkbRGNamesMask)&&(rep->nRadioGroups>0)) { - register CARD32 *atm= (CARD32 *)desc; - for (i=0;i<rep->nRadioGroups;i++,atm++) { - *atm= (CARD32)xkb->names->radio_groups[i]; - if (client->swapped) { - swapl(atm,n); - } - } - desc+= rep->nRadioGroups*4; - } - } - - if ((desc-start)!=(length)) { - ErrorF("[xkb] BOGUS LENGTH in write names, expected %d, got %ld\n", - length, (unsigned long)(desc-start)); - } - WriteToClient(client, SIZEOF(xkbGetNamesReply), (char *)rep); - WriteToClient(client, length, start); - xfree((char *)start); - return client->noClientException; -} - -int -ProcXkbGetNames(ClientPtr client) -{ - DeviceIntPtr dev; - XkbDescPtr xkb; - xkbGetNamesReply rep; - - REQUEST(xkbGetNamesReq); - REQUEST_SIZE_MATCH(xkbGetNamesReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); - CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask); - - xkb = dev->key->xkbInfo->desc; - memset(&rep, 0, sizeof(xkbGetNamesReply)); - rep.type= X_Reply; - rep.sequenceNumber= client->sequence; - rep.length = 0; - rep.deviceID = dev->id; - rep.which = stuff->which; - rep.nTypes = xkb->map->num_types; - rep.firstKey = xkb->min_key_code; - rep.nKeys = XkbNumKeys(xkb); - if (xkb->names!=NULL) { - rep.nKeyAliases= xkb->names->num_key_aliases; - rep.nRadioGroups = xkb->names->num_rg; - } - else { - rep.nKeyAliases= rep.nRadioGroups= 0; - } - XkbComputeGetNamesReplySize(xkb,&rep); - return XkbSendNames(client,xkb,&rep); -} - -/***====================================================================***/ - -static CARD32 * -_XkbCheckAtoms(CARD32 *wire,int nAtoms,int swapped,Atom *pError) -{ -register int i; - - for (i=0;i<nAtoms;i++,wire++) { - if (swapped) { - register int n; - swapl(wire,n); - } - if ((((Atom)*wire)!=None)&&(!ValidAtom((Atom)*wire))) { - *pError= ((Atom)*wire); - return NULL; - } - } - return wire; -} - -static CARD32 * -_XkbCheckMaskedAtoms(CARD32 *wire,int nAtoms,CARD32 present,int swapped, - Atom *pError) -{ -register unsigned i,bit; - - for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) { - if ((present&bit)==0) - continue; - if (swapped) { - register int n; - swapl(wire,n); - } - if ((((Atom)*wire)!=None)&&(!ValidAtom(((Atom)*wire)))) { - *pError= (Atom)*wire; - return NULL; - } - wire++; - } - return wire; -} - -static Atom * -_XkbCopyMaskedAtoms( Atom *wire, - Atom *dest, - int nAtoms, - CARD32 present) -{ -register int i,bit; - - for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) { - if ((present&bit)==0) - continue; - dest[i]= *wire++; - } - return wire; -} - -static Bool -_XkbCheckTypeName(Atom name,int typeNdx) -{ -const char * str; - - str= NameForAtom(name); - if ((strcmp(str,"ONE_LEVEL")==0)||(strcmp(str,"TWO_LEVEL")==0)|| - (strcmp(str,"ALPHABETIC")==0)||(strcmp(str,"KEYPAD")==0)) - return FALSE; - return TRUE; -} - -/** - * Check the device-dependent data in the request against the device. Returns - * Success, or the appropriate error code. - */ -static int -_XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev, - xkbSetNamesReq *stuff, CARD32 *data) -{ - XkbDescRec *xkb; - XkbNamesRec *names; - CARD32 *tmp; - Atom bad; - - tmp = data; - xkb = dev->key->xkbInfo->desc; - names = xkb->names; - - - if (stuff->which & XkbKeyTypeNamesMask) { - int i; - CARD32 *old; - if ( stuff->nTypes<1 ) { - client->errorValue = _XkbErrCode2(0x02,stuff->nTypes); - return BadValue; - } - if ((unsigned)(stuff->firstType+stuff->nTypes-1)>=xkb->map->num_types) { - client->errorValue = _XkbErrCode4(0x03,stuff->firstType, - stuff->nTypes, - xkb->map->num_types); - return BadValue; - } - if (((unsigned)stuff->firstType)<=XkbLastRequiredType) { - client->errorValue = _XkbErrCode2(0x04,stuff->firstType); - return BadAccess; - } - old= tmp; - tmp= _XkbCheckAtoms(tmp,stuff->nTypes,client->swapped,&bad); - if (!tmp) { - client->errorValue= bad; - return BadAtom; - } - for (i=0;i<stuff->nTypes;i++,old++) { - if (!_XkbCheckTypeName((Atom)*old,stuff->firstType+i)) - client->errorValue= _XkbErrCode2(0x05,i); - } - } - if (stuff->which&XkbKTLevelNamesMask) { - unsigned i; - XkbKeyTypePtr type; - CARD8 * width; - if ( stuff->nKTLevels<1 ) { - client->errorValue = _XkbErrCode2(0x05,stuff->nKTLevels); - return BadValue; - } - if ((unsigned)(stuff->firstKTLevel+stuff->nKTLevels-1)>= - xkb->map->num_types) { - client->errorValue = _XkbErrCode4(0x06,stuff->firstKTLevel, - stuff->nKTLevels,xkb->map->num_types); - return BadValue; - } - width = (CARD8 *)tmp; - tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); - type = &xkb->map->types[stuff->firstKTLevel]; - for (i=0;i<stuff->nKTLevels;i++,type++) { - if (width[i]==0) - continue; - else if (width[i]!=type->num_levels) { - client->errorValue= _XkbErrCode4(0x07,i+stuff->firstKTLevel, - type->num_levels,width[i]); - return BadMatch; - } - tmp= _XkbCheckAtoms(tmp,width[i],client->swapped,&bad); - if (!tmp) { - client->errorValue= bad; - return BadAtom; - } - } - } - if (stuff->which&XkbIndicatorNamesMask) { - if (stuff->indicators==0) { - client->errorValue= 0x08; - return BadMatch; - } - tmp= _XkbCheckMaskedAtoms(tmp,XkbNumIndicators,stuff->indicators, - client->swapped,&bad); - if (!tmp) { - client->errorValue= bad; - return BadAtom; - } - } - if (stuff->which&XkbVirtualModNamesMask) { - if (stuff->virtualMods==0) { - client->errorValue= 0x09; - return BadMatch; - } - tmp= _XkbCheckMaskedAtoms(tmp,XkbNumVirtualMods, - (CARD32)stuff->virtualMods, - client->swapped,&bad); - if (!tmp) { - client->errorValue = bad; - return BadAtom; - } - } - if (stuff->which&XkbGroupNamesMask) { - if (stuff->groupNames==0) { - client->errorValue= 0x0a; - return BadMatch; - } - tmp= _XkbCheckMaskedAtoms(tmp,XkbNumKbdGroups, - (CARD32)stuff->groupNames, - client->swapped,&bad); - if (!tmp) { - client->errorValue = bad; - return BadAtom; - } - } - if (stuff->which&XkbKeyNamesMask) { - if (stuff->firstKey<(unsigned)xkb->min_key_code) { - client->errorValue= _XkbErrCode3(0x0b,xkb->min_key_code, - stuff->firstKey); - return BadValue; - } - if (((unsigned)(stuff->firstKey+stuff->nKeys-1)>xkb->max_key_code)|| - (stuff->nKeys<1)) { - client->errorValue= _XkbErrCode4(0x0c,xkb->max_key_code, - stuff->firstKey,stuff->nKeys); - return BadValue; - } - tmp+= stuff->nKeys; - } - if ((stuff->which&XkbKeyAliasesMask)&&(stuff->nKeyAliases>0)) { - tmp+= stuff->nKeyAliases*2; - } - if (stuff->which&XkbRGNamesMask) { - if ( stuff->nRadioGroups<1 ) { - client->errorValue= _XkbErrCode2(0x0d,stuff->nRadioGroups); - return BadValue; - } - tmp= _XkbCheckAtoms(tmp,stuff->nRadioGroups,client->swapped,&bad); - if (!tmp) { - client->errorValue= bad; - return BadAtom; - } - } - if ((tmp-((CARD32 *)stuff))!=stuff->length) { - client->errorValue = stuff->length; - return BadLength; - } - - - - return Success; -} - -static int -_XkbSetNames(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq *stuff) -{ - XkbDescRec *xkb; - XkbNamesRec *names; - CARD32 *tmp; - xkbNamesNotify nn; - - tmp = (CARD32 *)&stuff[1]; - xkb = dev->key->xkbInfo->desc; - names = xkb->names; - - if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups, - stuff->nKeyAliases)!=Success) { - return BadAlloc; - } - - bzero(&nn,sizeof(xkbNamesNotify)); - nn.changed= stuff->which; - tmp = (CARD32 *)&stuff[1]; - if (stuff->which&XkbKeycodesNameMask) - names->keycodes= *tmp++; - if (stuff->which&XkbGeometryNameMask) - names->geometry= *tmp++; - if (stuff->which&XkbSymbolsNameMask) - names->symbols= *tmp++; - if (stuff->which&XkbPhysSymbolsNameMask) - names->phys_symbols= *tmp++; - if (stuff->which&XkbTypesNameMask) - names->types= *tmp++; - if (stuff->which&XkbCompatNameMask) - names->compat= *tmp++; - if ((stuff->which&XkbKeyTypeNamesMask)&&(stuff->nTypes>0)) { - register unsigned i; - register XkbKeyTypePtr type; - - type= &xkb->map->types[stuff->firstType]; - for (i=0;i<stuff->nTypes;i++,type++) { - type->name= *tmp++; - } - nn.firstType= stuff->firstType; - nn.nTypes= stuff->nTypes; - } - if (stuff->which&XkbKTLevelNamesMask) { - register XkbKeyTypePtr type; - register unsigned i; - CARD8 *width; - - width = (CARD8 *)tmp; - tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels)); - type= &xkb->map->types[stuff->firstKTLevel]; - for (i=0;i<stuff->nKTLevels;i++,type++) { - if (width[i]>0) { - if (type->level_names) { - register unsigned n; - for (n=0;n<width[i];n++) { - type->level_names[n]= tmp[n]; - } - } - tmp+= width[i]; - } - } - nn.firstLevelName= 0; - nn.nLevelNames= stuff->nTypes; - } - if (stuff->which&XkbIndicatorNamesMask) { - tmp= _XkbCopyMaskedAtoms(tmp,names->indicators,XkbNumIndicators, - stuff->indicators); - nn.changedIndicators= stuff->indicators; - } - if (stuff->which&XkbVirtualModNamesMask) { - tmp= _XkbCopyMaskedAtoms(tmp,names->vmods,XkbNumVirtualMods, - stuff->virtualMods); - nn.changedVirtualMods= stuff->virtualMods; - } - if (stuff->which&XkbGroupNamesMask) { - tmp= _XkbCopyMaskedAtoms(tmp,names->groups,XkbNumKbdGroups, - stuff->groupNames); - nn.changedVirtualMods= stuff->groupNames; - } - if (stuff->which&XkbKeyNamesMask) { - memcpy((char*)&names->keys[stuff->firstKey],(char *)tmp, - stuff->nKeys*XkbKeyNameLength); - tmp+= stuff->nKeys; - nn.firstKey= stuff->firstKey; - nn.nKeys= stuff->nKeys; - } - if (stuff->which&XkbKeyAliasesMask) { - if (stuff->nKeyAliases>0) { - register int na= stuff->nKeyAliases; - if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,na)!=Success) - return BadAlloc; - memcpy((char *)names->key_aliases,(char *)tmp, - stuff->nKeyAliases*sizeof(XkbKeyAliasRec)); - tmp+= stuff->nKeyAliases*2; - } - else if (names->key_aliases!=NULL) { - xfree(names->key_aliases); - names->key_aliases= NULL; - names->num_key_aliases= 0; - } - nn.nAliases= names->num_key_aliases; - } - if (stuff->which&XkbRGNamesMask) { - if (stuff->nRadioGroups>0) { - register unsigned i,nrg; - nrg= stuff->nRadioGroups; - if (XkbAllocNames(xkb,XkbRGNamesMask,nrg,0)!=Success) - return BadAlloc; - - for (i=0;i<stuff->nRadioGroups;i++) { - names->radio_groups[i]= tmp[i]; - } - tmp+= stuff->nRadioGroups; - } - else if (names->radio_groups) { - xfree(names->radio_groups); - names->radio_groups= NULL; - names->num_rg= 0; - } - nn.nRadioGroups= names->num_rg; - } - if (nn.changed) { - Bool needExtEvent; - needExtEvent= (nn.changed&XkbIndicatorNamesMask)!=0; - XkbSendNamesNotify(dev,&nn); - if (needExtEvent) { - XkbSrvLedInfoPtr sli; - xkbExtensionDeviceNotify edev; - register int i; - register unsigned bit; - - sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId, - XkbXI_IndicatorsMask); - sli->namesPresent= 0; - for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { - if (names->indicators[i]!=None) - sli->namesPresent|= bit; - } - bzero(&edev,sizeof(xkbExtensionDeviceNotify)); - edev.reason= XkbXI_IndicatorNamesMask; - edev.ledClass= KbdFeedbackClass; - edev.ledID= dev->kbdfeed->ctrl.id; - edev.ledsDefined= sli->namesPresent|sli->mapsPresent; - edev.ledState= sli->effectiveState; - edev.firstBtn= 0; - edev.nBtns= 0; - edev.supported= XkbXI_AllFeaturesMask; - edev.unsupported= 0; - XkbSendExtensionDeviceNotify(dev,client,&edev); - } - } - return Success; -} - -int -ProcXkbSetNames(ClientPtr client) -{ - DeviceIntPtr dev; - CARD32 *tmp; - Atom bad; - int rc; - - REQUEST(xkbSetNamesReq); - REQUEST_AT_LEAST_SIZE(xkbSetNamesReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); - CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask); - - /* check device-independent stuff */ - tmp = (CARD32 *)&stuff[1]; - - if (stuff->which&XkbKeycodesNameMask) { - tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); - if (!tmp) { - client->errorValue = bad; - return BadAtom; - } - } - if (stuff->which&XkbGeometryNameMask) { - tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); - if (!tmp) { - client->errorValue = bad; - return BadAtom; - } - } - if (stuff->which&XkbSymbolsNameMask) { - tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); - if (!tmp) { - client->errorValue = bad; - return BadAtom; - } - } - if (stuff->which&XkbPhysSymbolsNameMask) { - tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); - if (!tmp) { - client->errorValue= bad; - return BadAtom; - } - } - if (stuff->which&XkbTypesNameMask) { - tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); - if (!tmp) { - client->errorValue = bad; - return BadAtom; - } - } - if (stuff->which&XkbCompatNameMask) { - tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad); - if (!tmp) { - client->errorValue = bad; - return BadAtom; - } - } - - /* start of device-dependent tests */ - rc = _XkbSetNamesCheck(client, dev, stuff, tmp); - if (rc != Success) - return rc; - - if (stuff->deviceSpec == XkbUseCoreKbd) - { - DeviceIntPtr other; - for (other = inputInfo.devices; other; other = other->next) - { - if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev)) - { - - rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); - if (rc == Success) - { - rc = _XkbSetNamesCheck(client, other, stuff, tmp); - if (rc != Success) - return rc; - } - } - } - } - - /* everything is okay -- update names */ - - rc = _XkbSetNames(client, dev, stuff); - if (rc != Success) - return rc; - - if (stuff->deviceSpec == XkbUseCoreKbd) - { - DeviceIntPtr other; - for (other = inputInfo.devices; other; other = other->next) - { - if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev)) - { - - rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); - if (rc == Success) - _XkbSetNames(client, other, stuff); - } - } - } - - /* everything is okay -- update names */ - - return client->noClientException; -} - -/***====================================================================***/ - -#include "xkbgeom.h" - -#define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4) - -static char * -XkbWriteCountedString(char *wire,char *str,Bool swap) -{ - CARD16 len,*pLen; - - if (!str) - return wire; - - len= strlen(str); - pLen= (CARD16 *)wire; - *pLen= len; - if (swap) { - register int n; - swaps(pLen,n); - } - memcpy(&wire[2],str,len); - wire+= ((2+len+3)/4)*4; - return wire; -} - -static int -XkbSizeGeomProperties(XkbGeometryPtr geom) -{ -register int i,size; -XkbPropertyPtr prop; - - for (size=i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { - size+= XkbSizeCountedString(prop->name); - size+= XkbSizeCountedString(prop->value); - } - return size; -} - -static char * -XkbWriteGeomProperties(char *wire,XkbGeometryPtr geom,Bool swap) -{ -register int i; -register XkbPropertyPtr prop; - - for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) { - wire= XkbWriteCountedString(wire,prop->name,swap); - wire= XkbWriteCountedString(wire,prop->value,swap); - } - return wire; -} - -static int -XkbSizeGeomKeyAliases(XkbGeometryPtr geom) -{ - return geom->num_key_aliases*(2*XkbKeyNameLength); -} - -static char * -XkbWriteGeomKeyAliases(char *wire,XkbGeometryPtr geom,Bool swap) -{ -register int sz; - - sz= geom->num_key_aliases*(XkbKeyNameLength*2); - if (sz>0) { - memcpy(wire,(char *)geom->key_aliases,sz); - wire+= sz; - } - return wire; -} - -static int -XkbSizeGeomColors(XkbGeometryPtr geom) -{ -register int i,size; -register XkbColorPtr color; - - for (i=size=0,color=geom->colors;i<geom->num_colors;i++,color++) { - size+= XkbSizeCountedString(color->spec); - } - return size; -} - -static char * -XkbWriteGeomColors(char *wire,XkbGeometryPtr geom,Bool swap) -{ -register int i; -register XkbColorPtr color; - - for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) { - wire= XkbWriteCountedString(wire,color->spec,swap); - } - return wire; -} - -static int -XkbSizeGeomShapes(XkbGeometryPtr geom) -{ -register int i,size; -register XkbShapePtr shape; - - for (i=size=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { - register int n; - register XkbOutlinePtr ol; - size+= SIZEOF(xkbShapeWireDesc); - for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) { - size+= SIZEOF(xkbOutlineWireDesc); - size+= ol->num_points*SIZEOF(xkbPointWireDesc); - } - } - return size; -} - -static char * -XkbWriteGeomShapes(char *wire,XkbGeometryPtr geom,Bool swap) -{ -int i; -XkbShapePtr shape; -xkbShapeWireDesc * shapeWire; - - for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) { - register int o; - XkbOutlinePtr ol; - xkbOutlineWireDesc * olWire; - shapeWire= (xkbShapeWireDesc *)wire; - shapeWire->name= shape->name; - shapeWire->nOutlines= shape->num_outlines; - if (shape->primary!=NULL) - shapeWire->primaryNdx= XkbOutlineIndex(shape,shape->primary); - else shapeWire->primaryNdx= XkbNoShape; - if (shape->approx!=NULL) - shapeWire->approxNdx= XkbOutlineIndex(shape,shape->approx); - else shapeWire->approxNdx= XkbNoShape; - if (swap) { - register int n; - swapl(&shapeWire->name,n); - } - wire= (char *)&shapeWire[1]; - for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) { - register int p; - XkbPointPtr pt; - xkbPointWireDesc * ptWire; - olWire= (xkbOutlineWireDesc *)wire; - olWire->nPoints= ol->num_points; - olWire->cornerRadius= ol->corner_radius; - wire= (char *)&olWire[1]; - ptWire= (xkbPointWireDesc *)wire; - for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) { - ptWire[p].x= pt->x; - ptWire[p].y= pt->y; - if (swap) { - register int n; - swaps(&ptWire[p].x,n); - swaps(&ptWire[p].y,n); - } - } - wire= (char *)&ptWire[ol->num_points]; - } - } - return wire; -} - -static int -XkbSizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad) -{ -register int i,size; - - for (i=size=0;i<num_doodads;i++,doodad++) { - size+= SIZEOF(xkbAnyDoodadWireDesc); - if (doodad->any.type==XkbTextDoodad) { - size+= XkbSizeCountedString(doodad->text.text); - size+= XkbSizeCountedString(doodad->text.font); - } - else if (doodad->any.type==XkbLogoDoodad) { - size+= XkbSizeCountedString(doodad->logo.logo_name); - } - } - return size; -} - -static char * -XkbWriteGeomDoodads(char *wire,int num_doodads,XkbDoodadPtr doodad,Bool swap) -{ -register int i; -xkbDoodadWireDesc * doodadWire; - - for (i=0;i<num_doodads;i++,doodad++) { - doodadWire= (xkbDoodadWireDesc *)wire; - wire= (char *)&doodadWire[1]; - bzero(doodadWire,SIZEOF(xkbDoodadWireDesc)); - doodadWire->any.name= doodad->any.name; - doodadWire->any.type= doodad->any.type; - doodadWire->any.priority= doodad->any.priority; - doodadWire->any.top= doodad->any.top; - doodadWire->any.left= doodad->any.left; - if (swap) { - register int n; - swapl(&doodadWire->any.name,n); - swaps(&doodadWire->any.top,n); - swaps(&doodadWire->any.left,n); - } - switch (doodad->any.type) { - case XkbOutlineDoodad: - case XkbSolidDoodad: - doodadWire->shape.angle= doodad->shape.angle; - doodadWire->shape.colorNdx= doodad->shape.color_ndx; - doodadWire->shape.shapeNdx= doodad->shape.shape_ndx; - if (swap) { - register int n; - swaps(&doodadWire->shape.angle,n); - } - break; - case XkbTextDoodad: - doodadWire->text.angle= doodad->text.angle; - doodadWire->text.width= doodad->text.width; - doodadWire->text.height= doodad->text.height; - doodadWire->text.colorNdx= doodad->text.color_ndx; - if (swap) { - register int n; - swaps(&doodadWire->text.angle,n); - swaps(&doodadWire->text.width,n); - swaps(&doodadWire->text.height,n); - } - wire= XkbWriteCountedString(wire,doodad->text.text,swap); - wire= XkbWriteCountedString(wire,doodad->text.font,swap); - break; - case XkbIndicatorDoodad: - doodadWire->indicator.shapeNdx= doodad->indicator.shape_ndx; - doodadWire->indicator.onColorNdx=doodad->indicator.on_color_ndx; - doodadWire->indicator.offColorNdx= - doodad->indicator.off_color_ndx; - break; - case XkbLogoDoodad: - doodadWire->logo.angle= doodad->logo.angle; - doodadWire->logo.colorNdx= doodad->logo.color_ndx; - doodadWire->logo.shapeNdx= doodad->logo.shape_ndx; - wire= XkbWriteCountedString(wire,doodad->logo.logo_name,swap); - break; - default: - ErrorF("[xkb] Unknown doodad type %d in XkbWriteGeomDoodads\n", - doodad->any.type); - ErrorF("[xkb] Ignored\n"); - break; - } - } - return wire; -} - -static char * -XkbWriteGeomOverlay(char *wire,XkbOverlayPtr ol,Bool swap) -{ -register int r; -XkbOverlayRowPtr row; -xkbOverlayWireDesc * olWire; - - olWire= (xkbOverlayWireDesc *)wire; - olWire->name= ol->name; - olWire->nRows= ol->num_rows; - if (swap) { - register int n; - swapl(&olWire->name,n); - } - wire= (char *)&olWire[1]; - for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { - unsigned int k; - XkbOverlayKeyPtr key; - xkbOverlayRowWireDesc * rowWire; - rowWire= (xkbOverlayRowWireDesc *)wire; - rowWire->rowUnder= row->row_under; - rowWire->nKeys= row->num_keys; - wire= (char *)&rowWire[1]; - for (k=0,key=row->keys;k<row->num_keys;k++,key++) { - xkbOverlayKeyWireDesc * keyWire; - keyWire= (xkbOverlayKeyWireDesc *)wire; - memcpy(keyWire->over,key->over.name,XkbKeyNameLength); - memcpy(keyWire->under,key->under.name,XkbKeyNameLength); - wire= (char *)&keyWire[1]; - } - } - return wire; -} - -static int -XkbSizeGeomSections(XkbGeometryPtr geom) -{ -register int i,size; -XkbSectionPtr section; - - for (i=size=0,section=geom->sections;i<geom->num_sections;i++,section++) { - size+= SIZEOF(xkbSectionWireDesc); - if (section->rows) { - int r; - XkbRowPtr row; - for (r=0,row=section->rows;r<section->num_rows;row++,r++) { - size+= SIZEOF(xkbRowWireDesc); - size+= row->num_keys*SIZEOF(xkbKeyWireDesc); - } - } - if (section->doodads) - size+= XkbSizeGeomDoodads(section->num_doodads,section->doodads); - if (section->overlays) { - int o; - XkbOverlayPtr ol; - for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) { - int r; - XkbOverlayRowPtr row; - size+= SIZEOF(xkbOverlayWireDesc); - for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) { - size+= SIZEOF(xkbOverlayRowWireDesc); - size+= row->num_keys*SIZEOF(xkbOverlayKeyWireDesc); - } - } - } - } - return size; -} - -static char * -XkbWriteGeomSections(char *wire,XkbGeometryPtr geom,Bool swap) -{ -register int i; -XkbSectionPtr section; -xkbSectionWireDesc * sectionWire; - - for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) { - sectionWire= (xkbSectionWireDesc *)wire; - sectionWire->name= section->name; - sectionWire->top= section->top; - sectionWire->left= section->left; - sectionWire->width= section->width; - sectionWire->height= section->height; - sectionWire->angle= section->angle; - sectionWire->priority= section->priority; - sectionWire->nRows= section->num_rows; - sectionWire->nDoodads= section->num_doodads; - sectionWire->nOverlays= section->num_overlays; - sectionWire->pad= 0; - if (swap) { - register int n; - swapl(§ionWire->name,n); - swaps(§ionWire->top,n); - swaps(§ionWire->left,n); - swaps(§ionWire->width,n); - swaps(§ionWire->height,n); - swaps(§ionWire->angle,n); - } - wire= (char *)§ionWire[1]; - if (section->rows) { - int r; - XkbRowPtr row; - xkbRowWireDesc * rowWire; - for (r=0,row=section->rows;r<section->num_rows;r++,row++) { - rowWire= (xkbRowWireDesc *)wire; - rowWire->top= row->top; - rowWire->left= row->left; - rowWire->nKeys= row->num_keys; - rowWire->vertical= row->vertical; - rowWire->pad= 0; - if (swap) { - register int n; - swaps(&rowWire->top,n); - swaps(&rowWire->left,n); - } - wire= (char *)&rowWire[1]; - if (row->keys) { - int k; - XkbKeyPtr key; - xkbKeyWireDesc * keyWire; - keyWire= (xkbKeyWireDesc *)wire; - for (k=0,key=row->keys;k<row->num_keys;k++,key++) { - memcpy(keyWire[k].name,key->name.name,XkbKeyNameLength); - keyWire[k].gap= key->gap; - keyWire[k].shapeNdx= key->shape_ndx; - keyWire[k].colorNdx= key->color_ndx; - if (swap) { - register int n; - swaps(&keyWire[k].gap,n); - } - } - wire= (char *)&keyWire[row->num_keys]; - } - } - } - if (section->doodads) { - wire= XkbWriteGeomDoodads(wire, - section->num_doodads,section->doodads, - swap); - } - if (section->overlays) { - register int o; - for (o=0;o<section->num_overlays;o++) { - wire= XkbWriteGeomOverlay(wire,§ion->overlays[o],swap); - } - } - } - return wire; -} - -static Status -XkbComputeGetGeometryReplySize( XkbGeometryPtr geom, - xkbGetGeometryReply * rep, - Atom name) -{ -int len; - - if (geom!=NULL) { - len= XkbSizeCountedString(geom->label_font); - len+= XkbSizeGeomProperties(geom); - len+= XkbSizeGeomColors(geom); - len+= XkbSizeGeomShapes(geom); - len+= XkbSizeGeomSections(geom); - len+= XkbSizeGeomDoodads(geom->num_doodads,geom->doodads); - len+= XkbSizeGeomKeyAliases(geom); - rep->length= len/4; - rep->found= TRUE; - rep->name= geom->name; - rep->widthMM= geom->width_mm; - rep->heightMM= geom->height_mm; - rep->nProperties= geom->num_properties; - rep->nColors= geom->num_colors; - rep->nShapes= geom->num_shapes; - rep->nSections= geom->num_sections; - rep->nDoodads= geom->num_doodads; - rep->nKeyAliases= geom->num_key_aliases; - rep->baseColorNdx= XkbGeomColorIndex(geom,geom->base_color); - rep->labelColorNdx= XkbGeomColorIndex(geom,geom->label_color); - } - else { - rep->length= 0; - rep->found= FALSE; - rep->name= name; - rep->widthMM= rep->heightMM= 0; - rep->nProperties= rep->nColors= rep->nShapes= 0; - rep->nSections= rep->nDoodads= 0; - rep->nKeyAliases= 0; - rep->labelColorNdx= rep->baseColorNdx= 0; - } - return Success; -} - -static int -XkbSendGeometry( ClientPtr client, - XkbGeometryPtr geom, - xkbGetGeometryReply * rep, - Bool freeGeom) -{ - char *desc,*start; - int len; - - if (geom!=NULL) { - len= rep->length*4; - start= desc= xalloc(len); - if (!start) - return BadAlloc; - desc= XkbWriteCountedString(desc,geom->label_font,client->swapped); - if ( rep->nProperties>0 ) - desc = XkbWriteGeomProperties(desc,geom,client->swapped); - if ( rep->nColors>0 ) - desc = XkbWriteGeomColors(desc,geom,client->swapped); - if ( rep->nShapes>0 ) - desc = XkbWriteGeomShapes(desc,geom,client->swapped); - if ( rep->nSections>0 ) - desc = XkbWriteGeomSections(desc,geom,client->swapped); - if ( rep->nDoodads>0 ) - desc = XkbWriteGeomDoodads(desc,geom->num_doodads,geom->doodads, - client->swapped); - if ( rep->nKeyAliases>0 ) - desc = XkbWriteGeomKeyAliases(desc,geom,client->swapped); - if ((desc-start)!=(len)) { - ErrorF("[xkb] BOGUS LENGTH in XkbSendGeometry, expected %d, got %ld\n", - len, (unsigned long)(desc-start)); - } - } - else { - len= 0; - start= NULL; - } - if (client->swapped) { - register int n; - swaps(&rep->sequenceNumber,n); - swapl(&rep->length,n); - swapl(&rep->name,n); - swaps(&rep->widthMM,n); - swaps(&rep->heightMM,n); - swaps(&rep->nProperties,n); - swaps(&rep->nColors,n); - swaps(&rep->nShapes,n); - swaps(&rep->nSections,n); - swaps(&rep->nDoodads,n); - swaps(&rep->nKeyAliases,n); - } - WriteToClient(client, SIZEOF(xkbGetGeometryReply), (char *)rep); - if (len>0) - WriteToClient(client, len, start); - if (start!=NULL) - xfree((char *)start); - if (freeGeom) - XkbFreeGeometry(geom,XkbGeomAllMask,TRUE); - return client->noClientException; -} - -int -ProcXkbGetGeometry(ClientPtr client) -{ - DeviceIntPtr dev; - xkbGetGeometryReply rep; - XkbGeometryPtr geom; - Bool shouldFree; - Status status; - - REQUEST(xkbGetGeometryReq); - REQUEST_SIZE_MATCH(xkbGetGeometryReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); - CHK_ATOM_OR_NONE(stuff->name); - - geom= XkbLookupNamedGeometry(dev,stuff->name,&shouldFree); - rep.type= X_Reply; - rep.deviceID= dev->id; - rep.sequenceNumber= client->sequence; - rep.length= 0; - status= XkbComputeGetGeometryReplySize(geom,&rep,stuff->name); - if (status!=Success) - return status; - else return XkbSendGeometry(client,geom,&rep,shouldFree); -} - -/***====================================================================***/ - -static char * -_GetCountedString(char **wire_inout,Bool swap) -{ -char * wire,*str; -CARD16 len,*plen; - - wire= *wire_inout; - plen= (CARD16 *)wire; - if (swap) { - register int n; - swaps(plen,n); - } - len= *plen; - str= xalloc(len+1); - if (str) { - memcpy(str,&wire[2],len); - str[len]= '\0'; - } - wire+= XkbPaddedSize(len+2); - *wire_inout= wire; - return str; -} - -static Status -_CheckSetDoodad( char ** wire_inout, - XkbGeometryPtr geom, - XkbSectionPtr section, - ClientPtr client) -{ -char * wire; -xkbDoodadWireDesc * dWire; -XkbDoodadPtr doodad; - - dWire= (xkbDoodadWireDesc *)(*wire_inout); - wire= (char *)&dWire[1]; - if (client->swapped) { - register int n; - swapl(&dWire->any.name,n); - swaps(&dWire->any.top,n); - swaps(&dWire->any.left,n); - swaps(&dWire->any.angle,n); - } - CHK_ATOM_ONLY(dWire->any.name); - doodad= XkbAddGeomDoodad(geom,section,dWire->any.name); - if (!doodad) - return BadAlloc; - doodad->any.type= dWire->any.type; - doodad->any.priority= dWire->any.priority; - doodad->any.top= dWire->any.top; - doodad->any.left= dWire->any.left; - doodad->any.angle= dWire->any.angle; - switch (doodad->any.type) { - case XkbOutlineDoodad: - case XkbSolidDoodad: - if (dWire->shape.colorNdx>=geom->num_colors) { - client->errorValue= _XkbErrCode3(0x40,geom->num_colors, - dWire->shape.colorNdx); - return BadMatch; - } - if (dWire->shape.shapeNdx>=geom->num_shapes) { - client->errorValue= _XkbErrCode3(0x41,geom->num_shapes, - dWire->shape.shapeNdx); - return BadMatch; - } - doodad->shape.color_ndx= dWire->shape.colorNdx; - doodad->shape.shape_ndx= dWire->shape.shapeNdx; - break; - case XkbTextDoodad: - if (dWire->text.colorNdx>=geom->num_colors) { - client->errorValue= _XkbErrCode3(0x42,geom->num_colors, - dWire->text.colorNdx); - return BadMatch; - } - if (client->swapped) { - register int n; - swaps(&dWire->text.width,n); - swaps(&dWire->text.height,n); - } - doodad->text.width= dWire->text.width; - doodad->text.height= dWire->text.height; - doodad->text.color_ndx= dWire->text.colorNdx; - doodad->text.text= _GetCountedString(&wire,client->swapped); - doodad->text.font= _GetCountedString(&wire,client->swapped); - break; - case XkbIndicatorDoodad: - if (dWire->indicator.onColorNdx>=geom->num_colors) { - client->errorValue= _XkbErrCode3(0x43,geom->num_colors, - dWire->indicator.onColorNdx); - return BadMatch; - } - if (dWire->indicator.offColorNdx>=geom->num_colors) { - client->errorValue= _XkbErrCode3(0x44,geom->num_colors, - dWire->indicator.offColorNdx); - return BadMatch; - } - if (dWire->indicator.shapeNdx>=geom->num_shapes) { - client->errorValue= _XkbErrCode3(0x45,geom->num_shapes, - dWire->indicator.shapeNdx); - return BadMatch; - } - doodad->indicator.shape_ndx= dWire->indicator.shapeNdx; - doodad->indicator.on_color_ndx= dWire->indicator.onColorNdx; - doodad->indicator.off_color_ndx= dWire->indicator.offColorNdx; - break; - case XkbLogoDoodad: - if (dWire->logo.colorNdx>=geom->num_colors) { - client->errorValue= _XkbErrCode3(0x46,geom->num_colors, - dWire->logo.colorNdx); - return BadMatch; - } - if (dWire->logo.shapeNdx>=geom->num_shapes) { - client->errorValue= _XkbErrCode3(0x47,geom->num_shapes, - dWire->logo.shapeNdx); - return BadMatch; - } - doodad->logo.color_ndx= dWire->logo.colorNdx; - doodad->logo.shape_ndx= dWire->logo.shapeNdx; - doodad->logo.logo_name= _GetCountedString(&wire,client->swapped); - break; - default: - client->errorValue= _XkbErrCode2(0x4F,dWire->any.type); - return BadValue; - } - *wire_inout= wire; - return Success; -} - -static Status -_CheckSetOverlay( char ** wire_inout, - XkbGeometryPtr geom, - XkbSectionPtr section, - ClientPtr client) -{ -register int r; -char * wire; -XkbOverlayPtr ol; -xkbOverlayWireDesc * olWire; -xkbOverlayRowWireDesc * rWire; - - wire= *wire_inout; - olWire= (xkbOverlayWireDesc *)wire; - if (client->swapped) { - register int n; - swapl(&olWire->name,n); - } - CHK_ATOM_ONLY(olWire->name); - ol= XkbAddGeomOverlay(section,olWire->name,olWire->nRows); - rWire= (xkbOverlayRowWireDesc *)&olWire[1]; - for (r=0;r<olWire->nRows;r++) { - register int k; - xkbOverlayKeyWireDesc * kWire; - XkbOverlayRowPtr row; - - if (rWire->rowUnder>section->num_rows) { - client->errorValue= _XkbErrCode4(0x20,r,section->num_rows, - rWire->rowUnder); - return BadMatch; - } - row= XkbAddGeomOverlayRow(ol,rWire->rowUnder,rWire->nKeys); - kWire= (xkbOverlayKeyWireDesc *)&rWire[1]; - for (k=0;k<rWire->nKeys;k++,kWire++) { - if (XkbAddGeomOverlayKey(ol,row, - (char *)kWire->over,(char *)kWire->under)==NULL) { - client->errorValue= _XkbErrCode3(0x21,r,k); - return BadMatch; - } - } - rWire= (xkbOverlayRowWireDesc *)kWire; - } - olWire= (xkbOverlayWireDesc *)rWire; - wire= (char *)olWire; - *wire_inout= wire; - return Success; -} - -static Status -_CheckSetSections( XkbGeometryPtr geom, - xkbSetGeometryReq * req, - char ** wire_inout, - ClientPtr client) -{ -Status status; -register int s; -char * wire; -xkbSectionWireDesc * sWire; -XkbSectionPtr section; - - wire= *wire_inout; - if (req->nSections<1) - return Success; - sWire= (xkbSectionWireDesc *)wire; - for (s=0;s<req->nSections;s++) { - register int r; - xkbRowWireDesc * rWire; - if (client->swapped) { - register int n; - swapl(&sWire->name,n); - swaps(&sWire->top,n); - swaps(&sWire->left,n); - swaps(&sWire->width,n); - swaps(&sWire->height,n); - swaps(&sWire->angle,n); - } - CHK_ATOM_ONLY(sWire->name); - section= XkbAddGeomSection(geom,sWire->name,sWire->nRows, - sWire->nDoodads,sWire->nOverlays); - if (!section) - return BadAlloc; - section->priority= sWire->priority; - section->top= sWire->top; - section->left= sWire->left; - section->width= sWire->width; - section->height= sWire->height; - section->angle= sWire->angle; - rWire= (xkbRowWireDesc *)&sWire[1]; - for (r=0;r<sWire->nRows;r++) { - register int k; - XkbRowPtr row; - xkbKeyWireDesc * kWire; - if (client->swapped) { - register int n; - swaps(&rWire->top,n); - swaps(&rWire->left,n); - } - row= XkbAddGeomRow(section,rWire->nKeys); - if (!row) - return BadAlloc; - row->top= rWire->top; - row->left= rWire->left; - row->vertical= rWire->vertical; - kWire= (xkbKeyWireDesc *)&rWire[1]; - for (k=0;k<rWire->nKeys;k++) { - XkbKeyPtr key; - key= XkbAddGeomKey(row); - if (!key) - return BadAlloc; - memcpy(key->name.name,kWire[k].name,XkbKeyNameLength); - key->gap= kWire[k].gap; - key->shape_ndx= kWire[k].shapeNdx; - key->color_ndx= kWire[k].colorNdx; - if (key->shape_ndx>=geom->num_shapes) { - client->errorValue= _XkbErrCode3(0x10,key->shape_ndx, - geom->num_shapes); - return BadMatch; - } - if (key->color_ndx>=geom->num_colors) { - client->errorValue= _XkbErrCode3(0x11,key->color_ndx, - geom->num_colors); - return BadMatch; - } - } - rWire= (xkbRowWireDesc *)&kWire[rWire->nKeys]; - } - wire= (char *)rWire; - if (sWire->nDoodads>0) { - register int d; - for (d=0;d<sWire->nDoodads;d++) { - status=_CheckSetDoodad(&wire,geom,section,client); - if (status!=Success) - return status; - } - } - if (sWire->nOverlays>0) { - register int o; - for (o=0;o<sWire->nOverlays;o++) { - status= _CheckSetOverlay(&wire,geom,section,client); - if (status!=Success) - return status; - } - } - sWire= (xkbSectionWireDesc *)wire; - } - wire= (char *)sWire; - *wire_inout= wire; - return Success; -} - -static Status -_CheckSetShapes( XkbGeometryPtr geom, - xkbSetGeometryReq * req, - char ** wire_inout, - ClientPtr client) -{ -register int i; -char * wire; - - wire= *wire_inout; - if (req->nShapes<1) { - client->errorValue= _XkbErrCode2(0x06,req->nShapes); - return BadValue; - } - else { - xkbShapeWireDesc * shapeWire; - XkbShapePtr shape; - register int o; - shapeWire= (xkbShapeWireDesc *)wire; - for (i=0;i<req->nShapes;i++) { - xkbOutlineWireDesc * olWire; - XkbOutlinePtr ol; - shape= XkbAddGeomShape(geom,shapeWire->name,shapeWire->nOutlines); - if (!shape) - return BadAlloc; - olWire= (xkbOutlineWireDesc *)(&shapeWire[1]); - for (o=0;o<shapeWire->nOutlines;o++) { - register int p; - XkbPointPtr pt; - xkbPointWireDesc * ptWire; - - ol= XkbAddGeomOutline(shape,olWire->nPoints); - if (!ol) - return BadAlloc; - ol->corner_radius= olWire->cornerRadius; - ptWire= (xkbPointWireDesc *)&olWire[1]; - for (p=0,pt=ol->points;p<olWire->nPoints;p++,pt++) { - pt->x= ptWire[p].x; - pt->y= ptWire[p].y; - if (client->swapped) { - register int n; - swaps(&pt->x,n); - swaps(&pt->y,n); - } - } - ol->num_points= olWire->nPoints; - olWire= (xkbOutlineWireDesc *)(&ptWire[olWire->nPoints]); - } - if (shapeWire->primaryNdx!=XkbNoShape) - shape->primary= &shape->outlines[shapeWire->primaryNdx]; - if (shapeWire->approxNdx!=XkbNoShape) - shape->approx= &shape->outlines[shapeWire->approxNdx]; - shapeWire= (xkbShapeWireDesc *)olWire; - } - wire= (char *)shapeWire; - } - if (geom->num_shapes!=req->nShapes) { - client->errorValue= _XkbErrCode3(0x07,geom->num_shapes,req->nShapes); - return BadMatch; - } - - *wire_inout= wire; - return Success; -} - -static Status -_CheckSetGeom( XkbGeometryPtr geom, - xkbSetGeometryReq * req, - ClientPtr client) -{ -register int i; -Status status; -char * wire; - - wire= (char *)&req[1]; - geom->label_font= _GetCountedString(&wire,client->swapped); - - for (i=0;i<req->nProperties;i++) { - char *name,*val; - name= _GetCountedString(&wire,client->swapped); - if (!name) - return BadAlloc; - val= _GetCountedString(&wire,client->swapped); - if (!val) { - xfree(name); - return BadAlloc; - } - if (XkbAddGeomProperty(geom,name,val)==NULL) { - xfree(name); - xfree(val); - return BadAlloc; - } - xfree(name); - xfree(val); - } - - if (req->nColors<2) { - client->errorValue= _XkbErrCode3(0x01,2,req->nColors); - return BadValue; - } - if (req->baseColorNdx>req->nColors) { - client->errorValue=_XkbErrCode3(0x03,req->nColors,req->baseColorNdx); - return BadMatch; - } - if (req->labelColorNdx>req->nColors) { - client->errorValue= _XkbErrCode3(0x03,req->nColors,req->labelColorNdx); - return BadMatch; - } - if (req->labelColorNdx==req->baseColorNdx) { - client->errorValue= _XkbErrCode3(0x04,req->baseColorNdx, - req->labelColorNdx); - return BadMatch; - } - - for (i=0;i<req->nColors;i++) { - char *name; - name= _GetCountedString(&wire,client->swapped); - if (!name) - return BadAlloc; - if (!XkbAddGeomColor(geom,name,geom->num_colors)) { - xfree(name); - return BadAlloc; - } - xfree(name); - } - if (req->nColors!=geom->num_colors) { - client->errorValue= _XkbErrCode3(0x05,req->nColors,geom->num_colors); - return BadMatch; - } - geom->label_color= &geom->colors[req->labelColorNdx]; - geom->base_color= &geom->colors[req->baseColorNdx]; - - if ((status=_CheckSetShapes(geom,req,&wire,client))!=Success) - return status; - - if ((status=_CheckSetSections(geom,req,&wire,client))!=Success) - return status; - - for (i=0;i<req->nDoodads;i++) { - status=_CheckSetDoodad(&wire,geom,NULL,client); - if (status!=Success) - return status; - } - - for (i=0;i<req->nKeyAliases;i++) { - if (XkbAddGeomKeyAlias(geom,&wire[XkbKeyNameLength],wire)==NULL) - return BadAlloc; - wire+= 2*XkbKeyNameLength; - } - return Success; -} - -static int -_XkbSetGeometry(ClientPtr client, DeviceIntPtr dev, xkbSetGeometryReq *stuff) -{ - XkbDescPtr xkb; - Bool new_name; - xkbNewKeyboardNotify nkn; - XkbGeometryPtr geom,old; - XkbGeometrySizesRec sizes; - Status status; - - xkb= dev->key->xkbInfo->desc; - old= xkb->geom; - xkb->geom= NULL; - - sizes.which= XkbGeomAllMask; - sizes.num_properties= stuff->nProperties; - sizes.num_colors= stuff->nColors; - sizes.num_shapes= stuff->nShapes; - sizes.num_sections= stuff->nSections; - sizes.num_doodads= stuff->nDoodads; - sizes.num_key_aliases= stuff->nKeyAliases; - if ((status= XkbAllocGeometry(xkb,&sizes))!=Success) { - xkb->geom= old; - return status; - } - geom= xkb->geom; - geom->name= stuff->name; - geom->width_mm= stuff->widthMM; - geom->height_mm= stuff->heightMM; - if ((status= _CheckSetGeom(geom,stuff,client))!=Success) { - XkbFreeGeometry(geom,XkbGeomAllMask,TRUE); - xkb->geom= old; - return status; - } - new_name= (xkb->names->geometry!=geom->name); - xkb->names->geometry= geom->name; - if (old) - XkbFreeGeometry(old,XkbGeomAllMask,TRUE); - if (new_name) { - xkbNamesNotify nn; - bzero(&nn,sizeof(xkbNamesNotify)); - nn.changed= XkbGeometryNameMask; - XkbSendNamesNotify(dev,&nn); - } - nkn.deviceID= nkn.oldDeviceID= dev->id; - nkn.minKeyCode= nkn.oldMinKeyCode= xkb->min_key_code; - nkn.maxKeyCode= nkn.oldMaxKeyCode= xkb->max_key_code; - nkn.requestMajor= XkbReqCode; - nkn.requestMinor= X_kbSetGeometry; - nkn.changed= XkbNKN_GeometryMask; - XkbSendNewKeyboardNotify(dev,&nkn); - return Success; -} - -int -ProcXkbSetGeometry(ClientPtr client) -{ - DeviceIntPtr dev; - int rc; - - REQUEST(xkbSetGeometryReq); - REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); - CHK_ATOM_OR_NONE(stuff->name); - - rc = _XkbSetGeometry(client, dev, stuff); - if (rc != Success) - return rc; - - if (stuff->deviceSpec == XkbUseCoreKbd) - { - DeviceIntPtr other; - for (other = inputInfo.devices; other; other = other->next) - { - if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev)) - { - rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); - if (rc == Success) - _XkbSetGeometry(client, other, stuff); - } - } - } - - return Success; -} - -/***====================================================================***/ - -int -ProcXkbPerClientFlags(ClientPtr client) -{ - DeviceIntPtr dev; - xkbPerClientFlagsReply rep; - XkbInterestPtr interest; - Mask access_mode = DixGetAttrAccess | DixSetAttrAccess; - - REQUEST(xkbPerClientFlagsReq); - REQUEST_SIZE_MATCH(xkbPerClientFlagsReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); - CHK_MASK_LEGAL(0x01,stuff->change,XkbPCF_AllFlagsMask); - CHK_MASK_MATCH(0x02,stuff->change,stuff->value); - - interest = XkbFindClientResource((DevicePtr)dev,client); - memset(&rep, 0, sizeof(xkbPerClientFlagsReply)); - rep.type= X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - if (stuff->change) { - client->xkbClientFlags&= ~stuff->change; - client->xkbClientFlags|= stuff->value; - } - if (stuff->change&XkbPCF_AutoResetControlsMask) { - Bool want; - want= stuff->value&XkbPCF_AutoResetControlsMask; - if (interest && !want) { - interest->autoCtrls= interest->autoCtrlValues= 0; - } - else if (want && (!interest)) { - XID id = FakeClientID(client->index); - AddResource(id,RT_XKBCLIENT,dev); - interest= XkbAddClientResource((DevicePtr)dev,client,id); - if (!interest) - return BadAlloc; - } - if (interest && want ) { - register unsigned affect; - affect= stuff->ctrlsToChange; - - CHK_MASK_LEGAL(0x03,affect,XkbAllBooleanCtrlsMask); - CHK_MASK_MATCH(0x04,affect,stuff->autoCtrls); - CHK_MASK_MATCH(0x05,stuff->autoCtrls,stuff->autoCtrlValues); - - interest->autoCtrls&= ~affect; - interest->autoCtrlValues&= ~affect; - interest->autoCtrls|= stuff->autoCtrls&affect; - interest->autoCtrlValues|= stuff->autoCtrlValues&affect; - } - } - rep.supported = XkbPCF_AllFlagsMask; - rep.value= client->xkbClientFlags&XkbPCF_AllFlagsMask; - if (interest) { - rep.autoCtrls= interest->autoCtrls; - rep.autoCtrlValues= interest->autoCtrlValues; - } - else { - rep.autoCtrls= rep.autoCtrlValues= 0; - } - if ( client->swapped ) { - register int n; - swaps(&rep.sequenceNumber, n); - swapl(&rep.supported,n); - swapl(&rep.value,n); - swapl(&rep.autoCtrls,n); - swapl(&rep.autoCtrlValues,n); - } - WriteToClient(client,SIZEOF(xkbPerClientFlagsReply), (char *)&rep); - return client->noClientException; -} - -/***====================================================================***/ - -/* all latin-1 alphanumerics, plus parens, minus, underscore, slash */ -/* and wildcards */ -static unsigned char componentSpecLegal[] = { - 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87, - 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff -}; - -/* same as above but accepts percent, plus and bar too */ -static unsigned char componentExprLegal[] = { - 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87, - 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff -}; - -static char * -GetComponentSpec(unsigned char **pWire,Bool allowExpr,int *errRtrn) -{ -int len; -register int i; -unsigned char *wire,*str,*tmp,*legal; - - if (allowExpr) legal= &componentExprLegal[0]; - else legal= &componentSpecLegal[0]; - - wire= *pWire; - len= (*(unsigned char *)wire++); - if (len>0) { - str= xcalloc(1, len+1); - if (str) { - tmp= str; - for (i=0;i<len;i++) { - if (legal[(*wire)/8]&(1<<((*wire)%8))) - *tmp++= *wire++; - else wire++; - } - if (tmp!=str) - *tmp++= '\0'; - else { - xfree(str); - str= NULL; - } - } - else { - *errRtrn= BadAlloc; - } - } - else { - str= NULL; - } - *pWire= wire; - return (char *)str; -} - -/***====================================================================***/ - -int -ProcXkbListComponents(ClientPtr client) -{ - DeviceIntPtr dev; - xkbListComponentsReply rep; - unsigned len; - int status; - unsigned char * str; - XkbSrvListInfoRec list; - - REQUEST(xkbListComponentsReq); - REQUEST_AT_LEAST_SIZE(xkbListComponentsReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); - - status= Success; - str= (unsigned char *)&stuff[1]; - bzero(&list,sizeof(XkbSrvListInfoRec)); - list.maxRtrn= stuff->maxNames; - list.pattern[_XkbListKeycodes]= GetComponentSpec(&str,FALSE,&status); - list.pattern[_XkbListTypes]= GetComponentSpec(&str,FALSE,&status); - list.pattern[_XkbListCompat]= GetComponentSpec(&str,FALSE,&status); - list.pattern[_XkbListSymbols]= GetComponentSpec(&str,FALSE,&status); - list.pattern[_XkbListGeometry]= GetComponentSpec(&str,FALSE,&status); - if (status!=Success) - return status; - len= str-((unsigned char *)stuff); - if ((XkbPaddedSize(len)/4)!=stuff->length) - return BadLength; - if ((status=XkbDDXList(dev,&list,client))!=Success) { - if (list.pool) { - xfree(list.pool); - list.pool= NULL; - } - return status; - } - bzero(&rep,sizeof(xkbListComponentsReply)); - rep.type= X_Reply; - rep.deviceID = dev->id; - rep.sequenceNumber = client->sequence; - rep.length = XkbPaddedSize(list.nPool)/4; - rep.nKeymaps = 0; - rep.nKeycodes = list.nFound[_XkbListKeycodes]; - rep.nTypes = list.nFound[_XkbListTypes]; - rep.nCompatMaps = list.nFound[_XkbListCompat]; - rep.nSymbols = list.nFound[_XkbListSymbols]; - rep.nGeometries = list.nFound[_XkbListGeometry]; - rep.extra= 0; - if (list.nTotal>list.maxRtrn) - rep.extra = (list.nTotal-list.maxRtrn); - if (client->swapped) { - register int n; - swaps(&rep.sequenceNumber,n); - swapl(&rep.length,n); - swaps(&rep.nKeymaps,n); - swaps(&rep.nKeycodes,n); - swaps(&rep.nTypes,n); - swaps(&rep.nCompatMaps,n); - swaps(&rep.nSymbols,n); - swaps(&rep.nGeometries,n); - swaps(&rep.extra,n); - } - WriteToClient(client,SIZEOF(xkbListComponentsReply),(char *)&rep); - if (list.nPool && list.pool) { - WriteToClient(client,XkbPaddedSize(list.nPool), (char *)list.pool); - xfree(list.pool); - list.pool= NULL; - } - return client->noClientException; -} - -/***====================================================================***/ - -int -ProcXkbGetKbdByName(ClientPtr client) -{ - DeviceIntPtr dev; - DeviceIntPtr tmpd; - xkbGetKbdByNameReply rep; - xkbGetMapReply mrep; - xkbGetCompatMapReply crep; - xkbGetIndicatorMapReply irep; - xkbGetNamesReply nrep; - xkbGetGeometryReply grep; - XkbComponentNamesRec names; - XkbDescPtr xkb, new; - unsigned char * str; - char mapFile[PATH_MAX]; - unsigned len; - unsigned fwant,fneed,reported; - int status; - Bool geom_changed; - XkbSrvLedInfoPtr old_sli; - XkbSrvLedInfoPtr sli; - Mask access_mode = DixGetAttrAccess | DixManageAccess; - - REQUEST(xkbGetKbdByNameReq); - REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode); - - xkb = dev->key->xkbInfo->desc; - status= Success; - str= (unsigned char *)&stuff[1]; - if (GetComponentSpec(&str,TRUE,&status)) /* keymap, unsupported */ - return BadMatch; - names.keycodes= GetComponentSpec(&str,TRUE,&status); - names.types= GetComponentSpec(&str,TRUE,&status); - names.compat= GetComponentSpec(&str,TRUE,&status); - names.symbols= GetComponentSpec(&str,TRUE,&status); - names.geometry= GetComponentSpec(&str,TRUE,&status); - if (status!=Success) - return status; - len= str-((unsigned char *)stuff); - if ((XkbPaddedSize(len)/4)!=stuff->length) - return BadLength; - - CHK_MASK_LEGAL(0x01,stuff->want,XkbGBN_AllComponentsMask); - CHK_MASK_LEGAL(0x02,stuff->need,XkbGBN_AllComponentsMask); - - if (stuff->load) - fwant= XkbGBN_AllComponentsMask; - else fwant= stuff->want|stuff->need; - if ((!names.compat)&& - (fwant&(XkbGBN_CompatMapMask|XkbGBN_IndicatorMapMask))) { - names.compat= _XkbDupString("%"); - } - if ((!names.types)&&(fwant&(XkbGBN_TypesMask))) { - names.types= _XkbDupString("%"); - } - if ((!names.symbols)&&(fwant&XkbGBN_SymbolsMask)) { - names.symbols= _XkbDupString("%"); - } - geom_changed= ((names.geometry!=NULL)&&(strcmp(names.geometry,"%")!=0)); - if ((!names.geometry)&&(fwant&XkbGBN_GeometryMask)) { - names.geometry= _XkbDupString("%"); - geom_changed= FALSE; - } - - bzero(mapFile,PATH_MAX); - rep.type= X_Reply; - rep.deviceID = dev->id; - rep.sequenceNumber = client->sequence; - rep.length = 0; - rep.minKeyCode = xkb->min_key_code; - rep.maxKeyCode = xkb->max_key_code; - rep.loaded= FALSE; - fwant= XkbConvertGetByNameComponents(TRUE,stuff->want)|XkmVirtualModsMask; - fneed= XkbConvertGetByNameComponents(TRUE,stuff->need); - rep.reported= XkbConvertGetByNameComponents(FALSE,fwant|fneed); - if (stuff->load) { - fneed|= XkmKeymapRequired; - fwant|= XkmKeymapLegal; - } - if ((fwant|fneed)&XkmSymbolsMask) { - fneed|= XkmKeyNamesIndex|XkmTypesIndex; - fwant|= XkmIndicatorsIndex; - } - - /* We pass dev in here so we can get the old names out if needed. */ - rep.found = XkbDDXLoadKeymapByNames(dev,&names,fwant,fneed,&new, - mapFile,PATH_MAX); - rep.newKeyboard= FALSE; - rep.pad1= rep.pad2= rep.pad3= rep.pad4= 0; - - stuff->want|= stuff->need; - if (new==NULL) - rep.reported= 0; - else { - if (stuff->load) - rep.loaded= TRUE; - if (stuff->load || - ((rep.reported&XkbGBN_SymbolsMask) && (new->compat))) { - XkbChangesRec changes; - bzero(&changes,sizeof(changes)); - XkbUpdateDescActions(new, - new->min_key_code,XkbNumKeys(new), - &changes); - } - - if (new->map==NULL) - rep.reported&= ~(XkbGBN_SymbolsMask|XkbGBN_TypesMask); - else if (rep.reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) { - mrep.type= X_Reply; - mrep.deviceID = dev->id; - mrep.sequenceNumber= client->sequence; - mrep.length = ((SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2); - mrep.minKeyCode = new->min_key_code; - mrep.maxKeyCode = new->max_key_code; - mrep.present = 0; - mrep.totalSyms = mrep.totalActs = - mrep.totalKeyBehaviors= mrep.totalKeyExplicit= - mrep.totalModMapKeys= mrep.totalVModMapKeys= 0; - if (rep.reported&(XkbGBN_TypesMask|XkbGBN_ClientSymbolsMask)) { - mrep.present|= XkbKeyTypesMask; - mrep.firstType = 0; - mrep.nTypes = mrep.totalTypes= new->map->num_types; - } - else { - mrep.firstType = mrep.nTypes= 0; - mrep.totalTypes= 0; - } - if (rep.reported&XkbGBN_ClientSymbolsMask) { - mrep.present|= (XkbKeySymsMask|XkbModifierMapMask); - mrep.firstKeySym = mrep.firstModMapKey= new->min_key_code; - mrep.nKeySyms = mrep.nModMapKeys= XkbNumKeys(new); - } - else { - mrep.firstKeySym= mrep.firstModMapKey= 0; - mrep.nKeySyms= mrep.nModMapKeys= 0; - } - if (rep.reported&XkbGBN_ServerSymbolsMask) { - mrep.present|= XkbAllServerInfoMask; - mrep.virtualMods= ~0; - mrep.firstKeyAct = mrep.firstKeyBehavior = - mrep.firstKeyExplicit = new->min_key_code; - mrep.nKeyActs = mrep.nKeyBehaviors = - mrep.nKeyExplicit = XkbNumKeys(new); - mrep.firstVModMapKey= new->min_key_code; - mrep.nVModMapKeys= XkbNumKeys(new); - } - else { - mrep.virtualMods= 0; - mrep.firstKeyAct= mrep.firstKeyBehavior= - mrep.firstKeyExplicit = 0; - mrep.nKeyActs= mrep.nKeyBehaviors= mrep.nKeyExplicit= 0; - } - XkbComputeGetMapReplySize(new,&mrep); - rep.length+= SIZEOF(xGenericReply)/4+mrep.length; - } - if (new->compat==NULL) - rep.reported&= ~XkbGBN_CompatMapMask; - else if (rep.reported&XkbGBN_CompatMapMask) { - crep.type= X_Reply; - crep.deviceID= dev->id; - crep.sequenceNumber= client->sequence; - crep.length= 0; - crep.groups= XkbAllGroupsMask; - crep.firstSI= 0; - crep.nSI= crep.nTotalSI= new->compat->num_si; - XkbComputeGetCompatMapReplySize(new->compat,&crep); - rep.length+= SIZEOF(xGenericReply)/4+crep.length; - } - if (new->indicators==NULL) - rep.reported&= ~XkbGBN_IndicatorMapMask; - else if (rep.reported&XkbGBN_IndicatorMapMask) { - irep.type= X_Reply; - irep.deviceID= dev->id; - irep.sequenceNumber= client->sequence; - irep.length= 0; - irep.which= XkbAllIndicatorsMask; - XkbComputeGetIndicatorMapReplySize(new->indicators,&irep); - rep.length+= SIZEOF(xGenericReply)/4+irep.length; - } - if (new->names==NULL) - rep.reported&= ~(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask); - else if (rep.reported&(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask)) { - nrep.type= X_Reply; - nrep.deviceID= dev->id; - nrep.sequenceNumber= client->sequence; - nrep.length= 0; - nrep.minKeyCode= new->min_key_code; - nrep.maxKeyCode= new->max_key_code; - if (rep.reported&XkbGBN_OtherNamesMask) { - nrep.which= XkbAllNamesMask; - if (new->map!=NULL) - nrep.nTypes= new->map->num_types; - else nrep.nTypes= 0; - nrep.nKTLevels= 0; - nrep.groupNames= XkbAllGroupsMask; - nrep.virtualMods= XkbAllVirtualModsMask; - nrep.indicators= XkbAllIndicatorsMask; - nrep.nRadioGroups= new->names->num_rg; - } - else { - nrep.which= 0; - nrep.nTypes= 0; - nrep.nKTLevels= 0; - nrep.groupNames= 0; - nrep.virtualMods= 0; - nrep.indicators= 0; - nrep.nRadioGroups= 0; - } - if (rep.reported&XkbGBN_KeyNamesMask) { - nrep.which|= XkbKeyNamesMask; - nrep.firstKey= new->min_key_code; - nrep.nKeys= XkbNumKeys(new); - nrep.nKeyAliases= new->names->num_key_aliases; - if (nrep.nKeyAliases) - nrep.which|= XkbKeyAliasesMask; - } - else { - nrep.which&= ~(XkbKeyNamesMask|XkbKeyAliasesMask); - nrep.firstKey= nrep.nKeys= 0; - nrep.nKeyAliases= 0; - } - XkbComputeGetNamesReplySize(new,&nrep); - rep.length+= SIZEOF(xGenericReply)/4+nrep.length; - } - if (new->geom==NULL) - rep.reported&= ~XkbGBN_GeometryMask; - else if (rep.reported&XkbGBN_GeometryMask) { - grep.type= X_Reply; - grep.deviceID= dev->id; - grep.sequenceNumber= client->sequence; - grep.length= 0; - grep.found= TRUE; - grep.pad= 0; - grep.widthMM= grep.heightMM= 0; - grep.nProperties= grep.nColors= grep.nShapes= 0; - grep.nSections= grep.nDoodads= 0; - grep.baseColorNdx= grep.labelColorNdx= 0; - XkbComputeGetGeometryReplySize(new->geom,&grep,None); - rep.length+= SIZEOF(xGenericReply)/4+grep.length; - } - } - - reported= rep.reported; - if ( client->swapped ) { - register int n; - swaps(&rep.sequenceNumber,n); - swapl(&rep.length,n); - swaps(&rep.found,n); - swaps(&rep.reported,n); - } - WriteToClient(client,SIZEOF(xkbGetKbdByNameReply), (char *)&rep); - if (reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) - XkbSendMap(client,new,&mrep); - if (reported&XkbGBN_CompatMapMask) - XkbSendCompatMap(client,new->compat,&crep); - if (reported&XkbGBN_IndicatorMapMask) - XkbSendIndicatorMap(client,new->indicators,&irep); - if (reported&(XkbGBN_KeyNamesMask|XkbGBN_OtherNamesMask)) - XkbSendNames(client,new,&nrep); - if (reported&XkbGBN_GeometryMask) - XkbSendGeometry(client,new->geom,&grep,FALSE); - if (rep.loaded) { - XkbDescPtr old_xkb; - xkbNewKeyboardNotify nkn; - int i,nG,nTG; - old_xkb= xkb; - xkb= new; - dev->key->xkbInfo->desc= xkb; - new= old_xkb; /* so it'll get freed automatically */ - - *xkb->ctrls= *old_xkb->ctrls; - for (nG=nTG=0,i=xkb->min_key_code;i<=xkb->max_key_code;i++) { - nG= XkbKeyNumGroups(xkb,i); - if (nG>=XkbNumKbdGroups) { - nTG= XkbNumKbdGroups; - break; - } - if (nG>nTG) { - nTG= nG; - } - } - xkb->ctrls->num_groups= nTG; - - for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) { - if ((tmpd == dev) || (!IsMaster(tmpd) && tmpd->u.master == dev)) { - if (tmpd != dev) - XkbCopyDeviceKeymap(tmpd, dev); - - if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) { - old_sli = tmpd->kbdfeed->xkb_sli; - tmpd->kbdfeed->xkb_sli = NULL; - sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0); - if (sli) { - sli->explicitState = old_sli->explicitState; - sli->effectiveState = old_sli->effectiveState; - } - tmpd->kbdfeed->xkb_sli = sli; - XkbFreeSrvLedInfo(old_sli); - } - } - } - - nkn.deviceID= nkn.oldDeviceID= dev->id; - nkn.minKeyCode= new->min_key_code; - nkn.maxKeyCode= new->max_key_code; - nkn.oldMinKeyCode= xkb->min_key_code; - nkn.oldMaxKeyCode= xkb->max_key_code; - nkn.requestMajor= XkbReqCode; - nkn.requestMinor= X_kbGetKbdByName; - nkn.changed= XkbNKN_KeycodesMask; - if (geom_changed) - nkn.changed|= XkbNKN_GeometryMask; - XkbSendNewKeyboardNotify(dev,&nkn); - - if (!IsMaster(dev) && dev->u.master) - { - DeviceIntPtr master = dev->u.master; - if (master->u.lastSlave == dev) - { - XkbCopyDeviceKeymap(dev->u.master, dev); - XkbSendNewKeyboardNotify(dev,&nkn); - } - } - } - if ((new!=NULL)&&(new!=xkb)) { - XkbFreeKeyboard(new,XkbAllComponentsMask,TRUE); - new= NULL; - } - if (names.keycodes) { xfree(names.keycodes); names.keycodes= NULL; } - if (names.types) { xfree(names.types); names.types= NULL; } - if (names.compat) { xfree(names.compat); names.compat= NULL; } - if (names.symbols) { xfree(names.symbols); names.symbols= NULL; } - if (names.geometry) { xfree(names.geometry); names.geometry= NULL; } - return client->noClientException; -} - -/***====================================================================***/ - -static int -ComputeDeviceLedInfoSize( DeviceIntPtr dev, - unsigned int what, - XkbSrvLedInfoPtr sli) -{ -int nNames,nMaps; -register unsigned n,bit; - - if (sli==NULL) - return 0; - nNames= nMaps= 0; - if ((what&XkbXI_IndicatorNamesMask)==0) - sli->namesPresent= 0; - if ((what&XkbXI_IndicatorMapsMask)==0) - sli->mapsPresent= 0; - - for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { - if (sli->names && sli->names[n]!=None) { - sli->namesPresent|= bit; - nNames++; - } - if (sli->maps && XkbIM_InUse(&sli->maps[n])) { - sli->mapsPresent|= bit; - nMaps++; - } - } - return (nNames*4)+(nMaps*SIZEOF(xkbIndicatorMapWireDesc)); -} - -static int -CheckDeviceLedFBs( DeviceIntPtr dev, - int class, - int id, - xkbGetDeviceInfoReply * rep, - ClientPtr client) -{ -int nFBs= 0; -int length= 0; -Bool classOk; - - if (class==XkbDfltXIClass) { - if (dev->kbdfeed) class= KbdFeedbackClass; - else if (dev->leds) class= LedFeedbackClass; - else { - client->errorValue= _XkbErrCode2(XkbErr_BadClass,class); - return XkbKeyboardErrorCode; - } - } - classOk= FALSE; - if ((dev->kbdfeed)&&((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) { - KbdFeedbackPtr kf; - classOk= TRUE; - for (kf= dev->kbdfeed;(kf);kf=kf->next) { - if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=kf->ctrl.id)) - continue; - nFBs++; - length+= SIZEOF(xkbDeviceLedsWireDesc); - if (!kf->xkb_sli) - kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,0); - length+= ComputeDeviceLedInfoSize(dev,rep->present,kf->xkb_sli); - if (id!=XkbAllXIIds) - break; - } - } - if ((dev->leds)&&((class==LedFeedbackClass)||(class==XkbAllXIClasses))) { - LedFeedbackPtr lf; - classOk= TRUE; - for (lf= dev->leds;(lf);lf=lf->next) { - if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=lf->ctrl.id)) - continue; - nFBs++; - length+= SIZEOF(xkbDeviceLedsWireDesc); - if (!lf->xkb_sli) - lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,0); - length+= ComputeDeviceLedInfoSize(dev,rep->present,lf->xkb_sli); - if (id!=XkbAllXIIds) - break; - } - } - if (nFBs>0) { - rep->nDeviceLedFBs= nFBs; - rep->length+= (length/4); - return Success; - } - if (classOk) client->errorValue= _XkbErrCode2(XkbErr_BadId,id); - else client->errorValue= _XkbErrCode2(XkbErr_BadClass,class); - return XkbKeyboardErrorCode; -} - -static int -SendDeviceLedInfo( XkbSrvLedInfoPtr sli, - ClientPtr client) -{ -xkbDeviceLedsWireDesc wire; -int length; - - length= 0; - wire.ledClass= sli->class; - wire.ledID= sli->id; - wire.namesPresent= sli->namesPresent; - wire.mapsPresent= sli->mapsPresent; - wire.physIndicators= sli->physIndicators; - wire.state= sli->effectiveState; - if (client->swapped) { - register int n; - swaps(&wire.ledClass,n); - swaps(&wire.ledID,n); - swapl(&wire.namesPresent,n); - swapl(&wire.mapsPresent,n); - swapl(&wire.physIndicators,n); - swapl(&wire.state,n); - } - WriteToClient(client,SIZEOF(xkbDeviceLedsWireDesc),(char *)&wire); - length+= SIZEOF(xkbDeviceLedsWireDesc); - if (sli->namesPresent|sli->mapsPresent) { - register unsigned i,bit; - if (sli->namesPresent) { - CARD32 awire; - for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { - if (sli->namesPresent&bit) { - awire= (CARD32)sli->names[i]; - if (client->swapped) { - register int n; - swapl(&awire,n); - } - WriteToClient(client,4,(char *)&awire); - length+= 4; - } - } - } - if (sli->mapsPresent) { - for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) { - xkbIndicatorMapWireDesc iwire; - if (sli->mapsPresent&bit) { - iwire.flags= sli->maps[i].flags; - iwire.whichGroups= sli->maps[i].which_groups; - iwire.groups= sli->maps[i].groups; - iwire.whichMods= sli->maps[i].which_mods; - iwire.mods= sli->maps[i].mods.mask; - iwire.realMods= sli->maps[i].mods.real_mods; - iwire.virtualMods= sli->maps[i].mods.vmods; - iwire.ctrls= sli->maps[i].ctrls; - if (client->swapped) { - register int n; - swaps(&iwire.virtualMods,n); - swapl(&iwire.ctrls,n); - } - WriteToClient(client,SIZEOF(xkbIndicatorMapWireDesc), - (char *)&iwire); - length+= SIZEOF(xkbIndicatorMapWireDesc); - } - } - } - } - return length; -} - -static int -SendDeviceLedFBs( DeviceIntPtr dev, - int class, - int id, - unsigned wantLength, - ClientPtr client) -{ -int length= 0; - - if (class==XkbDfltXIClass) { - if (dev->kbdfeed) class= KbdFeedbackClass; - else if (dev->leds) class= LedFeedbackClass; - } - if ((dev->kbdfeed)&& - ((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) { - KbdFeedbackPtr kf; - for (kf= dev->kbdfeed;(kf);kf=kf->next) { - if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==kf->ctrl.id)) { - length+= SendDeviceLedInfo(kf->xkb_sli,client); - if (id!=XkbAllXIIds) - break; - } - } - } - if ((dev->leds)&& - ((class==LedFeedbackClass)||(class==XkbAllXIClasses))) { - LedFeedbackPtr lf; - for (lf= dev->leds;(lf);lf=lf->next) { - if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==lf->ctrl.id)) { - length+= SendDeviceLedInfo(lf->xkb_sli,client); - if (id!=XkbAllXIIds) - break; - } - } - } - if (length==wantLength) - return Success; - else return BadLength; -} - -int -ProcXkbGetDeviceInfo(ClientPtr client) -{ -DeviceIntPtr dev; -xkbGetDeviceInfoReply rep; -int status,nDeviceLedFBs; -unsigned length,nameLen; -CARD16 ledClass,ledID; -unsigned wanted; -char * str; - - REQUEST(xkbGetDeviceInfoReq); - REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - wanted= stuff->wanted; - - CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess); - CHK_MASK_LEGAL(0x01,wanted,XkbXI_AllDeviceFeaturesMask); - - if ((!dev->button)||((stuff->nBtns<1)&&(!stuff->allBtns))) - wanted&= ~XkbXI_ButtonActionsMask; - if ((!dev->kbdfeed)&&(!dev->leds)) - wanted&= ~XkbXI_IndicatorsMask; - - nameLen= XkbSizeCountedString(dev->name); - bzero((char *)&rep,SIZEOF(xkbGetDeviceInfoReply)); - rep.type = X_Reply; - rep.deviceID= dev->id; - rep.sequenceNumber = client->sequence; - rep.length = nameLen/4; - rep.present = wanted; - rep.supported = XkbXI_AllDeviceFeaturesMask; - rep.unsupported = 0; - rep.firstBtnWanted = rep.nBtnsWanted = 0; - rep.firstBtnRtrn = rep.nBtnsRtrn = 0; - if (dev->button) - rep.totalBtns= dev->button->numButtons; - else rep.totalBtns= 0; - rep.devType= dev->xinput_type; - rep.hasOwnState= (dev->key && dev->key->xkbInfo); - rep.nDeviceLedFBs = 0; - if (dev->kbdfeed) rep.dfltKbdFB= dev->kbdfeed->ctrl.id; - else rep.dfltKbdFB= XkbXINone; - if (dev->leds) rep.dfltLedFB= dev->leds->ctrl.id; - else rep.dfltLedFB= XkbXINone; - - ledClass= stuff->ledClass; - ledID= stuff->ledID; - - rep.firstBtnWanted= rep.nBtnsWanted= 0; - rep.firstBtnRtrn= rep.nBtnsRtrn= 0; - if (wanted&XkbXI_ButtonActionsMask) { - if (stuff->allBtns) { - stuff->firstBtn= 0; - stuff->nBtns= dev->button->numButtons; - } - - if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) { - client->errorValue = _XkbErrCode4(0x02,dev->button->numButtons, - stuff->firstBtn, - stuff->nBtns); - return BadValue; - } - else { - rep.firstBtnWanted= stuff->firstBtn; - rep.nBtnsWanted= stuff->nBtns; - if (dev->button->xkb_acts!=NULL) { - XkbAction *act; - register int i; - - rep.firstBtnRtrn= stuff->firstBtn; - rep.nBtnsRtrn= stuff->nBtns; - act= &dev->button->xkb_acts[rep.firstBtnWanted]; - for (i=0;i<rep.nBtnsRtrn;i++,act++) { - if (act->type!=XkbSA_NoAction) - break; - } - rep.firstBtnRtrn+= i; - rep.nBtnsRtrn-= i; - act= &dev->button->xkb_acts[rep.firstBtnRtrn+rep.nBtnsRtrn-1]; - for (i=0;i<rep.nBtnsRtrn;i++,act--) { - if (act->type!=XkbSA_NoAction) - break; - } - rep.nBtnsRtrn-= i; - } - rep.length+= (rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc))/4; - } - } - - if (wanted&XkbXI_IndicatorsMask) { - status= CheckDeviceLedFBs(dev,ledClass,ledID,&rep,client); - if (status!=Success) - return status; - } - length= rep.length*4; - nDeviceLedFBs = rep.nDeviceLedFBs; - if (client->swapped) { - register int n; - swaps(&rep.sequenceNumber,n); - swapl(&rep.length,n); - swaps(&rep.present,n); - swaps(&rep.supported,n); - swaps(&rep.unsupported,n); - swaps(&rep.nDeviceLedFBs,n); - swapl(&rep.type,n); - } - WriteToClient(client,SIZEOF(xkbGetDeviceInfoReply), (char *)&rep); - - str= xalloc(nameLen); - if (!str) - return BadAlloc; - XkbWriteCountedString(str,dev->name,client->swapped); - WriteToClient(client,nameLen,str); - xfree(str); - length-= nameLen; - - if (rep.nBtnsRtrn>0) { - int sz; - xkbActionWireDesc * awire; - sz= rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc); - awire= (xkbActionWireDesc *)&dev->button->xkb_acts[rep.firstBtnRtrn]; - WriteToClient(client,sz,(char *)awire); - length-= sz; - } - if (nDeviceLedFBs>0) { - status= SendDeviceLedFBs(dev,ledClass,ledID,length,client); - if (status!=Success) - return status; - } - else if (length!=0) { - ErrorF("[xkb] Internal Error! BadLength in ProcXkbGetDeviceInfo\n"); - ErrorF("[xkb] Wrote %d fewer bytes than expected\n",length); - return BadLength; - } - return client->noClientException; -} - -static char * -CheckSetDeviceIndicators( char * wire, - DeviceIntPtr dev, - int num, - int * status_rtrn, - ClientPtr client) -{ -xkbDeviceLedsWireDesc * ledWire; -int i; -XkbSrvLedInfoPtr sli; - - ledWire= (xkbDeviceLedsWireDesc *)wire; - for (i=0;i<num;i++) { - if (client->swapped) { - register int n; - swaps(&ledWire->ledClass,n); - swaps(&ledWire->ledID,n); - swapl(&ledWire->namesPresent,n); - swapl(&ledWire->mapsPresent,n); - swapl(&ledWire->physIndicators,n); - } - - sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID, - XkbXI_IndicatorsMask); - if (sli!=NULL) { - register int n; - register unsigned bit; - int nMaps,nNames; - CARD32 *atomWire; - xkbIndicatorMapWireDesc *mapWire; - - nMaps= nNames= 0; - for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { - if (ledWire->namesPresent&bit) - nNames++; - if (ledWire->mapsPresent&bit) - nMaps++; - } - atomWire= (CARD32 *)&ledWire[1]; - if (nNames>0) { - for (n=0;n<nNames;n++) { - if (client->swapped) { - register int t; - swapl(atomWire,t); - } - CHK_ATOM_OR_NONE3(((Atom)(*atomWire)),client->errorValue, - *status_rtrn,NULL); - atomWire++; - } - } - mapWire= (xkbIndicatorMapWireDesc *)atomWire; - if (nMaps>0) { - for (n=0;n<nMaps;n++) { - if (client->swapped) { - register int t; - swaps(&mapWire->virtualMods,t); - swapl(&mapWire->ctrls,t); - } - CHK_MASK_LEGAL3(0x21,mapWire->whichGroups, - XkbIM_UseAnyGroup, - client->errorValue, - *status_rtrn,NULL); - CHK_MASK_LEGAL3(0x22,mapWire->whichMods,XkbIM_UseAnyMods, - client->errorValue, - *status_rtrn,NULL); - mapWire++; - } - } - ledWire= (xkbDeviceLedsWireDesc *)mapWire; - } - else { - /* SHOULD NEVER HAPPEN */ - return (char *)ledWire; - } - } - return (char *)ledWire; -} - -static char * -SetDeviceIndicators( char * wire, - DeviceIntPtr dev, - unsigned changed, - int num, - int * status_rtrn, - ClientPtr client, - xkbExtensionDeviceNotify *ev) -{ -xkbDeviceLedsWireDesc * ledWire; -int i; -XkbEventCauseRec cause; -unsigned namec,mapc,statec; -xkbExtensionDeviceNotify ed; -XkbChangesRec changes; -DeviceIntPtr kbd; - - bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify)); - bzero((char *)&changes,sizeof(XkbChangesRec)); - XkbSetCauseXkbReq(&cause,X_kbSetDeviceInfo,client); - ledWire= (xkbDeviceLedsWireDesc *)wire; - for (i=0;i<num;i++) { - register int n; - register unsigned bit; - CARD32 * atomWire; - xkbIndicatorMapWireDesc * mapWire; - XkbSrvLedInfoPtr sli; - - namec= mapc= statec= 0; - sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID, - XkbXI_IndicatorMapsMask); - if (!sli) { - /* SHOULD NEVER HAPPEN!! */ - return (char *)ledWire; - } - - atomWire= (CARD32 *)&ledWire[1]; - if (changed&XkbXI_IndicatorNamesMask) { - namec= sli->namesPresent|ledWire->namesPresent; - bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom)); - } - if (ledWire->namesPresent) { - sli->namesPresent= ledWire->namesPresent; - bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom)); - for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { - if (ledWire->namesPresent&bit) { - sli->names[n]= (Atom)*atomWire; - if (sli->names[n]==None) - ledWire->namesPresent&= ~bit; - atomWire++; - } - } - } - mapWire= (xkbIndicatorMapWireDesc *)atomWire; - if (changed&XkbXI_IndicatorMapsMask) { - mapc= sli->mapsPresent|ledWire->mapsPresent; - sli->mapsPresent= ledWire->mapsPresent; - bzero((char*)sli->maps,XkbNumIndicators*sizeof(XkbIndicatorMapRec)); - } - if (ledWire->mapsPresent) { - for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) { - if (ledWire->mapsPresent&bit) { - sli->maps[n].flags= mapWire->flags; - sli->maps[n].which_groups= mapWire->whichGroups; - sli->maps[n].groups= mapWire->groups; - sli->maps[n].which_mods= mapWire->whichMods; - sli->maps[n].mods.mask= mapWire->mods; - sli->maps[n].mods.real_mods=mapWire->realMods; - sli->maps[n].mods.vmods= mapWire->virtualMods; - sli->maps[n].ctrls= mapWire->ctrls; - mapWire++; - } - } - } - if (changed&XkbXI_IndicatorStateMask) { - statec= sli->effectiveState^ledWire->state; - sli->explicitState&= ~statec; - sli->explicitState|= (ledWire->state&statec); - } - if (namec) - XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause); - if (mapc) - XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause); - if (statec) - XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause); - - kbd= dev; - if ((sli->flags&XkbSLI_HasOwnState)==0) - kbd = inputInfo.keyboard; - - XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause); - ledWire= (xkbDeviceLedsWireDesc *)mapWire; - } - return (char *)ledWire; -} - - -static int -_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev, - xkbSetDeviceInfoReq *stuff) -{ - char *wire; - - wire= (char *)&stuff[1]; - if (stuff->change&XkbXI_ButtonActionsMask) { - if (!dev->button) { - client->errorValue = _XkbErrCode2(XkbErr_BadClass,ButtonClass); - return XkbKeyboardErrorCode; - } - if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) { - client->errorValue= _XkbErrCode4(0x02,stuff->firstBtn,stuff->nBtns, - dev->button->numButtons); - return BadMatch; - } - wire+= (stuff->nBtns*SIZEOF(xkbActionWireDesc)); - } - if (stuff->change&XkbXI_IndicatorsMask) { - int status= Success; - wire= CheckSetDeviceIndicators(wire,dev,stuff->nDeviceLedFBs, - &status,client); - if (status!=Success) - return status; - } - if (((wire-((char *)stuff))/4)!=stuff->length) - return BadLength; - - return Success; -} - -static int -_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev, - xkbSetDeviceInfoReq *stuff) -{ - char *wire; - xkbExtensionDeviceNotify ed; - - bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify)); - ed.deviceID= dev->id; - wire= (char *)&stuff[1]; - if (stuff->change&XkbXI_ButtonActionsMask) { - int nBtns,sz,i; - XkbAction * acts; - DeviceIntPtr kbd; - - nBtns= dev->button->numButtons; - acts= dev->button->xkb_acts; - if (acts==NULL) { - acts= xcalloc(nBtns, sizeof(XkbAction)); - if (!acts) - return BadAlloc; - dev->button->xkb_acts= acts; - } - sz= stuff->nBtns*SIZEOF(xkbActionWireDesc); - memcpy((char *)&acts[stuff->firstBtn],(char *)wire,sz); - wire+= sz; - ed.reason|= XkbXI_ButtonActionsMask; - ed.firstBtn= stuff->firstBtn; - ed.nBtns= stuff->nBtns; - - if (dev->key) kbd= dev; - else kbd= inputInfo.keyboard; - acts= &dev->button->xkb_acts[stuff->firstBtn]; - for (i=0;i<stuff->nBtns;i++,acts++) { - if (acts->type!=XkbSA_NoAction) - XkbSetActionKeyMods(kbd->key->xkbInfo->desc,acts,0); - } - } - if (stuff->change&XkbXI_IndicatorsMask) { - int status= Success; - wire= SetDeviceIndicators(wire,dev,stuff->change, - stuff->nDeviceLedFBs, &status,client,&ed); - if (status!=Success) - return status; - } - if ((stuff->change)&&(ed.reason)) - XkbSendExtensionDeviceNotify(dev,client,&ed); - return Success; -} - -int -ProcXkbSetDeviceInfo(ClientPtr client) -{ - DeviceIntPtr dev; - int rc; - - REQUEST(xkbSetDeviceInfoReq); - REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq); - - if (!(client->xkbClientFlags&_XkbClientInitialized)) - return BadAccess; - - CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess); - CHK_MASK_LEGAL(0x01,stuff->change,XkbXI_AllFeaturesMask); - - rc = _XkbSetDeviceInfoCheck(client, dev, stuff); - - if (rc != Success) - return rc; - - if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr) - { - DeviceIntPtr other; - for (other = inputInfo.devices; other; other = other->next) - { - if (((other != dev) && !IsMaster(other) && (other->u.master == dev)) && - ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || - (stuff->deviceSpec == XkbUseCorePtr && other->button))) - { - rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); - if (rc == Success) - { - rc = _XkbSetDeviceInfoCheck(client, other, stuff); - if (rc != Success) - return rc; - } - } - } - } - - /* checks done, apply */ - rc = _XkbSetDeviceInfo(client, dev, stuff); - if (rc != Success) - return rc; - - if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr) - { - DeviceIntPtr other; - for (other = inputInfo.devices; other; other = other->next) - { - if (((other != dev) && !IsMaster(other) && (other->u.master == dev)) && - ((stuff->deviceSpec == XkbUseCoreKbd && other->key) || - (stuff->deviceSpec == XkbUseCorePtr && other->button))) - { - rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess); - if (rc == Success) - { - rc = _XkbSetDeviceInfo(client, other, stuff); - if (rc != Success) - return rc; - } - } - } - } - - return client->noClientException; -} - -/***====================================================================***/ - -int -ProcXkbSetDebuggingFlags(ClientPtr client) -{ -CARD32 newFlags,newCtrls,extraLength; -xkbSetDebuggingFlagsReply rep; -int rc; - - REQUEST(xkbSetDebuggingFlagsReq); - REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq); - - rc = XaceHook(XACE_SERVER_ACCESS, client, DixDebugAccess); - if (rc != Success) - return rc; - - newFlags= xkbDebugFlags&(~stuff->affectFlags); - newFlags|= (stuff->flags&stuff->affectFlags); - newCtrls= xkbDebugCtrls&(~stuff->affectCtrls); - newCtrls|= (stuff->ctrls&stuff->affectCtrls); - if (xkbDebugFlags || newFlags || stuff->msgLength) { - ErrorF("[xkb] XkbDebug: Setting debug flags to 0x%lx\n",(long)newFlags); - if (newCtrls!=xkbDebugCtrls) - ErrorF("[xkb] XkbDebug: Setting debug controls to 0x%lx\n",(long)newCtrls); - } - extraLength= (stuff->length<<2)-sz_xkbSetDebuggingFlagsReq; - if (stuff->msgLength>0) { - char *msg; - if (extraLength<XkbPaddedSize(stuff->msgLength)) { - ErrorF("[xkb] XkbDebug: msgLength= %d, length= %ld (should be %d)\n", - stuff->msgLength,(long)extraLength, - XkbPaddedSize(stuff->msgLength)); - return BadLength; - } - msg= (char *)&stuff[1]; - if (msg[stuff->msgLength-1]!='\0') { - ErrorF("[xkb] XkbDebug: message not null-terminated\n"); - return BadValue; - } - ErrorF("[xkb] XkbDebug: %s\n",msg); - } - xkbDebugFlags = newFlags; - xkbDebugCtrls = newCtrls; - - rep.type= X_Reply; - rep.length = 0; - rep.sequenceNumber = client->sequence; - rep.currentFlags = newFlags; - rep.currentCtrls = newCtrls; - rep.supportedFlags = ~0; - rep.supportedCtrls = ~0; - if ( client->swapped ) { - register int n; - swaps(&rep.sequenceNumber, n); - swapl(&rep.currentFlags, n); - swapl(&rep.currentCtrls, n); - swapl(&rep.supportedFlags, n); - swapl(&rep.supportedCtrls, n); - } - WriteToClient(client,SIZEOF(xkbSetDebuggingFlagsReply), (char *)&rep); - return client->noClientException; -} - -/***====================================================================***/ - -static int -ProcXkbDispatch (ClientPtr client) -{ - REQUEST(xReq); - switch (stuff->data) - { - case X_kbUseExtension: - return ProcXkbUseExtension(client); - case X_kbSelectEvents: - return ProcXkbSelectEvents(client); - case X_kbBell: - return ProcXkbBell(client); - case X_kbGetState: - return ProcXkbGetState(client); - case X_kbLatchLockState: - return ProcXkbLatchLockState(client); - case X_kbGetControls: - return ProcXkbGetControls(client); - case X_kbSetControls: - return ProcXkbSetControls(client); - case X_kbGetMap: - return ProcXkbGetMap(client); - case X_kbSetMap: - return ProcXkbSetMap(client); - case X_kbGetCompatMap: - return ProcXkbGetCompatMap(client); - case X_kbSetCompatMap: - return ProcXkbSetCompatMap(client); - case X_kbGetIndicatorState: - return ProcXkbGetIndicatorState(client); - case X_kbGetIndicatorMap: - return ProcXkbGetIndicatorMap(client); - case X_kbSetIndicatorMap: - return ProcXkbSetIndicatorMap(client); - case X_kbGetNamedIndicator: - return ProcXkbGetNamedIndicator(client); - case X_kbSetNamedIndicator: - return ProcXkbSetNamedIndicator(client); - case X_kbGetNames: - return ProcXkbGetNames(client); - case X_kbSetNames: - return ProcXkbSetNames(client); - case X_kbGetGeometry: - return ProcXkbGetGeometry(client); - case X_kbSetGeometry: - return ProcXkbSetGeometry(client); - case X_kbPerClientFlags: - return ProcXkbPerClientFlags(client); - case X_kbListComponents: - return ProcXkbListComponents(client); - case X_kbGetKbdByName: - return ProcXkbGetKbdByName(client); - case X_kbGetDeviceInfo: - return ProcXkbGetDeviceInfo(client); - case X_kbSetDeviceInfo: - return ProcXkbSetDeviceInfo(client); - case X_kbSetDebuggingFlags: - return ProcXkbSetDebuggingFlags(client); - default: - return BadRequest; - } -} - -static int -XkbClientGone(pointer data,XID id) -{ - DevicePtr pXDev = (DevicePtr)data; - - if (!XkbRemoveResourceClient(pXDev,id)) { - ErrorF("[xkb] Internal Error! bad RemoveResourceClient in XkbClientGone\n"); - } - return 1; -} - -void -XkbExtensionInit(void) -{ - ExtensionEntry *extEntry; - - RT_XKBCLIENT = CreateNewResourceType(XkbClientGone, "XkbClient"); - if (!RT_XKBCLIENT) - return; - - if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors, - ProcXkbDispatch, SProcXkbDispatch, - NULL, StandardMinorOpcode))) { - XkbReqCode = (unsigned char)extEntry->base; - XkbEventBase = (unsigned char)extEntry->eventBase; - XkbErrorBase = (unsigned char)extEntry->errorBase; - XkbKeyboardErrorCode = XkbErrorBase+XkbKeyboard; - } - return; -} - - +/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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 <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "inputstr.h"
+#define XKBSRV_NEED_FILE_FUNCS
+#include <xkbsrv.h>
+#include "extnsionst.h"
+#include "xace.h"
+#include "xkb.h"
+#include "protocol-versions.h"
+
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XKMformat.h>
+
+int XkbEventBase;
+static int XkbErrorBase;
+int XkbReqCode;
+int XkbKeyboardErrorCode;
+CARD32 xkbDebugFlags = 0;
+static CARD32 xkbDebugCtrls = 0;
+
+static RESTYPE RT_XKBCLIENT;
+
+/***====================================================================***/
+
+#define CHK_DEVICE(dev, id, client, access_mode, lf) {\
+ int why;\
+ int rc = lf(&(dev), id, client, access_mode, &why);\
+ if (rc != Success) {\
+ client->errorValue = _XkbErrCode2(why, id);\
+ return rc;\
+ }\
+}
+
+#define CHK_KBD_DEVICE(dev, id, client, mode) \
+ CHK_DEVICE(dev, id, client, mode, _XkbLookupKeyboard)
+#define CHK_LED_DEVICE(dev, id, client, mode) \
+ CHK_DEVICE(dev, id, client, mode, _XkbLookupLedDevice)
+#define CHK_BELL_DEVICE(dev, id, client, mode) \
+ CHK_DEVICE(dev, id, client, mode, _XkbLookupBellDevice)
+#define CHK_ANY_DEVICE(dev, id, client, mode) \
+ CHK_DEVICE(dev, id, client, mode, _XkbLookupAnyDevice)
+
+#define CHK_ATOM_ONLY2(a,ev,er) {\
+ if (((a)==None)||(!ValidAtom((a)))) {\
+ (ev)= (XID)(a);\
+ return er;\
+ }\
+}
+#define CHK_ATOM_ONLY(a) \
+ CHK_ATOM_ONLY2(a,client->errorValue,BadAtom)
+
+#define CHK_ATOM_OR_NONE3(a,ev,er,ret) {\
+ if (((a)!=None)&&(!ValidAtom((a)))) {\
+ (ev)= (XID)(a);\
+ (er)= BadAtom;\
+ return ret;\
+ }\
+}
+#define CHK_ATOM_OR_NONE2(a,ev,er) {\
+ if (((a)!=None)&&(!ValidAtom((a)))) {\
+ (ev)= (XID)(a);\
+ return er;\
+ }\
+}
+#define CHK_ATOM_OR_NONE(a) \
+ CHK_ATOM_OR_NONE2(a,client->errorValue,BadAtom)
+
+#define CHK_MASK_LEGAL3(err,mask,legal,ev,er,ret) {\
+ if ((mask)&(~(legal))) { \
+ (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
+ (er)= BadValue;\
+ return ret;\
+ }\
+}
+#define CHK_MASK_LEGAL2(err,mask,legal,ev,er) {\
+ if ((mask)&(~(legal))) { \
+ (ev)= _XkbErrCode2((err),((mask)&(~(legal))));\
+ return er;\
+ }\
+}
+#define CHK_MASK_LEGAL(err,mask,legal) \
+ CHK_MASK_LEGAL2(err,mask,legal,client->errorValue,BadValue)
+
+#define CHK_MASK_MATCH(err,affect,value) {\
+ if ((value)&(~(affect))) { \
+ client->errorValue= _XkbErrCode2((err),((value)&(~(affect))));\
+ return BadMatch;\
+ }\
+}
+#define CHK_MASK_OVERLAP(err,m1,m2) {\
+ if ((m1)&(m2)) { \
+ client->errorValue= _XkbErrCode2((err),((m1)&(m2)));\
+ return BadMatch;\
+ }\
+}
+#define CHK_KEY_RANGE2(err,first,num,x,ev,er) {\
+ if (((unsigned)(first)+(num)-1)>(x)->max_key_code) {\
+ (ev)=_XkbErrCode4(err,(first),(num),(x)->max_key_code);\
+ return er;\
+ }\
+ else if ( (first)<(x)->min_key_code ) {\
+ (ev)=_XkbErrCode3(err+1,(first),xkb->min_key_code);\
+ return er;\
+ }\
+}
+#define CHK_KEY_RANGE(err,first,num,x) \
+ CHK_KEY_RANGE2(err,first,num,x,client->errorValue,BadValue)
+
+#define CHK_REQ_KEY_RANGE2(err,first,num,r,ev,er) {\
+ if (((unsigned)(first)+(num)-1)>(r)->maxKeyCode) {\
+ (ev)=_XkbErrCode4(err,(first),(num),(r)->maxKeyCode);\
+ return er;\
+ }\
+ else if ( (first)<(r)->minKeyCode ) {\
+ (ev)=_XkbErrCode3(err+1,(first),(r)->minKeyCode);\
+ return er;\
+ }\
+}
+#define CHK_REQ_KEY_RANGE(err,first,num,r) \
+ CHK_REQ_KEY_RANGE2(err,first,num,r,client->errorValue,BadValue)
+
+/***====================================================================***/
+
+int
+ProcXkbUseExtension(ClientPtr client)
+{
+ REQUEST(xkbUseExtensionReq);
+ xkbUseExtensionReply rep;
+ register int n;
+ int supported;
+
+ REQUEST_SIZE_MATCH(xkbUseExtensionReq);
+ if (stuff->wantedMajor != SERVER_XKB_MAJOR_VERSION) {
+ /* pre-release version 0.65 is compatible with 1.00 */
+ supported= ((SERVER_XKB_MAJOR_VERSION==1)&&
+ (stuff->wantedMajor==0)&&(stuff->wantedMinor==65));
+ }
+ else supported = 1;
+
+ if ((supported) && (!(client->xkbClientFlags&_XkbClientInitialized))) {
+ client->xkbClientFlags= _XkbClientInitialized;
+ client->vMajor= stuff->wantedMajor;
+ client->vMinor= stuff->wantedMinor;
+ }
+ else if (xkbDebugFlags&0x1) {
+ ErrorF("[xkb] Rejecting client %d (0x%lx) (wants %d.%02d, have %d.%02d)\n",
+ client->index,
+ (long)client->clientAsMask,
+ stuff->wantedMajor,stuff->wantedMinor,
+ SERVER_XKB_MAJOR_VERSION,SERVER_XKB_MINOR_VERSION);
+ }
+ memset(&rep, 0, sizeof(xkbUseExtensionReply));
+ rep.type = X_Reply;
+ rep.supported = supported;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.serverMajor = SERVER_XKB_MAJOR_VERSION;
+ rep.serverMinor = SERVER_XKB_MINOR_VERSION;
+ if ( client->swapped ) {
+ swaps(&rep.sequenceNumber, n);
+ swaps(&rep.serverMajor, n);
+ swaps(&rep.serverMinor, n);
+ }
+ WriteToClient(client,SIZEOF(xkbUseExtensionReply), (char *)&rep);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbSelectEvents(ClientPtr client)
+{
+ unsigned legal;
+ DeviceIntPtr dev;
+ XkbInterestPtr masks;
+ REQUEST(xkbSelectEventsReq);
+
+ REQUEST_AT_LEAST_SIZE(xkbSelectEventsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixUseAccess);
+
+ if (((stuff->affectWhich&XkbMapNotifyMask)!=0)&&(stuff->affectMap)) {
+ client->mapNotifyMask&= ~stuff->affectMap;
+ client->mapNotifyMask|= (stuff->affectMap&stuff->map);
+ }
+ if ((stuff->affectWhich&(~XkbMapNotifyMask))==0)
+ return client->noClientException;
+
+ masks = XkbFindClientResource((DevicePtr)dev,client);
+ if (!masks){
+ XID id = FakeClientID(client->index);
+ AddResource(id,RT_XKBCLIENT,dev);
+ masks= XkbAddClientResource((DevicePtr)dev,client,id);
+ }
+ if (masks) {
+ union {
+ CARD8 *c8;
+ CARD16 *c16;
+ CARD32 *c32;
+ } from,to;
+ register unsigned bit,ndx,maskLeft,dataLeft,size;
+
+ from.c8= (CARD8 *)&stuff[1];
+ dataLeft= (stuff->length*4)-SIZEOF(xkbSelectEventsReq);
+ maskLeft= (stuff->affectWhich&(~XkbMapNotifyMask));
+ for (ndx=0,bit=1; (maskLeft!=0); ndx++, bit<<=1) {
+ if ((bit&maskLeft)==0)
+ continue;
+ maskLeft&= ~bit;
+ switch (ndx) {
+ case XkbNewKeyboardNotify:
+ to.c16= &client->newKeyboardNotifyMask;
+ legal= XkbAllNewKeyboardEventsMask;
+ size= 2;
+ break;
+ case XkbStateNotify:
+ to.c16= &masks->stateNotifyMask;
+ legal= XkbAllStateEventsMask;
+ size= 2;
+ break;
+ case XkbControlsNotify:
+ to.c32= &masks->ctrlsNotifyMask;
+ legal= XkbAllControlEventsMask;
+ size= 4;
+ break;
+ case XkbIndicatorStateNotify:
+ to.c32= &masks->iStateNotifyMask;
+ legal= XkbAllIndicatorEventsMask;
+ size= 4;
+ break;
+ case XkbIndicatorMapNotify:
+ to.c32= &masks->iMapNotifyMask;
+ legal= XkbAllIndicatorEventsMask;
+ size= 4;
+ break;
+ case XkbNamesNotify:
+ to.c16= &masks->namesNotifyMask;
+ legal= XkbAllNameEventsMask;
+ size= 2;
+ break;
+ case XkbCompatMapNotify:
+ to.c8= &masks->compatNotifyMask;
+ legal= XkbAllCompatMapEventsMask;
+ size= 1;
+ break;
+ case XkbBellNotify:
+ to.c8= &masks->bellNotifyMask;
+ legal= XkbAllBellEventsMask;
+ size= 1;
+ break;
+ case XkbActionMessage:
+ to.c8= &masks->actionMessageMask;
+ legal= XkbAllActionMessagesMask;
+ size= 1;
+ break;
+ case XkbAccessXNotify:
+ to.c16= &masks->accessXNotifyMask;
+ legal= XkbAllAccessXEventsMask;
+ size= 2;
+ break;
+ case XkbExtensionDeviceNotify:
+ to.c16= &masks->extDevNotifyMask;
+ legal= XkbAllExtensionDeviceEventsMask;
+ size= 2;
+ break;
+ default:
+ client->errorValue = _XkbErrCode2(33,bit);
+ return BadValue;
+ }
+
+ if (stuff->clear&bit) {
+ if (size==2) to.c16[0]= 0;
+ else if (size==4) to.c32[0]= 0;
+ else to.c8[0]= 0;
+ }
+ else if (stuff->selectAll&bit) {
+ if (size==2) to.c16[0]= ~0;
+ else if (size==4) to.c32[0]= ~0;
+ else to.c8[0]= ~0;
+ }
+ else {
+ if (dataLeft<(size*2))
+ return BadLength;
+ if (size==2) {
+ CHK_MASK_MATCH(ndx,from.c16[0],from.c16[1]);
+ CHK_MASK_LEGAL(ndx,from.c16[0],legal);
+ to.c16[0]&= ~from.c16[0];
+ to.c16[0]|= (from.c16[0]&from.c16[1]);
+ }
+ else if (size==4) {
+ CHK_MASK_MATCH(ndx,from.c32[0],from.c32[1]);
+ CHK_MASK_LEGAL(ndx,from.c32[0],legal);
+ to.c32[0]&= ~from.c32[0];
+ to.c32[0]|= (from.c32[0]&from.c32[1]);
+ }
+ else {
+ CHK_MASK_MATCH(ndx,from.c8[0],from.c8[1]);
+ CHK_MASK_LEGAL(ndx,from.c8[0],legal);
+ to.c8[0]&= ~from.c8[0];
+ to.c8[0]|= (from.c8[0]&from.c8[1]);
+ size= 2;
+ }
+ from.c8+= (size*2);
+ dataLeft-= (size*2);
+ }
+ }
+ if (dataLeft>2) {
+ ErrorF("[xkb] Extra data (%d bytes) after SelectEvents\n",dataLeft);
+ return BadLength;
+ }
+ return client->noClientException;
+ }
+ return BadAlloc;
+}
+
+/***====================================================================***/
+/**
+ * Ring a bell on the given device for the given client.
+ */
+static int
+_XkbBell(ClientPtr client, DeviceIntPtr dev, WindowPtr pWin,
+ int bellClass, int bellID, int pitch, int duration,
+ int percent, int forceSound, int eventOnly, Atom name)
+{
+ int base;
+ pointer ctrl;
+ int oldPitch, oldDuration;
+ int newPercent;
+
+ if (bellClass == KbdFeedbackClass) {
+ KbdFeedbackPtr k;
+ if (bellID==XkbDfltXIId)
+ k= dev->kbdfeed;
+ else {
+ for (k=dev->kbdfeed; k; k=k->next) {
+ if (k->ctrl.id == bellID)
+ break;
+ }
+ }
+ if (!k) {
+ client->errorValue = _XkbErrCode2(0x5,bellID);
+ return BadValue;
+ }
+ base = k->ctrl.bell;
+ ctrl = (pointer) &(k->ctrl);
+ oldPitch= k->ctrl.bell_pitch;
+ oldDuration= k->ctrl.bell_duration;
+ if (pitch!=0) {
+ if (pitch==-1)
+ k->ctrl.bell_pitch= defaultKeyboardControl.bell_pitch;
+ else k->ctrl.bell_pitch= pitch;
+ }
+ if (duration!=0) {
+ if (duration==-1)
+ k->ctrl.bell_duration= defaultKeyboardControl.bell_duration;
+ else k->ctrl.bell_duration= duration;
+ }
+ }
+ else if (bellClass == BellFeedbackClass) {
+ BellFeedbackPtr b;
+ if (bellID==XkbDfltXIId)
+ b= dev->bell;
+ else {
+ for (b=dev->bell; b; b=b->next) {
+ if (b->ctrl.id == bellID)
+ break;
+ }
+ }
+ if (!b) {
+ client->errorValue = _XkbErrCode2(0x6,bellID);
+ return BadValue;
+ }
+ base = b->ctrl.percent;
+ ctrl = (pointer) &(b->ctrl);
+ oldPitch= b->ctrl.pitch;
+ oldDuration= b->ctrl.duration;
+ if (pitch!=0) {
+ if (pitch==-1)
+ b->ctrl.pitch= defaultKeyboardControl.bell_pitch;
+ else b->ctrl.pitch= pitch;
+ }
+ if (duration!=0) {
+ if (duration==-1)
+ b->ctrl.duration= defaultKeyboardControl.bell_duration;
+ else b->ctrl.duration= duration;
+ }
+ }
+ else {
+ client->errorValue = _XkbErrCode2(0x7, bellClass);
+ return BadValue;
+ }
+
+ newPercent = (base * percent)/100;
+ if (percent < 0)
+ newPercent = base + newPercent;
+ else newPercent = base - newPercent + percent;
+
+ XkbHandleBell(forceSound, eventOnly,
+ dev, newPercent, ctrl, bellClass,
+ name, pWin, client);
+ if ((pitch!=0)||(duration!=0)) {
+ if (bellClass == KbdFeedbackClass) {
+ KbdFeedbackPtr k;
+ k= (KbdFeedbackPtr)ctrl;
+ if (pitch!=0)
+ k->ctrl.bell_pitch= oldPitch;
+ if (duration!=0)
+ k->ctrl.bell_duration= oldDuration;
+ }
+ else {
+ BellFeedbackPtr b;
+ b= (BellFeedbackPtr)ctrl;
+ if (pitch!=0)
+ b->ctrl.pitch= oldPitch;
+ if (duration!=0)
+ b->ctrl.duration= oldDuration;
+ }
+ }
+
+ return Success;
+}
+
+int
+ProcXkbBell(ClientPtr client)
+{
+ REQUEST(xkbBellReq);
+ DeviceIntPtr dev;
+ WindowPtr pWin;
+ int rc;
+
+ REQUEST_SIZE_MATCH(xkbBellReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_BELL_DEVICE(dev, stuff->deviceSpec, client, DixBellAccess);
+ CHK_ATOM_OR_NONE(stuff->name);
+
+ /* device-independent checks request for sane values */
+ if ((stuff->forceSound)&&(stuff->eventOnly)) {
+ client->errorValue=_XkbErrCode3(0x1,stuff->forceSound,stuff->eventOnly);
+ return BadMatch;
+ }
+ if (stuff->percent < -100 || stuff->percent > 100) {
+ client->errorValue = _XkbErrCode2(0x2,stuff->percent);
+ return BadValue;
+ }
+ if (stuff->duration<-1) {
+ client->errorValue = _XkbErrCode2(0x3,stuff->duration);
+ return BadValue;
+ }
+ if (stuff->pitch<-1) {
+ client->errorValue = _XkbErrCode2(0x4,stuff->pitch);
+ return BadValue;
+ }
+
+ if (stuff->bellClass == XkbDfltXIClass) {
+ if (dev->kbdfeed!=NULL)
+ stuff->bellClass= KbdFeedbackClass;
+ else stuff->bellClass= BellFeedbackClass;
+ }
+
+ if (stuff->window!=None) {
+ rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
+ if (rc != Success) {
+ client->errorValue= stuff->window;
+ return rc;
+ }
+ }
+ else pWin= NULL;
+
+ /* Client wants to ring a bell on the core keyboard?
+ Ring the bell on the core keyboard (which does nothing, but if that
+ fails the client is screwed anyway), and then on all extension devices.
+ Fail if the core keyboard fails but not the extension devices. this
+ may cause some keyboards to ding and others to stay silent. Fix
+ your client to use explicit keyboards to avoid this.
+
+ dev is the device the client requested.
+ */
+ rc = _XkbBell(client, dev, pWin, stuff->bellClass, stuff->bellID,
+ stuff->pitch, stuff->duration, stuff->percent,
+ stuff->forceSound, stuff->eventOnly, stuff->name);
+
+ if ((rc == Success) && ((stuff->deviceSpec == XkbUseCoreKbd) ||
+ (stuff->deviceSpec == XkbUseCorePtr)))
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixBellAccess);
+ if (rc == Success)
+ _XkbBell(client, other, pWin, stuff->bellClass,
+ stuff->bellID, stuff->pitch, stuff->duration,
+ stuff->percent, stuff->forceSound,
+ stuff->eventOnly, stuff->name);
+ }
+ }
+ rc = Success; /* reset to success, that's what we got for the VCK */
+ }
+
+ return rc;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbGetState(ClientPtr client)
+{
+ REQUEST(xkbGetStateReq);
+ DeviceIntPtr dev;
+ xkbGetStateReply rep;
+ XkbStateRec *xkb;
+
+ REQUEST_SIZE_MATCH(xkbGetStateReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+
+ xkb= &dev->key->xkbInfo->state;
+ bzero(&rep,sizeof(xkbGetStateReply));
+ rep.type= X_Reply;
+ rep.sequenceNumber= client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.mods = XkbStateFieldFromRec(xkb) & 0xff;
+ rep.baseMods = xkb->base_mods;
+ rep.lockedMods = xkb->locked_mods;
+ rep.latchedMods = xkb->latched_mods;
+ rep.group = xkb->group;
+ rep.baseGroup = xkb->base_group;
+ rep.latchedGroup = xkb->latched_group;
+ rep.lockedGroup = xkb->locked_group;
+ rep.compatState = xkb->compat_state;
+ rep.ptrBtnState = xkb->ptr_buttons;
+ if (client->swapped) {
+ register int n;
+ swaps(&rep.sequenceNumber,n);
+ swaps(&rep.ptrBtnState,n);
+ }
+ WriteToClient(client, SIZEOF(xkbGetStateReply), (char *)&rep);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbLatchLockState(ClientPtr client)
+{
+ int status;
+ DeviceIntPtr dev, tmpd;
+ XkbStateRec oldState,*newState;
+ CARD16 changed;
+ xkbStateNotify sn;
+ XkbEventCauseRec cause;
+
+ REQUEST(xkbLatchLockStateReq);
+ REQUEST_SIZE_MATCH(xkbLatchLockStateReq);
+
+ if (!(client->xkbClientFlags & _XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess);
+ CHK_MASK_MATCH(0x01, stuff->affectModLocks, stuff->modLocks);
+ CHK_MASK_MATCH(0x01, stuff->affectModLatches, stuff->modLatches);
+
+ status = Success;
+
+ for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
+ if ((tmpd == dev) || (!IsMaster(tmpd) && tmpd->u.master == dev)) {
+ if (!tmpd->key || !tmpd->key->xkbInfo)
+ continue;
+
+ oldState = tmpd->key->xkbInfo->state;
+ newState = &tmpd->key->xkbInfo->state;
+ if (stuff->affectModLocks) {
+ newState->locked_mods &= ~stuff->affectModLocks;
+ newState->locked_mods |= (stuff->affectModLocks & stuff->modLocks);
+ }
+ if (status == Success && stuff->lockGroup)
+ newState->locked_group = stuff->groupLock;
+ if (status == Success && stuff->affectModLatches)
+ status = XkbLatchModifiers(tmpd, stuff->affectModLatches,
+ stuff->modLatches);
+ if (status == Success && stuff->latchGroup)
+ status = XkbLatchGroup(tmpd, stuff->groupLatch);
+
+ if (status != Success)
+ return status;
+
+ XkbComputeDerivedState(tmpd->key->xkbInfo);
+
+ changed = XkbStateChangedFlags(&oldState, newState);
+ if (changed) {
+ sn.keycode = 0;
+ sn.eventType = 0;
+ sn.requestMajor = XkbReqCode;
+ sn.requestMinor = X_kbLatchLockState;
+ sn.changed = changed;
+ XkbSendStateNotify(tmpd, &sn);
+ changed = XkbIndicatorsToUpdate(tmpd, changed, FALSE);
+ if (changed) {
+ XkbSetCauseXkbReq(&cause, X_kbLatchLockState, client);
+ XkbUpdateIndicators(tmpd, changed, TRUE, NULL, &cause);
+ }
+ }
+ }
+ }
+
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbGetControls(ClientPtr client)
+{
+ xkbGetControlsReply rep;
+ XkbControlsPtr xkb;
+ DeviceIntPtr dev;
+ register int n;
+
+ REQUEST(xkbGetControlsReq);
+ REQUEST_SIZE_MATCH(xkbGetControlsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+
+ xkb = dev->key->xkbInfo->desc->ctrls;
+ rep.type = X_Reply;
+ rep.length = bytes_to_int32(SIZEOF(xkbGetControlsReply)-
+ SIZEOF(xGenericReply));
+ rep.sequenceNumber = client->sequence;
+ rep.deviceID = ((DeviceIntPtr)dev)->id;
+ rep.numGroups = xkb->num_groups;
+ rep.groupsWrap = xkb->groups_wrap;
+ rep.internalMods = xkb->internal.mask;
+ rep.ignoreLockMods = xkb->ignore_lock.mask;
+ rep.internalRealMods = xkb->internal.real_mods;
+ rep.ignoreLockRealMods = xkb->ignore_lock.real_mods;
+ rep.internalVMods = xkb->internal.vmods;
+ rep.ignoreLockVMods = xkb->ignore_lock.vmods;
+ rep.enabledCtrls = xkb->enabled_ctrls;
+ rep.repeatDelay = xkb->repeat_delay;
+ rep.repeatInterval = xkb->repeat_interval;
+ rep.slowKeysDelay = xkb->slow_keys_delay;
+ rep.debounceDelay = xkb->debounce_delay;
+ rep.mkDelay = xkb->mk_delay;
+ rep.mkInterval = xkb->mk_interval;
+ rep.mkTimeToMax = xkb->mk_time_to_max;
+ rep.mkMaxSpeed = xkb->mk_max_speed;
+ rep.mkCurve = xkb->mk_curve;
+ rep.mkDfltBtn = xkb->mk_dflt_btn;
+ rep.axTimeout = xkb->ax_timeout;
+ rep.axtCtrlsMask = xkb->axt_ctrls_mask;
+ rep.axtCtrlsValues = xkb->axt_ctrls_values;
+ rep.axtOptsMask = xkb->axt_opts_mask;
+ rep.axtOptsValues = xkb->axt_opts_values;
+ rep.axOptions = xkb->ax_options;
+ memcpy(rep.perKeyRepeat,xkb->per_key_repeat,XkbPerKeyBitArraySize);
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.length,n);
+ swaps(&rep.internalVMods, n);
+ swaps(&rep.ignoreLockVMods, n);
+ swapl(&rep.enabledCtrls, n);
+ swaps(&rep.repeatDelay, n);
+ swaps(&rep.repeatInterval, n);
+ swaps(&rep.slowKeysDelay, n);
+ swaps(&rep.debounceDelay, n);
+ swaps(&rep.mkDelay, n);
+ swaps(&rep.mkInterval, n);
+ swaps(&rep.mkTimeToMax, n);
+ swaps(&rep.mkMaxSpeed, n);
+ swaps(&rep.mkCurve, n);
+ swaps(&rep.axTimeout, n);
+ swapl(&rep.axtCtrlsMask, n);
+ swapl(&rep.axtCtrlsValues, n);
+ swaps(&rep.axtOptsMask, n);
+ swaps(&rep.axtOptsValues, n);
+ swaps(&rep.axOptions, n);
+ }
+ WriteToClient(client, SIZEOF(xkbGetControlsReply), (char *)&rep);
+ return(client->noClientException);
+}
+
+int
+ProcXkbSetControls(ClientPtr client)
+{
+ DeviceIntPtr dev, tmpd;
+ XkbSrvInfoPtr xkbi;
+ XkbControlsPtr ctrl;
+ XkbControlsRec new,old;
+ xkbControlsNotify cn;
+ XkbEventCauseRec cause;
+ XkbSrvLedInfoPtr sli;
+
+ REQUEST(xkbSetControlsReq);
+ REQUEST_SIZE_MATCH(xkbSetControlsReq);
+
+ if (!(client->xkbClientFlags & _XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
+ CHK_MASK_LEGAL(0x01, stuff->changeCtrls, XkbAllControlsMask);
+
+ for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
+ if (!tmpd->key || !tmpd->key->xkbInfo)
+ continue;
+ if ((tmpd == dev) || (!IsMaster(tmpd) && tmpd->u.master == dev)) {
+ xkbi = tmpd->key->xkbInfo;
+ ctrl = xkbi->desc->ctrls;
+ new = *ctrl;
+ XkbSetCauseXkbReq(&cause, X_kbSetControls, client);
+
+ if (stuff->changeCtrls & XkbInternalModsMask) {
+ CHK_MASK_MATCH(0x02, stuff->affectInternalMods,
+ stuff->internalMods);
+ CHK_MASK_MATCH(0x03, stuff->affectInternalVMods,
+ stuff->internalVMods);
+
+ new.internal.real_mods &= ~(stuff->affectInternalMods);
+ new.internal.real_mods |= (stuff->affectInternalMods &
+ stuff->internalMods);
+ new.internal.vmods &= ~(stuff->affectInternalVMods);
+ new.internal.vmods |= (stuff->affectInternalVMods &
+ stuff->internalVMods);
+ new.internal.mask = new.internal.real_mods |
+ XkbMaskForVMask(xkbi->desc,
+ new.internal.vmods);
+ }
+
+ if (stuff->changeCtrls & XkbIgnoreLockModsMask) {
+ CHK_MASK_MATCH(0x4, stuff->affectIgnoreLockMods,
+ stuff->ignoreLockMods);
+ CHK_MASK_MATCH(0x5, stuff->affectIgnoreLockVMods,
+ stuff->ignoreLockVMods);
+
+ new.ignore_lock.real_mods &= ~(stuff->affectIgnoreLockMods);
+ new.ignore_lock.real_mods |= (stuff->affectIgnoreLockMods &
+ stuff->ignoreLockMods);
+ new.ignore_lock.vmods &= ~(stuff->affectIgnoreLockVMods);
+ new.ignore_lock.vmods |= (stuff->affectIgnoreLockVMods &
+ stuff->ignoreLockVMods);
+ new.ignore_lock.mask = new.ignore_lock.real_mods |
+ XkbMaskForVMask(xkbi->desc,
+ new.ignore_lock.vmods);
+ }
+
+ CHK_MASK_MATCH(0x06, stuff->affectEnabledCtrls,
+ stuff->enabledCtrls);
+ if (stuff->affectEnabledCtrls) {
+ CHK_MASK_LEGAL(0x07, stuff->affectEnabledCtrls,
+ XkbAllBooleanCtrlsMask);
+
+ new.enabled_ctrls &= ~(stuff->affectEnabledCtrls);
+ new.enabled_ctrls |= (stuff->affectEnabledCtrls &
+ stuff->enabledCtrls);
+ }
+
+ if (stuff->changeCtrls & XkbRepeatKeysMask) {
+ if (stuff->repeatDelay < 1 || stuff->repeatInterval < 1) {
+ client->errorValue = _XkbErrCode3(0x08, stuff->repeatDelay,
+ stuff->repeatInterval);
+ return BadValue;
+ }
+
+ new.repeat_delay = stuff->repeatDelay;
+ new.repeat_interval = stuff->repeatInterval;
+ }
+
+ if (stuff->changeCtrls & XkbSlowKeysMask) {
+ if (stuff->slowKeysDelay < 1) {
+ client->errorValue = _XkbErrCode2(0x09,
+ stuff->slowKeysDelay);
+ return BadValue;
+ }
+
+ new.slow_keys_delay = stuff->slowKeysDelay;
+ }
+
+ if (stuff->changeCtrls & XkbBounceKeysMask) {
+ if (stuff->debounceDelay < 1) {
+ client->errorValue = _XkbErrCode2(0x0A,
+ stuff->debounceDelay);
+ return BadValue;
+ }
+
+ new.debounce_delay = stuff->debounceDelay;
+ }
+
+ if (stuff->changeCtrls & XkbMouseKeysMask) {
+ if (stuff->mkDfltBtn > XkbMaxMouseKeysBtn) {
+ client->errorValue = _XkbErrCode2(0x0B, stuff->mkDfltBtn);
+ return BadValue;
+ }
+
+ new.mk_dflt_btn = stuff->mkDfltBtn;
+ }
+
+ if (stuff->changeCtrls & XkbMouseKeysAccelMask) {
+ if (stuff->mkDelay < 1 || stuff->mkInterval < 1 ||
+ stuff->mkTimeToMax < 1 || stuff->mkMaxSpeed < 1 ||
+ stuff->mkCurve < -1000) {
+ client->errorValue = _XkbErrCode2(0x0C,0);
+ return BadValue;
+ }
+
+ new.mk_delay = stuff->mkDelay;
+ new.mk_interval = stuff->mkInterval;
+ new.mk_time_to_max = stuff->mkTimeToMax;
+ new.mk_max_speed = stuff->mkMaxSpeed;
+ new.mk_curve = stuff->mkCurve;
+ AccessXComputeCurveFactor(xkbi, &new);
+ }
+
+ if (stuff->changeCtrls & XkbGroupsWrapMask) {
+ unsigned act, num;
+
+ act = XkbOutOfRangeGroupAction(stuff->groupsWrap);
+ switch (act) {
+ case XkbRedirectIntoRange:
+ num = XkbOutOfRangeGroupNumber(stuff->groupsWrap);
+ if (num >= new.num_groups) {
+ client->errorValue = _XkbErrCode3(0x0D, new.num_groups,
+ num);
+ return BadValue;
+ }
+ case XkbWrapIntoRange:
+ case XkbClampIntoRange:
+ break;
+ default:
+ client->errorValue = _XkbErrCode2(0x0E, act);
+ return BadValue;
+ }
+
+ new.groups_wrap= stuff->groupsWrap;
+ }
+
+ CHK_MASK_LEGAL(0x0F, stuff->axOptions, XkbAX_AllOptionsMask);
+ if (stuff->changeCtrls & XkbAccessXKeysMask) {
+ new.ax_options = stuff->axOptions & XkbAX_AllOptionsMask;
+ }
+ else {
+ if (stuff->changeCtrls & XkbStickyKeysMask) {
+ new.ax_options &= ~(XkbAX_SKOptionsMask);
+ new.ax_options |= (stuff->axOptions & XkbAX_SKOptionsMask);
+ }
+
+ if (stuff->changeCtrls & XkbAccessXFeedbackMask) {
+ new.ax_options &= ~(XkbAX_FBOptionsMask);
+ new.ax_options |= (stuff->axOptions & XkbAX_FBOptionsMask);
+ }
+ }
+
+ if (stuff->changeCtrls & XkbAccessXTimeoutMask) {
+ if (stuff->axTimeout < 1) {
+ client->errorValue = _XkbErrCode2(0x10, stuff->axTimeout);
+ return BadValue;
+ }
+ CHK_MASK_MATCH(0x11, stuff->axtCtrlsMask,
+ stuff->axtCtrlsValues);
+ CHK_MASK_LEGAL(0x12, stuff->axtCtrlsMask,
+ XkbAllBooleanCtrlsMask);
+ CHK_MASK_MATCH(0x13, stuff->axtOptsMask, stuff->axtOptsValues);
+ CHK_MASK_LEGAL(0x14, stuff->axtOptsMask, XkbAX_AllOptionsMask);
+ new.ax_timeout = stuff->axTimeout;
+ new.axt_ctrls_mask = stuff->axtCtrlsMask;
+ new.axt_ctrls_values = (stuff->axtCtrlsValues &
+ stuff->axtCtrlsMask);
+ new.axt_opts_mask = stuff->axtOptsMask;
+ new.axt_opts_values = (stuff->axtOptsValues &
+ stuff->axtOptsMask);
+ }
+
+ if (stuff->changeCtrls & XkbPerKeyRepeatMask)
+ memcpy(new.per_key_repeat, stuff->perKeyRepeat,
+ XkbPerKeyBitArraySize);
+
+ old= *ctrl;
+ *ctrl= new;
+ XkbDDXChangeControls(tmpd, &old, ctrl);
+
+ if (XkbComputeControlsNotify(tmpd, &old, ctrl, &cn, FALSE)) {
+ cn.keycode = 0;
+ cn.eventType = 0;
+ cn.requestMajor = XkbReqCode;
+ cn.requestMinor = X_kbSetControls;
+ XkbSendControlsNotify(tmpd, &cn);
+ }
+
+ sli = XkbFindSrvLedInfo(tmpd, XkbDfltXIClass, XkbDfltXIId, 0);
+ if (sli)
+ XkbUpdateIndicators(tmpd, sli->usesControls, TRUE, NULL,
+ &cause);
+
+ /* If sticky keys were disabled, clear all locks and latches */
+ if ((old.enabled_ctrls & XkbStickyKeysMask) &&
+ !(ctrl->enabled_ctrls & XkbStickyKeysMask))
+ XkbClearAllLatchesAndLocks(tmpd, xkbi, TRUE, &cause);
+ }
+ }
+
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+static int
+XkbSizeKeyTypes(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ XkbKeyTypeRec *type;
+ unsigned i,len;
+
+ len= 0;
+ if (((rep->present&XkbKeyTypesMask)==0)||(rep->nTypes<1)||
+ (!xkb)||(!xkb->map)||(!xkb->map->types)) {
+ rep->present&= ~XkbKeyTypesMask;
+ rep->firstType= rep->nTypes= 0;
+ return 0;
+ }
+ type= &xkb->map->types[rep->firstType];
+ for (i=0;i<rep->nTypes;i++,type++){
+ len+= SIZEOF(xkbKeyTypeWireDesc);
+ if (type->map_count>0) {
+ len+= (type->map_count*SIZEOF(xkbKTMapEntryWireDesc));
+ if (type->preserve)
+ len+= (type->map_count*SIZEOF(xkbModsWireDesc));
+ }
+ }
+ return len;
+}
+
+static char *
+XkbWriteKeyTypes( XkbDescPtr xkb,
+ xkbGetMapReply * rep,
+ char * buf,
+ ClientPtr client)
+{
+ XkbKeyTypePtr type;
+ unsigned i;
+ xkbKeyTypeWireDesc *wire;
+
+ type= &xkb->map->types[rep->firstType];
+ for (i=0;i<rep->nTypes;i++,type++) {
+ register unsigned n;
+ wire= (xkbKeyTypeWireDesc *)buf;
+ wire->mask = type->mods.mask;
+ wire->realMods = type->mods.real_mods;
+ wire->virtualMods = type->mods.vmods;
+ wire->numLevels = type->num_levels;
+ wire->nMapEntries = type->map_count;
+ wire->preserve = (type->preserve!=NULL);
+ if (client->swapped) {
+ register int n;
+ swaps(&wire->virtualMods,n);
+ }
+
+ buf= (char *)&wire[1];
+ if (wire->nMapEntries>0) {
+ xkbKTMapEntryWireDesc * wire;
+ XkbKTMapEntryPtr entry;
+ wire= (xkbKTMapEntryWireDesc *)buf;
+ entry= type->map;
+ for (n=0;n<type->map_count;n++,wire++,entry++) {
+ wire->active= entry->active;
+ wire->mask= entry->mods.mask;
+ wire->level= entry->level;
+ wire->realMods= entry->mods.real_mods;
+ wire->virtualMods= entry->mods.vmods;
+ if (client->swapped) {
+ register int n;
+ swaps(&wire->virtualMods,n);
+ }
+ }
+ buf= (char *)wire;
+ if (type->preserve!=NULL) {
+ xkbModsWireDesc * pwire;
+ XkbModsPtr preserve;
+ pwire= (xkbModsWireDesc *)buf;
+ preserve= type->preserve;
+ for (n=0;n<type->map_count;n++,pwire++,preserve++) {
+ pwire->mask= preserve->mask;
+ pwire->realMods= preserve->real_mods;
+ pwire->virtualMods= preserve->vmods;
+ if (client->swapped) {
+ register int n;
+ swaps(&pwire->virtualMods,n);
+ }
+ }
+ buf= (char *)pwire;
+ }
+ }
+ }
+ return buf;
+}
+
+static int
+XkbSizeKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ XkbSymMapPtr symMap;
+ unsigned i,len;
+ unsigned nSyms,nSymsThisKey;
+
+ if (((rep->present&XkbKeySymsMask)==0)||(rep->nKeySyms<1)||
+ (!xkb)||(!xkb->map)||(!xkb->map->key_sym_map)) {
+ rep->present&= ~XkbKeySymsMask;
+ rep->firstKeySym= rep->nKeySyms= 0;
+ rep->totalSyms= 0;
+ return 0;
+ }
+ len= rep->nKeySyms*SIZEOF(xkbSymMapWireDesc);
+ symMap = &xkb->map->key_sym_map[rep->firstKeySym];
+ for (i=nSyms=0;i<rep->nKeySyms;i++,symMap++) {
+ if (symMap->offset!=0) {
+ nSymsThisKey= XkbNumGroups(symMap->group_info)*symMap->width;
+ nSyms+= nSymsThisKey;
+ }
+ }
+ len+= nSyms*4;
+ rep->totalSyms= nSyms;
+ return len;
+}
+
+static int
+XkbSizeVirtualMods(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+register unsigned i,nMods,bit;
+
+ if (((rep->present&XkbVirtualModsMask)==0)||(rep->virtualMods==0)||
+ (!xkb)||(!xkb->server)) {
+ rep->present&= ~XkbVirtualModsMask;
+ rep->virtualMods= 0;
+ return 0;
+ }
+ for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (rep->virtualMods&bit)
+ nMods++;
+ }
+ return XkbPaddedSize(nMods);
+}
+
+static char *
+XkbWriteKeySyms(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client)
+{
+register KeySym * pSym;
+XkbSymMapPtr symMap;
+xkbSymMapWireDesc * outMap;
+register unsigned i;
+
+ symMap = &xkb->map->key_sym_map[rep->firstKeySym];
+ for (i=0;i<rep->nKeySyms;i++,symMap++) {
+ outMap = (xkbSymMapWireDesc *)buf;
+ outMap->ktIndex[0] = symMap->kt_index[0];
+ outMap->ktIndex[1] = symMap->kt_index[1];
+ outMap->ktIndex[2] = symMap->kt_index[2];
+ outMap->ktIndex[3] = symMap->kt_index[3];
+ outMap->groupInfo = symMap->group_info;
+ outMap->width= symMap->width;
+ outMap->nSyms = symMap->width*XkbNumGroups(symMap->group_info);
+ buf= (char *)&outMap[1];
+ if (outMap->nSyms==0)
+ continue;
+
+ pSym = &xkb->map->syms[symMap->offset];
+ memcpy((char *)buf,(char *)pSym,outMap->nSyms*4);
+ if (client->swapped) {
+ register int n,nSyms= outMap->nSyms;
+ swaps(&outMap->nSyms,n);
+ while (nSyms-->0) {
+ swapl(buf,n);
+ buf+= 4;
+ }
+ }
+ else buf+= outMap->nSyms*4;
+ }
+ return buf;
+}
+
+static int
+XkbSizeKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ unsigned i,len,nActs;
+ register KeyCode firstKey;
+
+ if (((rep->present&XkbKeyActionsMask)==0)||(rep->nKeyActs<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->key_acts)) {
+ rep->present&= ~XkbKeyActionsMask;
+ rep->firstKeyAct= rep->nKeyActs= 0;
+ rep->totalActs= 0;
+ return 0;
+ }
+ firstKey= rep->firstKeyAct;
+ for (nActs=i=0;i<rep->nKeyActs;i++) {
+ if (xkb->server->key_acts[i+firstKey]!=0)
+ nActs+= XkbKeyNumActions(xkb,i+firstKey);
+ }
+ len= XkbPaddedSize(rep->nKeyActs)+(nActs*SIZEOF(xkbActionWireDesc));
+ rep->totalActs= nActs;
+ return len;
+}
+
+static char *
+XkbWriteKeyActions(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+{
+ unsigned i;
+ CARD8 * numDesc;
+ XkbAnyAction * actDesc;
+
+ numDesc = (CARD8 *)buf;
+ for (i=0;i<rep->nKeyActs;i++) {
+ if (xkb->server->key_acts[i+rep->firstKeyAct]==0)
+ numDesc[i] = 0;
+ else numDesc[i] = XkbKeyNumActions(xkb,(i+rep->firstKeyAct));
+ }
+ buf+= XkbPaddedSize(rep->nKeyActs);
+
+ actDesc = (XkbAnyAction *)buf;
+ for (i=0;i<rep->nKeyActs;i++) {
+ if (xkb->server->key_acts[i+rep->firstKeyAct]!=0) {
+ unsigned int num;
+ num = XkbKeyNumActions(xkb,(i+rep->firstKeyAct));
+ memcpy((char *)actDesc,
+ (char*)XkbKeyActionsPtr(xkb,(i+rep->firstKeyAct)),
+ num*SIZEOF(xkbActionWireDesc));
+ actDesc+= num;
+ }
+ }
+ buf = (char *)actDesc;
+ return buf;
+}
+
+static int
+XkbSizeKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ unsigned i,len,nBhvr;
+ XkbBehavior * bhv;
+
+ if (((rep->present&XkbKeyBehaviorsMask)==0)||(rep->nKeyBehaviors<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->behaviors)) {
+ rep->present&= ~XkbKeyBehaviorsMask;
+ rep->firstKeyBehavior= rep->nKeyBehaviors= 0;
+ rep->totalKeyBehaviors= 0;
+ return 0;
+ }
+ bhv= &xkb->server->behaviors[rep->firstKeyBehavior];
+ for (nBhvr=i=0;i<rep->nKeyBehaviors;i++,bhv++) {
+ if (bhv->type!=XkbKB_Default)
+ nBhvr++;
+ }
+ len= nBhvr*SIZEOF(xkbBehaviorWireDesc);
+ rep->totalKeyBehaviors= nBhvr;
+ return len;
+}
+
+static char *
+XkbWriteKeyBehaviors(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+{
+ unsigned i;
+ xkbBehaviorWireDesc *wire;
+ XkbBehavior *pBhvr;
+
+ wire = (xkbBehaviorWireDesc *)buf;
+ pBhvr= &xkb->server->behaviors[rep->firstKeyBehavior];
+ for (i=0;i<rep->nKeyBehaviors;i++,pBhvr++) {
+ if (pBhvr->type!=XkbKB_Default) {
+ wire->key= i+rep->firstKeyBehavior;
+ wire->type= pBhvr->type;
+ wire->data= pBhvr->data;
+ wire++;
+ }
+ }
+ buf = (char *)wire;
+ return buf;
+}
+
+static int
+XkbSizeExplicit(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ unsigned i,len,nRtrn;
+
+ if (((rep->present&XkbExplicitComponentsMask)==0)||(rep->nKeyExplicit<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->explicit)) {
+ rep->present&= ~XkbExplicitComponentsMask;
+ rep->firstKeyExplicit= rep->nKeyExplicit= 0;
+ rep->totalKeyExplicit= 0;
+ return 0;
+ }
+ for (nRtrn=i=0;i<rep->nKeyExplicit;i++) {
+ if (xkb->server->explicit[i+rep->firstKeyExplicit]!=0)
+ nRtrn++;
+ }
+ rep->totalKeyExplicit= nRtrn;
+ len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero explicit component */
+ return len;
+}
+
+static char *
+XkbWriteExplicit(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,ClientPtr client)
+{
+unsigned i;
+char * start;
+unsigned char * pExp;
+
+ start= buf;
+ pExp= &xkb->server->explicit[rep->firstKeyExplicit];
+ for (i=0;i<rep->nKeyExplicit;i++,pExp++) {
+ if (*pExp!=0) {
+ *buf++= i+rep->firstKeyExplicit;
+ *buf++= *pExp;
+ }
+ }
+ i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */
+ return buf+i;
+}
+
+static int
+XkbSizeModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ unsigned i,len,nRtrn;
+
+ if (((rep->present&XkbModifierMapMask)==0)||(rep->nModMapKeys<1)||
+ (!xkb)||(!xkb->map)||(!xkb->map->modmap)) {
+ rep->present&= ~XkbModifierMapMask;
+ rep->firstModMapKey= rep->nModMapKeys= 0;
+ rep->totalModMapKeys= 0;
+ return 0;
+ }
+ for (nRtrn=i=0;i<rep->nModMapKeys;i++) {
+ if (xkb->map->modmap[i+rep->firstModMapKey]!=0)
+ nRtrn++;
+ }
+ rep->totalModMapKeys= nRtrn;
+ len= XkbPaddedSize(nRtrn*2); /* two bytes per non-zero modmap component */
+ return len;
+}
+
+static char *
+XkbWriteModifierMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+{
+unsigned i;
+char * start;
+unsigned char * pMap;
+
+ start= buf;
+ pMap= &xkb->map->modmap[rep->firstModMapKey];
+ for (i=0;i<rep->nModMapKeys;i++,pMap++) {
+ if (*pMap!=0) {
+ *buf++= i+rep->firstModMapKey;
+ *buf++= *pMap;
+ }
+ }
+ i= XkbPaddedSize(buf-start)-(buf-start); /* pad to word boundary */
+ return buf+i;
+}
+
+static int
+XkbSizeVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+ unsigned i,len,nRtrn;
+
+ if (((rep->present&XkbVirtualModMapMask)==0)||(rep->nVModMapKeys<1)||
+ (!xkb)||(!xkb->server)||(!xkb->server->vmodmap)) {
+ rep->present&= ~XkbVirtualModMapMask;
+ rep->firstVModMapKey= rep->nVModMapKeys= 0;
+ rep->totalVModMapKeys= 0;
+ return 0;
+ }
+ for (nRtrn=i=0;i<rep->nVModMapKeys;i++) {
+ if (xkb->server->vmodmap[i+rep->firstVModMapKey]!=0)
+ nRtrn++;
+ }
+ rep->totalVModMapKeys= nRtrn;
+ len= nRtrn*SIZEOF(xkbVModMapWireDesc);
+ return len;
+}
+
+static char *
+XkbWriteVirtualModMap(XkbDescPtr xkb,xkbGetMapReply *rep,char *buf,
+ ClientPtr client)
+{
+unsigned i;
+xkbVModMapWireDesc * wire;
+unsigned short * pMap;
+
+ wire= (xkbVModMapWireDesc *)buf;
+ pMap= &xkb->server->vmodmap[rep->firstVModMapKey];
+ for (i=0;i<rep->nVModMapKeys;i++,pMap++) {
+ if (*pMap!=0) {
+ wire->key= i+rep->firstVModMapKey;
+ wire->vmods= *pMap;
+ wire++;
+ }
+ }
+ return (char *)wire;
+}
+
+static Status
+XkbComputeGetMapReplySize(XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+int len;
+
+ rep->minKeyCode= xkb->min_key_code;
+ rep->maxKeyCode= xkb->max_key_code;
+ len= XkbSizeKeyTypes(xkb,rep);
+ len+= XkbSizeKeySyms(xkb,rep);
+ len+= XkbSizeKeyActions(xkb,rep);
+ len+= XkbSizeKeyBehaviors(xkb,rep);
+ len+= XkbSizeVirtualMods(xkb,rep);
+ len+= XkbSizeExplicit(xkb,rep);
+ len+= XkbSizeModifierMap(xkb,rep);
+ len+= XkbSizeVirtualModMap(xkb,rep);
+ rep->length+= (len/4);
+ return Success;
+}
+
+static int
+XkbSendMap(ClientPtr client,XkbDescPtr xkb,xkbGetMapReply *rep)
+{
+unsigned i,len;
+char *desc,*start;
+
+ len= (rep->length*4)-(SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply));
+ start= desc= xcalloc(1, len);
+ if (!start)
+ return BadAlloc;
+ if ( rep->nTypes>0 )
+ desc = XkbWriteKeyTypes(xkb,rep,desc,client);
+ if ( rep->nKeySyms>0 )
+ desc = XkbWriteKeySyms(xkb,rep,desc,client);
+ if ( rep->nKeyActs>0 )
+ desc = XkbWriteKeyActions(xkb,rep,desc,client);
+ if ( rep->totalKeyBehaviors>0 )
+ desc = XkbWriteKeyBehaviors(xkb,rep,desc,client);
+ if ( rep->virtualMods ) {
+ register int sz,bit;
+ for (i=sz=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (rep->virtualMods&bit) {
+ desc[sz++]= xkb->server->vmods[i];
+ }
+ }
+ desc+= XkbPaddedSize(sz);
+ }
+ if ( rep->totalKeyExplicit>0 )
+ desc= XkbWriteExplicit(xkb,rep,desc,client);
+ if ( rep->totalModMapKeys>0 )
+ desc= XkbWriteModifierMap(xkb,rep,desc,client);
+ if ( rep->totalVModMapKeys>0 )
+ desc= XkbWriteVirtualModMap(xkb,rep,desc,client);
+ if ((desc-start)!=(len)) {
+ ErrorF("[xkb] BOGUS LENGTH in write keyboard desc, expected %d, got %ld\n",
+ len, (unsigned long)(desc-start));
+ }
+ if (client->swapped) {
+ register int n;
+ swaps(&rep->sequenceNumber,n);
+ swapl(&rep->length,n);
+ swaps(&rep->present,n);
+ swaps(&rep->totalSyms,n);
+ swaps(&rep->totalActs,n);
+ }
+ WriteToClient(client, (i=SIZEOF(xkbGetMapReply)), (char *)rep);
+ WriteToClient(client, len, start);
+ xfree((char *)start);
+ return client->noClientException;
+}
+
+int
+ProcXkbGetMap(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xkbGetMapReply rep;
+ XkbDescRec *xkb;
+ int n,status;
+
+ REQUEST(xkbGetMapReq);
+ REQUEST_SIZE_MATCH(xkbGetMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+ CHK_MASK_OVERLAP(0x01,stuff->full,stuff->partial);
+ CHK_MASK_LEGAL(0x02,stuff->full,XkbAllMapComponentsMask);
+ CHK_MASK_LEGAL(0x03,stuff->partial,XkbAllMapComponentsMask);
+
+ xkb= dev->key->xkbInfo->desc;
+ bzero(&rep,sizeof(xkbGetMapReply));
+ rep.type= X_Reply;
+ rep.sequenceNumber= client->sequence;
+ rep.length = (SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2;
+ rep.deviceID = dev->id;
+ rep.present = stuff->partial|stuff->full;
+ rep.minKeyCode = xkb->min_key_code;
+ rep.maxKeyCode = xkb->max_key_code;
+ if ( stuff->full&XkbKeyTypesMask ) {
+ rep.firstType = 0;
+ rep.nTypes = xkb->map->num_types;
+ }
+ else if (stuff->partial&XkbKeyTypesMask) {
+ if (((unsigned)stuff->firstType+stuff->nTypes)>xkb->map->num_types) {
+ client->errorValue = _XkbErrCode4(0x04,xkb->map->num_types,
+ stuff->firstType,stuff->nTypes);
+ return BadValue;
+ }
+ rep.firstType = stuff->firstType;
+ rep.nTypes = stuff->nTypes;
+ }
+ else rep.nTypes = 0;
+ rep.totalTypes = xkb->map->num_types;
+
+ n= XkbNumKeys(xkb);
+ if ( stuff->full&XkbKeySymsMask ) {
+ rep.firstKeySym = xkb->min_key_code;
+ rep.nKeySyms = n;
+ }
+ else if (stuff->partial&XkbKeySymsMask) {
+ CHK_KEY_RANGE(0x05,stuff->firstKeySym,stuff->nKeySyms,xkb);
+ rep.firstKeySym = stuff->firstKeySym;
+ rep.nKeySyms = stuff->nKeySyms;
+ }
+ else rep.nKeySyms = 0;
+ rep.totalSyms= 0;
+
+ if ( stuff->full&XkbKeyActionsMask ) {
+ rep.firstKeyAct= xkb->min_key_code;
+ rep.nKeyActs= n;
+ }
+ else if (stuff->partial&XkbKeyActionsMask) {
+ CHK_KEY_RANGE(0x07,stuff->firstKeyAct,stuff->nKeyActs,xkb);
+ rep.firstKeyAct= stuff->firstKeyAct;
+ rep.nKeyActs= stuff->nKeyActs;
+ }
+ else rep.nKeyActs= 0;
+ rep.totalActs= 0;
+
+ if ( stuff->full&XkbKeyBehaviorsMask ) {
+ rep.firstKeyBehavior = xkb->min_key_code;
+ rep.nKeyBehaviors = n;
+ }
+ else if (stuff->partial&XkbKeyBehaviorsMask) {
+ CHK_KEY_RANGE(0x09,stuff->firstKeyBehavior,stuff->nKeyBehaviors,xkb);
+ rep.firstKeyBehavior= stuff->firstKeyBehavior;
+ rep.nKeyBehaviors= stuff->nKeyBehaviors;
+ }
+ else rep.nKeyBehaviors = 0;
+ rep.totalKeyBehaviors= 0;
+
+ if (stuff->full&XkbVirtualModsMask)
+ rep.virtualMods= ~0;
+ else if (stuff->partial&XkbVirtualModsMask)
+ rep.virtualMods= stuff->virtualMods;
+
+ if (stuff->full&XkbExplicitComponentsMask) {
+ rep.firstKeyExplicit= xkb->min_key_code;
+ rep.nKeyExplicit= n;
+ }
+ else if (stuff->partial&XkbExplicitComponentsMask) {
+ CHK_KEY_RANGE(0x0B,stuff->firstKeyExplicit,stuff->nKeyExplicit,xkb);
+ rep.firstKeyExplicit= stuff->firstKeyExplicit;
+ rep.nKeyExplicit= stuff->nKeyExplicit;
+ }
+ else rep.nKeyExplicit = 0;
+ rep.totalKeyExplicit= 0;
+
+ if (stuff->full&XkbModifierMapMask) {
+ rep.firstModMapKey= xkb->min_key_code;
+ rep.nModMapKeys= n;
+ }
+ else if (stuff->partial&XkbModifierMapMask) {
+ CHK_KEY_RANGE(0x0D,stuff->firstModMapKey,stuff->nModMapKeys,xkb);
+ rep.firstModMapKey= stuff->firstModMapKey;
+ rep.nModMapKeys= stuff->nModMapKeys;
+ }
+ else rep.nModMapKeys = 0;
+ rep.totalModMapKeys= 0;
+
+ if (stuff->full&XkbVirtualModMapMask) {
+ rep.firstVModMapKey= xkb->min_key_code;
+ rep.nVModMapKeys= n;
+ }
+ else if (stuff->partial&XkbVirtualModMapMask) {
+ CHK_KEY_RANGE(0x0F,stuff->firstVModMapKey,stuff->nVModMapKeys,xkb);
+ rep.firstVModMapKey= stuff->firstVModMapKey;
+ rep.nVModMapKeys= stuff->nVModMapKeys;
+ }
+ else rep.nVModMapKeys = 0;
+ rep.totalVModMapKeys= 0;
+
+ if ((status=XkbComputeGetMapReplySize(xkb,&rep))!=Success)
+ return status;
+ return XkbSendMap(client,xkb,&rep);
+}
+
+/***====================================================================***/
+
+static int
+CheckKeyTypes( ClientPtr client,
+ XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbKeyTypeWireDesc **wireRtrn,
+ int * nMapsRtrn,
+ CARD8 * mapWidthRtrn)
+{
+unsigned nMaps;
+register unsigned i,n;
+register CARD8 * map;
+register xkbKeyTypeWireDesc *wire = *wireRtrn;
+
+ if (req->firstType>((unsigned)xkb->map->num_types)) {
+ *nMapsRtrn = _XkbErrCode3(0x01,req->firstType,xkb->map->num_types);
+ return 0;
+ }
+ if (req->flags&XkbSetMapResizeTypes) {
+ nMaps = req->firstType+req->nTypes;
+ if (nMaps<XkbNumRequiredTypes) { /* canonical types must be there */
+ *nMapsRtrn= _XkbErrCode4(0x02,req->firstType,req->nTypes,4);
+ return 0;
+ }
+ }
+ else if (req->present&XkbKeyTypesMask) {
+ nMaps = xkb->map->num_types;
+ if ((req->firstType+req->nTypes)>nMaps) {
+ *nMapsRtrn = req->firstType+req->nTypes;
+ return 0;
+ }
+ }
+ else {
+ *nMapsRtrn = xkb->map->num_types;
+ for (i=0;i<xkb->map->num_types;i++) {
+ mapWidthRtrn[i] = xkb->map->types[i].num_levels;
+ }
+ return 1;
+ }
+
+ for (i=0;i<req->firstType;i++) {
+ mapWidthRtrn[i] = xkb->map->types[i].num_levels;
+ }
+ for (i=0;i<req->nTypes;i++) {
+ unsigned width;
+ if (client->swapped) {
+ register int s;
+ swaps(&wire->virtualMods,s);
+ }
+ n= i+req->firstType;
+ width= wire->numLevels;
+ if (width<1) {
+ *nMapsRtrn= _XkbErrCode3(0x04,n,width);
+ return 0;
+ }
+ else if ((n==XkbOneLevelIndex)&&(width!=1)) { /* must be width 1 */
+ *nMapsRtrn= _XkbErrCode3(0x05,n,width);
+ return 0;
+ }
+ else if ((width!=2)&&
+ ((n==XkbTwoLevelIndex)||(n==XkbKeypadIndex)||
+ (n==XkbAlphabeticIndex))) {
+ /* TWO_LEVEL, ALPHABETIC and KEYPAD must be width 2 */
+ *nMapsRtrn= _XkbErrCode3(0x05,n,width);
+ return 0;
+ }
+ if (wire->nMapEntries>0) {
+ xkbKTSetMapEntryWireDesc * mapWire;
+ xkbModsWireDesc * preWire;
+ mapWire= (xkbKTSetMapEntryWireDesc *)&wire[1];
+ preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries];
+ for (n=0;n<wire->nMapEntries;n++) {
+ if (client->swapped) {
+ register int s;
+ swaps(&mapWire[n].virtualMods,s);
+ }
+ if (mapWire[n].realMods&(~wire->realMods)) {
+ *nMapsRtrn= _XkbErrCode4(0x06,n,mapWire[n].realMods,
+ wire->realMods);
+ return 0;
+ }
+ if (mapWire[n].virtualMods&(~wire->virtualMods)) {
+ *nMapsRtrn= _XkbErrCode3(0x07,n,mapWire[n].virtualMods);
+ return 0;
+ }
+ if (mapWire[n].level>=wire->numLevels) {
+ *nMapsRtrn= _XkbErrCode4(0x08,n,wire->numLevels,
+ mapWire[n].level);
+ return 0;
+ }
+ if (wire->preserve) {
+ if (client->swapped) {
+ register int s;
+ swaps(&preWire[n].virtualMods,s);
+ }
+ if (preWire[n].realMods&(~mapWire[n].realMods)) {
+ *nMapsRtrn= _XkbErrCode4(0x09,n,preWire[n].realMods,
+ mapWire[n].realMods);
+ return 0;
+ }
+ if (preWire[n].virtualMods&(~mapWire[n].virtualMods)) {
+ *nMapsRtrn=_XkbErrCode3(0x0a,n,preWire[n].virtualMods);
+ return 0;
+ }
+ }
+ }
+ if (wire->preserve)
+ map= (CARD8 *)&preWire[wire->nMapEntries];
+ else map= (CARD8 *)&mapWire[wire->nMapEntries];
+ }
+ else map= (CARD8 *)&wire[1];
+ mapWidthRtrn[i+req->firstType] = wire->numLevels;
+ wire= (xkbKeyTypeWireDesc *)map;
+ }
+ for (i=req->firstType+req->nTypes;i<nMaps;i++) {
+ mapWidthRtrn[i] = xkb->map->types[i].num_levels;
+ }
+ *nMapsRtrn = nMaps;
+ *wireRtrn = wire;
+ return 1;
+}
+
+static int
+CheckKeySyms( ClientPtr client,
+ XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ int nTypes,
+ CARD8 * mapWidths,
+ CARD16 * symsPerKey,
+ xkbSymMapWireDesc ** wireRtrn,
+ int * errorRtrn)
+{
+register unsigned i;
+XkbSymMapPtr map;
+xkbSymMapWireDesc* wire = *wireRtrn;
+
+ if (!(XkbKeySymsMask&req->present))
+ return 1;
+ CHK_REQ_KEY_RANGE2(0x11,req->firstKeySym,req->nKeySyms,req,(*errorRtrn),0);
+ map = &xkb->map->key_sym_map[xkb->min_key_code];
+ for (i=xkb->min_key_code;i<(unsigned)req->firstKeySym;i++,map++) {
+ register int g,ng,w;
+ ng= XkbNumGroups(map->group_info);
+ for (w=g=0;g<ng;g++) {
+ if (map->kt_index[g]>=(unsigned)nTypes) {
+ *errorRtrn = _XkbErrCode4(0x13,i,g,map->kt_index[g]);
+ return 0;
+ }
+ if (mapWidths[map->kt_index[g]]>w)
+ w= mapWidths[map->kt_index[g]];
+ }
+ symsPerKey[i] = w*ng;
+ }
+ for (i=0;i<req->nKeySyms;i++) {
+ KeySym *pSyms;
+ register unsigned nG;
+ if (client->swapped) {
+ swaps(&wire->nSyms,nG);
+ }
+ nG = XkbNumGroups(wire->groupInfo);
+ if (nG>XkbNumKbdGroups) {
+ *errorRtrn = _XkbErrCode3(0x14,i+req->firstKeySym,nG);
+ return 0;
+ }
+ if (nG>0) {
+ register int g,w;
+ for (g=w=0;g<nG;g++) {
+ if (wire->ktIndex[g]>=(unsigned)nTypes) {
+ *errorRtrn= _XkbErrCode4(0x15,i+req->firstKeySym,g,
+ wire->ktIndex[g]);
+ return 0;
+ }
+ if (mapWidths[wire->ktIndex[g]]>w)
+ w= mapWidths[wire->ktIndex[g]];
+ }
+ if (wire->width!=w) {
+ *errorRtrn= _XkbErrCode3(0x16,i+req->firstKeySym,wire->width);
+ return 0;
+ }
+ w*= nG;
+ symsPerKey[i+req->firstKeySym] = w;
+ if (w!=wire->nSyms) {
+ *errorRtrn=_XkbErrCode4(0x16,i+req->firstKeySym,wire->nSyms,w);
+ return 0;
+ }
+ }
+ else if (wire->nSyms!=0) {
+ *errorRtrn = _XkbErrCode3(0x17,i+req->firstKeySym,wire->nSyms);
+ return 0;
+ }
+ pSyms = (KeySym *)&wire[1];
+ wire = (xkbSymMapWireDesc *)&pSyms[wire->nSyms];
+ }
+
+ map = &xkb->map->key_sym_map[i];
+ for (;i<=(unsigned)xkb->max_key_code;i++,map++) {
+ register int g,nG,w;
+ nG= XkbKeyNumGroups(xkb,i);
+ for (w=g=0;g<nG;g++) {
+ if (map->kt_index[g]>=(unsigned)nTypes) {
+ *errorRtrn = _XkbErrCode4(0x18,i,g,map->kt_index[g]);
+ return 0;
+ }
+ if (mapWidths[map->kt_index[g]]>w)
+ w= mapWidths[map->kt_index[g]];
+ }
+ symsPerKey[i] = w*nG;
+ }
+ *wireRtrn = wire;
+ return 1;
+}
+
+static int
+CheckKeyActions( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ int nTypes,
+ CARD8 * mapWidths,
+ CARD16 * symsPerKey,
+ CARD8 ** wireRtrn,
+ int * nActsRtrn)
+{
+int nActs;
+CARD8 * wire = *wireRtrn;
+register unsigned i;
+
+ if (!(XkbKeyActionsMask&req->present))
+ return 1;
+ CHK_REQ_KEY_RANGE2(0x21,req->firstKeyAct,req->nKeyActs,req,(*nActsRtrn),0);
+ for (nActs=i=0;i<req->nKeyActs;i++) {
+ if (wire[0]!=0) {
+ if (wire[0]==symsPerKey[i+req->firstKeyAct])
+ nActs+= wire[0];
+ else {
+ *nActsRtrn= _XkbErrCode3(0x23,i+req->firstKeyAct,wire[0]);
+ return 0;
+ }
+ }
+ wire++;
+ }
+ if (req->nKeyActs%4)
+ wire+= 4-(req->nKeyActs%4);
+ *wireRtrn = (CARD8 *)(((XkbAnyAction *)wire)+nActs);
+ *nActsRtrn = nActs;
+ return 1;
+}
+
+static int
+CheckKeyBehaviors( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbBehaviorWireDesc ** wireRtrn,
+ int * errorRtrn)
+{
+register xkbBehaviorWireDesc * wire = *wireRtrn;
+register XkbServerMapPtr server = xkb->server;
+register unsigned i;
+unsigned first,last;
+
+ if (((req->present&XkbKeyBehaviorsMask)==0)||(req->nKeyBehaviors<1)) {
+ req->present&= ~XkbKeyBehaviorsMask;
+ req->nKeyBehaviors= 0;
+ return 1;
+ }
+ first= req->firstKeyBehavior;
+ last= req->firstKeyBehavior+req->nKeyBehaviors-1;
+ if (first<req->minKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x31,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x32,last,req->maxKeyCode);
+ return 0;
+ }
+
+ for (i=0;i<req->totalKeyBehaviors;i++,wire++) {
+ if ((wire->key<first)||(wire->key>last)) {
+ *errorRtrn = _XkbErrCode4(0x33,first,last,wire->key);
+ return 0;
+ }
+ if ((wire->type&XkbKB_Permanent)&&
+ ((server->behaviors[wire->key].type!=wire->type)||
+ (server->behaviors[wire->key].data!=wire->data))) {
+ *errorRtrn = _XkbErrCode3(0x33,wire->key,wire->type);
+ return 0;
+ }
+ if ((wire->type==XkbKB_RadioGroup)&&
+ ((wire->data&(~XkbKB_RGAllowNone))>XkbMaxRadioGroups)) {
+ *errorRtrn= _XkbErrCode4(0x34,wire->key,wire->data,
+ XkbMaxRadioGroups);
+ return 0;
+ }
+ if ((wire->type==XkbKB_Overlay1)||(wire->type==XkbKB_Overlay2)) {
+ CHK_KEY_RANGE2(0x35,wire->key,1,xkb,*errorRtrn,0);
+ }
+ }
+ *wireRtrn = wire;
+ return 1;
+}
+
+static int
+CheckVirtualMods( XkbDescRec * xkb,
+ xkbSetMapReq * req,
+ CARD8 ** wireRtrn,
+ int * errorRtrn)
+{
+register CARD8 *wire = *wireRtrn;
+register unsigned i,nMods,bit;
+
+ if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0))
+ return 1;
+ for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (req->virtualMods&bit)
+ nMods++;
+ }
+ *wireRtrn= (wire+XkbPaddedSize(nMods));
+ return 1;
+}
+
+static int
+CheckKeyExplicit( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ CARD8 ** wireRtrn,
+ int * errorRtrn)
+{
+register CARD8 * wire = *wireRtrn;
+CARD8 * start;
+register unsigned i;
+int first,last;
+
+ if (((req->present&XkbExplicitComponentsMask)==0)||(req->nKeyExplicit<1)) {
+ req->present&= ~XkbExplicitComponentsMask;
+ req->nKeyExplicit= 0;
+ return 1;
+ }
+ first= req->firstKeyExplicit;
+ last= first+req->nKeyExplicit-1;
+ if (first<req->minKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x51,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errorRtrn = _XkbErrCode3(0x52,last,req->maxKeyCode);
+ return 0;
+ }
+ start= wire;
+ for (i=0;i<req->totalKeyExplicit;i++,wire+=2) {
+ if ((wire[0]<first)||(wire[0]>last)) {
+ *errorRtrn = _XkbErrCode4(0x53,first,last,wire[0]);
+ return 0;
+ }
+ if (wire[1]&(~XkbAllExplicitMask)) {
+ *errorRtrn= _XkbErrCode3(0x52,~XkbAllExplicitMask,wire[1]);
+ return 0;
+ }
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ *wireRtrn= wire;
+ return 1;
+}
+
+static int
+CheckModifierMap(XkbDescPtr xkb,xkbSetMapReq *req,CARD8 **wireRtrn,int *errRtrn)
+{
+register CARD8 * wire = *wireRtrn;
+CARD8 * start;
+register unsigned i;
+int first,last;
+
+ if (((req->present&XkbModifierMapMask)==0)||(req->nModMapKeys<1)) {
+ req->present&= ~XkbModifierMapMask;
+ req->nModMapKeys= 0;
+ return 1;
+ }
+ first= req->firstModMapKey;
+ last= first+req->nModMapKeys-1;
+ if (first<req->minKeyCode) {
+ *errRtrn = _XkbErrCode3(0x61,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errRtrn = _XkbErrCode3(0x62,last,req->maxKeyCode);
+ return 0;
+ }
+ start= wire;
+ for (i=0;i<req->totalModMapKeys;i++,wire+=2) {
+ if ((wire[0]<first)||(wire[0]>last)) {
+ *errRtrn = _XkbErrCode4(0x63,first,last,wire[0]);
+ return 0;
+ }
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ *wireRtrn= wire;
+ return 1;
+}
+
+static int
+CheckVirtualModMap( XkbDescPtr xkb,
+ xkbSetMapReq *req,
+ xkbVModMapWireDesc **wireRtrn,
+ int *errRtrn)
+{
+register xkbVModMapWireDesc * wire = *wireRtrn;
+register unsigned i;
+int first,last;
+
+ if (((req->present&XkbVirtualModMapMask)==0)||(req->nVModMapKeys<1)) {
+ req->present&= ~XkbVirtualModMapMask;
+ req->nVModMapKeys= 0;
+ return 1;
+ }
+ first= req->firstVModMapKey;
+ last= first+req->nVModMapKeys-1;
+ if (first<req->minKeyCode) {
+ *errRtrn = _XkbErrCode3(0x71,first,req->minKeyCode);
+ return 0;
+ }
+ if (last>req->maxKeyCode) {
+ *errRtrn = _XkbErrCode3(0x72,last,req->maxKeyCode);
+ return 0;
+ }
+ for (i=0;i<req->totalVModMapKeys;i++,wire++) {
+ if ((wire->key<first)||(wire->key>last)) {
+ *errRtrn = _XkbErrCode4(0x73,first,last,wire->key);
+ return 0;
+ }
+ }
+ *wireRtrn= wire;
+ return 1;
+}
+
+static char *
+SetKeyTypes( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbKeyTypeWireDesc * wire,
+ XkbChangesPtr changes)
+{
+register unsigned i;
+unsigned first,last;
+CARD8 *map;
+
+ if ((unsigned)(req->firstType+req->nTypes)>xkb->map->size_types) {
+ i= req->firstType+req->nTypes;
+ if (XkbAllocClientMap(xkb,XkbKeyTypesMask,i)!=Success) {
+ return NULL;
+ }
+ }
+ if ((unsigned)(req->firstType+req->nTypes)>xkb->map->num_types)
+ xkb->map->num_types= req->firstType+req->nTypes;
+
+ for (i=0;i<req->nTypes;i++) {
+ XkbKeyTypePtr pOld;
+ register unsigned n;
+
+ if (XkbResizeKeyType(xkb,i+req->firstType,wire->nMapEntries,
+ wire->preserve,wire->numLevels)!=Success) {
+ return NULL;
+ }
+ pOld = &xkb->map->types[i+req->firstType];
+ map = (CARD8 *)&wire[1];
+
+ pOld->mods.real_mods = wire->realMods;
+ pOld->mods.vmods= wire->virtualMods;
+ pOld->num_levels = wire->numLevels;
+ pOld->map_count= wire->nMapEntries;
+
+ pOld->mods.mask= pOld->mods.real_mods|
+ XkbMaskForVMask(xkb,pOld->mods.vmods);
+
+ if (wire->nMapEntries) {
+ xkbKTSetMapEntryWireDesc *mapWire;
+ xkbModsWireDesc *preWire;
+ unsigned tmp;
+ mapWire= (xkbKTSetMapEntryWireDesc *)map;
+ preWire= (xkbModsWireDesc *)&mapWire[wire->nMapEntries];
+ for (n=0;n<wire->nMapEntries;n++) {
+ pOld->map[n].active= 1;
+ pOld->map[n].mods.mask= mapWire[n].realMods;
+ pOld->map[n].mods.real_mods= mapWire[n].realMods;
+ pOld->map[n].mods.vmods= mapWire[n].virtualMods;
+ pOld->map[n].level= mapWire[n].level;
+ if (mapWire[n].virtualMods!=0) {
+ tmp= XkbMaskForVMask(xkb,mapWire[n].virtualMods);
+ pOld->map[n].active= (tmp!=0);
+ pOld->map[n].mods.mask|= tmp;
+ }
+ if (wire->preserve) {
+ pOld->preserve[n].real_mods= preWire[n].realMods;
+ pOld->preserve[n].vmods= preWire[n].virtualMods;
+ tmp= XkbMaskForVMask(xkb,preWire[n].virtualMods);
+ pOld->preserve[n].mask= preWire[n].realMods|tmp;
+ }
+ }
+ if (wire->preserve)
+ map= (CARD8 *)&preWire[wire->nMapEntries];
+ else map= (CARD8 *)&mapWire[wire->nMapEntries];
+ }
+ else map= (CARD8 *)&wire[1];
+ wire = (xkbKeyTypeWireDesc *)map;
+ }
+ first= req->firstType;
+ last= first+req->nTypes-1; /* last changed type */
+ if (changes->map.changed&XkbKeyTypesMask) {
+ int oldLast;
+ oldLast= changes->map.first_type+changes->map.num_types-1;
+ if (changes->map.first_type<first)
+ first= changes->map.first_type;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeyTypesMask;
+ changes->map.first_type = first;
+ changes->map.num_types = (last-first)+1;
+ return (char *)wire;
+}
+
+static char *
+SetKeySyms( ClientPtr client,
+ XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ xkbSymMapWireDesc * wire,
+ XkbChangesPtr changes,
+ DeviceIntPtr dev)
+{
+register unsigned i,s;
+XkbSymMapPtr oldMap;
+KeySym * newSyms;
+KeySym * pSyms;
+unsigned first,last;
+
+ oldMap = &xkb->map->key_sym_map[req->firstKeySym];
+ for (i=0;i<req->nKeySyms;i++,oldMap++) {
+ pSyms = (KeySym *)&wire[1];
+ if (wire->nSyms>0) {
+ newSyms = XkbResizeKeySyms(xkb,i+req->firstKeySym,wire->nSyms);
+ for (s=0;s<wire->nSyms;s++) {
+ newSyms[s]= pSyms[s];
+ }
+ if (client->swapped) {
+ int n;
+ for (s=0;s<wire->nSyms;s++) {
+ swapl(&newSyms[s],n);
+ }
+ }
+ }
+ oldMap->kt_index[0] = wire->ktIndex[0];
+ oldMap->kt_index[1] = wire->ktIndex[1];
+ oldMap->kt_index[2] = wire->ktIndex[2];
+ oldMap->kt_index[3] = wire->ktIndex[3];
+ oldMap->group_info = wire->groupInfo;
+ oldMap->width = wire->width;
+ wire= (xkbSymMapWireDesc *)&pSyms[wire->nSyms];
+ }
+ first= req->firstKeySym;
+ last= first+req->nKeySyms-1;
+ if (changes->map.changed&XkbKeySymsMask) {
+ int oldLast= (changes->map.first_key_sym+changes->map.num_key_syms-1);
+ if (changes->map.first_key_sym<first)
+ first= changes->map.first_key_sym;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeySymsMask;
+ changes->map.first_key_sym = first;
+ changes->map.num_key_syms = (last-first+1);
+
+ s= 0;
+ for (i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ if (XkbKeyNumGroups(xkb,i)>s)
+ s= XkbKeyNumGroups(xkb,i);
+ }
+ if (s!=xkb->ctrls->num_groups) {
+ xkbControlsNotify cn;
+ XkbControlsRec old;
+ cn.keycode= 0;
+ cn.eventType= 0;
+ cn.requestMajor= XkbReqCode;
+ cn.requestMinor= X_kbSetMap;
+ old= *xkb->ctrls;
+ xkb->ctrls->num_groups= s;
+ if (XkbComputeControlsNotify(dev,&old,xkb->ctrls,&cn,FALSE))
+ XkbSendControlsNotify(dev,&cn);
+ }
+ return (char *)wire;
+}
+
+static char *
+SetKeyActions( XkbDescPtr xkb,
+ xkbSetMapReq * req,
+ CARD8 * wire,
+ XkbChangesPtr changes)
+{
+register unsigned i,first,last;
+CARD8 * nActs = wire;
+XkbAction * newActs;
+
+ wire+= XkbPaddedSize(req->nKeyActs);
+ for (i=0;i<req->nKeyActs;i++) {
+ if (nActs[i]==0)
+ xkb->server->key_acts[i+req->firstKeyAct]= 0;
+ else {
+ newActs= XkbResizeKeyActions(xkb,i+req->firstKeyAct,nActs[i]);
+ memcpy((char *)newActs,(char *)wire,
+ nActs[i]*SIZEOF(xkbActionWireDesc));
+ wire+= nActs[i]*SIZEOF(xkbActionWireDesc);
+ }
+ }
+ first= req->firstKeyAct;
+ last= (first+req->nKeyActs-1);
+ if (changes->map.changed&XkbKeyActionsMask) {
+ int oldLast;
+ oldLast= changes->map.first_key_act+changes->map.num_key_acts-1;
+ if (changes->map.first_key_act<first)
+ first= changes->map.first_key_act;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeyActionsMask;
+ changes->map.first_key_act= first;
+ changes->map.num_key_acts= (last-first+1);
+ return (char *)wire;
+}
+
+static char *
+SetKeyBehaviors( XkbSrvInfoPtr xkbi,
+ xkbSetMapReq *req,
+ xkbBehaviorWireDesc *wire,
+ XkbChangesPtr changes)
+{
+register unsigned i;
+int maxRG = -1;
+XkbDescPtr xkb = xkbi->desc;
+XkbServerMapPtr server = xkb->server;
+unsigned first,last;
+
+ first= req->firstKeyBehavior;
+ last= req->firstKeyBehavior+req->nKeyBehaviors-1;
+ bzero(&server->behaviors[first],req->nKeyBehaviors*sizeof(XkbBehavior));
+ for (i=0;i<req->totalKeyBehaviors;i++) {
+ if ((server->behaviors[wire->key].type&XkbKB_Permanent)==0) {
+ server->behaviors[wire->key].type= wire->type;
+ server->behaviors[wire->key].data= wire->data;
+ if ((wire->type==XkbKB_RadioGroup)&&(((int)wire->data)>maxRG))
+ maxRG= wire->data + 1;
+ }
+ wire++;
+ }
+
+ if (maxRG>(int)xkbi->nRadioGroups) {
+ int sz = maxRG*sizeof(XkbRadioGroupRec);
+ if (xkbi->radioGroups)
+ xkbi->radioGroups= xrealloc(xkbi->radioGroups,sz);
+ else xkbi->radioGroups= xcalloc(1, sz);
+ if (xkbi->radioGroups) {
+ if (xkbi->nRadioGroups)
+ bzero(&xkbi->radioGroups[xkbi->nRadioGroups],
+ (maxRG-xkbi->nRadioGroups)*sizeof(XkbRadioGroupRec));
+ xkbi->nRadioGroups= maxRG;
+ }
+ else xkbi->nRadioGroups= 0;
+ /* should compute members here */
+ }
+ if (changes->map.changed&XkbKeyBehaviorsMask) {
+ unsigned oldLast;
+ oldLast= changes->map.first_key_behavior+
+ changes->map.num_key_behaviors-1;
+ if (changes->map.first_key_behavior<req->firstKeyBehavior)
+ first= changes->map.first_key_behavior;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.changed|= XkbKeyBehaviorsMask;
+ changes->map.first_key_behavior = first;
+ changes->map.num_key_behaviors = (last-first+1);
+ return (char *)wire;
+}
+
+static char *
+SetVirtualMods(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire,
+ XkbChangesPtr changes)
+{
+register int i,bit,nMods;
+XkbServerMapPtr srv = xkbi->desc->server;
+
+ if (((req->present&XkbVirtualModsMask)==0)||(req->virtualMods==0))
+ return (char *)wire;
+ for (i=nMods=0,bit=1;i<XkbNumVirtualMods;i++,bit<<=1) {
+ if (req->virtualMods&bit) {
+ if (srv->vmods[i]!=wire[nMods]) {
+ changes->map.changed|= XkbVirtualModsMask;
+ changes->map.vmods|= bit;
+ srv->vmods[i]= wire[nMods];
+ }
+ nMods++;
+ }
+ }
+ return (char *)(wire+XkbPaddedSize(nMods));
+}
+
+static char *
+SetKeyExplicit(XkbSrvInfoPtr xkbi,xkbSetMapReq *req,CARD8 *wire,
+ XkbChangesPtr changes)
+{
+register unsigned i,first,last;
+XkbServerMapPtr xkb = xkbi->desc->server;
+CARD8 * start;
+
+ start= wire;
+ first= req->firstKeyExplicit;
+ last= req->firstKeyExplicit+req->nKeyExplicit-1;
+ bzero(&xkb->explicit[first],req->nKeyExplicit);
+ for (i=0;i<req->totalKeyExplicit;i++,wire+= 2) {
+ xkb->explicit[wire[0]]= wire[1];
+ }
+ if (first>0) {
+ if (changes->map.changed&XkbExplicitComponentsMask) {
+ int oldLast;
+ oldLast= changes->map.first_key_explicit+
+ changes->map.num_key_explicit-1;
+ if (changes->map.first_key_explicit<first)
+ first= changes->map.first_key_explicit;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.first_key_explicit= first;
+ changes->map.num_key_explicit= (last-first)+1;
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ return (char *)wire;
+}
+
+static char *
+SetModifierMap( XkbSrvInfoPtr xkbi,
+ xkbSetMapReq * req,
+ CARD8 * wire,
+ XkbChangesPtr changes)
+{
+register unsigned i,first,last;
+XkbClientMapPtr xkb = xkbi->desc->map;
+CARD8 * start;
+
+ start= wire;
+ first= req->firstModMapKey;
+ last= req->firstModMapKey+req->nModMapKeys-1;
+ bzero(&xkb->modmap[first],req->nModMapKeys);
+ for (i=0;i<req->totalModMapKeys;i++,wire+= 2) {
+ xkb->modmap[wire[0]]= wire[1];
+ }
+ if (first>0) {
+ if (changes->map.changed&XkbModifierMapMask) {
+ int oldLast;
+ oldLast= changes->map.first_modmap_key+
+ changes->map.num_modmap_keys-1;
+ if (changes->map.first_modmap_key<first)
+ first= changes->map.first_modmap_key;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.first_modmap_key= first;
+ changes->map.num_modmap_keys= (last-first)+1;
+ }
+ wire+= XkbPaddedSize(wire-start)-(wire-start);
+ return (char *)wire;
+}
+
+static char *
+SetVirtualModMap( XkbSrvInfoPtr xkbi,
+ xkbSetMapReq * req,
+ xkbVModMapWireDesc * wire,
+ XkbChangesPtr changes)
+{
+register unsigned i,first,last;
+XkbServerMapPtr srv = xkbi->desc->server;
+
+ first= req->firstVModMapKey;
+ last= req->firstVModMapKey+req->nVModMapKeys-1;
+ bzero(&srv->vmodmap[first],req->nVModMapKeys*sizeof(unsigned short));
+ for (i=0;i<req->totalVModMapKeys;i++,wire++) {
+ srv->vmodmap[wire->key]= wire->vmods;
+ }
+ if (first>0) {
+ if (changes->map.changed&XkbVirtualModMapMask) {
+ int oldLast;
+ oldLast= changes->map.first_vmodmap_key+
+ changes->map.num_vmodmap_keys-1;
+ if (changes->map.first_vmodmap_key<first)
+ first= changes->map.first_vmodmap_key;
+ if (oldLast>last)
+ last= oldLast;
+ }
+ changes->map.first_vmodmap_key= first;
+ changes->map.num_vmodmap_keys= (last-first)+1;
+ }
+ return (char *)wire;
+}
+
+/**
+ * Check if the given request can be applied to the given device but don't
+ * actually do anything..
+ */
+static int
+_XkbSetMapChecks(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char* values)
+{
+ XkbSrvInfoPtr xkbi;
+ XkbDescPtr xkb;
+ int error;
+ int nTypes = 0, nActions;
+ CARD8 mapWidths[XkbMaxLegalKeyCode + 1];
+ CARD16 symsPerKey[XkbMaxLegalKeyCode + 1];
+
+ xkbi= dev->key->xkbInfo;
+ xkb = xkbi->desc;
+
+ if ((xkb->min_key_code != req->minKeyCode)||
+ (xkb->max_key_code != req->maxKeyCode)) {
+ if (client->vMajor!=1) { /* pre 1.0 versions of Xlib have a bug */
+ req->minKeyCode= xkb->min_key_code;
+ req->maxKeyCode= xkb->max_key_code;
+ }
+ else {
+ if (!XkbIsLegalKeycode(req->minKeyCode)) {
+ client->errorValue = _XkbErrCode3(2, req->minKeyCode, req->maxKeyCode);
+ return BadValue;
+ }
+ if (req->minKeyCode > req->maxKeyCode) {
+ client->errorValue = _XkbErrCode3(3, req->minKeyCode, req->maxKeyCode);
+ return BadMatch;
+ }
+ }
+ }
+
+ if ((req->present & XkbKeyTypesMask) &&
+ (!CheckKeyTypes(client,xkb,req,(xkbKeyTypeWireDesc **)&values,
+ &nTypes,mapWidths))) {
+ client->errorValue = nTypes;
+ return BadValue;
+ }
+ if ((req->present & XkbKeySymsMask) &&
+ (!CheckKeySyms(client,xkb,req,nTypes,mapWidths,symsPerKey,
+ (xkbSymMapWireDesc **)&values,&error))) {
+ client->errorValue = error;
+ return BadValue;
+ }
+
+ if ((req->present & XkbKeyActionsMask) &&
+ (!CheckKeyActions(xkb,req,nTypes,mapWidths,symsPerKey,
+ (CARD8 **)&values,&nActions))) {
+ client->errorValue = nActions;
+ return BadValue;
+ }
+
+ if ((req->present & XkbKeyBehaviorsMask) &&
+ (!CheckKeyBehaviors(xkb,req,(xkbBehaviorWireDesc**)&values,&error))) {
+ client->errorValue = error;
+ return BadValue;
+ }
+
+ if ((req->present & XkbVirtualModsMask) &&
+ (!CheckVirtualMods(xkb,req,(CARD8 **)&values,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+ if ((req->present&XkbExplicitComponentsMask) &&
+ (!CheckKeyExplicit(xkb,req,(CARD8 **)&values,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+ if ((req->present&XkbModifierMapMask) &&
+ (!CheckModifierMap(xkb,req,(CARD8 **)&values,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+ if ((req->present&XkbVirtualModMapMask) &&
+ (!CheckVirtualModMap(xkb,req,(xkbVModMapWireDesc **)&values,&error))) {
+ client->errorValue= error;
+ return BadValue;
+ }
+
+ if (((values-((char *)req))/4)!= req->length) {
+ ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after check)\n");
+ client->errorValue = values-((char *)&req[1]);
+ return BadLength;
+ }
+
+ return Success;
+}
+
+/**
+ * Apply the given request on the given device.
+ */
+static int
+_XkbSetMap(ClientPtr client, DeviceIntPtr dev, xkbSetMapReq *req, char *values)
+{
+ XkbEventCauseRec cause;
+ XkbChangesRec change;
+ Bool sentNKN;
+ XkbSrvInfoPtr xkbi;
+ XkbDescPtr xkb;
+
+ xkbi= dev->key->xkbInfo;
+ xkb = xkbi->desc;
+
+ XkbSetCauseXkbReq(&cause,X_kbSetMap,client);
+ bzero(&change, sizeof(change));
+ sentNKN = FALSE;
+ if ((xkb->min_key_code!=req->minKeyCode)||
+ (xkb->max_key_code!=req->maxKeyCode)) {
+ Status status;
+ xkbNewKeyboardNotify nkn;
+ nkn.deviceID = nkn.oldDeviceID = dev->id;
+ nkn.oldMinKeyCode = xkb->min_key_code;
+ nkn.oldMaxKeyCode = xkb->max_key_code;
+ status= XkbChangeKeycodeRange(xkb, req->minKeyCode,
+ req->maxKeyCode, &change);
+ if (status != Success)
+ return status; /* oh-oh. what about the other keyboards? */
+ nkn.minKeyCode = xkb->min_key_code;
+ nkn.maxKeyCode = xkb->max_key_code;
+ nkn.requestMajor = XkbReqCode;
+ nkn.requestMinor = X_kbSetMap;
+ nkn.changed = XkbNKN_KeycodesMask;
+ XkbSendNewKeyboardNotify(dev,&nkn);
+ sentNKN = TRUE;
+ }
+
+ if (req->present&XkbKeyTypesMask) {
+ values = SetKeyTypes(xkb,req,(xkbKeyTypeWireDesc *)values,&change);
+ if (!values) goto allocFailure;
+ }
+ if (req->present&XkbKeySymsMask) {
+ values = SetKeySyms(client,xkb,req,(xkbSymMapWireDesc *)values,&change,dev);
+ if (!values) goto allocFailure;
+ }
+ if (req->present&XkbKeyActionsMask) {
+ values = SetKeyActions(xkb,req,(CARD8 *)values,&change);
+ if (!values) goto allocFailure;
+ }
+ if (req->present&XkbKeyBehaviorsMask) {
+ values= SetKeyBehaviors(xkbi,req,(xkbBehaviorWireDesc *)values,&change);
+ if (!values) goto allocFailure;
+ }
+ if (req->present&XkbVirtualModsMask)
+ values= SetVirtualMods(xkbi,req,(CARD8 *)values,&change);
+ if (req->present&XkbExplicitComponentsMask)
+ values= SetKeyExplicit(xkbi,req,(CARD8 *)values,&change);
+ if (req->present&XkbModifierMapMask)
+ values= SetModifierMap(xkbi,req,(CARD8 *)values,&change);
+ if (req->present&XkbVirtualModMapMask)
+ values= SetVirtualModMap(xkbi,req,(xkbVModMapWireDesc *)values,&change);
+ if (((values-((char *)req))/4)!=req->length) {
+ ErrorF("[xkb] Internal error! Bad length in XkbSetMap (after set)\n");
+ client->errorValue = values-((char *)&req[1]);
+ return BadLength;
+ }
+ if (req->flags&XkbSetMapRecomputeActions) {
+ KeyCode first,last,firstMM,lastMM;
+ if (change.map.num_key_syms>0) {
+ first= change.map.first_key_sym;
+ last= first+change.map.num_key_syms-1;
+ }
+ else first= last= 0;
+ if (change.map.num_modmap_keys>0) {
+ firstMM= change.map.first_modmap_key;
+ lastMM= first+change.map.num_modmap_keys-1;
+ }
+ else firstMM= lastMM= 0;
+ if ((last>0) && (lastMM>0)) {
+ if (firstMM<first)
+ first= firstMM;
+ if (lastMM>last)
+ last= lastMM;
+ }
+ else if (lastMM>0) {
+ first= firstMM;
+ last= lastMM;
+ }
+ if (last>0) {
+ unsigned check= 0;
+ XkbUpdateActions(dev,first,(last-first+1),&change,&check,&cause);
+ if (check)
+ XkbCheckSecondaryEffects(xkbi,check,&change,&cause);
+ }
+ }
+ if (!sentNKN)
+ XkbSendNotification(dev,&change,&cause);
+
+ return Success;
+allocFailure:
+ return BadAlloc;
+}
+
+
+int
+ProcXkbSetMap(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ char * tmp;
+ int rc;
+
+ REQUEST(xkbSetMapReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
+ CHK_MASK_LEGAL(0x01,stuff->present,XkbAllMapComponentsMask);
+
+ tmp = (char *)&stuff[1];
+
+ /* Check if we can to the SetMap on the requested device. If this
+ succeeds, do the same thing for all extension devices (if needed).
+ If any of them fails, fail. */
+ rc = _XkbSetMapChecks(client, dev, stuff, tmp);
+
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ {
+ rc = _XkbSetMapChecks(client, other, stuff, tmp);
+ if (rc != Success)
+ return rc;
+ }
+ }
+ }
+ }
+
+ /* We know now that we will succed with the SetMap. In theory anyway. */
+ rc = _XkbSetMap(client, dev, stuff, tmp);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ _XkbSetMap(client, other, stuff, tmp);
+ /* ignore rc. if the SetMap failed although the check above
+ reported true there isn't much we can do. we still need to
+ set all other devices, hoping that at least they stay in
+ sync. */
+ }
+ }
+ }
+
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+static Status
+XkbComputeGetCompatMapReplySize( XkbCompatMapPtr compat,
+ xkbGetCompatMapReply * rep)
+{
+unsigned size,nGroups;
+
+ nGroups= 0;
+ if (rep->groups!=0) {
+ register int i,bit;
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (rep->groups&bit)
+ nGroups++;
+ }
+ }
+ size= nGroups*SIZEOF(xkbModsWireDesc);
+ size+= (rep->nSI*SIZEOF(xkbSymInterpretWireDesc));
+ rep->length= size/4;
+ return Success;
+}
+
+static int
+XkbSendCompatMap( ClientPtr client,
+ XkbCompatMapPtr compat,
+ xkbGetCompatMapReply * rep)
+{
+char * data;
+int size;
+
+ size= rep->length*4;
+ if (size>0) {
+ data = xalloc(size);
+ if (data) {
+ register unsigned i,bit;
+ xkbModsWireDesc * grp;
+ XkbSymInterpretPtr sym= &compat->sym_interpret[rep->firstSI];
+ xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
+ for (i=0;i<rep->nSI;i++,sym++,wire++) {
+ wire->sym= sym->sym;
+ wire->mods= sym->mods;
+ wire->match= sym->match;
+ wire->virtualMod= sym->virtual_mod;
+ wire->flags= sym->flags;
+ memcpy((char*)&wire->act,(char*)&sym->act,sz_xkbActionWireDesc);
+ if (client->swapped) {
+ register int n;
+ swapl(&wire->sym,n);
+ }
+ }
+ if (rep->groups) {
+ grp = (xkbModsWireDesc *)wire;
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if (rep->groups&bit) {
+ grp->mask= compat->groups[i].mask;
+ grp->realMods= compat->groups[i].real_mods;
+ grp->virtualMods= compat->groups[i].vmods;
+ if (client->swapped) {
+ register int n;
+ swaps(&grp->virtualMods,n);
+ }
+ grp++;
+ }
+ }
+ wire= (xkbSymInterpretWireDesc*)grp;
+ }
+ }
+ else return BadAlloc;
+ }
+ else data= NULL;
+
+ if (client->swapped) {
+ register int n;
+ swaps(&rep->sequenceNumber,n);
+ swapl(&rep->length,n);
+ swaps(&rep->firstSI,n);
+ swaps(&rep->nSI,n);
+ swaps(&rep->nTotalSI,n);
+ }
+
+ WriteToClient(client, SIZEOF(xkbGetCompatMapReply), (char *)rep);
+ if (data) {
+ WriteToClient(client, size, data);
+ xfree((char *)data);
+ }
+ return client->noClientException;
+}
+
+int
+ProcXkbGetCompatMap(ClientPtr client)
+{
+ xkbGetCompatMapReply rep;
+ DeviceIntPtr dev;
+ XkbDescPtr xkb;
+ XkbCompatMapPtr compat;
+
+ REQUEST(xkbGetCompatMapReq);
+ REQUEST_SIZE_MATCH(xkbGetCompatMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+
+ xkb = dev->key->xkbInfo->desc;
+ compat= xkb->compat;
+
+ rep.type = X_Reply;
+ rep.deviceID = dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.firstSI = stuff->firstSI;
+ rep.nSI = stuff->nSI;
+ if (stuff->getAllSI) {
+ rep.firstSI = 0;
+ rep.nSI = compat->num_si;
+ }
+ else if ((((unsigned)stuff->nSI)>0)&&
+ ((unsigned)(stuff->firstSI+stuff->nSI-1)>=compat->num_si)) {
+ client->errorValue = _XkbErrCode2(0x05,compat->num_si);
+ return BadValue;
+ }
+ rep.nTotalSI = compat->num_si;
+ rep.groups= stuff->groups;
+ XkbComputeGetCompatMapReplySize(compat,&rep);
+ return XkbSendCompatMap(client,compat,&rep);
+}
+
+/**
+ * Apply the given request on the given device.
+ * If dryRun is TRUE, then value checks are performed, but the device isn't
+ * modified.
+ */
+static int
+_XkbSetCompatMap(ClientPtr client, DeviceIntPtr dev,
+ xkbSetCompatMapReq *req, char* data, BOOL dryRun)
+{
+ XkbSrvInfoPtr xkbi;
+ XkbDescPtr xkb;
+ XkbCompatMapPtr compat;
+ int nGroups;
+ unsigned i,bit;
+
+ xkbi = dev->key->xkbInfo;
+ xkb = xkbi->desc;
+ compat = xkb->compat;
+
+ if ((req->nSI>0)||(req->truncateSI)) {
+ xkbSymInterpretWireDesc *wire;
+ if (req->firstSI>compat->num_si) {
+ client->errorValue = _XkbErrCode2(0x02,compat->num_si);
+ return BadValue;
+ }
+ wire= (xkbSymInterpretWireDesc *)data;
+ wire+= req->nSI;
+ data = (char *)wire;
+ }
+
+ nGroups= 0;
+ if (req->groups!=0) {
+ for (i=0,bit=1;i<XkbNumKbdGroups;i++,bit<<=1) {
+ if ( req->groups&bit )
+ nGroups++;
+ }
+ }
+ data+= nGroups*SIZEOF(xkbModsWireDesc);
+ if (((data-((char *)req))/4)!=req->length) {
+ return BadLength;
+ }
+
+ /* Done all the checks we can do */
+ if (dryRun)
+ return Success;
+
+ data = (char *)&req[1];
+ if (req->nSI>0) {
+ xkbSymInterpretWireDesc *wire = (xkbSymInterpretWireDesc *)data;
+ XkbSymInterpretPtr sym;
+ if ((unsigned)(req->firstSI+req->nSI)>compat->num_si) {
+ compat->num_si= req->firstSI+req->nSI;
+ compat->sym_interpret= xrealloc(compat->sym_interpret,
+ compat->num_si * sizeof(XkbSymInterpretRec));
+ if (!compat->sym_interpret) {
+ compat->num_si= 0;
+ return BadAlloc;
+ }
+ }
+ else if (req->truncateSI) {
+ compat->num_si = req->firstSI+req->nSI;
+ }
+ sym = &compat->sym_interpret[req->firstSI];
+ for (i=0;i<req->nSI;i++,wire++,sym++) {
+ if (client->swapped) {
+ int n;
+ swapl(&wire->sym,n);
+ }
+ sym->sym= wire->sym;
+ sym->mods= wire->mods;
+ sym->match= wire->match;
+ sym->flags= wire->flags;
+ sym->virtual_mod= wire->virtualMod;
+ memcpy((char *)&sym->act,(char *)&wire->act,
+ SIZEOF(xkbActionWireDesc));
+ }
+ data = (char *)wire;
+ }
+ else if (req->truncateSI) {
+ compat->num_si = req->firstSI;
+ }
+
+ if (req->groups!=0) {
+ unsigned i, bit;
+ xkbModsWireDesc *wire = (xkbModsWireDesc *)data;
+ for (i = 0, bit = 1; i < XkbNumKbdGroups; i++, bit <<= 1) {
+ if (req->groups & bit) {
+ if (client->swapped) {
+ int n;
+ swaps(&wire->virtualMods,n);
+ }
+ compat->groups[i].mask= wire->realMods;
+ compat->groups[i].real_mods= wire->realMods;
+ compat->groups[i].vmods= wire->virtualMods;
+ if (wire->virtualMods!=0) {
+ unsigned tmp;
+ tmp= XkbMaskForVMask(xkb,wire->virtualMods);
+ compat->groups[i].mask|= tmp;
+ }
+ data+= SIZEOF(xkbModsWireDesc);
+ wire= (xkbModsWireDesc *)data;
+ }
+ }
+ }
+ i= XkbPaddedSize((data-((char *)req)));
+ if ((i/4)!=req->length) {
+ ErrorF("[xkb] Internal length error on read in _XkbSetCompatMap\n");
+ return BadLength;
+ }
+
+ if (dev->xkb_interest) {
+ xkbCompatMapNotify ev;
+ ev.deviceID = dev->id;
+ ev.changedGroups = req->groups;
+ ev.firstSI = req->firstSI;
+ ev.nSI = req->nSI;
+ ev.nTotalSI = compat->num_si;
+ XkbSendCompatMapNotify(dev,&ev);
+ }
+
+ if (req->recomputeActions) {
+ XkbChangesRec change;
+ unsigned check;
+ XkbEventCauseRec cause;
+
+ XkbSetCauseXkbReq(&cause,X_kbSetCompatMap,client);
+ bzero(&change,sizeof(XkbChangesRec));
+ XkbUpdateActions(dev,xkb->min_key_code,XkbNumKeys(xkb),&change,&check,
+ &cause);
+ if (check)
+ XkbCheckSecondaryEffects(xkbi,check,&change,&cause);
+ XkbSendNotification(dev,&change,&cause);
+ }
+ return Success;
+}
+
+int
+ProcXkbSetCompatMap(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ char *data;
+ int rc;
+
+ REQUEST(xkbSetCompatMapReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetCompatMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
+
+ data = (char *)&stuff[1];
+
+ /* check first using a dry-run */
+ rc = _XkbSetCompatMap(client, dev, stuff, data, TRUE);
+ if (rc != Success)
+ return rc;
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ {
+ /* dry-run */
+ rc = _XkbSetCompatMap(client, other, stuff, data, TRUE);
+ if (rc != Success)
+ return rc;
+ }
+ }
+ }
+ }
+
+ /* Yay, the dry-runs succeed. Let's apply */
+ rc = _XkbSetCompatMap(client, dev, stuff, data, FALSE);
+ if (rc != Success)
+ return rc;
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ {
+ rc = _XkbSetCompatMap(client, other, stuff, data, FALSE);
+ if (rc != Success)
+ return rc;
+ }
+ }
+ }
+ }
+
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbGetIndicatorState(ClientPtr client)
+{
+ xkbGetIndicatorStateReply rep;
+ XkbSrvLedInfoPtr sli;
+ DeviceIntPtr dev;
+ register int i;
+
+ REQUEST(xkbGetIndicatorStateReq);
+ REQUEST_SIZE_MATCH(xkbGetIndicatorStateReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess);
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,
+ XkbXI_IndicatorStateMask);
+ if (!sli)
+ return BadAlloc;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.state = sli->effectiveState;
+
+ if (client->swapped) {
+ swaps(&rep.sequenceNumber,i);
+ swapl(&rep.state,i);
+ }
+ WriteToClient(client, SIZEOF(xkbGetIndicatorStateReply), (char *)&rep);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+static Status
+XkbComputeGetIndicatorMapReplySize(
+ XkbIndicatorPtr indicators,
+ xkbGetIndicatorMapReply *rep)
+{
+register int i,bit;
+int nIndicators;
+
+ rep->realIndicators = indicators->phys_indicators;
+ for (i=nIndicators=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (rep->which&bit)
+ nIndicators++;
+ }
+ rep->length = (nIndicators*SIZEOF(xkbIndicatorMapWireDesc))/4;
+ return Success;
+}
+
+static int
+XkbSendIndicatorMap( ClientPtr client,
+ XkbIndicatorPtr indicators,
+ xkbGetIndicatorMapReply * rep)
+{
+int length;
+CARD8 * map;
+register int i;
+register unsigned bit;
+
+ length = rep->length*4;
+ if (length>0) {
+ CARD8 *to;
+ to= map= xalloc(length);
+ if (map) {
+ xkbIndicatorMapWireDesc *wire = (xkbIndicatorMapWireDesc *)to;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (rep->which&bit) {
+ wire->flags= indicators->maps[i].flags;
+ wire->whichGroups= indicators->maps[i].which_groups;
+ wire->groups= indicators->maps[i].groups;
+ wire->whichMods= indicators->maps[i].which_mods;
+ wire->mods= indicators->maps[i].mods.mask;
+ wire->realMods= indicators->maps[i].mods.real_mods;
+ wire->virtualMods= indicators->maps[i].mods.vmods;
+ wire->ctrls= indicators->maps[i].ctrls;
+ if (client->swapped) {
+ register int n;
+ swaps(&wire->virtualMods,n);
+ swapl(&wire->ctrls,n);
+ }
+ wire++;
+ }
+ }
+ to = (CARD8 *)wire;
+ if ((to-map)!=length) {
+ client->errorValue = _XkbErrCode2(0xff,length);
+ return BadLength;
+ }
+ }
+ else return BadAlloc;
+ }
+ else map = NULL;
+ if (client->swapped) {
+ swaps(&rep->sequenceNumber,i);
+ swapl(&rep->length,i);
+ swapl(&rep->which,i);
+ swapl(&rep->realIndicators,i);
+ }
+ WriteToClient(client, SIZEOF(xkbGetIndicatorMapReply), (char *)rep);
+ if (map) {
+ WriteToClient(client, length, (char *)map);
+ xfree((char *)map);
+ }
+ return client->noClientException;
+}
+
+int
+ProcXkbGetIndicatorMap(ClientPtr client)
+{
+xkbGetIndicatorMapReply rep;
+DeviceIntPtr dev;
+XkbDescPtr xkb;
+XkbIndicatorPtr leds;
+
+ REQUEST(xkbGetIndicatorMapReq);
+ REQUEST_SIZE_MATCH(xkbGetIndicatorMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+
+ xkb= dev->key->xkbInfo->desc;
+ leds= xkb->indicators;
+
+ rep.type = X_Reply;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.which = stuff->which;
+ XkbComputeGetIndicatorMapReplySize(leds,&rep);
+ return XkbSendIndicatorMap(client,leds,&rep);
+}
+
+/**
+ * Apply the given map to the given device. Which specifies which components
+ * to apply.
+ */
+static int
+_XkbSetIndicatorMap(ClientPtr client, DeviceIntPtr dev,
+ int which, xkbIndicatorMapWireDesc *desc)
+{
+ XkbSrvInfoPtr xkbi;
+ XkbSrvLedInfoPtr sli;
+ XkbEventCauseRec cause;
+ int i, bit;
+
+ xkbi = dev->key->xkbInfo;
+
+ sli= XkbFindSrvLedInfo(dev, XkbDfltXIClass, XkbDfltXIId,
+ XkbXI_IndicatorMapsMask);
+ if (!sli)
+ return BadAlloc;
+
+ for (i = 0, bit = 1; i < XkbNumIndicators; i++, bit <<= 1) {
+ if (which & bit) {
+ sli->maps[i].flags = desc->flags;
+ sli->maps[i].which_groups = desc->whichGroups;
+ sli->maps[i].groups = desc->groups;
+ sli->maps[i].which_mods = desc->whichMods;
+ sli->maps[i].mods.mask = desc->mods;
+ sli->maps[i].mods.real_mods = desc->mods;
+ sli->maps[i].mods.vmods= desc->virtualMods;
+ sli->maps[i].ctrls = desc->ctrls;
+ if (desc->virtualMods!=0) {
+ unsigned tmp;
+ tmp= XkbMaskForVMask(xkbi->desc,desc->virtualMods);
+ sli->maps[i].mods.mask= desc->mods|tmp;
+ }
+ desc++;
+ }
+ }
+
+ XkbSetCauseXkbReq(&cause,X_kbSetIndicatorMap,client);
+ XkbApplyLedMapChanges(dev,sli,which,NULL,NULL,&cause);
+
+ return Success;
+}
+
+int
+ProcXkbSetIndicatorMap(ClientPtr client)
+{
+ int i, bit;
+ int nIndicators;
+ DeviceIntPtr dev;
+ xkbIndicatorMapWireDesc *from;
+ int rc;
+
+ REQUEST(xkbSetIndicatorMapReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetIndicatorMapReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess);
+
+ if (stuff->which==0)
+ return client->noClientException;
+
+ for (nIndicators=i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (stuff->which&bit)
+ nIndicators++;
+ }
+ if (stuff->length!=((SIZEOF(xkbSetIndicatorMapReq)+
+ (nIndicators*SIZEOF(xkbIndicatorMapWireDesc)))/4)) {
+ return BadLength;
+ }
+
+ from = (xkbIndicatorMapWireDesc *)&stuff[1];
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (stuff->which&bit) {
+ if (client->swapped) {
+ int n;
+ swaps(&from->virtualMods,n);
+ swapl(&from->ctrls,n);
+ }
+ CHK_MASK_LEGAL(i,from->whichGroups,XkbIM_UseAnyGroup);
+ CHK_MASK_LEGAL(i,from->whichMods,XkbIM_UseAnyMods);
+ from++;
+ }
+ }
+
+ from = (xkbIndicatorMapWireDesc *)&stuff[1];
+ rc = _XkbSetIndicatorMap(client, dev, stuff->which, from);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess);
+ if (rc == Success)
+ _XkbSetIndicatorMap(client, other, stuff->which, from);
+ }
+ }
+ }
+
+ return Success;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbGetNamedIndicator(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xkbGetNamedIndicatorReply rep;
+ register int i = 0;
+ XkbSrvLedInfoPtr sli;
+ XkbIndicatorMapPtr map = NULL;
+
+ REQUEST(xkbGetNamedIndicatorReq);
+ REQUEST_SIZE_MATCH(xkbGetNamedIndicatorReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixReadAccess);
+ CHK_ATOM_ONLY(stuff->indicator);
+
+ sli= XkbFindSrvLedInfo(dev,stuff->ledClass,stuff->ledID,0);
+ if (!sli)
+ return BadAlloc;
+
+ i= 0;
+ map= NULL;
+ if ((sli->names)&&(sli->maps)) {
+ for (i=0;i<XkbNumIndicators;i++) {
+ if (stuff->indicator==sli->names[i]) {
+ map= &sli->maps[i];
+ break;
+ }
+ }
+ }
+
+ rep.type= X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.deviceID = dev->id;
+ rep.indicator= stuff->indicator;
+ if (map!=NULL) {
+ rep.found= TRUE;
+ rep.on= ((sli->effectiveState&(1<<i))!=0);
+ rep.realIndicator= ((sli->physIndicators&(1<<i))!=0);
+ rep.ndx= i;
+ rep.flags= map->flags;
+ rep.whichGroups= map->which_groups;
+ rep.groups= map->groups;
+ rep.whichMods= map->which_mods;
+ rep.mods= map->mods.mask;
+ rep.realMods= map->mods.real_mods;
+ rep.virtualMods= map->mods.vmods;
+ rep.ctrls= map->ctrls;
+ rep.supported= TRUE;
+ }
+ else {
+ rep.found= FALSE;
+ rep.on= FALSE;
+ rep.realIndicator= FALSE;
+ rep.ndx= XkbNoIndicator;
+ rep.flags= 0;
+ rep.whichGroups= 0;
+ rep.groups= 0;
+ rep.whichMods= 0;
+ rep.mods= 0;
+ rep.realMods= 0;
+ rep.virtualMods= 0;
+ rep.ctrls= 0;
+ rep.supported= TRUE;
+ }
+ if ( client->swapped ) {
+ register int n;
+ swapl(&rep.length,n);
+ swaps(&rep.sequenceNumber,n);
+ swapl(&rep.indicator,n);
+ swaps(&rep.virtualMods,n);
+ swapl(&rep.ctrls,n);
+ }
+
+ WriteToClient(client,SIZEOF(xkbGetNamedIndicatorReply), (char *)&rep);
+ return client->noClientException;
+}
+
+
+/**
+ * Find the IM on the device.
+ * Returns the map, or NULL if the map doesn't exist.
+ * If the return value is NULL, led_return is undefined. Otherwise, led_return
+ * is set to the led index of the map.
+ */
+static XkbIndicatorMapPtr
+_XkbFindNamedIndicatorMap(XkbSrvLedInfoPtr sli, Atom indicator,
+ int *led_return)
+{
+ XkbIndicatorMapPtr map;
+
+ /* search for the right indicator */
+ map = NULL;
+ if (sli->names && sli->maps) {
+ int led;
+
+ for (led = 0; (led < XkbNumIndicators) && (map == NULL); led++) {
+ if (sli->names[led] == indicator) {
+ map= &sli->maps[led];
+ *led_return = led;
+ break;
+ }
+ }
+ }
+
+ return map;
+}
+
+/**
+ * Creates an indicator map on the device. If dryRun is TRUE, it only checks
+ * if creation is possible, but doesn't actually create it.
+ */
+static int
+_XkbCreateIndicatorMap(DeviceIntPtr dev, Atom indicator,
+ int ledClass, int ledID,
+ XkbIndicatorMapPtr *map_return, int *led_return,
+ Bool dryRun)
+{
+ XkbSrvLedInfoPtr sli;
+ XkbIndicatorMapPtr map;
+ int led;
+
+ sli = XkbFindSrvLedInfo(dev, ledClass, ledID, XkbXI_IndicatorsMask);
+ if (!sli)
+ return BadAlloc;
+
+ map = _XkbFindNamedIndicatorMap(sli, indicator, &led);
+
+ if (!map)
+ {
+ /* find first unused indicator maps and assign the name to it */
+ for (led = 0, map = NULL; (led < XkbNumIndicators) && (map == NULL); led++) {
+ if ((sli->names) && (sli->maps) && (sli->names[led] == None) &&
+ (!XkbIM_InUse(&sli->maps[led])))
+ {
+ map = &sli->maps[led];
+ if (!dryRun)
+ sli->names[led] = indicator;
+ break;
+ }
+ }
+ }
+
+ if (!map)
+ return BadAlloc;
+
+ *led_return = led;
+ *map_return = map;
+ return Success;
+}
+
+static int
+_XkbSetNamedIndicator(ClientPtr client, DeviceIntPtr dev,
+ xkbSetNamedIndicatorReq *stuff)
+{
+ unsigned int extDevReason;
+ unsigned int statec, namec, mapc;
+ XkbSrvLedInfoPtr sli;
+ int led = 0;
+ XkbIndicatorMapPtr map;
+ DeviceIntPtr kbd;
+ XkbEventCauseRec cause;
+ xkbExtensionDeviceNotify ed;
+ XkbChangesRec changes;
+ int rc;
+
+ rc = _XkbCreateIndicatorMap(dev, stuff->indicator, stuff->ledClass,
+ stuff->ledID, &map, &led, FALSE);
+ if (rc != Success || !map) /* oh-oh */
+ return rc;
+
+ sli = XkbFindSrvLedInfo(dev, stuff->ledClass, stuff->ledID,
+ XkbXI_IndicatorsMask);
+ if (!sli)
+ return BadAlloc;
+
+ namec = mapc = statec = 0;
+ extDevReason = 0;
+
+ namec |= (1<<led);
+ sli->namesPresent |= ((stuff->indicator != None) ? (1 << led) : 0);
+ extDevReason |= XkbXI_IndicatorNamesMask;
+
+ if (stuff->setMap) {
+ map->flags = stuff->flags;
+ map->which_groups = stuff->whichGroups;
+ map->groups = stuff->groups;
+ map->which_mods = stuff->whichMods;
+ map->mods.mask = stuff->realMods;
+ map->mods.real_mods = stuff->realMods;
+ map->mods.vmods= stuff->virtualMods;
+ map->ctrls = stuff->ctrls;
+ mapc|= (1<<led);
+ }
+
+ if ((stuff->setState) && ((map->flags & XkbIM_NoExplicit) == 0))
+ {
+ if (stuff->on) sli->explicitState |= (1<<led);
+ else sli->explicitState &= ~(1<<led);
+ statec |= ((sli->effectiveState ^ sli->explicitState) & (1 << led));
+ }
+
+ bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
+ bzero((char *)&changes,sizeof(XkbChangesRec));
+ XkbSetCauseXkbReq(&cause,X_kbSetNamedIndicator,client);
+ if (namec)
+ XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause);
+ if (mapc)
+ XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause);
+ if (statec)
+ XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause);
+
+ kbd = dev;
+ if ((sli->flags&XkbSLI_HasOwnState)==0)
+ kbd = inputInfo.keyboard;
+ XkbFlushLedEvents(dev, kbd, sli, &ed, &changes, &cause);
+
+ return Success;
+}
+
+int
+ProcXkbSetNamedIndicator(ClientPtr client)
+{
+ int rc;
+ DeviceIntPtr dev;
+ int led = 0;
+ XkbIndicatorMapPtr map;
+
+ REQUEST(xkbSetNamedIndicatorReq);
+ REQUEST_SIZE_MATCH(xkbSetNamedIndicatorReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_LED_DEVICE(dev, stuff->deviceSpec, client, DixSetAttrAccess);
+ CHK_ATOM_ONLY(stuff->indicator);
+ CHK_MASK_LEGAL(0x10,stuff->whichGroups,XkbIM_UseAnyGroup);
+ CHK_MASK_LEGAL(0x11,stuff->whichMods,XkbIM_UseAnyMods);
+
+ /* Dry-run for checks */
+ rc = _XkbCreateIndicatorMap(dev, stuff->indicator,
+ stuff->ledClass, stuff->ledID,
+ &map, &led, TRUE);
+ if (rc != Success || !map) /* couldn't be created or didn't exist */
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd ||
+ stuff->deviceSpec == XkbUseCorePtr)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && !IsMaster(other) && (other->u.master == dev) &&
+ (other->kbdfeed || other->leds) &&
+ (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success))
+ {
+ rc = _XkbCreateIndicatorMap(other, stuff->indicator,
+ stuff->ledClass, stuff->ledID,
+ &map, &led, TRUE);
+ if (rc != Success || !map)
+ return rc;
+ }
+ }
+ }
+
+ /* All checks passed, let's do it */
+ rc = _XkbSetNamedIndicator(client, dev, stuff);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd ||
+ stuff->deviceSpec == XkbUseCorePtr)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && !IsMaster(other) && (other->u.master == dev) &&
+ (other->kbdfeed || other->leds) &&
+ (XaceHook(XACE_DEVICE_ACCESS, client, other, DixSetAttrAccess) == Success))
+ {
+ _XkbSetNamedIndicator(client, other, stuff);
+ }
+ }
+ }
+
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+static CARD32
+_XkbCountAtoms(Atom *atoms,int maxAtoms,int *count)
+{
+register unsigned int i,bit,nAtoms;
+register CARD32 atomsPresent;
+
+ for (i=nAtoms=atomsPresent=0,bit=1;i<maxAtoms;i++,bit<<=1) {
+ if (atoms[i]!=None) {
+ atomsPresent|= bit;
+ nAtoms++;
+ }
+ }
+ if (count)
+ *count= nAtoms;
+ return atomsPresent;
+}
+
+static char *
+_XkbWriteAtoms(char *wire,Atom *atoms,int maxAtoms,int swap)
+{
+register unsigned int i;
+Atom *atm;
+
+ atm = (Atom *)wire;
+ for (i=0;i<maxAtoms;i++) {
+ if (atoms[i]!=None) {
+ *atm= atoms[i];
+ if (swap) {
+ register int n;
+ swapl(atm,n);
+ }
+ atm++;
+ }
+ }
+ return (char *)atm;
+}
+
+static Status
+XkbComputeGetNamesReplySize(XkbDescPtr xkb,xkbGetNamesReply *rep)
+{
+register unsigned which,length;
+register int i;
+
+ rep->minKeyCode= xkb->min_key_code;
+ rep->maxKeyCode= xkb->max_key_code;
+ which= rep->which;
+ length= 0;
+ if (xkb->names!=NULL) {
+ if (which&XkbKeycodesNameMask) length++;
+ if (which&XkbGeometryNameMask) length++;
+ if (which&XkbSymbolsNameMask) length++;
+ if (which&XkbPhysSymbolsNameMask) length++;
+ if (which&XkbTypesNameMask) length++;
+ if (which&XkbCompatNameMask) length++;
+ }
+ else which&= ~XkbComponentNamesMask;
+
+ if (xkb->map!=NULL) {
+ if (which&XkbKeyTypeNamesMask)
+ length+= xkb->map->num_types;
+ rep->nTypes= xkb->map->num_types;
+ if (which&XkbKTLevelNamesMask) {
+ XkbKeyTypePtr pType = xkb->map->types;
+ int nKTLevels = 0;
+
+ length+= XkbPaddedSize(xkb->map->num_types)/4;
+ for (i=0;i<xkb->map->num_types;i++,pType++) {
+ if (pType->level_names!=NULL)
+ nKTLevels+= pType->num_levels;
+ }
+ rep->nKTLevels= nKTLevels;
+ length+= nKTLevels;
+ }
+ }
+ else {
+ rep->nTypes= 0;
+ rep->nKTLevels= 0;
+ which&= ~(XkbKeyTypeNamesMask|XkbKTLevelNamesMask);
+ }
+
+ rep->minKeyCode= xkb->min_key_code;
+ rep->maxKeyCode= xkb->max_key_code;
+ rep->indicators= 0;
+ rep->virtualMods= 0;
+ rep->groupNames= 0;
+ if (xkb->names!=NULL) {
+ if (which&XkbIndicatorNamesMask) {
+ int nLeds;
+ rep->indicators=
+ _XkbCountAtoms(xkb->names->indicators,XkbNumIndicators,&nLeds);
+ length+= nLeds;
+ if (nLeds==0)
+ which&= ~XkbIndicatorNamesMask;
+ }
+
+ if (which&XkbVirtualModNamesMask) {
+ int nVMods;
+ rep->virtualMods=
+ _XkbCountAtoms(xkb->names->vmods,XkbNumVirtualMods,&nVMods);
+ length+= nVMods;
+ if (nVMods==0)
+ which&= ~XkbVirtualModNamesMask;
+ }
+
+ if (which&XkbGroupNamesMask) {
+ int nGroups;
+ rep->groupNames=
+ _XkbCountAtoms(xkb->names->groups,XkbNumKbdGroups,&nGroups);
+ length+= nGroups;
+ if (nGroups==0)
+ which&= ~XkbGroupNamesMask;
+ }
+
+ if ((which&XkbKeyNamesMask)&&(xkb->names->keys))
+ length+= rep->nKeys;
+ else which&= ~XkbKeyNamesMask;
+
+ if ((which&XkbKeyAliasesMask)&&
+ (xkb->names->key_aliases)&&(xkb->names->num_key_aliases>0)) {
+ rep->nKeyAliases= xkb->names->num_key_aliases;
+ length+= rep->nKeyAliases*2;
+ }
+ else {
+ which&= ~XkbKeyAliasesMask;
+ rep->nKeyAliases= 0;
+ }
+
+ if ((which&XkbRGNamesMask)&&(xkb->names->num_rg>0))
+ length+= xkb->names->num_rg;
+ else which&= ~XkbRGNamesMask;
+ }
+ else {
+ which&= ~(XkbIndicatorNamesMask|XkbVirtualModNamesMask);
+ which&= ~(XkbGroupNamesMask|XkbKeyNamesMask|XkbKeyAliasesMask);
+ which&= ~XkbRGNamesMask;
+ }
+
+ rep->length= length;
+ rep->which= which;
+ return Success;
+}
+
+static int
+XkbSendNames(ClientPtr client,XkbDescPtr xkb,xkbGetNamesReply *rep)
+{
+register unsigned i,length,which;
+char * start;
+char * desc;
+register int n;
+
+ length= rep->length*4;
+ which= rep->which;
+ if (client->swapped) {
+ swaps(&rep->sequenceNumber,n);
+ swapl(&rep->length,n);
+ swapl(&rep->which,n);
+ swaps(&rep->virtualMods,n);
+ swapl(&rep->indicators,n);
+ }
+
+ start = desc = xalloc(length);
+ if ( !start )
+ return BadAlloc;
+ if (xkb->names) {
+ if (which&XkbKeycodesNameMask) {
+ *((CARD32 *)desc)= xkb->names->keycodes;
+ if (client->swapped) {
+ swapl(desc,n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbGeometryNameMask) {
+ *((CARD32 *)desc)= xkb->names->geometry;
+ if (client->swapped) {
+ swapl(desc,n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbSymbolsNameMask) {
+ *((CARD32 *)desc)= xkb->names->symbols;
+ if (client->swapped) {
+ swapl(desc,n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbPhysSymbolsNameMask) {
+ register CARD32 *atm= (CARD32 *)desc;
+ atm[0]= (CARD32)xkb->names->phys_symbols;
+ if (client->swapped) {
+ swapl(&atm[0],n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbTypesNameMask) {
+ *((CARD32 *)desc)= (CARD32)xkb->names->types;
+ if (client->swapped) {
+ swapl(desc,n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbCompatNameMask) {
+ *((CARD32 *)desc)= (CARD32)xkb->names->compat;
+ if (client->swapped) {
+ swapl(desc,n);
+ }
+ desc+= 4;
+ }
+ if (which&XkbKeyTypeNamesMask) {
+ register CARD32 *atm= (CARD32 *)desc;
+ register XkbKeyTypePtr type= xkb->map->types;
+
+ for (i=0;i<xkb->map->num_types;i++,atm++,type++) {
+ *atm= (CARD32)type->name;
+ if (client->swapped) {
+ swapl(atm,n);
+ }
+ }
+ desc= (char *)atm;
+ }
+ if (which&XkbKTLevelNamesMask && xkb->map) {
+ XkbKeyTypePtr type = xkb->map->types;
+ register CARD32 *atm;
+ for (i=0;i<rep->nTypes;i++,type++) {
+ *desc++ = type->num_levels;
+ }
+ desc+= XkbPaddedSize(rep->nTypes)-rep->nTypes;
+
+ atm= (CARD32 *)desc;
+ type = xkb->map->types;
+ for (i=0;i<xkb->map->num_types;i++,type++) {
+ register unsigned l;
+ if (type->level_names) {
+ for (l=0;l<type->num_levels;l++,atm++) {
+ *atm= type->level_names[l];
+ if (client->swapped) {
+ swapl(atm,n);
+ }
+ }
+ desc+= type->num_levels*4;
+ }
+ }
+ }
+ if (which&XkbIndicatorNamesMask) {
+ desc= _XkbWriteAtoms(desc,xkb->names->indicators,XkbNumIndicators,
+ client->swapped);
+ }
+ if (which&XkbVirtualModNamesMask) {
+ desc= _XkbWriteAtoms(desc,xkb->names->vmods,XkbNumVirtualMods,
+ client->swapped);
+ }
+ if (which&XkbGroupNamesMask) {
+ desc= _XkbWriteAtoms(desc,xkb->names->groups,XkbNumKbdGroups,
+ client->swapped);
+ }
+ if (which&XkbKeyNamesMask) {
+ for (i=0;i<rep->nKeys;i++,desc+= sizeof(XkbKeyNameRec)) {
+ *((XkbKeyNamePtr)desc)= xkb->names->keys[i+rep->firstKey];
+ }
+ }
+ if (which&XkbKeyAliasesMask) {
+ XkbKeyAliasPtr pAl;
+ pAl= xkb->names->key_aliases;
+ for (i=0;i<rep->nKeyAliases;i++,pAl++,desc+=2*XkbKeyNameLength) {
+ *((XkbKeyAliasPtr)desc)= *pAl;
+ }
+ }
+ if ((which&XkbRGNamesMask)&&(rep->nRadioGroups>0)) {
+ register CARD32 *atm= (CARD32 *)desc;
+ for (i=0;i<rep->nRadioGroups;i++,atm++) {
+ *atm= (CARD32)xkb->names->radio_groups[i];
+ if (client->swapped) {
+ swapl(atm,n);
+ }
+ }
+ desc+= rep->nRadioGroups*4;
+ }
+ }
+
+ if ((desc-start)!=(length)) {
+ ErrorF("[xkb] BOGUS LENGTH in write names, expected %d, got %ld\n",
+ length, (unsigned long)(desc-start));
+ }
+ WriteToClient(client, SIZEOF(xkbGetNamesReply), (char *)rep);
+ WriteToClient(client, length, start);
+ xfree((char *)start);
+ return client->noClientException;
+}
+
+int
+ProcXkbGetNames(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ XkbDescPtr xkb;
+ xkbGetNamesReply rep;
+
+ REQUEST(xkbGetNamesReq);
+ REQUEST_SIZE_MATCH(xkbGetNamesReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+ CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask);
+
+ xkb = dev->key->xkbInfo->desc;
+ memset(&rep, 0, sizeof(xkbGetNamesReply));
+ rep.type= X_Reply;
+ rep.sequenceNumber= client->sequence;
+ rep.length = 0;
+ rep.deviceID = dev->id;
+ rep.which = stuff->which;
+ rep.nTypes = xkb->map->num_types;
+ rep.firstKey = xkb->min_key_code;
+ rep.nKeys = XkbNumKeys(xkb);
+ if (xkb->names!=NULL) {
+ rep.nKeyAliases= xkb->names->num_key_aliases;
+ rep.nRadioGroups = xkb->names->num_rg;
+ }
+ else {
+ rep.nKeyAliases= rep.nRadioGroups= 0;
+ }
+ XkbComputeGetNamesReplySize(xkb,&rep);
+ return XkbSendNames(client,xkb,&rep);
+}
+
+/***====================================================================***/
+
+static CARD32 *
+_XkbCheckAtoms(CARD32 *wire,int nAtoms,int swapped,Atom *pError)
+{
+register int i;
+
+ for (i=0;i<nAtoms;i++,wire++) {
+ if (swapped) {
+ register int n;
+ swapl(wire,n);
+ }
+ if ((((Atom)*wire)!=None)&&(!ValidAtom((Atom)*wire))) {
+ *pError= ((Atom)*wire);
+ return NULL;
+ }
+ }
+ return wire;
+}
+
+static CARD32 *
+_XkbCheckMaskedAtoms(CARD32 *wire,int nAtoms,CARD32 present,int swapped,
+ Atom *pError)
+{
+register unsigned i,bit;
+
+ for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) {
+ if ((present&bit)==0)
+ continue;
+ if (swapped) {
+ register int n;
+ swapl(wire,n);
+ }
+ if ((((Atom)*wire)!=None)&&(!ValidAtom(((Atom)*wire)))) {
+ *pError= (Atom)*wire;
+ return NULL;
+ }
+ wire++;
+ }
+ return wire;
+}
+
+static Atom *
+_XkbCopyMaskedAtoms( Atom *wire,
+ Atom *dest,
+ int nAtoms,
+ CARD32 present)
+{
+register int i,bit;
+
+ for (i=0,bit=1;(i<nAtoms)&&(present);i++,bit<<=1) {
+ if ((present&bit)==0)
+ continue;
+ dest[i]= *wire++;
+ }
+ return wire;
+}
+
+static Bool
+_XkbCheckTypeName(Atom name,int typeNdx)
+{
+const char * str;
+
+ str= NameForAtom(name);
+ if ((strcmp(str,"ONE_LEVEL")==0)||(strcmp(str,"TWO_LEVEL")==0)||
+ (strcmp(str,"ALPHABETIC")==0)||(strcmp(str,"KEYPAD")==0))
+ return FALSE;
+ return TRUE;
+}
+
+/**
+ * Check the device-dependent data in the request against the device. Returns
+ * Success, or the appropriate error code.
+ */
+static int
+_XkbSetNamesCheck(ClientPtr client, DeviceIntPtr dev,
+ xkbSetNamesReq *stuff, CARD32 *data)
+{
+ XkbDescRec *xkb;
+ XkbNamesRec *names;
+ CARD32 *tmp;
+ Atom bad;
+
+ tmp = data;
+ xkb = dev->key->xkbInfo->desc;
+ names = xkb->names;
+
+
+ if (stuff->which & XkbKeyTypeNamesMask) {
+ int i;
+ CARD32 *old;
+ if ( stuff->nTypes<1 ) {
+ client->errorValue = _XkbErrCode2(0x02,stuff->nTypes);
+ return BadValue;
+ }
+ if ((unsigned)(stuff->firstType+stuff->nTypes-1)>=xkb->map->num_types) {
+ client->errorValue = _XkbErrCode4(0x03,stuff->firstType,
+ stuff->nTypes,
+ xkb->map->num_types);
+ return BadValue;
+ }
+ if (((unsigned)stuff->firstType)<=XkbLastRequiredType) {
+ client->errorValue = _XkbErrCode2(0x04,stuff->firstType);
+ return BadAccess;
+ }
+ old= tmp;
+ tmp= _XkbCheckAtoms(tmp,stuff->nTypes,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ for (i=0;i<stuff->nTypes;i++,old++) {
+ if (!_XkbCheckTypeName((Atom)*old,stuff->firstType+i))
+ client->errorValue= _XkbErrCode2(0x05,i);
+ }
+ }
+ if (stuff->which&XkbKTLevelNamesMask) {
+ unsigned i;
+ XkbKeyTypePtr type;
+ CARD8 * width;
+ if ( stuff->nKTLevels<1 ) {
+ client->errorValue = _XkbErrCode2(0x05,stuff->nKTLevels);
+ return BadValue;
+ }
+ if ((unsigned)(stuff->firstKTLevel+stuff->nKTLevels-1)>=
+ xkb->map->num_types) {
+ client->errorValue = _XkbErrCode4(0x06,stuff->firstKTLevel,
+ stuff->nKTLevels,xkb->map->num_types);
+ return BadValue;
+ }
+ width = (CARD8 *)tmp;
+ tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels));
+ type = &xkb->map->types[stuff->firstKTLevel];
+ for (i=0;i<stuff->nKTLevels;i++,type++) {
+ if (width[i]==0)
+ continue;
+ else if (width[i]!=type->num_levels) {
+ client->errorValue= _XkbErrCode4(0x07,i+stuff->firstKTLevel,
+ type->num_levels,width[i]);
+ return BadMatch;
+ }
+ tmp= _XkbCheckAtoms(tmp,width[i],client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ }
+ if (stuff->which&XkbIndicatorNamesMask) {
+ if (stuff->indicators==0) {
+ client->errorValue= 0x08;
+ return BadMatch;
+ }
+ tmp= _XkbCheckMaskedAtoms(tmp,XkbNumIndicators,stuff->indicators,
+ client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbVirtualModNamesMask) {
+ if (stuff->virtualMods==0) {
+ client->errorValue= 0x09;
+ return BadMatch;
+ }
+ tmp= _XkbCheckMaskedAtoms(tmp,XkbNumVirtualMods,
+ (CARD32)stuff->virtualMods,
+ client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbGroupNamesMask) {
+ if (stuff->groupNames==0) {
+ client->errorValue= 0x0a;
+ return BadMatch;
+ }
+ tmp= _XkbCheckMaskedAtoms(tmp,XkbNumKbdGroups,
+ (CARD32)stuff->groupNames,
+ client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbKeyNamesMask) {
+ if (stuff->firstKey<(unsigned)xkb->min_key_code) {
+ client->errorValue= _XkbErrCode3(0x0b,xkb->min_key_code,
+ stuff->firstKey);
+ return BadValue;
+ }
+ if (((unsigned)(stuff->firstKey+stuff->nKeys-1)>xkb->max_key_code)||
+ (stuff->nKeys<1)) {
+ client->errorValue= _XkbErrCode4(0x0c,xkb->max_key_code,
+ stuff->firstKey,stuff->nKeys);
+ return BadValue;
+ }
+ tmp+= stuff->nKeys;
+ }
+ if ((stuff->which&XkbKeyAliasesMask)&&(stuff->nKeyAliases>0)) {
+ tmp+= stuff->nKeyAliases*2;
+ }
+ if (stuff->which&XkbRGNamesMask) {
+ if ( stuff->nRadioGroups<1 ) {
+ client->errorValue= _XkbErrCode2(0x0d,stuff->nRadioGroups);
+ return BadValue;
+ }
+ tmp= _XkbCheckAtoms(tmp,stuff->nRadioGroups,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ if ((tmp-((CARD32 *)stuff))!=stuff->length) {
+ client->errorValue = stuff->length;
+ return BadLength;
+ }
+
+
+
+ return Success;
+}
+
+static int
+_XkbSetNames(ClientPtr client, DeviceIntPtr dev, xkbSetNamesReq *stuff)
+{
+ XkbDescRec *xkb;
+ XkbNamesRec *names;
+ CARD32 *tmp;
+ xkbNamesNotify nn;
+
+ tmp = (CARD32 *)&stuff[1];
+ xkb = dev->key->xkbInfo->desc;
+ names = xkb->names;
+
+ if (XkbAllocNames(xkb,stuff->which,stuff->nRadioGroups,
+ stuff->nKeyAliases)!=Success) {
+ return BadAlloc;
+ }
+
+ bzero(&nn,sizeof(xkbNamesNotify));
+ nn.changed= stuff->which;
+ tmp = (CARD32 *)&stuff[1];
+ if (stuff->which&XkbKeycodesNameMask)
+ names->keycodes= *tmp++;
+ if (stuff->which&XkbGeometryNameMask)
+ names->geometry= *tmp++;
+ if (stuff->which&XkbSymbolsNameMask)
+ names->symbols= *tmp++;
+ if (stuff->which&XkbPhysSymbolsNameMask)
+ names->phys_symbols= *tmp++;
+ if (stuff->which&XkbTypesNameMask)
+ names->types= *tmp++;
+ if (stuff->which&XkbCompatNameMask)
+ names->compat= *tmp++;
+ if ((stuff->which&XkbKeyTypeNamesMask)&&(stuff->nTypes>0)) {
+ register unsigned i;
+ register XkbKeyTypePtr type;
+
+ type= &xkb->map->types[stuff->firstType];
+ for (i=0;i<stuff->nTypes;i++,type++) {
+ type->name= *tmp++;
+ }
+ nn.firstType= stuff->firstType;
+ nn.nTypes= stuff->nTypes;
+ }
+ if (stuff->which&XkbKTLevelNamesMask) {
+ register XkbKeyTypePtr type;
+ register unsigned i;
+ CARD8 *width;
+
+ width = (CARD8 *)tmp;
+ tmp= (CARD32 *)(((char *)tmp)+XkbPaddedSize(stuff->nKTLevels));
+ type= &xkb->map->types[stuff->firstKTLevel];
+ for (i=0;i<stuff->nKTLevels;i++,type++) {
+ if (width[i]>0) {
+ if (type->level_names) {
+ register unsigned n;
+ for (n=0;n<width[i];n++) {
+ type->level_names[n]= tmp[n];
+ }
+ }
+ tmp+= width[i];
+ }
+ }
+ nn.firstLevelName= 0;
+ nn.nLevelNames= stuff->nTypes;
+ }
+ if (stuff->which&XkbIndicatorNamesMask) {
+ tmp= _XkbCopyMaskedAtoms(tmp,names->indicators,XkbNumIndicators,
+ stuff->indicators);
+ nn.changedIndicators= stuff->indicators;
+ }
+ if (stuff->which&XkbVirtualModNamesMask) {
+ tmp= _XkbCopyMaskedAtoms(tmp,names->vmods,XkbNumVirtualMods,
+ stuff->virtualMods);
+ nn.changedVirtualMods= stuff->virtualMods;
+ }
+ if (stuff->which&XkbGroupNamesMask) {
+ tmp= _XkbCopyMaskedAtoms(tmp,names->groups,XkbNumKbdGroups,
+ stuff->groupNames);
+ nn.changedVirtualMods= stuff->groupNames;
+ }
+ if (stuff->which&XkbKeyNamesMask) {
+ memcpy((char*)&names->keys[stuff->firstKey],(char *)tmp,
+ stuff->nKeys*XkbKeyNameLength);
+ tmp+= stuff->nKeys;
+ nn.firstKey= stuff->firstKey;
+ nn.nKeys= stuff->nKeys;
+ }
+ if (stuff->which&XkbKeyAliasesMask) {
+ if (stuff->nKeyAliases>0) {
+ register int na= stuff->nKeyAliases;
+ if (XkbAllocNames(xkb,XkbKeyAliasesMask,0,na)!=Success)
+ return BadAlloc;
+ memcpy((char *)names->key_aliases,(char *)tmp,
+ stuff->nKeyAliases*sizeof(XkbKeyAliasRec));
+ tmp+= stuff->nKeyAliases*2;
+ }
+ else if (names->key_aliases!=NULL) {
+ xfree(names->key_aliases);
+ names->key_aliases= NULL;
+ names->num_key_aliases= 0;
+ }
+ nn.nAliases= names->num_key_aliases;
+ }
+ if (stuff->which&XkbRGNamesMask) {
+ if (stuff->nRadioGroups>0) {
+ register unsigned i,nrg;
+ nrg= stuff->nRadioGroups;
+ if (XkbAllocNames(xkb,XkbRGNamesMask,nrg,0)!=Success)
+ return BadAlloc;
+
+ for (i=0;i<stuff->nRadioGroups;i++) {
+ names->radio_groups[i]= tmp[i];
+ }
+ tmp+= stuff->nRadioGroups;
+ }
+ else if (names->radio_groups) {
+ xfree(names->radio_groups);
+ names->radio_groups= NULL;
+ names->num_rg= 0;
+ }
+ nn.nRadioGroups= names->num_rg;
+ }
+ if (nn.changed) {
+ Bool needExtEvent;
+ needExtEvent= (nn.changed&XkbIndicatorNamesMask)!=0;
+ XkbSendNamesNotify(dev,&nn);
+ if (needExtEvent) {
+ XkbSrvLedInfoPtr sli;
+ xkbExtensionDeviceNotify edev;
+ register int i;
+ register unsigned bit;
+
+ sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,
+ XkbXI_IndicatorsMask);
+ sli->namesPresent= 0;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (names->indicators[i]!=None)
+ sli->namesPresent|= bit;
+ }
+ bzero(&edev,sizeof(xkbExtensionDeviceNotify));
+ edev.reason= XkbXI_IndicatorNamesMask;
+ edev.ledClass= KbdFeedbackClass;
+ edev.ledID= dev->kbdfeed->ctrl.id;
+ edev.ledsDefined= sli->namesPresent|sli->mapsPresent;
+ edev.ledState= sli->effectiveState;
+ edev.firstBtn= 0;
+ edev.nBtns= 0;
+ edev.supported= XkbXI_AllFeaturesMask;
+ edev.unsupported= 0;
+ XkbSendExtensionDeviceNotify(dev,client,&edev);
+ }
+ }
+ return Success;
+}
+
+int
+ProcXkbSetNames(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ CARD32 *tmp;
+ Atom bad;
+ int rc;
+
+ REQUEST(xkbSetNamesReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetNamesReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
+ CHK_MASK_LEGAL(0x01,stuff->which,XkbAllNamesMask);
+
+ /* check device-independent stuff */
+ tmp = (CARD32 *)&stuff[1];
+
+ if (stuff->which&XkbKeycodesNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbGeometryNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbSymbolsNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbPhysSymbolsNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue= bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbTypesNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+ if (stuff->which&XkbCompatNameMask) {
+ tmp= _XkbCheckAtoms(tmp,1,client->swapped,&bad);
+ if (!tmp) {
+ client->errorValue = bad;
+ return BadAtom;
+ }
+ }
+
+ /* start of device-dependent tests */
+ rc = _XkbSetNamesCheck(client, dev, stuff, tmp);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ {
+ rc = _XkbSetNamesCheck(client, other, stuff, tmp);
+ if (rc != Success)
+ return rc;
+ }
+ }
+ }
+ }
+
+ /* everything is okay -- update names */
+
+ rc = _XkbSetNames(client, dev, stuff);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ _XkbSetNames(client, other, stuff);
+ }
+ }
+ }
+
+ /* everything is okay -- update names */
+
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+#include "xkbgeom.h"
+
+#define XkbSizeCountedString(s) ((s)?((((2+strlen(s))+3)/4)*4):4)
+
+static char *
+XkbWriteCountedString(char *wire,char *str,Bool swap)
+{
+ CARD16 len,*pLen;
+
+ if (!str)
+ return wire;
+
+ len= strlen(str);
+ pLen= (CARD16 *)wire;
+ *pLen= len;
+ if (swap) {
+ register int n;
+ swaps(pLen,n);
+ }
+ memcpy(&wire[2],str,len);
+ wire+= ((2+len+3)/4)*4;
+ return wire;
+}
+
+static int
+XkbSizeGeomProperties(XkbGeometryPtr geom)
+{
+register int i,size;
+XkbPropertyPtr prop;
+
+ for (size=i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
+ size+= XkbSizeCountedString(prop->name);
+ size+= XkbSizeCountedString(prop->value);
+ }
+ return size;
+}
+
+static char *
+XkbWriteGeomProperties(char *wire,XkbGeometryPtr geom,Bool swap)
+{
+register int i;
+register XkbPropertyPtr prop;
+
+ for (i=0,prop=geom->properties;i<geom->num_properties;i++,prop++) {
+ wire= XkbWriteCountedString(wire,prop->name,swap);
+ wire= XkbWriteCountedString(wire,prop->value,swap);
+ }
+ return wire;
+}
+
+static int
+XkbSizeGeomKeyAliases(XkbGeometryPtr geom)
+{
+ return geom->num_key_aliases*(2*XkbKeyNameLength);
+}
+
+static char *
+XkbWriteGeomKeyAliases(char *wire,XkbGeometryPtr geom,Bool swap)
+{
+register int sz;
+
+ sz= geom->num_key_aliases*(XkbKeyNameLength*2);
+ if (sz>0) {
+ memcpy(wire,(char *)geom->key_aliases,sz);
+ wire+= sz;
+ }
+ return wire;
+}
+
+static int
+XkbSizeGeomColors(XkbGeometryPtr geom)
+{
+register int i,size;
+register XkbColorPtr color;
+
+ for (i=size=0,color=geom->colors;i<geom->num_colors;i++,color++) {
+ size+= XkbSizeCountedString(color->spec);
+ }
+ return size;
+}
+
+static char *
+XkbWriteGeomColors(char *wire,XkbGeometryPtr geom,Bool swap)
+{
+register int i;
+register XkbColorPtr color;
+
+ for (i=0,color=geom->colors;i<geom->num_colors;i++,color++) {
+ wire= XkbWriteCountedString(wire,color->spec,swap);
+ }
+ return wire;
+}
+
+static int
+XkbSizeGeomShapes(XkbGeometryPtr geom)
+{
+register int i,size;
+register XkbShapePtr shape;
+
+ for (i=size=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
+ register int n;
+ register XkbOutlinePtr ol;
+ size+= SIZEOF(xkbShapeWireDesc);
+ for (n=0,ol=shape->outlines;n<shape->num_outlines;n++,ol++) {
+ size+= SIZEOF(xkbOutlineWireDesc);
+ size+= ol->num_points*SIZEOF(xkbPointWireDesc);
+ }
+ }
+ return size;
+}
+
+static char *
+XkbWriteGeomShapes(char *wire,XkbGeometryPtr geom,Bool swap)
+{
+int i;
+XkbShapePtr shape;
+xkbShapeWireDesc * shapeWire;
+
+ for (i=0,shape=geom->shapes;i<geom->num_shapes;i++,shape++) {
+ register int o;
+ XkbOutlinePtr ol;
+ xkbOutlineWireDesc * olWire;
+ shapeWire= (xkbShapeWireDesc *)wire;
+ shapeWire->name= shape->name;
+ shapeWire->nOutlines= shape->num_outlines;
+ if (shape->primary!=NULL)
+ shapeWire->primaryNdx= XkbOutlineIndex(shape,shape->primary);
+ else shapeWire->primaryNdx= XkbNoShape;
+ if (shape->approx!=NULL)
+ shapeWire->approxNdx= XkbOutlineIndex(shape,shape->approx);
+ else shapeWire->approxNdx= XkbNoShape;
+ if (swap) {
+ register int n;
+ swapl(&shapeWire->name,n);
+ }
+ wire= (char *)&shapeWire[1];
+ for (o=0,ol=shape->outlines;o<shape->num_outlines;o++,ol++) {
+ register int p;
+ XkbPointPtr pt;
+ xkbPointWireDesc * ptWire;
+ olWire= (xkbOutlineWireDesc *)wire;
+ olWire->nPoints= ol->num_points;
+ olWire->cornerRadius= ol->corner_radius;
+ wire= (char *)&olWire[1];
+ ptWire= (xkbPointWireDesc *)wire;
+ for (p=0,pt=ol->points;p<ol->num_points;p++,pt++) {
+ ptWire[p].x= pt->x;
+ ptWire[p].y= pt->y;
+ if (swap) {
+ register int n;
+ swaps(&ptWire[p].x,n);
+ swaps(&ptWire[p].y,n);
+ }
+ }
+ wire= (char *)&ptWire[ol->num_points];
+ }
+ }
+ return wire;
+}
+
+static int
+XkbSizeGeomDoodads(int num_doodads,XkbDoodadPtr doodad)
+{
+register int i,size;
+
+ for (i=size=0;i<num_doodads;i++,doodad++) {
+ size+= SIZEOF(xkbAnyDoodadWireDesc);
+ if (doodad->any.type==XkbTextDoodad) {
+ size+= XkbSizeCountedString(doodad->text.text);
+ size+= XkbSizeCountedString(doodad->text.font);
+ }
+ else if (doodad->any.type==XkbLogoDoodad) {
+ size+= XkbSizeCountedString(doodad->logo.logo_name);
+ }
+ }
+ return size;
+}
+
+static char *
+XkbWriteGeomDoodads(char *wire,int num_doodads,XkbDoodadPtr doodad,Bool swap)
+{
+register int i;
+xkbDoodadWireDesc * doodadWire;
+
+ for (i=0;i<num_doodads;i++,doodad++) {
+ doodadWire= (xkbDoodadWireDesc *)wire;
+ wire= (char *)&doodadWire[1];
+ bzero(doodadWire,SIZEOF(xkbDoodadWireDesc));
+ doodadWire->any.name= doodad->any.name;
+ doodadWire->any.type= doodad->any.type;
+ doodadWire->any.priority= doodad->any.priority;
+ doodadWire->any.top= doodad->any.top;
+ doodadWire->any.left= doodad->any.left;
+ if (swap) {
+ register int n;
+ swapl(&doodadWire->any.name,n);
+ swaps(&doodadWire->any.top,n);
+ swaps(&doodadWire->any.left,n);
+ }
+ switch (doodad->any.type) {
+ case XkbOutlineDoodad:
+ case XkbSolidDoodad:
+ doodadWire->shape.angle= doodad->shape.angle;
+ doodadWire->shape.colorNdx= doodad->shape.color_ndx;
+ doodadWire->shape.shapeNdx= doodad->shape.shape_ndx;
+ if (swap) {
+ register int n;
+ swaps(&doodadWire->shape.angle,n);
+ }
+ break;
+ case XkbTextDoodad:
+ doodadWire->text.angle= doodad->text.angle;
+ doodadWire->text.width= doodad->text.width;
+ doodadWire->text.height= doodad->text.height;
+ doodadWire->text.colorNdx= doodad->text.color_ndx;
+ if (swap) {
+ register int n;
+ swaps(&doodadWire->text.angle,n);
+ swaps(&doodadWire->text.width,n);
+ swaps(&doodadWire->text.height,n);
+ }
+ wire= XkbWriteCountedString(wire,doodad->text.text,swap);
+ wire= XkbWriteCountedString(wire,doodad->text.font,swap);
+ break;
+ case XkbIndicatorDoodad:
+ doodadWire->indicator.shapeNdx= doodad->indicator.shape_ndx;
+ doodadWire->indicator.onColorNdx=doodad->indicator.on_color_ndx;
+ doodadWire->indicator.offColorNdx=
+ doodad->indicator.off_color_ndx;
+ break;
+ case XkbLogoDoodad:
+ doodadWire->logo.angle= doodad->logo.angle;
+ doodadWire->logo.colorNdx= doodad->logo.color_ndx;
+ doodadWire->logo.shapeNdx= doodad->logo.shape_ndx;
+ wire= XkbWriteCountedString(wire,doodad->logo.logo_name,swap);
+ break;
+ default:
+ ErrorF("[xkb] Unknown doodad type %d in XkbWriteGeomDoodads\n",
+ doodad->any.type);
+ ErrorF("[xkb] Ignored\n");
+ break;
+ }
+ }
+ return wire;
+}
+
+static char *
+XkbWriteGeomOverlay(char *wire,XkbOverlayPtr ol,Bool swap)
+{
+register int r;
+XkbOverlayRowPtr row;
+xkbOverlayWireDesc * olWire;
+
+ olWire= (xkbOverlayWireDesc *)wire;
+ olWire->name= ol->name;
+ olWire->nRows= ol->num_rows;
+ if (swap) {
+ register int n;
+ swapl(&olWire->name,n);
+ }
+ wire= (char *)&olWire[1];
+ for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
+ unsigned int k;
+ XkbOverlayKeyPtr key;
+ xkbOverlayRowWireDesc * rowWire;
+ rowWire= (xkbOverlayRowWireDesc *)wire;
+ rowWire->rowUnder= row->row_under;
+ rowWire->nKeys= row->num_keys;
+ wire= (char *)&rowWire[1];
+ for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
+ xkbOverlayKeyWireDesc * keyWire;
+ keyWire= (xkbOverlayKeyWireDesc *)wire;
+ memcpy(keyWire->over,key->over.name,XkbKeyNameLength);
+ memcpy(keyWire->under,key->under.name,XkbKeyNameLength);
+ wire= (char *)&keyWire[1];
+ }
+ }
+ return wire;
+}
+
+static int
+XkbSizeGeomSections(XkbGeometryPtr geom)
+{
+register int i,size;
+XkbSectionPtr section;
+
+ for (i=size=0,section=geom->sections;i<geom->num_sections;i++,section++) {
+ size+= SIZEOF(xkbSectionWireDesc);
+ if (section->rows) {
+ int r;
+ XkbRowPtr row;
+ for (r=0,row=section->rows;r<section->num_rows;row++,r++) {
+ size+= SIZEOF(xkbRowWireDesc);
+ size+= row->num_keys*SIZEOF(xkbKeyWireDesc);
+ }
+ }
+ if (section->doodads)
+ size+= XkbSizeGeomDoodads(section->num_doodads,section->doodads);
+ if (section->overlays) {
+ int o;
+ XkbOverlayPtr ol;
+ for (o=0,ol=section->overlays;o<section->num_overlays;o++,ol++) {
+ int r;
+ XkbOverlayRowPtr row;
+ size+= SIZEOF(xkbOverlayWireDesc);
+ for (r=0,row=ol->rows;r<ol->num_rows;r++,row++) {
+ size+= SIZEOF(xkbOverlayRowWireDesc);
+ size+= row->num_keys*SIZEOF(xkbOverlayKeyWireDesc);
+ }
+ }
+ }
+ }
+ return size;
+}
+
+static char *
+XkbWriteGeomSections(char *wire,XkbGeometryPtr geom,Bool swap)
+{
+register int i;
+XkbSectionPtr section;
+xkbSectionWireDesc * sectionWire;
+
+ for (i=0,section=geom->sections;i<geom->num_sections;i++,section++) {
+ sectionWire= (xkbSectionWireDesc *)wire;
+ sectionWire->name= section->name;
+ sectionWire->top= section->top;
+ sectionWire->left= section->left;
+ sectionWire->width= section->width;
+ sectionWire->height= section->height;
+ sectionWire->angle= section->angle;
+ sectionWire->priority= section->priority;
+ sectionWire->nRows= section->num_rows;
+ sectionWire->nDoodads= section->num_doodads;
+ sectionWire->nOverlays= section->num_overlays;
+ sectionWire->pad= 0;
+ if (swap) {
+ register int n;
+ swapl(§ionWire->name,n);
+ swaps(§ionWire->top,n);
+ swaps(§ionWire->left,n);
+ swaps(§ionWire->width,n);
+ swaps(§ionWire->height,n);
+ swaps(§ionWire->angle,n);
+ }
+ wire= (char *)§ionWire[1];
+ if (section->rows) {
+ int r;
+ XkbRowPtr row;
+ xkbRowWireDesc * rowWire;
+ for (r=0,row=section->rows;r<section->num_rows;r++,row++) {
+ rowWire= (xkbRowWireDesc *)wire;
+ rowWire->top= row->top;
+ rowWire->left= row->left;
+ rowWire->nKeys= row->num_keys;
+ rowWire->vertical= row->vertical;
+ rowWire->pad= 0;
+ if (swap) {
+ register int n;
+ swaps(&rowWire->top,n);
+ swaps(&rowWire->left,n);
+ }
+ wire= (char *)&rowWire[1];
+ if (row->keys) {
+ int k;
+ XkbKeyPtr key;
+ xkbKeyWireDesc * keyWire;
+ keyWire= (xkbKeyWireDesc *)wire;
+ for (k=0,key=row->keys;k<row->num_keys;k++,key++) {
+ memcpy(keyWire[k].name,key->name.name,XkbKeyNameLength);
+ keyWire[k].gap= key->gap;
+ keyWire[k].shapeNdx= key->shape_ndx;
+ keyWire[k].colorNdx= key->color_ndx;
+ if (swap) {
+ register int n;
+ swaps(&keyWire[k].gap,n);
+ }
+ }
+ wire= (char *)&keyWire[row->num_keys];
+ }
+ }
+ }
+ if (section->doodads) {
+ wire= XkbWriteGeomDoodads(wire,
+ section->num_doodads,section->doodads,
+ swap);
+ }
+ if (section->overlays) {
+ register int o;
+ for (o=0;o<section->num_overlays;o++) {
+ wire= XkbWriteGeomOverlay(wire,§ion->overlays[o],swap);
+ }
+ }
+ }
+ return wire;
+}
+
+static Status
+XkbComputeGetGeometryReplySize( XkbGeometryPtr geom,
+ xkbGetGeometryReply * rep,
+ Atom name)
+{
+int len;
+
+ if (geom!=NULL) {
+ len= XkbSizeCountedString(geom->label_font);
+ len+= XkbSizeGeomProperties(geom);
+ len+= XkbSizeGeomColors(geom);
+ len+= XkbSizeGeomShapes(geom);
+ len+= XkbSizeGeomSections(geom);
+ len+= XkbSizeGeomDoodads(geom->num_doodads,geom->doodads);
+ len+= XkbSizeGeomKeyAliases(geom);
+ rep->length= len/4;
+ rep->found= TRUE;
+ rep->name= geom->name;
+ rep->widthMM= geom->width_mm;
+ rep->heightMM= geom->height_mm;
+ rep->nProperties= geom->num_properties;
+ rep->nColors= geom->num_colors;
+ rep->nShapes= geom->num_shapes;
+ rep->nSections= geom->num_sections;
+ rep->nDoodads= geom->num_doodads;
+ rep->nKeyAliases= geom->num_key_aliases;
+ rep->baseColorNdx= XkbGeomColorIndex(geom,geom->base_color);
+ rep->labelColorNdx= XkbGeomColorIndex(geom,geom->label_color);
+ }
+ else {
+ rep->length= 0;
+ rep->found= FALSE;
+ rep->name= name;
+ rep->widthMM= rep->heightMM= 0;
+ rep->nProperties= rep->nColors= rep->nShapes= 0;
+ rep->nSections= rep->nDoodads= 0;
+ rep->nKeyAliases= 0;
+ rep->labelColorNdx= rep->baseColorNdx= 0;
+ }
+ return Success;
+}
+
+static int
+XkbSendGeometry( ClientPtr client,
+ XkbGeometryPtr geom,
+ xkbGetGeometryReply * rep,
+ Bool freeGeom)
+{
+ char *desc,*start;
+ int len;
+
+ if (geom!=NULL) {
+ len= rep->length*4;
+ start= desc= xalloc(len);
+ if (!start)
+ return BadAlloc;
+ desc= XkbWriteCountedString(desc,geom->label_font,client->swapped);
+ if ( rep->nProperties>0 )
+ desc = XkbWriteGeomProperties(desc,geom,client->swapped);
+ if ( rep->nColors>0 )
+ desc = XkbWriteGeomColors(desc,geom,client->swapped);
+ if ( rep->nShapes>0 )
+ desc = XkbWriteGeomShapes(desc,geom,client->swapped);
+ if ( rep->nSections>0 )
+ desc = XkbWriteGeomSections(desc,geom,client->swapped);
+ if ( rep->nDoodads>0 )
+ desc = XkbWriteGeomDoodads(desc,geom->num_doodads,geom->doodads,
+ client->swapped);
+ if ( rep->nKeyAliases>0 )
+ desc = XkbWriteGeomKeyAliases(desc,geom,client->swapped);
+ if ((desc-start)!=(len)) {
+ ErrorF("[xkb] BOGUS LENGTH in XkbSendGeometry, expected %d, got %ld\n",
+ len, (unsigned long)(desc-start));
+ }
+ }
+ else {
+ len= 0;
+ start= NULL;
+ }
+ if (client->swapped) {
+ register int n;
+ swaps(&rep->sequenceNumber,n);
+ swapl(&rep->length,n);
+ swapl(&rep->name,n);
+ swaps(&rep->widthMM,n);
+ swaps(&rep->heightMM,n);
+ swaps(&rep->nProperties,n);
+ swaps(&rep->nColors,n);
+ swaps(&rep->nShapes,n);
+ swaps(&rep->nSections,n);
+ swaps(&rep->nDoodads,n);
+ swaps(&rep->nKeyAliases,n);
+ }
+ WriteToClient(client, SIZEOF(xkbGetGeometryReply), (char *)rep);
+ if (len>0)
+ WriteToClient(client, len, start);
+ if (start!=NULL)
+ xfree((char *)start);
+ if (freeGeom)
+ XkbFreeGeometry(geom,XkbGeomAllMask,TRUE);
+ return client->noClientException;
+}
+
+int
+ProcXkbGetGeometry(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xkbGetGeometryReply rep;
+ XkbGeometryPtr geom;
+ Bool shouldFree;
+ Status status;
+
+ REQUEST(xkbGetGeometryReq);
+ REQUEST_SIZE_MATCH(xkbGetGeometryReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+ CHK_ATOM_OR_NONE(stuff->name);
+
+ geom= XkbLookupNamedGeometry(dev,stuff->name,&shouldFree);
+ rep.type= X_Reply;
+ rep.deviceID= dev->id;
+ rep.sequenceNumber= client->sequence;
+ rep.length= 0;
+ status= XkbComputeGetGeometryReplySize(geom,&rep,stuff->name);
+ if (status!=Success)
+ return status;
+ else return XkbSendGeometry(client,geom,&rep,shouldFree);
+}
+
+/***====================================================================***/
+
+static char *
+_GetCountedString(char **wire_inout,Bool swap)
+{
+char * wire,*str;
+CARD16 len,*plen;
+
+ wire= *wire_inout;
+ plen= (CARD16 *)wire;
+ if (swap) {
+ register int n;
+ swaps(plen,n);
+ }
+ len= *plen;
+ str= xalloc(len+1);
+ if (str) {
+ memcpy(str,&wire[2],len);
+ str[len]= '\0';
+ }
+ wire+= XkbPaddedSize(len+2);
+ *wire_inout= wire;
+ return str;
+}
+
+static Status
+_CheckSetDoodad( char ** wire_inout,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section,
+ ClientPtr client)
+{
+char * wire;
+xkbDoodadWireDesc * dWire;
+XkbDoodadPtr doodad;
+
+ dWire= (xkbDoodadWireDesc *)(*wire_inout);
+ wire= (char *)&dWire[1];
+ if (client->swapped) {
+ register int n;
+ swapl(&dWire->any.name,n);
+ swaps(&dWire->any.top,n);
+ swaps(&dWire->any.left,n);
+ swaps(&dWire->any.angle,n);
+ }
+ CHK_ATOM_ONLY(dWire->any.name);
+ doodad= XkbAddGeomDoodad(geom,section,dWire->any.name);
+ if (!doodad)
+ return BadAlloc;
+ doodad->any.type= dWire->any.type;
+ doodad->any.priority= dWire->any.priority;
+ doodad->any.top= dWire->any.top;
+ doodad->any.left= dWire->any.left;
+ doodad->any.angle= dWire->any.angle;
+ switch (doodad->any.type) {
+ case XkbOutlineDoodad:
+ case XkbSolidDoodad:
+ if (dWire->shape.colorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x40,geom->num_colors,
+ dWire->shape.colorNdx);
+ return BadMatch;
+ }
+ if (dWire->shape.shapeNdx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x41,geom->num_shapes,
+ dWire->shape.shapeNdx);
+ return BadMatch;
+ }
+ doodad->shape.color_ndx= dWire->shape.colorNdx;
+ doodad->shape.shape_ndx= dWire->shape.shapeNdx;
+ break;
+ case XkbTextDoodad:
+ if (dWire->text.colorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x42,geom->num_colors,
+ dWire->text.colorNdx);
+ return BadMatch;
+ }
+ if (client->swapped) {
+ register int n;
+ swaps(&dWire->text.width,n);
+ swaps(&dWire->text.height,n);
+ }
+ doodad->text.width= dWire->text.width;
+ doodad->text.height= dWire->text.height;
+ doodad->text.color_ndx= dWire->text.colorNdx;
+ doodad->text.text= _GetCountedString(&wire,client->swapped);
+ doodad->text.font= _GetCountedString(&wire,client->swapped);
+ break;
+ case XkbIndicatorDoodad:
+ if (dWire->indicator.onColorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x43,geom->num_colors,
+ dWire->indicator.onColorNdx);
+ return BadMatch;
+ }
+ if (dWire->indicator.offColorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x44,geom->num_colors,
+ dWire->indicator.offColorNdx);
+ return BadMatch;
+ }
+ if (dWire->indicator.shapeNdx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x45,geom->num_shapes,
+ dWire->indicator.shapeNdx);
+ return BadMatch;
+ }
+ doodad->indicator.shape_ndx= dWire->indicator.shapeNdx;
+ doodad->indicator.on_color_ndx= dWire->indicator.onColorNdx;
+ doodad->indicator.off_color_ndx= dWire->indicator.offColorNdx;
+ break;
+ case XkbLogoDoodad:
+ if (dWire->logo.colorNdx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x46,geom->num_colors,
+ dWire->logo.colorNdx);
+ return BadMatch;
+ }
+ if (dWire->logo.shapeNdx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x47,geom->num_shapes,
+ dWire->logo.shapeNdx);
+ return BadMatch;
+ }
+ doodad->logo.color_ndx= dWire->logo.colorNdx;
+ doodad->logo.shape_ndx= dWire->logo.shapeNdx;
+ doodad->logo.logo_name= _GetCountedString(&wire,client->swapped);
+ break;
+ default:
+ client->errorValue= _XkbErrCode2(0x4F,dWire->any.type);
+ return BadValue;
+ }
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+_CheckSetOverlay( char ** wire_inout,
+ XkbGeometryPtr geom,
+ XkbSectionPtr section,
+ ClientPtr client)
+{
+register int r;
+char * wire;
+XkbOverlayPtr ol;
+xkbOverlayWireDesc * olWire;
+xkbOverlayRowWireDesc * rWire;
+
+ wire= *wire_inout;
+ olWire= (xkbOverlayWireDesc *)wire;
+ if (client->swapped) {
+ register int n;
+ swapl(&olWire->name,n);
+ }
+ CHK_ATOM_ONLY(olWire->name);
+ ol= XkbAddGeomOverlay(section,olWire->name,olWire->nRows);
+ rWire= (xkbOverlayRowWireDesc *)&olWire[1];
+ for (r=0;r<olWire->nRows;r++) {
+ register int k;
+ xkbOverlayKeyWireDesc * kWire;
+ XkbOverlayRowPtr row;
+
+ if (rWire->rowUnder>section->num_rows) {
+ client->errorValue= _XkbErrCode4(0x20,r,section->num_rows,
+ rWire->rowUnder);
+ return BadMatch;
+ }
+ row= XkbAddGeomOverlayRow(ol,rWire->rowUnder,rWire->nKeys);
+ kWire= (xkbOverlayKeyWireDesc *)&rWire[1];
+ for (k=0;k<rWire->nKeys;k++,kWire++) {
+ if (XkbAddGeomOverlayKey(ol,row,
+ (char *)kWire->over,(char *)kWire->under)==NULL) {
+ client->errorValue= _XkbErrCode3(0x21,r,k);
+ return BadMatch;
+ }
+ }
+ rWire= (xkbOverlayRowWireDesc *)kWire;
+ }
+ olWire= (xkbOverlayWireDesc *)rWire;
+ wire= (char *)olWire;
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+_CheckSetSections( XkbGeometryPtr geom,
+ xkbSetGeometryReq * req,
+ char ** wire_inout,
+ ClientPtr client)
+{
+Status status;
+register int s;
+char * wire;
+xkbSectionWireDesc * sWire;
+XkbSectionPtr section;
+
+ wire= *wire_inout;
+ if (req->nSections<1)
+ return Success;
+ sWire= (xkbSectionWireDesc *)wire;
+ for (s=0;s<req->nSections;s++) {
+ register int r;
+ xkbRowWireDesc * rWire;
+ if (client->swapped) {
+ register int n;
+ swapl(&sWire->name,n);
+ swaps(&sWire->top,n);
+ swaps(&sWire->left,n);
+ swaps(&sWire->width,n);
+ swaps(&sWire->height,n);
+ swaps(&sWire->angle,n);
+ }
+ CHK_ATOM_ONLY(sWire->name);
+ section= XkbAddGeomSection(geom,sWire->name,sWire->nRows,
+ sWire->nDoodads,sWire->nOverlays);
+ if (!section)
+ return BadAlloc;
+ section->priority= sWire->priority;
+ section->top= sWire->top;
+ section->left= sWire->left;
+ section->width= sWire->width;
+ section->height= sWire->height;
+ section->angle= sWire->angle;
+ rWire= (xkbRowWireDesc *)&sWire[1];
+ for (r=0;r<sWire->nRows;r++) {
+ register int k;
+ XkbRowPtr row;
+ xkbKeyWireDesc * kWire;
+ if (client->swapped) {
+ register int n;
+ swaps(&rWire->top,n);
+ swaps(&rWire->left,n);
+ }
+ row= XkbAddGeomRow(section,rWire->nKeys);
+ if (!row)
+ return BadAlloc;
+ row->top= rWire->top;
+ row->left= rWire->left;
+ row->vertical= rWire->vertical;
+ kWire= (xkbKeyWireDesc *)&rWire[1];
+ for (k=0;k<rWire->nKeys;k++) {
+ XkbKeyPtr key;
+ key= XkbAddGeomKey(row);
+ if (!key)
+ return BadAlloc;
+ memcpy(key->name.name,kWire[k].name,XkbKeyNameLength);
+ key->gap= kWire[k].gap;
+ key->shape_ndx= kWire[k].shapeNdx;
+ key->color_ndx= kWire[k].colorNdx;
+ if (key->shape_ndx>=geom->num_shapes) {
+ client->errorValue= _XkbErrCode3(0x10,key->shape_ndx,
+ geom->num_shapes);
+ return BadMatch;
+ }
+ if (key->color_ndx>=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x11,key->color_ndx,
+ geom->num_colors);
+ return BadMatch;
+ }
+ }
+ rWire= (xkbRowWireDesc *)&kWire[rWire->nKeys];
+ }
+ wire= (char *)rWire;
+ if (sWire->nDoodads>0) {
+ register int d;
+ for (d=0;d<sWire->nDoodads;d++) {
+ status=_CheckSetDoodad(&wire,geom,section,client);
+ if (status!=Success)
+ return status;
+ }
+ }
+ if (sWire->nOverlays>0) {
+ register int o;
+ for (o=0;o<sWire->nOverlays;o++) {
+ status= _CheckSetOverlay(&wire,geom,section,client);
+ if (status!=Success)
+ return status;
+ }
+ }
+ sWire= (xkbSectionWireDesc *)wire;
+ }
+ wire= (char *)sWire;
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+_CheckSetShapes( XkbGeometryPtr geom,
+ xkbSetGeometryReq * req,
+ char ** wire_inout,
+ ClientPtr client)
+{
+register int i;
+char * wire;
+
+ wire= *wire_inout;
+ if (req->nShapes<1) {
+ client->errorValue= _XkbErrCode2(0x06,req->nShapes);
+ return BadValue;
+ }
+ else {
+ xkbShapeWireDesc * shapeWire;
+ XkbShapePtr shape;
+ register int o;
+ shapeWire= (xkbShapeWireDesc *)wire;
+ for (i=0;i<req->nShapes;i++) {
+ xkbOutlineWireDesc * olWire;
+ XkbOutlinePtr ol;
+ shape= XkbAddGeomShape(geom,shapeWire->name,shapeWire->nOutlines);
+ if (!shape)
+ return BadAlloc;
+ olWire= (xkbOutlineWireDesc *)(&shapeWire[1]);
+ for (o=0;o<shapeWire->nOutlines;o++) {
+ register int p;
+ XkbPointPtr pt;
+ xkbPointWireDesc * ptWire;
+
+ ol= XkbAddGeomOutline(shape,olWire->nPoints);
+ if (!ol)
+ return BadAlloc;
+ ol->corner_radius= olWire->cornerRadius;
+ ptWire= (xkbPointWireDesc *)&olWire[1];
+ for (p=0,pt=ol->points;p<olWire->nPoints;p++,pt++) {
+ pt->x= ptWire[p].x;
+ pt->y= ptWire[p].y;
+ if (client->swapped) {
+ register int n;
+ swaps(&pt->x,n);
+ swaps(&pt->y,n);
+ }
+ }
+ ol->num_points= olWire->nPoints;
+ olWire= (xkbOutlineWireDesc *)(&ptWire[olWire->nPoints]);
+ }
+ if (shapeWire->primaryNdx!=XkbNoShape)
+ shape->primary= &shape->outlines[shapeWire->primaryNdx];
+ if (shapeWire->approxNdx!=XkbNoShape)
+ shape->approx= &shape->outlines[shapeWire->approxNdx];
+ shapeWire= (xkbShapeWireDesc *)olWire;
+ }
+ wire= (char *)shapeWire;
+ }
+ if (geom->num_shapes!=req->nShapes) {
+ client->errorValue= _XkbErrCode3(0x07,geom->num_shapes,req->nShapes);
+ return BadMatch;
+ }
+
+ *wire_inout= wire;
+ return Success;
+}
+
+static Status
+_CheckSetGeom( XkbGeometryPtr geom,
+ xkbSetGeometryReq * req,
+ ClientPtr client)
+{
+register int i;
+Status status;
+char * wire;
+
+ wire= (char *)&req[1];
+ geom->label_font= _GetCountedString(&wire,client->swapped);
+
+ for (i=0;i<req->nProperties;i++) {
+ char *name,*val;
+ name= _GetCountedString(&wire,client->swapped);
+ if (!name)
+ return BadAlloc;
+ val= _GetCountedString(&wire,client->swapped);
+ if (!val) {
+ xfree(name);
+ return BadAlloc;
+ }
+ if (XkbAddGeomProperty(geom,name,val)==NULL) {
+ xfree(name);
+ xfree(val);
+ return BadAlloc;
+ }
+ xfree(name);
+ xfree(val);
+ }
+
+ if (req->nColors<2) {
+ client->errorValue= _XkbErrCode3(0x01,2,req->nColors);
+ return BadValue;
+ }
+ if (req->baseColorNdx>req->nColors) {
+ client->errorValue=_XkbErrCode3(0x03,req->nColors,req->baseColorNdx);
+ return BadMatch;
+ }
+ if (req->labelColorNdx>req->nColors) {
+ client->errorValue= _XkbErrCode3(0x03,req->nColors,req->labelColorNdx);
+ return BadMatch;
+ }
+ if (req->labelColorNdx==req->baseColorNdx) {
+ client->errorValue= _XkbErrCode3(0x04,req->baseColorNdx,
+ req->labelColorNdx);
+ return BadMatch;
+ }
+
+ for (i=0;i<req->nColors;i++) {
+ char *name;
+ name= _GetCountedString(&wire,client->swapped);
+ if (!name)
+ return BadAlloc;
+ if (!XkbAddGeomColor(geom,name,geom->num_colors)) {
+ xfree(name);
+ return BadAlloc;
+ }
+ xfree(name);
+ }
+ if (req->nColors!=geom->num_colors) {
+ client->errorValue= _XkbErrCode3(0x05,req->nColors,geom->num_colors);
+ return BadMatch;
+ }
+ geom->label_color= &geom->colors[req->labelColorNdx];
+ geom->base_color= &geom->colors[req->baseColorNdx];
+
+ if ((status=_CheckSetShapes(geom,req,&wire,client))!=Success)
+ return status;
+
+ if ((status=_CheckSetSections(geom,req,&wire,client))!=Success)
+ return status;
+
+ for (i=0;i<req->nDoodads;i++) {
+ status=_CheckSetDoodad(&wire,geom,NULL,client);
+ if (status!=Success)
+ return status;
+ }
+
+ for (i=0;i<req->nKeyAliases;i++) {
+ if (XkbAddGeomKeyAlias(geom,&wire[XkbKeyNameLength],wire)==NULL)
+ return BadAlloc;
+ wire+= 2*XkbKeyNameLength;
+ }
+ return Success;
+}
+
+static int
+_XkbSetGeometry(ClientPtr client, DeviceIntPtr dev, xkbSetGeometryReq *stuff)
+{
+ XkbDescPtr xkb;
+ Bool new_name;
+ xkbNewKeyboardNotify nkn;
+ XkbGeometryPtr geom,old;
+ XkbGeometrySizesRec sizes;
+ Status status;
+
+ xkb= dev->key->xkbInfo->desc;
+ old= xkb->geom;
+ xkb->geom= NULL;
+
+ sizes.which= XkbGeomAllMask;
+ sizes.num_properties= stuff->nProperties;
+ sizes.num_colors= stuff->nColors;
+ sizes.num_shapes= stuff->nShapes;
+ sizes.num_sections= stuff->nSections;
+ sizes.num_doodads= stuff->nDoodads;
+ sizes.num_key_aliases= stuff->nKeyAliases;
+ if ((status= XkbAllocGeometry(xkb,&sizes))!=Success) {
+ xkb->geom= old;
+ return status;
+ }
+ geom= xkb->geom;
+ geom->name= stuff->name;
+ geom->width_mm= stuff->widthMM;
+ geom->height_mm= stuff->heightMM;
+ if ((status= _CheckSetGeom(geom,stuff,client))!=Success) {
+ XkbFreeGeometry(geom,XkbGeomAllMask,TRUE);
+ xkb->geom= old;
+ return status;
+ }
+ new_name= (xkb->names->geometry!=geom->name);
+ xkb->names->geometry= geom->name;
+ if (old)
+ XkbFreeGeometry(old,XkbGeomAllMask,TRUE);
+ if (new_name) {
+ xkbNamesNotify nn;
+ bzero(&nn,sizeof(xkbNamesNotify));
+ nn.changed= XkbGeometryNameMask;
+ XkbSendNamesNotify(dev,&nn);
+ }
+ nkn.deviceID= nkn.oldDeviceID= dev->id;
+ nkn.minKeyCode= nkn.oldMinKeyCode= xkb->min_key_code;
+ nkn.maxKeyCode= nkn.oldMaxKeyCode= xkb->max_key_code;
+ nkn.requestMajor= XkbReqCode;
+ nkn.requestMinor= X_kbSetGeometry;
+ nkn.changed= XkbNKN_GeometryMask;
+ XkbSendNewKeyboardNotify(dev,&nkn);
+ return Success;
+}
+
+int
+ProcXkbSetGeometry(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ int rc;
+
+ REQUEST(xkbSetGeometryReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetGeometryReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
+ CHK_ATOM_OR_NONE(stuff->name);
+
+ rc = _XkbSetGeometry(client, dev, stuff);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if ((other != dev) && other->key && !IsMaster(other) && (other->u.master == dev))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ _XkbSetGeometry(client, other, stuff);
+ }
+ }
+ }
+
+ return Success;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbPerClientFlags(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xkbPerClientFlagsReply rep;
+ XkbInterestPtr interest;
+ Mask access_mode = DixGetAttrAccess | DixSetAttrAccess;
+
+ REQUEST(xkbPerClientFlagsReq);
+ REQUEST_SIZE_MATCH(xkbPerClientFlagsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode);
+ CHK_MASK_LEGAL(0x01,stuff->change,XkbPCF_AllFlagsMask);
+ CHK_MASK_MATCH(0x02,stuff->change,stuff->value);
+
+ interest = XkbFindClientResource((DevicePtr)dev,client);
+ memset(&rep, 0, sizeof(xkbPerClientFlagsReply));
+ rep.type= X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ if (stuff->change) {
+ client->xkbClientFlags&= ~stuff->change;
+ client->xkbClientFlags|= stuff->value;
+ }
+ if (stuff->change&XkbPCF_AutoResetControlsMask) {
+ Bool want;
+ want= stuff->value&XkbPCF_AutoResetControlsMask;
+ if (interest && !want) {
+ interest->autoCtrls= interest->autoCtrlValues= 0;
+ }
+ else if (want && (!interest)) {
+ XID id = FakeClientID(client->index);
+ AddResource(id,RT_XKBCLIENT,dev);
+ interest= XkbAddClientResource((DevicePtr)dev,client,id);
+ if (!interest)
+ return BadAlloc;
+ }
+ if (interest && want ) {
+ register unsigned affect;
+ affect= stuff->ctrlsToChange;
+
+ CHK_MASK_LEGAL(0x03,affect,XkbAllBooleanCtrlsMask);
+ CHK_MASK_MATCH(0x04,affect,stuff->autoCtrls);
+ CHK_MASK_MATCH(0x05,stuff->autoCtrls,stuff->autoCtrlValues);
+
+ interest->autoCtrls&= ~affect;
+ interest->autoCtrlValues&= ~affect;
+ interest->autoCtrls|= stuff->autoCtrls&affect;
+ interest->autoCtrlValues|= stuff->autoCtrlValues&affect;
+ }
+ }
+ rep.supported = XkbPCF_AllFlagsMask;
+ rep.value= client->xkbClientFlags&XkbPCF_AllFlagsMask;
+ if (interest) {
+ rep.autoCtrls= interest->autoCtrls;
+ rep.autoCtrlValues= interest->autoCtrlValues;
+ }
+ else {
+ rep.autoCtrls= rep.autoCtrlValues= 0;
+ }
+ if ( client->swapped ) {
+ register int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.supported,n);
+ swapl(&rep.value,n);
+ swapl(&rep.autoCtrls,n);
+ swapl(&rep.autoCtrlValues,n);
+ }
+ WriteToClient(client,SIZEOF(xkbPerClientFlagsReply), (char *)&rep);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+/* all latin-1 alphanumerics, plus parens, minus, underscore, slash */
+/* and wildcards */
+static unsigned char componentSpecLegal[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0xa7, 0xff, 0x87,
+ 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x07,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
+};
+
+/* same as above but accepts percent, plus and bar too */
+static unsigned char componentExprLegal[] = {
+ 0x00, 0x00, 0x00, 0x00, 0x20, 0xaf, 0xff, 0x87,
+ 0xfe, 0xff, 0xff, 0x87, 0xfe, 0xff, 0xff, 0x17,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff, 0x7f, 0xff
+};
+
+static char *
+GetComponentSpec(unsigned char **pWire,Bool allowExpr,int *errRtrn)
+{
+int len;
+register int i;
+unsigned char *wire,*str,*tmp,*legal;
+
+ if (allowExpr) legal= &componentExprLegal[0];
+ else legal= &componentSpecLegal[0];
+
+ wire= *pWire;
+ len= (*(unsigned char *)wire++);
+ if (len>0) {
+ str= xcalloc(1, len+1);
+ if (str) {
+ tmp= str;
+ for (i=0;i<len;i++) {
+ if (legal[(*wire)/8]&(1<<((*wire)%8)))
+ *tmp++= *wire++;
+ else wire++;
+ }
+ if (tmp!=str)
+ *tmp++= '\0';
+ else {
+ xfree(str);
+ str= NULL;
+ }
+ }
+ else {
+ *errRtrn= BadAlloc;
+ }
+ }
+ else {
+ str= NULL;
+ }
+ *pWire= wire;
+ return (char *)str;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbListComponents(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ xkbListComponentsReply rep;
+ unsigned len;
+ int status;
+ unsigned char * str;
+ XkbSrvListInfoRec list;
+
+ REQUEST(xkbListComponentsReq);
+ REQUEST_AT_LEAST_SIZE(xkbListComponentsReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+
+ status= Success;
+ str= (unsigned char *)&stuff[1];
+ bzero(&list,sizeof(XkbSrvListInfoRec));
+ list.maxRtrn= stuff->maxNames;
+ list.pattern[_XkbListKeycodes]= GetComponentSpec(&str,FALSE,&status);
+ list.pattern[_XkbListTypes]= GetComponentSpec(&str,FALSE,&status);
+ list.pattern[_XkbListCompat]= GetComponentSpec(&str,FALSE,&status);
+ list.pattern[_XkbListSymbols]= GetComponentSpec(&str,FALSE,&status);
+ list.pattern[_XkbListGeometry]= GetComponentSpec(&str,FALSE,&status);
+ if (status!=Success)
+ return status;
+ len= str-((unsigned char *)stuff);
+ if ((XkbPaddedSize(len)/4)!=stuff->length)
+ return BadLength;
+ if ((status=XkbDDXList(dev,&list,client))!=Success) {
+ if (list.pool) {
+ xfree(list.pool);
+ list.pool= NULL;
+ }
+ return status;
+ }
+ bzero(&rep,sizeof(xkbListComponentsReply));
+ rep.type= X_Reply;
+ rep.deviceID = dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = XkbPaddedSize(list.nPool)/4;
+ rep.nKeymaps = 0;
+ rep.nKeycodes = list.nFound[_XkbListKeycodes];
+ rep.nTypes = list.nFound[_XkbListTypes];
+ rep.nCompatMaps = list.nFound[_XkbListCompat];
+ rep.nSymbols = list.nFound[_XkbListSymbols];
+ rep.nGeometries = list.nFound[_XkbListGeometry];
+ rep.extra= 0;
+ if (list.nTotal>list.maxRtrn)
+ rep.extra = (list.nTotal-list.maxRtrn);
+ if (client->swapped) {
+ register int n;
+ swaps(&rep.sequenceNumber,n);
+ swapl(&rep.length,n);
+ swaps(&rep.nKeymaps,n);
+ swaps(&rep.nKeycodes,n);
+ swaps(&rep.nTypes,n);
+ swaps(&rep.nCompatMaps,n);
+ swaps(&rep.nSymbols,n);
+ swaps(&rep.nGeometries,n);
+ swaps(&rep.extra,n);
+ }
+ WriteToClient(client,SIZEOF(xkbListComponentsReply),(char *)&rep);
+ if (list.nPool && list.pool) {
+ WriteToClient(client,XkbPaddedSize(list.nPool), (char *)list.pool);
+ xfree(list.pool);
+ list.pool= NULL;
+ }
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbGetKbdByName(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ DeviceIntPtr tmpd;
+ xkbGetKbdByNameReply rep;
+ xkbGetMapReply mrep;
+ xkbGetCompatMapReply crep;
+ xkbGetIndicatorMapReply irep;
+ xkbGetNamesReply nrep;
+ xkbGetGeometryReply grep;
+ XkbComponentNamesRec names;
+ XkbDescPtr xkb, new;
+ unsigned char * str;
+ char mapFile[PATH_MAX];
+ unsigned len;
+ unsigned fwant,fneed,reported;
+ int status;
+ Bool geom_changed;
+ XkbSrvLedInfoPtr old_sli;
+ XkbSrvLedInfoPtr sli;
+ Mask access_mode = DixGetAttrAccess | DixManageAccess;
+
+ REQUEST(xkbGetKbdByNameReq);
+ REQUEST_AT_LEAST_SIZE(xkbGetKbdByNameReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ memset(&mrep,0,sizeof(mrep)); //MH
+
+ CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode);
+
+ xkb = dev->key->xkbInfo->desc;
+ status= Success;
+ str= (unsigned char *)&stuff[1];
+ if (GetComponentSpec(&str,TRUE,&status)) /* keymap, unsupported */
+ return BadMatch;
+ names.keycodes= GetComponentSpec(&str,TRUE,&status);
+ names.types= GetComponentSpec(&str,TRUE,&status);
+ names.compat= GetComponentSpec(&str,TRUE,&status);
+ names.symbols= GetComponentSpec(&str,TRUE,&status);
+ names.geometry= GetComponentSpec(&str,TRUE,&status);
+ if (status!=Success)
+ return status;
+ len= str-((unsigned char *)stuff);
+ if ((XkbPaddedSize(len)/4)!=stuff->length)
+ return BadLength;
+
+ CHK_MASK_LEGAL(0x01,stuff->want,XkbGBN_AllComponentsMask);
+ CHK_MASK_LEGAL(0x02,stuff->need,XkbGBN_AllComponentsMask);
+
+ if (stuff->load)
+ fwant= XkbGBN_AllComponentsMask;
+ else fwant= stuff->want|stuff->need;
+ if ((!names.compat)&&
+ (fwant&(XkbGBN_CompatMapMask|XkbGBN_IndicatorMapMask))) {
+ names.compat= _XkbDupString("%");
+ }
+ if ((!names.types)&&(fwant&(XkbGBN_TypesMask))) {
+ names.types= _XkbDupString("%");
+ }
+ if ((!names.symbols)&&(fwant&XkbGBN_SymbolsMask)) {
+ names.symbols= _XkbDupString("%");
+ }
+ geom_changed= ((names.geometry!=NULL)&&(strcmp(names.geometry,"%")!=0));
+ if ((!names.geometry)&&(fwant&XkbGBN_GeometryMask)) {
+ names.geometry= _XkbDupString("%");
+ geom_changed= FALSE;
+ }
+
+ bzero(mapFile,PATH_MAX);
+ rep.type= X_Reply;
+ rep.deviceID = dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = 0;
+ rep.minKeyCode = xkb->min_key_code;
+ rep.maxKeyCode = xkb->max_key_code;
+ rep.loaded= FALSE;
+ fwant= XkbConvertGetByNameComponents(TRUE,stuff->want)|XkmVirtualModsMask;
+ fneed= XkbConvertGetByNameComponents(TRUE,stuff->need);
+ rep.reported= XkbConvertGetByNameComponents(FALSE,fwant|fneed);
+ if (stuff->load) {
+ fneed|= XkmKeymapRequired;
+ fwant|= XkmKeymapLegal;
+ }
+ if ((fwant|fneed)&XkmSymbolsMask) {
+ fneed|= XkmKeyNamesIndex|XkmTypesIndex;
+ fwant|= XkmIndicatorsIndex;
+ }
+
+ /* We pass dev in here so we can get the old names out if needed. */
+ rep.found = XkbDDXLoadKeymapByNames(dev,&names,fwant,fneed,&new,
+ mapFile,PATH_MAX);
+ rep.newKeyboard= FALSE;
+ rep.pad1= rep.pad2= rep.pad3= rep.pad4= 0;
+
+ stuff->want|= stuff->need;
+ if (new==NULL)
+ rep.reported= 0;
+ else {
+ if (stuff->load)
+ rep.loaded= TRUE;
+ if (stuff->load ||
+ ((rep.reported&XkbGBN_SymbolsMask) && (new->compat))) {
+ XkbChangesRec changes;
+ bzero(&changes,sizeof(changes));
+ XkbUpdateDescActions(new,
+ new->min_key_code,XkbNumKeys(new),
+ &changes);
+ }
+
+ if (new->map==NULL)
+ rep.reported&= ~(XkbGBN_SymbolsMask|XkbGBN_TypesMask);
+ else if (rep.reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask)) {
+ mrep.type= X_Reply;
+ mrep.deviceID = dev->id;
+ mrep.sequenceNumber= client->sequence;
+ mrep.length = ((SIZEOF(xkbGetMapReply)-SIZEOF(xGenericReply))>>2);
+ mrep.minKeyCode = new->min_key_code;
+ mrep.maxKeyCode = new->max_key_code;
+ mrep.present = 0;
+ mrep.totalSyms = mrep.totalActs =
+ mrep.totalKeyBehaviors= mrep.totalKeyExplicit=
+ mrep.totalModMapKeys= mrep.totalVModMapKeys= 0;
+ if (rep.reported&(XkbGBN_TypesMask|XkbGBN_ClientSymbolsMask)) {
+ mrep.present|= XkbKeyTypesMask;
+ mrep.firstType = 0;
+ mrep.nTypes = mrep.totalTypes= new->map->num_types;
+ }
+ else {
+ mrep.firstType = mrep.nTypes= 0;
+ mrep.totalTypes= 0;
+ }
+ if (rep.reported&XkbGBN_ClientSymbolsMask) {
+ mrep.present|= (XkbKeySymsMask|XkbModifierMapMask);
+ mrep.firstKeySym = mrep.firstModMapKey= new->min_key_code;
+ mrep.nKeySyms = mrep.nModMapKeys= XkbNumKeys(new);
+ }
+ else {
+ mrep.firstKeySym= mrep.firstModMapKey= 0;
+ mrep.nKeySyms= mrep.nModMapKeys= 0;
+ }
+ if (rep.reported&XkbGBN_ServerSymbolsMask) {
+ mrep.present|= XkbAllServerInfoMask;
+ mrep.virtualMods= ~0;
+ mrep.firstKeyAct = mrep.firstKeyBehavior =
+ mrep.firstKeyExplicit = new->min_key_code;
+ mrep.nKeyActs = mrep.nKeyBehaviors =
+ mrep.nKeyExplicit = XkbNumKeys(new);
+ mrep.firstVModMapKey= new->min_key_code;
+ mrep.nVModMapKeys= XkbNumKeys(new);
+ }
+ else {
+ mrep.virtualMods= 0;
+ mrep.firstKeyAct= mrep.firstKeyBehavior=
+ mrep.firstKeyExplicit = 0;
+ mrep.nKeyActs= mrep.nKeyBehaviors= mrep.nKeyExplicit= 0;
+ }
+ XkbComputeGetMapReplySize(new,&mrep);
+ rep.length+= SIZEOF(xGenericReply)/4+mrep.length;
+ }
+ if (new->compat==NULL)
+ rep.reported&= ~XkbGBN_CompatMapMask;
+ else if (rep.reported&XkbGBN_CompatMapMask) {
+ crep.type= X_Reply;
+ crep.deviceID= dev->id;
+ crep.sequenceNumber= client->sequence;
+ crep.length= 0;
+ crep.groups= XkbAllGroupsMask;
+ crep.firstSI= 0;
+ crep.nSI= crep.nTotalSI= new->compat->num_si;
+ XkbComputeGetCompatMapReplySize(new->compat,&crep);
+ rep.length+= SIZEOF(xGenericReply)/4+crep.length;
+ }
+ if (new->indicators==NULL)
+ rep.reported&= ~XkbGBN_IndicatorMapMask;
+ else if (rep.reported&XkbGBN_IndicatorMapMask) {
+ irep.type= X_Reply;
+ irep.deviceID= dev->id;
+ irep.sequenceNumber= client->sequence;
+ irep.length= 0;
+ irep.which= XkbAllIndicatorsMask;
+ XkbComputeGetIndicatorMapReplySize(new->indicators,&irep);
+ rep.length+= SIZEOF(xGenericReply)/4+irep.length;
+ }
+ if (new->names==NULL)
+ rep.reported&= ~(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask);
+ else if (rep.reported&(XkbGBN_OtherNamesMask|XkbGBN_KeyNamesMask)) {
+ nrep.type= X_Reply;
+ nrep.deviceID= dev->id;
+ nrep.sequenceNumber= client->sequence;
+ nrep.length= 0;
+ nrep.minKeyCode= new->min_key_code;
+ nrep.maxKeyCode= new->max_key_code;
+ if (rep.reported&XkbGBN_OtherNamesMask) {
+ nrep.which= XkbAllNamesMask;
+ if (new->map!=NULL)
+ nrep.nTypes= new->map->num_types;
+ else nrep.nTypes= 0;
+ nrep.nKTLevels= 0;
+ nrep.groupNames= XkbAllGroupsMask;
+ nrep.virtualMods= XkbAllVirtualModsMask;
+ nrep.indicators= XkbAllIndicatorsMask;
+ nrep.nRadioGroups= new->names->num_rg;
+ }
+ else {
+ nrep.which= 0;
+ nrep.nTypes= 0;
+ nrep.nKTLevels= 0;
+ nrep.groupNames= 0;
+ nrep.virtualMods= 0;
+ nrep.indicators= 0;
+ nrep.nRadioGroups= 0;
+ }
+ if (rep.reported&XkbGBN_KeyNamesMask) {
+ nrep.which|= XkbKeyNamesMask;
+ nrep.firstKey= new->min_key_code;
+ nrep.nKeys= XkbNumKeys(new);
+ nrep.nKeyAliases= new->names->num_key_aliases;
+ if (nrep.nKeyAliases)
+ nrep.which|= XkbKeyAliasesMask;
+ }
+ else {
+ nrep.which&= ~(XkbKeyNamesMask|XkbKeyAliasesMask);
+ nrep.firstKey= nrep.nKeys= 0;
+ nrep.nKeyAliases= 0;
+ }
+ XkbComputeGetNamesReplySize(new,&nrep);
+ rep.length+= SIZEOF(xGenericReply)/4+nrep.length;
+ }
+ if (new->geom==NULL)
+ rep.reported&= ~XkbGBN_GeometryMask;
+ else if (rep.reported&XkbGBN_GeometryMask) {
+ grep.type= X_Reply;
+ grep.deviceID= dev->id;
+ grep.sequenceNumber= client->sequence;
+ grep.length= 0;
+ grep.found= TRUE;
+ grep.pad= 0;
+ grep.widthMM= grep.heightMM= 0;
+ grep.nProperties= grep.nColors= grep.nShapes= 0;
+ grep.nSections= grep.nDoodads= 0;
+ grep.baseColorNdx= grep.labelColorNdx= 0;
+ XkbComputeGetGeometryReplySize(new->geom,&grep,None);
+ rep.length+= SIZEOF(xGenericReply)/4+grep.length;
+ }
+ }
+
+ reported= rep.reported;
+ if ( client->swapped ) {
+ register int n;
+ swaps(&rep.sequenceNumber,n);
+ swapl(&rep.length,n);
+ swaps(&rep.found,n);
+ swaps(&rep.reported,n);
+ }
+ WriteToClient(client,SIZEOF(xkbGetKbdByNameReply), (char *)&rep);
+ if (reported&(XkbGBN_SymbolsMask|XkbGBN_TypesMask))
+ XkbSendMap(client,new,&mrep);
+ if (reported&XkbGBN_CompatMapMask)
+ XkbSendCompatMap(client,new->compat,&crep);
+ if (reported&XkbGBN_IndicatorMapMask)
+ XkbSendIndicatorMap(client,new->indicators,&irep);
+ if (reported&(XkbGBN_KeyNamesMask|XkbGBN_OtherNamesMask))
+ XkbSendNames(client,new,&nrep);
+ if (reported&XkbGBN_GeometryMask)
+ XkbSendGeometry(client,new->geom,&grep,FALSE);
+ if (rep.loaded) {
+ XkbDescPtr old_xkb;
+ xkbNewKeyboardNotify nkn;
+ int i,nG,nTG;
+ old_xkb= xkb;
+ xkb= new;
+ dev->key->xkbInfo->desc= xkb;
+ new= old_xkb; /* so it'll get freed automatically */
+
+ *xkb->ctrls= *old_xkb->ctrls;
+ for (nG=nTG=0,i=xkb->min_key_code;i<=xkb->max_key_code;i++) {
+ nG= XkbKeyNumGroups(xkb,i);
+ if (nG>=XkbNumKbdGroups) {
+ nTG= XkbNumKbdGroups;
+ break;
+ }
+ if (nG>nTG) {
+ nTG= nG;
+ }
+ }
+ xkb->ctrls->num_groups= nTG;
+
+ for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
+ if ((tmpd == dev) || (!IsMaster(tmpd) && tmpd->u.master == dev)) {
+ if (tmpd != dev)
+ XkbCopyDeviceKeymap(tmpd, dev);
+
+ if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
+ old_sli = tmpd->kbdfeed->xkb_sli;
+ tmpd->kbdfeed->xkb_sli = NULL;
+ sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0);
+ if (sli) {
+ sli->explicitState = old_sli->explicitState;
+ sli->effectiveState = old_sli->effectiveState;
+ }
+ tmpd->kbdfeed->xkb_sli = sli;
+ XkbFreeSrvLedInfo(old_sli);
+ }
+ }
+ }
+
+ nkn.deviceID= nkn.oldDeviceID= dev->id;
+ nkn.minKeyCode= new->min_key_code;
+ nkn.maxKeyCode= new->max_key_code;
+ nkn.oldMinKeyCode= xkb->min_key_code;
+ nkn.oldMaxKeyCode= xkb->max_key_code;
+ nkn.requestMajor= XkbReqCode;
+ nkn.requestMinor= X_kbGetKbdByName;
+ nkn.changed= XkbNKN_KeycodesMask;
+ if (geom_changed)
+ nkn.changed|= XkbNKN_GeometryMask;
+ XkbSendNewKeyboardNotify(dev,&nkn);
+
+ if (!IsMaster(dev) && dev->u.master)
+ {
+ DeviceIntPtr master = dev->u.master;
+ if (master->u.lastSlave == dev)
+ {
+ XkbCopyDeviceKeymap(dev->u.master, dev);
+ XkbSendNewKeyboardNotify(dev,&nkn);
+ }
+ }
+ }
+ if ((new!=NULL)&&(new!=xkb)) {
+ XkbFreeKeyboard(new,XkbAllComponentsMask,TRUE);
+ new= NULL;
+ }
+ if (names.keycodes) { xfree(names.keycodes); names.keycodes= NULL; }
+ if (names.types) { xfree(names.types); names.types= NULL; }
+ if (names.compat) { xfree(names.compat); names.compat= NULL; }
+ if (names.symbols) { xfree(names.symbols); names.symbols= NULL; }
+ if (names.geometry) { xfree(names.geometry); names.geometry= NULL; }
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+static int
+ComputeDeviceLedInfoSize( DeviceIntPtr dev,
+ unsigned int what,
+ XkbSrvLedInfoPtr sli)
+{
+int nNames,nMaps;
+register unsigned n,bit;
+
+ if (sli==NULL)
+ return 0;
+ nNames= nMaps= 0;
+ if ((what&XkbXI_IndicatorNamesMask)==0)
+ sli->namesPresent= 0;
+ if ((what&XkbXI_IndicatorMapsMask)==0)
+ sli->mapsPresent= 0;
+
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (sli->names && sli->names[n]!=None) {
+ sli->namesPresent|= bit;
+ nNames++;
+ }
+ if (sli->maps && XkbIM_InUse(&sli->maps[n])) {
+ sli->mapsPresent|= bit;
+ nMaps++;
+ }
+ }
+ return (nNames*4)+(nMaps*SIZEOF(xkbIndicatorMapWireDesc));
+}
+
+static int
+CheckDeviceLedFBs( DeviceIntPtr dev,
+ int class,
+ int id,
+ xkbGetDeviceInfoReply * rep,
+ ClientPtr client)
+{
+int nFBs= 0;
+int length= 0;
+Bool classOk;
+
+ if (class==XkbDfltXIClass) {
+ if (dev->kbdfeed) class= KbdFeedbackClass;
+ else if (dev->leds) class= LedFeedbackClass;
+ else {
+ client->errorValue= _XkbErrCode2(XkbErr_BadClass,class);
+ return XkbKeyboardErrorCode;
+ }
+ }
+ classOk= FALSE;
+ if ((dev->kbdfeed)&&((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) {
+ KbdFeedbackPtr kf;
+ classOk= TRUE;
+ for (kf= dev->kbdfeed;(kf);kf=kf->next) {
+ if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=kf->ctrl.id))
+ continue;
+ nFBs++;
+ length+= SIZEOF(xkbDeviceLedsWireDesc);
+ if (!kf->xkb_sli)
+ kf->xkb_sli= XkbAllocSrvLedInfo(dev,kf,NULL,0);
+ length+= ComputeDeviceLedInfoSize(dev,rep->present,kf->xkb_sli);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ if ((dev->leds)&&((class==LedFeedbackClass)||(class==XkbAllXIClasses))) {
+ LedFeedbackPtr lf;
+ classOk= TRUE;
+ for (lf= dev->leds;(lf);lf=lf->next) {
+ if ((id!=XkbAllXIIds)&&(id!=XkbDfltXIId)&&(id!=lf->ctrl.id))
+ continue;
+ nFBs++;
+ length+= SIZEOF(xkbDeviceLedsWireDesc);
+ if (!lf->xkb_sli)
+ lf->xkb_sli= XkbAllocSrvLedInfo(dev,NULL,lf,0);
+ length+= ComputeDeviceLedInfoSize(dev,rep->present,lf->xkb_sli);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ if (nFBs>0) {
+ rep->nDeviceLedFBs= nFBs;
+ rep->length+= (length/4);
+ return Success;
+ }
+ if (classOk) client->errorValue= _XkbErrCode2(XkbErr_BadId,id);
+ else client->errorValue= _XkbErrCode2(XkbErr_BadClass,class);
+ return XkbKeyboardErrorCode;
+}
+
+static int
+SendDeviceLedInfo( XkbSrvLedInfoPtr sli,
+ ClientPtr client)
+{
+xkbDeviceLedsWireDesc wire;
+int length;
+
+ length= 0;
+ wire.ledClass= sli->class;
+ wire.ledID= sli->id;
+ wire.namesPresent= sli->namesPresent;
+ wire.mapsPresent= sli->mapsPresent;
+ wire.physIndicators= sli->physIndicators;
+ wire.state= sli->effectiveState;
+ if (client->swapped) {
+ register int n;
+ swaps(&wire.ledClass,n);
+ swaps(&wire.ledID,n);
+ swapl(&wire.namesPresent,n);
+ swapl(&wire.mapsPresent,n);
+ swapl(&wire.physIndicators,n);
+ swapl(&wire.state,n);
+ }
+ WriteToClient(client,SIZEOF(xkbDeviceLedsWireDesc),(char *)&wire);
+ length+= SIZEOF(xkbDeviceLedsWireDesc);
+ if (sli->namesPresent|sli->mapsPresent) {
+ register unsigned i,bit;
+ if (sli->namesPresent) {
+ CARD32 awire;
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ if (sli->namesPresent&bit) {
+ awire= (CARD32)sli->names[i];
+ if (client->swapped) {
+ register int n;
+ swapl(&awire,n);
+ }
+ WriteToClient(client,4,(char *)&awire);
+ length+= 4;
+ }
+ }
+ }
+ if (sli->mapsPresent) {
+ for (i=0,bit=1;i<XkbNumIndicators;i++,bit<<=1) {
+ xkbIndicatorMapWireDesc iwire;
+ if (sli->mapsPresent&bit) {
+ iwire.flags= sli->maps[i].flags;
+ iwire.whichGroups= sli->maps[i].which_groups;
+ iwire.groups= sli->maps[i].groups;
+ iwire.whichMods= sli->maps[i].which_mods;
+ iwire.mods= sli->maps[i].mods.mask;
+ iwire.realMods= sli->maps[i].mods.real_mods;
+ iwire.virtualMods= sli->maps[i].mods.vmods;
+ iwire.ctrls= sli->maps[i].ctrls;
+ if (client->swapped) {
+ register int n;
+ swaps(&iwire.virtualMods,n);
+ swapl(&iwire.ctrls,n);
+ }
+ WriteToClient(client,SIZEOF(xkbIndicatorMapWireDesc),
+ (char *)&iwire);
+ length+= SIZEOF(xkbIndicatorMapWireDesc);
+ }
+ }
+ }
+ }
+ return length;
+}
+
+static int
+SendDeviceLedFBs( DeviceIntPtr dev,
+ int class,
+ int id,
+ unsigned wantLength,
+ ClientPtr client)
+{
+int length= 0;
+
+ if (class==XkbDfltXIClass) {
+ if (dev->kbdfeed) class= KbdFeedbackClass;
+ else if (dev->leds) class= LedFeedbackClass;
+ }
+ if ((dev->kbdfeed)&&
+ ((class==KbdFeedbackClass)||(class==XkbAllXIClasses))) {
+ KbdFeedbackPtr kf;
+ for (kf= dev->kbdfeed;(kf);kf=kf->next) {
+ if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==kf->ctrl.id)) {
+ length+= SendDeviceLedInfo(kf->xkb_sli,client);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ }
+ if ((dev->leds)&&
+ ((class==LedFeedbackClass)||(class==XkbAllXIClasses))) {
+ LedFeedbackPtr lf;
+ for (lf= dev->leds;(lf);lf=lf->next) {
+ if ((id==XkbAllXIIds)||(id==XkbDfltXIId)||(id==lf->ctrl.id)) {
+ length+= SendDeviceLedInfo(lf->xkb_sli,client);
+ if (id!=XkbAllXIIds)
+ break;
+ }
+ }
+ }
+ if (length==wantLength)
+ return Success;
+ else return BadLength;
+}
+
+int
+ProcXkbGetDeviceInfo(ClientPtr client)
+{
+DeviceIntPtr dev;
+xkbGetDeviceInfoReply rep;
+int status,nDeviceLedFBs;
+unsigned length,nameLen;
+CARD16 ledClass,ledID;
+unsigned wanted;
+char * str;
+
+ REQUEST(xkbGetDeviceInfoReq);
+ REQUEST_SIZE_MATCH(xkbGetDeviceInfoReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ wanted= stuff->wanted;
+
+ CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixGetAttrAccess);
+ CHK_MASK_LEGAL(0x01,wanted,XkbXI_AllDeviceFeaturesMask);
+
+ if ((!dev->button)||((stuff->nBtns<1)&&(!stuff->allBtns)))
+ wanted&= ~XkbXI_ButtonActionsMask;
+ if ((!dev->kbdfeed)&&(!dev->leds))
+ wanted&= ~XkbXI_IndicatorsMask;
+
+ nameLen= XkbSizeCountedString(dev->name);
+ bzero((char *)&rep,SIZEOF(xkbGetDeviceInfoReply));
+ rep.type = X_Reply;
+ rep.deviceID= dev->id;
+ rep.sequenceNumber = client->sequence;
+ rep.length = nameLen/4;
+ rep.present = wanted;
+ rep.supported = XkbXI_AllDeviceFeaturesMask;
+ rep.unsupported = 0;
+ rep.firstBtnWanted = rep.nBtnsWanted = 0;
+ rep.firstBtnRtrn = rep.nBtnsRtrn = 0;
+ if (dev->button)
+ rep.totalBtns= dev->button->numButtons;
+ else rep.totalBtns= 0;
+ rep.devType= dev->xinput_type;
+ rep.hasOwnState= (dev->key && dev->key->xkbInfo);
+ rep.nDeviceLedFBs = 0;
+ if (dev->kbdfeed) rep.dfltKbdFB= dev->kbdfeed->ctrl.id;
+ else rep.dfltKbdFB= XkbXINone;
+ if (dev->leds) rep.dfltLedFB= dev->leds->ctrl.id;
+ else rep.dfltLedFB= XkbXINone;
+
+ ledClass= stuff->ledClass;
+ ledID= stuff->ledID;
+
+ rep.firstBtnWanted= rep.nBtnsWanted= 0;
+ rep.firstBtnRtrn= rep.nBtnsRtrn= 0;
+ if (wanted&XkbXI_ButtonActionsMask) {
+ if (stuff->allBtns) {
+ stuff->firstBtn= 0;
+ stuff->nBtns= dev->button->numButtons;
+ }
+
+ if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) {
+ client->errorValue = _XkbErrCode4(0x02,dev->button->numButtons,
+ stuff->firstBtn,
+ stuff->nBtns);
+ return BadValue;
+ }
+ else {
+ rep.firstBtnWanted= stuff->firstBtn;
+ rep.nBtnsWanted= stuff->nBtns;
+ if (dev->button->xkb_acts!=NULL) {
+ XkbAction *act;
+ register int i;
+
+ rep.firstBtnRtrn= stuff->firstBtn;
+ rep.nBtnsRtrn= stuff->nBtns;
+ act= &dev->button->xkb_acts[rep.firstBtnWanted];
+ for (i=0;i<rep.nBtnsRtrn;i++,act++) {
+ if (act->type!=XkbSA_NoAction)
+ break;
+ }
+ rep.firstBtnRtrn+= i;
+ rep.nBtnsRtrn-= i;
+ act= &dev->button->xkb_acts[rep.firstBtnRtrn+rep.nBtnsRtrn-1];
+ for (i=0;i<rep.nBtnsRtrn;i++,act--) {
+ if (act->type!=XkbSA_NoAction)
+ break;
+ }
+ rep.nBtnsRtrn-= i;
+ }
+ rep.length+= (rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc))/4;
+ }
+ }
+
+ if (wanted&XkbXI_IndicatorsMask) {
+ status= CheckDeviceLedFBs(dev,ledClass,ledID,&rep,client);
+ if (status!=Success)
+ return status;
+ }
+ length= rep.length*4;
+ nDeviceLedFBs = rep.nDeviceLedFBs;
+ if (client->swapped) {
+ register int n;
+ swaps(&rep.sequenceNumber,n);
+ swapl(&rep.length,n);
+ swaps(&rep.present,n);
+ swaps(&rep.supported,n);
+ swaps(&rep.unsupported,n);
+ swaps(&rep.nDeviceLedFBs,n);
+ swapl(&rep.type,n);
+ }
+ WriteToClient(client,SIZEOF(xkbGetDeviceInfoReply), (char *)&rep);
+
+ str= xalloc(nameLen);
+ if (!str)
+ return BadAlloc;
+ XkbWriteCountedString(str,dev->name,client->swapped);
+ WriteToClient(client,nameLen,str);
+ xfree(str);
+ length-= nameLen;
+
+ if (rep.nBtnsRtrn>0) {
+ int sz;
+ xkbActionWireDesc * awire;
+ sz= rep.nBtnsRtrn*SIZEOF(xkbActionWireDesc);
+ awire= (xkbActionWireDesc *)&dev->button->xkb_acts[rep.firstBtnRtrn];
+ WriteToClient(client,sz,(char *)awire);
+ length-= sz;
+ }
+ if (nDeviceLedFBs>0) {
+ status= SendDeviceLedFBs(dev,ledClass,ledID,length,client);
+ if (status!=Success)
+ return status;
+ }
+ else if (length!=0) {
+ ErrorF("[xkb] Internal Error! BadLength in ProcXkbGetDeviceInfo\n");
+ ErrorF("[xkb] Wrote %d fewer bytes than expected\n",length);
+ return BadLength;
+ }
+ return client->noClientException;
+}
+
+static char *
+CheckSetDeviceIndicators( char * wire,
+ DeviceIntPtr dev,
+ int num,
+ int * status_rtrn,
+ ClientPtr client)
+{
+xkbDeviceLedsWireDesc * ledWire;
+int i;
+XkbSrvLedInfoPtr sli;
+
+ ledWire= (xkbDeviceLedsWireDesc *)wire;
+ for (i=0;i<num;i++) {
+ if (client->swapped) {
+ register int n;
+ swaps(&ledWire->ledClass,n);
+ swaps(&ledWire->ledID,n);
+ swapl(&ledWire->namesPresent,n);
+ swapl(&ledWire->mapsPresent,n);
+ swapl(&ledWire->physIndicators,n);
+ }
+
+ sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID,
+ XkbXI_IndicatorsMask);
+ if (sli!=NULL) {
+ register int n;
+ register unsigned bit;
+ int nMaps,nNames;
+ CARD32 *atomWire;
+ xkbIndicatorMapWireDesc *mapWire;
+
+ nMaps= nNames= 0;
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (ledWire->namesPresent&bit)
+ nNames++;
+ if (ledWire->mapsPresent&bit)
+ nMaps++;
+ }
+ atomWire= (CARD32 *)&ledWire[1];
+ if (nNames>0) {
+ for (n=0;n<nNames;n++) {
+ if (client->swapped) {
+ register int t;
+ swapl(atomWire,t);
+ }
+ CHK_ATOM_OR_NONE3(((Atom)(*atomWire)),client->errorValue,
+ *status_rtrn,NULL);
+ atomWire++;
+ }
+ }
+ mapWire= (xkbIndicatorMapWireDesc *)atomWire;
+ if (nMaps>0) {
+ for (n=0;n<nMaps;n++) {
+ if (client->swapped) {
+ register int t;
+ swaps(&mapWire->virtualMods,t);
+ swapl(&mapWire->ctrls,t);
+ }
+ CHK_MASK_LEGAL3(0x21,mapWire->whichGroups,
+ XkbIM_UseAnyGroup,
+ client->errorValue,
+ *status_rtrn,NULL);
+ CHK_MASK_LEGAL3(0x22,mapWire->whichMods,XkbIM_UseAnyMods,
+ client->errorValue,
+ *status_rtrn,NULL);
+ mapWire++;
+ }
+ }
+ ledWire= (xkbDeviceLedsWireDesc *)mapWire;
+ }
+ else {
+ /* SHOULD NEVER HAPPEN */
+ return (char *)ledWire;
+ }
+ }
+ return (char *)ledWire;
+}
+
+static char *
+SetDeviceIndicators( char * wire,
+ DeviceIntPtr dev,
+ unsigned changed,
+ int num,
+ int * status_rtrn,
+ ClientPtr client,
+ xkbExtensionDeviceNotify *ev)
+{
+xkbDeviceLedsWireDesc * ledWire;
+int i;
+XkbEventCauseRec cause;
+unsigned namec,mapc,statec;
+xkbExtensionDeviceNotify ed;
+XkbChangesRec changes;
+DeviceIntPtr kbd;
+
+ bzero((char *)&ed,sizeof(xkbExtensionDeviceNotify));
+ bzero((char *)&changes,sizeof(XkbChangesRec));
+ XkbSetCauseXkbReq(&cause,X_kbSetDeviceInfo,client);
+ ledWire= (xkbDeviceLedsWireDesc *)wire;
+ for (i=0;i<num;i++) {
+ register int n;
+ register unsigned bit;
+ CARD32 * atomWire;
+ xkbIndicatorMapWireDesc * mapWire;
+ XkbSrvLedInfoPtr sli;
+
+ namec= mapc= statec= 0;
+ sli= XkbFindSrvLedInfo(dev,ledWire->ledClass,ledWire->ledID,
+ XkbXI_IndicatorMapsMask);
+ if (!sli) {
+ /* SHOULD NEVER HAPPEN!! */
+ return (char *)ledWire;
+ }
+
+ atomWire= (CARD32 *)&ledWire[1];
+ if (changed&XkbXI_IndicatorNamesMask) {
+ namec= sli->namesPresent|ledWire->namesPresent;
+ bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom));
+ }
+ if (ledWire->namesPresent) {
+ sli->namesPresent= ledWire->namesPresent;
+ bzero((char *)sli->names,XkbNumIndicators*sizeof(Atom));
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (ledWire->namesPresent&bit) {
+ sli->names[n]= (Atom)*atomWire;
+ if (sli->names[n]==None)
+ ledWire->namesPresent&= ~bit;
+ atomWire++;
+ }
+ }
+ }
+ mapWire= (xkbIndicatorMapWireDesc *)atomWire;
+ if (changed&XkbXI_IndicatorMapsMask) {
+ mapc= sli->mapsPresent|ledWire->mapsPresent;
+ sli->mapsPresent= ledWire->mapsPresent;
+ bzero((char*)sli->maps,XkbNumIndicators*sizeof(XkbIndicatorMapRec));
+ }
+ if (ledWire->mapsPresent) {
+ for (n=0,bit=1;n<XkbNumIndicators;n++,bit<<=1) {
+ if (ledWire->mapsPresent&bit) {
+ sli->maps[n].flags= mapWire->flags;
+ sli->maps[n].which_groups= mapWire->whichGroups;
+ sli->maps[n].groups= mapWire->groups;
+ sli->maps[n].which_mods= mapWire->whichMods;
+ sli->maps[n].mods.mask= mapWire->mods;
+ sli->maps[n].mods.real_mods=mapWire->realMods;
+ sli->maps[n].mods.vmods= mapWire->virtualMods;
+ sli->maps[n].ctrls= mapWire->ctrls;
+ mapWire++;
+ }
+ }
+ }
+ if (changed&XkbXI_IndicatorStateMask) {
+ statec= sli->effectiveState^ledWire->state;
+ sli->explicitState&= ~statec;
+ sli->explicitState|= (ledWire->state&statec);
+ }
+ if (namec)
+ XkbApplyLedNameChanges(dev,sli,namec,&ed,&changes,&cause);
+ if (mapc)
+ XkbApplyLedMapChanges(dev,sli,mapc,&ed,&changes,&cause);
+ if (statec)
+ XkbApplyLedStateChanges(dev,sli,statec,&ed,&changes,&cause);
+
+ kbd= dev;
+ if ((sli->flags&XkbSLI_HasOwnState)==0)
+ kbd = inputInfo.keyboard;
+
+ XkbFlushLedEvents(dev,kbd,sli,&ed,&changes,&cause);
+ ledWire= (xkbDeviceLedsWireDesc *)mapWire;
+ }
+ return (char *)ledWire;
+}
+
+
+static int
+_XkbSetDeviceInfo(ClientPtr client, DeviceIntPtr dev,
+ xkbSetDeviceInfoReq *stuff)
+{
+ char *wire;
+
+ wire= (char *)&stuff[1];
+ if (stuff->change&XkbXI_ButtonActionsMask) {
+ if (!dev->button) {
+ client->errorValue = _XkbErrCode2(XkbErr_BadClass,ButtonClass);
+ return XkbKeyboardErrorCode;
+ }
+ if ((stuff->firstBtn+stuff->nBtns)>dev->button->numButtons) {
+ client->errorValue= _XkbErrCode4(0x02,stuff->firstBtn,stuff->nBtns,
+ dev->button->numButtons);
+ return BadMatch;
+ }
+ wire+= (stuff->nBtns*SIZEOF(xkbActionWireDesc));
+ }
+ if (stuff->change&XkbXI_IndicatorsMask) {
+ int status= Success;
+ wire= CheckSetDeviceIndicators(wire,dev,stuff->nDeviceLedFBs,
+ &status,client);
+ if (status!=Success)
+ return status;
+ }
+ if (((wire-((char *)stuff))/4)!=stuff->length)
+ return BadLength;
+
+ return Success;
+}
+
+static int
+_XkbSetDeviceInfoCheck(ClientPtr client, DeviceIntPtr dev,
+ xkbSetDeviceInfoReq *stuff)
+{
+ char *wire;
+ xkbExtensionDeviceNotify ed;
+
+ bzero((char *)&ed,SIZEOF(xkbExtensionDeviceNotify));
+ ed.deviceID= dev->id;
+ wire= (char *)&stuff[1];
+ if (stuff->change&XkbXI_ButtonActionsMask) {
+ int nBtns,sz,i;
+ XkbAction * acts;
+ DeviceIntPtr kbd;
+
+ nBtns= dev->button->numButtons;
+ acts= dev->button->xkb_acts;
+ if (acts==NULL) {
+ acts= xcalloc(nBtns, sizeof(XkbAction));
+ if (!acts)
+ return BadAlloc;
+ dev->button->xkb_acts= acts;
+ }
+ sz= stuff->nBtns*SIZEOF(xkbActionWireDesc);
+ memcpy((char *)&acts[stuff->firstBtn],(char *)wire,sz);
+ wire+= sz;
+ ed.reason|= XkbXI_ButtonActionsMask;
+ ed.firstBtn= stuff->firstBtn;
+ ed.nBtns= stuff->nBtns;
+
+ if (dev->key) kbd= dev;
+ else kbd= inputInfo.keyboard;
+ acts= &dev->button->xkb_acts[stuff->firstBtn];
+ for (i=0;i<stuff->nBtns;i++,acts++) {
+ if (acts->type!=XkbSA_NoAction)
+ XkbSetActionKeyMods(kbd->key->xkbInfo->desc,acts,0);
+ }
+ }
+ if (stuff->change&XkbXI_IndicatorsMask) {
+ int status= Success;
+ wire= SetDeviceIndicators(wire,dev,stuff->change,
+ stuff->nDeviceLedFBs, &status,client,&ed);
+ if (status!=Success)
+ return status;
+ }
+ if ((stuff->change)&&(ed.reason))
+ XkbSendExtensionDeviceNotify(dev,client,&ed);
+ return Success;
+}
+
+int
+ProcXkbSetDeviceInfo(ClientPtr client)
+{
+ DeviceIntPtr dev;
+ int rc;
+
+ REQUEST(xkbSetDeviceInfoReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetDeviceInfoReq);
+
+ if (!(client->xkbClientFlags&_XkbClientInitialized))
+ return BadAccess;
+
+ CHK_ANY_DEVICE(dev, stuff->deviceSpec, client, DixManageAccess);
+ CHK_MASK_LEGAL(0x01,stuff->change,XkbXI_AllFeaturesMask);
+
+ rc = _XkbSetDeviceInfoCheck(client, dev, stuff);
+
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if (((other != dev) && !IsMaster(other) && (other->u.master == dev)) &&
+ ((stuff->deviceSpec == XkbUseCoreKbd && other->key) ||
+ (stuff->deviceSpec == XkbUseCorePtr && other->button)))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ {
+ rc = _XkbSetDeviceInfoCheck(client, other, stuff);
+ if (rc != Success)
+ return rc;
+ }
+ }
+ }
+ }
+
+ /* checks done, apply */
+ rc = _XkbSetDeviceInfo(client, dev, stuff);
+ if (rc != Success)
+ return rc;
+
+ if (stuff->deviceSpec == XkbUseCoreKbd || stuff->deviceSpec == XkbUseCorePtr)
+ {
+ DeviceIntPtr other;
+ for (other = inputInfo.devices; other; other = other->next)
+ {
+ if (((other != dev) && !IsMaster(other) && (other->u.master == dev)) &&
+ ((stuff->deviceSpec == XkbUseCoreKbd && other->key) ||
+ (stuff->deviceSpec == XkbUseCorePtr && other->button)))
+ {
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, other, DixManageAccess);
+ if (rc == Success)
+ {
+ rc = _XkbSetDeviceInfo(client, other, stuff);
+ if (rc != Success)
+ return rc;
+ }
+ }
+ }
+ }
+
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+int
+ProcXkbSetDebuggingFlags(ClientPtr client)
+{
+CARD32 newFlags,newCtrls,extraLength;
+xkbSetDebuggingFlagsReply rep;
+int rc;
+
+ REQUEST(xkbSetDebuggingFlagsReq);
+ REQUEST_AT_LEAST_SIZE(xkbSetDebuggingFlagsReq);
+
+ rc = XaceHook(XACE_SERVER_ACCESS, client, DixDebugAccess);
+ if (rc != Success)
+ return rc;
+
+ newFlags= xkbDebugFlags&(~stuff->affectFlags);
+ newFlags|= (stuff->flags&stuff->affectFlags);
+ newCtrls= xkbDebugCtrls&(~stuff->affectCtrls);
+ newCtrls|= (stuff->ctrls&stuff->affectCtrls);
+ if (xkbDebugFlags || newFlags || stuff->msgLength) {
+ ErrorF("[xkb] XkbDebug: Setting debug flags to 0x%lx\n",(long)newFlags);
+ if (newCtrls!=xkbDebugCtrls)
+ ErrorF("[xkb] XkbDebug: Setting debug controls to 0x%lx\n",(long)newCtrls);
+ }
+ extraLength= (stuff->length<<2)-sz_xkbSetDebuggingFlagsReq;
+ if (stuff->msgLength>0) {
+ char *msg;
+ if (extraLength<XkbPaddedSize(stuff->msgLength)) {
+ ErrorF("[xkb] XkbDebug: msgLength= %d, length= %ld (should be %d)\n",
+ stuff->msgLength,(long)extraLength,
+ XkbPaddedSize(stuff->msgLength));
+ return BadLength;
+ }
+ msg= (char *)&stuff[1];
+ if (msg[stuff->msgLength-1]!='\0') {
+ ErrorF("[xkb] XkbDebug: message not null-terminated\n");
+ return BadValue;
+ }
+ ErrorF("[xkb] XkbDebug: %s\n",msg);
+ }
+ xkbDebugFlags = newFlags;
+ xkbDebugCtrls = newCtrls;
+
+ rep.type= X_Reply;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.currentFlags = newFlags;
+ rep.currentCtrls = newCtrls;
+ rep.supportedFlags = ~0;
+ rep.supportedCtrls = ~0;
+ if ( client->swapped ) {
+ register int n;
+ swaps(&rep.sequenceNumber, n);
+ swapl(&rep.currentFlags, n);
+ swapl(&rep.currentCtrls, n);
+ swapl(&rep.supportedFlags, n);
+ swapl(&rep.supportedCtrls, n);
+ }
+ WriteToClient(client,SIZEOF(xkbSetDebuggingFlagsReply), (char *)&rep);
+ return client->noClientException;
+}
+
+/***====================================================================***/
+
+static int
+ProcXkbDispatch (ClientPtr client)
+{
+ REQUEST(xReq);
+ switch (stuff->data)
+ {
+ case X_kbUseExtension:
+ return ProcXkbUseExtension(client);
+ case X_kbSelectEvents:
+ return ProcXkbSelectEvents(client);
+ case X_kbBell:
+ return ProcXkbBell(client);
+ case X_kbGetState:
+ return ProcXkbGetState(client);
+ case X_kbLatchLockState:
+ return ProcXkbLatchLockState(client);
+ case X_kbGetControls:
+ return ProcXkbGetControls(client);
+ case X_kbSetControls:
+ return ProcXkbSetControls(client);
+ case X_kbGetMap:
+ return ProcXkbGetMap(client);
+ case X_kbSetMap:
+ return ProcXkbSetMap(client);
+ case X_kbGetCompatMap:
+ return ProcXkbGetCompatMap(client);
+ case X_kbSetCompatMap:
+ return ProcXkbSetCompatMap(client);
+ case X_kbGetIndicatorState:
+ return ProcXkbGetIndicatorState(client);
+ case X_kbGetIndicatorMap:
+ return ProcXkbGetIndicatorMap(client);
+ case X_kbSetIndicatorMap:
+ return ProcXkbSetIndicatorMap(client);
+ case X_kbGetNamedIndicator:
+ return ProcXkbGetNamedIndicator(client);
+ case X_kbSetNamedIndicator:
+ return ProcXkbSetNamedIndicator(client);
+ case X_kbGetNames:
+ return ProcXkbGetNames(client);
+ case X_kbSetNames:
+ return ProcXkbSetNames(client);
+ case X_kbGetGeometry:
+ return ProcXkbGetGeometry(client);
+ case X_kbSetGeometry:
+ return ProcXkbSetGeometry(client);
+ case X_kbPerClientFlags:
+ return ProcXkbPerClientFlags(client);
+ case X_kbListComponents:
+ return ProcXkbListComponents(client);
+ case X_kbGetKbdByName:
+ return ProcXkbGetKbdByName(client);
+ case X_kbGetDeviceInfo:
+ return ProcXkbGetDeviceInfo(client);
+ case X_kbSetDeviceInfo:
+ return ProcXkbSetDeviceInfo(client);
+ case X_kbSetDebuggingFlags:
+ return ProcXkbSetDebuggingFlags(client);
+ default:
+ return BadRequest;
+ }
+}
+
+static int
+XkbClientGone(pointer data,XID id)
+{
+ DevicePtr pXDev = (DevicePtr)data;
+
+ if (!XkbRemoveResourceClient(pXDev,id)) {
+ ErrorF("[xkb] Internal Error! bad RemoveResourceClient in XkbClientGone\n");
+ }
+ return 1;
+}
+
+void
+XkbExtensionInit(void)
+{
+ ExtensionEntry *extEntry;
+
+ RT_XKBCLIENT = CreateNewResourceType(XkbClientGone, "XkbClient");
+ if (!RT_XKBCLIENT)
+ return;
+
+ if ((extEntry = AddExtension(XkbName, XkbNumberEvents, XkbNumberErrors,
+ ProcXkbDispatch, SProcXkbDispatch,
+ NULL, StandardMinorOpcode))) {
+ XkbReqCode = (unsigned char)extEntry->base;
+ XkbEventBase = (unsigned char)extEntry->eventBase;
+ XkbErrorBase = (unsigned char)extEntry->errorBase;
+ XkbKeyboardErrorCode = XkbErrorBase+XkbKeyboard;
+ }
+ return;
+}
+
+
diff --git a/xorg-server/xkb/xkbActions.c b/xorg-server/xkb/xkbActions.c index 2cdb6fcea..ec3d909e7 100644 --- a/xorg-server/xkb/xkbActions.c +++ b/xorg-server/xkb/xkbActions.c @@ -1,1318 +1,1318 @@ -/************************************************************ -Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc. - -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 Silicon Graphics not be -used in advertising or publicity pertaining to distribution -of the software without specific prior written permission. -Silicon Graphics makes no representation about the suitability -of this software for any purpose. It is provided "as is" -without any express or implied warranty. - -SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS -SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY -AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON -GRAPHICS 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 <dix-config.h> -#endif - -#include <stdio.h> -#include <math.h> -#include <X11/X.h> -#include <X11/Xproto.h> -#include <X11/keysym.h> -#include "misc.h" -#include "inputstr.h" -#include "exevents.h" -#include "eventstr.h" -#include <xkbsrv.h> -#include "xkb.h" -#include <ctype.h> -#define EXTENSION_EVENT_BASE 64 - -static int xkbDevicePrivateKeyIndex; -DevPrivateKey xkbDevicePrivateKey = &xkbDevicePrivateKeyIndex; - -void -xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc, - pointer data) -{ - xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device); - ProcessInputProc backupproc; - if(xkbPrivPtr->unwrapProc) - xkbPrivPtr->unwrapProc = NULL; - - UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc); - proc(device,data); - COND_WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, - backupproc,xkbUnwrapProc); -} - - -void -XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc) -{ - xkbDeviceInfoPtr xkbPrivPtr; - - xkbPrivPtr = (xkbDeviceInfoPtr) xcalloc(1, sizeof(xkbDeviceInfoRec)); - if (!xkbPrivPtr) - return; - xkbPrivPtr->unwrapProc = NULL; - - dixSetPrivate(&device->devPrivates, xkbDevicePrivateKey, xkbPrivPtr); - WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc); -} - -/***====================================================================***/ - -static XkbAction -_FixUpAction(XkbDescPtr xkb,XkbAction *act) -{ -static XkbAction fake; - - if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) { - fake.type = XkbSA_NoAction; - return fake; - } - if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) { - if (act->any.type==XkbSA_SetMods) { - fake.mods.type = XkbSA_LatchMods; - fake.mods.mask = act->mods.mask; - if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask)) - fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock; - else fake.mods.flags= XkbSA_ClearLocks; - return fake; - } - if (act->any.type==XkbSA_SetGroup) { - fake.group.type = XkbSA_LatchGroup; - if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask)) - fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock; - else fake.group.flags= XkbSA_ClearLocks; - XkbSASetGroup(&fake.group,XkbSAGroup(&act->group)); - return fake; - } - } - return *act; -} - -static XkbAction -XkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key) -{ -int effectiveGroup; -int col; -XkbDescPtr xkb; -XkbKeyTypePtr type; -XkbAction * pActs; -static XkbAction fake; - - xkb= xkbi->desc; - if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) { - fake.type = XkbSA_NoAction; - return fake; - } - pActs= XkbKeyActionsPtr(xkb,key); - col= 0; - - effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key); - if (effectiveGroup != XkbGroup1Index) - col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key)); - - type= XkbKeyKeyType(xkb,key,effectiveGroup); - if (type->map!=NULL) { - register unsigned i,mods; - register XkbKTMapEntryPtr entry; - mods= xkbState->mods&type->mods.mask; - for (entry= type->map,i=0;i<type->map_count;i++,entry++) { - if ((entry->active)&&(entry->mods.mask==mods)) { - col+= entry->level; - break; - } - } - } - if (pActs[col].any.type==XkbSA_NoAction) - return pActs[col]; - fake= _FixUpAction(xkb,&pActs[col]); - return fake; -} - -static XkbAction -XkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button) -{ -XkbAction fake; - if ((dev->button)&&(dev->button->xkb_acts)) { - if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) { - fake= _FixUpAction(kbd->key->xkbInfo->desc, - &dev->button->xkb_acts[button-1]); - return fake; - } - } - fake.any.type= XkbSA_NoAction; - return fake; -} - -/***====================================================================***/ - -#define SYNTHETIC_KEYCODE 1 -#define BTN_ACT_FLAG 0x100 - -static int -_XkbFilterSetState( XkbSrvInfoPtr xkbi, - XkbFilterPtr filter, - unsigned keycode, - XkbAction *pAction) -{ - if (filter->keycode==0) { /* initial press */ - filter->keycode = keycode; - filter->active = 1; - filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0); - filter->priv = 0; - filter->filter = _XkbFilterSetState; - if (pAction->type==XkbSA_SetMods) { - filter->upAction = *pAction; - xkbi->setMods= pAction->mods.mask; - } - else { - xkbi->groupChange = XkbSAGroup(&pAction->group); - if (pAction->group.flags&XkbSA_GroupAbsolute) - xkbi->groupChange-= xkbi->state.base_group; - filter->upAction= *pAction; - XkbSASetGroup(&filter->upAction.group,xkbi->groupChange); - } - } - else if (filter->keycode==keycode) { - if (filter->upAction.type==XkbSA_SetMods) { - xkbi->clearMods = filter->upAction.mods.mask; - if (filter->upAction.mods.flags&XkbSA_ClearLocks) { - xkbi->state.locked_mods&= ~filter->upAction.mods.mask; - } - } - else { - if (filter->upAction.group.flags&XkbSA_ClearLocks) { - xkbi->state.locked_group = 0; - } - xkbi->groupChange = -XkbSAGroup(&filter->upAction.group); - } - filter->active = 0; - } - else { - filter->upAction.mods.flags&= ~XkbSA_ClearLocks; - filter->filterOthers = 0; - } - return 1; -} - -#define LATCH_KEY_DOWN 1 -#define LATCH_PENDING 2 -#define NO_LATCH 3 - -static int -_XkbFilterLatchState( XkbSrvInfoPtr xkbi, - XkbFilterPtr filter, - unsigned keycode, - XkbAction * pAction) -{ - - if (filter->keycode==0) { /* initial press */ - filter->keycode = keycode; - filter->active = 1; - filter->filterOthers = 1; - filter->priv = LATCH_KEY_DOWN; - filter->filter = _XkbFilterLatchState; - if (pAction->type==XkbSA_LatchMods) { - filter->upAction = *pAction; - xkbi->setMods = pAction->mods.mask; - } - else { - xkbi->groupChange = XkbSAGroup(&pAction->group); - if (pAction->group.flags&XkbSA_GroupAbsolute) - xkbi->groupChange-= xkbi->state.base_group; - filter->upAction= *pAction; - XkbSASetGroup(&filter->upAction.group,xkbi->groupChange); - } - } - else if ( pAction && (filter->priv==LATCH_PENDING) ) { - if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) { - filter->active = 0; - if (filter->upAction.type==XkbSA_LatchMods) - xkbi->state.latched_mods&= ~filter->upAction.mods.mask; - else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group); - } - else if ((pAction->type==filter->upAction.type)&& - (pAction->mods.flags==filter->upAction.mods.flags)&& - (pAction->mods.mask==filter->upAction.mods.mask)) { - if (filter->upAction.mods.flags&XkbSA_LatchToLock) { - XkbControlsPtr ctrls= xkbi->desc->ctrls; - if (filter->upAction.type==XkbSA_LatchMods) - pAction->mods.type= XkbSA_LockMods; - else pAction->group.type= XkbSA_LockGroup; - if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&& - (ctrls->enabled_ctrls&XkbStickyKeysMask)) { - XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK, - XkbStickyKeysMask); - } - } - else { - if (filter->upAction.type==XkbSA_LatchMods) - pAction->mods.type= XkbSA_SetMods; - else pAction->group.type= XkbSA_SetGroup; - } - if (filter->upAction.type==XkbSA_LatchMods) - xkbi->state.latched_mods&= ~filter->upAction.mods.mask; - else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group); - filter->active = 0; - } - } - else if (filter->keycode==keycode) { /* release */ - XkbControlsPtr ctrls= xkbi->desc->ctrls; - int needBeep; - int beepType= _BEEP_NONE; - - needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&& - XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)); - if (filter->upAction.type==XkbSA_LatchMods) { - xkbi->clearMods = filter->upAction.mods.mask; - if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&& - (xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) { - xkbi->state.locked_mods&= ~xkbi->clearMods; - filter->priv= NO_LATCH; - beepType= _BEEP_STICKY_UNLOCK; - } - } - else { - xkbi->groupChange = -XkbSAGroup(&filter->upAction.group); - if ((filter->upAction.group.flags&XkbSA_ClearLocks)&& - (xkbi->state.locked_group)) { - xkbi->state.locked_group = 0; - filter->priv = NO_LATCH; - beepType= _BEEP_STICKY_UNLOCK; - } - } - if (filter->priv==NO_LATCH) { - filter->active= 0; - } - else { - filter->priv= LATCH_PENDING; - if (filter->upAction.type==XkbSA_LatchMods) { - xkbi->state.latched_mods |= filter->upAction.mods.mask; - needBeep = xkbi->state.latched_mods ? needBeep : 0; - xkbi->state.latched_mods |= filter->upAction.mods.mask; - } - else { - xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group); - } - if (needBeep && (beepType==_BEEP_NONE)) - beepType= _BEEP_STICKY_LATCH; - } - if (needBeep && (beepType!=_BEEP_NONE)) - XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask); - } - else if (filter->priv==LATCH_KEY_DOWN) { - filter->priv= NO_LATCH; - filter->filterOthers = 0; - } - return 1; -} - -static int -_XkbFilterLockState( XkbSrvInfoPtr xkbi, - XkbFilterPtr filter, - unsigned keycode, - XkbAction * pAction) -{ - if (pAction&&(pAction->type==XkbSA_LockGroup)) { - if (pAction->group.flags&XkbSA_GroupAbsolute) - xkbi->state.locked_group= XkbSAGroup(&pAction->group); - else xkbi->state.locked_group+= XkbSAGroup(&pAction->group); - return 1; - } - if (filter->keycode==0) { /* initial press */ - filter->keycode = keycode; - filter->active = 1; - filter->filterOthers = 0; - filter->priv = 0; - filter->filter = _XkbFilterLockState; - filter->upAction = *pAction; - xkbi->state.locked_mods^= pAction->mods.mask; - xkbi->setMods = pAction->mods.mask; - } - else if (filter->keycode==keycode) { - filter->active = 0; - xkbi->clearMods = filter->upAction.mods.mask; - } - return 1; -} - -#define ISO_KEY_DOWN 0 -#define NO_ISO_LOCK 1 - -static int -_XkbFilterISOLock( XkbSrvInfoPtr xkbi, - XkbFilterPtr filter, - unsigned keycode, - XkbAction * pAction) -{ - - if (filter->keycode==0) { /* initial press */ - CARD8 flags= pAction->iso.flags; - - filter->keycode = keycode; - filter->active = 1; - filter->filterOthers = 1; - filter->priv = ISO_KEY_DOWN; - filter->upAction = *pAction; - filter->filter = _XkbFilterISOLock; - if (flags&XkbSA_ISODfltIsGroup) { - xkbi->groupChange = XkbSAGroup(&pAction->iso); - xkbi->setMods = 0; - } - else { - xkbi->setMods = pAction->iso.mask; - xkbi->groupChange = 0; - } - if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) { - filter->priv= NO_ISO_LOCK; - xkbi->state.locked_mods^= xkbi->state.base_mods; - } - if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) { -/* 6/22/93 (ef) -- lock groups if group key is down first */ - } - if (!(flags&XkbSA_ISONoAffectPtr)) { -/* 6/22/93 (ef) -- lock mouse buttons if they're down */ - } - } - else if (filter->keycode==keycode) { - CARD8 flags= filter->upAction.iso.flags; - - if (flags&XkbSA_ISODfltIsGroup) { - xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso); - xkbi->clearMods = 0; - if (filter->priv==ISO_KEY_DOWN) - xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso); - } - else { - xkbi->clearMods= filter->upAction.iso.mask; - xkbi->groupChange= 0; - if (filter->priv==ISO_KEY_DOWN) - xkbi->state.locked_mods^= filter->upAction.iso.mask; - } - filter->active = 0; - } - else if (pAction) { - CARD8 flags= filter->upAction.iso.flags; - - switch (pAction->type) { - case XkbSA_SetMods: case XkbSA_LatchMods: - if (!(flags&XkbSA_ISONoAffectMods)) { - pAction->type= XkbSA_LockMods; - filter->priv= NO_ISO_LOCK; - } - break; - case XkbSA_SetGroup: case XkbSA_LatchGroup: - if (!(flags&XkbSA_ISONoAffectGroup)) { - pAction->type= XkbSA_LockGroup; - filter->priv= NO_ISO_LOCK; - } - break; - case XkbSA_PtrBtn: - if (!(flags&XkbSA_ISONoAffectPtr)) { - pAction->type= XkbSA_LockPtrBtn; - filter->priv= NO_ISO_LOCK; - } - break; - case XkbSA_SetControls: - if (!(flags&XkbSA_ISONoAffectCtrls)) { - pAction->type= XkbSA_LockControls; - filter->priv= NO_ISO_LOCK; - } - break; - } - } - return 1; -} - - -static CARD32 -_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg) -{ -XkbSrvInfoPtr xkbi= (XkbSrvInfoPtr)arg; -XkbControlsPtr ctrls= xkbi->desc->ctrls; -int dx,dy; - - if (xkbi->mouseKey==0) - return 0; - - if (xkbi->mouseKeysAccel) { - if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) { - double step; - xkbi->mouseKeysCounter++; - step= xkbi->mouseKeysCurveFactor* - pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve); - if (xkbi->mouseKeysDX<0) - dx= floor( ((double)xkbi->mouseKeysDX)*step ); - else dx= ceil( ((double)xkbi->mouseKeysDX)*step ); - if (xkbi->mouseKeysDY<0) - dy= floor( ((double)xkbi->mouseKeysDY)*step ); - else dy= ceil( ((double)xkbi->mouseKeysDY)*step ); - } - else { - dx= xkbi->mouseKeysDX*ctrls->mk_max_speed; - dy= xkbi->mouseKeysDY*ctrls->mk_max_speed; - } - if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX) - dx= xkbi->mouseKeysDX; - if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY) - dy= xkbi->mouseKeysDY; - } - else { - dx= xkbi->mouseKeysDX; - dy= xkbi->mouseKeysDY; - } - XkbDDXFakePointerMotion(xkbi->mouseKeysFlags,dx,dy); - return xkbi->desc->ctrls->mk_interval; -} - -static int -_XkbFilterPointerMove( XkbSrvInfoPtr xkbi, - XkbFilterPtr filter, - unsigned keycode, - XkbAction * pAction) -{ -int x,y; -Bool accel; - - if (xkbi->device == inputInfo.keyboard) - return 0; - - if (filter->keycode==0) { /* initial press */ - filter->keycode = keycode; - filter->active = 1; - filter->filterOthers = 0; - filter->priv=0; - filter->filter = _XkbFilterPointerMove; - filter->upAction= *pAction; - xkbi->mouseKeysCounter= 0; - xkbi->mouseKey= keycode; - accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0); - x= XkbPtrActionX(&pAction->ptr); - y= XkbPtrActionY(&pAction->ptr); - XkbDDXFakePointerMotion(pAction->ptr.flags,x,y); - AccessXCancelRepeatKey(xkbi,keycode); - xkbi->mouseKeysAccel= accel&& - (xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask); - xkbi->mouseKeysFlags= pAction->ptr.flags; - xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr); - xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr); - xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, - xkbi->desc->ctrls->mk_delay, - _XkbPtrAccelExpire,(pointer)xkbi); - } - else if (filter->keycode==keycode) { - filter->active = 0; - if (xkbi->mouseKey==keycode) { - xkbi->mouseKey= 0; - xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0, - NULL, NULL); - } - } - return 0; -} - -static int -_XkbFilterPointerBtn( XkbSrvInfoPtr xkbi, - XkbFilterPtr filter, - unsigned keycode, - XkbAction * pAction) -{ - if (filter->keycode==0) { /* initial press */ - int button= pAction->btn.button; - - if (button==XkbSA_UseDfltButton) - button = xkbi->desc->ctrls->mk_dflt_btn; - - filter->keycode = keycode; - filter->active = 1; - filter->filterOthers = 0; - filter->priv=0; - filter->filter = _XkbFilterPointerBtn; - filter->upAction= *pAction; - filter->upAction.btn.button= button; - switch (pAction->type) { - case XkbSA_LockPtrBtn: - if (((xkbi->lockedPtrButtons&(1<<button))==0)&& - ((pAction->btn.flags&XkbSA_LockNoLock)==0)) { - xkbi->lockedPtrButtons|= (1<<button); - AccessXCancelRepeatKey(xkbi,keycode); - XkbDDXFakeDeviceButton(xkbi->device, 1, button); - filter->upAction.type= XkbSA_NoAction; - } - break; - case XkbSA_PtrBtn: - { - register int i,nClicks; - AccessXCancelRepeatKey(xkbi,keycode); - if (pAction->btn.count>0) { - nClicks= pAction->btn.count; - for (i=0;i<nClicks;i++) { - XkbDDXFakeDeviceButton(xkbi->device, 1, button); - XkbDDXFakeDeviceButton(xkbi->device, 0, button); - } - filter->upAction.type= XkbSA_NoAction; - } - else XkbDDXFakeDeviceButton(xkbi->device, 1, button); - } - break; - case XkbSA_SetPtrDflt: - { - XkbControlsPtr ctrls= xkbi->desc->ctrls; - XkbControlsRec old; - xkbControlsNotify cn; - - old= *ctrls; - AccessXCancelRepeatKey(xkbi,keycode); - switch (pAction->dflt.affect) { - case XkbSA_AffectDfltBtn: - if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute) - ctrls->mk_dflt_btn= - XkbSAPtrDfltValue(&pAction->dflt); - else { - ctrls->mk_dflt_btn+= - XkbSAPtrDfltValue(&pAction->dflt); - if (ctrls->mk_dflt_btn>5) - ctrls->mk_dflt_btn= 5; - else if (ctrls->mk_dflt_btn<1) - ctrls->mk_dflt_btn= 1; - } - break; - default: - ErrorF( - "Attempt to change unknown pointer default (%d) ignored\n", - pAction->dflt.affect); - break; - } - if (XkbComputeControlsNotify(xkbi->device, - &old,xkbi->desc->ctrls, - &cn,FALSE)) { - cn.keycode = keycode; - /* XXX: what about DeviceKeyPress? */ - cn.eventType = KeyPress; - cn.requestMajor = 0; - cn.requestMinor = 0; - XkbSendControlsNotify(xkbi->device,&cn); - } - } - break; - } - } - else if (filter->keycode==keycode) { - int button= filter->upAction.btn.button; - - switch (filter->upAction.type) { - case XkbSA_LockPtrBtn: - if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)|| - ((xkbi->lockedPtrButtons&(1<<button))==0)) { - break; - } - xkbi->lockedPtrButtons&= ~(1<<button); - case XkbSA_PtrBtn: - XkbDDXFakeDeviceButton(xkbi->device, 0, button); - break; - } - filter->active = 0; - } - return 0; -} - -static int -_XkbFilterControls( XkbSrvInfoPtr xkbi, - XkbFilterPtr filter, - unsigned keycode, - XkbAction * pAction) -{ -XkbControlsRec old; -XkbControlsPtr ctrls; -DeviceIntPtr kbd; -unsigned int change; -XkbEventCauseRec cause; - - kbd= xkbi->device; - ctrls= xkbi->desc->ctrls; - old= *ctrls; - if (filter->keycode==0) { /* initial press */ - filter->keycode = keycode; - filter->active = 1; - filter->filterOthers = 0; - change= XkbActionCtrls(&pAction->ctrls); - filter->priv = change; - filter->filter = _XkbFilterControls; - filter->upAction = *pAction; - - if (pAction->type==XkbSA_LockControls) { - filter->priv= (ctrls->enabled_ctrls&change); - change&= ~ctrls->enabled_ctrls; - } - - if (change) { - xkbControlsNotify cn; - XkbSrvLedInfoPtr sli; - - ctrls->enabled_ctrls|= change; - if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) { - cn.keycode = keycode; - /* XXX: what about DeviceKeyPress? */ - cn.eventType = KeyPress; - cn.requestMajor = 0; - cn.requestMinor = 0; - XkbSendControlsNotify(kbd,&cn); - } - - XkbSetCauseKey(&cause,keycode,KeyPress); - - /* If sticky keys were disabled, clear all locks and latches */ - if ((old.enabled_ctrls&XkbStickyKeysMask)&& - (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) { - XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause); - } - sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); - XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause); - if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) - XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change); - } - } - else if (filter->keycode==keycode) { - change= filter->priv; - if (change) { - xkbControlsNotify cn; - XkbSrvLedInfoPtr sli; - - ctrls->enabled_ctrls&= ~change; - if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) { - cn.keycode = keycode; - cn.eventType = KeyRelease; - cn.requestMajor = 0; - cn.requestMinor = 0; - XkbSendControlsNotify(kbd,&cn); - } - - XkbSetCauseKey(&cause,keycode,KeyRelease); - /* If sticky keys were disabled, clear all locks and latches */ - if ((old.enabled_ctrls&XkbStickyKeysMask)&& - (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) { - XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause); - } - sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0); - XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause); - if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask)) - XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change); - } - filter->keycode= 0; - filter->active= 0; - } - return 1; -} - -static int -_XkbFilterActionMessage(XkbSrvInfoPtr xkbi, - XkbFilterPtr filter, - unsigned keycode, - XkbAction * pAction) -{ -XkbMessageAction * pMsg; -DeviceIntPtr kbd; - - kbd= xkbi->device; - if (filter->keycode==0) { /* initial press */ - pMsg= &pAction->msg; - if ((pMsg->flags&XkbSA_MessageOnRelease)|| - ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) { - filter->keycode = keycode; - filter->active = 1; - filter->filterOthers = 0; - filter->priv = 0; - filter->filter = _XkbFilterActionMessage; - filter->upAction = *pAction; - } - if (pMsg->flags&XkbSA_MessageOnPress) { - xkbActionMessage msg; - - msg.keycode= keycode; - msg.press= 1; - msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); - memcpy((char *)msg.message, - (char *)pMsg->message,XkbActionMessageLength); - XkbSendActionMessage(kbd,&msg); - } - return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0); - } - else if (filter->keycode==keycode) { - pMsg= &filter->upAction.msg; - if (pMsg->flags&XkbSA_MessageOnRelease) { - xkbActionMessage msg; - - msg.keycode= keycode; - msg.press= 0; - msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); - memcpy((char *)msg.message,(char *)pMsg->message, - XkbActionMessageLength); - XkbSendActionMessage(kbd,&msg); - } - filter->keycode= 0; - filter->active= 0; - return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0); - } - return 0; -} - -static int -_XkbFilterRedirectKey( XkbSrvInfoPtr xkbi, - XkbFilterPtr filter, - unsigned keycode, - XkbAction * pAction) -{ -DeviceEvent ev; -int x,y; -XkbStateRec old; -unsigned mods,mask; -xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device); -ProcessInputProc backupproc; - - /* never actually used uninitialised, but gcc isn't smart enough - * to work that out. */ - memset(&old, 0, sizeof(old)); - - if ((filter->keycode!=0)&&(filter->keycode!=keycode)) - return 1; - - GetSpritePosition(xkbi->device, &x,&y); - ev.header = ET_Internal; - ev.length = sizeof(DeviceEvent); - ev.time = GetTimeInMillis(); - ev.root_x = x; - ev.root_y = y; - - if (filter->keycode==0) { /* initial press */ - if ((pAction->redirect.new_key<xkbi->desc->min_key_code)|| - (pAction->redirect.new_key>xkbi->desc->max_key_code)) { - return 1; - } - filter->keycode = keycode; - filter->active = 1; - filter->filterOthers = 0; - filter->priv = 0; - filter->filter = _XkbFilterRedirectKey; - filter->upAction = *pAction; - - ev.type = ET_KeyPress; - ev.detail.key = pAction->redirect.new_key; - - mask= XkbSARedirectVModsMask(&pAction->redirect); - mods= XkbSARedirectVMods(&pAction->redirect); - if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask); - if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods); - mask|= pAction->redirect.mods_mask; - mods|= pAction->redirect.mods; - - if ( mask || mods ) { - old= xkbi->state; - xkbi->state.base_mods&= ~mask; - xkbi->state.base_mods|= (mods&mask); - xkbi->state.latched_mods&= ~mask; - xkbi->state.latched_mods|= (mods&mask); - xkbi->state.locked_mods&= ~mask; - xkbi->state.locked_mods|= (mods&mask); - XkbComputeDerivedState(xkbi); - } - - UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc); - xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device); - COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, - backupproc,xkbUnwrapProc); - - if ( mask || mods ) - xkbi->state= old; - } - else if (filter->keycode==keycode) { - - ev.type = ET_KeyRelease; - ev.detail.key = filter->upAction.redirect.new_key; - - mask= XkbSARedirectVModsMask(&filter->upAction.redirect); - mods= XkbSARedirectVMods(&filter->upAction.redirect); - if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask); - if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods); - mask|= filter->upAction.redirect.mods_mask; - mods|= filter->upAction.redirect.mods; - - if ( mask || mods ) { - old= xkbi->state; - xkbi->state.base_mods&= ~mask; - xkbi->state.base_mods|= (mods&mask); - xkbi->state.latched_mods&= ~mask; - xkbi->state.latched_mods|= (mods&mask); - xkbi->state.locked_mods&= ~mask; - xkbi->state.locked_mods|= (mods&mask); - XkbComputeDerivedState(xkbi); - } - - UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc); - xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device); - COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr, - backupproc,xkbUnwrapProc); - - if ( mask || mods ) - xkbi->state= old; - - filter->keycode= 0; - filter->active= 0; - } - return 0; -} - -static int -_XkbFilterSwitchScreen( XkbSrvInfoPtr xkbi, - XkbFilterPtr filter, - unsigned keycode, - XkbAction * pAction) -{ - DeviceIntPtr dev = xkbi->device; - if (dev == inputInfo.keyboard) - return 0; - - if (filter->keycode==0) { /* initial press */ - filter->keycode = keycode; - filter->active = 1; - filter->filterOthers = 0; - filter->filter = _XkbFilterSwitchScreen; - AccessXCancelRepeatKey(xkbi, keycode); - XkbDDXSwitchScreen(dev,keycode,pAction); - return 0; - } - else if (filter->keycode==keycode) { - filter->active= 0; - return 0; - } - return 1; -} - -static int -_XkbFilterXF86Private( XkbSrvInfoPtr xkbi, - XkbFilterPtr filter, - unsigned keycode, - XkbAction * pAction) -{ - DeviceIntPtr dev = xkbi->device; - if (dev == inputInfo.keyboard) - return 0; - - if (filter->keycode==0) { /* initial press */ - filter->keycode = keycode; - filter->active = 1; - filter->filterOthers = 0; - filter->filter = _XkbFilterXF86Private; - XkbDDXPrivate(dev,keycode,pAction); - return 0; - } - else if (filter->keycode==keycode) { - filter->active= 0; - return 0; - } - return 1; -} - - -static int -_XkbFilterDeviceBtn( XkbSrvInfoPtr xkbi, - XkbFilterPtr filter, - unsigned keycode, - XkbAction * pAction) -{ -DeviceIntPtr dev; -int button; - - if (xkbi->device == inputInfo.keyboard) - return 0; - - if (filter->keycode==0) { /* initial press */ - _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient, - DixUnknownAccess, &button); - if (!dev || !dev->public.on) - return 1; - - button= pAction->devbtn.button; - if ((button<1)||(button>dev->button->numButtons)) - return 1; - - filter->keycode = keycode; - filter->active = 1; - filter->filterOthers = 0; - filter->priv=0; - filter->filter = _XkbFilterDeviceBtn; - filter->upAction= *pAction; - switch (pAction->type) { - case XkbSA_LockDeviceBtn: - if ((pAction->devbtn.flags&XkbSA_LockNoLock)|| - BitIsOn(dev->button->down, button)) - return 0; - XkbDDXFakeDeviceButton(dev,TRUE,button); - filter->upAction.type= XkbSA_NoAction; - break; - case XkbSA_DeviceBtn: - if (pAction->devbtn.count>0) { - int nClicks,i; - nClicks= pAction->btn.count; - for (i=0;i<nClicks;i++) { - XkbDDXFakeDeviceButton(dev,TRUE,button); - XkbDDXFakeDeviceButton(dev,FALSE,button); - } - filter->upAction.type= XkbSA_NoAction; - } - else XkbDDXFakeDeviceButton(dev,TRUE,button); - break; - } - } - else if (filter->keycode==keycode) { - int button; - - filter->active= 0; - _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device, - serverClient, DixUnknownAccess, &button); - if (!dev || !dev->public.on) - return 1; - - button= filter->upAction.btn.button; - switch (filter->upAction.type) { - case XkbSA_LockDeviceBtn: - if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)|| - !BitIsOn(dev->button->down, button)) - return 0; - XkbDDXFakeDeviceButton(dev,FALSE,button); - break; - case XkbSA_DeviceBtn: - XkbDDXFakeDeviceButton(dev,FALSE,button); - break; - } - filter->active = 0; - } - return 0; -} - -static XkbFilterPtr -_XkbNextFreeFilter( - XkbSrvInfoPtr xkbi -) -{ -register int i; - - if (xkbi->szFilters==0) { - xkbi->szFilters = 4; - xkbi->filters = xcalloc(xkbi->szFilters, sizeof(XkbFilterRec)); - /* 6/21/93 (ef) -- XXX! deal with allocation failure */ - } - for (i=0;i<xkbi->szFilters;i++) { - if (!xkbi->filters[i].active) { - xkbi->filters[i].keycode = 0; - return &xkbi->filters[i]; - } - } - xkbi->szFilters*=2; - xkbi->filters= xrealloc(xkbi->filters, - xkbi->szFilters * sizeof(XkbFilterRec)); - /* 6/21/93 (ef) -- XXX! deal with allocation failure */ - bzero(&xkbi->filters[xkbi->szFilters/2], - (xkbi->szFilters/2)*sizeof(XkbFilterRec)); - return &xkbi->filters[xkbi->szFilters/2]; -} - -static int -_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction) -{ -register int i,send; - - send= 1; - for (i=0;i<xkbi->szFilters;i++) { - if ((xkbi->filters[i].active)&&(xkbi->filters[i].filter)) - send= ((*xkbi->filters[i].filter)(xkbi,&xkbi->filters[i],kc,pAction) - && send); - } - return send; -} - -void -XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent* event) -{ -int key,bit,i; -XkbSrvInfoPtr xkbi; -KeyClassPtr keyc; -int changed,sendEvent; -Bool genStateNotify; -XkbAction act; -XkbFilterPtr filter; -Bool keyEvent; -Bool pressEvent; -ProcessInputProc backupproc; - -xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev); - - keyc= kbd->key; - xkbi= keyc->xkbInfo; - key= event->detail.key; - /* The state may change, so if we're not in the middle of sending a state - * notify, prepare for it */ - if ((xkbi->flags&_XkbStateNotifyInProgress)==0) { - xkbi->prev_state = xkbi->state; - xkbi->flags|= _XkbStateNotifyInProgress; - genStateNotify= TRUE; - } - else genStateNotify= FALSE; - - xkbi->clearMods = xkbi->setMods = 0; - xkbi->groupChange = 0; - - sendEvent = 1; - keyEvent= ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease)); - pressEvent= ((event->type == ET_KeyPress)|| (event->type == ET_ButtonPress)); - - if (pressEvent) { - if (keyEvent) - act = XkbGetKeyAction(xkbi,&xkbi->state,key); - else { - act = XkbGetButtonAction(kbd,dev,key); - key|= BTN_ACT_FLAG; - } - sendEvent = _XkbApplyFilters(xkbi,key,&act); - if (sendEvent) { - switch (act.type) { - case XkbSA_SetMods: - case XkbSA_SetGroup: - filter = _XkbNextFreeFilter(xkbi); - sendEvent = _XkbFilterSetState(xkbi,filter,key,&act); - break; - case XkbSA_LatchMods: - case XkbSA_LatchGroup: - filter = _XkbNextFreeFilter(xkbi); - sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act); - break; - case XkbSA_LockMods: - case XkbSA_LockGroup: - filter = _XkbNextFreeFilter(xkbi); - sendEvent=_XkbFilterLockState(xkbi,filter,key,&act); - break; - case XkbSA_ISOLock: - filter = _XkbNextFreeFilter(xkbi); - sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act); - break; - case XkbSA_MovePtr: - filter = _XkbNextFreeFilter(xkbi); - sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act); - break; - case XkbSA_PtrBtn: - case XkbSA_LockPtrBtn: - case XkbSA_SetPtrDflt: - filter = _XkbNextFreeFilter(xkbi); - sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act); - break; - case XkbSA_Terminate: - sendEvent= XkbDDXTerminateServer(dev,key,&act); - break; - case XkbSA_SwitchScreen: - filter = _XkbNextFreeFilter(xkbi); - sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act); - break; - case XkbSA_SetControls: - case XkbSA_LockControls: - filter = _XkbNextFreeFilter(xkbi); - sendEvent=_XkbFilterControls(xkbi,filter,key,&act); - break; - case XkbSA_ActionMessage: - filter = _XkbNextFreeFilter(xkbi); - sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act); - break; - case XkbSA_RedirectKey: - filter = _XkbNextFreeFilter(xkbi); - sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act); - break; - case XkbSA_DeviceBtn: - case XkbSA_LockDeviceBtn: - filter = _XkbNextFreeFilter(xkbi); - sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act); - break; - case XkbSA_XFree86Private: - filter = _XkbNextFreeFilter(xkbi); - sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act); - break; - } - } - } - else { - if (!keyEvent) - key|= BTN_ACT_FLAG; - sendEvent = _XkbApplyFilters(xkbi,key,NULL); - } - - if (xkbi->groupChange!=0) - xkbi->state.base_group+= xkbi->groupChange; - if (xkbi->setMods) { - for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) { - if (xkbi->setMods&bit) { - keyc->modifierKeyCount[i]++; - xkbi->state.base_mods|= bit; - xkbi->setMods&= ~bit; - } - } - } - if (xkbi->clearMods) { - for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) { - if (xkbi->clearMods&bit) { - keyc->modifierKeyCount[i]--; - if (keyc->modifierKeyCount[i]<=0) { - xkbi->state.base_mods&= ~bit; - keyc->modifierKeyCount[i] = 0; - } - xkbi->clearMods&= ~bit; - } - } - } - - if (sendEvent) { - DeviceIntPtr tmpdev; - if (keyEvent) - tmpdev = dev; - else - tmpdev = GetPairedDevice(dev); - - UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc); - dev->public.processInputProc((InternalEvent*)event, tmpdev); - COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr, - backupproc,xkbUnwrapProc); - } - else if (keyEvent) { - FixKeyState(event, dev); - } - - XkbComputeDerivedState(xkbi); - changed = XkbStateChangedFlags(&xkbi->prev_state,&xkbi->state); - if (genStateNotify) { - if (changed) { - xkbStateNotify sn; - sn.keycode= key; - sn.eventType= event->type; - sn.requestMajor = sn.requestMinor = 0; - sn.changed= changed; - XkbSendStateNotify(dev,&sn); - } - xkbi->flags&= ~_XkbStateNotifyInProgress; - } - changed= XkbIndicatorsToUpdate(dev,changed,FALSE); - if (changed) { - XkbEventCauseRec cause; - XkbSetCauseKey(&cause, key, event->type); - XkbUpdateIndicators(dev,changed,FALSE,NULL,&cause); - } - return; -} - -int -XkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches) -{ -XkbSrvInfoPtr xkbi; -XkbFilterPtr filter; -XkbAction act; -unsigned clear; - - if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) { - xkbi = pXDev->key->xkbInfo; - clear= (mask&(~latches)); - xkbi->state.latched_mods&= ~clear; - /* Clear any pending latch to locks. - */ - act.type = XkbSA_NoAction; - _XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act); - act.type = XkbSA_LatchMods; - act.mods.flags = 0; - act.mods.mask = mask&latches; - filter = _XkbNextFreeFilter(xkbi); - _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act); - _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL); - return Success; - } - return BadValue; -} - -int -XkbLatchGroup(DeviceIntPtr pXDev,int group) -{ -XkbSrvInfoPtr xkbi; -XkbFilterPtr filter; -XkbAction act; - - if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) { - xkbi = pXDev->key->xkbInfo; - act.type = XkbSA_LatchGroup; - act.group.flags = 0; - XkbSASetGroup(&act.group,group); - filter = _XkbNextFreeFilter(xkbi); - _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act); - _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL); - return Success; - } - return BadValue; -} - -/***====================================================================***/ - -void -XkbClearAllLatchesAndLocks( DeviceIntPtr dev, - XkbSrvInfoPtr xkbi, - Bool genEv, - XkbEventCausePtr cause) -{ -XkbStateRec os; -xkbStateNotify sn; - - sn.changed= 0; - os= xkbi->state; - if (os.latched_mods) { /* clear all latches */ - XkbLatchModifiers(dev,~0,0); - sn.changed|= XkbModifierLatchMask; - } - if (os.latched_group) { - XkbLatchGroup(dev,0); - sn.changed|= XkbGroupLatchMask; - } - if (os.locked_mods) { - xkbi->state.locked_mods= 0; - sn.changed|= XkbModifierLockMask; - } - if (os.locked_group) { - xkbi->state.locked_group= 0; - sn.changed|= XkbGroupLockMask; - } - if ( genEv && sn.changed) { - CARD32 changed; - - XkbComputeDerivedState(xkbi); - sn.keycode= cause->kc; - sn.eventType= cause->event; - sn.requestMajor= cause->mjr; - sn.requestMinor= cause->mnr; - sn.changed= XkbStateChangedFlags(&os,&xkbi->state); - XkbSendStateNotify(dev,&sn); - changed= XkbIndicatorsToUpdate(dev,sn.changed,FALSE); - if (changed) { - XkbUpdateIndicators(dev,changed,TRUE,NULL,cause); - } - } - return; -} - +/************************************************************
+Copyright (c) 1993 by Silicon Graphics Computer Systems, Inc.
+
+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 Silicon Graphics not be
+used in advertising or publicity pertaining to distribution
+of the software without specific prior written permission.
+Silicon Graphics makes no representation about the suitability
+of this software for any purpose. It is provided "as is"
+without any express or implied warranty.
+
+SILICON GRAPHICS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
+SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
+AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON
+GRAPHICS 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 <dix-config.h>
+#endif
+
+#include <stdio.h>
+#include <math.h>
+#include <X11/X.h>
+#include <X11/Xproto.h>
+#include <X11/keysym.h>
+#include "misc.h"
+#include "inputstr.h"
+#include "exevents.h"
+#include "eventstr.h"
+#include <xkbsrv.h>
+#include "xkb.h"
+#include <ctype.h>
+#define EXTENSION_EVENT_BASE 64
+
+static int xkbDevicePrivateKeyIndex;
+DevPrivateKey xkbDevicePrivateKey = &xkbDevicePrivateKeyIndex;
+
+void
+xkbUnwrapProc(DeviceIntPtr device, DeviceHandleProc proc,
+ pointer data)
+{
+ xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(device);
+ ProcessInputProc backupproc;
+ if(xkbPrivPtr->unwrapProc)
+ xkbPrivPtr->unwrapProc = NULL;
+
+ UNWRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr, backupproc);
+ proc(device,data);
+ COND_WRAP_PROCESS_INPUT_PROC(device,xkbPrivPtr,
+ backupproc,xkbUnwrapProc);
+}
+
+
+void
+XkbSetExtension(DeviceIntPtr device, ProcessInputProc proc)
+{
+ xkbDeviceInfoPtr xkbPrivPtr;
+
+ xkbPrivPtr = (xkbDeviceInfoPtr) xcalloc(1, sizeof(xkbDeviceInfoRec));
+ if (!xkbPrivPtr)
+ return;
+ xkbPrivPtr->unwrapProc = NULL;
+
+ dixSetPrivate(&device->devPrivates, xkbDevicePrivateKey, xkbPrivPtr);
+ WRAP_PROCESS_INPUT_PROC(device, xkbPrivPtr, proc, xkbUnwrapProc);
+}
+
+/***====================================================================***/
+
+static XkbAction
+_FixUpAction(XkbDescPtr xkb,XkbAction *act)
+{
+static XkbAction fake;
+
+ if (XkbIsPtrAction(act)&&(!(xkb->ctrls->enabled_ctrls&XkbMouseKeysMask))) {
+ fake.type = XkbSA_NoAction;
+ return fake;
+ }
+ if (xkb->ctrls->enabled_ctrls&XkbStickyKeysMask) {
+ if (act->any.type==XkbSA_SetMods) {
+ fake.mods.type = XkbSA_LatchMods;
+ fake.mods.mask = act->mods.mask;
+ if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
+ fake.mods.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
+ else fake.mods.flags= XkbSA_ClearLocks;
+ return fake;
+ }
+ if (act->any.type==XkbSA_SetGroup) {
+ fake.group.type = XkbSA_LatchGroup;
+ if (XkbAX_NeedOption(xkb->ctrls,XkbAX_LatchToLockMask))
+ fake.group.flags= XkbSA_ClearLocks|XkbSA_LatchToLock;
+ else fake.group.flags= XkbSA_ClearLocks;
+ XkbSASetGroup(&fake.group,XkbSAGroup(&act->group));
+ return fake;
+ }
+ }
+ return *act;
+}
+
+static XkbAction
+XkbGetKeyAction(XkbSrvInfoPtr xkbi,XkbStatePtr xkbState,CARD8 key)
+{
+int effectiveGroup;
+int col;
+XkbDescPtr xkb;
+XkbKeyTypePtr type;
+XkbAction * pActs;
+static XkbAction fake;
+
+ xkb= xkbi->desc;
+ if (!XkbKeyHasActions(xkb,key) || !XkbKeycodeInRange(xkb,key)) {
+ fake.type = XkbSA_NoAction;
+ return fake;
+ }
+ pActs= XkbKeyActionsPtr(xkb,key);
+ col= 0;
+
+ effectiveGroup = XkbGetEffectiveGroup(xkbi, xkbState, key);
+ if (effectiveGroup != XkbGroup1Index)
+ col += (effectiveGroup * XkbKeyGroupsWidth(xkb, key));
+
+ type= XkbKeyKeyType(xkb,key,effectiveGroup);
+ if (type->map!=NULL) {
+ register unsigned i,mods;
+ register XkbKTMapEntryPtr entry;
+ mods= xkbState->mods&type->mods.mask;
+ for (entry= type->map,i=0;i<type->map_count;i++,entry++) {
+ if ((entry->active)&&(entry->mods.mask==mods)) {
+ col+= entry->level;
+ break;
+ }
+ }
+ }
+ if (pActs[col].any.type==XkbSA_NoAction)
+ return pActs[col];
+ fake= _FixUpAction(xkb,&pActs[col]);
+ return fake;
+}
+
+static XkbAction
+XkbGetButtonAction(DeviceIntPtr kbd,DeviceIntPtr dev,int button)
+{
+XkbAction fake;
+ if ((dev->button)&&(dev->button->xkb_acts)) {
+ if (dev->button->xkb_acts[button-1].any.type!=XkbSA_NoAction) {
+ fake= _FixUpAction(kbd->key->xkbInfo->desc,
+ &dev->button->xkb_acts[button-1]);
+ return fake;
+ }
+ }
+ fake.any.type= XkbSA_NoAction;
+ return fake;
+}
+
+/***====================================================================***/
+
+#define SYNTHETIC_KEYCODE 1
+#define BTN_ACT_FLAG 0x100
+
+static int
+_XkbFilterSetState( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction *pAction)
+{
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = ((pAction->mods.mask&XkbSA_ClearLocks)!=0);
+ filter->priv = 0;
+ filter->filter = _XkbFilterSetState;
+ if (pAction->type==XkbSA_SetMods) {
+ filter->upAction = *pAction;
+ xkbi->setMods= pAction->mods.mask;
+ }
+ else {
+ xkbi->groupChange = XkbSAGroup(&pAction->group);
+ if (pAction->group.flags&XkbSA_GroupAbsolute)
+ xkbi->groupChange-= xkbi->state.base_group;
+ filter->upAction= *pAction;
+ XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
+ }
+ }
+ else if (filter->keycode==keycode) {
+ if (filter->upAction.type==XkbSA_SetMods) {
+ xkbi->clearMods = filter->upAction.mods.mask;
+ if (filter->upAction.mods.flags&XkbSA_ClearLocks) {
+ xkbi->state.locked_mods&= ~filter->upAction.mods.mask;
+ }
+ }
+ else {
+ if (filter->upAction.group.flags&XkbSA_ClearLocks) {
+ xkbi->state.locked_group = 0;
+ }
+ xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
+ }
+ filter->active = 0;
+ }
+ else {
+ filter->upAction.mods.flags&= ~XkbSA_ClearLocks;
+ filter->filterOthers = 0;
+ }
+ return 1;
+}
+
+#define LATCH_KEY_DOWN 1
+#define LATCH_PENDING 2
+#define NO_LATCH 3
+
+static int
+_XkbFilterLatchState( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 1;
+ filter->priv = LATCH_KEY_DOWN;
+ filter->filter = _XkbFilterLatchState;
+ if (pAction->type==XkbSA_LatchMods) {
+ filter->upAction = *pAction;
+ xkbi->setMods = pAction->mods.mask;
+ }
+ else {
+ xkbi->groupChange = XkbSAGroup(&pAction->group);
+ if (pAction->group.flags&XkbSA_GroupAbsolute)
+ xkbi->groupChange-= xkbi->state.base_group;
+ filter->upAction= *pAction;
+ XkbSASetGroup(&filter->upAction.group,xkbi->groupChange);
+ }
+ }
+ else if ( pAction && (filter->priv==LATCH_PENDING) ) {
+ if (((1<<pAction->type)&XkbSA_BreakLatch)!=0) {
+ filter->active = 0;
+ if (filter->upAction.type==XkbSA_LatchMods)
+ xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
+ else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
+ }
+ else if ((pAction->type==filter->upAction.type)&&
+ (pAction->mods.flags==filter->upAction.mods.flags)&&
+ (pAction->mods.mask==filter->upAction.mods.mask)) {
+ if (filter->upAction.mods.flags&XkbSA_LatchToLock) {
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ if (filter->upAction.type==XkbSA_LatchMods)
+ pAction->mods.type= XkbSA_LockMods;
+ else pAction->group.type= XkbSA_LockGroup;
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask)&&
+ (ctrls->enabled_ctrls&XkbStickyKeysMask)) {
+ XkbDDXAccessXBeep(xkbi->device,_BEEP_STICKY_LOCK,
+ XkbStickyKeysMask);
+ }
+ }
+ else {
+ if (filter->upAction.type==XkbSA_LatchMods)
+ pAction->mods.type= XkbSA_SetMods;
+ else pAction->group.type= XkbSA_SetGroup;
+ }
+ if (filter->upAction.type==XkbSA_LatchMods)
+ xkbi->state.latched_mods&= ~filter->upAction.mods.mask;
+ else xkbi->state.latched_group-=XkbSAGroup(&filter->upAction.group);
+ filter->active = 0;
+ }
+ }
+ else if (filter->keycode==keycode) { /* release */
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ int needBeep;
+ int beepType= _BEEP_NONE;
+
+ needBeep= ((ctrls->enabled_ctrls&XkbStickyKeysMask)&&
+ XkbAX_NeedFeedback(ctrls,XkbAX_StickyKeysFBMask));
+ if (filter->upAction.type==XkbSA_LatchMods) {
+ xkbi->clearMods = filter->upAction.mods.mask;
+ if ((filter->upAction.mods.flags&XkbSA_ClearLocks)&&
+ (xkbi->clearMods&xkbi->state.locked_mods)==xkbi->clearMods) {
+ xkbi->state.locked_mods&= ~xkbi->clearMods;
+ filter->priv= NO_LATCH;
+ beepType= _BEEP_STICKY_UNLOCK;
+ }
+ }
+ else {
+ xkbi->groupChange = -XkbSAGroup(&filter->upAction.group);
+ if ((filter->upAction.group.flags&XkbSA_ClearLocks)&&
+ (xkbi->state.locked_group)) {
+ xkbi->state.locked_group = 0;
+ filter->priv = NO_LATCH;
+ beepType= _BEEP_STICKY_UNLOCK;
+ }
+ }
+ if (filter->priv==NO_LATCH) {
+ filter->active= 0;
+ }
+ else {
+ filter->priv= LATCH_PENDING;
+ if (filter->upAction.type==XkbSA_LatchMods) {
+ xkbi->state.latched_mods |= filter->upAction.mods.mask;
+ needBeep = xkbi->state.latched_mods ? needBeep : 0;
+ xkbi->state.latched_mods |= filter->upAction.mods.mask;
+ }
+ else {
+ xkbi->state.latched_group+= XkbSAGroup(&filter->upAction.group);
+ }
+ if (needBeep && (beepType==_BEEP_NONE))
+ beepType= _BEEP_STICKY_LATCH;
+ }
+ if (needBeep && (beepType!=_BEEP_NONE))
+ XkbDDXAccessXBeep(xkbi->device,beepType,XkbStickyKeysMask);
+ }
+ else if (filter->priv==LATCH_KEY_DOWN) {
+ filter->priv= NO_LATCH;
+ filter->filterOthers = 0;
+ }
+ return 1;
+}
+
+static int
+_XkbFilterLockState( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+ if (pAction&&(pAction->type==XkbSA_LockGroup)) {
+ if (pAction->group.flags&XkbSA_GroupAbsolute)
+ xkbi->state.locked_group= XkbSAGroup(&pAction->group);
+ else xkbi->state.locked_group+= XkbSAGroup(&pAction->group);
+ return 1;
+ }
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv = 0;
+ filter->filter = _XkbFilterLockState;
+ filter->upAction = *pAction;
+ xkbi->state.locked_mods^= pAction->mods.mask;
+ xkbi->setMods = pAction->mods.mask;
+ }
+ else if (filter->keycode==keycode) {
+ filter->active = 0;
+ xkbi->clearMods = filter->upAction.mods.mask;
+ }
+ return 1;
+}
+
+#define ISO_KEY_DOWN 0
+#define NO_ISO_LOCK 1
+
+static int
+_XkbFilterISOLock( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+
+ if (filter->keycode==0) { /* initial press */
+ CARD8 flags= pAction->iso.flags;
+
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 1;
+ filter->priv = ISO_KEY_DOWN;
+ filter->upAction = *pAction;
+ filter->filter = _XkbFilterISOLock;
+ if (flags&XkbSA_ISODfltIsGroup) {
+ xkbi->groupChange = XkbSAGroup(&pAction->iso);
+ xkbi->setMods = 0;
+ }
+ else {
+ xkbi->setMods = pAction->iso.mask;
+ xkbi->groupChange = 0;
+ }
+ if ((!(flags&XkbSA_ISONoAffectMods))&&(xkbi->state.base_mods)) {
+ filter->priv= NO_ISO_LOCK;
+ xkbi->state.locked_mods^= xkbi->state.base_mods;
+ }
+ if ((!(flags&XkbSA_ISONoAffectGroup))&&(xkbi->state.base_group)) {
+/* 6/22/93 (ef) -- lock groups if group key is down first */
+ }
+ if (!(flags&XkbSA_ISONoAffectPtr)) {
+/* 6/22/93 (ef) -- lock mouse buttons if they're down */
+ }
+ }
+ else if (filter->keycode==keycode) {
+ CARD8 flags= filter->upAction.iso.flags;
+
+ if (flags&XkbSA_ISODfltIsGroup) {
+ xkbi->groupChange = -XkbSAGroup(&filter->upAction.iso);
+ xkbi->clearMods = 0;
+ if (filter->priv==ISO_KEY_DOWN)
+ xkbi->state.locked_group+= XkbSAGroup(&filter->upAction.iso);
+ }
+ else {
+ xkbi->clearMods= filter->upAction.iso.mask;
+ xkbi->groupChange= 0;
+ if (filter->priv==ISO_KEY_DOWN)
+ xkbi->state.locked_mods^= filter->upAction.iso.mask;
+ }
+ filter->active = 0;
+ }
+ else if (pAction) {
+ CARD8 flags= filter->upAction.iso.flags;
+
+ switch (pAction->type) {
+ case XkbSA_SetMods: case XkbSA_LatchMods:
+ if (!(flags&XkbSA_ISONoAffectMods)) {
+ pAction->type= XkbSA_LockMods;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ case XkbSA_SetGroup: case XkbSA_LatchGroup:
+ if (!(flags&XkbSA_ISONoAffectGroup)) {
+ pAction->type= XkbSA_LockGroup;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ case XkbSA_PtrBtn:
+ if (!(flags&XkbSA_ISONoAffectPtr)) {
+ pAction->type= XkbSA_LockPtrBtn;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ case XkbSA_SetControls:
+ if (!(flags&XkbSA_ISONoAffectCtrls)) {
+ pAction->type= XkbSA_LockControls;
+ filter->priv= NO_ISO_LOCK;
+ }
+ break;
+ }
+ }
+ return 1;
+}
+
+
+static CARD32
+_XkbPtrAccelExpire(OsTimerPtr timer,CARD32 now,pointer arg)
+{
+XkbSrvInfoPtr xkbi= (XkbSrvInfoPtr)arg;
+XkbControlsPtr ctrls= xkbi->desc->ctrls;
+int dx,dy;
+
+ if (xkbi->mouseKey==0)
+ return 0;
+
+ if (xkbi->mouseKeysAccel) {
+ if ((xkbi->mouseKeysCounter)<ctrls->mk_time_to_max) {
+ double step;
+ xkbi->mouseKeysCounter++;
+ step= xkbi->mouseKeysCurveFactor*
+ pow((double)xkbi->mouseKeysCounter,xkbi->mouseKeysCurve);
+ if (xkbi->mouseKeysDX<0)
+ dx= floor( ((double)xkbi->mouseKeysDX)*step );
+ else dx= ceil( ((double)xkbi->mouseKeysDX)*step );
+ if (xkbi->mouseKeysDY<0)
+ dy= floor( ((double)xkbi->mouseKeysDY)*step );
+ else dy= ceil( ((double)xkbi->mouseKeysDY)*step );
+ }
+ else {
+ dx= xkbi->mouseKeysDX*ctrls->mk_max_speed;
+ dy= xkbi->mouseKeysDY*ctrls->mk_max_speed;
+ }
+ if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteX)
+ dx= xkbi->mouseKeysDX;
+ if (xkbi->mouseKeysFlags&XkbSA_MoveAbsoluteY)
+ dy= xkbi->mouseKeysDY;
+ }
+ else {
+ dx= xkbi->mouseKeysDX;
+ dy= xkbi->mouseKeysDY;
+ }
+ XkbDDXFakePointerMotion(xkbi->mouseKeysFlags,dx,dy);
+ return xkbi->desc->ctrls->mk_interval;
+}
+
+static int
+_XkbFilterPointerMove( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+int x,y;
+Bool accel;
+
+ if (xkbi->device == inputInfo.keyboard)
+ return 0;
+
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv=0;
+ filter->filter = _XkbFilterPointerMove;
+ filter->upAction= *pAction;
+ xkbi->mouseKeysCounter= 0;
+ xkbi->mouseKey= keycode;
+ accel= ((pAction->ptr.flags&XkbSA_NoAcceleration)==0);
+ x= XkbPtrActionX(&pAction->ptr);
+ y= XkbPtrActionY(&pAction->ptr);
+ XkbDDXFakePointerMotion(pAction->ptr.flags,x,y);
+ AccessXCancelRepeatKey(xkbi,keycode);
+ xkbi->mouseKeysAccel= accel&&
+ (xkbi->desc->ctrls->enabled_ctrls&XkbMouseKeysAccelMask);
+ xkbi->mouseKeysFlags= pAction->ptr.flags;
+ xkbi->mouseKeysDX= XkbPtrActionX(&pAction->ptr);
+ xkbi->mouseKeysDY= XkbPtrActionY(&pAction->ptr);
+ xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0,
+ xkbi->desc->ctrls->mk_delay,
+ _XkbPtrAccelExpire,(pointer)xkbi);
+ }
+ else if (filter->keycode==keycode) {
+ filter->active = 0;
+ if (xkbi->mouseKey==keycode) {
+ xkbi->mouseKey= 0;
+ xkbi->mouseKeyTimer= TimerSet(xkbi->mouseKeyTimer, 0, 0,
+ NULL, NULL);
+ }
+ }
+ return 0;
+}
+
+static int
+_XkbFilterPointerBtn( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+ if (filter->keycode==0) { /* initial press */
+ int button= pAction->btn.button;
+
+ if (button==XkbSA_UseDfltButton)
+ button = xkbi->desc->ctrls->mk_dflt_btn;
+
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv=0;
+ filter->filter = _XkbFilterPointerBtn;
+ filter->upAction= *pAction;
+ filter->upAction.btn.button= button;
+ switch (pAction->type) {
+ case XkbSA_LockPtrBtn:
+ if (((xkbi->lockedPtrButtons&(1<<button))==0)&&
+ ((pAction->btn.flags&XkbSA_LockNoLock)==0)) {
+ xkbi->lockedPtrButtons|= (1<<button);
+ AccessXCancelRepeatKey(xkbi,keycode);
+ XkbDDXFakeDeviceButton(xkbi->device, 1, button);
+ filter->upAction.type= XkbSA_NoAction;
+ }
+ break;
+ case XkbSA_PtrBtn:
+ {
+ register int i,nClicks;
+ AccessXCancelRepeatKey(xkbi,keycode);
+ if (pAction->btn.count>0) {
+ nClicks= pAction->btn.count;
+ for (i=0;i<nClicks;i++) {
+ XkbDDXFakeDeviceButton(xkbi->device, 1, button);
+ XkbDDXFakeDeviceButton(xkbi->device, 0, button);
+ }
+ filter->upAction.type= XkbSA_NoAction;
+ }
+ else XkbDDXFakeDeviceButton(xkbi->device, 1, button);
+ }
+ break;
+ case XkbSA_SetPtrDflt:
+ {
+ XkbControlsPtr ctrls= xkbi->desc->ctrls;
+ XkbControlsRec old;
+ xkbControlsNotify cn;
+
+ old= *ctrls;
+ AccessXCancelRepeatKey(xkbi,keycode);
+ switch (pAction->dflt.affect) {
+ case XkbSA_AffectDfltBtn:
+ if (pAction->dflt.flags&XkbSA_DfltBtnAbsolute)
+ ctrls->mk_dflt_btn=
+ XkbSAPtrDfltValue(&pAction->dflt);
+ else {
+ ctrls->mk_dflt_btn+=
+ XkbSAPtrDfltValue(&pAction->dflt);
+ if (ctrls->mk_dflt_btn>5)
+ ctrls->mk_dflt_btn= 5;
+ else if (ctrls->mk_dflt_btn<1)
+ ctrls->mk_dflt_btn= 1;
+ }
+ break;
+ default:
+ ErrorF(
+ "Attempt to change unknown pointer default (%d) ignored\n",
+ pAction->dflt.affect);
+ break;
+ }
+ if (XkbComputeControlsNotify(xkbi->device,
+ &old,xkbi->desc->ctrls,
+ &cn,FALSE)) {
+ cn.keycode = keycode;
+ /* XXX: what about DeviceKeyPress? */
+ cn.eventType = KeyPress;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ XkbSendControlsNotify(xkbi->device,&cn);
+ }
+ }
+ break;
+ }
+ }
+ else if (filter->keycode==keycode) {
+ int button= filter->upAction.btn.button;
+
+ switch (filter->upAction.type) {
+ case XkbSA_LockPtrBtn:
+ if (((filter->upAction.btn.flags&XkbSA_LockNoUnlock)!=0)||
+ ((xkbi->lockedPtrButtons&(1<<button))==0)) {
+ break;
+ }
+ xkbi->lockedPtrButtons&= ~(1<<button);
+ case XkbSA_PtrBtn:
+ XkbDDXFakeDeviceButton(xkbi->device, 0, button);
+ break;
+ }
+ filter->active = 0;
+ }
+ return 0;
+}
+
+static int
+_XkbFilterControls( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+XkbControlsRec old;
+XkbControlsPtr ctrls;
+DeviceIntPtr kbd;
+unsigned int change;
+XkbEventCauseRec cause;
+
+ kbd= xkbi->device;
+ ctrls= xkbi->desc->ctrls;
+ old= *ctrls;
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ change= XkbActionCtrls(&pAction->ctrls);
+ filter->priv = change;
+ filter->filter = _XkbFilterControls;
+ filter->upAction = *pAction;
+
+ if (pAction->type==XkbSA_LockControls) {
+ filter->priv= (ctrls->enabled_ctrls&change);
+ change&= ~ctrls->enabled_ctrls;
+ }
+
+ if (change) {
+ xkbControlsNotify cn;
+ XkbSrvLedInfoPtr sli;
+
+ ctrls->enabled_ctrls|= change;
+ if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) {
+ cn.keycode = keycode;
+ /* XXX: what about DeviceKeyPress? */
+ cn.eventType = KeyPress;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ XkbSendControlsNotify(kbd,&cn);
+ }
+
+ XkbSetCauseKey(&cause,keycode,KeyPress);
+
+ /* If sticky keys were disabled, clear all locks and latches */
+ if ((old.enabled_ctrls&XkbStickyKeysMask)&&
+ (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
+ XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause);
+ }
+ sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
+ XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_ON,change);
+ }
+ }
+ else if (filter->keycode==keycode) {
+ change= filter->priv;
+ if (change) {
+ xkbControlsNotify cn;
+ XkbSrvLedInfoPtr sli;
+
+ ctrls->enabled_ctrls&= ~change;
+ if (XkbComputeControlsNotify(kbd,&old,ctrls,&cn,FALSE)) {
+ cn.keycode = keycode;
+ cn.eventType = KeyRelease;
+ cn.requestMajor = 0;
+ cn.requestMinor = 0;
+ XkbSendControlsNotify(kbd,&cn);
+ }
+
+ XkbSetCauseKey(&cause,keycode,KeyRelease);
+ /* If sticky keys were disabled, clear all locks and latches */
+ if ((old.enabled_ctrls&XkbStickyKeysMask)&&
+ (!(ctrls->enabled_ctrls&XkbStickyKeysMask))) {
+ XkbClearAllLatchesAndLocks(kbd,xkbi,FALSE,&cause);
+ }
+ sli= XkbFindSrvLedInfo(kbd,XkbDfltXIClass,XkbDfltXIId,0);
+ XkbUpdateIndicators(kbd,sli->usesControls,TRUE,NULL,&cause);
+ if (XkbAX_NeedFeedback(ctrls,XkbAX_FeatureFBMask))
+ XkbDDXAccessXBeep(kbd,_BEEP_FEATURE_OFF,change);
+ }
+ filter->keycode= 0;
+ filter->active= 0;
+ }
+ return 1;
+}
+
+static int
+_XkbFilterActionMessage(XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+XkbMessageAction * pMsg;
+DeviceIntPtr kbd;
+
+ kbd= xkbi->device;
+ if (filter->keycode==0) { /* initial press */
+ pMsg= &pAction->msg;
+ if ((pMsg->flags&XkbSA_MessageOnRelease)||
+ ((pMsg->flags&XkbSA_MessageGenKeyEvent)==0)) {
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv = 0;
+ filter->filter = _XkbFilterActionMessage;
+ filter->upAction = *pAction;
+ }
+ if (pMsg->flags&XkbSA_MessageOnPress) {
+ xkbActionMessage msg;
+
+ msg.keycode= keycode;
+ msg.press= 1;
+ msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
+ memcpy((char *)msg.message,
+ (char *)pMsg->message,XkbActionMessageLength);
+ XkbSendActionMessage(kbd,&msg);
+ }
+ return ((pAction->msg.flags&XkbSA_MessageGenKeyEvent)!=0);
+ }
+ else if (filter->keycode==keycode) {
+ pMsg= &filter->upAction.msg;
+ if (pMsg->flags&XkbSA_MessageOnRelease) {
+ xkbActionMessage msg;
+
+ msg.keycode= keycode;
+ msg.press= 0;
+ msg.keyEventFollows=((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
+ memcpy((char *)msg.message,(char *)pMsg->message,
+ XkbActionMessageLength);
+ XkbSendActionMessage(kbd,&msg);
+ }
+ filter->keycode= 0;
+ filter->active= 0;
+ return ((pMsg->flags&XkbSA_MessageGenKeyEvent)!=0);
+ }
+ return 0;
+}
+
+static int
+_XkbFilterRedirectKey( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+DeviceEvent ev;
+int x,y;
+XkbStateRec old;
+unsigned mods,mask;
+xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(xkbi->device);
+ProcessInputProc backupproc;
+
+ /* never actually used uninitialised, but gcc isn't smart enough
+ * to work that out. */
+ memset(&old, 0, sizeof(old));
+
+ if ((filter->keycode!=0)&&(filter->keycode!=keycode))
+ return 1;
+
+ GetSpritePosition(xkbi->device, &x,&y);
+ ev.header = ET_Internal;
+ ev.length = sizeof(DeviceEvent);
+ ev.time = GetTimeInMillis();
+ ev.root_x = x;
+ ev.root_y = y;
+
+ if (filter->keycode==0) { /* initial press */
+ if ((pAction->redirect.new_key<xkbi->desc->min_key_code)||
+ (pAction->redirect.new_key>xkbi->desc->max_key_code)) {
+ return 1;
+ }
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv = 0;
+ filter->filter = _XkbFilterRedirectKey;
+ filter->upAction = *pAction;
+
+ ev.type = ET_KeyPress;
+ ev.detail.key = pAction->redirect.new_key;
+
+ mask= XkbSARedirectVModsMask(&pAction->redirect);
+ mods= XkbSARedirectVMods(&pAction->redirect);
+ if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
+ if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
+ mask|= pAction->redirect.mods_mask;
+ mods|= pAction->redirect.mods;
+
+ if ( mask || mods ) {
+ old= xkbi->state;
+ xkbi->state.base_mods&= ~mask;
+ xkbi->state.base_mods|= (mods&mask);
+ xkbi->state.latched_mods&= ~mask;
+ xkbi->state.latched_mods|= (mods&mask);
+ xkbi->state.locked_mods&= ~mask;
+ xkbi->state.locked_mods|= (mods&mask);
+ XkbComputeDerivedState(xkbi);
+ }
+
+ UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
+ xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device);
+ COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
+ backupproc,xkbUnwrapProc);
+
+ if ( mask || mods )
+ xkbi->state= old;
+ }
+ else if (filter->keycode==keycode) {
+
+ ev.type = ET_KeyRelease;
+ ev.detail.key = filter->upAction.redirect.new_key;
+
+ mask= XkbSARedirectVModsMask(&filter->upAction.redirect);
+ mods= XkbSARedirectVMods(&filter->upAction.redirect);
+ if (mask) XkbVirtualModsToReal(xkbi->desc,mask,&mask);
+ if (mods) XkbVirtualModsToReal(xkbi->desc,mods,&mods);
+ mask|= filter->upAction.redirect.mods_mask;
+ mods|= filter->upAction.redirect.mods;
+
+ if ( mask || mods ) {
+ old= xkbi->state;
+ xkbi->state.base_mods&= ~mask;
+ xkbi->state.base_mods|= (mods&mask);
+ xkbi->state.latched_mods&= ~mask;
+ xkbi->state.latched_mods|= (mods&mask);
+ xkbi->state.locked_mods&= ~mask;
+ xkbi->state.locked_mods|= (mods&mask);
+ XkbComputeDerivedState(xkbi);
+ }
+
+ UNWRAP_PROCESS_INPUT_PROC(xkbi->device,xkbPrivPtr, backupproc);
+ xkbi->device->public.processInputProc((InternalEvent*)&ev, xkbi->device);
+ COND_WRAP_PROCESS_INPUT_PROC(xkbi->device, xkbPrivPtr,
+ backupproc,xkbUnwrapProc);
+
+ if ( mask || mods )
+ xkbi->state= old;
+
+ filter->keycode= 0;
+ filter->active= 0;
+ }
+ return 0;
+}
+
+static int
+_XkbFilterSwitchScreen( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+ DeviceIntPtr dev = xkbi->device;
+ if (dev == inputInfo.keyboard)
+ return 0;
+
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->filter = _XkbFilterSwitchScreen;
+ AccessXCancelRepeatKey(xkbi, keycode);
+ XkbDDXSwitchScreen(dev,keycode,pAction);
+ return 0;
+ }
+ else if (filter->keycode==keycode) {
+ filter->active= 0;
+ return 0;
+ }
+ return 1;
+}
+
+static int
+_XkbFilterXF86Private( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+ DeviceIntPtr dev = xkbi->device;
+ if (dev == inputInfo.keyboard)
+ return 0;
+
+ if (filter->keycode==0) { /* initial press */
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->filter = _XkbFilterXF86Private;
+ XkbDDXPrivate(dev,keycode,pAction);
+ return 0;
+ }
+ else if (filter->keycode==keycode) {
+ filter->active= 0;
+ return 0;
+ }
+ return 1;
+}
+
+
+static int
+_XkbFilterDeviceBtn( XkbSrvInfoPtr xkbi,
+ XkbFilterPtr filter,
+ unsigned keycode,
+ XkbAction * pAction)
+{
+DeviceIntPtr dev;
+int button;
+
+ if (filter->keycode==0) { /* initial press */
+ _XkbLookupButtonDevice(&dev, pAction->devbtn.device, serverClient,
+ DixUnknownAccess, &button);
+ if (!dev || !dev->public.on)
+ return 1;
+
+ if (xkbi->device == inputInfo.keyboard)
+ return 0;
+
+ button= pAction->devbtn.button;
+ if ((button<1)||(button>dev->button->numButtons))
+ return 1;
+
+ filter->keycode = keycode;
+ filter->active = 1;
+ filter->filterOthers = 0;
+ filter->priv=0;
+ filter->filter = _XkbFilterDeviceBtn;
+ filter->upAction= *pAction;
+ switch (pAction->type) {
+ case XkbSA_LockDeviceBtn:
+ if ((pAction->devbtn.flags&XkbSA_LockNoLock)||
+ BitIsOn(dev->button->down, button))
+ return 0;
+ XkbDDXFakeDeviceButton(dev,TRUE,button);
+ filter->upAction.type= XkbSA_NoAction;
+ break;
+ case XkbSA_DeviceBtn:
+ if (pAction->devbtn.count>0) {
+ int nClicks,i;
+ nClicks= pAction->btn.count;
+ for (i=0;i<nClicks;i++) {
+ XkbDDXFakeDeviceButton(dev,TRUE,button);
+ XkbDDXFakeDeviceButton(dev,FALSE,button);
+ }
+ filter->upAction.type= XkbSA_NoAction;
+ }
+ else XkbDDXFakeDeviceButton(dev,TRUE,button);
+ break;
+ }
+ }
+ else if (filter->keycode==keycode) {
+ int button;
+
+ filter->active= 0;
+ _XkbLookupButtonDevice(&dev, filter->upAction.devbtn.device,
+ serverClient, DixUnknownAccess, &button);
+ if (!dev || !dev->public.on)
+ return 1;
+
+ button= filter->upAction.btn.button;
+ switch (filter->upAction.type) {
+ case XkbSA_LockDeviceBtn:
+ if ((filter->upAction.devbtn.flags&XkbSA_LockNoUnlock)||
+ !BitIsOn(dev->button->down, button))
+ return 0;
+ XkbDDXFakeDeviceButton(dev,FALSE,button);
+ break;
+ case XkbSA_DeviceBtn:
+ XkbDDXFakeDeviceButton(dev,FALSE,button);
+ break;
+ }
+ filter->active = 0;
+ }
+ return 0;
+}
+
+static XkbFilterPtr
+_XkbNextFreeFilter(
+ XkbSrvInfoPtr xkbi
+)
+{
+register int i;
+
+ if (xkbi->szFilters==0) {
+ xkbi->szFilters = 4;
+ xkbi->filters = xcalloc(xkbi->szFilters, sizeof(XkbFilterRec));
+ /* 6/21/93 (ef) -- XXX! deal with allocation failure */
+ }
+ for (i=0;i<xkbi->szFilters;i++) {
+ if (!xkbi->filters[i].active) {
+ xkbi->filters[i].keycode = 0;
+ return &xkbi->filters[i];
+ }
+ }
+ xkbi->szFilters*=2;
+ xkbi->filters= xrealloc(xkbi->filters,
+ xkbi->szFilters * sizeof(XkbFilterRec));
+ /* 6/21/93 (ef) -- XXX! deal with allocation failure */
+ bzero(&xkbi->filters[xkbi->szFilters/2],
+ (xkbi->szFilters/2)*sizeof(XkbFilterRec));
+ return &xkbi->filters[xkbi->szFilters/2];
+}
+
+static int
+_XkbApplyFilters(XkbSrvInfoPtr xkbi,unsigned kc,XkbAction *pAction)
+{
+register int i,send;
+
+ send= 1;
+ for (i=0;i<xkbi->szFilters;i++) {
+ if ((xkbi->filters[i].active)&&(xkbi->filters[i].filter))
+ send= ((*xkbi->filters[i].filter)(xkbi,&xkbi->filters[i],kc,pAction)
+ && send);
+ }
+ return send;
+}
+
+void
+XkbHandleActions(DeviceIntPtr dev, DeviceIntPtr kbd, DeviceEvent* event)
+{
+int key,bit,i;
+XkbSrvInfoPtr xkbi;
+KeyClassPtr keyc;
+int changed,sendEvent;
+Bool genStateNotify;
+XkbAction act;
+XkbFilterPtr filter;
+Bool keyEvent;
+Bool pressEvent;
+ProcessInputProc backupproc;
+
+xkbDeviceInfoPtr xkbPrivPtr = XKBDEVICEINFO(dev);
+
+ keyc= kbd->key;
+ xkbi= keyc->xkbInfo;
+ key= event->detail.key;
+ /* The state may change, so if we're not in the middle of sending a state
+ * notify, prepare for it */
+ if ((xkbi->flags&_XkbStateNotifyInProgress)==0) {
+ xkbi->prev_state = xkbi->state;
+ xkbi->flags|= _XkbStateNotifyInProgress;
+ genStateNotify= TRUE;
+ }
+ else genStateNotify= FALSE;
+
+ xkbi->clearMods = xkbi->setMods = 0;
+ xkbi->groupChange = 0;
+
+ sendEvent = 1;
+ keyEvent= ((event->type == ET_KeyPress) || (event->type == ET_KeyRelease));
+ pressEvent= ((event->type == ET_KeyPress)|| (event->type == ET_ButtonPress));
+
+ if (pressEvent) {
+ if (keyEvent)
+ act = XkbGetKeyAction(xkbi,&xkbi->state,key);
+ else {
+ act = XkbGetButtonAction(kbd,dev,key);
+ key|= BTN_ACT_FLAG;
+ }
+ sendEvent = _XkbApplyFilters(xkbi,key,&act);
+ if (sendEvent) {
+ switch (act.type) {
+ case XkbSA_SetMods:
+ case XkbSA_SetGroup:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent = _XkbFilterSetState(xkbi,filter,key,&act);
+ break;
+ case XkbSA_LatchMods:
+ case XkbSA_LatchGroup:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent=_XkbFilterLatchState(xkbi,filter,key,&act);
+ break;
+ case XkbSA_LockMods:
+ case XkbSA_LockGroup:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent=_XkbFilterLockState(xkbi,filter,key,&act);
+ break;
+ case XkbSA_ISOLock:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent=_XkbFilterISOLock(xkbi,filter,key,&act);
+ break;
+ case XkbSA_MovePtr:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent= _XkbFilterPointerMove(xkbi,filter,key,&act);
+ break;
+ case XkbSA_PtrBtn:
+ case XkbSA_LockPtrBtn:
+ case XkbSA_SetPtrDflt:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent= _XkbFilterPointerBtn(xkbi,filter,key,&act);
+ break;
+ case XkbSA_Terminate:
+ sendEvent= XkbDDXTerminateServer(dev,key,&act);
+ break;
+ case XkbSA_SwitchScreen:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent=_XkbFilterSwitchScreen(xkbi,filter,key,&act);
+ break;
+ case XkbSA_SetControls:
+ case XkbSA_LockControls:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent=_XkbFilterControls(xkbi,filter,key,&act);
+ break;
+ case XkbSA_ActionMessage:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent=_XkbFilterActionMessage(xkbi,filter,key,&act);
+ break;
+ case XkbSA_RedirectKey:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent= _XkbFilterRedirectKey(xkbi,filter,key,&act);
+ break;
+ case XkbSA_DeviceBtn:
+ case XkbSA_LockDeviceBtn:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent= _XkbFilterDeviceBtn(xkbi,filter,key,&act);
+ break;
+ case XkbSA_XFree86Private:
+ filter = _XkbNextFreeFilter(xkbi);
+ sendEvent= _XkbFilterXF86Private(xkbi,filter,key,&act);
+ break;
+ }
+ }
+ }
+ else {
+ if (!keyEvent)
+ key|= BTN_ACT_FLAG;
+ sendEvent = _XkbApplyFilters(xkbi,key,NULL);
+ }
+
+ if (xkbi->groupChange!=0)
+ xkbi->state.base_group+= xkbi->groupChange;
+ if (xkbi->setMods) {
+ for (i=0,bit=1; xkbi->setMods; i++,bit<<=1 ) {
+ if (xkbi->setMods&bit) {
+ keyc->modifierKeyCount[i]++;
+ xkbi->state.base_mods|= bit;
+ xkbi->setMods&= ~bit;
+ }
+ }
+ }
+ if (xkbi->clearMods) {
+ for (i=0,bit=1; xkbi->clearMods; i++,bit<<=1 ) {
+ if (xkbi->clearMods&bit) {
+ keyc->modifierKeyCount[i]--;
+ if (keyc->modifierKeyCount[i]<=0) {
+ xkbi->state.base_mods&= ~bit;
+ keyc->modifierKeyCount[i] = 0;
+ }
+ xkbi->clearMods&= ~bit;
+ }
+ }
+ }
+
+ if (sendEvent) {
+ DeviceIntPtr tmpdev;
+ if (keyEvent)
+ tmpdev = dev;
+ else
+ tmpdev = GetPairedDevice(dev);
+
+ UNWRAP_PROCESS_INPUT_PROC(tmpdev,xkbPrivPtr, backupproc);
+ dev->public.processInputProc((InternalEvent*)event, tmpdev);
+ COND_WRAP_PROCESS_INPUT_PROC(tmpdev, xkbPrivPtr,
+ backupproc,xkbUnwrapProc);
+ }
+ else if (keyEvent) {
+ FixKeyState(event, dev);
+ }
+
+ XkbComputeDerivedState(xkbi);
+ changed = XkbStateChangedFlags(&xkbi->prev_state,&xkbi->state);
+ if (genStateNotify) {
+ if (changed) {
+ xkbStateNotify sn;
+ sn.keycode= key;
+ sn.eventType= event->type;
+ sn.requestMajor = sn.requestMinor = 0;
+ sn.changed= changed;
+ XkbSendStateNotify(dev,&sn);
+ }
+ xkbi->flags&= ~_XkbStateNotifyInProgress;
+ }
+ changed= XkbIndicatorsToUpdate(dev,changed,FALSE);
+ if (changed) {
+ XkbEventCauseRec cause;
+ XkbSetCauseKey(&cause, key, event->type);
+ XkbUpdateIndicators(dev,changed,FALSE,NULL,&cause);
+ }
+ return;
+}
+
+int
+XkbLatchModifiers(DeviceIntPtr pXDev,CARD8 mask,CARD8 latches)
+{
+XkbSrvInfoPtr xkbi;
+XkbFilterPtr filter;
+XkbAction act;
+unsigned clear;
+
+ if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
+ xkbi = pXDev->key->xkbInfo;
+ clear= (mask&(~latches));
+ xkbi->state.latched_mods&= ~clear;
+ /* Clear any pending latch to locks.
+ */
+ act.type = XkbSA_NoAction;
+ _XkbApplyFilters(xkbi,SYNTHETIC_KEYCODE,&act);
+ act.type = XkbSA_LatchMods;
+ act.mods.flags = 0;
+ act.mods.mask = mask&latches;
+ filter = _XkbNextFreeFilter(xkbi);
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
+ return Success;
+ }
+ return BadValue;
+}
+
+int
+XkbLatchGroup(DeviceIntPtr pXDev,int group)
+{
+XkbSrvInfoPtr xkbi;
+XkbFilterPtr filter;
+XkbAction act;
+
+ if ( pXDev && pXDev->key && pXDev->key->xkbInfo ) {
+ xkbi = pXDev->key->xkbInfo;
+ act.type = XkbSA_LatchGroup;
+ act.group.flags = 0;
+ XkbSASetGroup(&act.group,group);
+ filter = _XkbNextFreeFilter(xkbi);
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,&act);
+ _XkbFilterLatchState(xkbi,filter,SYNTHETIC_KEYCODE,(XkbAction *)NULL);
+ return Success;
+ }
+ return BadValue;
+}
+
+/***====================================================================***/
+
+void
+XkbClearAllLatchesAndLocks( DeviceIntPtr dev,
+ XkbSrvInfoPtr xkbi,
+ Bool genEv,
+ XkbEventCausePtr cause)
+{
+XkbStateRec os;
+xkbStateNotify sn;
+
+ sn.changed= 0;
+ os= xkbi->state;
+ if (os.latched_mods) { /* clear all latches */
+ XkbLatchModifiers(dev,~0,0);
+ sn.changed|= XkbModifierLatchMask;
+ }
+ if (os.latched_group) {
+ XkbLatchGroup(dev,0);
+ sn.changed|= XkbGroupLatchMask;
+ }
+ if (os.locked_mods) {
+ xkbi->state.locked_mods= 0;
+ sn.changed|= XkbModifierLockMask;
+ }
+ if (os.locked_group) {
+ xkbi->state.locked_group= 0;
+ sn.changed|= XkbGroupLockMask;
+ }
+ if ( genEv && sn.changed) {
+ CARD32 changed;
+
+ XkbComputeDerivedState(xkbi);
+ sn.keycode= cause->kc;
+ sn.eventType= cause->event;
+ sn.requestMajor= cause->mjr;
+ sn.requestMinor= cause->mnr;
+ sn.changed= XkbStateChangedFlags(&os,&xkbi->state);
+ XkbSendStateNotify(dev,&sn);
+ changed= XkbIndicatorsToUpdate(dev,sn.changed,FALSE);
+ if (changed) {
+ XkbUpdateIndicators(dev,changed,TRUE,NULL,cause);
+ }
+ }
+ return;
+}
+
diff --git a/xorg-server/xkb/xkbInit.c b/xorg-server/xkb/xkbInit.c index 4a3219e2a..57b450c49 100644 --- a/xorg-server/xkb/xkbInit.c +++ b/xorg-server/xkb/xkbInit.c @@ -87,8 +87,8 @@ typedef struct _SrvXkmInfo { #define XKB_DFLT_RULES_PROP TRUE #endif -char * XkbBaseDirectory= XKB_BASE_DIRECTORY; -char * XkbBinDirectory= XKB_BIN_DIRECTORY; +const char * XkbBaseDirectory= XKB_BASE_DIRECTORY; +const char * XkbBinDirectory= XKB_BIN_DIRECTORY; static int XkbWantAccessX= 0; static char * XkbRulesDflt= NULL; diff --git a/xorg-server/xkbdata.src/compat/default b/xorg-server/xkbdata.src/compat/default.in index 5355e1318..5355e1318 100644 --- a/xorg-server/xkbdata.src/compat/default +++ b/xorg-server/xkbdata.src/compat/default.in diff --git a/xorg-server/xkbdata.src/compat/makefile b/xorg-server/xkbdata.src/compat/makefile new file mode 100644 index 000000000..486ca5541 --- /dev/null +++ b/xorg-server/xkbdata.src/compat/makefile @@ -0,0 +1,20 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +THISDIR=compat + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\$(THISDIR) + +dist_xkbdata_compat_DATA = \ +accessx basic complete \ +default iso9995 \ +japan keypad ledcaps \ +lednum ledscroll level5 \ +misc mousekeys norepeat \ +olpc pc pc98 xfree86 \ +xtest README + +DATA_FILES=$(dist_xkbdata_compat_DATA:%=$(DESTDIR)\%) + +include ..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/geometry/digital_vndr/makefile b/xorg-server/xkbdata.src/geometry/digital_vndr/makefile new file mode 100644 index 000000000..12d4c37fc --- /dev/null +++ b/xorg-server/xkbdata.src/geometry/digital_vndr/makefile @@ -0,0 +1,12 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\geometry\digital_vndr + +dist_geom_DATA = \ +lk pc unix + +DATA_FILES=$(dist_geom_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/geometry/makefile b/xorg-server/xkbdata.src/geometry/makefile new file mode 100644 index 000000000..4b4aedac5 --- /dev/null +++ b/xorg-server/xkbdata.src/geometry/makefile @@ -0,0 +1,25 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +THISDIR=geometry + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\$(THISDIR) + +dist_xkbdata_geometry_DATA = \ +amiga ataritt chicony \ +dell everex fujitsu \ +hhk hp keytronic kinesis \ +macintosh microsoft nec nokia \ +northgate pc sony thinkpad \ +sun typematrix winbook README + +DATA_FILES=$(dist_xkbdata_geometry_DATA:%=$(DESTDIR)\%) + +SUBDIRS = digital_vndr sgi_vndr + +load_makefile $(SUBDIRS:%=%\makefile MAKESERVER=0 DEBUG=$(DEBUG);) + +extrastuff: $(SUBDIRS:%=%\all) + +include ..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/geometry/sgi_vndr/makefile b/xorg-server/xkbdata.src/geometry/sgi_vndr/makefile new file mode 100644 index 000000000..285067802 --- /dev/null +++ b/xorg-server/xkbdata.src/geometry/sgi_vndr/makefile @@ -0,0 +1,13 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\geometry\sgi_vndr + + +dist_geom_DATA = \ +indigo indy O2 + +DATA_FILES=$(dist_geom_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/keycodes/digital_vndr/makefile b/xorg-server/xkbdata.src/keycodes/digital_vndr/makefile new file mode 100644 index 000000000..9cf1180e5 --- /dev/null +++ b/xorg-server/xkbdata.src/keycodes/digital_vndr/makefile @@ -0,0 +1,12 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\keycodes\digital_vndr + +dist_keycodes_DATA = \ +lk pc + +DATA_FILES=$(dist_keycodes_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/keycodes/makefile b/xorg-server/xkbdata.src/keycodes/makefile new file mode 100644 index 000000000..cdc1dde71 --- /dev/null +++ b/xorg-server/xkbdata.src/keycodes/makefile @@ -0,0 +1,32 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +THISDIR=keycodes + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\$(THISDIR) + +SUBDIRS = digital_vndr sgi_vndr + +dist_xkbdata_keycodes_DATA = \ + aliases \ + amiga \ + ataritt \ + evdev \ + fujitsu \ + hp \ + ibm \ + macintosh \ + sony \ + sun \ + xfree86 \ + xfree98 \ + README + +DATA_FILES=$(dist_xkbdata_keycodes_DATA:%=$(DESTDIR)\%) + +load_makefile $(SUBDIRS:%=%\makefile MAKESERVER=0 DEBUG=$(DEBUG);) + +extrastuff: $(SUBDIRS:%=%\all) + +include ..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/keycodes/sgi_vndr/makefile b/xorg-server/xkbdata.src/keycodes/sgi_vndr/makefile new file mode 100644 index 000000000..e6c1defda --- /dev/null +++ b/xorg-server/xkbdata.src/keycodes/sgi_vndr/makefile @@ -0,0 +1,12 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\keycodes\sgi_vndr + +dist_keycodes_DATA = \ +indigo indy iris + +DATA_FILES=$(dist_keycodes_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/keymap/digital_vndr/makefile b/xorg-server/xkbdata.src/keymap/digital_vndr/makefile new file mode 100644 index 000000000..09dd6f797 --- /dev/null +++ b/xorg-server/xkbdata.src/keymap/digital_vndr/makefile @@ -0,0 +1,12 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\keymap\digital_vndr + +dist_keymap_DATA = \ +us + +DATA_FILES=$(dist_keymap_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/keymap/makefile b/xorg-server/xkbdata.src/keymap/makefile new file mode 100644 index 000000000..1b549a08f --- /dev/null +++ b/xorg-server/xkbdata.src/keymap/makefile @@ -0,0 +1,22 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +THISDIR=keymap + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\$(THISDIR) + +SUBDIRS = digital_vndr sgi_vndr sun_vndr + +dist_xkbdata_keymap_DATA = \ +amiga ataritt macintosh \ +sony xfree86 xfree98 \ +README + +DATA_FILES=$(dist_xkbdata_keymap_DATA:%=$(DESTDIR)\%) + +load_makefile $(SUBDIRS:%=%\makefile MAKESERVER=0 DEBUG=$(DEBUG);) + +extrastuff: $(SUBDIRS:%=%\all) + +include ..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/keymap/sgi_vndr/makefile b/xorg-server/xkbdata.src/keymap/sgi_vndr/makefile new file mode 100644 index 000000000..d2cb6083e --- /dev/null +++ b/xorg-server/xkbdata.src/keymap/sgi_vndr/makefile @@ -0,0 +1,20 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\keymap\sgi_vndr + +dist_keymap_DATA = \ +be bg ca \ +ch cz de \ +dk dvorak \ +es fi \ +fr gb \ +hu it jp \ +no pl pt \ +ru se sk \ +th us + +DATA_FILES=$(dist_keymap_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/keymap/sun_vndr/all b/xorg-server/xkbdata.src/keymap/sun_vndr/all.in index 047ae7bc4..047ae7bc4 100644 --- a/xorg-server/xkbdata.src/keymap/sun_vndr/all +++ b/xorg-server/xkbdata.src/keymap/sun_vndr/all.in diff --git a/xorg-server/xkbdata.src/keymap/sun_vndr/makefile b/xorg-server/xkbdata.src/keymap/sun_vndr/makefile new file mode 100644 index 000000000..1dd8b4c45 --- /dev/null +++ b/xorg-server/xkbdata.src/keymap/sun_vndr/makefile @@ -0,0 +1,20 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\keymap\sun_vndr + +dist_keymap_DATA = \ +all de es fi \ +fr no pl \ +ru se uk \ +us + +DATA_FILES=$(dist_keymap_DATA:%=$(DESTDIR)\%) + +# We need to make the rule for all explicit since searching it in the implicit rules doesn't work for all +$(DESTDIR)\all: all.in + copy $< $@ + + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/makefile b/xorg-server/xkbdata.src/makefile new file mode 100644 index 000000000..94c550947 --- /dev/null +++ b/xorg-server/xkbdata.src/makefile @@ -0,0 +1,9 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +SUBDIRS = compat geometry keycodes keymap rules semantics symbols types + +load_makefile $(SUBDIRS:%=%\makefile MAKESERVER=0 DEBUG=$(DEBUG);) + +all: $(SUBDIRS:%=%\all) diff --git a/xorg-server/xkbdata.src/rules/bin/ln_s.sh b/xorg-server/xkbdata.src/rules/bin/ln_s.sh index 07ac2f087..78e557d8f 100644 --- a/xorg-server/xkbdata.src/rules/bin/ln_s.sh +++ b/xorg-server/xkbdata.src/rules/bin/ln_s.sh @@ -1,20 +1,10 @@ -#!/bin/sh +@echo off +set variant=%1 -variant=$1 +set OUTFILE=base.l%variant%_s.part -INDIR=$2 -OUTFILE=base.l${variant}_s.part +if exist %OUTFILE% del %OUTFILE% -> $OUTFILE +gawk "{ if (index($2, """(""") == 0) { printf """ %%s = +%%s%%%%(v[%variant%]):%variant%\n""", $1, $2; } else { printf """ %%s = +%%s:%variant%\n""", $1, $2; }}" < layoutsMapping.lst >> %OUTFILE% -awk '{ - if (index($2, "(") == 0) { - printf " %s = +%s%%(v['${variant}']):'${variant}'\n", $1, $2; - } else { - printf " %s = +%s:'${variant}'\n", $1, $2; - } -}' < $INDIR/layoutsMapping.lst >> $OUTFILE - -awk '{ - printf " %s(%s) = +%s(%s):'${variant}'\n", $1, $2, $3, $4; -}' < $INDIR/variantsMapping.lst >> $OUTFILE +gawk "{ printf """ %%s(%%s) = +%%s(%%s):%variant%\n""", $1, $2, $3, $4; }" < variantsMapping.lst >> %OUTFILE% diff --git a/xorg-server/xkbdata.src/rules/bin/lnv_s.sh b/xorg-server/xkbdata.src/rules/bin/lnv_s.sh index fc0d42020..6bbf285e7 100644 --- a/xorg-server/xkbdata.src/rules/bin/lnv_s.sh +++ b/xorg-server/xkbdata.src/rules/bin/lnv_s.sh @@ -1,12 +1,8 @@ -#!/bin/sh +@echo off +set variant=%1 -variant=$1 +set OUTFILE=base.l%variant%v%variant%_s.part -INDIR=$2 -OUTFILE=base.l${variant}v${variant}_s.part +if exist %OUTFILE% del %OUTFILE% -> $OUTFILE - -awk '{ - printf " %s %s = +%s(%s):'${variant}'\n", $1, $2, $3, $4; -}' < $INDIR/variantsMapping.lst >> $OUTFILE +gawk "{ printf """ %%s %%s = +%%s(%%s):%variant%\n""", $1, $2, $3, $4; }" < variantsMapping.lst >> %OUTFILE% diff --git a/xorg-server/xkbdata.src/rules/bin/ml1_s.sh b/xorg-server/xkbdata.src/rules/bin/ml1_s.sh index b2d222432..b09459a5d 100644 --- a/xorg-server/xkbdata.src/rules/bin/ml1_s.sh +++ b/xorg-server/xkbdata.src/rules/bin/ml1_s.sh @@ -1,18 +1,9 @@ -#!/bin/sh +@echo off -INDIR=$1 -OUTFILE=base.ml1_s.part +set OUTFILE=base.ml1_s.part -> $OUTFILE +if exist %OUTFILE% del %OUTFILE% -awk '{ - if (index($2, "(") == 0) { - printf " * %s = pc+%s%%(v[1])\n", $1, $2; - } else { - printf " * %s = pc+%s\n", $1, $2; - } -}' < $INDIR/layoutsMapping.lst >> $OUTFILE +gawk "{ if (index($2, """(""") == 0) { printf """ * %%s = pc+%%s%%%%(v[1])\n""", $1, $2; } else { printf """ * %%s = pc+%%s\n""", $1, $2; }}" < layoutsMapping.lst >> %OUTFILE% -awk '{ - printf " * %s(%s) = pc+%s(%s)\n", $1, $2, $3, $4; -}' < $INDIR/variantsMapping.lst >> $OUTFILE +gawk "{ printf """ * %%s(%%s) = pc+%%s(%%s)\n""", $1, $2, $3, $4; }" < variantsMapping.lst >> %OUTFILE% diff --git a/xorg-server/xkbdata.src/rules/bin/ml1v1_s.sh b/xorg-server/xkbdata.src/rules/bin/ml1v1_s.sh index 7c2b1a84c..4d492e02b 100644 --- a/xorg-server/xkbdata.src/rules/bin/ml1v1_s.sh +++ b/xorg-server/xkbdata.src/rules/bin/ml1v1_s.sh @@ -1,10 +1,7 @@ -#!/bin/sh +@echo off -INDIR=$1 -OUTFILE=base.ml1v1_s.part +set OUTFILE=base.ml1v1_s.part -> $OUTFILE +if exist %OUTFILE% del %OUTFILE% -awk '{ - printf " * %s %s = pc+%s(%s)\n", $1, $2, $3, $4; -}' < $INDIR/variantsMapping.lst >> $OUTFILE +gawk "{ printf """ * %%s %%s = pc+%%s(%%s)\n""", $1, $2, $3, $4; }" < variantsMapping.lst >> %OUTFILE% diff --git a/xorg-server/xkbdata.src/rules/bin/ml1v_s.sh b/xorg-server/xkbdata.src/rules/bin/ml1v_s.sh index 084d4c0be..cec1334c0 100644 --- a/xorg-server/xkbdata.src/rules/bin/ml1v_s.sh +++ b/xorg-server/xkbdata.src/rules/bin/ml1v_s.sh @@ -1,10 +1,7 @@ -#!/bin/sh +@echo off -INDIR=$1 -OUTFILE=base.ml1v_s.part +set OUTFILE=base.ml1v_s.part -> $OUTFILE +if exist %OUTFILE% del %OUTFILE% -awk '{ - printf " * %s %s = pc+%s(%s)\n", $1, $2, $3, $4; -}' < $INDIR/variantsMapping.lst >> $OUTFILE +gawk "{ printf """ * %%s %%s = pc+%%s(%%s)\n""", $1, $2, $3, $4; }" < variantsMapping.lst >> %OUTFILE% diff --git a/xorg-server/xkbdata.src/rules/bin/ml_s.sh b/xorg-server/xkbdata.src/rules/bin/ml_s.sh index 666ba870f..b7f0d9c46 100644 --- a/xorg-server/xkbdata.src/rules/bin/ml_s.sh +++ b/xorg-server/xkbdata.src/rules/bin/ml_s.sh @@ -1,14 +1,9 @@ -#!/bin/sh +@echo off -INDIR=$1 -OUTFILE=base.ml_s.part +set OUTFILE=base.ml_s.part -> $OUTFILE +if exist %OUTFILE% del %OUTFILE% -awk '{ - printf " * %s = pc+%s\n", $1, $2; -}' < $INDIR/layoutsMapping.lst >> $OUTFILE +gawk "{ printf """ * %%s = pc+%%s\n""", $1, $2; }" < layoutsMapping.lst >> %OUTFILE% -awk '{ - printf " * %s(%s) = pc+%s(%s)\n", $1, $2, $3, $4; -}' < $INDIR/variantsMapping.lst >> $OUTFILE +gawk "{ printf """ * %%s(%%s) = pc+%%s(%%s)\n""", $1, $2, $3, $4; }" < variantsMapping.lst >> %OUTFILE% diff --git a/xorg-server/xkbdata.src/rules/bin/mlv_s.sh b/xorg-server/xkbdata.src/rules/bin/mlv_s.sh index 5b466d59c..573cb930f 100644 --- a/xorg-server/xkbdata.src/rules/bin/mlv_s.sh +++ b/xorg-server/xkbdata.src/rules/bin/mlv_s.sh @@ -1,10 +1,7 @@ -#!/bin/sh +@echo off -INDIR=$1 -OUTFILE=base.mlv_s.part +set OUTFILE=base.mlv_s.part -> $OUTFILE +if exist %OUTFILE% del %OUTFILE% -awk '{ - printf " * %s %s = pc+%s(%s)\n", $1, $2, $3, $4; -}' < $INDIR/variantsMapping.lst >> $OUTFILE +gawk "{ printf """ * %%s %%s = pc+%%s(%%s)\n""", $1, $2, $3, $4; }" < variantsMapping.lst >> %OUTFILE% diff --git a/xorg-server/xkbdata.src/rules/compat/makefile b/xorg-server/xkbdata.src/rules/compat/makefile new file mode 100644 index 000000000..4a1a7b832 --- /dev/null +++ b/xorg-server/xkbdata.src/rules/compat/makefile @@ -0,0 +1,53 @@ +TRANSFORM_FILES=layoutsMapping.lst variantsMapping.lst + +scripts_dir=..\bin + +SCRIPTS= \ +base.l2_s.part \ +base.l3_s.part \ +base.l4_s.part \ +base.l2v2_s.part \ +base.l3v3_s.part \ +base.l4v4_s.part \ +base.ml_s.part \ +base.ml1_s.part \ +base.mlv_s.part \ +base.ml1v1_s.part \ +base.ml_s.part + +SH=cmd /c + +%.bat: $(scripts_dir)\%.sh + copy $< $@ + +base.l2_s.part: ln_s.bat $(TRANSFORM_FILES) + $(SH) $< 2 + +base.l3_s.part: ln_s.bat $(TRANSFORM_FILES) + $(SH) $< 3 + +base.l4_s.part: ln_s.bat $(TRANSFORM_FILES) + $(SH) $< 4 + +base.l2v2_s.part: lnv_s.bat $(TRANSFORM_FILES) + $(SH) $< 2 + +base.l3v3_s.part: lnv_s.bat $(TRANSFORM_FILES) + $(SH) $< 3 + +base.l4v4_s.part: lnv_s.bat $(TRANSFORM_FILES) + $(SH) $< 4 + +base.ml_s.part: ml_s.bat $(TRANSFORM_FILES) + $(SH) $< + +base.ml1_s.part: ml1_s.bat $(TRANSFORM_FILES) + $(SH) $< + +base.mlv_s.part: mlv_s.bat $(TRANSFORM_FILES) + $(SH) $< + +base.ml1v1_s.part: ml1v1_s.bat $(TRANSFORM_FILES) + $(SH) $< + +all: $(SCRIPTS) diff --git a/xorg-server/xkbdata.src/rules/extras/makefile b/xorg-server/xkbdata.src/rules/extras/makefile new file mode 100644 index 000000000..f5753f674 --- /dev/null +++ b/xorg-server/xkbdata.src/rules/extras/makefile @@ -0,0 +1,53 @@ +TRANSFORM_FILES=layoutsMapping.lst variantsMapping.lst + +scripts_dir=..\bin + +SCRIPTS= \ +base.l2_s.part \ +base.l3_s.part \ +base.l4_s.part \ +base.l2v2_s.part \ +base.l3v3_s.part \ +base.l4v4_s.part \ +base.ml_s.part \ +base.ml1_s.part \ +base.mlv_s.part \ +base.ml1v1_s.part \ +base.ml_s.part + +SH=cmd /c + +%.bat: $(scripts_dir)\%.sh + copy $< $@ + +base.l2_s.part: ln_s.bat $(TRANSFORM_FILES) + $(SH) $< 2 + +base.l3_s.part: ln_s.bat $(TRANSFORM_FILES) + $(SH) $< 3 + +base.l4_s.part: ln_s.bat $(TRANSFORM_FILES) + $(SH) $< 4 + +base.l2v2_s.part: lnv_s.bat $(TRANSFORM_FILES) + $(SH) $< 2 + +base.l3v3_s.part: lnv_s.bat $(TRANSFORM_FILES) + $(SH) $< 3 + +base.l4v4_s.part: lnv_s.bat $(TRANSFORM_FILES) + $(SH) $< 4 + +base.ml_s.part: ml_s.bat $(TRANSFORM_FILES) + $(SH) $< + +base.ml1_s.part: ml1_s.bat $(TRANSFORM_FILES) + $(SH) $< + +base.mlv_s.part: mlv_s.bat $(TRANSFORM_FILES) + $(SH) $< + +base.ml1v1_s.part: ml1v1_s.bat $(TRANSFORM_FILES) + $(SH) $< + +all=$(SCRIPTS) diff --git a/xorg-server/xkbdata.src/rules/makefile b/xorg-server/xkbdata.src/rules/makefile new file mode 100644 index 000000000..65cd8378e --- /dev/null +++ b/xorg-server/xkbdata.src/rules/makefile @@ -0,0 +1,166 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +load_makefile compat\makefile DEBUG=$(DEBUG) +load_makefile extras\makefile DEBUG=$(DEBUG) + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\rules + +BASE_PARTS_NO_COMPAT = base.hdr.part base.lists.part \ +compat/base.lists.part \ +HDR base.m_k.part \ +HDR base.l1_k.part \ +HDR base.l_k.part \ +HDR base.o_k.part \ +HDR base.ml_g.part \ +HDR base.m_g.part \ +HDR compat/base.mlv_s.part extras/base.mlv_s.part base.mlv_s.part \ +HDR compat/base.ml_s.part extras/base.ml_s.part base.ml_s.part \ +HDR compat/base.ml1_s.part extras/base.ml1_s.part base.ml1_s.part \ +HDR compat/base.ml1v1_s.part extras/base.ml1v1_s.part \ +HDR compat/base.l2_s.part extras/base.l2_s.part base.l2_s.part \ +HDR compat/base.l3_s.part extras/base.l3_s.part base.l3_s.part \ +HDR compat/base.l4_s.part extras/base.l4_s.part base.l4_s.part \ +HDR compat/base.l2v2_s.part extras/base.l2v2_s.part \ +HDR compat/base.l3v3_s.part extras/base.l3v3_s.part \ +HDR compat/base.l4v4_s.part extras/base.l4v4_s.part \ +HDR base.m_s.part \ +HDR base.ml_c.part \ +HDR base.ml1_c.part \ +HDR base.m_t.part \ +HDR base.lo_s.part \ +HDR base.l1o_s.part \ +HDR base.l2o_s.part \ +HDR base.l3o_s.part \ +HDR base.l4o_s.part \ +HDR compat/base.o_s.part base.o_s.part \ +HDR base.o_c.part \ +HDR base.o_t.part + +EVDEV_PARTS_NO_COMPAT = base.hdr.part base.lists.part \ +compat/base.lists.part \ +HDR evdev.m_k.part \ +HDR base.l1_k.part \ +HDR base.l_k.part \ +HDR base.o_k.part \ +HDR base.ml_g.part \ +HDR base.m_g.part \ +HDR compat/base.mlv_s.part extras/base.mlv_s.part base.mlv_s.part \ +HDR compat/base.ml_s.part extras/base.ml_s.part base.ml_s.part \ +HDR compat/base.ml1_s.part extras/base.ml1_s.part base.ml1_s.part \ +HDR compat/base.ml1v1_s.part extras/base.ml1v1_s.part \ +HDR compat/base.l2_s.part extras/base.l2_s.part base.l2_s.part \ +HDR compat/base.l3_s.part extras/base.l3_s.part base.l3_s.part \ +HDR compat/base.l4_s.part extras/base.l4_s.part base.l4_s.part \ +HDR compat/base.l2v2_s.part extras/base.l2v2_s.part \ +HDR compat/base.l3v3_s.part extras/base.l3v3_s.part \ +HDR compat/base.l4v4_s.part extras/base.l4v4_s.part \ +HDR evdev.m_s.part \ +HDR base.ml_c.part \ +HDR base.ml1_c.part \ +HDR base.m_t.part \ +HDR base.lo_s.part \ +HDR base.l1o_s.part \ +HDR base.l2o_s.part \ +HDR base.l3o_s.part \ +HDR base.l4o_s.part \ +HDR compat/base.o_s.part base.o_s.part \ +HDR base.o_c.part \ +HDR base.o_t.part + +BASE_PARTS = base.hdr.part base.lists.part \ +HDR base.m_k.part \ +HDR base.l1_k.part \ +HDR base.l_k.part \ +HDR \ +HDR base.ml_g.part \ +HDR base.m_g.part \ +HDR extras/base.mlv_s.part base.mlv_s.part \ +HDR extras/base.ml_s.part base.ml_s.part \ +HDR extras/base.ml1_s.part base.ml1_s.part \ +HDR extras/base.ml1v1_s.part \ +HDR extras/base.l2_s.part base.l2_s.part \ +HDR extras/base.l3_s.part base.l3_s.part \ +HDR extras/base.l4_s.part base.l4_s.part \ +HDR extras/base.l2v2_s.part \ +HDR extras/base.l3v3_s.part \ +HDR extras/base.l4v4_s.part \ +HDR base.m_s.part \ +HDR base.ml_c.part \ +HDR base.ml1_c.part \ +HDR base.m_t.part \ +HDR \ +HDR base.l1o_s.part \ +HDR base.l2o_s.part \ +HDR base.l3o_s.part \ +HDR base.l4o_s.part \ +HDR base.o_s.part \ +HDR base.o_c.part \ +HDR base.o_t.part + +EVDEV_PARTS = base.hdr.part base.lists.part \ +HDR evdev.m_k.part \ +HDR base.l1_k.part \ +HDR base.l_k.part \ +HDR \ +HDR base.ml_g.part \ +HDR base.m_g.part \ +HDR extras/base.mlv_s.part base.mlv_s.part \ +HDR extras/base.ml_s.part base.ml_s.part \ +HDR extras/base.ml1_s.part base.ml1_s.part \ +HDR extras/base.ml1v1_s.part \ +HDR extras/base.l2_s.part base.l2_s.part \ +HDR extras/base.l3_s.part base.l3_s.part \ +HDR extras/base.l4_s.part base.l4_s.part \ +HDR extras/base.l2v2_s.part \ +HDR extras/base.l3v3_s.part \ +HDR extras/base.l4v4_s.part \ +HDR evdev.m_s.part \ +HDR base.ml_c.part \ +HDR base.ml1_c.part \ +HDR base.m_t.part \ +HDR \ +HDR base.l1o_s.part \ +HDR base.l2o_s.part \ +HDR base.l3o_s.part \ +HDR base.l4o_s.part \ +HDR base.o_s.part \ +HDR base.o_c.part \ +HDR base.o_t.part + +RULES_FILES = base evdev xfree98 + +LST_FILES = base.lst evdev.lst + +$(DESTDIR)\%.lst: $(DESTDIR)\%.xml + perl xml2lst.pl < $< > $@ + +$(DESTDIR)\base: compat\all $(BASE_PARTS_NO_COMPAT) + merge $@ $(BASE_PARTS) + +$(DESTDIR)\evdev: compat\all $(EVDEV_PARTS_NO_COMPAT) + merge $@ $(EVDEV_PARTS) + +ALL_RULES_FILES = $(RULES_FILES) $(LST_FILES) \ +xkb.dtd README + +COMPATFILES=xorg xorg.xml xorg.lst +$(DESTDIR)\xorg: $(DESTDIR)\base + copy $< $@ +$(DESTDIR)\xorg%: $(DESTDIR)\base% + copy $< $@ + +rules_DATA = $(ALL_RULES_FILES) $(COMPATFILES) + +XML_IN_FILES = base.xml.in evdev.xml.in base.extras.xml.in evdev.extras.xml.in +xml_DATA = $(XML_IN_FILES:%.xml.in=%.xml) + +$(DESTDIR)\%.xml: %.xml.in + copy $< $@ + + + +DATA_FILES=$(rules_DATA:%=$(DESTDIR)\%) $(xml_DATA:%=$(DESTDIR)\%) + +include ..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/rules/merge.py b/xorg-server/xkbdata.src/rules/merge.py new file mode 100644 index 000000000..442a866f2 --- /dev/null +++ b/xorg-server/xkbdata.src/rules/merge.py @@ -0,0 +1,13 @@ +import sys + +pOUT=open(sys.argv[1],"wb") +pHDR=open("HDR","r") +for item in sys.argv[2:]: + if item == 'HDR': + pOUT.write("\n") + pOUT.write(pHDR.readline()) + else: + pOUT.write(open(item,"rb").read()) + +pOUT.close() + diff --git a/xorg-server/xkbdata.src/semantics/default b/xorg-server/xkbdata.src/semantics/default.in index 42e755e3c..42e755e3c 100644 --- a/xorg-server/xkbdata.src/semantics/default +++ b/xorg-server/xkbdata.src/semantics/default.in diff --git a/xorg-server/xkbdata.src/semantics/makefile b/xorg-server/xkbdata.src/semantics/makefile new file mode 100644 index 000000000..0181c169f --- /dev/null +++ b/xorg-server/xkbdata.src/semantics/makefile @@ -0,0 +1,17 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +THISDIR=semantics + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\$(THISDIR) + +dist_xkbdata_semantics_DATA = \ + basic \ + complete \ + default \ + xtest + +DATA_FILES=$(dist_xkbdata_semantics_DATA:%=$(DESTDIR)\%) + +include ..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/symbols/digital_vndr/makefile b/xorg-server/xkbdata.src/symbols/digital_vndr/makefile new file mode 100644 index 000000000..cdfa2ef28 --- /dev/null +++ b/xorg-server/xkbdata.src/symbols/digital_vndr/makefile @@ -0,0 +1,13 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\symbols\digital_vndr + +dist_symbols_DATA = \ +lk pc us \ +vt + +DATA_FILES=$(dist_symbols_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/symbols/fujitsu_vndr/makefile b/xorg-server/xkbdata.src/symbols/fujitsu_vndr/makefile new file mode 100644 index 000000000..841c123d8 --- /dev/null +++ b/xorg-server/xkbdata.src/symbols/fujitsu_vndr/makefile @@ -0,0 +1,12 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\symbols\fujitsu_vndr + +dist_symbols_DATA = \ +jp us + +DATA_FILES=$(dist_symbols_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/symbols/hp_vndr/makefile b/xorg-server/xkbdata.src/symbols/hp_vndr/makefile new file mode 100644 index 000000000..3e6a64f47 --- /dev/null +++ b/xorg-server/xkbdata.src/symbols/hp_vndr/makefile @@ -0,0 +1,12 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\symbols\hp_vndr + +dist_symbols_DATA = \ +us + +DATA_FILES=$(dist_symbols_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/symbols/level3 b/xorg-server/xkbdata.src/symbols/level3 index 79fdcea03..a52708e2e 100644 --- a/xorg-server/xkbdata.src/symbols/level3 +++ b/xorg-server/xkbdata.src/symbols/level3 @@ -11,7 +11,7 @@ default partial modifier_keys xkb_symbols "ralt_switch" { key <RALT> { - type[Group1]="ONE_LEVEL", + type[Group1]="TWO_LEVEL", symbols[Group1] = [ ISO_Level3_Shift ] }; modifier_map Mod5 { ISO_Level3_Shift }; diff --git a/xorg-server/xkbdata.src/symbols/macintosh_vndr/makefile b/xorg-server/xkbdata.src/symbols/macintosh_vndr/makefile new file mode 100644 index 000000000..eb65d93a0 --- /dev/null +++ b/xorg-server/xkbdata.src/symbols/macintosh_vndr/makefile @@ -0,0 +1,16 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\symbols\macintosh_vndr + +dist_symbols_DATA = \ +apple ch de dk \ +fi fr \ +gb is it \ +latam nl no pt \ +se us + +DATA_FILES=$(dist_symbols_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/symbols/makefile b/xorg-server/xkbdata.src/symbols/makefile new file mode 100644 index 000000000..866d2d1a5 --- /dev/null +++ b/xorg-server/xkbdata.src/symbols/makefile @@ -0,0 +1,49 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +THISDIR=symbols + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\$(THISDIR) + +SUBDIRS = digital_vndr fujitsu_vndr hp_vndr macintosh_vndr nec_vndr nokia_vndr sgi_vndr sony_vndr sun_vndr xfree68_vndr + +dist_xkbdata_symbols_DATA = \ +ad af al \ +am ara az \ +be bd \ +bg br ba \ +bt by brai \ +ca cd \ +ch cn cz \ +de dk \ +ee es et epo \ +fi fo fr \ +gb ge gh gn \ +gr hr hu \ +ie il in iq \ +ir is it jp \ +kg kh kr kz \ +la latam latin \ +lk lt lv \ +ma mao me mk \ +mm mn mt mv \ +ng nl no np \ +pc pk pl pt \ +ro rs ru \ +se si sk sn \ +sy th \ +terminate \ +tj tm tr \ +ua us uz vn \ +za \ +altwin capslock compose ctrl eurosign group inet \ +keypad kpdl level3 level5 nbsp olpc shift srvr_ctrl typo + +DATA_FILES=$(dist_xkbdata_symbols_DATA:%=$(DESTDIR)\%) + +load_makefile $(SUBDIRS:%=%\makefile MAKESERVER=0 DEBUG=$(DEBUG);) + +extrastuff: $(SUBDIRS:%=%\all) + +include ..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/symbols/nec_vndr/makefile b/xorg-server/xkbdata.src/symbols/nec_vndr/makefile new file mode 100644 index 000000000..6ab523a2b --- /dev/null +++ b/xorg-server/xkbdata.src/symbols/nec_vndr/makefile @@ -0,0 +1,12 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\symbols\nec_vndr + +dist_symbols_DATA = \ +jp + +DATA_FILES=$(dist_symbols_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/symbols/nokia_vndr/makefile b/xorg-server/xkbdata.src/symbols/nokia_vndr/makefile new file mode 100644 index 000000000..f3719bbac --- /dev/null +++ b/xorg-server/xkbdata.src/symbols/nokia_vndr/makefile @@ -0,0 +1,14 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\symbols\nokia_vndr + +dist_symbols_DATA = \ +rx-44 \ +rx-51 \ +su-8w + +DATA_FILES=$(dist_symbols_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/symbols/sgi_vndr/makefile b/xorg-server/xkbdata.src/symbols/sgi_vndr/makefile new file mode 100644 index 000000000..79a27fead --- /dev/null +++ b/xorg-server/xkbdata.src/symbols/sgi_vndr/makefile @@ -0,0 +1,12 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\symbols\sgi_vndr + +dist_symbols_DATA = \ +jp + +DATA_FILES=$(dist_symbols_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/symbols/sony_vndr/makefile b/xorg-server/xkbdata.src/symbols/sony_vndr/makefile new file mode 100644 index 000000000..c2c1fa757 --- /dev/null +++ b/xorg-server/xkbdata.src/symbols/sony_vndr/makefile @@ -0,0 +1,12 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\symbols\sony_vndr + +dist_symbols_DATA = \ +us + +DATA_FILES=$(dist_symbols_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/symbols/sun_vndr/makefile b/xorg-server/xkbdata.src/symbols/sun_vndr/makefile new file mode 100644 index 000000000..5741501b3 --- /dev/null +++ b/xorg-server/xkbdata.src/symbols/sun_vndr/makefile @@ -0,0 +1,17 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\symbols\sun_vndr + +dist_symbols_DATA = \ + cs cz de dk es \ + fi fr gb gr hu \ + it jp ko lt lv \ + nl no pl pt ru \ + se solaris sw tr tuv \ + tw us usb + +DATA_FILES=$(dist_symbols_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/symbols/xfree68_vndr/makefile b/xorg-server/xkbdata.src/symbols/xfree68_vndr/makefile new file mode 100644 index 000000000..c9c1b3ede --- /dev/null +++ b/xorg-server/xkbdata.src/symbols/xfree68_vndr/makefile @@ -0,0 +1,12 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\symbols\xfree68_vndr + +dist_symbols_DATA = \ +amiga ataritt + +DATA_FILES=$(dist_symbols_DATA:%=$(DESTDIR)\%) + +include ..\..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/types/default b/xorg-server/xkbdata.src/types/default.in index 18859b742..18859b742 100644 --- a/xorg-server/xkbdata.src/types/default +++ b/xorg-server/xkbdata.src/types/default.in diff --git a/xorg-server/xkbdata.src/types/makefile b/xorg-server/xkbdata.src/types/makefile new file mode 100644 index 000000000..ef03746ed --- /dev/null +++ b/xorg-server/xkbdata.src/types/makefile @@ -0,0 +1,17 @@ +ifeq ($(MAKESERVER),1) +$(error Please do not specify MAKESERVER=1) +endif + +THISDIR=types + +DESTDIR=$(MHMAKECONF)\xorg-server\xkbdata\$(THISDIR) + +dist_xkbdata_types_DATA = \ +basic cancel caps \ +complete default extra \ +iso9995 level5 mousekeys nokia numpad \ +pc README + +DATA_FILES=$(dist_xkbdata_types_DATA:%=$(DESTDIR)\%) + +include ..\xkbrules.mak diff --git a/xorg-server/xkbdata.src/xkbrules.mak b/xorg-server/xkbdata.src/xkbrules.mak new file mode 100644 index 000000000..3b5480e46 --- /dev/null +++ b/xorg-server/xkbdata.src/xkbrules.mak @@ -0,0 +1,16 @@ +DIRFILE=$(THISDIR:%=$(DESTDIR)\..\%.dir) +all: $(DESTDIR) $(DATA_FILES) $(DIRFILE) + +$(DESTDIR)\default: default.in + copy $< $@ + +$(DESTDIR)\%: % + copy $< $@ + +ifneq ($(DIRFILE),) +.PHONY: extrastuff + +$(DIRFILE): extrastuff $(DATA_FILES) + -del -e $@ + cd $(DESTDIR) & ..\..\xkbcomp.exe -lfhlpR -o $(relpath $@) * +endif |