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