1 /*
2  * Motif Tools Library, Version 3.1
3  * $Id: EnumCvt.c,v 1.2 2001/09/19 02:57:18 grmcdorman Exp $
4  *
5  * Written by David Flanagan.
6  * Copyright (c) 1992-2001 by David Flanagan.
7  * All Rights Reserved.  See the file COPYRIGHT for details.
8  * This is open source software.  See the file LICENSE for details.
9  * There is no warranty for this software.  See NO_WARRANTY for details.
10  *
11  * $Log: EnumCvt.c,v $
12  * Revision 1.2  2001/09/19 02:57:18  grmcdorman
13  * This change makes the following modifications:
14  *   A new program, printConfig, is provided. This is built by a
15  *   simple rule in the Makefile and not installed. It prints
16  *   significant defines from Xmt.tmpl.
17  *
18  *   XmtP.h is now generated from XmtP.h.in using printConfig. As
19  *   a result, code compiled outside of the Xmt Imakefiles will
20  *   have all of the Xmt.tmpl defines.
21  *
22  *   Source files are modified to use XmtP.h instead of Xmt.h.
23  *
24  *   WorkingBox.c is modified to use the new Progress widget.
25  *   It can be compiled in the old style if WORKINGBOX_USE_SCALE is
26  *   defined at compile time.
27  *
28  *   Because XmtP.h is generated dynamically, it is removed from CVS
29  *   with this check-in.
30  *
31  * Revision 1.1.1.1  2001/02/10 13:42:21  motiftools
32  * Initial import of Xmt310 to CVS
33  *
34  *
35  */
36 
37 #include <Xmt/XmtP.h>
38 #include <Xmt/ConvertersP.h>
39 
40 /* ARGSUSED */
41 #if NeedFunctionPrototypes
XmtConvertStringToEnum(Display * dpy,XrmValue * args,Cardinal * num_args,XrmValue * from,XrmValue * to,XtPointer * data)42 Boolean XmtConvertStringToEnum(Display *dpy,
43 			       XrmValue *args, Cardinal *num_args,
44 			       XrmValue *from, XrmValue *to, XtPointer *data)
45 #else
46 Boolean XmtConvertStringToEnum(dpy, args, num_args, from, to, data)
47 Display *dpy;
48 XrmValue *args;
49 Cardinal *num_args;
50 XrmValue *from;
51 XrmValue *to;
52 XtPointer *data;
53 #endif
54 {
55     String type = *(String *)args[0].addr;
56     String *names = *(String **)args[1].addr;
57     int *values = *(int **)args[2].addr;
58     int num = *(int *)args[3].addr;
59     String *prefixes = *(String **)args[4].addr;
60     String target = (String) from->addr;
61     String prefix;
62     int i;
63     static int value;  /* static for converter return */
64 
65     /*
66      * First, strip any of the listed prefixes off of target.
67      * All of the prefixes are optional, but they must occur in the
68      * order that they appear in the array in.
69      */
70     if (prefixes) {
71 	while (*prefixes) {
72 	    prefix = *prefixes;
73 	    for(i=0; prefix[i] && (target[i] == prefix[i]); i++);
74 	    if (prefix[i] == '\0') target += i;
75 	    prefixes++;
76 	}
77     }
78 
79     /*
80      * now see if the target appears in the names array.
81      * If not, print a warning and fail.
82      */
83     i = XmtBSearch(target, names, num);
84     if (i == -1) {
85 	XtDisplayStringConversionWarning(dpy, (String)from->addr, type);
86 	return False;
87     }
88 
89     /*
90      * converted value is values[i].
91      * We return it in different ways depending on the desired size to.size.
92      * Note how this code compares to the done() macro in ConvertersP.h
93      */
94     value = values[i];
95     if (to->addr != NULL) {
96 	switch (to->size) {
97 	case sizeof(char):
98 	    *(char *)to->addr = value;
99 	    break;
100 	case sizeof(short):
101 	    *(short *)to->addr = value;
102 	    break;
103 	case sizeof(int):
104 	    *(int *)to->addr = value;
105 	    break;
106 	default:
107 	    if (to->size > sizeof(int)) {
108 		to->size = sizeof(int);
109 		*(int *)to->addr = value;
110 	    }
111 	    else {
112 		to->size = sizeof(int);
113 		return False;
114 	    }
115 	    break;
116 	}
117     }
118     else {
119 	to->addr = (XtPointer)&value;  /* value is a static variable */
120 	to->size = sizeof(value);
121     }
122     return True;
123 }
124 
125 
126 #if NeedFunctionPrototypes
XmtRegisterEnumConverter(StringConst type,String * names,int * values,int num,String * prefixes)127 void XmtRegisterEnumConverter(StringConst type, String *names, int *values,
128 			      int num, String *prefixes)
129 #else
130 void XmtRegisterEnumConverter(type, names, values, num, prefixes)
131 StringConst type;
132 String *names;
133 int *values;
134 int num;
135 String *prefixes;
136 #endif
137 {
138     XtConvertArgRec args[5];
139 
140     /*
141      * XtSetTypeConverter copies these args, so it is
142      * okay to use an automatic array.
143      */
144     args[0].address_mode = XtImmediate;
145     args[0].address_id = (XtPointer) type;
146     args[0].size = sizeof(type);
147 
148     args[1].address_mode = XtImmediate;
149     args[1].address_id = (XtPointer) names;
150     args[1].size = sizeof(names);
151 
152     args[2].address_mode = XtImmediate;
153     args[2].address_id = (XtPointer) values;
154     args[2].size = sizeof(values);
155 
156     args[3].address_mode = XtImmediate;
157     args[3].address_id = (XtPointer) num;
158     args[3].size = sizeof(num);
159 
160     args[4].address_mode = XtImmediate;
161     args[4].address_id = (XtPointer) prefixes;
162     args[4].size = sizeof(prefixes);
163 
164     XtSetTypeConverter(XtRString, (String)type, XmtConvertStringToEnum,
165 		       args, 5, XtCacheNone, NULL);
166 }
167