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