Imported Upstream version 1.1.1
[platform/upstream/libXmu.git] / src / StrToCurs.c
1 /*
2
3 Copyright 1987, 1988, 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 /***********************************************************
28
29 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
30
31                         All Rights Reserved
32
33 Permission to use, copy, modify, and distribute this software and its
34 documentation for any purpose and without fee is hereby granted,
35 provided that the above copyright notice appear in all copies and that
36 both that copyright notice and this permission notice appear in
37 supporting documentation, and that the name of Digital not be
38 used in advertising or publicity pertaining to distribution of the
39 software without specific, written prior permission.
40
41 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
42 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
43 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
44 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
45 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
46 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
47 SOFTWARE.
48
49 ******************************************************************/
50
51 #ifdef HAVE_CONFIG_H
52 #include <config.h>
53 #endif
54 #include        <X11/Intrinsic.h>
55 #include        <X11/StringDefs.h>
56 #include        <X11/Xmu/Converters.h>
57 #include        <X11/Xmu/Drawing.h>
58 #include        <X11/Xmu/CurUtil.h>
59 #include        <X11/Xmu/CharSet.h>
60
61 #ifndef X_NOT_POSIX
62 #include <stdlib.h>
63 #ifdef _POSIX_SOURCE
64 #include <limits.h>
65 #else
66 #define _POSIX_SOURCE
67 #include <limits.h>
68 #undef _POSIX_SOURCE
69 #endif
70 #endif /* X_NOT_POSIX */
71 #ifndef PATH_MAX
72 #ifdef WIN32
73 #define PATH_MAX 512
74 #else
75 #include <sys/param.h>
76 #endif
77 #ifndef PATH_MAX
78 #ifdef MAXPATHLEN
79 #define PATH_MAX MAXPATHLEN
80 #else
81 #define PATH_MAX 1024
82 #endif
83 #endif
84 #endif /* PATH_MAX */
85
86 /* Kludge source to avoid encountering broken shared library linkers
87    which insist on resolving references unused by the application,
88    and broken object file formats that don't correctly distinguish
89    references to procedures from references to data.
90  */
91 #if defined(SUNSHLIB) || defined(SVR4)
92 #define XMU_KLUDGE
93 #endif
94
95 /*
96  * XmuConvertStringToCursor:
97  *
98  * allows String to specify a standard cursor name (from cursorfont.h), a
99  * font name and glyph index of the form "FONT fontname index [[font] index]",
100  * or a bitmap file name (absolute, or relative to the global resource
101  * bitmapFilePath, class BitmapFilePath).  If the resource is not
102  * defined, the default value is the build symbol BITMAPDIR.
103  *
104  * shares lots of code with XmuCvtStringToPixmap, but unfortunately
105  * can't use it as the hotspot info is lost.
106  *
107  * To use, include the following in your ClassInitialize procedure:
108
109 static XtConvertArgRec screenConvertArg[] = {
110     {XtBaseOffset, (XtPointer) XtOffsetOf(WidgetRec, core.screen),
111      sizeof(Screen *)}
112 };
113
114     XtAddConverter(XtRString, XtRCursor, XmuCvtStringToCursor,
115                    screenConvertArg, XtNumber(screenConvertArg));
116  *
117  */
118
119 #define done(address, type) \
120         { (*toVal).size = sizeof(type); (*toVal).addr = (XPointer) address; }
121
122 #define FONTSPECIFIER           "FONT "
123
124 /*ARGSUSED*/
125 void
126 XmuCvtStringToCursor(XrmValuePtr args, Cardinal *num_args,
127                      XrmValuePtr fromVal, XrmValuePtr toVal)
128 {
129     static Cursor cursor;               /* static for cvt magic */
130     char *name = (char *)fromVal->addr;
131     Screen *screen;
132     register int i;
133     char maskname[PATH_MAX];
134     Pixmap source, mask = 0;
135     /* XXX - make fg/bg resources */
136     static XColor bgColor = {0, 0xffff, 0xffff, 0xffff};
137     static XColor fgColor = {0, 0, 0, 0};
138     int xhot, yhot;
139     int len;
140
141
142     if (*num_args != 1)
143      XtErrorMsg("wrongParameters","cvtStringToCursor","XtToolkitError",
144              "String to cursor conversion needs screen argument",
145               (String *)NULL, (Cardinal *)NULL);
146
147     if (XmuCompareISOLatin1(name, "None") == 0)
148       {
149         cursor = None;
150         done(&cursor, Cursor);
151         return;
152       }
153
154     screen = *((Screen **) args[0].addr);
155
156     if (0 == strncmp(FONTSPECIFIER, name, strlen(FONTSPECIFIER))) {
157         char source_name[PATH_MAX], mask_name[PATH_MAX];
158         int source_char, mask_char, fields = 0;
159         Font source_font, mask_font;
160         XrmValue fromString, toFont;
161         XrmValue cvtArg;
162         Boolean success;
163         Display *dpy = DisplayOfScreen(screen);
164         char *strspec = NULL;
165         int strspeclen;
166 #ifdef XMU_KLUDGE
167         Cardinal num;
168 #endif
169
170         strspeclen = strlen("FONT %s %d %s %d") + 21;
171         strspec = XtMalloc(strspeclen);
172         if (strspec != NULL) {
173             snprintf(strspec, strspeclen, "FONT %%%lds %%d %%%lds %%d",
174                      (unsigned long)sizeof(source_name) - 1,
175                      (unsigned long)sizeof(mask_name) - 1);
176             fields = sscanf(name, strspec,
177                             source_name, &source_char,
178                             mask_name, &mask_char);
179             XtFree(strspec);
180         }
181         if (fields < 2) {
182             XtStringConversionWarning(name, XtRCursor);
183             return;
184         }
185
186         fromString.addr = source_name;
187         fromString.size = strlen(source_name) + 1;
188         toFont.addr = (XPointer) &source_font;
189         toFont.size = sizeof(Font);
190         cvtArg.addr = (XPointer) &dpy;
191         cvtArg.size = sizeof(Display *);
192         /* XXX using display of screen argument as message display */
193 #ifdef XMU_KLUDGE
194         /* XXX Sacrifice caching */
195         num = 1;
196         success = XtCvtStringToFont(dpy, &cvtArg, &num, &fromString, &toFont,
197                                     NULL);
198 #else
199         success = XtCallConverter(dpy, XtCvtStringToFont, &cvtArg,
200                                   (Cardinal)1, &fromString, &toFont, NULL);
201 #endif
202         if (!success) {
203             XtStringConversionWarning(name, XtRCursor);
204             return;
205         }
206
207         switch (fields) {
208           case 2:               /* defaulted mask font & char */
209             mask_font = source_font;
210             mask_char = source_char;
211             break;
212
213           case 3:               /* defaulted mask font */
214             mask_font = source_font;
215             mask_char = atoi(mask_name);
216             break;
217
218           case 4:               /* specified mask font & char */
219             fromString.addr = mask_name;
220             fromString.size = strlen(mask_name) + 1;
221             toFont.addr = (XPointer) &mask_font;
222             toFont.size = sizeof(Font);
223             /* XXX using display of screen argument as message display */
224 #ifdef XMU_KLUDGE
225             /* XXX Sacrifice caching */
226             num = 1;
227             success = XtCvtStringToFont(dpy, &cvtArg, &num, &fromString,
228                                         &toFont, NULL);
229 #else
230             success = XtCallConverter(dpy, XtCvtStringToFont, &cvtArg,
231                                       (Cardinal)1, &fromString, &toFont, NULL);
232 #endif
233             if (!success) {
234                 XtStringConversionWarning(name, XtRCursor);
235                 return;
236             }
237         }
238
239         cursor = XCreateGlyphCursor( DisplayOfScreen(screen), source_font,
240                                      mask_font, source_char, mask_char,
241                                      &fgColor, &bgColor );
242         done(&cursor, Cursor);
243         return;
244     }
245
246     i = XmuCursorNameToIndex (name);
247     if (i != -1) {
248         cursor = XCreateFontCursor (DisplayOfScreen(screen), i);
249         done(&cursor, Cursor);
250         return;
251     }
252
253     if ((source = XmuLocateBitmapFile (screen, name,
254                                        maskname, (sizeof maskname) - 4,
255                                        NULL, NULL, &xhot, &yhot)) == None) {
256         XtStringConversionWarning (name, XtRCursor);
257         cursor = None;
258         done(&cursor, Cursor);
259         return;
260     }
261     len = strlen (maskname);
262     for (i = 0; i < 2; i++) {
263         strcpy (maskname + len, i == 0 ? "Mask" : "msk");
264         if ((mask = XmuLocateBitmapFile (screen, maskname, NULL, 0,
265                                          NULL, NULL, NULL, NULL)) != None)
266           break;
267     }
268
269     cursor = XCreatePixmapCursor( DisplayOfScreen(screen), source, mask,
270                                   &fgColor, &bgColor, xhot, yhot );
271     XFreePixmap( DisplayOfScreen(screen), source );
272     if (mask != None) XFreePixmap( DisplayOfScreen(screen), mask );
273
274     done(&cursor, Cursor);
275 }
276
277 #define new_done(type, value) \
278         {                                                       \
279             if (toVal->addr != NULL) {                          \
280                 if (toVal->size < sizeof(type)) {               \
281                     toVal->size = sizeof(type);                 \
282                     return False;                               \
283                 }                                               \
284                 *(type*)(toVal->addr) = (value);                \
285             }                                                   \
286             else {                                              \
287                 static type static_val;                         \
288                 static_val = (value);                           \
289                 toVal->addr = (XPointer)&static_val;            \
290             }                                                   \
291             toVal->size = sizeof(type);                         \
292             return True;                                        \
293         }
294
295 /*      Function Name: XmuCvtStringToColorCursor
296  *      Description: Converts a string into a colored cursor.
297  *      Arguments: dpy
298  *                 args - an argument list (see below).
299  *                 num_args - number of elements in the argument list.
300  *                 fromVal - value to convert from.
301  *                 toVal - value to convert to.
302  *                 data
303  *      Returns:   True or False
304  */
305
306 /*ARGSUSED*/
307 Boolean
308 XmuCvtStringToColorCursor(Display *dpy, XrmValuePtr args, Cardinal *num_args,
309                           XrmValuePtr fromVal, XrmValuePtr toVal,
310                           XtPointer *converter_data)
311 {
312     Cursor cursor;
313     Screen *screen;
314     Pixel fg, bg;
315     Colormap c_map;
316     XColor colors[2];
317     Cardinal number;
318     XrmValue ret_val;
319
320     if (*num_args != 4) {
321         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
322             "wrongParameters","cvtStringToColorCursor","XmuError",
323             "String to color cursor conversion needs four arguments",
324             (String *)NULL, (Cardinal *)NULL);
325         return False;
326     }
327
328     screen = *((Screen **) args[0].addr);
329     fg = *((Pixel *) args[1].addr);
330     bg = *((Pixel *) args[2].addr);
331     c_map = *((Colormap *) args[3].addr);
332
333     number = 1;
334     XmuCvtStringToCursor(args, &number, fromVal, &ret_val);
335
336     cursor = *((Cursor *) ret_val.addr);
337
338     if (cursor == None || (fg == BlackPixelOfScreen(screen)
339                            && bg == WhitePixelOfScreen(screen)))
340         new_done(Cursor, cursor);
341
342     colors[0].pixel = fg;
343     colors[1].pixel = bg;
344
345     XQueryColors (dpy, c_map, colors, 2);
346     XRecolorCursor(dpy, cursor, colors, colors + 1);
347     new_done(Cursor, cursor);
348 }
349
350
351