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