diff options
author | Ulrich Sibiller <uli42@gmx.de> | 2017-10-31 01:54:47 +0100 |
---|---|---|
committer | Mihai Moldovan <ionic@ionic.de> | 2018-02-26 02:38:53 +0100 |
commit | a667131e2846355b7b2099635761a79e22bcbe68 (patch) | |
tree | 16c659450b5354b729da8ac2cd6115a493bfd05b /nx-X11/programs/Xserver/xfixes/cursor.c | |
parent | 164263e1a12fc8a3a496739799cb60d547857f0a (diff) | |
download | nx-libs-a667131e2846355b7b2099635761a79e22bcbe68.tar.gz nx-libs-a667131e2846355b7b2099635761a79e22bcbe68.tar.bz2 nx-libs-a667131e2846355b7b2099635761a79e22bcbe68.zip |
Lift XFIXES to xorg-xserver-7.1/1.1.0 state (XFIXES 4.0)
Diffstat (limited to 'nx-X11/programs/Xserver/xfixes/cursor.c')
-rw-r--r-- | nx-X11/programs/Xserver/xfixes/cursor.c | 275 |
1 files changed, 273 insertions, 2 deletions
diff --git a/nx-X11/programs/Xserver/xfixes/cursor.c b/nx-X11/programs/Xserver/xfixes/cursor.c index 00a912be3..e0705ed0a 100644 --- a/nx-X11/programs/Xserver/xfixes/cursor.c +++ b/nx-X11/programs/Xserver/xfixes/cursor.c @@ -35,10 +35,14 @@ #include "windowstr.h" static RESTYPE CursorClientType; +static RESTYPE CursorHideCountType; static RESTYPE CursorWindowType; static int CursorScreenPrivateIndex = -1; static int CursorGeneration; static CursorPtr CursorCurrent; +static CursorPtr pInvisibleCursor = NULL; + +static void deleteCursorHideCountsForScreen (ScreenPtr pScreen); #define VERIFY_CURSOR(pCursor, cursor, client, access) { \ pCursor = (CursorPtr)SecurityLookupIDByType((client), (cursor), \ @@ -66,12 +70,29 @@ typedef struct _CursorEvent { 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) ((s)->devPrivates[CursorScreenPrivateIndex].ptr)) @@ -88,7 +109,13 @@ CursorDisplayCursor (ScreenPtr pScreen, Bool ret; Unwrap (cs, pScreen, DisplayCursor); - ret = (*pScreen->DisplayCursor) (pScreen, pCursor); + + if (cs->pCursorHideCounts != NULL) { + ret = (*pScreen->DisplayCursor) (pScreen, pInvisibleCursor); + } else { + ret = (*pScreen->DisplayCursor) (pScreen, pCursor); + } + if (pCursor != CursorCurrent) { CursorEventPtr e; @@ -96,7 +123,7 @@ CursorDisplayCursor (ScreenPtr pScreen, CursorCurrent = pCursor; for (e = cursorEvents; e; e = e->next) { - if ((e->eventMask & XFixesDisplayCursorNotifyMask)) + if (e->eventMask & XFixesDisplayCursorNotifyMask) { xXFixesCursorNotifyEvent ev; ev.type = XFixesEventBase + XFixesCursorNotify; @@ -121,6 +148,7 @@ CursorCloseScreen (ScreenPtr pScreen) Unwrap (cs, pScreen, CloseScreen); Unwrap (cs, pScreen, DisplayCursor); + deleteCursorHideCountsForScreen(pScreen); ret = (*pScreen->CloseScreen) (pScreen); free (cs); if (screenInfo.numScreens <= 1) @@ -674,6 +702,197 @@ SProcXFixesChangeCursorByName (ClientPtr client) 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) malloc(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, + (void *) pChc)) { + free(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) { + free(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); + + pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); + if (!pWin) { + client->errorValue = stuff->window; + return BadWindow; + } + + /* + * 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 = createCursorHideCount(client, pWin->drawable.pScreen); + + if (ret == Success) { + (void) CursorDisplayCursor(pWin->drawable.pScreen, CursorCurrent); + } + + return ret; +} + +int +SProcXFixesHideCursor (ClientPtr client) +{ + REQUEST(xXFixesHideCursorReq); + + swaps (&stuff->length); + REQUEST_SIZE_MATCH (xXFixesHideCursorReq); + swapl (&stuff->window); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + +int +ProcXFixesShowCursor (ClientPtr client) +{ + WindowPtr pWin; + CursorHideCountPtr pChc; + REQUEST(xXFixesShowCursorReq); + + REQUEST_SIZE_MATCH (xXFixesShowCursorReq); + + pWin = (WindowPtr) LookupIDByType (stuff->window, RT_WINDOW); + if (!pWin) { + client->errorValue = stuff->window; + return BadWindow; + } + + /* + * Has client hidden the cursor on this screen? + * If not, generate an error. + */ + pChc = findCursorHideCount(client, pWin->drawable.pScreen); + if (pChc == NULL) { + return BadMatch; + } + + pChc->hideCount--; + if (pChc->hideCount <= 0) { + FreeResource(pChc->resource, 0); + } + + return (client->noClientException); +} + +int +SProcXFixesShowCursor (ClientPtr client) +{ + REQUEST(xXFixesShowCursorReq); + + swaps (&stuff->length); + REQUEST_SIZE_MATCH (xXFixesShowCursorReq); + swapl (&stuff->window); + return (*ProcXFixesVector[stuff->xfixesReqType]) (client); +} + static int CursorFreeClient (void * data, XID id) { @@ -693,6 +912,18 @@ CursorFreeClient (void * data, XID id) } static int +CursorFreeHideCount (void * data, XID id) +{ + CursorHideCountPtr pChc = (CursorHideCountPtr) data; + ScreenPtr pScreen = pChc->pScreen; + + deleteCursorHideCount(pChc, pChc->pScreen); + (void) CursorDisplayCursor(pScreen, CursorCurrent); + + return 1; +} + +static int CursorFreeWindow (void * data, XID id) { WindowPtr pWindow = (WindowPtr) data; @@ -709,6 +940,36 @@ CursorFreeWindow (void * data, XID id) return 1; } +static CursorPtr +createInvisibleCursor (void) +{ + CursorPtr pCursor; + static unsigned int *psrcbits, *pmaskbits; + CursorMetricRec cm; + + psrcbits = (unsigned int *) malloc(4); + pmaskbits = (unsigned int *) malloc(4); + if (psrcbits == NULL || pmaskbits == NULL) { + return NULL; + } + *psrcbits = 0; + *pmaskbits = 0; + + cm.width = 1; + cm.height = 1; + cm.xhot = 0; + cm.yhot = 0; + + pCursor = AllocCursor( + (unsigned char *)psrcbits, + (unsigned char *)pmaskbits, + &cm, + 0, 0, 0, + 0, 0, 0); + + return pCursor; +} + Bool XFixesCursorInit (void) { @@ -731,10 +992,20 @@ XFixesCursorInit (void) return FALSE; Wrap (cs, pScreen, CloseScreen, CursorCloseScreen); Wrap (cs, pScreen, DisplayCursor, CursorDisplayCursor); + cs->pCursorHideCounts = NULL; SetCursorScreen (pScreen, cs); } CursorClientType = CreateNewResourceType(CursorFreeClient); + CursorHideCountType = CreateNewResourceType(CursorFreeHideCount); CursorWindowType = CreateNewResourceType(CursorFreeWindow); + + if (pInvisibleCursor == NULL) { + pInvisibleCursor = createInvisibleCursor(); + if (pInvisibleCursor == NULL) { + return BadAlloc; + } + } + return CursorClientType && CursorWindowType; } |