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