]> git.sesse.net Git - rdpsrv/blobdiff - Xserver/programs/Xserver/dix/cursor.c
Import X server from vnc-3.3.7.
[rdpsrv] / Xserver / programs / Xserver / dix / cursor.c
diff --git a/Xserver/programs/Xserver/dix/cursor.c b/Xserver/programs/Xserver/dix/cursor.c
new file mode 100644 (file)
index 0000000..4fafc60
--- /dev/null
@@ -0,0 +1,405 @@
+/***********************************************************
+
+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;
+}