convert all Imakefile LinuxDistribution to LinuxArchitecture.
[oweals/cde.git] / cde / programs / dtksh / dtkcvt.c
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $TOG: dtkcvt.c /main/7 1998/04/20 12:54:59 mgreess $ */
24
25 /*      Copyright (c) 1991, 1992 UNIX System Laboratories, Inc. */
26 /*      All Rights Reserved     */
27
28 /*      THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF          */
29 /*      UNIX System Laboratories, Inc.                          */
30 /*      The copyright notice above does not evidence any        */
31 /*      actual or intended publication of such source code.     */
32
33 /* X includes */
34
35 #include        "shell.h" 
36 #include <signal.h>
37 #include <fcntl.h>
38 #include <X11/X.h>
39 #include <X11/Intrinsic.h>
40 #include <X11/IntrinsicP.h>
41 #include <X11/CoreP.h>
42 #include <X11/StringDefs.h>
43 #include <Xm/XmStrDefs.h>
44 #include <setjmp.h>
45 #include <string.h>
46 #include <ctype.h>
47 #include <Xm/Xm.h>
48 #include <Xm/Protocols.h>
49 #include <Xm/MwmUtil.h>
50 #include <Dt/Service.h>
51 #include <Dt/Wsm.h>
52 #include <Dt/HourGlass.h>
53 #include <Dt/Help.h>
54 #include <Dt/EnvControlP.h>
55 #include <Dt/Print.h>
56 #include "hash.h"
57 #include "stdio.h"
58 #define NO_AST
59 #include "dtksh.h"
60 #undef NO_AST
61 #include "xmksh.h"
62 #include "XtCvtrs.h"
63 #include "dtkcmds.h"
64 #include "xmcvt.h"
65 #include "widget.h"
66 #include "extra.h"
67 #include "xmwidgets.h"
68 #include "msgs.h"
69
70 #if defined(SYSV) || defined(SVR4_0) || defined(SVR4) || defined(DEC)
71 #define lsprintf sprintf
72 #endif
73
74 extern Hashtab_t * Wclasses;
75
76
77
78 static void CvtStringToMWMValue( 
79         MWMTable * table, 
80         Display *dpy,
81         XrmValuePtr args,
82         Cardinal *nargs,
83         XrmValuePtr fval,
84         XrmValuePtr toval,
85         XtPointer data ) ;
86 static void CvtMWMValueToString(
87         MWMTable * table,
88         Display *dpy,
89         XrmValuePtr args,
90         Cardinal *nargs,
91         XrmValuePtr fval,
92         XrmValuePtr toval,
93         XtPointer data ) ;
94
95 /*
96  * Converters for dtksh
97  */
98
99 void
100 DtkshCvtWindowToString(
101         XrmValuePtr args,
102         Cardinal *nargs,
103         XrmValuePtr fval,
104         XrmValuePtr toval )
105 {
106    static char result[16];
107    Window window;
108    char * errmsg;
109
110    if (fval->size != sizeof(Window))
111    {
112       errmsg = strdup(GETMESSAGE(6,1, 
113             "DtkshCvtWindowToString: The 'from' value is an invalid size"));
114       XtWarning(errmsg);
115       free(errmsg);
116       toval->addr = NULL;
117       toval->size = 0;
118       return;
119    }
120    window = ((Window *)(fval->addr))[0];
121    if (window == None)
122       sprintf(result, "None");
123    else
124       sprintf(result, "0x%x", window);
125    toval->addr = result;
126    toval->size = strlen(result)+1;
127 }
128
129 void
130 DtkshCvtScreenToString(
131         XrmValuePtr args,
132         Cardinal *nargs,
133         XrmValuePtr fval,
134         XrmValuePtr toval )
135 {
136    static char result[16];
137    Screen * screen;
138    char * errmsg;
139
140    if (fval->size != sizeof(Screen *))
141    {
142       errmsg = strdup(GETMESSAGE(6,14, 
143             "DtkshCvtScreenToString: The 'from' value is an invalid size"));
144       XtWarning(errmsg);
145       free(errmsg);
146       toval->addr = NULL;
147       toval->size = 0;
148       return;
149    }
150    screen = ((Screen **)(fval->addr))[0];
151    sprintf(result, "0x%lx", (unsigned long)screen);
152    toval->addr = result;
153    toval->size = strlen(result)+1;
154 }
155
156 void
157 DtkshCvtStringToScreen(
158         XrmValuePtr args,
159         Cardinal *nargs,
160         XrmValuePtr fval,
161         XrmValuePtr toval )
162 {
163    static Screen * screen;
164    char * errmsg;
165    char * p;
166
167    if (fval->size <= 0 || fval->addr == NULL) 
168    {
169       toval->addr = NULL;
170       toval->size = 0;
171       return;
172    }
173  
174    screen = (Screen *)strtoul(fval->addr, &p, 0);
175    if (p != fval->addr)
176    {
177       toval->addr = (XtPointer)&screen;
178       toval->size = sizeof(Screen *);
179    }
180    else
181    {
182       toval->addr = NULL;
183       toval->size = 0;
184       return;
185    }
186 }
187
188 void
189 DtkshCvtStringToTopItemPosition(
190         XrmValuePtr args,
191         Cardinal *nargs,
192         XrmValuePtr fval,
193         XrmValuePtr toval )
194 {
195    static int topItemPosition;
196    char * p;
197
198    if (fval->size <= 0 || fval->addr == NULL) 
199    {
200       toval->addr = NULL;
201       toval->size = 0;
202       return;
203    }
204  
205    topItemPosition = (int)strtoul(fval->addr, &p, 0);
206    if (p != fval->addr)
207    {
208       toval->addr = (XtPointer)&topItemPosition;
209       toval->size = sizeof(int);
210    }
211    else
212    {
213       toval->addr = NULL;
214       toval->size = 0;
215       return;
216    }
217 }
218
219 void
220 DtkshCvtHexIntToString(
221         XrmValuePtr args,
222         Cardinal *nargs,
223         XrmValuePtr fval,
224         XrmValuePtr toval )
225 {
226    static char result[16];
227    char * errmsg;
228
229    if (fval->size != sizeof(long) && fval->size != sizeof(int) && 
230        fval->size != sizeof(short) && fval->size != sizeof(char)) 
231    {
232       errmsg = strdup(GETMESSAGE(6,2, 
233            "DtkshCvtHexIntToString: The 'from' value is an invalid size"));
234       XtWarning(errmsg);
235       free(errmsg);
236       toval->addr = NULL;
237       toval->size = 0;
238       return;
239    }
240    if (fval->size == sizeof(long))
241       sprintf(result, "0x%lx", ((long *)(fval->addr))[0]);
242    else if (fval->size == sizeof(int))
243       sprintf(result, "0x%x", ((int *)(fval->addr))[0]);
244    else if (fval->size == sizeof(short))
245       sprintf(result, "0x%x", (int)(((short *)(fval->addr))[0]));
246    else if (fval->size == sizeof(char))
247       sprintf(result, "0x%x", (int)(((char *)(fval->addr))[0]));
248    toval->addr = result;
249    toval->size = strlen(result)+1;
250 }
251
252 void
253 DtkshCvtIntToString(
254         XrmValuePtr args,
255         Cardinal *nargs,
256         XrmValuePtr fval,
257         XrmValuePtr toval )
258 {
259    static char result[16];
260    char * errmsg;
261
262    if (fval->size != sizeof(int) && fval->size != sizeof(short)) 
263    {
264       errmsg = strdup(GETMESSAGE(6,3, 
265              "DtkshCvtIntToString: The 'from' value is an invalid size"));
266       XtWarning(errmsg);
267       free(errmsg);
268       toval->addr = NULL;
269       toval->size = 0;
270       return;
271    }
272    if (fval->size == sizeof(int))
273       sprintf(result, "%d", ((int *)(fval->addr))[0]);
274    else
275       sprintf(result, "%d", (int)(((short *)(fval->addr))[0]));
276    toval->addr = result;
277    toval->size = strlen(result)+1;
278 }
279
280 void
281 DtkshCvtBooleanToString(
282         XrmValuePtr args,
283         Cardinal *nargs,
284         XrmValuePtr fval,
285         XrmValuePtr toval )
286 {
287    char * errmsg;
288    Boolean booleanState;
289
290    if (fval->size != sizeof(int) && fval->size != sizeof(short) &&
291        fval->size != sizeof(char)) 
292    {
293       errmsg = strdup(GETMESSAGE(6,4, 
294              "DtkshCvtBooleanToString: The 'from' value is an invalid size"));
295       XtWarning(errmsg);
296       free(errmsg);
297       toval->addr = NULL;
298       toval->size = 0;
299       return;
300    }
301
302    if (fval->size == sizeof(int))
303       booleanState = (Boolean) (((int *)(fval->addr))[0]);
304    else if (fval->size == sizeof(short))
305       booleanState =  (Boolean) (((short *)(fval->addr))[0]);
306    else if (fval->size == sizeof(char))
307       booleanState = (Boolean) (((char *)(fval->addr))[0]);
308
309    if (booleanState)
310       toval->addr = (caddr_t)("true");
311    else
312       toval->addr = (caddr_t)("false");
313
314    toval->size = strlen(toval->addr)+1;
315 }
316
317 void
318 DtkshCvtStringToPointer(
319         XrmValuePtr args,
320         Cardinal *nargs,
321         XrmValuePtr fval,
322         XrmValuePtr toval )
323 {
324    static XtPointer ret;
325
326    if (fval->size <= 0 || fval->addr == NULL) 
327    {
328       toval->addr = NULL;
329       toval->size = 0;
330       return;
331    }
332    ret = (XtPointer)strdup(fval->addr);
333    toval->addr = (XtPointer)&ret;
334    toval->size = sizeof(XtPointer);
335    return;
336 }
337
338 void
339 DtkshCvtStringToWidget(
340         Display *dpy,
341         XrmValuePtr args,
342         Cardinal *nargs,
343         XrmValuePtr fval,
344         XrmValuePtr toval,
345         XtPointer data )
346 {
347    char *wname;
348    static Widget wid;
349    wtab_t *w;
350    char * errmsg;
351
352    if (fval->size <= 0) 
353    {
354       errmsg = strdup(GETMESSAGE(6,5, 
355              "DtkshCvtStringToWidget: The 'from' value is an invalid size"));
356       XtWarning(errmsg);
357       free(errmsg);
358       toval->addr = NULL;
359       toval->size = 0;
360       return;
361    }
362    wname = (char *)fval->addr;
363    if (wname == NULL || wname[0] == '\0' || strcmp(wname, "NULL") == 0) 
364    {
365       static Widget NullWidget = NULL;
366
367       toval->addr = (XtPointer)&NullWidget;
368       toval->size = sizeof(Widget);
369       return;
370    }
371    if ((w = str_to_wtab("DtkshCvtStringToWidget", wname)) != NULL) 
372    {
373       wid= w->w;
374       toval->addr = (XtPointer)&wid;
375       toval->size = sizeof(Widget);
376       return;
377    }
378    /*
379     * If we couldn't find it in our table, try looking up the
380     * name in standard resource format.
381     */
382    if ((wid = DtkshNameToWidget(wname)) != NULL) 
383    {
384       toval->addr = (XtPointer)&wid;
385       toval->size = sizeof(Widget);
386       return;
387    }
388    /*
389     * We failed completely
390     */
391    {
392       char errbuf[1024];
393
394       errmsg = strdup(GETMESSAGE(6,6, 
395                "DtkshCvtStringToWidget: Unable to find a widget named '%s'"));
396       sprintf(errbuf, errmsg, wname);
397       XtWarning(errbuf);
398       free(errmsg);
399    }
400    toval->addr = NULL;
401    toval->size = 0;
402 }
403
404 void
405 DtkshCvtStringToCallback(
406         Display *dpy,
407         XrmValuePtr args,
408         Cardinal *nargs,
409         XrmValuePtr fval,
410         XrmValuePtr toval,
411         XtPointer data )
412 {
413    static XtCallbackList cb;
414    dtksh_client_data_t *cdata;
415    classtab_t *c = DTKSHConversionClass;
416    wtab_t *w = DTKSHConversionWidget;
417    char * errmsg;
418
419    if (fval->size <= 0) 
420    {
421       errmsg = strdup(GETMESSAGE(6,7, 
422              "DtkshCvtStringToCallback: The 'from' value is an invalid size"));
423       XtWarning(errmsg);
424       free(errmsg);
425       toval->addr = NULL;
426       toval->size = 0;
427       return;
428    }
429
430    cb = (XtCallbackList)XtMalloc(sizeof(XtCallbackRec)*2);
431    cb[0].callback = (XtCallbackProc)stdCB;
432
433    cdata = GetNewCBData((String)fval->addr, w, DTKSHConversionResource, NULL);
434
435    cb[0].closure = (caddr_t)cdata;
436    cb[1].callback = NULL;
437    toval->addr = (XtPointer)&cb;
438    toval->size = sizeof(XtCallbackList);
439 }
440
441 void
442 DtkshCvtCallbackToString(
443         Display *display,
444         XrmValuePtr args,
445         Cardinal *nargs,
446         XrmValuePtr fval,
447         XrmValuePtr toval,
448         XtPointer converterData )
449 {
450    XtCallbackList cb;
451    char buf[2048];
452    register char *p;
453    char * errmsg;
454    Boolean count = 0;
455
456    if (fval->size != sizeof(XtCallbackList)) 
457    {
458       errmsg = strdup(GETMESSAGE(6,8, 
459           "DtkshCvtCallbackToString: The 'from' value is an invalid size"));
460       XtWarning(errmsg);
461       free(errmsg);
462       toval->addr = NULL;
463       toval->size = 0;
464       return;
465    }
466    if (fval->addr == NULL) 
467    {
468       toval->addr = ": ;";
469       toval->size = 1;
470       return;
471    }
472    p = &buf[0];
473    *p = '\0';
474    for (cb = ((XtCallbackList *)(fval->addr))[0]; cb->callback != NULL; cb++) 
475    {
476       if (cb->callback == (XtCallbackProc)stdCB) 
477       {
478          dtksh_client_data_t *cdata = (dtksh_client_data_t *)cb->closure;
479
480          if (p + strlen((String)cdata->ksh_cmd) + 1 - buf > sizeof(buf)) 
481          {
482             errmsg = strdup(GetSharedMsg(DT_CONV_BUF_OVFL));
483             XtWarning(errmsg);
484             free(errmsg);
485             break;
486          }
487          if (count > 0)
488             p += lsprintf(p, "|%s", (String)cdata->ksh_cmd);
489          else
490             p += lsprintf(p, "%s", (String)cdata->ksh_cmd);
491          count++;
492       }
493    }
494    toval->addr = (XtPointer)strdup(buf);
495    toval->size = strlen(buf) + 1;
496 }
497
498
499 void
500 DtkshCvtWidgetToString(
501         Display *dpy,
502         XrmValuePtr args,
503         Cardinal *nargs,
504         XrmValuePtr fval,
505         XrmValuePtr toval,
506         XtPointer data )
507 {
508    char *wname;
509    Widget widget;
510    wtab_t *w;
511    char * errmsg;
512
513    if (fval->size != sizeof(Widget) || fval->addr == NULL) 
514    {
515       errmsg = strdup(GETMESSAGE(6,9, 
516            "DtkshCvtWidgetToString: The 'from' value is an invalid size"));
517       XtWarning(errmsg);
518       free(errmsg);
519       toval->addr = NULL;
520       toval->size = 0;
521       return;
522    }
523    widget = ((Widget *)fval->addr)[0];
524    if (widget == NULL) 
525    {
526       toval->addr = (XtPointer)("NULL");
527       toval->size = 5;
528       return;
529    }
530    if ((w = widget_to_wtab(widget)) == NULL) 
531    {
532       errmsg = strdup(GETMESSAGE(6,10, 
533           "DtkshCvtWidgetToString: Unable to find a name for the widget"));
534       XtWarning(errmsg);
535       free(errmsg);
536       toval->addr = NULL;
537       toval->size = 0;
538       return;
539    }
540    toval->addr = (XtPointer)w->widid;
541    toval->size = strlen(w->widid) + 1;
542 }
543
544
545 /***********************************************/
546
547 static EventMaskTable eventMasks[] = {
548    {"XtAllEvents", XtAllEvents},
549    {"NoEventMask", NoEventMask},
550    {"KeyPressMask", KeyPressMask},
551    {"KeyReleaseMask", KeyReleaseMask},
552    {"ButtonPressMask", ButtonPressMask},
553    {"ButtonReleaseMask", ButtonReleaseMask},
554    {"EnterWindowMask", EnterWindowMask},
555    {"LeaveWindowMask", LeaveWindowMask},
556    {"PointerMotionMask", PointerMotionMask},
557    {"PointerMotionHintMask", PointerMotionHintMask},
558    {"Button1MotionMask", Button1MotionMask},
559    {"Button2MotionMask", Button2MotionMask},
560    {"Button3MotionMask", Button3MotionMask},
561    {"Button4MotionMask", Button4MotionMask},
562    {"Button5MotionMask", Button5MotionMask},
563    {"ButtonMotionMask", ButtonMotionMask},
564    {"KeymapStateMask", KeymapStateMask},
565    {"ExposureMask", ExposureMask},
566    {"VisibilityChangeMask", VisibilityChangeMask},
567    {"StructureNotifyMask", StructureNotifyMask},
568    {"ResizeRedirectMask", ResizeRedirectMask},
569    {"SubstructureNotifyMask", SubstructureNotifyMask},
570    {"SubstructureRedirectMask", SubstructureRedirectMask},
571    {"FocusChangeMask", FocusChangeMask},
572    {"PropertyChangeMask", PropertyChangeMask},
573    {"ColormapChangeMask", ColormapChangeMask},
574    {"OwnerGrabButtonMask", OwnerGrabButtonMask},
575    {NULL, NULL},
576 };
577
578
579 void
580 DtkshCvtStringToEventMask(
581         Display *dpy,
582         XrmValuePtr args,
583         Cardinal *nargs,
584         XrmValuePtr fval,
585         XrmValuePtr toval,
586         XtPointer data )
587 {
588    static EventMask eventMask = 0;
589    int i;
590    char * ptr;
591    char * eventMaskString;
592
593    toval->addr = (XtPointer)&eventMask;
594    toval->size = sizeof(EventMask);
595
596    if (fval->size <= 0 || fval->addr == NULL) 
597       return;
598
599    ptr = eventMaskString = strdup(fval->addr);
600
601    /*  Skip any leading whitespace.  */
602    while (isspace(*ptr) && (*ptr != '\0'))
603       ptr++;
604
605    eventMask = 0;
606    ptr = strtok(ptr, "|");
607    while (ptr)
608    {
609       for (i = 0; eventMasks[i].name; i++)
610       {
611          if (DtCompareISOLatin1(ptr, eventMasks[i].name))
612          {
613             eventMask |= eventMasks[i].mask;
614             break;
615          }
616       }
617       ptr = strtok(NULL, "|");
618    }
619
620    XtFree(eventMaskString);
621 }
622
623
624 void
625 DtkshCvtStringToListItems(
626         Display *dpy,
627         XrmValuePtr args,
628         Cardinal *nargs,
629         XrmValuePtr fval,
630         XrmValuePtr toval,
631         XtPointer data )
632 {
633    XtConvert(Toplevel, XtRString, fval, XmRXmStringTable, toval);
634 }
635
636
637 void
638 DtkshCvtWidgetClassToString(
639         Display *dpy,
640         XrmValuePtr args,
641         Cardinal *nargs,
642         XrmValuePtr fval,
643         XrmValuePtr toval,
644         XtPointer data )
645 {
646    static char result[16];
647    char * errmsg;
648    WidgetClass wc;
649    int i;
650
651    if (fval->size != sizeof(WidgetClass))
652    {
653       errmsg = strdup(GETMESSAGE(6,11, 
654            "DtkshCvtWidgetClassToString: The 'from' value is an invalid size"));
655       XtWarning(errmsg);
656       free(errmsg);
657       toval->addr = NULL;
658       toval->size = 0;
659       return;
660    }
661
662    if ((wc = ((WidgetClass *)(fval->addr))[0]) == NULL)
663    {
664       toval->addr = "";
665       toval->size = 1;
666       return;
667    }
668
669    for (i = 0; C[i].cname != NULL; i++)
670    {
671       if (C[i].class == wc)
672       {
673          toval->addr = C[i].cname;
674          toval->size = strlen(C[i].cname)+1;
675          return;
676       }
677    }
678
679    /* No match found */
680    errmsg = strdup(GETMESSAGE(6,12,
681           "DtkshCvtWidgetClassToString: Unknown widget class"));
682    XtWarning(errmsg);
683    free(errmsg);
684    toval->addr = NULL;
685    toval->size = 0;
686    return;
687 }
688
689 void
690 DtkshCvtStringToWidgetClass(
691         Display *dpy,
692         XrmValuePtr args,
693         Cardinal *nargs,
694         XrmValuePtr fval,
695         XrmValuePtr toval,
696         XtPointer data )
697 {
698    static char result[16];
699    char * errmsg;
700    static WidgetClass wc;
701    int i;
702    char * wcName;
703    char * hashInfo;
704    classtab_t * classtab;
705
706    if (fval->size <= 0 || fval->addr == NULL) 
707    {
708       toval->addr = NULL;
709       toval->size = 0;
710       return;
711    }
712
713    wcName = (char *)(fval->addr);
714    if ((hashInfo = hashget(Wclasses, wcName)) != NULL)
715    {
716       classtab = (classtab_t *)hashInfo;
717       wc = classtab->class;
718       toval->addr = (caddr_t)&wc;
719       toval->size = sizeof(WidgetClass);
720       return;
721    }
722
723    /* No match found */
724    errmsg = strdup(GETMESSAGE(6,13,
725           "DtkshCvtStringToWidgetClass: Unknown widget class name"));
726    XtWarning(errmsg);
727    free(errmsg);
728    toval->addr = NULL;
729    toval->size = 0;
730    return;
731 }
732
733
734 static MWMTable mwmDecorations[] = {
735    {"MWM_DECOR_ALL", MWM_DECOR_ALL},
736    {"MWM_DECOR_BORDER", MWM_DECOR_BORDER},
737    {"MWM_DECOR_RESIZEH", MWM_DECOR_RESIZEH},
738    {"MWM_DECOR_TITLE", MWM_DECOR_TITLE},
739    {"MWM_DECOR_MENU", MWM_DECOR_MENU},
740    {"MWM_DECOR_MINIMIZE", MWM_DECOR_MINIMIZE},
741    {"MWM_DECOR_MAXIMIZE", MWM_DECOR_MAXIMIZE},
742    {NULL, NULL},
743 };
744
745 static MWMTable mwmFunctions[] = {
746    {"MWM_FUNC_ALL", MWM_FUNC_ALL},
747    {"MWM_FUNC_RESIZE", MWM_FUNC_RESIZE},
748    {"MWM_FUNC_MOVE", MWM_FUNC_MOVE},
749    {"MWM_FUNC_MINIMIZE", MWM_FUNC_MINIMIZE},
750    {"MWM_FUNC_MAXIMIZE", MWM_FUNC_MAXIMIZE},
751    {"MWM_FUNC_CLOSE", MWM_FUNC_CLOSE},
752    {NULL, NULL},
753 };
754
755 static void
756 CvtStringToMWMValue(
757         MWMTable * table,
758         Display *dpy,
759         XrmValuePtr args,
760         Cardinal *nargs,
761         XrmValuePtr fval,
762         XrmValuePtr toval,
763         XtPointer data )
764 {
765    static long value;
766    int i;
767    char * ptr;
768    char * valueString;
769    char * p;
770    int intVal;
771
772    value = 0;
773    toval->addr = (XtPointer)&value;
774    toval->size = sizeof(int);
775
776    if (fval->size <= 0 || fval->addr == NULL) 
777       return;
778
779    ptr = valueString = strdup(fval->addr);
780
781    /*  Skip any leading whitespace.  */
782    while (isspace(*ptr) && (*ptr != '\0'))
783       ptr++;
784
785    /* Integer values, especially -1, are also supported */
786    intVal = strtol(ptr, &p, 0);
787    if (p != ptr)
788    {
789       value = intVal;
790       XtFree(valueString);
791       return;
792    }
793
794    ptr = strtok(ptr, "|");
795    while (ptr)
796    {
797       for (i = 0; table[i].name; i++)
798       {
799          if (DtCompareISOLatin1(ptr, table[i].name))
800          {
801             value |= table[i].value;
802             break;
803          }
804       }
805       ptr = strtok(NULL, "|");
806    }
807
808    XtFree(valueString);
809 }
810
811
812 static void
813 CvtMWMValueToString(
814         MWMTable * table,
815         Display *dpy,
816         XrmValuePtr args,
817         Cardinal *nargs,
818         XrmValuePtr fval,
819         XrmValuePtr toval,
820         XtPointer data )
821 {
822    static char *string = NULL;
823    int value;
824    int i = 0;
825    Boolean firstOne = True;
826
827    value = ((int *)(fval->addr))[0];
828
829    if (value == -1)
830    {
831       string = XtRealloc(string, 5);
832       strcpy(string, "-1");
833    }
834    else
835    {
836       string = XtRealloc(string, 1);
837       string[0] = '\0';
838
839       while (table[i].name)
840       {
841          if (value & table[i].value)
842          {
843             if (!firstOne)
844             {
845                string = XtRealloc(string,
846                      strlen(string) + strlen(table[i].name) + 2);
847                strcat(string, "|");
848                strcat(string, table[i].name);
849             }
850             else
851             {
852                firstOne = False;
853                string = XtRealloc(string,
854                      strlen(string) + strlen(table[i].name) + 1);
855                strcat(string, table[i].name);
856             }
857          }
858          i++;
859       }
860    }
861
862    toval->addr = (caddr_t)string;
863    toval->size = strlen(string) + 1;
864 }
865
866 void
867 DtkshCvtStringToMWMDecoration(
868         Display *dpy,
869         XrmValuePtr args,
870         Cardinal *nargs,
871         XrmValuePtr fval,
872         XrmValuePtr toval,
873         XtPointer data )
874 {
875    CvtStringToMWMValue(mwmDecorations, dpy, args, nargs, fval, toval, data);
876 }
877
878
879 void
880 DtkshCvtMWMDecorationToString(
881         Display *dpy,
882         XrmValuePtr args,
883         Cardinal *nargs,
884         XrmValuePtr fval,
885         XrmValuePtr toval,
886         XtPointer data )
887 {
888    CvtMWMValueToString(mwmDecorations, dpy, args, nargs, fval, toval, data);
889 }
890
891 void
892 DtkshCvtStringToMWMFunctions(
893         Display *dpy,
894         XrmValuePtr args,
895         Cardinal *nargs,
896         XrmValuePtr fval,
897         XrmValuePtr toval,
898         XtPointer data )
899 {
900    CvtStringToMWMValue(mwmFunctions, dpy, args, nargs, fval, toval, data);
901 }
902
903
904 void
905 DtkshCvtMWMFunctionsToString(
906         Display *dpy,
907         XrmValuePtr args,
908         Cardinal *nargs,
909         XrmValuePtr fval,
910         XrmValuePtr toval,
911         XtPointer data )
912 {
913    CvtMWMValueToString(mwmFunctions, dpy, args, nargs, fval, toval, data);
914 }
915
916 void
917 DtkshCvtStringToPanedWinPosIndex(
918         Display *dpy,
919         XrmValuePtr args,
920         Cardinal *nargs,
921         XrmValuePtr fval,
922         XrmValuePtr toval,
923         XtPointer data )
924 {
925    static short value;
926    char * pos;
927    char * p;
928
929    if (fval->size <= 0 || fval->addr == NULL) 
930    {
931       toval->addr = NULL;
932       toval->size = 0;
933       return;
934    }
935  
936    pos = (char *)fval->addr;
937    if (DtCompareISOLatin1(pos, "LAST_POSITION"))
938       value = XmLAST_POSITION;
939    else
940       value = strtol(pos, &p, 0);
941
942    toval->addr = (XtPointer)&value;
943    toval->size = sizeof(short);
944 }
945
946 void
947 DtkshCvtPanedWinPosIndexToString(
948         Display *dpy,
949         XrmValuePtr args,
950         Cardinal *nargs,
951         XrmValuePtr fval,
952         XrmValuePtr toval,
953         XtPointer data )
954 {
955    static char result[50];
956    short value;
957
958    if (fval->size != sizeof(short))
959    {
960       toval->addr = NULL;
961       toval->size = 0;
962       return;
963    }
964    value = ((short *)(fval->addr))[0];
965    if (value == XmLAST_POSITION)
966       sprintf(result, "LAST_POSITION");
967    else
968       sprintf(result, "%d", value);
969    toval->addr = result;
970    toval->size = strlen(result)+1;
971 }
972
973
974 void
975 DtkshCvtStringToPrintSetupProc(
976         Display *dpy,
977         XrmValuePtr args,
978         Cardinal *nargs,
979         XrmValuePtr fval,
980         XrmValuePtr toval,
981         XtPointer data)
982 {
983         static void (*proc)();
984         extern wtab_t *DTKSHConversionWidget;
985         wtab_t *w = DTKSHConversionWidget;
986         extern char *DTKSHConversionResource;
987         ProcInfo_t *pinfo;
988
989         if (w != NULL) {
990                 if (w->info == NULL) {
991                         w->info = (XtPointer)XtMalloc(sizeof(ProcInfo_t));
992                         memset(w->info, '\0', sizeof(ProcInfo_t));
993                 }
994                 pinfo = (ProcInfo_t *)w->info;
995                 if (strcmp(DTKSHConversionResource, CONSTCHAR "printerInfoProc") == 0) {
996                         if (pinfo->printerInfoProcCommand != NULL)
997                                 XtFree(pinfo->printerInfoProcCommand);
998                         pinfo->printerInfoProcCommand = strdup((String)fval->addr);
999                         proc = stdPrinterInfoProc;
1000                 } else if (strcmp(DTKSHConversionResource, CONSTCHAR "selectFileProc") == 0) {
1001                         if (pinfo->selectFileProcCommand != NULL)
1002                                 XtFree(pinfo->selectFileProcCommand);
1003                         pinfo->selectFileProcCommand = strdup((String)fval->addr);
1004                         proc = stdSelectFileProc;
1005                 }
1006                 else if (strcmp(DTKSHConversionResource, CONSTCHAR "selectPrinterProc") == 0) {
1007                         if (pinfo->selectPrinterProcCommand != NULL)
1008                                 XtFree(pinfo->selectPrinterProcCommand);
1009                         pinfo->selectPrinterProcCommand = strdup((String)fval->addr);
1010                         proc = stdSelectPrinterProc;
1011                 }
1012                 else if (strcmp(DTKSHConversionResource, CONSTCHAR "setupProc") == 0) {
1013                         if (pinfo->setupProcCommand != NULL)
1014                                 XtFree(pinfo->setupProcCommand);
1015                         pinfo->setupProcCommand = strdup((String)fval->addr);
1016                         proc = stdSetupProc;
1017                 }
1018                 else if (strcmp(DTKSHConversionResource, CONSTCHAR "verifyPrinterProc") == 0) {
1019                         if (pinfo->verifyPrinterProcCommand != NULL)
1020                                 XtFree(pinfo->verifyPrinterProcCommand);
1021                         pinfo->verifyPrinterProcCommand = strdup((String)fval->addr);
1022                         proc = stdVerifyPrinterProc;
1023                 }
1024                 else {
1025                         XtWarningMsg(CONSTCHAR "CvtStringToPrintSetupProc", CONSTCHAR "unsupported DtPrintSetupBox resource.", CONSTCHAR "XtToolkitError", "This resource is not currently supported by dtksh.", NULL, 0);
1026                 }
1027         } else {
1028                 XtWarningMsg(CONSTCHAR "CvtStringToPrintSetupProc", CONSTCHAR "widget must exist.", CONSTCHAR "XtToolkitError", "This resource cannot be set at creation time by dtksh, use XtSetValues after creation instead.", NULL, 0);
1029                 toval->size = 0;
1030                 toval->addr = NULL;
1031                 return;
1032         }
1033
1034         toval->size = sizeof(DtPrintSetupProc);
1035         toval->addr = (XtPointer)&proc;
1036         return;
1037 }