cursor.c revision 4642e01f
105b261ecSmrg/*********************************************************** 205b261ecSmrg 305b261ecSmrgCopyright 1987, 1998 The Open Group 405b261ecSmrg 505b261ecSmrgPermission to use, copy, modify, distribute, and sell this software and its 605b261ecSmrgdocumentation for any purpose is hereby granted without fee, provided that 705b261ecSmrgthe above copyright notice appear in all copies and that both that 805b261ecSmrgcopyright notice and this permission notice appear in supporting 905b261ecSmrgdocumentation. 1005b261ecSmrg 1105b261ecSmrgThe above copyright notice and this permission notice shall be included in 1205b261ecSmrgall copies or substantial portions of the Software. 1305b261ecSmrg 1405b261ecSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1505b261ecSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1605b261ecSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1705b261ecSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 1805b261ecSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 1905b261ecSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 2005b261ecSmrg 2105b261ecSmrgExcept as contained in this notice, the name of The Open Group shall not be 2205b261ecSmrgused in advertising or otherwise to promote the sale, use or other dealings 2305b261ecSmrgin this Software without prior written authorization from The Open Group. 2405b261ecSmrg 2505b261ecSmrg 2605b261ecSmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 2705b261ecSmrg 2805b261ecSmrg All Rights Reserved 2905b261ecSmrg 3005b261ecSmrgPermission to use, copy, modify, and distribute this software and its 3105b261ecSmrgdocumentation for any purpose and without fee is hereby granted, 3205b261ecSmrgprovided that the above copyright notice appear in all copies and that 3305b261ecSmrgboth that copyright notice and this permission notice appear in 3405b261ecSmrgsupporting documentation, and that the name of Digital not be 3505b261ecSmrgused in advertising or publicity pertaining to distribution of the 3605b261ecSmrgsoftware without specific, written prior permission. 3705b261ecSmrg 3805b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 3905b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 4005b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 4105b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 4205b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 4305b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 4405b261ecSmrgSOFTWARE. 4505b261ecSmrg 4605b261ecSmrg******************************************************************/ 4705b261ecSmrg 4805b261ecSmrg 4905b261ecSmrg 5005b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 5105b261ecSmrg#include <dix-config.h> 5205b261ecSmrg#endif 5305b261ecSmrg 5405b261ecSmrg#include <X11/X.h> 5505b261ecSmrg#include <X11/Xmd.h> 5605b261ecSmrg#include "servermd.h" 5705b261ecSmrg#include "scrnintstr.h" 5805b261ecSmrg#include "dixstruct.h" 5905b261ecSmrg#include "cursorstr.h" 6005b261ecSmrg#include "dixfontstr.h" 6105b261ecSmrg#include "opaque.h" 624642e01fSmrg#include "inputstr.h" 634642e01fSmrg#include "xace.h" 6405b261ecSmrg 6505b261ecSmrgtypedef struct _GlyphShare { 6605b261ecSmrg FontPtr font; 6705b261ecSmrg unsigned short sourceChar; 6805b261ecSmrg unsigned short maskChar; 6905b261ecSmrg CursorBitsPtr bits; 7005b261ecSmrg struct _GlyphShare *next; 7105b261ecSmrg} GlyphShare, *GlyphSharePtr; 7205b261ecSmrg 7305b261ecSmrgstatic GlyphSharePtr sharedGlyphs = (GlyphSharePtr)NULL; 7405b261ecSmrg 7505b261ecSmrg#ifdef XFIXES 7605b261ecSmrgstatic CARD32 cursorSerial; 7705b261ecSmrg#endif 7805b261ecSmrg 7905b261ecSmrgstatic void 8005b261ecSmrgFreeCursorBits(CursorBitsPtr bits) 8105b261ecSmrg{ 8205b261ecSmrg if (--bits->refcnt > 0) 8305b261ecSmrg return; 8405b261ecSmrg xfree(bits->source); 8505b261ecSmrg xfree(bits->mask); 8605b261ecSmrg#ifdef ARGB_CURSOR 8705b261ecSmrg xfree(bits->argb); 8805b261ecSmrg#endif 8905b261ecSmrg if (bits->refcnt == 0) 9005b261ecSmrg { 9105b261ecSmrg GlyphSharePtr *prev, this; 9205b261ecSmrg 9305b261ecSmrg for (prev = &sharedGlyphs; 9405b261ecSmrg (this = *prev) && (this->bits != bits); 9505b261ecSmrg prev = &this->next) 9605b261ecSmrg ; 9705b261ecSmrg if (this) 9805b261ecSmrg { 9905b261ecSmrg *prev = this->next; 10005b261ecSmrg CloseFont(this->font, (Font)0); 10105b261ecSmrg xfree(this); 10205b261ecSmrg } 1034642e01fSmrg dixFreePrivates(bits->devPrivates); 10405b261ecSmrg xfree(bits); 10505b261ecSmrg } 10605b261ecSmrg} 10705b261ecSmrg 10805b261ecSmrg/** 10905b261ecSmrg * To be called indirectly by DeleteResource; must use exactly two args. 11005b261ecSmrg * 11105b261ecSmrg * \param value must conform to DeleteType 11205b261ecSmrg */ 11305b261ecSmrg_X_EXPORT int 11405b261ecSmrgFreeCursor(pointer value, XID cid) 11505b261ecSmrg{ 11605b261ecSmrg int nscr; 11705b261ecSmrg CursorPtr pCurs = (CursorPtr)value; 11805b261ecSmrg 11905b261ecSmrg ScreenPtr pscr; 1204642e01fSmrg DeviceIntPtr pDev = NULL; /* unused anyway */ 12105b261ecSmrg 1224642e01fSmrg if ( --pCurs->refcnt != 0) 12305b261ecSmrg return(Success); 12405b261ecSmrg 12505b261ecSmrg for (nscr = 0; nscr < screenInfo.numScreens; nscr++) 12605b261ecSmrg { 12705b261ecSmrg pscr = screenInfo.screens[nscr]; 1284642e01fSmrg (void)( *pscr->UnrealizeCursor)(pDev, pscr, pCurs); 12905b261ecSmrg } 1304642e01fSmrg dixFreePrivates(pCurs->devPrivates); 13105b261ecSmrg FreeCursorBits(pCurs->bits); 13205b261ecSmrg xfree( pCurs); 13305b261ecSmrg return(Success); 13405b261ecSmrg} 13505b261ecSmrg 13605b261ecSmrg 13705b261ecSmrg/* 13805b261ecSmrg * We check for empty cursors so that we won't have to display them 13905b261ecSmrg */ 14005b261ecSmrgstatic void 14105b261ecSmrgCheckForEmptyMask(CursorBitsPtr bits) 14205b261ecSmrg{ 14305b261ecSmrg unsigned char *msk = bits->mask; 14405b261ecSmrg int n = BitmapBytePad(bits->width) * bits->height; 14505b261ecSmrg 14605b261ecSmrg bits->emptyMask = FALSE; 14705b261ecSmrg while(n--) 14805b261ecSmrg if(*(msk++) != 0) return; 14905b261ecSmrg#ifdef ARGB_CURSOR 15005b261ecSmrg if (bits->argb) 15105b261ecSmrg { 15205b261ecSmrg CARD32 *argb = bits->argb; 15305b261ecSmrg int n = bits->width * bits->height; 15405b261ecSmrg while (n--) 15505b261ecSmrg if (*argb++ & 0xff000000) return; 15605b261ecSmrg } 15705b261ecSmrg#endif 15805b261ecSmrg bits->emptyMask = TRUE; 15905b261ecSmrg} 16005b261ecSmrg 16105b261ecSmrg/** 16205b261ecSmrg * does nothing about the resource table, just creates the data structure. 16305b261ecSmrg * does not copy the src and mask bits 16405b261ecSmrg * 16505b261ecSmrg * \param psrcbits server-defined padding 16605b261ecSmrg * \param pmaskbits server-defined padding 16705b261ecSmrg * \param argb no padding 16805b261ecSmrg */ 1694642e01fSmrgint 1704642e01fSmrgAllocARGBCursor(unsigned char *psrcbits, unsigned char *pmaskbits, 1714642e01fSmrg CARD32 *argb, CursorMetricPtr cm, 1724642e01fSmrg unsigned foreRed, unsigned foreGreen, unsigned foreBlue, 1734642e01fSmrg unsigned backRed, unsigned backGreen, unsigned backBlue, 1744642e01fSmrg CursorPtr *ppCurs, ClientPtr client, XID cid) 17505b261ecSmrg{ 17605b261ecSmrg CursorBitsPtr bits; 17705b261ecSmrg CursorPtr pCurs; 1784642e01fSmrg int rc, nscr; 17905b261ecSmrg ScreenPtr pscr; 1804642e01fSmrg DeviceIntPtr pDev; 18105b261ecSmrg 1824642e01fSmrg *ppCurs = NULL; 1834642e01fSmrg pCurs = (CursorPtr)xcalloc(sizeof(CursorRec) + sizeof(CursorBits), 1); 18405b261ecSmrg if (!pCurs) 18505b261ecSmrg { 18605b261ecSmrg xfree(psrcbits); 18705b261ecSmrg xfree(pmaskbits); 1884642e01fSmrg return BadAlloc; 18905b261ecSmrg } 19005b261ecSmrg bits = (CursorBitsPtr)((char *)pCurs + sizeof(CursorRec)); 19105b261ecSmrg bits->source = psrcbits; 19205b261ecSmrg bits->mask = pmaskbits; 19305b261ecSmrg#ifdef ARGB_CURSOR 19405b261ecSmrg bits->argb = argb; 19505b261ecSmrg#endif 19605b261ecSmrg bits->width = cm->width; 19705b261ecSmrg bits->height = cm->height; 19805b261ecSmrg bits->xhot = cm->xhot; 19905b261ecSmrg bits->yhot = cm->yhot; 2004642e01fSmrg pCurs->refcnt = 1; 2014642e01fSmrg bits->devPrivates = NULL; 20205b261ecSmrg bits->refcnt = -1; 20305b261ecSmrg CheckForEmptyMask(bits); 20405b261ecSmrg pCurs->bits = bits; 20505b261ecSmrg#ifdef XFIXES 20605b261ecSmrg pCurs->serialNumber = ++cursorSerial; 20705b261ecSmrg pCurs->name = None; 20805b261ecSmrg#endif 20905b261ecSmrg 21005b261ecSmrg pCurs->foreRed = foreRed; 21105b261ecSmrg pCurs->foreGreen = foreGreen; 21205b261ecSmrg pCurs->foreBlue = foreBlue; 21305b261ecSmrg 21405b261ecSmrg pCurs->backRed = backRed; 21505b261ecSmrg pCurs->backGreen = backGreen; 21605b261ecSmrg pCurs->backBlue = backBlue; 21705b261ecSmrg 2184642e01fSmrg pCurs->id = cid; 2194642e01fSmrg pCurs->devPrivates = NULL; 2204642e01fSmrg 2214642e01fSmrg /* security creation/labeling check */ 2224642e01fSmrg rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR, 2234642e01fSmrg pCurs, RT_NONE, NULL, DixCreateAccess); 2244642e01fSmrg if (rc != Success) { 2254642e01fSmrg dixFreePrivates(pCurs->devPrivates); 2264642e01fSmrg FreeCursorBits(bits); 2274642e01fSmrg xfree(pCurs); 2284642e01fSmrg return rc; 2294642e01fSmrg } 2304642e01fSmrg 23105b261ecSmrg /* 23205b261ecSmrg * realize the cursor for every screen 2334642e01fSmrg * Do not change the refcnt, this will be changed when ChangeToCursor 2344642e01fSmrg * actually changes the sprite. 23505b261ecSmrg */ 23605b261ecSmrg for (nscr = 0; nscr < screenInfo.numScreens; nscr++) 23705b261ecSmrg { 2384642e01fSmrg pscr = screenInfo.screens[nscr]; 2394642e01fSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) 2404642e01fSmrg { 2414642e01fSmrg if (DevHasCursor(pDev)) 2424642e01fSmrg { 2434642e01fSmrg if (!( *pscr->RealizeCursor)(pDev, pscr, pCurs)) 2444642e01fSmrg { 2454642e01fSmrg /* Realize failed for device pDev on screen pscr. 2464642e01fSmrg * We have to assume that for all devices before, realize 2474642e01fSmrg * worked. We need to rollback all devices so far on the 2484642e01fSmrg * current screen and then all devices on previous 2494642e01fSmrg * screens. 2504642e01fSmrg */ 2514642e01fSmrg DeviceIntPtr pDevIt = inputInfo.devices; /*dev iterator*/ 2524642e01fSmrg while(pDevIt && pDevIt != pDev) 2534642e01fSmrg { 2544642e01fSmrg if (DevHasCursor(pDevIt)) 2554642e01fSmrg ( *pscr->UnrealizeCursor)(pDevIt, pscr, pCurs); 2564642e01fSmrg pDevIt = pDevIt->next; 2574642e01fSmrg } 2584642e01fSmrg while (--nscr >= 0) 2594642e01fSmrg { 2604642e01fSmrg pscr = screenInfo.screens[nscr]; 2614642e01fSmrg /* now unrealize all devices on previous screens */ 2624642e01fSmrg pDevIt = inputInfo.devices; 2634642e01fSmrg while (pDevIt) 2644642e01fSmrg { 2654642e01fSmrg if (DevHasCursor(pDevIt)) 2664642e01fSmrg ( *pscr->UnrealizeCursor)(pDevIt, pscr, pCurs); 2674642e01fSmrg pDevIt = pDevIt->next; 2684642e01fSmrg } 2694642e01fSmrg ( *pscr->UnrealizeCursor)(pDev, pscr, pCurs); 2704642e01fSmrg } 2714642e01fSmrg dixFreePrivates(pCurs->devPrivates); 2724642e01fSmrg FreeCursorBits(bits); 2734642e01fSmrg xfree(pCurs); 2744642e01fSmrg return BadAlloc; 2754642e01fSmrg } 2764642e01fSmrg } 2774642e01fSmrg } 27805b261ecSmrg } 2794642e01fSmrg *ppCurs = pCurs; 2804642e01fSmrg return rc; 28105b261ecSmrg} 28205b261ecSmrg 28305b261ecSmrgint 28405b261ecSmrgAllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar, 28505b261ecSmrg unsigned foreRed, unsigned foreGreen, unsigned foreBlue, 28605b261ecSmrg unsigned backRed, unsigned backGreen, unsigned backBlue, 2874642e01fSmrg CursorPtr *ppCurs, ClientPtr client, XID cid) 28805b261ecSmrg{ 28905b261ecSmrg FontPtr sourcefont, maskfont; 29005b261ecSmrg unsigned char *srcbits; 29105b261ecSmrg unsigned char *mskbits; 29205b261ecSmrg CursorMetricRec cm; 2934642e01fSmrg int rc; 29405b261ecSmrg CursorBitsPtr bits; 29505b261ecSmrg CursorPtr pCurs; 29605b261ecSmrg int nscr; 29705b261ecSmrg ScreenPtr pscr; 29805b261ecSmrg GlyphSharePtr pShare; 2994642e01fSmrg DeviceIntPtr pDev; 30005b261ecSmrg 3014642e01fSmrg rc = dixLookupResource((pointer *)&sourcefont, source, RT_FONT, client, 3024642e01fSmrg DixUseAccess); 3034642e01fSmrg if (rc != Success) 30405b261ecSmrg { 30505b261ecSmrg client->errorValue = source; 3064642e01fSmrg return (rc == BadValue) ? BadFont : rc; 30705b261ecSmrg } 3084642e01fSmrg rc = dixLookupResource((pointer *)&maskfont, mask, RT_FONT, client, 3094642e01fSmrg DixUseAccess); 3104642e01fSmrg if (rc != Success && mask != None) 31105b261ecSmrg { 31205b261ecSmrg client->errorValue = mask; 3134642e01fSmrg return (rc == BadValue) ? BadFont : rc; 31405b261ecSmrg } 31505b261ecSmrg if (sourcefont != maskfont) 31605b261ecSmrg pShare = (GlyphSharePtr)NULL; 31705b261ecSmrg else 31805b261ecSmrg { 31905b261ecSmrg for (pShare = sharedGlyphs; 32005b261ecSmrg pShare && 32105b261ecSmrg ((pShare->font != sourcefont) || 32205b261ecSmrg (pShare->sourceChar != sourceChar) || 32305b261ecSmrg (pShare->maskChar != maskChar)); 32405b261ecSmrg pShare = pShare->next) 32505b261ecSmrg ; 32605b261ecSmrg } 32705b261ecSmrg if (pShare) 32805b261ecSmrg { 3294642e01fSmrg pCurs = (CursorPtr)xcalloc(sizeof(CursorRec), 1); 33005b261ecSmrg if (!pCurs) 33105b261ecSmrg return BadAlloc; 33205b261ecSmrg bits = pShare->bits; 33305b261ecSmrg bits->refcnt++; 33405b261ecSmrg } 33505b261ecSmrg else 33605b261ecSmrg { 33705b261ecSmrg if (!CursorMetricsFromGlyph(sourcefont, sourceChar, &cm)) 33805b261ecSmrg { 33905b261ecSmrg client->errorValue = sourceChar; 34005b261ecSmrg return BadValue; 34105b261ecSmrg } 34205b261ecSmrg if (!maskfont) 34305b261ecSmrg { 34405b261ecSmrg long n; 34505b261ecSmrg unsigned char *mskptr; 34605b261ecSmrg 34705b261ecSmrg n = BitmapBytePad(cm.width)*(long)cm.height; 34805b261ecSmrg mskptr = mskbits = (unsigned char *)xalloc(n); 34905b261ecSmrg if (!mskptr) 35005b261ecSmrg return BadAlloc; 35105b261ecSmrg while (--n >= 0) 35205b261ecSmrg *mskptr++ = ~0; 35305b261ecSmrg } 35405b261ecSmrg else 35505b261ecSmrg { 35605b261ecSmrg if (!CursorMetricsFromGlyph(maskfont, maskChar, &cm)) 35705b261ecSmrg { 35805b261ecSmrg client->errorValue = maskChar; 35905b261ecSmrg return BadValue; 36005b261ecSmrg } 3614642e01fSmrg if ((rc = ServerBitsFromGlyph(maskfont, maskChar, &cm, &mskbits))) 3624642e01fSmrg return rc; 36305b261ecSmrg } 3644642e01fSmrg if ((rc = ServerBitsFromGlyph(sourcefont, sourceChar, &cm, &srcbits))) 36505b261ecSmrg { 36605b261ecSmrg xfree(mskbits); 3674642e01fSmrg return rc; 36805b261ecSmrg } 36905b261ecSmrg if (sourcefont != maskfont) 37005b261ecSmrg { 3714642e01fSmrg pCurs = 3724642e01fSmrg (CursorPtr)xcalloc(sizeof(CursorRec) + sizeof(CursorBits), 1); 37305b261ecSmrg if (pCurs) 37405b261ecSmrg bits = (CursorBitsPtr)((char *)pCurs + sizeof(CursorRec)); 37505b261ecSmrg else 37605b261ecSmrg bits = (CursorBitsPtr)NULL; 37705b261ecSmrg } 37805b261ecSmrg else 37905b261ecSmrg { 3804642e01fSmrg pCurs = (CursorPtr)xcalloc(sizeof(CursorRec), 1); 38105b261ecSmrg if (pCurs) 3824642e01fSmrg bits = (CursorBitsPtr)xcalloc(sizeof(CursorBits), 1); 38305b261ecSmrg else 38405b261ecSmrg bits = (CursorBitsPtr)NULL; 38505b261ecSmrg } 38605b261ecSmrg if (!bits) 38705b261ecSmrg { 38805b261ecSmrg xfree(pCurs); 38905b261ecSmrg xfree(mskbits); 39005b261ecSmrg xfree(srcbits); 39105b261ecSmrg return BadAlloc; 39205b261ecSmrg } 39305b261ecSmrg bits->source = srcbits; 39405b261ecSmrg bits->mask = mskbits; 39505b261ecSmrg#ifdef ARGB_CURSOR 39605b261ecSmrg bits->argb = 0; 39705b261ecSmrg#endif 39805b261ecSmrg bits->width = cm.width; 39905b261ecSmrg bits->height = cm.height; 40005b261ecSmrg bits->xhot = cm.xhot; 40105b261ecSmrg bits->yhot = cm.yhot; 4024642e01fSmrg bits->devPrivates = NULL; 40305b261ecSmrg if (sourcefont != maskfont) 40405b261ecSmrg bits->refcnt = -1; 40505b261ecSmrg else 40605b261ecSmrg { 40705b261ecSmrg bits->refcnt = 1; 40805b261ecSmrg pShare = (GlyphSharePtr)xalloc(sizeof(GlyphShare)); 40905b261ecSmrg if (!pShare) 41005b261ecSmrg { 41105b261ecSmrg FreeCursorBits(bits); 41205b261ecSmrg return BadAlloc; 41305b261ecSmrg } 41405b261ecSmrg pShare->font = sourcefont; 41505b261ecSmrg sourcefont->refcnt++; 41605b261ecSmrg pShare->sourceChar = sourceChar; 41705b261ecSmrg pShare->maskChar = maskChar; 41805b261ecSmrg pShare->bits = bits; 41905b261ecSmrg pShare->next = sharedGlyphs; 42005b261ecSmrg sharedGlyphs = pShare; 42105b261ecSmrg } 42205b261ecSmrg } 4234642e01fSmrg 42405b261ecSmrg CheckForEmptyMask(bits); 42505b261ecSmrg pCurs->bits = bits; 42605b261ecSmrg pCurs->refcnt = 1; 42705b261ecSmrg#ifdef XFIXES 42805b261ecSmrg pCurs->serialNumber = ++cursorSerial; 42905b261ecSmrg pCurs->name = None; 43005b261ecSmrg#endif 43105b261ecSmrg 43205b261ecSmrg pCurs->foreRed = foreRed; 43305b261ecSmrg pCurs->foreGreen = foreGreen; 43405b261ecSmrg pCurs->foreBlue = foreBlue; 43505b261ecSmrg 43605b261ecSmrg pCurs->backRed = backRed; 43705b261ecSmrg pCurs->backGreen = backGreen; 43805b261ecSmrg pCurs->backBlue = backBlue; 43905b261ecSmrg 4404642e01fSmrg pCurs->id = cid; 4414642e01fSmrg pCurs->devPrivates = NULL; 4424642e01fSmrg 4434642e01fSmrg /* security creation/labeling check */ 4444642e01fSmrg rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR, 4454642e01fSmrg pCurs, RT_NONE, NULL, DixCreateAccess); 4464642e01fSmrg if (rc != Success) { 4474642e01fSmrg dixFreePrivates(pCurs->devPrivates); 4484642e01fSmrg FreeCursorBits(bits); 4494642e01fSmrg xfree(pCurs); 4504642e01fSmrg return rc; 4514642e01fSmrg } 4524642e01fSmrg 45305b261ecSmrg /* 45405b261ecSmrg * realize the cursor for every screen 45505b261ecSmrg */ 45605b261ecSmrg for (nscr = 0; nscr < screenInfo.numScreens; nscr++) 45705b261ecSmrg { 4584642e01fSmrg pscr = screenInfo.screens[nscr]; 4594642e01fSmrg 4604642e01fSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) 4614642e01fSmrg { 4624642e01fSmrg if (DevHasCursor(pDev)) 4634642e01fSmrg { 4644642e01fSmrg if (!( *pscr->RealizeCursor)(pDev, pscr, pCurs)) 4654642e01fSmrg { 4664642e01fSmrg /* Realize failed for device pDev on screen pscr. 4674642e01fSmrg * We have to assume that for all devices before, realize 4684642e01fSmrg * worked. We need to rollback all devices so far on the 4694642e01fSmrg * current screen and then all devices on previous 4704642e01fSmrg * screens. 4714642e01fSmrg */ 4724642e01fSmrg DeviceIntPtr pDevIt = inputInfo.devices; /*dev iterator*/ 4734642e01fSmrg while(pDevIt && pDevIt != pDev) 4744642e01fSmrg { 4754642e01fSmrg if (DevHasCursor(pDevIt)) 4764642e01fSmrg ( *pscr->UnrealizeCursor)(pDevIt, pscr, pCurs); 4774642e01fSmrg pDevIt = pDevIt->next; 4784642e01fSmrg } 4794642e01fSmrg 4804642e01fSmrg (*pscr->UnrealizeCursor)(inputInfo.pointer, pscr, pCurs); 4814642e01fSmrg 4824642e01fSmrg while (--nscr >= 0) 4834642e01fSmrg { 4844642e01fSmrg pscr = screenInfo.screens[nscr]; 4854642e01fSmrg /* now unrealize all devices on previous screens */ 4864642e01fSmrg ( *pscr->UnrealizeCursor)(inputInfo.pointer, pscr, pCurs); 4874642e01fSmrg 4884642e01fSmrg pDevIt = inputInfo.devices; 4894642e01fSmrg while (pDevIt) 4904642e01fSmrg { 4914642e01fSmrg if (DevHasCursor(pDevIt)) 4924642e01fSmrg ( *pscr->UnrealizeCursor)(pDevIt, pscr, pCurs); 4934642e01fSmrg pDevIt = pDevIt->next; 4944642e01fSmrg } 4954642e01fSmrg ( *pscr->UnrealizeCursor)(pDev, pscr, pCurs); 4964642e01fSmrg } 4974642e01fSmrg dixFreePrivates(pCurs->devPrivates); 4984642e01fSmrg FreeCursorBits(bits); 4994642e01fSmrg xfree(pCurs); 5004642e01fSmrg return BadAlloc; 5014642e01fSmrg } 5024642e01fSmrg } 5034642e01fSmrg } 50405b261ecSmrg } 50505b261ecSmrg *ppCurs = pCurs; 50605b261ecSmrg return Success; 50705b261ecSmrg} 50805b261ecSmrg 50905b261ecSmrg/** CreateRootCursor 51005b261ecSmrg * 51105b261ecSmrg * look up the name of a font 51205b261ecSmrg * open the font 51305b261ecSmrg * add the font to the resource table 51405b261ecSmrg * make a cursor from the glyphs 51505b261ecSmrg * add the cursor to the resource table 51605b261ecSmrg *************************************************************/ 51705b261ecSmrg 51805b261ecSmrgCursorPtr 51905b261ecSmrgCreateRootCursor(char *unused1, unsigned int unused2) 52005b261ecSmrg{ 52105b261ecSmrg CursorPtr curs; 52205b261ecSmrg#ifdef NULL_ROOT_CURSOR 52305b261ecSmrg CursorMetricRec cm; 52405b261ecSmrg#else 52505b261ecSmrg FontPtr cursorfont; 52605b261ecSmrg int err; 52705b261ecSmrg XID fontID; 52805b261ecSmrg#endif 52905b261ecSmrg 53005b261ecSmrg#ifdef NULL_ROOT_CURSOR 53105b261ecSmrg cm.width = 0; 53205b261ecSmrg cm.height = 0; 53305b261ecSmrg cm.xhot = 0; 53405b261ecSmrg cm.yhot = 0; 53505b261ecSmrg 5364642e01fSmrg AllocARGBCursor(NULL, NULL, NULL, &cm, 0, 0, 0, 0, 0, 0, 5374642e01fSmrg &curs, serverClient, (XID)0); 53805b261ecSmrg 53905b261ecSmrg if (curs == NullCursor) 54005b261ecSmrg return NullCursor; 54105b261ecSmrg#else 54205b261ecSmrg fontID = FakeClientID(0); 54305b261ecSmrg err = OpenFont(serverClient, fontID, FontLoadAll | FontOpenSync, 54405b261ecSmrg (unsigned)strlen(defaultCursorFont), defaultCursorFont); 54505b261ecSmrg if (err != Success) 54605b261ecSmrg return NullCursor; 54705b261ecSmrg 54805b261ecSmrg cursorfont = (FontPtr)LookupIDByType(fontID, RT_FONT); 54905b261ecSmrg if (!cursorfont) 55005b261ecSmrg return NullCursor; 5514642e01fSmrg if (AllocGlyphCursor(fontID, 0, fontID, 1, 0, 0, 0, ~0, ~0, ~0, 5524642e01fSmrg &curs, serverClient, (XID)0) != Success) 55305b261ecSmrg return NullCursor; 55405b261ecSmrg#endif 55505b261ecSmrg 55605b261ecSmrg if (!AddResource(FakeClientID(0), RT_CURSOR, (pointer)curs)) 55705b261ecSmrg return NullCursor; 55805b261ecSmrg 55905b261ecSmrg return curs; 56005b261ecSmrg} 561