1 /*
2 * Motif Tools Library, Version 3.1
3 * $Id: Create.c,v 1.3 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: Create.c,v $
12 * Revision 1.3 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.2 2001/04/15 15:29:36 grmcdorman
32 * * XmtCallCallback has two new arguments types: XmtRCallbackUserData, which
33 * is the XmNuserData value, and XmtRCallbackImmediate, which is a value
34 * embedded in the list.
35 *
36 * * Two new functions, XmtCreateQueryListChildren and XmtCreateQueryListChild,
37 * are provided. They are like the XmtCreate* functions except that they
38 * return a list of the widgets created (quark and pointer to the widget).
39 *
40 * * Major enhancements to XmtInputField:
41 * - The input field now has a cancel() action. This reverts the field's
42 * value to that prior to the start of editing (i.e. the last commit).
43 * No default translation is bound to this action, however.
44 * - There is a callback for the cancel action (XmtNcancelCallback).
45 * - The input field can be set to cancel, commit, or do nothing on focus
46 * out. (Previously, it always did a commit). The default is commit.
47 * (XmtNfocusOutAction)
48 *
49 * * XmtLayout:
50 * - It now has a losingFocusCallback (XmNloosingFocusCallback).
51 * - It, and the layout widgets (XmtLayoutBox/XmtLayoutString), now
52 * support background pixmaps.
53 * - It now supports XmNresizePolicy.
54 * - Strings in the layout parser are converted to XmStrings by
55 * XtConvertAndStore, so any custom XmString conversion is used
56 * (as, for example, the Xmt convert, which supports the @[]
57 * embedded items)
58 *
59 * * Other:
60 * - Pixmaps are convered using XtConvertAndStore, again to allow
61 * custom converters.
62 *
63 * Bug Fixes: (for Solaris 2.5.1/Motif 1.2/Sparc system)
64 * * XmtInputField did not work properly if the widget had traversalOn
65 * false.
66 * * XmtLayout's child geometry manager was called by Xt when
67 * a shell child was added to the layout; it did not handle
68 * this case.
69 * * XmtLayout had an XmtWarningMsg call with a missing argument (line 2029).
70 * * Widgets automatically created by XmtLayout parsing have been given
71 * non-blank names. [You may wish to tweak this by adding, for example,
72 * a leading underscore.]
73 * * Under some circumstances, XmtNameToWidget could be called during
74 * widget creation, with 'w->core.num_popups' uninitialized. The
75 * workaround applied is to ignore the popup list if the 'num_popups'
76 * value is more than 50 or negative.
77 *
78 * Revision 1.1.1.1 2001/02/10 13:42:08 motiftools
79 * Initial import of Xmt310 to CVS
80 *
81 *
82 */
83
84 #include <Xmt/XmtP.h>
85 #include <Xmt/Create.h>
86 #include <Xmt/WidgetType.h>
87 #include <Xmt/Include.h>
88 #include <Xmt/Template.h>
89 #include <Xmt/DialogP.h>
90 #include <Xmt/Lexer.h>
91 #include <Xmt/ConvertersP.h>
92 #include <Xmt/AppResP.h>
93 #include <Xm/DialogS.h>
94 #include <X11/IntrinsicP.h>
95 #include <X11/CompositeP.h>
96
97 #include <unistd.h>
98
99
100 #if NeedFunctionPrototypes
ConvertCallbackList(Widget w,StringConst s,XtCallbackList * list_return,XtCacheRef * ref_return)101 static void ConvertCallbackList(Widget w, StringConst s,
102 XtCallbackList *list_return,
103 XtCacheRef *ref_return)
104 #else
105 static void ConvertCallbackList(w, s, list_return, ref_return)
106 Widget w;
107 StringConst s;
108 XtCallbackList *list_return;
109 XtCacheRef *ref_return;
110 #endif
111 {
112 XrmValue from, to;
113
114 if (_XmtCallbackConverter == NULL) {
115 XmtWarningMsg("CreateWidget", "noConverter",
116 "no String to XtCallbackList converter registered.\n\tCall XmtRegisterCallbackConverter().");
117 return;
118 }
119
120 from.addr = (XPointer) s;
121 from.size = strlen(s)+1;
122 to.addr = (XPointer) list_return;
123 to.size = sizeof(XtCallbackList);
124 XtCallConverter(XtDisplayOfObject(w), _XmtCallbackConverter, NULL, 0,
125 &from, &to, ref_return);
126 }
127
128 #if NeedFunctionPrototypes
FreeCallbackList(Widget w,XtCacheRef ref)129 static void FreeCallbackList(Widget w, XtCacheRef ref)
130 #else
131 static void FreeCallbackList(w, ref)
132 Widget w;
133 XtCacheRef ref;
134 #endif
135 {
136 XtCacheRef refs[2];
137
138 if (ref == NULL) return;
139 refs[0] = ref;
140 refs[1] = NULL;
141 XtAppReleaseCacheRefs(XtWidgetToApplicationContext(w), refs);
142 }
143
144 #if NeedFunctionPrototypes
CallCallbackList(Widget w,XtCallbackList list)145 static void CallCallbackList(Widget w, XtCallbackList list)
146 #else
147 static void CallCallbackList(w, list)
148 Widget w;
149 XtCallbackList list;
150 #endif
151 {
152 for(; list->callback; list++)
153 (*list->callback)(w, list->closure, NULL);
154 }
155
156 typedef XmtWidgetList WidgetName;
157
158 /* forward declaration */
159 #if NeedFunctionPrototypes
160 static void CreateChildren(Widget, XmtDialogInfo *, WidgetName *, Cardinal);
161 static Widget _XmtCreateChild(Widget, StringConst, XmtDialogInfo *,
162 WidgetName *, Cardinal);
163 #else
164 static void CreateChildren();
165 static Widget _XmtCreateChild();
166 #endif
167
168 typedef struct {
169 String create;
170 String children;
171 String managed;
172 } CallbackStringsType;
173
174 static XtResource callback_resources[] = {
175 {XmtNxmtCreationCallback, XmtCXmtCreationCallback, XtRString,
176 sizeof(String), XtOffsetOf(CallbackStringsType, create),
177 XtRString, (XtPointer) NULL},
178 {XmtNxmtChildrenCreationCallback, XmtCXmtChildrenCreationCallback, XtRString,
179 sizeof(String), XtOffsetOf(CallbackStringsType, children),
180 XtRString, (XtPointer) NULL},
181 {XmtNxmtManagedCreationCallback, XmtCXmtManagedCreationCallback, XtRString,
182 sizeof(String), XtOffsetOf(CallbackStringsType, managed),
183 XtRString, (XtPointer) NULL},
184 };
185
186 static XtResource requires_resource[] = {
187 {XmtNxmtRequires, XmtCXmtRequires, XtRString,
188 sizeof(String), 0, XtRString, NULL}
189 };
190
191 #if NeedFunctionPrototypes
CreateChild(Widget parent,StringConst name,XmtWidgetType * type,String template,Boolean managed,String * styles,Cardinal num_styles,Boolean load,XmtDialogInfo * dialog_info,WidgetName * names,Cardinal num_names)192 static Widget CreateChild(Widget parent, StringConst name, XmtWidgetType *type,
193 String template, Boolean managed,
194 String *styles, Cardinal num_styles, Boolean load,
195 XmtDialogInfo *dialog_info,
196 WidgetName *names, Cardinal num_names)
197 #else
198 static Widget CreateChild(parent, name, type, template, managed,
199 styles, num_styles, load, dialog_info,
200 names, num_names)
201 Widget parent;
202 StringConst name;
203 XmtWidgetType *type;
204 String template;
205 Boolean managed;
206 String *styles;
207 Cardinal num_styles;
208 Boolean load;
209 XmtDialogInfo *dialog_info;
210 WidgetName *names;
211 Cardinal num_names;
212 #endif
213 {
214 Widget w = NULL;
215 String requires_string;
216 CallbackStringsType callback_strings;
217 XrmQuark nameq;
218 XtCallbackList create_callback_list = NULL;
219 XtCallbackList children_callback_list = NULL;
220 XtCallbackList managed_callback_list = NULL;
221 XtCacheRef create_callback_ref;
222 XtCacheRef children_callback_ref;
223 XtCacheRef managed_callback_ref;
224 int i;
225
226 /* first, load any required files, unless already loaded */
227 if (load) {
228 XtGetSubresources(parent, (XtPointer)&requires_string,
229 (String)name, (String)name,
230 requires_resource, (Cardinal)1,
231 NULL, (Cardinal) 0);
232 if (requires_string) XmtLoadResourceFileList(parent, requires_string);
233 }
234
235 /* apply any styles that were specified */
236 if (num_styles)
237 for(i=0; i < num_styles; i++)
238 XmtTemplateInstantiate(parent, name, styles[i], NULL, 0);
239
240 /* now create the widget */
241 if (type)
242 w = XmtCreateWidgetType(name, type, parent, NULL, 0);
243 else if (template) {
244 /*
245 * if the widget is a template type, instantiate the template,
246 * and then start the creation process over to read the xmtType
247 * resource. Note that we recurse and then return immediately.
248 * If we don't return the callbacks will be called twice and
249 * the children created twice.
250 */
251 XmtTemplateInstantiate(parent, name, template, NULL, 0);
252 w = _XmtCreateChild(parent, name, dialog_info, names, num_names);
253 return w;
254 }
255
256 /*
257 * if we don't have a widget now, something went wrong.
258 * Assume that someone else printed a warning message, and return.
259 */
260 if (w == NULL) return NULL;
261
262 /*
263 * see if the widget matches any in the names list, and if so,
264 * store the widget pointer at the given address
265 */
266 nameq = XrmStringToQuark(name);
267 for(i=0; i < num_names; i++) {
268 if (nameq == names[i].nameq) {
269 *names[i].widgetp = w;
270 break;
271 }
272 }
273
274 /*
275 * A widget has just been created. Next we:
276 * (0) fetch and convert the creation callback resources
277 * (1) invoke the xmtCreationCallback list
278 * (2) call CreateChildren to create the widget's children (reg. or popup)
279 * (2a) invoke the xmtChildrenCreationCallback list
280 * (3) manage it, unless a shell or unmanaged
281 * (3a) invoke the xmtManagedCreationCallback list
282 * (4) free any creation callbacks.
283 */
284
285 /* (0) fetch and convert the creation callback resources */
286 XtGetApplicationResources(w, (XtPointer)&callback_strings,
287 callback_resources, XtNumber(callback_resources),
288 NULL, (Cardinal)0);
289 if (callback_strings.create)
290 ConvertCallbackList(w, callback_strings.create,
291 &create_callback_list, &create_callback_ref);
292 if (callback_strings.children)
293 ConvertCallbackList(w, callback_strings.children,
294 &children_callback_list, &children_callback_ref);
295 if (callback_strings.managed)
296 ConvertCallbackList(w, callback_strings.managed,
297 &managed_callback_list, &managed_callback_ref);
298
299 /* (1) invoke the xmtCreationCallback list */
300 if (create_callback_list) CallCallbackList(w, create_callback_list);
301
302 /* (2) call CreateChildren, to create regular or popup children */
303 CreateChildren(w, dialog_info, names, num_names);
304
305 /* (2a) invoke the xmtChildrenCreationCallback list */
306 if (children_callback_list) CallCallbackList(w,children_callback_list);
307
308 /* (3) manage it, unless a shell or unmanaged */
309 if (managed && !XtIsShell(w)) {
310 XtManageChild(w);
311 /* (3a) invoke the xmtManagedCreationCallback list */
312 if (managed_callback_list) CallCallbackList(w, managed_callback_list);
313 }
314
315 /* (4) free any creation callbacks. */
316 if (create_callback_list) FreeCallbackList(w, create_callback_ref);
317 if (children_callback_list) FreeCallbackList(w, children_callback_ref);
318 if (managed_callback_list) FreeCallbackList(w, managed_callback_ref);
319
320 return w;
321 }
322
323 static String keywords[] = {
324 "managed",
325 "unmanaged",
326 };
327
328 #define MANAGED 0
329 #define UNMANAGED 1
330
331 #define MAX_TEMPLATE_ARGS 10
332
333 #if NeedFunctionPrototypes
ParseType(Widget w,StringConst name,XmtLexer l,XmtWidgetType ** type,String * template,Boolean * managed,String ** styles,Cardinal * num_styles)334 static Boolean ParseType(Widget w, StringConst name, XmtLexer l,
335 XmtWidgetType **type, String *template,
336 Boolean *managed,
337 String **styles, Cardinal *num_styles)
338 #else
339 static Boolean ParseType(w, name, l, type, template, managed,
340 styles, num_styles)
341 Widget w;
342 StringConst name;
343 XmtLexer l;
344 XmtWidgetType **type;
345 String *template;
346 Boolean *managed;
347 String **styles;
348 Cardinal *num_styles;
349 #endif
350 {
351 XmtLexerToken tok;
352 int max_styles = 0;
353 String style;
354 String args[MAX_TEMPLATE_ARGS];
355 Cardinal num_args;
356 Cardinal expected_args;
357 String template_name;
358 int i;
359
360 /* set defaults and parse any modifiers or styles */
361 *managed = True;
362 *num_styles = 0;
363 *styles = NULL;
364 while (1) {
365 tok = XmtLexerGetToken(l);
366 if (tok == XmtLexerKeyword) {
367 switch(XmtLexerKeyValue(l)) {
368 case MANAGED:
369 *managed = True;
370 break;
371 case UNMANAGED:
372 *managed = False;
373 break;
374 }
375 XmtLexerConsumeToken(l);
376 }
377 else if ((tok == XmtLexerIdent) &&
378 ((style = XmtLookupStyle(w, XmtLexerStrValue(l))) != NULL)) {
379 if (*num_styles == max_styles) {
380 max_styles += 4;
381 *styles = (String *)XtRealloc((char *)*styles,
382 max_styles * sizeof(String));
383 }
384 template_name = XmtLexerStrValue(l);
385 XmtLexerConsumeToken(l);
386 XmtLexerGetArgList(l, args, MAX_TEMPLATE_ARGS, &num_args);
387 style = XmtTemplateSubstituteArgs(style, args, num_args,
388 &expected_args);
389 *styles[*num_styles] = style;
390 *num_styles += 1;
391 if (num_args > expected_args)
392 XmtWarningMsg("XmtParseWidgetType", "styleArgs",
393 "widget '%s':\n\tstyle '%s' expects up to %d args; %d passed.",
394 name, template_name, expected_args, num_args);
395 for(i=0; i < num_args; i++) XtFree(args[i]);
396 XtFree(template_name);
397 }
398 else
399 break;
400 }
401
402 /* now we expect a widget type or template */
403 *type = NULL;
404 *template = NULL;
405 if (XmtLexerGetToken(l) != XmtLexerIdent) {
406 XmtWarningMsg("XmtParseWidgetType", "syntax",
407 "syntax error in xmtChildren or xmtType resource\n\tof widget '%s'.",
408 name);
409 return False;
410 }
411 *type = XmtLookupWidgetType(XmtLexerStrValue(l));
412 if (!*type) {
413 *template = XmtLookupTemplate(w, XmtLexerStrValue(l));
414 if (*template) {
415 template_name = XmtLexerStrValue(l);
416 XmtLexerConsumeToken(l);
417 XmtLexerGetArgList(l, args, MAX_TEMPLATE_ARGS, &num_args);
418 *template = XmtTemplateSubstituteArgs(*template, args, num_args,
419 &expected_args);
420 if (num_args > expected_args)
421 XmtWarningMsg("XmtParseWidgetType", "templateArgs",
422 "widget '%s':\n\ttemplate '%s' expects up to %d args; %d passed.",
423 name, template_name, expected_args, num_args);
424 for(i=0; i < num_args; i++) XtFree(args[i]);
425 XtFree(template_name);
426 }
427 }
428
429 if (!*type && !*template)
430 XmtWarningMsg("XmtParseWidgetType", "type",
431 "unknown widget type %s\n\tin xmtChildren or xmtType resource of widget %s.",
432 XmtLexerStrValue(l), name);
433 if (!*template) {
434 XtFree(XmtLexerStrValue(l));
435 XmtLexerConsumeToken(l);
436 }
437
438 if (*type || *template) return True;
439 else {
440 if (*num_styles) {
441 for(i=0; i < *num_styles; i++) XtFree(*styles[i]);
442 XtFree((char *)*styles);
443 *styles = NULL;
444 *num_styles = 0;
445 }
446 return False;
447 }
448 }
449
450 #if NeedFunctionPrototypes
SetDialogInfo(XmtDialogInfo * info,String resource,Widget w,XmtWidgetType * type)451 static void SetDialogInfo(XmtDialogInfo *info, String resource,
452 Widget w, XmtWidgetType *type)
453 #else
454 static void SetDialogInfo(info, resource, w, type)
455 XmtDialogInfo *info;
456 String resource;
457 Widget w;
458 XmtWidgetType *type;
459 #endif
460 {
461 int i;
462 XrmQuark resourceq = XrmStringToQuark(resource);
463
464 if ((type->get_value_proc == NULL) && (type->set_value_proc == NULL)) {
465 XmtWarningMsg("XmtCreateChildren", "notype",
466 "Can't associate resource '%s' with child '%s';\n\twidget class '%s' has no get value nor set value procedure.",
467 resource, XtName(w), type->name);
468 return;
469 }
470
471 for(i = 0; i < info->num_resources; i++)
472 if (info->resources[i].resource_name == (String)resourceq) break;
473
474 if (i < info->num_resources) {
475 info->widgets[i] = w;
476 info->types[i] = type;
477 }
478 else
479 XmtWarningMsg("XmtCreateChildren", "noname",
480 "Child '%s': resource name '%s' not found.",
481 XtName(w), resource);
482 }
483
484 #if NeedFunctionPrototypes
CreateWidgetList(Widget parent,XmtLexer l,XmtDialogInfo * dialog_info,WidgetName * names,Cardinal num_names)485 static void CreateWidgetList(Widget parent, XmtLexer l,
486 XmtDialogInfo *dialog_info,
487 WidgetName *names, Cardinal num_names)
488 #else
489 static void CreateWidgetList(parent, l, dialog_info, names, num_names)
490 Widget parent;
491 XmtLexer l;
492 XmtDialogInfo *dialog_info;
493 WidgetName *names;
494 Cardinal num_names;
495 #endif
496 {
497 Boolean managed;
498 XmtWidgetType *type;
499 String template;
500 String *styles;
501 Cardinal num_styles;
502 XmtLexerToken tok;
503 Widget child;
504 int i;
505
506 if (ParseType(parent, XtName(parent), l, &type, &template,
507 &managed, &styles, &num_styles) == False)
508 goto error;
509
510 /* now read a list of names, and create them */
511 /* grammar: id [= name] (',' id[= name])* ';' */
512 while (1) {
513 if (XmtLexerGetToken(l) != XmtLexerIdent) goto syntax;
514 child = CreateChild(parent, XmtLexerStrValue(l), type, template,
515 managed, styles, num_styles, True, dialog_info,
516 names, num_names);
517 XtFree(XmtLexerStrValue(l));
518 tok = XmtLexerNextToken(l);
519 if (tok == XmtLexerEqual) {
520 tok = XmtLexerNextToken(l);
521 if (tok != XmtLexerIdent) goto syntax;
522 if (!type) {
523 XmtWarningMsg("XmtCreateChildren", "resource",
524 "child '%s' cannot have a resource name '%s':\n\tchild's type is a template, not a registered widget type.",
525 XtName(child), XmtLexerStrValue(l));
526 }
527 else if (dialog_info)
528 SetDialogInfo(dialog_info, XmtLexerStrValue(l), child, type);
529 else
530 XmtWarningMsg("XmtCreateChildren", "resource",
531 "child '%s' cannot have a resource name '%s':\n\tthere is no resource list associated with this widget tree.",
532 XtName(child), XmtLexerStrValue(l));
533
534 XtFree(XmtLexerStrValue(l));
535 tok = XmtLexerNextToken(l);
536 }
537 if (tok == XmtLexerSemicolon) break;
538 else if (tok != XmtLexerComma) goto syntax;
539 XmtLexerConsumeToken(l);
540 }
541 XmtLexerConsumeToken(l); /* skip the semicolon */
542
543 if (template) XtFree(template);
544 if (num_styles) {
545 for(i=0; i < num_styles; i++) XtFree(styles[i]);
546 XtFree((char *)styles);
547 }
548
549 /* eat the final semicolon, and we're done */
550 XmtLexerConsumeToken(l);
551 return;
552
553 syntax:
554 XmtWarningMsg("XmtCreateChildren", "syntax",
555 "syntax error in xmtChildren resource\n\t of widget %s",
556 XtName(parent));
557 error: /* read till semicolon */
558 while(((tok = XmtLexerNextToken(l)) != XmtLexerSemicolon) &&
559 (tok != XmtLexerEndOfString));
560 XmtLexerConsumeToken(l);
561 }
562
563
564 static XtResource children_resource[] = {
565 {XmtNxmtChildren, XmtCXmtChildren, XtRString,
566 sizeof(String), 0, XtRString, NULL}
567 };
568
569 #if NeedFunctionPrototypes
CreateChildren(Widget parent,XmtDialogInfo * dialog_info,WidgetName * names,Cardinal num_names)570 static void CreateChildren(Widget parent, XmtDialogInfo *dialog_info,
571 WidgetName *names, Cardinal num_names)
572 #else
573 static void CreateChildren(parent, dialog_info, names, num_names)
574 Widget parent;
575 XmtDialogInfo *dialog_info;
576 WidgetName *names;
577 Cardinal num_names;
578 #endif
579 {
580 String children_string;
581 XmtLexer lexer;
582
583 /* fetch the value of the xmtChildren resource */
584 XtGetApplicationResources(parent, (XtPointer)&children_string,
585 children_resource, (Cardinal) 1,
586 NULL, (Cardinal)0);
587
588 /* XXX should we issue a warning here? */
589 if (children_string == NULL) return;
590
591 /*
592 * get ready to parse the string.
593 * we copy the string because the process of parsing it can cause
594 * new resource files to be loaded, which could cause it to be freed
595 * from underneath us.
596 */
597
598 children_string = XtNewString(children_string);
599 lexer = XmtLexerCreate(keywords, XtNumber(keywords));
600 XmtLexerInit(lexer, children_string);
601
602 while(XmtLexerGetToken(lexer) != XmtLexerEndOfString)
603 CreateWidgetList(parent, lexer, dialog_info, names, num_names);
604
605 XmtLexerDestroy(lexer);
606 XtFree(children_string);
607 }
608
609
610 #if NeedFunctionPrototypes
_XmtCreateChildren(Widget parent,WidgetName * names,Cardinal num_names)611 static void _XmtCreateChildren(Widget parent,
612 WidgetName *names, Cardinal num_names)
613 #else
614 static void _XmtCreateChildren(parent, names, num_names)
615 Widget parent;
616 WidgetName *names;
617 Cardinal num_names;
618 #endif
619 {
620 XmtDialogInfo *dialog_info;
621 String requires_string;
622
623 /* see if there is a resource list associated with this parent */
624 dialog_info = _XmtDialogLookupDialogInfo(parent);
625
626 /* first, load any required files */
627 XtGetApplicationResources(parent, (XtPointer)&requires_string,
628 requires_resource, (Cardinal)1,
629 NULL, (Cardinal) 0);
630 if (requires_string) XmtLoadResourceFileList(parent, requires_string);
631
632 /* do the rest */
633 CreateChildren(parent, dialog_info, names, num_names);
634 }
635
636 #if NeedFunctionPrototypes
XmtCreateChildren(Widget parent)637 void XmtCreateChildren(Widget parent)
638 #else
639 void XmtCreateChildren(parent)
640 Widget parent;
641 #endif
642 {
643 _XmtCreateChildren(parent, NULL, 0);
644 }
645
646 #if NeedFunctionPrototypes
GetWidgetNames(va_list var,WidgetName ** names_return,Cardinal * num_return)647 static void GetWidgetNames(va_list var,
648 WidgetName **names_return, Cardinal *num_return)
649 #else
650 static void GetWidgetNames(var, names_return, num_return)
651 va_list var;
652 WidgetName **names_return;
653 Cardinal *num_return;
654 #endif
655 {
656 WidgetName *names;
657 String name;
658 Cardinal num, max;
659
660 num = max = 0;
661 names = NULL;
662 while((name = va_arg(var, String)) != NULL) {
663 if (num == max) {
664 max += 10;
665 names = (WidgetName *)XtRealloc((char *)names,
666 max * sizeof(WidgetName));
667 }
668 names[num].nameq = XrmStringToQuark(name);
669 names[num].widgetp = va_arg(var, Widget *);
670 /* initialize *widgetp to NULL in case it is not found */
671 *names[num].widgetp = NULL;
672 num++;
673 }
674
675 *names_return = names;
676 *num_return = num;
677 }
678
679 #if NeedVarargsPrototypes
XmtCreateQueryChildren(Widget parent,...)680 void XmtCreateQueryChildren(Widget parent, ...)
681 #else
682 void XmtCreateQueryChildren(parent, va_alist)
683 Widget parent;
684 va_dcl
685 #endif
686 {
687 va_list var;
688 WidgetName *names;
689 Cardinal num_names;
690
691 Va_start(var, parent);
692 GetWidgetNames(var, &names, &num_names);
693 va_end(var);
694 _XmtCreateChildren(parent, names, num_names);
695 XtFree((char *)names);
696 }
697
698 #if NeedFunctionPrototypes
XmtCreateQueryListChildren(Widget parent,XmtWidgetList * names,Cardinal num_names)699 void XmtCreateQueryListChildren(Widget parent, XmtWidgetList * names,
700 Cardinal num_names)
701 #else
702 void XmtCreateQueryListChildren(parent, names, num_names)
703 Widget parent;
704 XmtWidgetList * names;
705 Cardinal num_names;
706 #endif
707 {
708 /*
709 * initialize widgets to NULL
710 */
711 int i;
712 for (i = 0; i < num_names; i++) {
713 *names[i].widgetp = NULL;
714 }
715
716 _XmtCreateChildren(parent, names, num_names);
717 }
718
719 static XtResource type_resource[] = {
720 {XmtNxmtType, XmtCXmtType, XtRString,
721 sizeof(String), 0, XtRString, NULL}
722 };
723
724
725 #if NeedFunctionPrototypes
_XmtCreateChild(Widget parent,StringConst name,XmtDialogInfo * dialog_info,WidgetName * names,Cardinal num_names)726 static Widget _XmtCreateChild(Widget parent, StringConst name,
727 XmtDialogInfo *dialog_info,
728 WidgetName *names, Cardinal num_names)
729 #else
730 static Widget _XmtCreateChild(parent, name, dialog_info, names, num_names)
731 Widget parent;
732 StringConst name;
733 XmtDialogInfo *dialog_info;
734 WidgetName *names;
735 Cardinal num_names;
736 #endif
737 {
738 String requires_string, type_string;
739 XmtLexer lexer;
740 XmtWidgetType *type;
741 String template;
742 Boolean managed;
743 String *styles;
744 Cardinal num_styles;
745 Widget w;
746 int i;
747
748 /* first, load any required files XXX ?*/
749 XtGetSubresources(parent, (XtPointer)&requires_string,
750 (String)name, (String)name,
751 requires_resource, (Cardinal)1,
752 NULL, (Cardinal) 0);
753 if (requires_string) XmtLoadResourceFileList(parent, requires_string);
754
755 /* fetch the value of the xmtType resource */
756 XtGetSubresources(parent, (XtPointer)&type_string,
757 (String)name, (String)name,
758 type_resource, (Cardinal) 1,
759 NULL, (Cardinal)0);
760
761 if (type_string == NULL) {
762 XmtWarningMsg("XmtCreateChild", "noType",
763 "widget '%s' has no xmtType resource.",
764 name);
765 return NULL;
766 }
767
768 /* get ready to parse the string */
769 lexer = XmtLexerCreate(keywords, XtNumber(keywords));
770 XmtLexerInit(lexer, type_string);
771
772 /*
773 * if we parse it sucessfully, create the child.
774 * Note that CreateChild won't re-load the required files.
775 */
776 if (ParseType(parent, name, lexer, &type, &template,
777 &managed, &styles, &num_styles)) {
778 w = CreateChild(parent, name, type, template,
779 managed, styles, num_styles, False,
780 dialog_info, names, num_names);
781 if (template) XtFree(template);
782 if (num_styles) {
783 for(i=0; i < num_styles; i++) XtFree(styles[i]);
784 XtFree((char *)styles);
785 }
786 }
787 else
788 w = NULL;
789
790 XmtLexerDestroy(lexer);
791 return w;
792 }
793
794 #if NeedFunctionPrototypes
XmtCreateChild(Widget parent,StringConst name)795 Widget XmtCreateChild(Widget parent, StringConst name)
796 #else
797 Widget XmtCreateChild(parent, name)
798 Widget parent;
799 StringConst name;
800 #endif
801 {
802 return _XmtCreateChild(parent, name, NULL, NULL, 0);
803 }
804
805 #if NeedVarargsPrototypes
XmtCreateQueryChild(Widget parent,StringConst name,...)806 Widget XmtCreateQueryChild(Widget parent, StringConst name, ...)
807 #else
808 Widget XmtCreateQueryChild(parent, name, va_alist)
809 Widget parent;
810 StringConst name;
811 va_dcl
812 #endif
813 {
814 va_list var;
815 WidgetName *names;
816 Cardinal num_names;
817 Widget child;
818
819 Va_start(var, name);
820 GetWidgetNames(var, &names, &num_names);
821 va_end(var);
822 child = _XmtCreateChild(parent, name, NULL, names, num_names);
823 XtFree((char *)names);
824 return child;
825 }
826
827 #if NeedFunctionPrototypes
XmtCreateQueryListChild(Widget parent,StringConst name,XmtWidgetList * names,Cardinal num_names)828 Widget XmtCreateQueryListChild(Widget parent, StringConst name,
829 XmtWidgetList * names, Cardinal num_names)
830 #else
831 Widget XmtCreateQueryListChild(parent, name, names, num_names)
832 Widget parent;
833 StringConst name;
834 XmtWidgetList * names;
835 Cardinal num_names;
836 #endif
837 {
838 /*
839 * initialize widgets to NULL
840 */
841 int i;
842 for (i = 0; i < num_names; i++) {
843 *names[i].widgetp = NULL;
844 }
845 return _XmtCreateChild(parent, name, NULL, names, num_names);
846 }
847
848 #if NeedFunctionPrototypes
_XmtBuildDialog(Widget parent,StringConst dialog_name,XtResourceList resources,Cardinal num_resources,WidgetName * names,Cardinal num_names)849 static Widget _XmtBuildDialog(Widget parent, StringConst dialog_name,
850 XtResourceList resources, Cardinal num_resources,
851 WidgetName *names, Cardinal num_names)
852 #else
853 static Widget _XmtBuildDialog(parent, dialog_name, resources, num_resources,
854 names, num_names)
855 Widget parent;
856 StringConst dialog_name;
857 XtResourceList resources;
858 Cardinal num_resources;
859 WidgetName *names;
860 Cardinal num_names;
861 #endif
862 {
863 Widget shell;
864 Arg arg;
865
866 /* create the dialog shell */
867 /* XXX do I need/want allowShellResize? What happens without? */
868 XtSetArg(arg, XmNallowShellResize, True);
869 shell = XmCreateDialogShell(parent, (String)dialog_name, &arg, 1);
870
871 /* associate the resources with the shell */
872 XmtDialogBindResourceList(shell, resources, num_resources);
873
874 /* create the dialog child and its children */
875 _XmtCreateChildren(shell, names, num_names);
876
877 /* return the dialog child, if any, or warn and return NULL */
878 if (((CompositeWidget)shell)->composite.num_children)
879 return ((CompositeWidget)shell)->composite.children[0];
880 else
881 XmtWarningMsg("XmtBuildDialog", "nochild",
882 "No xmtChildren resource for shell widget '%s'",
883 dialog_name);
884 return NULL;
885 }
886
887 #if NeedFunctionPrototypes
XmtBuildDialog(Widget parent,StringConst dialog_name,XtResourceList resources,Cardinal num_resources)888 Widget XmtBuildDialog(Widget parent, StringConst dialog_name,
889 XtResourceList resources, Cardinal num_resources)
890 #else
891 Widget XmtBuildDialog(parent, dialog_name, resources, num_resources)
892 Widget parent;
893 StringConst dialog_name;
894 XtResourceList resources;
895 Cardinal num_resources;
896 #endif
897 {
898 return _XmtBuildDialog(parent, dialog_name,
899 resources, num_resources,
900 NULL, 0);
901 }
902
903
904 #if NeedVarargsPrototypes
XmtBuildQueryDialog(Widget parent,StringConst dialog_name,XtResourceList resources,Cardinal num_resources,...)905 Widget XmtBuildQueryDialog(Widget parent, StringConst dialog_name,
906 XtResourceList resources, Cardinal num_resources,
907 ...)
908 #else
909 Widget XmtBuildQueryDialog(parent, dialog_name,
910 resources, num_resources, va_alist)
911 Widget parent;
912 StringConst dialog_name;
913 XtResourceList resources;
914 Cardinal num_resources;
915 va_dcl
916 #endif
917 {
918 va_list var;
919 WidgetName *names;
920 Cardinal num_names;
921 Widget dialog;
922
923 Va_start(var, num_resources);
924 GetWidgetNames(var, &names, &num_names);
925 va_end(var);
926 dialog = _XmtBuildDialog(parent, dialog_name,
927 resources, num_resources,
928 names, num_names);
929 XtFree((char *)names);
930 return dialog;
931 }
932
933 #if NeedVarargsPrototypes
XmtBuildQueryToplevel(Widget parent,StringConst name,...)934 Widget XmtBuildQueryToplevel(Widget parent, StringConst name, ...)
935 #else
936 Widget XmtBuildQueryToplevel(parent, name, va_alist)
937 Widget parent;
938 StringConst name;
939 va_dcl
940 #endif
941 {
942 va_list var;
943 WidgetName *names;
944 Cardinal num_names;
945 Widget shell;
946
947 shell = XtCreatePopupShell((String)name, topLevelShellWidgetClass,
948 parent, NULL, 0);
949
950 Va_start(var, name);
951 GetWidgetNames(var, &names, &num_names);
952 va_end(var);
953 _XmtCreateChildren(shell, names, num_names);
954 XtFree((char *)names);
955 if (!((CompositeWidget)shell)->composite.num_children)
956 XmtWarningMsg("XmtBuildToplevel", "nochild",
957 "No xmtChildren resource for shell widget '%s'",
958 name);
959 return shell;
960 }
961
962 #if NeedFunctionPrototypes
XmtBuildToplevel(Widget parent,StringConst name)963 Widget XmtBuildToplevel(Widget parent, StringConst name)
964 #else
965 Widget XmtBuildToplevel(parent, name)
966 Widget parent;
967 StringConst name;
968 #endif
969 {
970 return XmtBuildQueryToplevel(parent, name, NULL);
971 }
972
973 #if NeedVarargsPrototypes
XmtBuildQueryApplication(StringConst appname,StringConst appclass,Display * display,ArgList args,Cardinal num_args,...)974 Widget XmtBuildQueryApplication(StringConst appname, StringConst appclass,
975 Display *display,
976 ArgList args, Cardinal num_args, ...)
977 #else
978 Widget XmtBuildQueryApplication(appname, appclass, display, args, num_args,
979 va_alist)
980 StringConst appname, appclass;
981 Display *display;
982 ArgList args;
983 Cardinal num_args;
984 va_dcl
985 #endif
986 {
987 va_list var;
988 WidgetName *names;
989 Cardinal num_names;
990 Widget rootshell;
991
992 rootshell = XtAppCreateShell((String)appname, (String)appclass,
993 applicationShellWidgetClass,
994 display, args, num_args);
995 Va_start(var, num_args);
996 GetWidgetNames(var, &names, &num_names);
997 va_end(var);
998 _XmtCreateChildren(rootshell, names, num_names);
999 XtFree((char *)names);
1000
1001 if (!((CompositeWidget)rootshell)->composite.num_children)
1002 XmtWarningMsg("XmtBuildApplication", "nochild",
1003 "No xmtChildren resource for root shell widget '%s'",
1004 appname);
1005
1006 XmtInitializeApplicationShell(rootshell, args, num_args);
1007 return rootshell;
1008 }
1009
1010 #if NeedFunctionPrototypes
XmtBuildApplication(StringConst appname,StringConst appclass,Display * display,ArgList args,Cardinal num_args)1011 Widget XmtBuildApplication(StringConst appname, StringConst appclass,
1012 Display *display,
1013 ArgList args, Cardinal num_args)
1014 #else
1015 Widget XmtBuildApplication(appname, appclass, display, args, num_args)
1016 StringConst appname, appclass;
1017 Display *display;
1018 ArgList args;
1019 Cardinal num_args;
1020 #endif
1021 {
1022 return XmtBuildQueryApplication(appname, appclass, display,
1023 args, num_args, NULL);
1024 }
1025