Home | History | Annotate | Line # | Download | only in src
      1 /*
      2 
      3 Copyright 1986, 1998  The Open Group
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 the above copyright notice appear in all copies and that both that
      8 copyright notice and this permission notice appear in supporting
      9 documentation.
     10 
     11 The above copyright notice and this permission notice shall be included in
     12 all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     20 
     21 Except as contained in this notice, the name of The Open Group shall not be
     22 used in advertising or otherwise to promote the sale, use or other dealings
     23 in this Software without prior written authorization from The Open Group.
     24 
     25 */
     26 
     27 #ifdef HAVE_CONFIG_H
     28 #include <config.h>
     29 #endif
     30 #include "Xlibint.h"
     31 
     32 #ifdef USE_DYNAMIC_XCURSOR
     33 
     34 #include <stdio.h>
     35 #include <string.h>
     36 #include <dlfcn.h>
     37 #include "Cr.h"
     38 
     39 #ifdef __CYGWIN__
     40 #define LIBXCURSOR "cygXcursor-1.dll"
     41 #endif
     42 
     43 typedef void *XModuleType;
     44 
     45 #ifndef LIBXCURSOR
     46 #define LIBXCURSOR "libXcursor.so"
     47 #endif
     48 
     49 static char libraryName[] = LIBXCURSOR;
     50 
     51 static XModuleType
     52 open_library (void)
     53 {
     54     char	*library = libraryName;
     55     char	*dot;
     56     XModuleType	module;
     57     for (;;)
     58     {
     59 	module =  dlopen(library, RTLD_LAZY);
     60 	if (module)
     61 	    return module;
     62 	dot = strrchr (library, '.');
     63 	if (!dot)
     64 	    break;
     65 	*dot = '\0';
     66     }
     67     return NULL;
     68 }
     69 
     70 static void *
     71 fetch_symbol (XModuleType module, const char *under_symbol)
     72 {
     73     void *result = NULL;
     74     const char *symbol = under_symbol + 1;
     75     result = dlsym (module, symbol);
     76     if (!result)
     77 	result = dlsym (module, under_symbol);
     78     return result;
     79 }
     80 
     81 typedef void	(*NoticeCreateBitmapFunc) (Display	    *dpy,
     82 					   Pixmap	    pid,
     83 					   unsigned int width,
     84 					   unsigned int height);
     85 
     86 typedef void	(*NoticePutBitmapFunc) (Display	    *dpy,
     87 					Drawable    draw,
     88 					XImage	    *image);
     89 
     90 typedef Cursor	(*TryShapeBitmapCursorFunc) (Display	    *dpy,
     91 					     Pixmap	    source,
     92 					     Pixmap	    mask,
     93 					     XColor	    *foreground,
     94 					     XColor	    *background,
     95 					     unsigned int   x,
     96 					     unsigned int   y);
     97 
     98 typedef Cursor	(*TryShapeCursorFunc) (Display	    *dpy,
     99 				       Font	    source_font,
    100 				       Font	    mask_font,
    101 				       unsigned int source_char,
    102 				       unsigned int mask_char,
    103 				       XColor _Xconst *foreground,
    104 				       XColor _Xconst *background);
    105 
    106 static XModuleType  _XcursorModule;
    107 static Bool	    _XcursorModuleTried;
    108 
    109 #define GetFunc(type,name,ret) do { \
    110     static Bool	    been_here; \
    111     static type	    staticFunc; \
    112      \
    113     _XLockMutex (_Xglobal_lock); \
    114     if (!been_here) \
    115     { \
    116 	been_here = True; \
    117 	if (!_XcursorModuleTried) \
    118 	{ \
    119 	    _XcursorModuleTried = True; \
    120 	    _XcursorModule = open_library (); \
    121 	} \
    122 	if (_XcursorModule) \
    123 	    staticFunc = (type) fetch_symbol (_XcursorModule, "_" name); \
    124     } \
    125     ret = staticFunc; \
    126     _XUnlockMutex (_Xglobal_lock); \
    127 } while (0)
    128 
    129 static Cursor
    130 _XTryShapeCursor (Display	    *dpy,
    131 		  Font		    source_font,
    132 		  Font		    mask_font,
    133 		  unsigned int	    source_char,
    134 		  unsigned int	    mask_char,
    135 		  XColor _Xconst    *foreground,
    136 		  XColor _Xconst    *background)
    137 {
    138     TryShapeCursorFunc		func;
    139 
    140     GetFunc (TryShapeCursorFunc, "XcursorTryShapeCursor", func);
    141     if (func)
    142 	return (*func) (dpy, source_font, mask_font, source_char, mask_char,
    143 			foreground, background);
    144     return None;
    145 }
    146 
    147 void
    148 _XNoticeCreateBitmap (Display	    *dpy,
    149 		      Pixmap	    pid,
    150 		      unsigned int  width,
    151 		      unsigned int  height)
    152 {
    153     NoticeCreateBitmapFunc  func;
    154 
    155     GetFunc (NoticeCreateBitmapFunc, "XcursorNoticeCreateBitmap", func);
    156     if (func)
    157 	(*func) (dpy, pid, width, height);
    158 }
    159 
    160 void
    161 _XNoticePutBitmap (Display	*dpy,
    162 		   Drawable	draw,
    163 		   XImage	*image)
    164 {
    165     NoticePutBitmapFunc	func;
    166 
    167     GetFunc (NoticePutBitmapFunc, "XcursorNoticePutBitmap", func);
    168     if (func)
    169 	(*func) (dpy, draw, image);
    170 }
    171 
    172 Cursor
    173 _XTryShapeBitmapCursor (Display		*dpy,
    174 			Pixmap		source,
    175 			Pixmap		mask,
    176 			XColor		*foreground,
    177 			XColor		*background,
    178 			unsigned int	x,
    179 			unsigned int	y)
    180 {
    181     TryShapeBitmapCursorFunc	func;
    182 
    183     GetFunc (TryShapeBitmapCursorFunc, "XcursorTryShapeBitmapCursor", func);
    184     if (func)
    185 	return (*func) (dpy, source, mask, foreground, background, x, y);
    186     return None;
    187 }
    188 #endif
    189 
    190 Cursor XCreateGlyphCursor(
    191      register Display *dpy,
    192      Font source_font,
    193      Font mask_font,
    194      unsigned int source_char,
    195      unsigned int mask_char,
    196      XColor _Xconst *foreground,
    197      XColor _Xconst *background)
    198 {
    199     Cursor cid;
    200     register xCreateGlyphCursorReq *req;
    201 
    202 #ifdef USE_DYNAMIC_XCURSOR
    203     cid = _XTryShapeCursor (dpy, source_font, mask_font,
    204 			    source_char, mask_char, foreground, background);
    205     if (cid)
    206 	return cid;
    207 #endif
    208     LockDisplay(dpy);
    209     GetReq(CreateGlyphCursor, req);
    210     cid = req->cid = XAllocID(dpy);
    211     req->source = source_font;
    212     req->mask = mask_font;
    213     req->sourceChar = source_char;
    214     req->maskChar = mask_char;
    215     req->foreRed = foreground->red;
    216     req->foreGreen = foreground->green;
    217     req->foreBlue = foreground->blue;
    218     req->backRed = background->red;
    219     req->backGreen = background->green;
    220     req->backBlue = background->blue;
    221     UnlockDisplay(dpy);
    222     SyncHandle();
    223     return (cid);
    224 }
    225 
    226