--- /dev/null
+/***********************************************************
+
+Copyright (c) 1987 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.
+
+
+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.
+
+******************************************************************/
+
+
+/* $XConsortium: cursor.c /main/19 1996/08/01 19:20:16 dpw $ */
+/* $XFree86: xc/programs/Xserver/dix/cursor.c,v 3.1 1996/12/23 06:29:36 dawes Exp $ */
+
+#include "X.h"
+#include "Xmd.h"
+#include "servermd.h"
+#include "scrnintstr.h"
+#include "dixstruct.h"
+#include "cursorstr.h"
+#include "dixfontstr.h"
+#include "opaque.h"
+
+typedef struct _GlyphShare {
+ FontPtr font;
+ unsigned short sourceChar;
+ unsigned short maskChar;
+ CursorBitsPtr bits;
+ struct _GlyphShare *next;
+} GlyphShare, *GlyphSharePtr;
+
+static GlyphSharePtr sharedGlyphs = (GlyphSharePtr)NULL;
+
+static void
+#if NeedFunctionPrototypes
+FreeCursorBits(CursorBitsPtr bits)
+#else
+FreeCursorBits(bits)
+ CursorBitsPtr bits;
+#endif
+{
+ if (--bits->refcnt > 0)
+ return;
+ xfree(bits->source);
+ xfree(bits->mask);
+ if (bits->refcnt == 0)
+ {
+ register GlyphSharePtr *prev, this;
+
+ for (prev = &sharedGlyphs;
+ (this = *prev) && (this->bits != bits);
+ prev = &this->next)
+ ;
+ if (this)
+ {
+ *prev = this->next;
+ CloseFont(this->font, (Font)0);
+ xfree(this);
+ }
+ xfree(bits);
+ }
+}
+
+/*
+ * To be called indirectly by DeleteResource; must use exactly two args
+ */
+/*ARGSUSED*/
+int
+FreeCursor(value, cid)
+ pointer value; /* must conform to DeleteType */
+ XID cid;
+{
+ int nscr;
+ CursorPtr pCurs = (CursorPtr)value;
+
+ ScreenPtr pscr;
+
+ if ( --pCurs->refcnt > 0)
+ return(Success);
+
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+ {
+ pscr = screenInfo.screens[nscr];
+ (void)( *pscr->UnrealizeCursor)( pscr, pCurs);
+ }
+ FreeCursorBits(pCurs->bits);
+ xfree( pCurs);
+ return(Success);
+}
+
+/*
+ * does nothing about the resource table, just creates the data structure.
+ * does not copy the src and mask bits
+ */
+CursorPtr
+AllocCursor(psrcbits, pmaskbits, cm,
+ foreRed, foreGreen, foreBlue, backRed, backGreen, backBlue)
+ unsigned char * psrcbits; /* server-defined padding */
+ unsigned char * pmaskbits; /* server-defined padding */
+ CursorMetricPtr cm;
+ unsigned foreRed, foreGreen, foreBlue;
+ unsigned backRed, backGreen, backBlue;
+{
+ CursorBitsPtr bits;
+ CursorPtr pCurs;
+ int nscr;
+ ScreenPtr pscr;
+
+ pCurs = (CursorPtr)xalloc(sizeof(CursorRec) + sizeof(CursorBits));
+ if (!pCurs)
+ {
+ xfree(psrcbits);
+ xfree(pmaskbits);
+ return (CursorPtr)NULL;
+ }
+ bits = (CursorBitsPtr)((char *)pCurs + sizeof(CursorRec));
+ bits->source = psrcbits;
+ bits->mask = pmaskbits;
+ bits->width = cm->width;
+ bits->height = cm->height;
+ bits->xhot = cm->xhot;
+ bits->yhot = cm->yhot;
+ bits->refcnt = -1;
+
+ pCurs->bits = bits;
+ pCurs->refcnt = 1;
+
+ pCurs->foreRed = foreRed;
+ pCurs->foreGreen = foreGreen;
+ pCurs->foreBlue = foreBlue;
+
+ pCurs->backRed = backRed;
+ pCurs->backGreen = backGreen;
+ pCurs->backBlue = backBlue;
+
+ /*
+ * realize the cursor for every screen
+ */
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+ {
+ pscr = screenInfo.screens[nscr];
+ if (!( *pscr->RealizeCursor)( pscr, pCurs))
+ {
+ while (--nscr >= 0)
+ {
+ pscr = screenInfo.screens[nscr];
+ ( *pscr->UnrealizeCursor)( pscr, pCurs);
+ }
+ FreeCursorBits(bits);
+ xfree(pCurs);
+ return (CursorPtr)NULL;
+ }
+ }
+ return pCurs;
+}
+
+int
+AllocGlyphCursor(source, sourceChar, mask, maskChar,
+ foreRed, foreGreen, foreBlue, backRed, backGreen, backBlue,
+ ppCurs, client)
+ Font source, mask;
+ unsigned int sourceChar, maskChar;
+ unsigned foreRed, foreGreen, foreBlue;
+ unsigned backRed, backGreen, backBlue;
+ CursorPtr *ppCurs;
+ ClientPtr client;
+{
+ FontPtr sourcefont, maskfont;
+ unsigned char *srcbits;
+ unsigned char *mskbits;
+ CursorMetricRec cm;
+ int res;
+ CursorBitsPtr bits;
+ CursorPtr pCurs;
+ int nscr;
+ ScreenPtr pscr;
+ GlyphSharePtr pShare;
+
+ sourcefont = (FontPtr) SecurityLookupIDByType(client, source, RT_FONT,
+ SecurityReadAccess);
+ maskfont = (FontPtr) SecurityLookupIDByType(client, mask, RT_FONT,
+ SecurityReadAccess);
+
+ if (!sourcefont)
+ {
+ client->errorValue = source;
+ return(BadFont);
+ }
+ if (!maskfont && (mask != None))
+ {
+ client->errorValue = mask;
+ return(BadFont);
+ }
+ if (sourcefont != maskfont)
+ pShare = (GlyphSharePtr)NULL;
+ else
+ {
+ for (pShare = sharedGlyphs;
+ pShare &&
+ ((pShare->font != sourcefont) ||
+ (pShare->sourceChar != sourceChar) ||
+ (pShare->maskChar != maskChar));
+ pShare = pShare->next)
+ ;
+ }
+ if (pShare)
+ {
+ pCurs = (CursorPtr)xalloc(sizeof(CursorRec));
+ if (!pCurs)
+ return BadAlloc;
+ bits = pShare->bits;
+ bits->refcnt++;
+ }
+ else
+ {
+ if (!CursorMetricsFromGlyph(sourcefont, sourceChar, &cm))
+ {
+ client->errorValue = sourceChar;
+ return BadValue;
+ }
+ if (!maskfont)
+ {
+ register long n;
+ register unsigned char *mskptr;
+
+ n = BitmapBytePad(cm.width)*(long)cm.height;
+ mskptr = mskbits = (unsigned char *)xalloc(n);
+ if (!mskptr)
+ return BadAlloc;
+ while (--n >= 0)
+ *mskptr++ = ~0;
+ }
+ else
+ {
+ if (!CursorMetricsFromGlyph(maskfont, maskChar, &cm))
+ {
+ client->errorValue = maskChar;
+ return BadValue;
+ }
+ if ((res = ServerBitsFromGlyph(maskfont, maskChar, &cm, &mskbits)) != 0)
+ return res;
+ }
+ if ((res = ServerBitsFromGlyph(sourcefont, sourceChar, &cm, &srcbits)) != 0)
+ {
+ xfree(mskbits);
+ return res;
+ }
+ if (sourcefont != maskfont)
+ {
+ pCurs = (CursorPtr)xalloc(sizeof(CursorRec) + sizeof(CursorBits));
+ if (pCurs)
+ bits = (CursorBitsPtr)((char *)pCurs + sizeof(CursorRec));
+ else
+ bits = (CursorBitsPtr)NULL;
+ }
+ else
+ {
+ pCurs = (CursorPtr)xalloc(sizeof(CursorRec));
+ if (pCurs)
+ bits = (CursorBitsPtr)xalloc(sizeof(CursorBits));
+ else
+ bits = (CursorBitsPtr)NULL;
+ }
+ if (!bits)
+ {
+ xfree(pCurs);
+ xfree(mskbits);
+ xfree(srcbits);
+ return BadAlloc;
+ }
+ bits->source = srcbits;
+ bits->mask = mskbits;
+ bits->width = cm.width;
+ bits->height = cm.height;
+ bits->xhot = cm.xhot;
+ bits->yhot = cm.yhot;
+ if (sourcefont != maskfont)
+ bits->refcnt = -1;
+ else
+ {
+ bits->refcnt = 1;
+ pShare = (GlyphSharePtr)xalloc(sizeof(GlyphShare));
+ if (!pShare)
+ {
+ FreeCursorBits(bits);
+ return BadAlloc;
+ }
+ pShare->font = sourcefont;
+ sourcefont->refcnt++;
+ pShare->sourceChar = sourceChar;
+ pShare->maskChar = maskChar;
+ pShare->bits = bits;
+ pShare->next = sharedGlyphs;
+ sharedGlyphs = pShare;
+ }
+ }
+ pCurs->bits = bits;
+ pCurs->refcnt = 1;
+
+ pCurs->foreRed = foreRed;
+ pCurs->foreGreen = foreGreen;
+ pCurs->foreBlue = foreBlue;
+
+ pCurs->backRed = backRed;
+ pCurs->backGreen = backGreen;
+ pCurs->backBlue = backBlue;
+
+ /*
+ * realize the cursor for every screen
+ */
+ for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
+ {
+ pscr = screenInfo.screens[nscr];
+ if (!( *pscr->RealizeCursor)( pscr, pCurs))
+ {
+ while (--nscr >= 0)
+ {
+ pscr = screenInfo.screens[nscr];
+ ( *pscr->UnrealizeCursor)( pscr, pCurs);
+ }
+ FreeCursorBits(pCurs->bits);
+ xfree(pCurs);
+ return BadAlloc;
+ }
+ }
+ *ppCurs = pCurs;
+ return Success;
+}
+
+/***********************************************************
+ * CreateRootCursor
+ *
+ * look up the name of a font
+ * open the font
+ * add the font to the resource table
+ * make a cursor from the glyphs
+ * add the cursor to the resource table
+ *************************************************************/
+
+CursorPtr
+CreateRootCursor(pfilename, glyph)
+ char * pfilename;
+ unsigned int glyph;
+{
+ CursorPtr curs;
+ FontPtr cursorfont;
+ int err;
+ XID fontID;
+
+ fontID = FakeClientID(0);
+ err = OpenFont(serverClient, fontID, FontLoadAll | FontOpenSync,
+ (unsigned)strlen( pfilename), pfilename);
+ if (err != Success)
+ return NullCursor;
+
+ cursorfont = (FontPtr)LookupIDByType(fontID, RT_FONT);
+ if (!cursorfont)
+ return NullCursor;
+ if (AllocGlyphCursor(fontID, glyph, fontID, glyph + 1,
+ 0, 0, 0, ~0, ~0, ~0, &curs, serverClient) != Success)
+ return NullCursor;
+
+ if (!AddResource(FakeClientID(0), RT_CURSOR, (pointer)curs))
+ return NullCursor;
+
+ return curs;
+}