Create.c revision 249c3046
11.5Sperry/***********************************************************
21.2SperryCopyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
31.1Sjtc
41.1SjtcPermission is hereby granted, free of charge, to any person obtaining a
51.1Sjtccopy of this software and associated documentation files (the "Software"),
61.1Sjtcto deal in the Software without restriction, including without limitation
71.1Sjtcthe rights to use, copy, modify, merge, publish, distribute, sublicense,
81.3Sthorpejand/or sell copies of the Software, and to permit persons to whom the
91.4SlukemSoftware is furnished to do so, subject to the following conditions:
101.5Sperry
111.4SlukemThe above copyright notice and this permission notice (including the next
121.3Sthorpejparagraph) shall be included in all copies or substantial portions of the
131.3SthorpejSoftware.
141.3Sthorpej
151.1SjtcTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
161.3SthorpejIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
171.3SthorpejFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
181.3SthorpejTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
191.3SthorpejLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
201.1SjtcFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
211.1SjtcDEALINGS IN THE SOFTWARE.
221.1Sjtc
231.1SjtcCopyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts.
241.1Sjtc
251.1Sjtc                        All Rights Reserved
261.5Sperry
271.1SjtcPermission to use, copy, modify, and distribute this software and its
281.1Sjtcdocumentation for any purpose and without fee is hereby granted,
29provided that the above copyright notice appear in all copies and that
30both that copyright notice and this permission notice appear in
31supporting documentation, and that the name of Digital not be
32used in advertising or publicity pertaining to distribution of the
33software without specific, written prior permission.
34
35DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
36ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
37DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
38ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
39WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
40ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
41SOFTWARE.
42
43******************************************************************/
44
45/*
46
47Copyright 1987, 1988, 1994, 1998  The Open Group
48
49Permission to use, copy, modify, distribute, and sell this software and its
50documentation for any purpose is hereby granted without fee, provided that
51the above copyright notice appear in all copies and that both that
52copyright notice and this permission notice appear in supporting
53documentation.
54
55The above copyright notice and this permission notice shall be included in
56all copies or substantial portions of the Software.
57
58THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
59IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
60FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
61OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
62AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
63CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
64
65Except as contained in this notice, the name of The Open Group shall not be
66used in advertising or otherwise to promote the sale, use or other dealings
67in this Software without prior written authorization from The Open Group.
68
69*/
70
71#ifdef HAVE_CONFIG_H
72#include <config.h>
73#endif
74#include "IntrinsicI.h"
75#include "VarargsI.h"
76#include "ShellP.h"
77#include "CreateI.h"
78#ifndef X_NO_RESOURCE_CONFIGURATION_MANAGEMENT
79#include "ResConfigP.h"
80#endif
81#include <stdio.h>
82
83static String XtNxtCreateWidget = "xtCreateWidget";
84static String XtNxtCreatePopupShell = "xtCreatePopupShell";
85
86static void
87CallClassPartInit(WidgetClass ancestor, WidgetClass wc)
88{
89    if (ancestor->core_class.superclass != NULL) {
90	CallClassPartInit(ancestor->core_class.superclass, wc);
91    }
92    if (ancestor->core_class.class_part_initialize != NULL) {
93	(*(ancestor->core_class.class_part_initialize)) (wc);
94    }
95}
96
97void
98XtInitializeWidgetClass(WidgetClass wc)
99{
100    XtEnum inited;
101    LOCK_PROCESS;
102    if (wc->core_class.class_inited) {
103	UNLOCK_PROCESS;
104	return;
105    }
106    inited = 0x01;
107    {
108	WidgetClass pc;
109#define LeaveIfClass(c, d) if (pc == c) { inited = d; break; }
110	for (pc = wc; pc; pc = pc->core_class.superclass) {
111	    LeaveIfClass(rectObjClass, 0x01 |
112			 RectObjClassFlag);
113	    LeaveIfClass(coreWidgetClass, 0x01 |
114			 RectObjClassFlag |
115			 WidgetClassFlag);
116	    LeaveIfClass(compositeWidgetClass, 0x01 |
117			 RectObjClassFlag |
118			 WidgetClassFlag |
119			 CompositeClassFlag);
120	    LeaveIfClass(constraintWidgetClass, 0x01 |
121			 RectObjClassFlag |
122			 WidgetClassFlag |
123			 CompositeClassFlag |
124			 ConstraintClassFlag);
125	    LeaveIfClass(shellWidgetClass, 0x01 |
126			 RectObjClassFlag |
127			 WidgetClassFlag |
128			 CompositeClassFlag |
129			 ShellClassFlag);
130	    LeaveIfClass(wmShellWidgetClass, 0x01 |
131			 RectObjClassFlag |
132			 WidgetClassFlag |
133			 CompositeClassFlag |
134			 ShellClassFlag |
135			 WMShellClassFlag);
136	    LeaveIfClass(topLevelShellWidgetClass, 0x01 |
137			 RectObjClassFlag |
138			 WidgetClassFlag |
139			 CompositeClassFlag |
140			 ShellClassFlag |
141			 WMShellClassFlag |
142			 TopLevelClassFlag);
143	}
144#undef LeaveIfClass
145    }
146    if (wc->core_class.version != XtVersion &&
147	wc->core_class.version != XtVersionDontCheck) {
148	String param[3];
149	String mismatch = "Widget class %s version mismatch (recompilation needed):\n  widget %d vs. intrinsics %d.";
150	String recompile = "Widget class %s must be re-compiled.";
151	Cardinal num_params;
152
153	param[0] = wc->core_class.class_name;
154	param[1] = (String) wc->core_class.version;
155	param[2] = (String) XtVersion;
156
157	if (wc->core_class.version == (11 * 1000 + 5) || /* MIT X11R5 */
158	    wc->core_class.version == (11 * 1000 + 4)) { /* MIT X11R4 */
159	    if ((inited & WMShellClassFlag) &&
160		(sizeof(Boolean) != sizeof(char) ||
161		 sizeof(Atom) != sizeof(Widget) ||
162		 sizeof(Atom) != sizeof(String))) {
163		num_params=3;
164		XtWarningMsg("versionMismatch","widget",XtCXtToolkitError,
165			     mismatch, param, &num_params);
166		num_params=1;
167		XtErrorMsg("R4orR5versionMismatch","widget",XtCXtToolkitError,
168			   recompile, param, &num_params);
169
170	    }
171	}
172	else if (wc->core_class.version == (11 * 1000 + 3)) { /* MIT X11R3 */
173	    if (inited & ShellClassFlag) {
174		num_params=1;
175		XtWarningMsg("r3versionMismatch","widget",XtCXtToolkitError,
176			     "Shell Widget class %s binary compiled for R3",
177			     param,&num_params);
178		XtErrorMsg("R3versionMismatch","widget",XtCXtToolkitError,
179			   recompile, param, &num_params);
180	    }
181	}
182	else {
183	    num_params=3;
184	    XtWarningMsg("versionMismatch","widget",XtCXtToolkitError,
185			 mismatch, param, &num_params);
186	    if (wc->core_class.version == (2 * 1000 + 2)) /* MIT X11R2 */ {
187		num_params=1;
188		XtErrorMsg("r2versionMismatch","widget",XtCXtToolkitError,
189			   recompile, param, &num_params);
190	    }
191	}
192    }
193
194    if ((wc->core_class.superclass != NULL)
195	    && (!(wc->core_class.superclass->core_class.class_inited)))
196 	XtInitializeWidgetClass(wc->core_class.superclass);
197
198    if (wc->core_class.class_initialize != NULL)
199	(*(wc->core_class.class_initialize))();
200    CallClassPartInit(wc, wc);
201    wc->core_class.class_inited = inited;
202    UNLOCK_PROCESS;
203}
204
205static void
206CallInitialize (
207    WidgetClass class,
208    Widget      req_widget,
209    Widget      new_widget,
210    ArgList     args,
211    Cardinal    num_args)
212{
213    WidgetClass superclass;
214    XtInitProc initialize;
215    XtArgsProc initialize_hook;
216
217    LOCK_PROCESS;
218    superclass = class->core_class.superclass;
219    UNLOCK_PROCESS;
220    if (superclass)
221        CallInitialize (superclass, req_widget, new_widget, args, num_args);
222    LOCK_PROCESS;
223    initialize = class->core_class.initialize;
224    UNLOCK_PROCESS;
225    if (initialize)
226	(*initialize) (req_widget, new_widget, args, &num_args);
227    LOCK_PROCESS;
228    initialize_hook = class->core_class.initialize_hook;
229    UNLOCK_PROCESS;
230    if (initialize_hook)
231	(*initialize_hook) (new_widget, args, &num_args);
232}
233
234static void
235CallConstraintInitialize (
236    ConstraintWidgetClass class,
237    Widget	req_widget,
238    Widget	new_widget,
239    ArgList	args,
240    Cardinal	num_args)
241{
242    WidgetClass superclass;
243    XtInitProc initialize;
244
245    LOCK_PROCESS;
246    superclass = class->core_class.superclass;
247    UNLOCK_PROCESS;
248    if (superclass != constraintWidgetClass)
249	CallConstraintInitialize((ConstraintWidgetClass) superclass,
250		req_widget, new_widget, args, num_args);
251    LOCK_PROCESS;
252    initialize = class->constraint_class.initialize;
253    UNLOCK_PROCESS;
254    if (initialize)
255        (*initialize) (req_widget, new_widget, args, &num_args);
256}
257
258static Widget
259xtWidgetAlloc(
260    WidgetClass widget_class,
261    ConstraintWidgetClass parent_constraint_class,
262    Widget parent,
263    String name,
264    ArgList     args,		/* must be NULL if typed_args is non-NULL */
265    Cardinal    num_args,
266    XtTypedArgList typed_args,	/* must be NULL if args is non-NULL */
267    Cardinal	num_typed_args)
268{
269    Widget widget;
270    Cardinal                wsize, csize = 0;
271    ObjectClassExtension    ext;
272
273    LOCK_PROCESS;
274    if (! (widget_class->core_class.class_inited))
275	XtInitializeWidgetClass(widget_class);
276    ext = (ObjectClassExtension)
277	XtGetClassExtension(widget_class,
278			    XtOffsetOf(ObjectClassRec, object_class.extension),
279			    NULLQUARK, XtObjectExtensionVersion,
280			    sizeof(ObjectClassExtensionRec));
281    if (parent_constraint_class)
282	csize = parent_constraint_class->constraint_class.constraint_size;
283    if (ext && ext->allocate) {
284	XtAllocateProc allocate;
285	Cardinal extra = 0;
286	Cardinal nargs = num_args;
287	Cardinal ntyped = num_typed_args;
288	allocate = ext->allocate;
289	UNLOCK_PROCESS;
290	(*allocate)(widget_class, &csize, &extra, args, &nargs,
291		    typed_args, &ntyped, &widget, NULL);
292    } else {
293	wsize = widget_class->core_class.widget_size;
294	UNLOCK_PROCESS;
295	if (csize) {
296	    if (sizeof(struct {char a; double b;}) !=
297		(sizeof(struct {char a; unsigned long b;}) -
298		 sizeof(unsigned long) + sizeof(double))) {
299		if (csize && !(csize & (sizeof(double) - 1)))
300		    wsize = (wsize + sizeof(double) - 1) & ~(sizeof(double)-1);
301	    }
302	}
303	widget = (Widget) __XtMalloc((unsigned)(wsize + csize));
304	bzero(widget, wsize + csize);
305	widget->core.constraints =
306	    (csize ? (XtPointer)((char *)widget + wsize) : NULL);
307    }
308    widget->core.self = widget;
309    widget->core.parent = parent;
310    widget->core.widget_class = widget_class;
311    widget->core.xrm_name = StringToName((name != NULL) ? name : "");
312    widget->core.being_destroyed =
313	(parent != NULL ? parent->core.being_destroyed : FALSE);
314    return widget;
315}
316
317static void
318CompileCallbacks(
319    Widget widget)
320{
321    CallbackTable offsets;
322    InternalCallbackList* cl;
323    int i;
324
325    LOCK_PROCESS;
326    offsets = (CallbackTable)
327	widget->core.widget_class->core_class.callback_private;
328
329    for (i = (int)(long) *(offsets++); --i >= 0; offsets++) {
330	cl = (InternalCallbackList *)
331	    ((char *) widget - (*offsets)->xrm_offset - 1);
332	if (*cl)
333	    *cl = _XtCompileCallbackList((XtCallbackList) *cl);
334    }
335    UNLOCK_PROCESS;
336}
337
338static Widget
339xtCreate(
340    char        *name,
341    char        *class,
342    WidgetClass widget_class,
343    Widget      parent,
344    Screen*     default_screen, /* undefined when creating a nonwidget */
345    ArgList     args,		/* must be NULL if typed_args is non-NULL */
346    Cardinal    num_args,
347    XtTypedArgList typed_args,	/* must be NULL if args is non-NULL */
348    Cardinal	num_typed_args,
349    ConstraintWidgetClass parent_constraint_class,
350        /* NULL if not a subclass of Constraint or if child is popup shell */
351    XtWidgetProc post_proc)
352{
353    /* need to use strictest alignment rules possible in next two decls. */
354    double                  widget_cache[100];
355    double                  constraint_cache[20];
356    Widget                  req_widget;
357    XtPointer               req_constraints = NULL;
358    Cardinal                wsize, csize;
359    Widget	    	    widget;
360    XtCacheRef		    *cache_refs;
361    Cardinal		    i;
362    XtCreateHookDataRec     call_data;
363
364    widget = xtWidgetAlloc(widget_class, parent_constraint_class, parent,
365		name, args, num_args, typed_args, num_typed_args);
366
367    if (XtIsRectObj(widget)) {
368	widget->core.managed = FALSE;
369    }
370    if (XtIsWidget(widget)) {
371	widget->core.name = XrmNameToString(widget->core.xrm_name);
372        widget->core.screen = default_screen;
373        widget->core.tm.translations = NULL;
374	widget->core.window = (Window) 0;
375	widget->core.visible = TRUE;
376	widget->core.popup_list = NULL;
377	widget->core.num_popups = 0;
378    };
379    LOCK_PROCESS;
380    if (XtIsApplicationShell(widget)) {
381	ApplicationShellWidget a = (ApplicationShellWidget) widget;
382	if (class != NULL)
383	    a->application.xrm_class = StringToClass(class);
384	else
385	    a->application.xrm_class = widget_class->core_class.xrm_class;
386	a->application.class = XrmQuarkToString(a->application.xrm_class);
387    }
388    UNLOCK_PROCESS;
389
390    /* fetch resources */
391    cache_refs = _XtGetResources(widget, args, num_args,
392		typed_args, &num_typed_args);
393
394    /* Convert typed arg list to arg list */
395    if (typed_args != NULL && num_typed_args > 0) {
396	args = (ArgList)ALLOCATE_LOCAL(sizeof(Arg) * num_typed_args);
397	if (args == NULL) _XtAllocError(NULL);
398	for (i = 0; i < num_typed_args; i++) {
399	    args[i].name = typed_args[i].name;
400	    args[i].value = typed_args[i].value;
401	}
402	num_args = num_typed_args;
403    }
404
405    CompileCallbacks(widget);
406
407    if (cache_refs != NULL) {
408	XtAddCallback(widget, XtNdestroyCallback,
409		XtCallbackReleaseCacheRefList, (XtPointer)cache_refs );
410    }
411
412    wsize = widget_class->core_class.widget_size;
413    csize = 0;
414    req_widget = (Widget) XtStackAlloc(wsize, widget_cache);
415    (void) memmove ((char *) req_widget, (char *) widget, (int) wsize);
416    CallInitialize (XtClass(widget), req_widget, widget, args, num_args);
417    if (parent_constraint_class != NULL) {
418        csize = parent_constraint_class->constraint_class.constraint_size;
419	if (csize) {
420	    req_constraints = XtStackAlloc(csize, constraint_cache);
421	    (void) memmove((char*)req_constraints, widget->core.constraints,
422			(int)csize);
423	    req_widget->core.constraints = req_constraints;
424	} else req_widget->core.constraints = NULL;
425	CallConstraintInitialize(parent_constraint_class, req_widget, widget,
426		args, num_args);
427	if (csize) {
428	    XtStackFree(req_constraints, constraint_cache);
429	}
430    }
431    XtStackFree((XtPointer)req_widget, widget_cache);
432    if (post_proc != (XtWidgetProc) NULL) {
433	Widget hookobj;
434	(*post_proc)(widget);
435	hookobj = XtHooksOfDisplay((default_screen != (Screen*) NULL) ?
436		default_screen->display :
437		XtDisplayOfObject(parent));
438	if (XtHasCallbacks(hookobj, XtNcreateHook) == XtCallbackHasSome) {
439
440	    call_data.type = XtHcreate;
441	    call_data.widget = widget;
442	    call_data.args = args;
443	    call_data.num_args = num_args;
444	    XtCallCallbackList(hookobj,
445		((HookObject)hookobj)->hooks.createhook_callbacks,
446		(XtPointer)&call_data);
447	}
448    }
449    if (typed_args != NULL) {
450	while (num_typed_args-- > 0) {
451
452	    /* In GetResources we may have dynamically alloc'd store to hold */
453	    /* a copy of a resource which was larger then sizeof(XtArgVal). */
454	    /* We must free this store now in order to prevent a memory leak */
455	    /* A typed arg that has a converted value in dynamic store has a */
456	    /* negated size field. */
457
458	    if (typed_args->type != NULL && typed_args->size < 0) {
459		XtFree((char*)typed_args->value);
460		typed_args->size = -(typed_args->size);
461	    }
462	    typed_args++;
463	}
464	DEALLOCATE_LOCAL((char*)args);
465    }
466    return (widget);
467}
468
469static void
470widgetPostProc(Widget w)
471{
472    XtWidgetProc insert_child;
473    Widget parent = XtParent(w);
474    String param = XtName(w);
475    Cardinal num_params = 1;
476
477    if (XtIsComposite(parent)) {
478	LOCK_PROCESS;
479	insert_child = ((CompositeWidgetClass) parent->core.widget_class)->
480	    composite_class.insert_child;
481	UNLOCK_PROCESS;
482    } else {
483	return;
484    }
485    if (insert_child == NULL) {
486	XtAppErrorMsg(XtWidgetToApplicationContext(parent),
487		"nullProc","insertChild",XtCXtToolkitError,
488		"\"%s\" parent has NULL insert_child method",
489		&param, &num_params);
490    } else {
491	(*insert_child) (w);
492    }
493}
494
495Widget
496_XtCreateWidget(
497    String      name,
498    WidgetClass widget_class,
499    Widget      parent,
500    ArgList     args,
501    Cardinal    num_args,
502    XtTypedArgList typed_args,
503    Cardinal	num_typed_args)
504{
505    register Widget	    widget;
506    ConstraintWidgetClass   cwc;
507    Screen*                 default_screen;
508    XtEnum		    class_inited;
509    String		    params[3];
510    Cardinal		    num_params;
511
512    params[0] = name;
513    num_params = 1;
514
515    if (parent == NULL) {
516	XtErrorMsg("invalidParent", XtNxtCreateWidget, XtCXtToolkitError,
517		   "XtCreateWidget \"%s\" requires non-NULL parent",
518		   params, &num_params);
519    } else if (widget_class == NULL) {
520	XtAppErrorMsg(XtWidgetToApplicationContext(parent),
521		      "invalidClass", XtNxtCreateWidget, XtCXtToolkitError,
522		      "XtCreateWidget \"%s\" requires non-NULL widget class",
523		      params, &num_params);
524    }
525    LOCK_PROCESS;
526    if (!widget_class->core_class.class_inited)
527	XtInitializeWidgetClass(widget_class);
528    class_inited = widget_class->core_class.class_inited;
529    UNLOCK_PROCESS;
530    if ((class_inited & WidgetClassFlag) == 0) {
531	/* not a widget */
532	default_screen = NULL;
533	if (XtIsComposite(parent)) {
534	    CompositeClassExtension ext;
535	    ext = (CompositeClassExtension)
536		XtGetClassExtension(XtClass(parent),
537		      XtOffsetOf(CompositeClassRec, composite_class.extension),
538		      NULLQUARK, 1L, (Cardinal) 0);
539	    LOCK_PROCESS;
540	    if (ext &&
541		(ext->version > XtCompositeExtensionVersion ||
542		 ext->record_size > sizeof(CompositeClassExtensionRec))) {
543		params[1] = XtClass(parent)->core_class.class_name;
544		num_params = 2;
545		XtAppWarningMsg(XtWidgetToApplicationContext(parent),
546				"invalidExtension", XtNxtCreateWidget,
547				XtCXtToolkitError,
548	   "widget \"%s\" class %s has invalid CompositeClassExtension record",
549				params, &num_params);
550	    }
551	    if (!ext || !ext->accepts_objects) {
552		params[1] = XtName(parent);
553		num_params = 2;
554		XtAppErrorMsg(XtWidgetToApplicationContext(parent),
555			      "nonWidget", XtNxtCreateWidget,XtCXtToolkitError,
556"attempt to add non-widget child \"%s\" to parent \"%s\" which supports only widgets",
557			      params, &num_params);
558	    }
559	    UNLOCK_PROCESS;
560	}
561    } else {
562	default_screen = parent->core.screen;
563    }
564
565    if (XtIsConstraint(parent)) {
566	cwc = (ConstraintWidgetClass) parent->core.widget_class;
567    } else {
568	cwc = NULL;
569    }
570    widget = xtCreate(name, (char *)NULL, widget_class, parent,
571		default_screen, args, num_args,
572		typed_args, num_typed_args, cwc, widgetPostProc);
573    return (widget);
574}
575
576Widget
577XtCreateWidget(
578    _Xconst char* name,
579    WidgetClass widget_class,
580    Widget   	parent,
581    ArgList 	args,
582    Cardinal    num_args
583    )
584{
585    Widget retval;
586    WIDGET_TO_APPCON(parent);
587
588    LOCK_APP(app);
589    retval = _XtCreateWidget((String)name, widget_class, parent, args, num_args,
590		(XtTypedArgList)NULL, (Cardinal)0);
591    UNLOCK_APP(app);
592    return retval;
593}
594
595
596Widget
597XtCreateManagedWidget(
598    _Xconst char* name,
599    WidgetClass widget_class,
600    Widget      parent,
601    ArgList     args,
602    Cardinal    num_args
603    )
604{
605    register Widget	    widget;
606    WIDGET_TO_APPCON(parent);
607
608    LOCK_APP(app);
609    XtCheckSubclass(parent, compositeWidgetClass, "in XtCreateManagedWidget");
610    widget = _XtCreateWidget((String)name, widget_class, parent, args,
611		num_args, (XtTypedArgList)NULL, (Cardinal) 0);
612    XtManageChild(widget);
613    UNLOCK_APP(app);
614    return widget;
615}
616
617static void
618popupPostProc(Widget w)
619{
620    Widget parent = XtParent(w);
621
622    parent->core.popup_list =
623	(WidgetList) XtRealloc((char*) parent->core.popup_list,
624		(unsigned) (parent->core.num_popups+1) * sizeof(Widget));
625    parent->core.popup_list[parent->core.num_popups++] = w;
626}
627
628Widget
629_XtCreatePopupShell(
630    String      name,
631    WidgetClass widget_class,
632    Widget      parent,
633    ArgList     args,
634    Cardinal    num_args,
635    XtTypedArgList      typed_args,
636    Cardinal            num_typed_args)
637{
638    register Widget widget;
639    Screen* default_screen;
640
641    if (parent == NULL) {
642	XtErrorMsg("invalidParent",XtNxtCreatePopupShell,XtCXtToolkitError,
643		"XtCreatePopupShell requires non-NULL parent",
644		(String *)NULL, (Cardinal *)NULL);
645    } else if (widget_class == NULL) {
646	XtAppErrorMsg(XtWidgetToApplicationContext(parent),
647		"invalidClass",XtNxtCreatePopupShell,XtCXtToolkitError,
648		"XtCreatePopupShell requires non-NULL widget class",
649		(String *)NULL, (Cardinal *)NULL);
650    }
651    XtCheckSubclass(parent, coreWidgetClass, "in XtCreatePopupShell");
652    default_screen = parent->core.screen;
653    widget = xtCreate(name, (char *)NULL, widget_class, parent,
654		default_screen, args, num_args, typed_args,
655		num_typed_args, (ConstraintWidgetClass)NULL,
656		popupPostProc);
657
658#ifndef X_NO_RESOURCE_CONFIGURATION_MANAGEMENT
659    XtAddEventHandler (widget, (EventMask) PropertyChangeMask, FALSE,
660		(XtEventHandler) _XtResourceConfigurationEH, NULL);
661#endif
662    return(widget);
663}
664
665Widget
666XtCreatePopupShell(
667    _Xconst char* name,
668    WidgetClass widget_class,
669    Widget      parent,
670    ArgList     args,
671    Cardinal    num_args
672    )
673{
674    Widget retval;
675    WIDGET_TO_APPCON(parent);
676
677    LOCK_APP(app);
678    retval = _XtCreatePopupShell((String)name, widget_class, parent, args,
679		num_args, (XtTypedArgList)NULL, (Cardinal)0);
680    UNLOCK_APP(app);
681    return retval;
682}
683
684Widget
685_XtAppCreateShell(
686    String      name,
687    String      class,
688    WidgetClass widget_class,
689    Display*    display,
690    ArgList     args,
691    Cardinal    num_args,
692    XtTypedArgList typed_args,
693    Cardinal	num_typed_args)
694{
695    Widget shell;
696
697    if (widget_class == NULL) {
698	XtAppErrorMsg(XtDisplayToApplicationContext(display),
699		"invalidClass","xtAppCreateShell",XtCXtToolkitError,
700		"XtAppCreateShell requires non-NULL widget class",
701		(String *)NULL, (Cardinal *)NULL);
702    }
703    if (name == NULL)
704	name = XrmNameToString(_XtGetPerDisplay(display)->name);
705    shell = xtCreate(name, class, widget_class, (Widget)NULL,
706		(Screen*)DefaultScreenOfDisplay(display),
707		args, num_args, typed_args, num_typed_args,
708		(ConstraintWidgetClass) NULL, _XtAddShellToHookObj);
709
710#ifndef X_NO_RESOURCE_CONFIGURATION_MANAGEMENT
711    XtAddEventHandler (shell, (EventMask) PropertyChangeMask, FALSE,
712		(XtEventHandler) _XtResourceConfigurationEH, NULL);
713#endif
714
715    return shell;
716}
717
718Widget
719XtAppCreateShell(
720    _Xconst char*       name,
721    _Xconst char*       class,
722    WidgetClass         widget_class,
723    Display             *display,
724    ArgList             args,
725    Cardinal            num_args
726    )
727{
728    Widget retval;
729    DPY_TO_APPCON(display);
730
731    LOCK_APP(app);
732    retval = _XtAppCreateShell((String)name, (String)class, widget_class,
733		display, args, num_args, (XtTypedArgList)NULL, (Cardinal)0);
734    UNLOCK_APP(app);
735    return retval;
736}
737
738/* ARGSUSED */
739Widget
740XtCreateApplicationShell(
741    _Xconst char* name,		/* unused in R3 and later */
742    WidgetClass widget_class,
743    ArgList     args,
744    Cardinal    num_args
745    )
746{
747    Widget retval;
748    Display* dpy;
749    XrmClass class;
750    XtAppContext app = _XtDefaultAppContext();
751
752    LOCK_APP(app);
753    dpy = app->list[0];
754    class = _XtGetPerDisplay(dpy)->class;
755
756    retval = _XtAppCreateShell((String)NULL, XrmQuarkToString((XrmQuark)class),
757		widget_class, dpy, args, num_args,
758		(XtTypedArgList)NULL, (Cardinal)0);
759    UNLOCK_APP(app);
760    return retval;
761}
762
763Widget
764_XtCreateHookObj(Screen* screen)
765{
766    Widget req_widget;
767    double widget_cache[100];
768    Cardinal wsize = 0;
769    Widget hookobj = xtWidgetAlloc(hookObjectClass,
770		(ConstraintWidgetClass)NULL,
771		(Widget)NULL, "hooks",
772		(ArgList)NULL, (Cardinal)0,
773		(XtTypedArgList)NULL, (Cardinal)0);
774
775    ((HookObject)hookobj)->hooks.screen = screen;
776    (void) _XtGetResources(hookobj, (ArgList)NULL, 0,
777		(XtTypedArgList)NULL, &wsize);
778    CompileCallbacks(hookobj);
779    wsize = hookObjectClass->core_class.widget_size;
780    req_widget = (Widget) XtStackAlloc(wsize, widget_cache);
781    (void) memmove ((char *) req_widget, (char *) hookobj, (int) wsize);
782    CallInitialize (hookObjectClass, req_widget, hookobj,
783		(ArgList)NULL, (Cardinal) 0);
784    XtStackFree((XtPointer)req_widget, widget_cache);
785    return hookobj;
786}
787