1 /*
2 * Motif Tools Library, Version 3.1
3 * $Id: Symbols.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: Symbols.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:50:55 motiftools
32 * Initial import of Xmt310 to CVS
33 *
34 *
35 */
36
37 #include <Xmt/XmtP.h>
38 #include <Xmt/Symbols.h>
39 #include <Xmt/Hash.h>
40 #include <Xmt/QuarksP.h>
41 #include <X11/IntrinsicP.h>
42
43 /*
44 * values for the XmtSymbolRec mode field.
45 */
46 #define XmtSymbolABSOLUTE 1
47 #define XmtSymbolIMMEDIATE 2
48 #define XmtSymbolRESOURCE 3
49
50 static XmtHashTable symbol_table = NULL;
51
52 #if NeedFunctionPrototypes
GetResourceTypeAndSize(Widget w,String resource_name,XrmQuark * type,Cardinal * size)53 static void GetResourceTypeAndSize(Widget w, String resource_name,
54 XrmQuark *type, Cardinal *size)
55 #else
56 static void GetResourceTypeAndSize(w, resource_name, type, size)
57 Widget w;
58 String resource_name;
59 XrmQuark *type;
60 Cardinal *size;
61 #endif
62 {
63 int i;
64 Boolean found = False;
65 WidgetClass c = XtClass(w);
66 XtResourceList *list = (XtResourceList *) c->core_class.resources;
67 XrmQuark name = XrmStringToQuark(resource_name);
68
69 /* check normal resources first */
70 /* Note that we assume knowledge of the compiled resource format */
71 for(i=0; i < c->core_class.num_resources; i++) {
72 if ((list[i] != NULL) &&
73 ((XrmName)list[i]->resource_name == name)) {
74 found = True;
75 break;
76 }
77 }
78
79 /* check constraint resources if parent is constraint */
80 if (!found && XtParent(w) && XtIsConstraint(XtParent(w))) {
81 ConstraintWidgetClass c =
82 (ConstraintWidgetClass) XtClass(XtParent(w));
83 list = (XtResourceList *) c->constraint_class.resources;
84 for(i = 0; i < c->constraint_class.num_resources; i++) {
85 if ((list[i] != NULL) &&
86 ((XrmName)list[i]->resource_name == name)) {
87 found = True;
88 break;
89 }
90 }
91 }
92
93 if (found) {
94 *type = (XrmQuark)list[i]->resource_type;
95 *size = list[i]->resource_size;
96 }
97 }
98
99 /*
100 * s must be in static memory, or at least in memory that will never
101 * be freed. s->name must be the same. For statically declared arrays
102 * of symbols this is the usual case. For dynamically created symbols,
103 * the programmer must make a copy of the name in allocated memory.
104 */
105 #if NeedFunctionPrototypes
XmtRegisterSymbol(XmtSymbol s)106 void XmtRegisterSymbol(XmtSymbol s)
107 #else
108 void XmtRegisterSymbol(s)
109 XmtSymbol s;
110 #endif
111 {
112 XrmName name;
113
114 if (symbol_table == NULL)
115 symbol_table = XmtHashTableCreate(3);
116
117 if (s->addr == 0) { /* symbol is an immediate value */
118 /*
119 * if size > sizeof(XtPointer), an immediate value won't
120 * actually fit, so issue error msg. and exit.
121 */
122 if (s->size > sizeof(s->addr))
123 XmtErrorMsg("XmtSymbol", "size",
124 "Symbol '%s' has size too big for immediate mode.",
125 s->name);
126 s->mode = XmtSymbolIMMEDIATE;
127 s->type = (String)XrmStringToQuark(s->type);
128 }
129 else if (s->resource_name) { /* symbol is a widget resource */
130 GetResourceTypeAndSize((Widget)s->addr, s->resource_name,
131 (XrmQuark *) &s->type, &s->size);
132 s->mode = XmtSymbolRESOURCE;
133 }
134 else {
135 s->mode = XmtSymbolABSOLUTE;
136 s->type = (String)XrmStringToQuark(s->type);
137 }
138
139 name = XrmPermStringToQuark(s->name);
140 XmtHashTableStore(symbol_table, (XtPointer)name, (XtPointer)s);
141 }
142
143
144 /*
145 * The symbol records and the string within must be permanently allocated
146 */
147 #if NeedFunctionPrototypes
XmtRegisterSymbols(XmtSymbolRec * syms,Cardinal num_syms)148 void XmtRegisterSymbols(XmtSymbolRec *syms, Cardinal num_syms)
149 #else
150 void XmtRegisterSymbols(syms, num_syms)
151 XmtSymbolRec *syms;
152 Cardinal num_syms;
153 #endif
154 {
155 int i;
156 for(i=0; i < num_syms; i++) XmtRegisterSymbol(&syms[i]);
157 }
158
159 /*
160 * All strings must be permanently allocated, and may not change
161 */
162 #if NeedVarargsPrototypes
XmtVaRegisterSymbols(StringConst name,...)163 void XmtVaRegisterSymbols(StringConst name, ...)
164 #else
165 void XmtVaRegisterSymbols(name, va_alist)
166 StringConst name;
167 va_dcl
168 #endif
169 {
170 va_list var;
171 XmtSymbol sym;
172
173 Va_start(var, name);
174
175 while(name) {
176 sym = (XmtSymbol) XtCalloc(1, sizeof(XmtSymbolRec));
177 sym->name = (String) name;
178 sym->type = va_arg(var, String);
179 sym->size = va_arg(var, int);
180 sym->addr = va_arg(var, XtPointer);
181 XmtRegisterSymbol(sym);
182 name = va_arg(var, String);
183 }
184
185 va_end(var);
186 }
187
188 #if NeedFunctionPrototypes
XmtRegisterResourceList(XtPointer base,XtResourceList resources,Cardinal num_resources)189 void XmtRegisterResourceList(XtPointer base,
190 XtResourceList resources, Cardinal num_resources)
191 #else
192 void XmtRegisterResourceList(base, resources, num_resources)
193 XtPointer base;
194 XtResourceList resources;
195 Cardinal num_resources;
196 #endif
197 {
198 int i;
199 XmtSymbolRec *syms = (XmtSymbolRec *)XtCalloc(num_resources,
200 sizeof(XmtSymbolRec));
201
202 /*
203 * This procedure knows about the Intrinsics compiled resource format.
204 * This is a little dangerous.
205 */
206 if (((int) resources[0].resource_offset) >= 0) { /* uncompiled */
207 for(i=0; i < num_resources; i++) {
208 syms[i].name = resources[i].resource_name;
209 syms[i].type = resources[i].resource_type;
210 syms[i].size = resources[i].resource_size;
211 syms[i].addr = (XtPointer)
212 (resources[i].resource_offset + (char *)base);
213 }
214 }
215 else { /* compiled */
216 #define tostring(s) XrmQuarkToString((XrmQuark)s)
217 for(i=0; i < num_resources; i++) {
218 syms[i].name = tostring(resources[i].resource_name);
219 syms[i].type = tostring(resources[i].resource_type);
220 syms[i].size = resources[i].resource_size;
221 syms[i].addr = (XtPointer)
222 (-resources[i].resource_offset - 1 + (char *)base);
223 }
224 #undef tostring
225 }
226
227 XmtRegisterSymbols(syms, num_resources);
228 }
229
230 #if NeedFunctionPrototypes
XmtRegisterWidgetResource(StringConst name,Widget w,StringConst res)231 void XmtRegisterWidgetResource(StringConst name, Widget w, StringConst res)
232 #else
233 void XmtRegisterWidgetResource(name, w, res)
234 StringConst name;
235 Widget w;
236 StringConst res;
237 #endif
238 {
239 XmtSymbol s = (XmtSymbol) XtCalloc(1, sizeof(XmtSymbolRec));
240
241 s->name = (String) name;
242 s->addr = (XtPointer) w;
243 s->resource_name = (String) res;
244 XmtRegisterSymbol(s);
245 }
246
247
248 #if NeedFunctionPrototypes
XmtLookupSymbol(StringConst name)249 XmtSymbol XmtLookupSymbol(StringConst name)
250 #else
251 XmtSymbol XmtLookupSymbol(name)
252 StringConst name;
253 #endif
254 {
255 XmtSymbol s;
256 XrmQuark q = XrmStringToQuark(name);
257
258 if (!symbol_table) return NULL;
259 if (XmtHashTableLookup(symbol_table,(XtPointer)q, (XtPointer *)&s))
260 return s;
261 else
262 return NULL;
263 }
264
265 #if NeedFunctionPrototypes
XmtSymbolSetValue(XmtSymbol s,XtArgVal value)266 void XmtSymbolSetValue(XmtSymbol s, XtArgVal value)
267 #else
268 void XmtSymbolSetValue(s, value)
269 XmtSymbol s;
270 XtArgVal value;
271 #endif
272 {
273 XmtSymbolCallbackRec *p;
274 extern void _XtCopyFromArg();
275 int index;
276
277 /*
278 * Special case for XmtRBuffer type symbols.
279 * we copy the NULL-terminated string, and warn if it is too
280 * large for the buffer.
281 * XXX
282 * we should do sanity checking on buffer symbols. They can only
283 * have ABSOLUTE addressing mode.
284 */
285 if (s->type == (String) XmtQBuffer) {
286 int len = strlen((char *)value);
287 if (len < s->size)
288 strcpy((char *)s->addr, (char *) value);
289 else {
290 strncpy((char *)s->addr, (char *)value, s->size-1);
291 ((char *)s->addr)[s->size] = '\0';
292 XmtWarningMsg("XmtSymbolSetValue", "overflow",
293 "Symbol '%s': buffer overflow.\n\t%d characters lost.",
294 s->name, len - s->size +1);
295 }
296 }
297 else { /* anything other than buffer symbols */
298 /*
299 * if this is an enumerated symbol, then the new value is the
300 * index into the supplied array of values, not the value itself.
301 */
302 if (s->num_values > 0) {
303 index = (unsigned int) value;
304 if ((index >= s->num_values) || (index < 0)) {
305 XmtWarningMsg("XmtSymbolSetValue", "badValue",
306 "symbol '%s' has no enumerated value for %d.",
307 s->name, index);
308 return;
309 }
310 s->index = (unsigned short)index;
311 value = (XtArgVal)s->values[index];
312 }
313
314 /* XXX
315 * machine dependencies? Does this work on a Sparc?
316 */
317 switch(s->mode) {
318 case XmtSymbolABSOLUTE:
319 _XtCopyFromArg(value, s->addr, s->size);
320 break;
321 case XmtSymbolIMMEDIATE:
322 _XtCopyFromArg(value, &s->addr, s->size);
323 break;
324 case XmtSymbolRESOURCE:
325 XtVaSetValues((Widget)s->addr, s->resource_name, value, NULL);
326 break;
327 }
328 }
329
330 /*
331 * call notify procs.
332 */
333 for(p = s->callbacks; p; p = p->next)
334 (*p->proc)(s, p->closure, value);
335 }
336
337 #if NeedFunctionPrototypes
XmtSymbolSetTypedValue(Widget w,XmtSymbol s,String type,XtArgVal value,Cardinal size)338 Boolean XmtSymbolSetTypedValue(Widget w, XmtSymbol s, String type,
339 XtArgVal value, Cardinal size)
340 #else
341 Boolean XmtSymbolSetTypedValue(w, s, type, value, size)
342 Widget w;
343 XmtSymbol s;
344 String type;
345 XtArgVal value;
346 Cardinal size;
347 #endif
348 {
349 XrmQuark typeq = XrmStringToQuark(type);
350 XrmValue from, to;
351 XtArgVal converted_value;
352 Boolean status;
353 extern void _XtCopyToArg();
354
355 /*
356 * if the types match, just call XmtSymbolSetValue().
357 * if the symbol is a buffer, and the value a string, that is a match.
358 */
359 if ((typeq == (XrmQuark) s->type) ||
360 ((typeq == XmtQString) && (s->type == (String) XmtQBuffer))) {
361 XmtSymbolSetValue(s, value);
362 return True;
363 }
364
365 /*
366 * otherwise attempt to convert the value.
367 */
368 from.size = size;
369 if ((size > sizeof(XtArgVal)) ||
370 (typeq == XmtQString) || (typeq == XmtQBuffer))
371 from.addr = (XPointer) value;
372 else
373 from.addr = (XPointer) &value;
374 /* let the converter return a value of the right type. */
375 to.addr = NULL;
376 to.size = s->size;
377 status = XtConvertAndStore(w, type, &from,
378 XrmQuarkToString((XrmQuark)s->type), &to);
379
380 if (status) {
381 converted_value = 0; /* make func below store directly into us */
382 _XtCopyToArg(to.addr, &converted_value, to.size);
383 XmtSymbolSetValue(s, converted_value);
384 }
385 else {
386 XmtWarningMsg("XmtSymbolSetTypedValue", "convert",
387 "Couldn't set symbol '%s'.", s->name);
388 }
389
390 return status;
391 }
392
393 #if NeedFunctionPrototypes
XmtSymbolGetValue(XmtSymbol s,XtArgVal * valuep)394 void XmtSymbolGetValue(XmtSymbol s, XtArgVal *valuep)
395 #else
396 void XmtSymbolGetValue(s, valuep)
397 XmtSymbol s;
398 XtArgVal *valuep;
399 #endif
400 {
401 extern void _XtCopyToArg();
402
403 /*
404 * Special case for XmtRBuffer type symbols.
405 * Just return the address.
406 */
407 if (s->type == (String) XmtQBuffer) {
408 *(char **)valuep = s->addr;
409 return;
410 }
411
412 switch(s->mode) {
413 case XmtSymbolABSOLUTE:
414 _XtCopyToArg(s->addr, (XtArgVal *) &valuep, s->size);
415 break;
416 case XmtSymbolIMMEDIATE:
417 _XtCopyToArg(&s->addr, (XtArgVal *) &valuep, s->size);
418 break;
419 case XmtSymbolRESOURCE:
420 XtVaGetValues((Widget)s->addr, s->resource_name, valuep);
421 break;
422 }
423 }
424
425 #if NeedFunctionPrototypes
XmtSymbolGetScalarValue(XmtSymbol s)426 int XmtSymbolGetScalarValue(XmtSymbol s)
427 #else
428 int XmtSymbolGetScalarValue(s)
429 XmtSymbol s;
430 #endif
431 {
432 if (s->num_values > 0) return (int)s->index;
433 else
434 XmtWarningMsg("XmtSymbolGetScalarValue", "badSymbol",
435 "symbol '%s' is not an enumerated value.",
436 s->name);
437 return -1;
438 }
439
440
441 #if NeedFunctionPrototypes
XmtSymbolAddCallback(XmtSymbol s,XmtSymbolCallbackProc proc,XtPointer closure)442 void XmtSymbolAddCallback(XmtSymbol s, XmtSymbolCallbackProc proc,
443 XtPointer closure)
444 #else
445 void XmtSymbolAddCallback(s, proc, closure)
446 XmtSymbol s;
447 XmtSymbolCallbackProc proc;
448 XtPointer closure;
449 #endif
450 {
451 XmtSymbolCallbackRec *cb = XtNew(XmtSymbolCallbackRec);
452 XmtSymbolCallbackRec *p;
453
454 cb->proc = proc;
455 cb->closure = closure;
456 cb->next = NULL;
457 if (s->callbacks == NULL) s->callbacks = cb;
458 else {
459 for(p = s->callbacks; p->next; p = p->next);
460 p->next = cb;
461 }
462 }
463
464 #if NeedFunctionPrototypes
XmtSymbolRemoveCallback(XmtSymbol s,XmtSymbolCallbackProc proc,XtPointer closure)465 void XmtSymbolRemoveCallback(XmtSymbol s, XmtSymbolCallbackProc proc,
466 XtPointer closure)
467 #else
468 void XmtSymbolRemoveCallback(s, proc, closure)
469 XmtSymbol s;
470 XmtSymbolCallbackProc proc;
471 XtPointer closure;
472 #endif
473 {
474 XmtSymbolCallbackRec *p, *q;
475
476 for(q=NULL, p = s->callbacks; p; q=p, p = p->next)
477 if ((p->proc == proc) && (p->closure == closure)) break;
478
479 if (p) {
480 if (!q) s->callbacks = p->next;
481 else q->next = p->next;
482 XtFree((char *)p);
483 }
484 }
485
486 #if NeedFunctionPrototypes
XmtSymbolName(XmtSymbol s)487 String XmtSymbolName(XmtSymbol s)
488 #else
489 String XmtSymbolName(s)
490 XmtSymbol s;
491 #endif
492 {
493 return s->name;
494 }
495
496 #if NeedFunctionPrototypes
XmtSymbolSize(XmtSymbol s)497 int XmtSymbolSize(XmtSymbol s)
498 #else
499 int XmtSymbolSize(s)
500 XmtSymbol s;
501 #endif
502 {
503 return s->size;
504 }
505
506 #if NeedFunctionPrototypes
XmtSymbolTypeQuark(XmtSymbol s)507 XrmQuark XmtSymbolTypeQuark(XmtSymbol s)
508 #else
509 XrmQuark XmtSymbolTypeQuark(s)
510 XmtSymbol s;
511 #endif
512 {
513 return (XrmQuark) s->type;
514 }
515
516 #if NeedFunctionPrototypes
XmtSymbolType(XmtSymbol s)517 String XmtSymbolType(XmtSymbol s)
518 #else
519 String XmtSymbolType(s)
520 XmtSymbol s;
521 #endif
522 {
523 return XrmQuarkToString((XrmQuark)s->type);
524 }
525
526 #if NeedFunctionPrototypes
XmtSymbolIsEnumerated(XmtSymbol s)527 Boolean XmtSymbolIsEnumerated(XmtSymbol s)
528 #else
529 Boolean XmtSymbolIsEnumerated(s)
530 XmtSymbol s;
531 #endif
532 {
533 return (s->num_values > 0);
534 }
535