CrGlCur.c revision b4ee4795
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#ifdef __UNIXOS2__
35#define RTLD_LAZY 1
36#define LIBXCURSOR "Xcursor.dll"
37#endif
38#include <stdio.h>
39#include <string.h>
40#if defined(hpux)
41#include <dl.h>
42#else
43#include <dlfcn.h>
44#endif
45#include "Cr.h"
46
47#ifdef __CYGWIN__
48#define LIBXCURSOR "cygXcursor-1.dll"
49#endif
50
51#if defined(hpux)
52typedef shl_t	XModuleType;
53#else
54typedef void *XModuleType;
55#endif
56
57#ifndef LIBXCURSOR
58#define LIBXCURSOR "libXcursor.so.1"
59#endif
60
61static char libraryName[] = LIBXCURSOR;
62
63static XModuleType
64open_library (void)
65{
66    char	*library = libraryName;
67    char	*dot;
68    XModuleType	module;
69    for (;;)
70    {
71#if defined(hpux)
72	module = shl_load(library, BIND_DEFERRED, 0L);
73#else
74	module =  dlopen(library, RTLD_LAZY);
75#endif
76	if (module)
77	    return module;
78	dot = strrchr (library, '.');
79	if (!dot)
80	    break;
81	*dot = '\0';
82    }
83    return NULL;
84}
85
86static void *
87fetch_symbol (XModuleType module, const char *under_symbol)
88{
89    void *result = NULL;
90    const char *symbol = under_symbol + 1;
91#if defined(hpux)
92    int getsyms_cnt, i;
93    struct shl_symbol *symbols;
94
95    getsyms_cnt = shl_getsymbols(module, TYPE_PROCEDURE,
96				 EXPORT_SYMBOLS, malloc, &symbols);
97
98    for(i=0; i<getsyms_cnt; i++) {
99        if(!strcmp(symbols[i].name, symbol)) {
100	    result = symbols[i].value;
101	    break;
102         }
103    }
104
105    if(getsyms_cnt > 0) {
106        free(symbols);
107    }
108#else
109    result = dlsym (module, symbol);
110    if (!result)
111	result = dlsym (module, under_symbol);
112#endif
113    return result;
114}
115
116typedef void	(*NoticeCreateBitmapFunc) (Display	    *dpy,
117					   Pixmap	    pid,
118					   unsigned int width,
119					   unsigned int height);
120
121typedef void	(*NoticePutBitmapFunc) (Display	    *dpy,
122					Drawable    draw,
123					XImage	    *image);
124
125typedef Cursor	(*TryShapeBitmapCursorFunc) (Display	    *dpy,
126					     Pixmap	    source,
127					     Pixmap	    mask,
128					     XColor	    *foreground,
129					     XColor	    *background,
130					     unsigned int   x,
131					     unsigned int   y);
132
133typedef Cursor	(*TryShapeCursorFunc) (Display	    *dpy,
134				       Font	    source_font,
135				       Font	    mask_font,
136				       unsigned int source_char,
137				       unsigned int mask_char,
138				       XColor _Xconst *foreground,
139				       XColor _Xconst *background);
140
141static XModuleType  _XcursorModule;
142static Bool	    _XcursorModuleTried;
143
144#define GetFunc(type,name,ret) {\
145    static Bool	    been_here; \
146    static type	    staticFunc; \
147     \
148    _XLockMutex (_Xglobal_lock); \
149    if (!been_here) \
150    { \
151	been_here = True; \
152	if (!_XcursorModuleTried) \
153	{ \
154	    _XcursorModuleTried = True; \
155	    _XcursorModule = open_library (); \
156	} \
157	if (_XcursorModule) \
158	    staticFunc = (type) fetch_symbol (_XcursorModule, "_" name); \
159    } \
160    ret = staticFunc; \
161    _XUnlockMutex (_Xglobal_lock); \
162}
163
164static Cursor
165_XTryShapeCursor (Display	    *dpy,
166		  Font		    source_font,
167		  Font		    mask_font,
168		  unsigned int	    source_char,
169		  unsigned int	    mask_char,
170		  XColor _Xconst    *foreground,
171		  XColor _Xconst    *background)
172{
173    TryShapeCursorFunc		func;
174
175    GetFunc (TryShapeCursorFunc, "XcursorTryShapeCursor", func);
176    if (func)
177	return (*func) (dpy, source_font, mask_font, source_char, mask_char,
178			foreground, background);
179    return None;
180}
181
182void
183_XNoticeCreateBitmap (Display	    *dpy,
184		      Pixmap	    pid,
185		      unsigned int  width,
186		      unsigned int  height)
187{
188    NoticeCreateBitmapFunc  func;
189
190    GetFunc (NoticeCreateBitmapFunc, "XcursorNoticeCreateBitmap", func);
191    if (func)
192	(*func) (dpy, pid, width, height);
193}
194
195void
196_XNoticePutBitmap (Display	*dpy,
197		   Drawable	draw,
198		   XImage	*image)
199{
200    NoticePutBitmapFunc	func;
201
202    GetFunc (NoticePutBitmapFunc, "XcursorNoticePutBitmap", func);
203    if (func)
204	(*func) (dpy, draw, image);
205}
206
207Cursor
208_XTryShapeBitmapCursor (Display		*dpy,
209			Pixmap		source,
210			Pixmap		mask,
211			XColor		*foreground,
212			XColor		*background,
213			unsigned int	x,
214			unsigned int	y)
215{
216    TryShapeBitmapCursorFunc	func;
217
218    GetFunc (TryShapeBitmapCursorFunc, "XcursorTryShapeBitmapCursor", func);
219    if (func)
220	return (*func) (dpy, source, mask, foreground, background, x, y);
221    return None;
222}
223#endif
224
225Cursor XCreateGlyphCursor(
226     register Display *dpy,
227     Font source_font,
228     Font mask_font,
229     unsigned int source_char,
230     unsigned int mask_char,
231     XColor _Xconst *foreground,
232     XColor _Xconst *background)
233{
234    Cursor cid;
235    register xCreateGlyphCursorReq *req;
236
237#ifdef USE_DYNAMIC_XCURSOR
238    cid = _XTryShapeCursor (dpy, source_font, mask_font,
239			    source_char, mask_char, foreground, background);
240    if (cid)
241	return cid;
242#endif
243    LockDisplay(dpy);
244    GetReq(CreateGlyphCursor, req);
245    cid = req->cid = XAllocID(dpy);
246    req->source = source_font;
247    req->mask = mask_font;
248    req->sourceChar = source_char;
249    req->maskChar = mask_char;
250    req->foreRed = foreground->red;
251    req->foreGreen = foreground->green;
252    req->foreBlue = foreground->blue;
253    req->backRed = background->red;
254    req->backGreen = background->green;
255    req->backBlue = background->blue;
256    UnlockDisplay(dpy);
257    SyncHandle();
258    return (cid);
259}
260
261