1 /***********************************************************
2 Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
3 
4 Permission is hereby granted, free of charge, to any person obtaining a
5 copy of this software and associated documentation files (the "Software"),
6 to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and/or sell copies of the Software, and to permit persons to whom the
9 Software is furnished to do so, subject to the following conditions:
10 
11 The above copyright notice and this permission notice (including the next
12 paragraph) shall be included in all copies or substantial portions of the
13 Software.
14 
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 DEALINGS IN THE SOFTWARE.
22 
23 Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
24 
25                         All Rights Reserved
26 
27 Permission to use, copy, modify, and distribute this software and its
28 documentation for any purpose and without fee is hereby granted,
29 provided that the above copyright notice appear in all copies and that
30 both that copyright notice and this permission notice appear in
31 supporting documentation, and that the name of Digital not be
32 used in advertising or publicity pertaining to distribution of the
33 software without specific, written prior permission.
34 
35 DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
36 ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
37 DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
38 ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
39 WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
40 ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
41 SOFTWARE.
42 
43 ******************************************************************/
44 
45 /*
46 
47 Copyright 1987, 1988, 1994, 1998  The Open Group
48 
49 Permission to use, copy, modify, distribute, and sell this software and its
50 documentation for any purpose is hereby granted without fee, provided that
51 the above copyright notice appear in all copies and that both that
52 copyright notice and this permission notice appear in supporting
53 documentation.
54 
55 The above copyright notice and this permission notice shall be included in
56 all copies or substantial portions of the Software.
57 
58 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
61 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
62 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
63 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
64 
65 Except as contained in this notice, the name of The Open Group shall not be
66 used in advertising or otherwise to promote the sale, use or other dealings
67 in this Software without prior written authorization from The Open Group.
68 
69 */
70 
71 /* Conversion.c - implementations of resource type conversion procs */
72 
73 #ifdef HAVE_CONFIG_H
74 #include <config.h>
75 #endif
76 #include        "IntrinsicI.h"
77 #include        "StringDefs.h"
78 #include        "Shell.h"
79 #include        <stdio.h>
80 #include        <X11/cursorfont.h>
81 #include        <X11/keysym.h>
82 #include        <X11/Xlocale.h>
83 #include        <errno.h>       /* for StringToDirectoryString */
84 
85 #define IsNewline(str) ((str) == '\n')
86 #define IsWhitespace(str) ((str)== ' ' || (str) == '\t')
87 
88 static _Xconst _XtString XtNwrongParameters = "wrongParameters";
89 static _Xconst _XtString XtNconversionError = "conversionError";
90 static _Xconst _XtString XtNmissingCharsetList = "missingCharsetList";
91 
92 /* Representation types */
93 
94 #define XtQAtom                 XrmPermStringToQuark(XtRAtom)
95 #define XtQCommandArgArray      XrmPermStringToQuark(XtRCommandArgArray)
96 #define XtQCursor               XrmPermStringToQuark(XtRCursor)
97 #define XtQDirectoryString      XrmPermStringToQuark(XtRDirectoryString)
98 #define XtQDisplay              XrmPermStringToQuark(XtRDisplay)
99 #define XtQFile                 XrmPermStringToQuark(XtRFile)
100 #define XtQFloat                XrmPermStringToQuark(XtRFloat)
101 #define XtQInitialState         XrmPermStringToQuark(XtRInitialState)
102 #define XtQPixmap               XrmPermStringToQuark(XtRPixmap)
103 #define XtQRestartStyle         XrmPermStringToQuark(XtRRestartStyle)
104 #define XtQShort                XrmPermStringToQuark(XtRShort)
105 #define XtQUnsignedChar         XrmPermStringToQuark(XtRUnsignedChar)
106 #define XtQVisual               XrmPermStringToQuark(XtRVisual)
107 
108 static XrmQuark XtQBool;
109 static XrmQuark XtQBoolean;
110 static XrmQuark XtQColor;
111 static XrmQuark XtQDimension;
112 static XrmQuark XtQFont;
113 static XrmQuark XtQFontSet;
114 static XrmQuark XtQFontStruct;
115 static XrmQuark XtQGravity;
116 static XrmQuark XtQInt;
117 static XrmQuark XtQPixel;
118 static XrmQuark XtQPosition;
119 XrmQuark _XtQString;
120 
121 void
_XtConvertInitialize(void)122 _XtConvertInitialize(void)
123 {
124     XtQBool = XrmPermStringToQuark(XtRBool);
125     XtQBoolean = XrmPermStringToQuark(XtRBoolean);
126     XtQColor = XrmPermStringToQuark(XtRColor);
127     XtQDimension = XrmPermStringToQuark(XtRDimension);
128     XtQFont = XrmPermStringToQuark(XtRFont);
129     XtQFontSet = XrmPermStringToQuark(XtRFontSet);
130     XtQFontStruct = XrmPermStringToQuark(XtRFontStruct);
131     XtQGravity = XrmPermStringToQuark(XtRGravity);
132     XtQInt = XrmPermStringToQuark(XtRInt);
133     XtQPixel = XrmPermStringToQuark(XtRPixel);
134     XtQPosition = XrmPermStringToQuark(XtRPosition);
135     _XtQString = XrmPermStringToQuark(XtRString);
136 }
137 
138 #define done_typed_string(type, typed_value, tstr) \
139         {                                                       \
140             if (toVal->addr != NULL) {                          \
141                 if (toVal->size < sizeof(type)) {               \
142                     toVal->size = sizeof(type);                 \
143                     XtDisplayStringConversionWarning(dpy,       \
144                         (char*) fromVal->addr, tstr);           \
145                     return False;                               \
146                 }                                               \
147                 *(type*)(toVal->addr) = typed_value;            \
148             }                                                   \
149             else {                                              \
150                 static type static_val;                         \
151                 static_val = typed_value;                       \
152                 toVal->addr = (XPointer)&static_val;            \
153             }                                                   \
154             toVal->size = sizeof(type);                         \
155             return True;                                        \
156         }
157 
158 #define done_string(type, value, tstr) \
159         done_typed_string(type, (type) (value), tstr)
160 
161 #define done_typed(type, typed_value) \
162         {                                                       \
163             if (toVal->addr != NULL) {                          \
164                 if (toVal->size < sizeof(type)) {               \
165                     toVal->size = sizeof(type);                 \
166                     return False;                               \
167                 }                                               \
168                 *(type*)(toVal->addr) = typed_value;            \
169             }                                                   \
170             else {                                              \
171                 static type static_val;                         \
172                 static_val = typed_value;                       \
173                 toVal->addr = (XPointer)&static_val;            \
174             }                                                   \
175             toVal->size = sizeof(type);                         \
176             return True;                                        \
177         }
178 
179 #define done(type, value) \
180         done_typed(type, (type) (value))
181 
182 void
XtDisplayStringConversionWarning(Display * dpy,_Xconst char * from,_Xconst char * toType)183 XtDisplayStringConversionWarning(Display *dpy,
184                                  _Xconst char *from,
185                                  _Xconst char *toType)
186 {
187 #ifndef NO_MIT_HACKS
188     /* Allow suppression of conversion warnings. %%%  Not specified. */
189 
190     static enum { Check, Report, Ignore } report_it = Check;
191     XtAppContext app = XtDisplayToApplicationContext(dpy);
192 
193     LOCK_APP(app);
194     LOCK_PROCESS;
195     if (report_it == Check) {
196         XrmDatabase rdb = XtDatabase(dpy);
197         XrmName xrm_name[2];
198         XrmClass xrm_class[2];
199         XrmRepresentation rep_type;
200         XrmValue value;
201 
202         xrm_name[0] = XrmPermStringToQuark("stringConversionWarnings");
203         xrm_name[1] = 0;
204         xrm_class[0] = XrmPermStringToQuark("StringConversionWarnings");
205         xrm_class[1] = 0;
206         if (XrmQGetResource(rdb, xrm_name, xrm_class, &rep_type, &value)) {
207             if (rep_type == XtQBoolean)
208                 report_it = *(Boolean *) value.addr ? Report : Ignore;
209             else if (rep_type == _XtQString) {
210                 XrmValue toVal;
211                 Boolean report;
212 
213                 toVal.addr = (XPointer) &report;
214                 toVal.size = sizeof(Boolean);
215                 if (XtCallConverter
216                     (dpy, XtCvtStringToBoolean, (XrmValuePtr) NULL,
217                      (Cardinal) 0, &value, &toVal, (XtCacheRef *) NULL))
218                     report_it = report ? Report : Ignore;
219             }
220             else
221                 report_it = Report;
222         }
223         else
224             report_it = Report;
225     }
226 
227     if (report_it == Report) {
228 #endif                          /* ifndef NO_MIT_HACKS */
229         String params[2];
230         Cardinal num_params = 2;
231 
232         params[0] = (String) from;
233         params[1] = (String) toType;
234         XtAppWarningMsg(app,
235                         XtNconversionError, "string", XtCXtToolkitError,
236                         "Cannot convert string \"%s\" to type %s",
237                         params, &num_params);
238 #ifndef NO_MIT_HACKS
239     }
240 #endif                          /* ifndef NO_MIT_HACKS */
241     UNLOCK_PROCESS;
242     UNLOCK_APP(app);
243 }
244 
245 void
XtStringConversionWarning(_Xconst char * from,_Xconst char * toType)246 XtStringConversionWarning(_Xconst char *from, _Xconst char *toType)
247 {
248     String params[2];
249     Cardinal num_params = 2;
250 
251     params[0] = (String) from;
252     params[1] = (String) toType;
253     XtWarningMsg(XtNconversionError, "string", XtCXtToolkitError,
254                  "Cannot convert string \"%s\" to type %s",
255                  params, &num_params);
256 }
257 
258 static int CompareISOLatin1(const char *, const char *);
259 
260 static Boolean
IsInteger(String string,int * value)261 IsInteger(String string, int *value)
262 {
263     Boolean foundDigit = False;
264     Boolean isNegative = False;
265     Boolean isPositive = False;
266     int val = 0;
267     char ch;
268 
269     /* skip leading whitespace */
270     while ((ch = *string) == ' ' || ch == '\t')
271         string++;
272     while ((ch = *string++)) {
273         if (ch >= '0' && ch <= '9') {
274             val *= 10;
275             val += ch - '0';
276             foundDigit = True;
277             continue;
278         }
279         if (IsWhitespace(ch)) {
280             if (!foundDigit)
281                 return False;
282             /* make sure only trailing whitespace */
283             while ((ch = *string++)) {
284                 if (!IsWhitespace(ch))
285                     return False;
286             }
287             break;
288         }
289         if (ch == '-' && !foundDigit && !isNegative && !isPositive) {
290             isNegative = True;
291             continue;
292         }
293         if (ch == '+' && !foundDigit && !isNegative && !isPositive) {
294             isPositive = True;
295             continue;
296         }
297         return False;
298     }
299     if (ch == '\0') {
300         if (isNegative)
301             *value = -val;
302         else
303             *value = val;
304         return True;
305     }
306     return False;
307 }
308 
309 Boolean
XtCvtIntToBoolean(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)310 XtCvtIntToBoolean(Display *dpy,
311                   XrmValuePtr args _X_UNUSED,
312                   Cardinal *num_args,
313                   XrmValuePtr fromVal,
314                   XrmValuePtr toVal,
315                   XtPointer *closure_ret _X_UNUSED)
316 {
317     if (*num_args != 0)
318         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
319                         XtNwrongParameters, "cvtIntToBoolean",
320                         XtCXtToolkitError,
321                         "Integer to Boolean conversion needs no extra arguments",
322                         NULL, NULL);
323     done(Boolean, (*(int *) fromVal->addr != 0));
324 }
325 
326 Boolean
XtCvtIntToShort(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)327 XtCvtIntToShort(Display *dpy,
328                 XrmValuePtr args _X_UNUSED,
329                 Cardinal *num_args,
330                 XrmValuePtr fromVal,
331                 XrmValuePtr toVal,
332                 XtPointer *closure_ret _X_UNUSED)
333 {
334     if (*num_args != 0)
335         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
336                         XtNwrongParameters, "cvtIntToShort", XtCXtToolkitError,
337                         "Integer to Short conversion needs no extra arguments",
338                         NULL, NULL);
339     done(short, (*(int *) fromVal->addr));
340 }
341 
342 Boolean
XtCvtStringToBoolean(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)343 XtCvtStringToBoolean(Display *dpy,
344                      XrmValuePtr args _X_UNUSED,
345                      Cardinal *num_args,
346                      XrmValuePtr fromVal,
347                      XrmValuePtr toVal,
348                      XtPointer *closure_ret _X_UNUSED)
349 {
350     String str = (String) fromVal->addr;
351 
352     if (*num_args != 0)
353         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
354                         XtNwrongParameters, "cvtStringToBoolean",
355                         XtCXtToolkitError,
356                         "String to Boolean conversion needs no extra arguments",
357                         NULL, NULL);
358 
359     if ((CompareISOLatin1(str, "true") == 0)
360         || (CompareISOLatin1(str, "yes") == 0)
361         || (CompareISOLatin1(str, "on") == 0)
362         || (CompareISOLatin1(str, "1") == 0))
363         done_string(Boolean, True, XtRBoolean);
364 
365     if ((CompareISOLatin1(str, "false") == 0)
366         || (CompareISOLatin1(str, "no") == 0)
367         || (CompareISOLatin1(str, "off") == 0)
368         || (CompareISOLatin1(str, "0") == 0))
369         done_string(Boolean, False, XtRBoolean);
370 
371     XtDisplayStringConversionWarning(dpy, str, XtRBoolean);
372     return False;
373 }
374 
375 Boolean
XtCvtIntToBool(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)376 XtCvtIntToBool(Display *dpy,
377                XrmValuePtr args _X_UNUSED,
378                Cardinal *num_args,
379                XrmValuePtr fromVal,
380                XrmValuePtr toVal,
381                XtPointer *closure_ret _X_UNUSED)
382 {
383     if (*num_args != 0)
384         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
385                         XtNwrongParameters, "cvtIntToBool", XtCXtToolkitError,
386                         "Integer to Bool conversion needs no extra arguments",
387                         NULL, NULL);
388     done(Bool, (*(int *) fromVal->addr != 0));
389 }
390 
391 Boolean
XtCvtStringToBool(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)392 XtCvtStringToBool(Display *dpy,
393                   XrmValuePtr args _X_UNUSED,
394                   Cardinal *num_args,
395                   XrmValuePtr fromVal,
396                   XrmValuePtr toVal,
397                   XtPointer *closure_ret _X_UNUSED)
398 {
399     String str = (String) fromVal->addr;
400 
401     if (*num_args != 0)
402         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
403                         XtNwrongParameters, "cvtStringToBool",
404                         XtCXtToolkitError,
405                         "String to Bool conversion needs no extra arguments",
406                         NULL, NULL);
407 
408     if ((CompareISOLatin1(str, "true") == 0)
409         || (CompareISOLatin1(str, "yes") == 0)
410         || (CompareISOLatin1(str, "on") == 0)
411         || (CompareISOLatin1(str, "1") == 0))
412         done_string(Bool, True, XtRBool);
413 
414     if ((CompareISOLatin1(str, "false") == 0)
415         || (CompareISOLatin1(str, "no") == 0)
416         || (CompareISOLatin1(str, "off") == 0)
417         || (CompareISOLatin1(str, "0") == 0))
418         done_string(Bool, False, XtRBool);
419 
420     XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr, XtRBool);
421     return False;
422 }
423 
424 /* *INDENT-OFF* */
425 XtConvertArgRec const colorConvertArgs[] = {
426     {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen),
427      sizeof(Screen *)},
428     {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.colormap),
429      sizeof(Colormap)}
430 };
431 /* *INDENT-ON* */
432 
433 Boolean
XtCvtIntToColor(Display * dpy,XrmValuePtr args,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)434 XtCvtIntToColor(Display *dpy,
435                 XrmValuePtr args,
436                 Cardinal *num_args,
437                 XrmValuePtr fromVal,
438                 XrmValuePtr toVal,
439                 XtPointer *closure_ret _X_UNUSED)
440 {
441     XColor c;
442     Screen *screen;
443     Colormap colormap;
444 
445     if (*num_args != 2) {
446         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
447                         XtNwrongParameters, "cvtIntOrPixelToXColor",
448                         XtCXtToolkitError,
449                         "Pixel to color conversion needs screen and colormap arguments",
450                         NULL, NULL);
451         return False;
452     }
453     screen = *((Screen **) args[0].addr);
454     colormap = *((Colormap *) args[1].addr);
455     c.pixel = (unsigned long) (*(int *) fromVal->addr);
456 
457     XQueryColor(DisplayOfScreen(screen), colormap, &c);
458     done_typed(XColor, c);
459 }
460 
461 Boolean
XtCvtStringToPixel(Display * dpy,XrmValuePtr args,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret)462 XtCvtStringToPixel(Display *dpy,
463                    XrmValuePtr args,
464                    Cardinal *num_args,
465                    XrmValuePtr fromVal,
466                    XrmValuePtr toVal,
467                    XtPointer *closure_ret)
468 {
469     String str = (String) fromVal->addr;
470     XColor screenColor;
471     XColor exactColor;
472     Screen *screen;
473     XtPerDisplay pd = _XtGetPerDisplay(dpy);
474     Colormap colormap;
475     Status status;
476     Cardinal num_params = 1;
477 
478     if (*num_args != 2) {
479         XtAppWarningMsg(pd->appContext, XtNwrongParameters, "cvtStringToPixel",
480                         XtCXtToolkitError,
481                         "String to pixel conversion needs screen and colormap arguments",
482                         NULL, NULL);
483         return False;
484     }
485 
486     screen = *((Screen **) args[0].addr);
487     colormap = *((Colormap *) args[1].addr);
488 
489     if (CompareISOLatin1(str, XtDefaultBackground) == 0) {
490         *closure_ret = NULL;
491         if (pd->rv) {
492             done_string(Pixel, BlackPixelOfScreen(screen), XtRPixel);
493         }
494         else {
495             done_string(Pixel, WhitePixelOfScreen(screen), XtRPixel);
496         }
497     }
498     if (CompareISOLatin1(str, XtDefaultForeground) == 0) {
499         *closure_ret = NULL;
500         if (pd->rv) {
501             done_string(Pixel, WhitePixelOfScreen(screen), XtRPixel);
502         }
503         else {
504             done_string(Pixel, BlackPixelOfScreen(screen), XtRPixel);
505         }
506     }
507 
508     status = XAllocNamedColor(DisplayOfScreen(screen), colormap,
509                               (_Xconst char *) str, &screenColor, &exactColor);
510     if (status == 0) {
511         _Xconst _XtString msg;
512         _Xconst _XtString type;
513         String params[1];
514 
515         params[0] = str;
516         /* Server returns a specific error code but Xlib discards it.  Ugh */
517         if (XLookupColor
518             (DisplayOfScreen(screen), colormap, (_Xconst char *) str,
519              &exactColor, &screenColor)) {
520             type = "noColormap";
521             msg = "Cannot allocate colormap entry for \"%s\"";
522         }
523         else {
524             type = "badValue";
525             msg = "Color name \"%s\" is not defined";
526         }
527 
528         XtAppWarningMsg(pd->appContext, type, "cvtStringToPixel",
529                         XtCXtToolkitError, msg, params, &num_params);
530         *closure_ret = NULL;
531         return False;
532     }
533     else {
534         *closure_ret = (char *) True;
535         done_string(Pixel, screenColor.pixel, XtRPixel);
536     }
537 }
538 
539 static void
FreePixel(XtAppContext app,XrmValuePtr toVal,XtPointer closure,XrmValuePtr args,Cardinal * num_args)540 FreePixel(XtAppContext app,
541           XrmValuePtr toVal,
542           XtPointer closure,
543           XrmValuePtr args,
544           Cardinal *num_args)
545 {
546     Screen *screen;
547     Colormap colormap;
548 
549     if (*num_args != 2) {
550         XtAppWarningMsg(app, XtNwrongParameters, "freePixel", XtCXtToolkitError,
551                         "Freeing a pixel requires screen and colormap arguments",
552                         NULL, NULL);
553         return;
554     }
555 
556     screen = *((Screen **) args[0].addr);
557     colormap = *((Colormap *) args[1].addr);
558 
559     if (closure) {
560         XFreeColors(DisplayOfScreen(screen), colormap,
561                     (unsigned long *) toVal->addr, 1, (unsigned long) 0);
562     }
563 }
564 
565 /* no longer used by Xt, but it's in the spec */
566 XtConvertArgRec const screenConvertArg[] = {
567     {XtWidgetBaseOffset, (XtPointer) XtOffsetOf(WidgetRec, core.screen),
568      sizeof(Screen *)}
569 };
570 
571 static void
FetchDisplayArg(Widget widget,Cardinal * size _X_UNUSED,XrmValue * value)572 FetchDisplayArg(Widget widget, Cardinal *size _X_UNUSED, XrmValue *value)
573 {
574     if (widget == NULL) {
575         XtErrorMsg("missingWidget", "fetchDisplayArg", XtCXtToolkitError,
576                    "FetchDisplayArg called without a widget to reference",
577                    NULL, NULL);
578         /* can't return any useful Display and caller will de-ref NULL,
579            so aborting is the only useful option */
580     }
581     else {
582         value->size = sizeof(Display *);
583         value->addr = (XPointer) &DisplayOfScreen(XtScreenOfObject(widget));
584     }
585 }
586 
587 /* *INDENT-OFF* */
588 static XtConvertArgRec const displayConvertArg[] = {
589     {XtProcedureArg, (XtPointer)FetchDisplayArg, 0},
590 };
591 /* *INDENT-ON* */
592 
593 Boolean
XtCvtStringToCursor(Display * dpy,XrmValuePtr args,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)594 XtCvtStringToCursor(Display *dpy,
595                     XrmValuePtr args,
596                     Cardinal *num_args,
597                     XrmValuePtr fromVal,
598                     XrmValuePtr toVal,
599                     XtPointer *closure_ret _X_UNUSED)
600 {
601     /* *INDENT-OFF* */
602     static const struct _CursorName {
603         const char      *name;
604         unsigned int    shape;
605     } cursor_names[] = {
606         {"X_cursor",            XC_X_cursor},
607         {"arrow",               XC_arrow},
608         {"based_arrow_down",    XC_based_arrow_down},
609         {"based_arrow_up",      XC_based_arrow_up},
610         {"boat",                XC_boat},
611         {"bogosity",            XC_bogosity},
612         {"bottom_left_corner",  XC_bottom_left_corner},
613         {"bottom_right_corner", XC_bottom_right_corner},
614         {"bottom_side",         XC_bottom_side},
615         {"bottom_tee",          XC_bottom_tee},
616         {"box_spiral",          XC_box_spiral},
617         {"center_ptr",          XC_center_ptr},
618         {"circle",              XC_circle},
619         {"clock",               XC_clock},
620         {"coffee_mug",          XC_coffee_mug},
621         {"cross",               XC_cross},
622         {"cross_reverse",       XC_cross_reverse},
623         {"crosshair",           XC_crosshair},
624         {"diamond_cross",       XC_diamond_cross},
625         {"dot",                 XC_dot},
626         {"dotbox",              XC_dotbox},
627         {"double_arrow",        XC_double_arrow},
628         {"draft_large",         XC_draft_large},
629         {"draft_small",         XC_draft_small},
630         {"draped_box",          XC_draped_box},
631         {"exchange",            XC_exchange},
632         {"fleur",               XC_fleur},
633         {"gobbler",             XC_gobbler},
634         {"gumby",               XC_gumby},
635         {"hand1",               XC_hand1},
636         {"hand2",               XC_hand2},
637         {"heart",               XC_heart},
638         {"icon",                XC_icon},
639         {"iron_cross",          XC_iron_cross},
640         {"left_ptr",            XC_left_ptr},
641         {"left_side",           XC_left_side},
642         {"left_tee",            XC_left_tee},
643         {"leftbutton",          XC_leftbutton},
644         {"ll_angle",            XC_ll_angle},
645         {"lr_angle",            XC_lr_angle},
646         {"man",                 XC_man},
647         {"middlebutton",        XC_middlebutton},
648         {"mouse",               XC_mouse},
649         {"pencil",              XC_pencil},
650         {"pirate",              XC_pirate},
651         {"plus",                XC_plus},
652         {"question_arrow",      XC_question_arrow},
653         {"right_ptr",           XC_right_ptr},
654         {"right_side",          XC_right_side},
655         {"right_tee",           XC_right_tee},
656         {"rightbutton",         XC_rightbutton},
657         {"rtl_logo",            XC_rtl_logo},
658         {"sailboat",            XC_sailboat},
659         {"sb_down_arrow",       XC_sb_down_arrow},
660         {"sb_h_double_arrow",   XC_sb_h_double_arrow},
661         {"sb_left_arrow",       XC_sb_left_arrow},
662         {"sb_right_arrow",      XC_sb_right_arrow},
663         {"sb_up_arrow",         XC_sb_up_arrow},
664         {"sb_v_double_arrow",   XC_sb_v_double_arrow},
665         {"shuttle",             XC_shuttle},
666         {"sizing",              XC_sizing},
667         {"spider",              XC_spider},
668         {"spraycan",            XC_spraycan},
669         {"star",                XC_star},
670         {"target",              XC_target},
671         {"tcross",              XC_tcross},
672         {"top_left_arrow",      XC_top_left_arrow},
673         {"top_left_corner",     XC_top_left_corner},
674         {"top_right_corner",    XC_top_right_corner},
675         {"top_side",            XC_top_side},
676         {"top_tee",             XC_top_tee},
677         {"trek",                XC_trek},
678         {"ul_angle",            XC_ul_angle},
679         {"umbrella",            XC_umbrella},
680         {"ur_angle",            XC_ur_angle},
681         {"watch",               XC_watch},
682         {"xterm",               XC_xterm},
683     };
684     /* *INDENT-ON* */
685     const struct _CursorName *nP;
686     char *name = (char *) fromVal->addr;
687     register Cardinal i;
688 
689     if (*num_args != 1) {
690         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
691                         XtNwrongParameters, "cvtStringToCursor",
692                         XtCXtToolkitError,
693                         "String to cursor conversion needs display argument",
694                         NULL, NULL);
695         return False;
696     }
697 
698     for (i = 0, nP = cursor_names; i < XtNumber(cursor_names); i++, nP++) {
699         if (strcmp(name, nP->name) == 0) {
700             Display *display = *(Display **) args[0].addr;
701             Cursor cursor = XCreateFontCursor(display, nP->shape);
702 
703             done_string(Cursor, cursor, XtRCursor);
704         }
705     }
706     XtDisplayStringConversionWarning(dpy, name, XtRCursor);
707     return False;
708 }
709 
710 static void
FreeCursor(XtAppContext app,XrmValuePtr toVal,XtPointer closure _X_UNUSED,XrmValuePtr args,Cardinal * num_args)711 FreeCursor(XtAppContext app,
712            XrmValuePtr toVal,
713            XtPointer closure _X_UNUSED,
714            XrmValuePtr args,
715            Cardinal *num_args)
716 {
717     Display *display;
718 
719     if (*num_args != 1) {
720         XtAppWarningMsg(app,
721                         XtNwrongParameters, "freeCursor", XtCXtToolkitError,
722                         "Free Cursor requires display argument", NULL, NULL);
723         return;
724     }
725 
726     display = *(Display **) args[0].addr;
727     XFreeCursor(display, *(Cursor *) toVal->addr);
728 }
729 
730 Boolean
XtCvtStringToDisplay(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)731 XtCvtStringToDisplay(Display *dpy,
732                      XrmValuePtr args _X_UNUSED,
733                      Cardinal *num_args,
734                      XrmValuePtr fromVal,
735                      XrmValuePtr toVal,
736                      XtPointer *closure_ret _X_UNUSED)
737 {
738     Display *d;
739 
740     if (*num_args != 0)
741         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
742                         XtNwrongParameters, "cvtStringToDisplay",
743                         XtCXtToolkitError,
744                         "String to Display conversion needs no extra arguments",
745                         NULL, NULL);
746 
747     d = XOpenDisplay((char *) fromVal->addr);
748     if (d != NULL)
749         done_string(Display *, d, XtRDisplay);
750 
751     XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr, XtRDisplay);
752     return False;
753 }
754 
755 Boolean
XtCvtStringToFile(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)756 XtCvtStringToFile(Display *dpy,
757                   XrmValuePtr args _X_UNUSED,
758                   Cardinal *num_args,
759                   XrmValuePtr fromVal,
760                   XrmValuePtr toVal,
761                   XtPointer *closure_ret _X_UNUSED)
762 {
763     FILE *f;
764 
765     if (*num_args != 0)
766         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
767                         XtNwrongParameters, "cvtStringToFile",
768                         XtCXtToolkitError,
769                         "String to File conversion needs no extra arguments",
770                         NULL, NULL);
771 
772     f = fopen((char *) fromVal->addr, "r");
773     if (f != NULL)
774         done_string(FILE *, f, XtRFile);
775 
776     XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr, XtRFile);
777     return False;
778 }
779 
780 static void
FreeFile(XtAppContext app,XrmValuePtr toVal,XtPointer closure _X_UNUSED,XrmValuePtr args _X_UNUSED,Cardinal * num_args)781 FreeFile(XtAppContext app,
782          XrmValuePtr toVal,
783          XtPointer closure _X_UNUSED,
784          XrmValuePtr args _X_UNUSED,
785          Cardinal *num_args)
786 {
787     if (*num_args != 0)
788         XtAppWarningMsg(app,
789                         XtNwrongParameters, "freeFile", XtCXtToolkitError,
790                         "Free File requires no extra arguments", NULL, NULL);
791 
792     fclose(*(FILE **) toVal->addr);
793 }
794 
795 Boolean
XtCvtIntToFloat(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)796 XtCvtIntToFloat(Display *dpy,
797                 XrmValuePtr args _X_UNUSED,
798                 Cardinal *num_args,
799                 XrmValuePtr fromVal,
800                 XrmValuePtr toVal,
801                 XtPointer *closure_ret _X_UNUSED)
802 {
803     if (*num_args != 0)
804         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
805                         XtNwrongParameters, "cvtIntToFloat", XtCXtToolkitError,
806                         "Integer to Float conversion needs no extra arguments",
807                         NULL, NULL);
808     done(float, (*(int *) fromVal->addr));
809 }
810 
811 Boolean
XtCvtStringToFloat(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)812 XtCvtStringToFloat(Display *dpy,
813                    XrmValuePtr args _X_UNUSED,
814                    Cardinal *num_args,
815                    XrmValuePtr fromVal,
816                    XrmValuePtr toVal,
817                    XtPointer *closure_ret _X_UNUSED)
818 {
819     int ret;
820     float f, nan;
821 
822     (void) sscanf("NaN", "%g",
823                   toVal->addr != NULL ? (float *) toVal->addr : &nan);
824 
825     if (*num_args != 0)
826         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
827                         XtNwrongParameters, "cvtStringToFloat",
828                         XtCXtToolkitError,
829                         "String to Float conversion needs no extra arguments",
830                         NULL, NULL);
831 
832     ret = sscanf(fromVal->addr, "%g", &f);
833     if (ret == 0) {
834         if (toVal->addr != NULL && toVal->size == sizeof nan)
835             *(float *) toVal->addr = nan;
836         XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr, XtRFloat);
837         return False;
838     }
839     done_string(float, f, XtRFloat);
840 }
841 
842 Boolean
XtCvtStringToFont(Display * dpy,XrmValuePtr args,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)843 XtCvtStringToFont(Display *dpy,
844                   XrmValuePtr args,
845                   Cardinal *num_args,
846                   XrmValuePtr fromVal,
847                   XrmValuePtr toVal,
848                   XtPointer *closure_ret _X_UNUSED)
849 {
850     Font f;
851     Display *display;
852 
853     if (*num_args != 1) {
854         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
855                         XtNwrongParameters, "cvtStringToFont",
856                         XtCXtToolkitError,
857                         "String to font conversion needs display argument",
858                         NULL, NULL);
859         return False;
860     }
861 
862     display = *(Display **) args[0].addr;
863 
864     if (CompareISOLatin1((String) fromVal->addr, XtDefaultFont) != 0) {
865         f = XLoadFont(display, (char *) fromVal->addr);
866 
867         if (f != 0) {
868  Done:     done_string(Font, f, XtRFont);
869         }
870         XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr, XtRFont);
871     }
872     /* try and get the default font */
873 
874     {
875         XrmName xrm_name[2];
876         XrmClass xrm_class[2];
877         XrmRepresentation rep_type;
878         XrmValue value;
879 
880         xrm_name[0] = XrmPermStringToQuark("xtDefaultFont");
881         xrm_name[1] = 0;
882         xrm_class[0] = XrmPermStringToQuark("XtDefaultFont");
883         xrm_class[1] = 0;
884         if (XrmQGetResource(XtDatabase(display), xrm_name, xrm_class,
885                             &rep_type, &value)) {
886             if (rep_type == _XtQString) {
887                 f = XLoadFont(display, (char *) value.addr);
888 
889                 if (f != 0)
890                     goto Done;
891                 else
892                     XtDisplayStringConversionWarning(dpy, (char *) value.addr,
893                                                      XtRFont);
894             }
895             else if (rep_type == XtQFont) {
896                 f = *(Font *) value.addr;
897                 goto Done;
898             }
899             else if (rep_type == XtQFontStruct) {
900                 f = ((XFontStruct *) value.addr)->fid;
901                 goto Done;
902             }
903         }
904     }
905     /* Should really do XListFonts, but most servers support this */
906     f = XLoadFont(display, "-*-*-*-R-*-*-*-120-*-*-*-*-ISO8859-*");
907 
908     if (f != 0)
909         goto Done;
910 
911     XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
912                     "noFont", "cvtStringToFont", XtCXtToolkitError,
913                     "Unable to load any usable ISO8859 font", NULL, NULL);
914 
915     return False;
916 }
917 
918 static void
FreeFont(XtAppContext app,XrmValuePtr toVal,XtPointer closure _X_UNUSED,XrmValuePtr args,Cardinal * num_args)919 FreeFont(XtAppContext app,
920          XrmValuePtr toVal,
921          XtPointer closure _X_UNUSED,
922          XrmValuePtr args,
923          Cardinal *num_args)
924 {
925     Display *display;
926 
927     if (*num_args != 1) {
928         XtAppWarningMsg(app,
929                         XtNwrongParameters, "freeFont", XtCXtToolkitError,
930                         "Free Font needs display argument", NULL, NULL);
931         return;
932     }
933 
934     display = *(Display **) args[0].addr;
935     XUnloadFont(display, *(Font *) toVal->addr);
936 }
937 
938 Boolean
XtCvtIntToFont(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)939 XtCvtIntToFont(Display *dpy,
940                XrmValuePtr args _X_UNUSED,
941                Cardinal *num_args,
942                XrmValuePtr fromVal,
943                XrmValuePtr toVal,
944                XtPointer *closure_ret _X_UNUSED)
945 {
946     if (*num_args != 0)
947         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
948                         XtNwrongParameters, "cvtIntToFont", XtCXtToolkitError,
949                         "Integer to Font conversion needs no extra arguments",
950                         NULL, NULL);
951     done(Font, *(int *) fromVal->addr);
952 }
953 
954 Boolean
XtCvtStringToFontSet(Display * dpy,XrmValuePtr args,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)955 XtCvtStringToFontSet(Display *dpy,
956                      XrmValuePtr args,
957                      Cardinal *num_args,
958                      XrmValuePtr fromVal,
959                      XrmValuePtr toVal,
960                      XtPointer *closure_ret _X_UNUSED)
961 {
962     XFontSet f;
963     Display *display;
964     char **missing_charset_list;
965     int missing_charset_count;
966     char *def_string;
967 
968     if (*num_args != 2) {
969         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
970                         XtNwrongParameters, "cvtStringToFontSet",
971                         XtCXtToolkitError,
972                         "String to FontSet conversion needs display and locale arguments",
973                         NULL, NULL);
974         return False;
975     }
976 
977     display = *(Display **) args[0].addr;
978 
979     if (CompareISOLatin1((String) fromVal->addr, XtDefaultFontSet) != 0) {
980         f = XCreateFontSet(display, (char *) fromVal->addr,
981                            &missing_charset_list, &missing_charset_count,
982                            &def_string);
983         /* Free any returned missing charset list */
984         if (missing_charset_count) {
985             XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
986                             XtNmissingCharsetList, "cvtStringToFontSet",
987                             XtCXtToolkitError,
988                             "Missing charsets in String to FontSet conversion",
989                             NULL, NULL);
990             XFreeStringList(missing_charset_list);
991         }
992         if (f != NULL) {
993  Done:     done_string(XFontSet, f, XtRFontSet);
994         }
995         XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr,
996                                          XtRFontSet);
997     }
998     /* try and get the default fontset */
999 
1000     {
1001         XrmName xrm_name[2];
1002         XrmClass xrm_class[2];
1003         XrmRepresentation rep_type;
1004         XrmValue value;
1005 
1006         xrm_name[0] = XrmPermStringToQuark("xtDefaultFontSet");
1007         xrm_name[1] = 0;
1008         xrm_class[0] = XrmPermStringToQuark("XtDefaultFontSet");
1009         xrm_class[1] = 0;
1010         if (XrmQGetResource(XtDatabase(display), xrm_name, xrm_class,
1011                             &rep_type, &value)) {
1012             if (rep_type == _XtQString) {
1013 
1014                 f = XCreateFontSet(display, (char *) value.addr,
1015                                    &missing_charset_list,
1016                                    &missing_charset_count, &def_string);
1017                 /* Free any returned missing charset list */
1018                 if (missing_charset_count) {
1019                     XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1020                                     XtNmissingCharsetList, "cvtStringToFontSet",
1021                                     XtCXtToolkitError,
1022                                     "Missing charsets in String to FontSet conversion",
1023                                     NULL, NULL);
1024                     XFreeStringList(missing_charset_list);
1025                 }
1026                 if (f != NULL)
1027                     goto Done;
1028                 else
1029                     XtDisplayStringConversionWarning(dpy, (char *) value.addr,
1030                                                      XtRFontSet);
1031             }
1032             else if (rep_type == XtQFontSet) {
1033                 f = *(XFontSet *) value.addr;
1034                 goto Done;
1035             }
1036         }
1037     }
1038 
1039     /* Should really do XListFonts, but most servers support this */
1040     f = XCreateFontSet(display, "-*-*-*-R-*-*-*-120-*-*-*-*,*",
1041                        &missing_charset_list, &missing_charset_count,
1042                        &def_string);
1043 
1044     /* Free any returned missing charset list */
1045     if (missing_charset_count) {
1046         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1047                         XtNmissingCharsetList, "cvtStringToFontSet",
1048                         XtCXtToolkitError,
1049                         "Missing charsets in String to FontSet conversion",
1050                         NULL, NULL);
1051         XFreeStringList(missing_charset_list);
1052     }
1053     if (f != NULL)
1054         goto Done;
1055 
1056     XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1057                     "noFont", "cvtStringToFontSet", XtCXtToolkitError,
1058                     "Unable to load any usable fontset", NULL, NULL);
1059 
1060     return False;
1061 }
1062 
1063 static void
FreeFontSet(XtAppContext app,XrmValuePtr toVal,XtPointer closure _X_UNUSED,XrmValuePtr args,Cardinal * num_args)1064 FreeFontSet(XtAppContext app,
1065             XrmValuePtr toVal,
1066             XtPointer closure _X_UNUSED,
1067             XrmValuePtr args,
1068             Cardinal *num_args)
1069 {
1070     Display *display;
1071 
1072     if (*num_args != 2) {
1073         XtAppWarningMsg(app,
1074                         XtNwrongParameters, "freeFontSet", XtCXtToolkitError,
1075                         "FreeFontSet needs display and locale arguments",
1076                         NULL, NULL);
1077         return;
1078     }
1079 
1080     display = *(Display **) args[0].addr;
1081     XFreeFontSet(display, *(XFontSet *) toVal->addr);
1082 }
1083 
1084 static void
FetchLocaleArg(Widget widget _X_UNUSED,Cardinal * size _X_UNUSED,XrmValue * value)1085 FetchLocaleArg(Widget widget _X_UNUSED,
1086                Cardinal *size _X_UNUSED,
1087                XrmValue *value)
1088 {
1089     static XrmString locale;
1090 
1091     locale = XrmQuarkToString(XrmStringToQuark
1092                               (setlocale(LC_CTYPE, (char *) NULL)));
1093     value->size = sizeof(XrmString);
1094     value->addr = (XPointer) &locale;
1095 }
1096 
1097 /* *INDENT-OFF* */
1098 static XtConvertArgRec const localeDisplayConvertArgs[] = {
1099     {XtProcedureArg, (XtPointer)FetchDisplayArg, 0},
1100     {XtProcedureArg, (XtPointer)FetchLocaleArg, 0},
1101 };
1102 /* *INDENT-ON* */
1103 
1104 Boolean
XtCvtStringToFontStruct(Display * dpy,XrmValuePtr args,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)1105 XtCvtStringToFontStruct(Display *dpy,
1106                         XrmValuePtr args,
1107                         Cardinal *num_args,
1108                         XrmValuePtr fromVal,
1109                         XrmValuePtr toVal,
1110                         XtPointer *closure_ret _X_UNUSED)
1111 {
1112     XFontStruct *f;
1113     Display *display;
1114 
1115     if (*num_args != 1) {
1116         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1117                         XtNwrongParameters, "cvtStringToFontStruct",
1118                         XtCXtToolkitError,
1119                         "String to font conversion needs display argument",
1120                         NULL, NULL);
1121         return False;
1122     }
1123 
1124     display = *(Display **) args[0].addr;
1125 
1126     if (CompareISOLatin1((String) fromVal->addr, XtDefaultFont) != 0) {
1127         f = XLoadQueryFont(display, (char *) fromVal->addr);
1128 
1129         if (f != NULL) {
1130  Done:     done_string(XFontStruct *, f, XtRFontStruct);
1131         }
1132 
1133         XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr,
1134                                          XtRFontStruct);
1135     }
1136 
1137     /* try and get the default font */
1138 
1139     {
1140         XrmName xrm_name[2];
1141         XrmClass xrm_class[2];
1142         XrmRepresentation rep_type;
1143         XrmValue value;
1144 
1145         xrm_name[0] = XrmPermStringToQuark("xtDefaultFont");
1146         xrm_name[1] = 0;
1147         xrm_class[0] = XrmPermStringToQuark("XtDefaultFont");
1148         xrm_class[1] = 0;
1149         if (XrmQGetResource(XtDatabase(display), xrm_name, xrm_class,
1150                             &rep_type, &value)) {
1151             if (rep_type == _XtQString) {
1152                 f = XLoadQueryFont(display, (char *) value.addr);
1153 
1154                 if (f != NULL)
1155                     goto Done;
1156                 else
1157                     XtDisplayStringConversionWarning(dpy, (char *) value.addr,
1158                                                      XtRFontStruct);
1159             }
1160             else if (rep_type == XtQFont) {
1161                 f = XQueryFont(display, *(Font *) value.addr);
1162 
1163                 if (f != NULL)
1164                     goto Done;
1165             }
1166             else if (rep_type == XtQFontStruct) {
1167                 f = (XFontStruct *) value.addr;
1168                 goto Done;
1169             }
1170         }
1171     }
1172     /* Should really do XListFonts, but most servers support this */
1173     f = XLoadQueryFont(display, "-*-*-*-R-*-*-*-120-*-*-*-*-ISO8859-*");
1174 
1175     if (f != NULL)
1176         goto Done;
1177 
1178     XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1179                     "noFont", "cvtStringToFontStruct", XtCXtToolkitError,
1180                     "Unable to load any usable ISO8859 font", NULL, NULL);
1181 
1182     return False;
1183 }
1184 
1185 static void
FreeFontStruct(XtAppContext app,XrmValuePtr toVal,XtPointer closure _X_UNUSED,XrmValuePtr args,Cardinal * num_args)1186 FreeFontStruct(XtAppContext app,
1187                XrmValuePtr toVal,
1188                XtPointer closure _X_UNUSED,
1189                XrmValuePtr args,
1190                Cardinal *num_args)
1191 {
1192     Display *display;
1193 
1194     if (*num_args != 1) {
1195         XtAppWarningMsg(app,
1196                         XtNwrongParameters, "freeFontStruct", XtCXtToolkitError,
1197                         "Free FontStruct requires display argument",
1198                         NULL, NULL);
1199         return;
1200     }
1201 
1202     display = *(Display **) args[0].addr;
1203     XFreeFont(display, *(XFontStruct **) toVal->addr);
1204 }
1205 
1206 Boolean
XtCvtStringToInt(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)1207 XtCvtStringToInt(Display *dpy,
1208                  XrmValuePtr args _X_UNUSED,
1209                  Cardinal *num_args,
1210                  XrmValuePtr fromVal,
1211                  XrmValuePtr toVal,
1212                  XtPointer *closure_ret _X_UNUSED)
1213 {
1214     int i;
1215 
1216     if (*num_args != 0)
1217         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1218                         XtNwrongParameters, "cvtStringToInt", XtCXtToolkitError,
1219                         "String to Integer conversion needs no extra arguments",
1220                         NULL, NULL);
1221     if (IsInteger((String) fromVal->addr, &i))
1222         done_string(int, i, XtRInt);
1223 
1224     XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr, XtRInt);
1225     return False;
1226 }
1227 
1228 Boolean
XtCvtStringToShort(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)1229 XtCvtStringToShort(Display *dpy,
1230                    XrmValuePtr args _X_UNUSED,
1231                    Cardinal *num_args,
1232                    XrmValuePtr fromVal,
1233                    XrmValuePtr toVal,
1234                    XtPointer *closure_ret _X_UNUSED)
1235 {
1236     int i;
1237 
1238     if (*num_args != 0)
1239         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1240                         XtNwrongParameters, "cvtStringToShort",
1241                         XtCXtToolkitError,
1242                         "String to Integer conversion needs no extra arguments",
1243                         NULL, NULL);
1244     if (IsInteger((String) fromVal->addr, &i))
1245         done_string(short, (short) i, XtRShort);
1246 
1247     XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr, XtRShort);
1248     return False;
1249 }
1250 
1251 Boolean
XtCvtStringToDimension(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)1252 XtCvtStringToDimension(Display *dpy,
1253                        XrmValuePtr args _X_UNUSED,
1254                        Cardinal *num_args,
1255                        XrmValuePtr fromVal,
1256                        XrmValuePtr toVal,
1257                        XtPointer *closure_ret _X_UNUSED)
1258 {
1259     int i;
1260 
1261     if (*num_args != 0)
1262         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1263                         XtNwrongParameters, "cvtStringToDimension",
1264                         XtCXtToolkitError,
1265                         "String to Dimension conversion needs no extra arguments",
1266                         NULL, NULL);
1267     if (IsInteger((String) fromVal->addr, &i)) {
1268         if (i < 0)
1269             XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr,
1270                                              XtRDimension);
1271         done_string(Dimension, (Dimension) i, XtRDimension);
1272     }
1273     XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr, XtRDimension);
1274     return False;
1275 }
1276 
1277 Boolean
XtCvtIntToUnsignedChar(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)1278 XtCvtIntToUnsignedChar(Display *dpy,
1279                        XrmValuePtr args _X_UNUSED,
1280                        Cardinal *num_args,
1281                        XrmValuePtr fromVal,
1282                        XrmValuePtr toVal,
1283                        XtPointer *closure_ret _X_UNUSED)
1284 {
1285     if (*num_args != 0)
1286         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1287                         XtNwrongParameters, "cvtIntToUnsignedChar",
1288                         XtCXtToolkitError,
1289                         "Integer to UnsignedChar conversion needs no extra arguments",
1290                         NULL, NULL);
1291     done(unsigned char, (*(int *) fromVal->addr));
1292 }
1293 
1294 Boolean
XtCvtStringToUnsignedChar(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)1295 XtCvtStringToUnsignedChar(Display *dpy,
1296                           XrmValuePtr args _X_UNUSED,
1297                           Cardinal *num_args,
1298                           XrmValuePtr fromVal,
1299                           XrmValuePtr toVal,
1300                           XtPointer *closure_ret _X_UNUSED)
1301 {
1302     int i;
1303 
1304     if (*num_args != 0)
1305         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1306                         XtNwrongParameters, "cvtStringToUnsignedChar",
1307                         XtCXtToolkitError,
1308                         "String to Integer conversion needs no extra arguments",
1309                         NULL, NULL);
1310     if (IsInteger((String) fromVal->addr, &i)) {
1311         if (i < 0 || i > 255)
1312             XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr,
1313                                              XtRUnsignedChar);
1314         done_string(unsigned char, i, XtRUnsignedChar);
1315     }
1316     XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr,
1317                                      XtRUnsignedChar);
1318     return False;
1319 }
1320 
1321 Boolean
XtCvtColorToPixel(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)1322 XtCvtColorToPixel(Display *dpy,
1323                   XrmValuePtr args _X_UNUSED,
1324                   Cardinal *num_args,
1325                   XrmValuePtr fromVal,
1326                   XrmValuePtr toVal,
1327                   XtPointer *closure_ret _X_UNUSED)
1328 {
1329     if (*num_args != 0)
1330         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1331                         XtNwrongParameters, "cvtXColorToPixel",
1332                         XtCXtToolkitError,
1333                         "Color to Pixel conversion needs no extra arguments",
1334                         NULL, NULL);
1335     done(Pixel, ((XColor *) fromVal->addr)->pixel);
1336 }
1337 
1338 Boolean
XtCvtIntToPixel(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)1339 XtCvtIntToPixel(Display *dpy,
1340                 XrmValuePtr args _X_UNUSED,
1341                 Cardinal *num_args,
1342                 XrmValuePtr fromVal,
1343                 XrmValuePtr toVal,
1344                 XtPointer *closure_ret _X_UNUSED)
1345 {
1346     if (*num_args != 0)
1347         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1348                         XtNwrongParameters, "cvtIntToPixel", XtCXtToolkitError,
1349                         "Integer to Pixel conversion needs no extra arguments",
1350                         NULL, NULL);
1351     done(Pixel, *(int *) fromVal->addr);
1352 }
1353 
1354 Boolean
XtCvtIntToPixmap(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)1355 XtCvtIntToPixmap(Display *dpy,
1356                  XrmValuePtr args _X_UNUSED,
1357                  Cardinal *num_args,
1358                  XrmValuePtr fromVal,
1359                  XrmValuePtr toVal,
1360                  XtPointer *closure_ret _X_UNUSED)
1361 {
1362     if (*num_args != 0)
1363         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1364                         XtNwrongParameters, "cvtIntToPixmap", XtCXtToolkitError,
1365                         "Integer to Pixmap conversion needs no extra arguments",
1366                         NULL, NULL);
1367     done(Pixmap, *(int *) fromVal->addr);
1368 }
1369 
1370 #ifdef MOTIFBC
1371 void
LowerCase(register char * source,register * dest)1372 LowerCase(register char *source, register *dest)
1373 {
1374     register char ch;
1375     int i;
1376 
1377     for (i = 0; (ch = *source) != 0 && i < 999; source++, dest++, i++) {
1378         if ('A' <= ch && ch <= 'Z')
1379             *dest = ch - 'A' + 'a';
1380         else
1381             *dest = ch;
1382     }
1383     *dest = 0;
1384 }
1385 #endif
1386 
1387 static int
CompareISOLatin1(const char * first,const char * second)1388 CompareISOLatin1(const char *first, const char *second)
1389 {
1390     register const unsigned char *ap, *bp;
1391 
1392     for (ap = (const unsigned char *) first,
1393          bp = (const unsigned char *) second; *ap && *bp; ap++, bp++) {
1394         register unsigned char a, b;
1395 
1396         if ((a = *ap) != (b = *bp)) {
1397             /* try lowercasing and try again */
1398 
1399             if ((a >= XK_A) && (a <= XK_Z))
1400                 a = (unsigned char) (a + (XK_a - XK_A));
1401             else if ((a >= XK_Agrave) && (a <= XK_Odiaeresis))
1402                 a = (unsigned char) (a + (XK_agrave - XK_Agrave));
1403             else if ((a >= XK_Ooblique) && (a <= XK_Thorn))
1404                 a = (unsigned char) (a + (XK_oslash - XK_Ooblique));
1405 
1406             if ((b >= XK_A) && (b <= XK_Z))
1407                 b = (unsigned char) (b + (XK_a - XK_A));
1408             else if ((b >= XK_Agrave) && (b <= XK_Odiaeresis))
1409                 b = (unsigned char) (b + (XK_agrave - XK_Agrave));
1410             else if ((b >= XK_Ooblique) && (b <= XK_Thorn))
1411                 b = (unsigned char) (b + (XK_oslash - XK_Ooblique));
1412 
1413             if (a != b)
1414                 break;
1415         }
1416     }
1417     return (((int) *bp) - ((int) *ap));
1418 }
1419 
1420 static void
CopyISOLatin1Lowered(char * dst,const char * src)1421 CopyISOLatin1Lowered(char *dst, const char *src)
1422 {
1423     unsigned char *dest = (unsigned char *) dst;
1424     const unsigned char *source = (const unsigned char *) src;
1425 
1426     for (; *source; source++, dest++) {
1427         if (*source >= XK_A && *source <= XK_Z)
1428             *dest = (unsigned char) (*source + (XK_a - XK_A));
1429         else if (*source >= XK_Agrave && *source <= XK_Odiaeresis)
1430             *dest = (unsigned char) (*source + (XK_agrave - XK_Agrave));
1431         else if (*source >= XK_Ooblique && *source <= XK_Thorn)
1432             *dest = (unsigned char) (*source + (XK_oslash - XK_Ooblique));
1433         else
1434             *dest = *source;
1435     }
1436     *dest = '\0';
1437 }
1438 
1439 Boolean
XtCvtStringToInitialState(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)1440 XtCvtStringToInitialState(Display *dpy,
1441                           XrmValuePtr args _X_UNUSED,
1442                           Cardinal *num_args,
1443                           XrmValuePtr fromVal,
1444                           XrmValuePtr toVal,
1445                           XtPointer *closure_ret _X_UNUSED)
1446 {
1447     String str = (String) fromVal->addr;
1448 
1449     if (*num_args != 0)
1450         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1451                         XtNwrongParameters, "cvtStringToInitialState",
1452                         XtCXtToolkitError,
1453                         "String to InitialState conversion needs no extra arguments",
1454                         NULL, NULL);
1455 
1456     if (CompareISOLatin1(str, "NormalState") == 0)
1457         done_string(int, NormalState, XtRInitialState);
1458 
1459     if (CompareISOLatin1(str, "IconicState") == 0)
1460         done_string(int, IconicState, XtRInitialState);
1461 
1462     {
1463         int val;
1464 
1465         if (IsInteger(str, &val))
1466             done_string(int, val, XtRInitialState);
1467     }
1468     XtDisplayStringConversionWarning(dpy, str, XtRInitialState);
1469     return False;
1470 }
1471 
1472 /* *INDENT-OFF* */
1473 static XtConvertArgRec const visualConvertArgs[] = {
1474     {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.screen),
1475      sizeof(Screen *)},
1476     {XtWidgetBaseOffset, (XtPointer)XtOffsetOf(WidgetRec, core.depth),
1477      sizeof(Cardinal)}
1478 };
1479 /* *INDENT-ON* */
1480 
1481 Boolean
XtCvtStringToVisual(Display * dpy,XrmValuePtr args,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)1482 XtCvtStringToVisual(Display *dpy, XrmValuePtr args,     /* Screen, depth */
1483                     Cardinal *num_args,        /* 2 */
1484                     XrmValuePtr fromVal,
1485                     XrmValuePtr toVal,
1486                     XtPointer *closure_ret _X_UNUSED)
1487 {
1488     String str = (String) fromVal->addr;
1489     int vc;
1490     XVisualInfo vinfo;
1491 
1492     if (*num_args != 2) {
1493         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1494                         XtNwrongParameters, "cvtStringToVisual",
1495                         XtCXtToolkitError,
1496                         "String to Visual conversion needs screen and depth arguments",
1497                         NULL, NULL);
1498         return False;
1499     }
1500 
1501     if (CompareISOLatin1(str, "StaticGray") == 0)
1502         vc = StaticGray;
1503     else if (CompareISOLatin1(str, "StaticColor") == 0)
1504         vc = StaticColor;
1505     else if (CompareISOLatin1(str, "TrueColor") == 0)
1506         vc = TrueColor;
1507     else if (CompareISOLatin1(str, "GrayScale") == 0)
1508         vc = GrayScale;
1509     else if (CompareISOLatin1(str, "PseudoColor") == 0)
1510         vc = PseudoColor;
1511     else if (CompareISOLatin1(str, "DirectColor") == 0)
1512         vc = DirectColor;
1513     else if (!IsInteger(str, &vc)) {
1514         XtDisplayStringConversionWarning(dpy, str, "Visual class name");
1515         return False;
1516     }
1517 
1518     if (XMatchVisualInfo(XDisplayOfScreen((Screen *) *(Screen **) args[0].addr),
1519                          XScreenNumberOfScreen((Screen *) *(Screen **) args[0].
1520                                                addr),
1521                          (int) *(int *) args[1].addr, vc, &vinfo)) {
1522         done_string(Visual *, vinfo.visual, XtRVisual);
1523     }
1524     else {
1525         String params[2];
1526         Cardinal num_params = 2;
1527 
1528         params[0] = str;
1529         params[1] =
1530             DisplayString(XDisplayOfScreen
1531                           ((Screen *) *(Screen **) args[0].addr));
1532         XtAppWarningMsg(XtDisplayToApplicationContext(dpy), XtNconversionError,
1533                         "stringToVisual", XtCXtToolkitError,
1534                         "Cannot find Visual of class %s for display %s", params,
1535                         &num_params);
1536         return False;
1537     }
1538 }
1539 
1540 Boolean
XtCvtStringToAtom(Display * dpy,XrmValuePtr args,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)1541 XtCvtStringToAtom(Display *dpy,
1542                   XrmValuePtr args,
1543                   Cardinal *num_args,
1544                   XrmValuePtr fromVal,
1545                   XrmValuePtr toVal,
1546                   XtPointer *closure_ret _X_UNUSED)
1547 {
1548     Atom atom;
1549 
1550     if (*num_args != 1) {
1551         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1552                         XtNwrongParameters, "cvtStringToAtom",
1553                         XtCXtToolkitError,
1554                         "String to Atom conversion needs Display argument",
1555                         NULL, NULL);
1556         return False;
1557     }
1558 
1559     atom = XInternAtom(*(Display **) args->addr, (char *) fromVal->addr, False);
1560     done_string(Atom, atom, XtRAtom);
1561 }
1562 
1563 Boolean
XtCvtStringToDirectoryString(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)1564 XtCvtStringToDirectoryString(Display *dpy,
1565                              XrmValuePtr args _X_UNUSED,
1566                              Cardinal *num_args,
1567                              XrmValuePtr fromVal,
1568                              XrmValuePtr toVal,
1569                              XtPointer *closure_ret _X_UNUSED)
1570 {
1571     String str;
1572     char directory[PATH_MAX + 1];
1573 
1574     if (*num_args != 0)
1575         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1576                         XtNwrongParameters, "cvtStringToDirectoryString",
1577                         XtCXtToolkitError,
1578                         "String to DirectoryString conversion needs no extra arguments",
1579                         NULL, NULL);
1580 
1581     str = (String) fromVal->addr;
1582     if (CompareISOLatin1(str, "XtCurrentDirectory") == 0) {
1583         /* uglier, but does not depend on compiler knowing return type */
1584 #if !defined(X_NOT_POSIX) || defined(SYSV) || defined(WIN32)
1585         if (getcwd(directory, PATH_MAX + 1))
1586             str = directory;
1587 #else
1588         if (getwd(directory))
1589             str = directory;
1590 #endif
1591         if (!str) {
1592             if (errno == EACCES)
1593                 errno = 0;      /* reset errno */
1594             XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr,
1595                                              XtRDirectoryString);
1596             return False;
1597         }
1598     }
1599 
1600     /* Since memory from the resource database or from static buffers of
1601      * system libraries may be freed or overwritten, allocate memory.
1602      * The memory is freed when all cache references are released.
1603      */
1604     str = XtNewString(str);
1605     done_string(String, str, XtRDirectoryString);
1606 }
1607 
1608 static void
FreeDirectoryString(XtAppContext app,XrmValuePtr toVal,XtPointer closure _X_UNUSED,XrmValuePtr args _X_UNUSED,Cardinal * num_args)1609 FreeDirectoryString(XtAppContext app,
1610                     XrmValuePtr toVal,
1611                     XtPointer closure _X_UNUSED,
1612                     XrmValuePtr args _X_UNUSED,
1613                     Cardinal *num_args)
1614 {
1615     if (*num_args != 0)
1616         XtAppWarningMsg(app,
1617                         XtNwrongParameters, "freeDirectoryString",
1618                         XtCXtToolkitError,
1619                         "Free Directory String requires no extra arguments",
1620                         NULL, NULL);
1621 
1622     XtFree((char *) toVal->addr);
1623 }
1624 
1625 Boolean
XtCvtStringToRestartStyle(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)1626 XtCvtStringToRestartStyle(Display *dpy,
1627                           XrmValuePtr args _X_UNUSED,
1628                           Cardinal *num_args,
1629                           XrmValuePtr fromVal,
1630                           XrmValuePtr toVal,
1631                           XtPointer *closure_ret _X_UNUSED)
1632 {
1633     String str = (String) fromVal->addr;
1634 
1635     if (*num_args != 0)
1636         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1637                         XtNwrongParameters, "cvtStringToRestartStyle",
1638                         XtCXtToolkitError,
1639                         "String to RestartStyle conversion needs no extra arguments",
1640                         NULL, NULL);
1641 
1642     if (CompareISOLatin1(str, "RestartIfRunning") == 0)
1643         done_string(unsigned char, SmRestartIfRunning, XtRRestartStyle);
1644 
1645     if (CompareISOLatin1(str, "RestartAnyway") == 0)
1646         done_string(unsigned char, SmRestartAnyway, XtRRestartStyle);
1647 
1648     if (CompareISOLatin1(str, "RestartImmediately") == 0)
1649         done_string(unsigned char, SmRestartImmediately, XtRRestartStyle);
1650 
1651     if (CompareISOLatin1(str, "RestartNever") == 0)
1652         done_string(unsigned char, SmRestartNever, XtRRestartStyle);
1653 
1654     XtDisplayStringConversionWarning(dpy, str, XtRRestartStyle);
1655     return False;
1656 }
1657 
1658 Boolean
XtCvtStringToCommandArgArray(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret)1659 XtCvtStringToCommandArgArray(Display *dpy,
1660                              XrmValuePtr args _X_UNUSED,
1661                              Cardinal *num_args,
1662                              XrmValuePtr fromVal,
1663                              XrmValuePtr toVal,
1664                              XtPointer *closure_ret)
1665 {
1666     String *strarray, *ptr;
1667     char *src;
1668     char *dst, *dst_str;
1669     int tokens, len;
1670 
1671     if (*num_args != 0)
1672         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1673                         XtNwrongParameters, "cvtStringToCommandArgArray",
1674                         XtCXtToolkitError,
1675                         "String to CommandArgArray conversion needs no extra arguments",
1676                         NULL, NULL);
1677 
1678     src = fromVal->addr;
1679     dst = dst_str = __XtMalloc((unsigned) strlen(src) + 1);
1680     tokens = 0;
1681 
1682     while (*src != '\0') {
1683         char *start;
1684 
1685         /* skip whitespace */
1686         while (IsWhitespace(*src) || IsNewline(*src))
1687             src++;
1688         /* test for end of string */
1689         if (*src == '\0')
1690             break;
1691 
1692         /* start new token */
1693         tokens++;
1694         start = src;
1695         while (*src != '\0' && !IsWhitespace(*src) && !IsNewline(*src)) {
1696             if (*src == '\\' &&
1697                 (IsWhitespace(*(src + 1)) || IsNewline(*(src + 1)))) {
1698                 len = (int) (src - start);
1699                 if (len) {
1700                     /* copy preceeding part of token */
1701                     memcpy(dst, start, (size_t) len);
1702                     dst += len;
1703                 }
1704                 /* skip backslash */
1705                 src++;
1706                 /* next part of token starts at whitespace */
1707                 start = src;
1708             }
1709             src++;
1710         }
1711         len = (int) (src - start);
1712         if (len) {
1713             /* copy last part of token */
1714             memcpy(dst, start, (size_t) len);
1715             dst += len;
1716         }
1717         *dst = '\0';
1718         if (*src != '\0')
1719             dst++;
1720     }
1721 
1722     ptr = strarray = (String *)
1723         __XtMalloc((Cardinal) ((size_t) (tokens + 1) * sizeof(String)));
1724     src = dst_str;
1725     while (--tokens >= 0) {
1726         *ptr = src;
1727         ptr++;
1728         if (tokens) {
1729             len = (int) strlen(src);
1730             src = src + len + 1;
1731         }
1732     }
1733     *ptr = NULL;
1734 
1735     *closure_ret = (XtPointer) strarray;
1736     done_typed_string(String *, strarray, XtRCommandArgArray)
1737 }
1738 
1739 static void
ArgArrayDestructor(XtAppContext app _X_UNUSED,XrmValuePtr toVal _X_UNUSED,XtPointer closure,XrmValuePtr args _X_UNUSED,Cardinal * num_args _X_UNUSED)1740 ArgArrayDestructor(XtAppContext app _X_UNUSED,
1741                    XrmValuePtr toVal _X_UNUSED,
1742                    XtPointer closure,
1743                    XrmValuePtr args _X_UNUSED,
1744                    Cardinal *num_args _X_UNUSED)
1745 {
1746     if (closure) {
1747         _XtString *strarray = (_XtString *) closure;
1748 
1749         XtFree(*strarray);
1750         XtFree((char *) strarray);
1751     }
1752 }
1753 
1754 Boolean
XtCvtStringToGravity(Display * dpy,XrmValuePtr args _X_UNUSED,Cardinal * num_args,XrmValuePtr fromVal,XrmValuePtr toVal,XtPointer * closure_ret _X_UNUSED)1755 XtCvtStringToGravity(Display *dpy,
1756                      XrmValuePtr args _X_UNUSED,
1757                      Cardinal *num_args,
1758                      XrmValuePtr fromVal,
1759                      XrmValuePtr toVal,
1760                      XtPointer *closure_ret _X_UNUSED)
1761 {
1762     /* *INDENT-OFF* */
1763     static struct _namepair {
1764         XrmQuark quark;
1765         const char *name;
1766         int gravity;
1767     } names[] = {
1768         { NULLQUARK, "forget",          ForgetGravity },
1769         { NULLQUARK, "northwest",       NorthWestGravity },
1770         { NULLQUARK, "north",           NorthGravity },
1771         { NULLQUARK, "northeast",       NorthEastGravity },
1772         { NULLQUARK, "west",            WestGravity },
1773         { NULLQUARK, "center",          CenterGravity },
1774         { NULLQUARK, "east",            EastGravity },
1775         { NULLQUARK, "southwest",       SouthWestGravity },
1776         { NULLQUARK, "south",           SouthGravity },
1777         { NULLQUARK, "southeast",       SouthEastGravity },
1778         { NULLQUARK, "static",          StaticGravity },
1779         { NULLQUARK, "unmap",           UnmapGravity },
1780         { NULLQUARK, "0",               ForgetGravity },
1781         { NULLQUARK, "1",               NorthWestGravity },
1782         { NULLQUARK, "2",               NorthGravity },
1783         { NULLQUARK, "3",               NorthEastGravity },
1784         { NULLQUARK, "4",               WestGravity },
1785         { NULLQUARK, "5",               CenterGravity },
1786         { NULLQUARK, "6",               EastGravity },
1787         { NULLQUARK, "7",               SouthWestGravity },
1788         { NULLQUARK, "8",               SouthGravity },
1789         { NULLQUARK, "9",               SouthEastGravity },
1790         { NULLQUARK, "10",              StaticGravity },
1791         { NULLQUARK, NULL,              ForgetGravity }
1792     };
1793     /* *INDENT-ON* */
1794     static Boolean haveQuarks = FALSE;
1795     char lowerName[40];
1796     XrmQuark q;
1797     char *s;
1798     struct _namepair *np;
1799 
1800     if (*num_args != 0) {
1801         XtAppWarningMsg(XtDisplayToApplicationContext(dpy),
1802                         "wrongParameters", "cvtStringToGravity",
1803                         "XtToolkitError",
1804                         "String to Gravity conversion needs no extra arguments",
1805                         NULL, NULL);
1806         return False;
1807     }
1808     if (!haveQuarks) {
1809         for (np = names; np->name; np++) {
1810             np->quark = XrmPermStringToQuark(np->name);
1811         }
1812         haveQuarks = TRUE;
1813     }
1814     s = (char *) fromVal->addr;
1815     if (strlen(s) < sizeof lowerName) {
1816         CopyISOLatin1Lowered(lowerName, s);
1817         q = XrmStringToQuark(lowerName);
1818         for (np = names; np->name; np++)
1819             if (np->quark == q)
1820                 done_string(int, np->gravity, XtRGravity);
1821     }
1822     XtDisplayStringConversionWarning(dpy, (char *) fromVal->addr, XtRGravity);
1823     return False;
1824 }
1825 
1826 void
_XtAddDefaultConverters(ConverterTable table)1827 _XtAddDefaultConverters(ConverterTable table)
1828 {
1829 #define Add(from, to, proc, convert_args, num_args, cache) \
1830     _XtTableAddConverter(table, from, to, proc, \
1831             (XtConvertArgRec const*) convert_args, (Cardinal)num_args, \
1832             True, cache, (XtDestructor)NULL, True)
1833 
1834 #define Add2(from, to, proc, convert_args, num_args, cache, destructor) \
1835     _XtTableAddConverter(table, from, to, proc, \
1836             (XtConvertArgRec const *) convert_args, (Cardinal)num_args, \
1837             True, cache, destructor, True)
1838 
1839     Add(XtQColor, XtQPixel, XtCvtColorToPixel, NULL, 0, XtCacheNone);
1840 
1841     Add(XtQInt, XtQBool, XtCvtIntToBool, NULL, 0, XtCacheNone);
1842     Add(XtQInt, XtQBoolean, XtCvtIntToBoolean, NULL, 0, XtCacheNone);
1843     Add(XtQInt, XtQColor, XtCvtIntToColor,
1844         colorConvertArgs, XtNumber(colorConvertArgs), XtCacheByDisplay);
1845     Add(XtQInt, XtQDimension, XtCvtIntToShort, NULL, 0, XtCacheNone);
1846     Add(XtQInt, XtQFloat, XtCvtIntToFloat, NULL, 0, XtCacheNone);
1847     Add(XtQInt, XtQFont, XtCvtIntToFont, NULL, 0, XtCacheNone);
1848     Add(XtQInt, XtQPixel, XtCvtIntToPixel, NULL, 0, XtCacheNone);
1849     Add(XtQInt, XtQPixmap, XtCvtIntToPixmap, NULL, 0, XtCacheNone);
1850     Add(XtQInt, XtQPosition, XtCvtIntToShort, NULL, 0, XtCacheNone);
1851     Add(XtQInt, XtQShort, XtCvtIntToShort, NULL, 0, XtCacheNone);
1852     Add(XtQInt, XtQUnsignedChar, XtCvtIntToUnsignedChar, NULL, 0, XtCacheNone);
1853 
1854     Add(XtQPixel, XtQColor, XtCvtIntToColor,
1855         colorConvertArgs, XtNumber(colorConvertArgs), XtCacheByDisplay);
1856 
1857     Add(_XtQString, XtQAtom, XtCvtStringToAtom,
1858         displayConvertArg, XtNumber(displayConvertArg), XtCacheNone);
1859     Add(_XtQString, XtQBool, XtCvtStringToBool, NULL, 0, XtCacheNone);
1860     Add(_XtQString, XtQBoolean, XtCvtStringToBoolean, NULL, 0, XtCacheNone);
1861     Add2(_XtQString, XtQCommandArgArray, XtCvtStringToCommandArgArray,
1862          NULL, 0, XtCacheNone | XtCacheRefCount, ArgArrayDestructor);
1863     Add2(_XtQString, XtQCursor, XtCvtStringToCursor,
1864          displayConvertArg, XtNumber(displayConvertArg),
1865          XtCacheByDisplay, FreeCursor);
1866     Add(_XtQString, XtQDimension, XtCvtStringToDimension, NULL, 0, XtCacheNone);
1867     Add2(_XtQString, XtQDirectoryString, XtCvtStringToDirectoryString, NULL, 0,
1868          XtCacheNone | XtCacheRefCount, FreeDirectoryString);
1869     Add(_XtQString, XtQDisplay, XtCvtStringToDisplay, NULL, 0, XtCacheAll);
1870     Add2(_XtQString, XtQFile, XtCvtStringToFile, NULL, 0,
1871          XtCacheAll | XtCacheRefCount, FreeFile);
1872     Add(_XtQString, XtQFloat, XtCvtStringToFloat, NULL, 0, XtCacheNone);
1873 
1874     Add2(_XtQString, XtQFont, XtCvtStringToFont,
1875          displayConvertArg, XtNumber(displayConvertArg),
1876          XtCacheByDisplay, FreeFont);
1877     Add2(_XtQString, XtQFontSet, XtCvtStringToFontSet,
1878          localeDisplayConvertArgs, XtNumber(localeDisplayConvertArgs),
1879          XtCacheByDisplay, FreeFontSet);
1880     Add2(_XtQString, XtQFontStruct, XtCvtStringToFontStruct,
1881          displayConvertArg, XtNumber(displayConvertArg),
1882          XtCacheByDisplay, FreeFontStruct);
1883 
1884     Add(_XtQString, XtQGravity, XtCvtStringToGravity, NULL, 0, XtCacheNone);
1885     Add(_XtQString, XtQInitialState, XtCvtStringToInitialState, NULL, 0,
1886         XtCacheNone);
1887     Add(_XtQString, XtQInt, XtCvtStringToInt, NULL, 0, XtCacheAll);
1888     Add2(_XtQString, XtQPixel, XtCvtStringToPixel,
1889          colorConvertArgs, XtNumber(colorConvertArgs),
1890          XtCacheByDisplay, FreePixel);
1891     Add(_XtQString, XtQPosition, XtCvtStringToShort, NULL, 0, XtCacheAll);
1892     Add(_XtQString, XtQRestartStyle, XtCvtStringToRestartStyle, NULL, 0,
1893         XtCacheNone);
1894     Add(_XtQString, XtQShort, XtCvtStringToShort, NULL, 0, XtCacheAll);
1895     Add(_XtQString, XtQUnsignedChar, XtCvtStringToUnsignedChar,
1896         NULL, 0, XtCacheAll);
1897     Add2(_XtQString, XtQVisual, XtCvtStringToVisual,
1898          visualConvertArgs, XtNumber(visualConvertArgs),
1899          XtCacheByDisplay, NULL);
1900 
1901     _XtAddTMConverters(table);
1902 }
1903