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 2505b261ecSmrgCopyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. 2605b261ecSmrg 2705b261ecSmrg All Rights Reserved 2805b261ecSmrg 2935c4bbdfSmrgPermission to use, copy, modify, and distribute this software and its 3035c4bbdfSmrgdocumentation for any purpose and without fee is hereby granted, 3105b261ecSmrgprovided that the above copyright notice appear in all copies and that 3235c4bbdfSmrgboth that copyright notice and this permission notice appear in 3305b261ecSmrgsupporting documentation, and that the name of Digital not be 3405b261ecSmrgused in advertising or publicity pertaining to distribution of the 3535c4bbdfSmrgsoftware without specific, written prior permission. 3605b261ecSmrg 3705b261ecSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 3805b261ecSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 3905b261ecSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 4005b261ecSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 4105b261ecSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 4205b261ecSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 4305b261ecSmrgSOFTWARE. 4405b261ecSmrg 4505b261ecSmrg******************************************************************/ 4605b261ecSmrg 4705b261ecSmrg#ifdef HAVE_DIX_CONFIG_H 4805b261ecSmrg#include <dix-config.h> 4905b261ecSmrg#endif 5005b261ecSmrg 5105b261ecSmrg#include <X11/X.h> 5205b261ecSmrg#include <X11/Xmd.h> 5305b261ecSmrg#include "servermd.h" 5405b261ecSmrg#include "scrnintstr.h" 5505b261ecSmrg#include "dixstruct.h" 5605b261ecSmrg#include "cursorstr.h" 5705b261ecSmrg#include "dixfontstr.h" 5805b261ecSmrg#include "opaque.h" 594642e01fSmrg#include "inputstr.h" 604642e01fSmrg#include "xace.h" 6105b261ecSmrg 6205b261ecSmrgtypedef struct _GlyphShare { 6305b261ecSmrg FontPtr font; 6405b261ecSmrg unsigned short sourceChar; 6505b261ecSmrg unsigned short maskChar; 6605b261ecSmrg CursorBitsPtr bits; 6705b261ecSmrg struct _GlyphShare *next; 6805b261ecSmrg} GlyphShare, *GlyphSharePtr; 6905b261ecSmrg 7035c4bbdfSmrgstatic GlyphSharePtr sharedGlyphs = (GlyphSharePtr) NULL; 7105b261ecSmrg 7235c4bbdfSmrgDevScreenPrivateKeyRec cursorScreenDevPriv; 736747b715Smrg 7435c4bbdfSmrgstatic CARD32 cursorSerial; 7505b261ecSmrg 7605b261ecSmrgstatic void 7705b261ecSmrgFreeCursorBits(CursorBitsPtr bits) 7805b261ecSmrg{ 7905b261ecSmrg if (--bits->refcnt > 0) 8035c4bbdfSmrg return; 816747b715Smrg free(bits->source); 826747b715Smrg free(bits->mask); 836747b715Smrg free(bits->argb); 846747b715Smrg dixFiniPrivates(bits, PRIVATE_CURSOR_BITS); 8535c4bbdfSmrg if (bits->refcnt == 0) { 8635c4bbdfSmrg GlyphSharePtr *prev, this; 8735c4bbdfSmrg 8835c4bbdfSmrg for (prev = &sharedGlyphs; 8935c4bbdfSmrg (this = *prev) && (this->bits != bits); prev = &this->next); 9035c4bbdfSmrg if (this) { 9135c4bbdfSmrg *prev = this->next; 9235c4bbdfSmrg CloseFont(this->font, (Font) 0); 9335c4bbdfSmrg free(this); 9435c4bbdfSmrg } 9535c4bbdfSmrg free(bits); 9605b261ecSmrg } 9705b261ecSmrg} 9805b261ecSmrg 9905b261ecSmrg/** 10005b261ecSmrg * To be called indirectly by DeleteResource; must use exactly two args. 10105b261ecSmrg * 10205b261ecSmrg * \param value must conform to DeleteType 10305b261ecSmrg */ 1046747b715Smrgint 10535c4bbdfSmrgFreeCursor(void *value, XID cid) 10605b261ecSmrg{ 10735c4bbdfSmrg int nscr; 10835c4bbdfSmrg CursorPtr pCurs = (CursorPtr) value; 10935c4bbdfSmrg 11035c4bbdfSmrg ScreenPtr pscr; 11135c4bbdfSmrg DeviceIntPtr pDev = NULL; /* unused anyway */ 11205b261ecSmrg 11305b261ecSmrg 11435c4bbdfSmrg UnrefCursor(pCurs); 11535c4bbdfSmrg if (CursorRefCount(pCurs) != 0) 11635c4bbdfSmrg return Success; 11705b261ecSmrg 11835c4bbdfSmrg BUG_WARN(CursorRefCount(pCurs) < 0); 11935c4bbdfSmrg 12035c4bbdfSmrg for (nscr = 0; nscr < screenInfo.numScreens; nscr++) { 12135c4bbdfSmrg pscr = screenInfo.screens[nscr]; 12235c4bbdfSmrg (void) (*pscr->UnrealizeCursor) (pDev, pscr, pCurs); 12305b261ecSmrg } 12405b261ecSmrg FreeCursorBits(pCurs->bits); 1256747b715Smrg dixFiniPrivates(pCurs, PRIVATE_CURSOR); 12635c4bbdfSmrg free(pCurs); 1276747b715Smrg return Success; 12805b261ecSmrg} 12905b261ecSmrg 13035c4bbdfSmrgCursorPtr 13135c4bbdfSmrgRefCursor(CursorPtr cursor) 13235c4bbdfSmrg{ 13335c4bbdfSmrg if (cursor) 13435c4bbdfSmrg cursor->refcnt++; 13535c4bbdfSmrg return cursor; 13635c4bbdfSmrg} 13735c4bbdfSmrg 13835c4bbdfSmrgCursorPtr 13935c4bbdfSmrgUnrefCursor(CursorPtr cursor) 14035c4bbdfSmrg{ 14135c4bbdfSmrg if (cursor) 14235c4bbdfSmrg cursor->refcnt--; 14335c4bbdfSmrg return cursor; 14435c4bbdfSmrg} 14535c4bbdfSmrg 14635c4bbdfSmrgint 14735c4bbdfSmrgCursorRefCount(const CursorPtr cursor) 14835c4bbdfSmrg{ 14935c4bbdfSmrg return cursor ? cursor->refcnt : 0; 15035c4bbdfSmrg} 15135c4bbdfSmrg 15205b261ecSmrg 15305b261ecSmrg/* 15405b261ecSmrg * We check for empty cursors so that we won't have to display them 15505b261ecSmrg */ 15605b261ecSmrgstatic void 15705b261ecSmrgCheckForEmptyMask(CursorBitsPtr bits) 15805b261ecSmrg{ 15905b261ecSmrg unsigned char *msk = bits->mask; 16005b261ecSmrg int n = BitmapBytePad(bits->width) * bits->height; 16105b261ecSmrg 16205b261ecSmrg bits->emptyMask = FALSE; 16335c4bbdfSmrg while (n--) 16435c4bbdfSmrg if (*(msk++) != 0) 16535c4bbdfSmrg return; 16635c4bbdfSmrg if (bits->argb) { 16735c4bbdfSmrg CARD32 *argb = bits->argb; 16835c4bbdfSmrg 16935c4bbdfSmrg n = bits->width * bits->height; 17035c4bbdfSmrg while (n--) 17135c4bbdfSmrg if (*argb++ & 0xff000000) 17235c4bbdfSmrg return; 17305b261ecSmrg } 17405b261ecSmrg bits->emptyMask = TRUE; 17505b261ecSmrg} 17605b261ecSmrg 1776747b715Smrg/** 1786747b715Smrg * realize the cursor for every screen. Do not change the refcnt, this will be 1796747b715Smrg * changed when ChangeToCursor actually changes the sprite. 1806747b715Smrg * 1816747b715Smrg * @return Success if all cursors realize on all screens, BadAlloc if realize 1826747b715Smrg * failed for a device on a given screen. 1836747b715Smrg */ 1846747b715Smrgstatic int 1856747b715SmrgRealizeCursorAllScreens(CursorPtr pCurs) 1866747b715Smrg{ 1876747b715Smrg DeviceIntPtr pDev; 18835c4bbdfSmrg ScreenPtr pscr; 1896747b715Smrg int nscr; 1906747b715Smrg 19135c4bbdfSmrg for (nscr = 0; nscr < screenInfo.numScreens; nscr++) { 1926747b715Smrg pscr = screenInfo.screens[nscr]; 19335c4bbdfSmrg for (pDev = inputInfo.devices; pDev; pDev = pDev->next) { 19435c4bbdfSmrg if (DevHasCursor(pDev)) { 19535c4bbdfSmrg if (!(*pscr->RealizeCursor) (pDev, pscr, pCurs)) { 1966747b715Smrg /* Realize failed for device pDev on screen pscr. 1976747b715Smrg * We have to assume that for all devices before, realize 1986747b715Smrg * worked. We need to rollback all devices so far on the 1996747b715Smrg * current screen and then all devices on previous 2006747b715Smrg * screens. 2016747b715Smrg */ 20235c4bbdfSmrg DeviceIntPtr pDevIt = inputInfo.devices; /*dev iterator */ 20335c4bbdfSmrg 20435c4bbdfSmrg while (pDevIt && pDevIt != pDev) { 2056747b715Smrg if (DevHasCursor(pDevIt)) 20635c4bbdfSmrg (*pscr->UnrealizeCursor) (pDevIt, pscr, pCurs); 2076747b715Smrg pDevIt = pDevIt->next; 2086747b715Smrg } 20935c4bbdfSmrg while (--nscr >= 0) { 2106747b715Smrg pscr = screenInfo.screens[nscr]; 2116747b715Smrg /* now unrealize all devices on previous screens */ 2126747b715Smrg pDevIt = inputInfo.devices; 21335c4bbdfSmrg while (pDevIt) { 2146747b715Smrg if (DevHasCursor(pDevIt)) 21535c4bbdfSmrg (*pscr->UnrealizeCursor) (pDevIt, pscr, pCurs); 2166747b715Smrg pDevIt = pDevIt->next; 2176747b715Smrg } 21835c4bbdfSmrg (*pscr->UnrealizeCursor) (pDev, pscr, pCurs); 2196747b715Smrg } 2206747b715Smrg return BadAlloc; 2216747b715Smrg } 2226747b715Smrg } 2236747b715Smrg } 2246747b715Smrg } 2256747b715Smrg 2266747b715Smrg return Success; 2276747b715Smrg} 2286747b715Smrg 22905b261ecSmrg/** 23005b261ecSmrg * does nothing about the resource table, just creates the data structure. 23105b261ecSmrg * does not copy the src and mask bits 23205b261ecSmrg * 23305b261ecSmrg * \param psrcbits server-defined padding 23405b261ecSmrg * \param pmaskbits server-defined padding 23505b261ecSmrg * \param argb no padding 23605b261ecSmrg */ 2374642e01fSmrgint 2384642e01fSmrgAllocARGBCursor(unsigned char *psrcbits, unsigned char *pmaskbits, 23935c4bbdfSmrg CARD32 *argb, CursorMetricPtr cm, 24035c4bbdfSmrg unsigned foreRed, unsigned foreGreen, unsigned foreBlue, 24135c4bbdfSmrg unsigned backRed, unsigned backGreen, unsigned backBlue, 24235c4bbdfSmrg CursorPtr *ppCurs, ClientPtr client, XID cid) 24305b261ecSmrg{ 24435c4bbdfSmrg CursorBitsPtr bits; 24535c4bbdfSmrg CursorPtr pCurs; 2466747b715Smrg int rc; 24705b261ecSmrg 2484642e01fSmrg *ppCurs = NULL; 24935c4bbdfSmrg pCurs = (CursorPtr) calloc(CURSOR_REC_SIZE + CURSOR_BITS_SIZE, 1); 25005b261ecSmrg if (!pCurs) 25135c4bbdfSmrg return BadAlloc; 25235c4bbdfSmrg 25335c4bbdfSmrg bits = (CursorBitsPtr) ((char *) pCurs + CURSOR_REC_SIZE); 2546747b715Smrg dixInitPrivates(pCurs, pCurs + 1, PRIVATE_CURSOR); 2556747b715Smrg dixInitPrivates(bits, bits + 1, PRIVATE_CURSOR_BITS) 25635c4bbdfSmrg bits->source = psrcbits; 25705b261ecSmrg bits->mask = pmaskbits; 25805b261ecSmrg bits->argb = argb; 25905b261ecSmrg bits->width = cm->width; 26005b261ecSmrg bits->height = cm->height; 26105b261ecSmrg bits->xhot = cm->xhot; 26205b261ecSmrg bits->yhot = cm->yhot; 26335c4bbdfSmrg pCurs->refcnt = 1; 26405b261ecSmrg bits->refcnt = -1; 26505b261ecSmrg CheckForEmptyMask(bits); 26605b261ecSmrg pCurs->bits = bits; 26705b261ecSmrg pCurs->serialNumber = ++cursorSerial; 26805b261ecSmrg pCurs->name = None; 26905b261ecSmrg 27005b261ecSmrg pCurs->foreRed = foreRed; 27105b261ecSmrg pCurs->foreGreen = foreGreen; 27205b261ecSmrg pCurs->foreBlue = foreBlue; 27305b261ecSmrg 27405b261ecSmrg pCurs->backRed = backRed; 27505b261ecSmrg pCurs->backGreen = backGreen; 27605b261ecSmrg pCurs->backBlue = backBlue; 27705b261ecSmrg 2784642e01fSmrg pCurs->id = cid; 2794642e01fSmrg 2804642e01fSmrg /* security creation/labeling check */ 2814642e01fSmrg rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR, 28235c4bbdfSmrg pCurs, RT_NONE, NULL, DixCreateAccess); 2836747b715Smrg if (rc != Success) 2846747b715Smrg goto error; 2856747b715Smrg 2866747b715Smrg rc = RealizeCursorAllScreens(pCurs); 2876747b715Smrg if (rc != Success) 2886747b715Smrg goto error; 2896747b715Smrg 2904642e01fSmrg *ppCurs = pCurs; 29135c4bbdfSmrg 29235c4bbdfSmrg if (argb) { 29335c4bbdfSmrg size_t i, size = bits->width * bits->height; 29435c4bbdfSmrg 29535c4bbdfSmrg for (i = 0; i < size; i++) { 29635c4bbdfSmrg if ((argb[i] & 0xff000000) == 0 && (argb[i] & 0xffffff) != 0) { 29735c4bbdfSmrg /* ARGB data doesn't seem pre-multiplied, fix it */ 29835c4bbdfSmrg for (i = 0; i < size; i++) { 29935c4bbdfSmrg CARD32 a, ar, ag, ab; 30035c4bbdfSmrg 30135c4bbdfSmrg a = argb[i] >> 24; 30235c4bbdfSmrg ar = a * ((argb[i] >> 16) & 0xff) / 0xff; 30335c4bbdfSmrg ag = a * ((argb[i] >> 8) & 0xff) / 0xff; 30435c4bbdfSmrg ab = a * (argb[i] & 0xff) / 0xff; 30535c4bbdfSmrg 30635c4bbdfSmrg argb[i] = a << 24 | ar << 16 | ag << 8 | ab; 30735c4bbdfSmrg } 30835c4bbdfSmrg 30935c4bbdfSmrg break; 31035c4bbdfSmrg } 31135c4bbdfSmrg } 31235c4bbdfSmrg } 31335c4bbdfSmrg 3146747b715Smrg return Success; 3156747b715Smrg 31635c4bbdfSmrg error: 3176747b715Smrg FreeCursorBits(bits); 3186747b715Smrg dixFiniPrivates(pCurs, PRIVATE_CURSOR); 3196747b715Smrg free(pCurs); 3206747b715Smrg 3214642e01fSmrg return rc; 32205b261ecSmrg} 32305b261ecSmrg 32405b261ecSmrgint 32505b261ecSmrgAllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar, 32635c4bbdfSmrg unsigned foreRed, unsigned foreGreen, unsigned foreBlue, 32735c4bbdfSmrg unsigned backRed, unsigned backGreen, unsigned backBlue, 32835c4bbdfSmrg CursorPtr *ppCurs, ClientPtr client, XID cid) 32905b261ecSmrg{ 33035c4bbdfSmrg FontPtr sourcefont, maskfont; 33135c4bbdfSmrg unsigned char *srcbits; 33235c4bbdfSmrg unsigned char *mskbits; 33305b261ecSmrg CursorMetricRec cm; 3344642e01fSmrg int rc; 33535c4bbdfSmrg CursorBitsPtr bits; 33635c4bbdfSmrg CursorPtr pCurs; 33705b261ecSmrg GlyphSharePtr pShare; 33805b261ecSmrg 33935c4bbdfSmrg rc = dixLookupResourceByType((void **) &sourcefont, source, RT_FONT, 34035c4bbdfSmrg client, DixUseAccess); 34135c4bbdfSmrg if (rc != Success) { 34235c4bbdfSmrg client->errorValue = source; 34335c4bbdfSmrg return rc; 34405b261ecSmrg } 34535c4bbdfSmrg rc = dixLookupResourceByType((void **) &maskfont, mask, RT_FONT, client, 34635c4bbdfSmrg DixUseAccess); 34735c4bbdfSmrg if (rc != Success && mask != None) { 34835c4bbdfSmrg client->errorValue = mask; 34935c4bbdfSmrg return rc; 35005b261ecSmrg } 35105b261ecSmrg if (sourcefont != maskfont) 35235c4bbdfSmrg pShare = (GlyphSharePtr) NULL; 35335c4bbdfSmrg else { 35435c4bbdfSmrg for (pShare = sharedGlyphs; 35535c4bbdfSmrg pShare && 35635c4bbdfSmrg ((pShare->font != sourcefont) || 35735c4bbdfSmrg (pShare->sourceChar != sourceChar) || 35835c4bbdfSmrg (pShare->maskChar != maskChar)); pShare = pShare->next); 35905b261ecSmrg } 36035c4bbdfSmrg if (pShare) { 36135c4bbdfSmrg pCurs = (CursorPtr) calloc(CURSOR_REC_SIZE, 1); 36235c4bbdfSmrg if (!pCurs) 36335c4bbdfSmrg return BadAlloc; 36435c4bbdfSmrg dixInitPrivates(pCurs, pCurs + 1, PRIVATE_CURSOR); 36535c4bbdfSmrg bits = pShare->bits; 36635c4bbdfSmrg bits->refcnt++; 36705b261ecSmrg } 36835c4bbdfSmrg else { 36935c4bbdfSmrg if (!CursorMetricsFromGlyph(sourcefont, sourceChar, &cm)) { 37035c4bbdfSmrg client->errorValue = sourceChar; 37135c4bbdfSmrg return BadValue; 37235c4bbdfSmrg } 37335c4bbdfSmrg if (!maskfont) { 37435c4bbdfSmrg long n; 37535c4bbdfSmrg unsigned char *mskptr; 37635c4bbdfSmrg 37735c4bbdfSmrg n = BitmapBytePad(cm.width) * (long) cm.height; 37835c4bbdfSmrg mskptr = mskbits = malloc(n); 37935c4bbdfSmrg if (!mskptr) 38035c4bbdfSmrg return BadAlloc; 38135c4bbdfSmrg while (--n >= 0) 38235c4bbdfSmrg *mskptr++ = ~0; 38335c4bbdfSmrg } 38435c4bbdfSmrg else { 38535c4bbdfSmrg if (!CursorMetricsFromGlyph(maskfont, maskChar, &cm)) { 38635c4bbdfSmrg client->errorValue = maskChar; 38735c4bbdfSmrg return BadValue; 38835c4bbdfSmrg } 38935c4bbdfSmrg if ((rc = ServerBitsFromGlyph(maskfont, maskChar, &cm, &mskbits))) 39035c4bbdfSmrg return rc; 39135c4bbdfSmrg } 39235c4bbdfSmrg if ((rc = ServerBitsFromGlyph(sourcefont, sourceChar, &cm, &srcbits))) { 39335c4bbdfSmrg free(mskbits); 39435c4bbdfSmrg return rc; 39535c4bbdfSmrg } 39635c4bbdfSmrg if (sourcefont != maskfont) { 39735c4bbdfSmrg pCurs = (CursorPtr) calloc(CURSOR_REC_SIZE + CURSOR_BITS_SIZE, 1); 39835c4bbdfSmrg if (pCurs) 39935c4bbdfSmrg bits = (CursorBitsPtr) ((char *) pCurs + CURSOR_REC_SIZE); 40035c4bbdfSmrg else 40135c4bbdfSmrg bits = (CursorBitsPtr) NULL; 40235c4bbdfSmrg } 40335c4bbdfSmrg else { 40435c4bbdfSmrg pCurs = (CursorPtr) calloc(CURSOR_REC_SIZE, 1); 40535c4bbdfSmrg if (pCurs) 40635c4bbdfSmrg bits = (CursorBitsPtr) calloc(CURSOR_BITS_SIZE, 1); 40735c4bbdfSmrg else 40835c4bbdfSmrg bits = (CursorBitsPtr) NULL; 40935c4bbdfSmrg } 41035c4bbdfSmrg if (!bits) { 41135c4bbdfSmrg free(pCurs); 41235c4bbdfSmrg free(mskbits); 41335c4bbdfSmrg free(srcbits); 41435c4bbdfSmrg return BadAlloc; 41535c4bbdfSmrg } 41635c4bbdfSmrg dixInitPrivates(pCurs, pCurs + 1, PRIVATE_CURSOR); 41735c4bbdfSmrg dixInitPrivates(bits, bits + 1, PRIVATE_CURSOR_BITS); 41835c4bbdfSmrg bits->source = srcbits; 41935c4bbdfSmrg bits->mask = mskbits; 42035c4bbdfSmrg bits->argb = 0; 42135c4bbdfSmrg bits->width = cm.width; 42235c4bbdfSmrg bits->height = cm.height; 42335c4bbdfSmrg bits->xhot = cm.xhot; 42435c4bbdfSmrg bits->yhot = cm.yhot; 42535c4bbdfSmrg if (sourcefont != maskfont) 42635c4bbdfSmrg bits->refcnt = -1; 42735c4bbdfSmrg else { 42835c4bbdfSmrg bits->refcnt = 1; 42935c4bbdfSmrg pShare = malloc(sizeof(GlyphShare)); 43035c4bbdfSmrg if (!pShare) { 43135c4bbdfSmrg FreeCursorBits(bits); 43235c4bbdfSmrg return BadAlloc; 43335c4bbdfSmrg } 43435c4bbdfSmrg pShare->font = sourcefont; 43535c4bbdfSmrg sourcefont->refcnt++; 43635c4bbdfSmrg pShare->sourceChar = sourceChar; 43735c4bbdfSmrg pShare->maskChar = maskChar; 43835c4bbdfSmrg pShare->bits = bits; 43935c4bbdfSmrg pShare->next = sharedGlyphs; 44035c4bbdfSmrg sharedGlyphs = pShare; 44135c4bbdfSmrg } 44205b261ecSmrg } 4434642e01fSmrg 44405b261ecSmrg CheckForEmptyMask(bits); 44505b261ecSmrg pCurs->bits = bits; 44605b261ecSmrg pCurs->refcnt = 1; 44705b261ecSmrg pCurs->serialNumber = ++cursorSerial; 44805b261ecSmrg pCurs->name = None; 44905b261ecSmrg 45005b261ecSmrg pCurs->foreRed = foreRed; 45105b261ecSmrg pCurs->foreGreen = foreGreen; 45205b261ecSmrg pCurs->foreBlue = foreBlue; 45305b261ecSmrg 45405b261ecSmrg pCurs->backRed = backRed; 45505b261ecSmrg pCurs->backGreen = backGreen; 45605b261ecSmrg pCurs->backBlue = backBlue; 45705b261ecSmrg 4584642e01fSmrg pCurs->id = cid; 4594642e01fSmrg 4604642e01fSmrg /* security creation/labeling check */ 4614642e01fSmrg rc = XaceHook(XACE_RESOURCE_ACCESS, client, cid, RT_CURSOR, 46235c4bbdfSmrg pCurs, RT_NONE, NULL, DixCreateAccess); 4636747b715Smrg if (rc != Success) 4646747b715Smrg goto error; 4654642e01fSmrg 4666747b715Smrg rc = RealizeCursorAllScreens(pCurs); 4676747b715Smrg if (rc != Success) 4686747b715Smrg goto error; 4694642e01fSmrg 47005b261ecSmrg *ppCurs = pCurs; 47105b261ecSmrg return Success; 4726747b715Smrg 47335c4bbdfSmrg error: 4746747b715Smrg FreeCursorBits(bits); 4756747b715Smrg dixFiniPrivates(pCurs, PRIVATE_CURSOR); 4766747b715Smrg free(pCurs); 4776747b715Smrg 4786747b715Smrg return rc; 47905b261ecSmrg} 48005b261ecSmrg 48105b261ecSmrg/** CreateRootCursor 48205b261ecSmrg * 48305b261ecSmrg * look up the name of a font 48405b261ecSmrg * open the font 48505b261ecSmrg * add the font to the resource table 48605b261ecSmrg * make a cursor from the glyphs 48705b261ecSmrg * add the cursor to the resource table 48805b261ecSmrg *************************************************************/ 48905b261ecSmrg 4906747b715SmrgCursorPtr 49105b261ecSmrgCreateRootCursor(char *unused1, unsigned int unused2) 49205b261ecSmrg{ 49335c4bbdfSmrg CursorPtr curs; 49435c4bbdfSmrg FontPtr cursorfont; 49535c4bbdfSmrg int err; 49635c4bbdfSmrg XID fontID; 497ed6184dfSmrg const char defaultCursorFont[] = "cursor"; 49805b261ecSmrg 49905b261ecSmrg fontID = FakeClientID(0); 50005b261ecSmrg err = OpenFont(serverClient, fontID, FontLoadAll | FontOpenSync, 50135c4bbdfSmrg (unsigned) strlen(defaultCursorFont), defaultCursorFont); 50205b261ecSmrg if (err != Success) 50335c4bbdfSmrg return NullCursor; 50405b261ecSmrg 50535c4bbdfSmrg err = dixLookupResourceByType((void **) &cursorfont, fontID, RT_FONT, 50635c4bbdfSmrg serverClient, DixReadAccess); 5076747b715Smrg if (err != Success) 50835c4bbdfSmrg return NullCursor; 5094642e01fSmrg if (AllocGlyphCursor(fontID, 0, fontID, 1, 0, 0, 0, ~0, ~0, ~0, 51035c4bbdfSmrg &curs, serverClient, (XID) 0) != Success) 51135c4bbdfSmrg return NullCursor; 51205b261ecSmrg 51335c4bbdfSmrg if (!AddResource(FakeClientID(0), RT_CURSOR, (void *) curs)) 51435c4bbdfSmrg return NullCursor; 51505b261ecSmrg 51605b261ecSmrg return curs; 51705b261ecSmrg} 518