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