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