1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027 |
- /*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2010 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.
- *
- * 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"
- 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), \
- RT_CURSOR, (access)); \
- if (!pCursor) { \
- (client)->errorValue = (cursor); \
- return BadCursor; \
- } \
- }
- /*
- * 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) ((s)->devPrivates[CursorScreenPrivateIndex].ptr))
- #define GetCursorScreenIfSet(s) ((CursorScreenPrivateIndex != -1) ? GetCursorScreen(s) : NULL)
- #define SetCursorScreen(s,p) ((s)->devPrivates[CursorScreenPrivateIndex].ptr = (pointer) (p))
- #define Wrap(as,s,elt,func) (((as)->elt = (s)->elt), (s)->elt = func)
- #define Unwrap(as,s,elt) ((s)->elt = (as)->elt)
- static Bool
- CursorDisplayCursor(ScreenPtr pScreen, CursorPtr pCursor)
- {
- CursorScreenPtr cs = GetCursorScreen(pScreen);
- Bool ret;
- Unwrap(cs, pScreen, DisplayCursor);
- if (cs->pCursorHideCounts != NULL) {
- ret = (*pScreen->DisplayCursor) (pScreen, pInvisibleCursor);
- }
- else {
- ret = (*pScreen->DisplayCursor) (pScreen, pCursor);
- }
- if (pCursor != CursorCurrent) {
- CursorEventPtr e;
- CursorCurrent = pCursor;
- for (e = cursorEvents; e; e = e->next) {
- if (e->eventMask & XFixesDisplayCursorNotifyMask) {
- xXFixesCursorNotifyEvent ev;
- ev.type = XFixesEventBase + XFixesCursorNotify;
- ev.subtype = XFixesDisplayCursorNotify;
- 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, CursorDisplayCursor);
- return ret;
- }
- static Bool
- CursorCloseScreen(int index, ScreenPtr pScreen)
- {
- CursorScreenPtr cs = GetCursorScreen(pScreen);
- Bool ret;
- Unwrap(cs, pScreen, CloseScreen);
- Unwrap(cs, pScreen, DisplayCursor);
- deleteCursorHideCountsForScreen(pScreen);
- ret = (*pScreen->CloseScreen) (index, pScreen);
- free(cs);
- if (index == 0)
- CursorScreenPrivateIndex = -1;
- return ret;
- }
- #define CursorAllEvents (XFixesDisplayCursorNotifyMask)
- static int
- XFixesSelectCursorInput(ClientPtr pClient, WindowPtr pWindow, CARD32 eventMask)
- {
- CursorEventPtr *prev, e;
- 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 = malloc(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
- */
- if (!LookupIDByType(pWindow->drawable.id, CursorWindowType))
- if (!AddResource(pWindow->drawable.id, CursorWindowType,
- (pointer) pWindow)) {
- free(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;
- REQUEST_SIZE_MATCH(xXFixesSelectCursorInputReq);
- pWin = (WindowPtr) SecurityLookupWindow(stuff->window, client,
- SecurityReadAccess);
- if (!pWin)
- return (BadWindow);
- 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)
- {
- REQUEST(xXFixesSelectCursorInputReq);
- swaps(&stuff->length);
- swapl(&stuff->window);
- swapl(&stuff->eventMask);
- 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, x, y;
- REQUEST_SIZE_MATCH(xXFixesGetCursorImageReq);
- pCursor = CursorCurrent;
- if (!pCursor)
- return BadCursor;
- GetSpritePosition(&x, &y);
- width = pCursor->bits->width;
- height = pCursor->bits->height;
- npixels = width * height;
- rep = malloc(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) {
- swaps(&rep->sequenceNumber);
- swapl(&rep->length);
- swaps(&rep->x);
- swaps(&rep->y);
- swaps(&rep->width);
- swaps(&rep->height);
- swaps(&rep->xhot);
- swaps(&rep->yhot);
- swapl(&rep->cursorSerial);
- SwapLongs(image, npixels);
- }
- (void) WriteToClient(client, sizeof(xXFixesGetCursorImageReply) +
- (npixels << 2), (char *) rep);
- free(rep);
- return client->noClientException;
- }
- int
- SProcXFixesGetCursorImage(ClientPtr client)
- {
- REQUEST(xXFixesGetCursorImageReq);
- swaps(&stuff->length);
- 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, SecurityWriteAccess);
- 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)
- {
- REQUEST(xXFixesSetCursorNameReq);
- swaps(&stuff->length);
- REQUEST_AT_LEAST_SIZE(xXFixesSetCursorNameReq);
- swapl(&stuff->cursor);
- swaps(&stuff->nbytes);
- return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
- }
- int
- ProcXFixesGetCursorName(ClientPtr client)
- {
- CursorPtr pCursor;
- xXFixesGetCursorNameReply reply;
- REQUEST(xXFixesGetCursorNameReq);
- char *str;
- int len;
- REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq);
- VERIFY_CURSOR(pCursor, stuff->cursor, client, SecurityReadAccess);
- if (pCursor->name)
- str = NameForAtom(pCursor->name);
- else
- str = "";
- len = strlen(str);
- reply.type = X_Reply;
- reply.length = (len + 3) >> 2;
- reply.sequenceNumber = client->sequence;
- reply.atom = pCursor->name;
- reply.nbytes = len;
- if (client->swapped) {
- swaps(&reply.sequenceNumber);
- swapl(&reply.length);
- swapl(&reply.atom);
- swaps(&reply.nbytes);
- }
- WriteReplyToClient(client, sizeof(xXFixesGetCursorNameReply), &reply);
- (void) WriteToClient(client, len, str);
- return (client->noClientException);
- }
- int
- SProcXFixesGetCursorName(ClientPtr client)
- {
- REQUEST(xXFixesGetCursorNameReq);
- swaps(&stuff->length);
- REQUEST_SIZE_MATCH(xXFixesGetCursorNameReq);
- swapl(&stuff->cursor);
- return (*ProcXFixesVector[stuff->xfixesReqType]) (client);
- }
- int
- ProcXFixesGetCursorImageAndName(ClientPtr client)
- {
- /* REQUEST(xXFixesGetCursorImageAndNameReq); */
- xXFixesGetCursorImageAndNameReply *rep;
- CursorPtr pCursor;
- CARD32 *image;
- int npixels;
- char *name;
- int nbytes, nbytesRound;
- int width, height;
- int x, y;
- REQUEST_SIZE_MATCH(xXFixesGetCursorImageAndNameReq);
- pCursor = CursorCurrent;
- if (!pCursor)
- return BadCursor;
- GetSpritePosition(&x, &y);
- width = pCursor->bits->width;
- height = pCursor->bits->height;
- npixels = width * height;
- name = pCursor->name ? NameForAtom(pCursor->name) : "";
- nbytes = strlen(name);
- nbytesRound = (nbytes + 3) & ~3;
- rep = malloc(sizeof(xXFixesGetCursorImageAndNameReply) +
- npixels * sizeof(CARD32) + nbytesRound);
- if (!rep)
- return BadAlloc;
- rep->type = X_Reply;
- rep->sequenceNumber = client->sequence;
- rep->length = npixels + (nbytesRound >> 2);
- 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) {
- swaps(&rep->sequenceNumber);
- swapl(&rep->length);
- swaps(&rep->x);
- swaps(&rep->y);
- swaps(&rep->width);
- swaps(&rep->height);
- swaps(&rep->xhot);
- swaps(&rep->yhot);
- swapl(&rep->cursorSerial);
- swapl(&rep->cursorName);
- swaps(&rep->nbytes);
- SwapLongs(image, npixels);
- }
- (void) WriteToClient(client, sizeof(xXFixesGetCursorImageAndNameReply) +
- (npixels << 2) + nbytesRound, (char *) rep);
- free(rep);
- return client->noClientException;
- }
- int
- SProcXFixesGetCursorImageAndName(ClientPtr client)
- {
- REQUEST(xXFixesGetCursorImageAndNameReq);
- swaps(&stuff->length);
- 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, SecurityReadAccess);
- VERIFY_CURSOR(pDestination, stuff->destination, client,
- SecurityWriteAccess);
- ReplaceCursor(pSource, TestForCursor, (pointer) pDestination);
- return (client->noClientException);
- }
- int
- SProcXFixesChangeCursor(ClientPtr client)
- {
- REQUEST(xXFixesChangeCursorReq);
- swaps(&stuff->length);
- REQUEST_SIZE_MATCH(xXFixesChangeCursorReq);
- swapl(&stuff->source);
- swapl(&stuff->destination);
- 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, SecurityReadAccess);
- tchar = (char *) &stuff[1];
- name = MakeAtom(tchar, stuff->nbytes, FALSE);
- if (name)
- ReplaceCursor(pSource, TestForCursorName, &name);
- return (client->noClientException);
- }
- int
- SProcXFixesChangeCursorByName(ClientPtr client)
- {
- REQUEST(xXFixesChangeCursorByNameReq);
- swaps(&stuff->length);
- REQUEST_AT_LEAST_SIZE(xXFixesChangeCursorByNameReq);
- swapl(&stuff->source);
- swaps(&stuff->nbytes);
- 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 = 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, (pointer) 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(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;
- free(e);
- break;
- }
- }
- return 1;
- }
- static int
- CursorFreeHideCount(pointer data, XID id)
- {
- CursorHideCountPtr pChc = (CursorHideCountPtr) data;
- ScreenPtr pScreen = pChc->pScreen;
- deleteCursorHideCount(pChc, pChc->pScreen);
- (void) CursorDisplayCursor(pScreen, CursorCurrent);
- 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;
- static unsigned int *psrcbits, *pmaskbits;
- CursorMetricRec cm;
- psrcbits = malloc(4);
- pmaskbits = 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)
- {
- int i;
- if (CursorGeneration != serverGeneration) {
- CursorScreenPrivateIndex = AllocateScreenPrivateIndex();
- if (CursorScreenPrivateIndex < 0)
- return FALSE;
- CursorGeneration = serverGeneration;
- }
- for (i = 0; i < screenInfo.numScreens; i++) {
- ScreenPtr pScreen = screenInfo.screens[i];
- CursorScreenPtr cs;
- cs = malloc(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);
- CursorHideCountType = CreateNewResourceType(CursorFreeHideCount);
- CursorWindowType = CreateNewResourceType(CursorFreeWindow);
- if (pInvisibleCursor == NULL) {
- pInvisibleCursor = createInvisibleCursor();
- if (pInvisibleCursor == NULL) {
- return BadAlloc;
- }
- }
- return CursorClientType && CursorWindowType;
- }
|