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