CrGlCur.c revision c6e579a2
1/* 2 3Copyright 1986, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in 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 43typedef void *XModuleType; 44 45#ifndef LIBXCURSOR 46#define LIBXCURSOR "libXcursor.so" 47#endif 48 49static char libraryName[] = LIBXCURSOR; 50 51static XModuleType 52open_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 70static void * 71fetch_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 81typedef void (*NoticeCreateBitmapFunc) (Display *dpy, 82 Pixmap pid, 83 unsigned int width, 84 unsigned int height); 85 86typedef void (*NoticePutBitmapFunc) (Display *dpy, 87 Drawable draw, 88 XImage *image); 89 90typedef 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 98typedef 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 106static XModuleType _XcursorModule; 107static Bool _XcursorModuleTried; 108 109#define GetFunc(type,name,ret) {\ 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} 128 129static 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 147void 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 160void 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 172Cursor 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 190Cursor 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