1444c061aSmrg/*
2444c061aSmrg
3444c061aSmrgCopyright 1994, 1998  The Open Group
4444c061aSmrg
5444c061aSmrgPermission to use, copy, modify, distribute, and sell this software and its
6444c061aSmrgdocumentation for any purpose is hereby granted without fee, provided that
7444c061aSmrgthe above copyright notice appear in all copies and that both that
8444c061aSmrgcopyright notice and this permission notice appear in supporting
9444c061aSmrgdocumentation.
10444c061aSmrg
11444c061aSmrgThe above copyright notice and this permission notice shall be included in
12444c061aSmrgall copies or substantial portions of the Software.
13444c061aSmrg
14444c061aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15444c061aSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16444c061aSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
17444c061aSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18444c061aSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19444c061aSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20444c061aSmrg
21444c061aSmrgExcept as contained in this notice, the name of The Open Group shall not be
22444c061aSmrgused in advertising or otherwise to promote the sale, use or other dealings
23444c061aSmrgin this Software without prior written authorization from The Open Group.
24444c061aSmrg
25444c061aSmrg*/
26444c061aSmrg
27444c061aSmrg#ifdef HAVE_CONFIG_H
28444c061aSmrg#include <config.h>
29444c061aSmrg#endif
30444c061aSmrg#include "IntrinsicI.h"
31444c061aSmrg#include "CreateI.h"
32444c061aSmrg
33a3bd7f05Smrgstatic void
34a3bd7f05SmrgFreeBlockHookList(Widget widget _X_UNUSED,
35a3bd7f05Smrg                  XtPointer closure, /* ActionHook* */
36a3bd7f05Smrg                  XtPointer call_data _X_UNUSED)
37444c061aSmrg{
38a3bd7f05Smrg    BlockHook list = *(BlockHook *) closure;
39a3bd7f05Smrg
40444c061aSmrg    while (list != NULL) {
41a3bd7f05Smrg        BlockHook next = list->next;
42a3bd7f05Smrg
43a3bd7f05Smrg        XtFree((XtPointer) list);
44a3bd7f05Smrg        list = next;
45444c061aSmrg    }
46444c061aSmrg}
47444c061aSmrg
48a3bd7f05SmrgXtBlockHookId
49a3bd7f05SmrgXtAppAddBlockHook(XtAppContext app, XtBlockHookProc proc, XtPointer closure)
50444c061aSmrg{
51444c061aSmrg    BlockHook hook = XtNew(BlockHookRec);
52a3bd7f05Smrg
53444c061aSmrg    LOCK_APP(app);
54444c061aSmrg    hook->next = app->block_hook_list;
55444c061aSmrg    hook->app = app;
56444c061aSmrg    hook->proc = proc;
57444c061aSmrg    hook->closure = closure;
58444c061aSmrg    if (app->block_hook_list == NULL) {
59a3bd7f05Smrg        _XtAddCallback(&app->destroy_callbacks,
60a3bd7f05Smrg                       FreeBlockHookList, (XtPointer) &app->block_hook_list);
61444c061aSmrg    }
62444c061aSmrg    app->block_hook_list = hook;
63444c061aSmrg    UNLOCK_APP(app);
64a3bd7f05Smrg    return (XtBlockHookId) hook;
65444c061aSmrg}
66444c061aSmrg
67a3bd7f05Smrgvoid
68a3bd7f05SmrgXtRemoveBlockHook(XtBlockHookId id)
69444c061aSmrg{
70a3bd7f05Smrg    BlockHook *p, hook = (BlockHook) id;
71444c061aSmrg    XtAppContext app = hook->app;
72a3bd7f05Smrg
73444c061aSmrg    LOCK_APP(app);
74444c061aSmrg    for (p = &app->block_hook_list; p != NULL && *p != hook; p = &(*p)->next);
75444c061aSmrg    if (p == NULL) {
76444c061aSmrg#ifdef DEBUG
77a3bd7f05Smrg        XtAppWarningMsg(app, "badId", "xtRemoveBlockHook", XtCXtToolkitError,
78a3bd7f05Smrg                        "XtRemoveBlockHook called with bad or old hook id",
79a3bd7f05Smrg                        NULL, NULL);
80a3bd7f05Smrg#endif   /*DEBUG*/
81a3bd7f05Smrg            UNLOCK_APP(app);
82a3bd7f05Smrg        return;
83444c061aSmrg    }
84444c061aSmrg    *p = hook->next;
85a3bd7f05Smrg    XtFree((XtPointer) hook);
86444c061aSmrg    UNLOCK_APP(app);
87444c061aSmrg}
88444c061aSmrg
89a3bd7f05Smrgstatic void
90fdf6a26fSmrgDeleteShellFromHookObj(const Widget shell,
91a3bd7f05Smrg                       XtPointer closure,
92a3bd7f05Smrg                       XtPointer call_data _X_UNUSED)
93444c061aSmrg{
94444c061aSmrg    /* app_con is locked when this function is called */
95444c061aSmrg    Cardinal ii, jj;
96444c061aSmrg    HookObject ho = (HookObject) closure;
97444c061aSmrg
98444c061aSmrg    for (ii = 0; ii < ho->hooks.num_shells; ii++)
99a3bd7f05Smrg        if (ho->hooks.shells[ii] == shell) {
100a3bd7f05Smrg            /* collapse the list */
101a3bd7f05Smrg            for (jj = ii; jj < ho->hooks.num_shells; jj++) {
102a3bd7f05Smrg                if ((jj + 1) < ho->hooks.num_shells)
103a3bd7f05Smrg                    ho->hooks.shells[jj] = ho->hooks.shells[jj + 1];
104a3bd7f05Smrg            }
105a3bd7f05Smrg            break;
106a3bd7f05Smrg        }
107444c061aSmrg    ho->hooks.num_shells--;
108444c061aSmrg}
109444c061aSmrg
110444c061aSmrg#define SHELL_INCR 4
111444c061aSmrg
112a3bd7f05Smrgvoid
113a3bd7f05Smrg_XtAddShellToHookObj(Widget shell)
114444c061aSmrg{
115444c061aSmrg    /* app_con is locked when this function is called */
116444c061aSmrg    HookObject ho = (HookObject) XtHooksOfDisplay(XtDisplay(shell));
117444c061aSmrg
118444c061aSmrg    if (ho->hooks.num_shells == ho->hooks.max_shells) {
119a3bd7f05Smrg        ho->hooks.max_shells += SHELL_INCR;
120fdf6a26fSmrg        ho->hooks.shells = XtReallocArray(ho->hooks.shells,
121fdf6a26fSmrg                                          (Cardinal) ho->hooks.max_shells,
122fdf6a26fSmrg                                          (Cardinal) sizeof(Widget));
123444c061aSmrg    }
124444c061aSmrg    ho->hooks.shells[ho->hooks.num_shells++] = shell;
125444c061aSmrg
126444c061aSmrg    XtAddCallback(shell, XtNdestroyCallback, DeleteShellFromHookObj,
127a3bd7f05Smrg                  (XtPointer) ho);
128444c061aSmrg}
129444c061aSmrg
130a3bd7f05SmrgBoolean
131a3bd7f05Smrg_XtIsHookObject(Widget widget)
132444c061aSmrg{
133444c061aSmrg    return (widget->core.widget_class == hookObjectClass);
134444c061aSmrg}
135444c061aSmrg
136a3bd7f05SmrgWidget
137a3bd7f05SmrgXtHooksOfDisplay(Display *dpy)
138444c061aSmrg{
139444c061aSmrg    Widget retval;
140444c061aSmrg    XtPerDisplay pd;
141a3bd7f05Smrg
142444c061aSmrg    DPY_TO_APPCON(dpy);
143444c061aSmrg
144444c061aSmrg    LOCK_APP(app);
145444c061aSmrg    pd = _XtGetPerDisplay(dpy);
146444c061aSmrg    if (pd->hook_object == NULL)
147a3bd7f05Smrg        pd->hook_object =
148a3bd7f05Smrg            _XtCreateHookObj((Screen *) DefaultScreenOfDisplay(dpy));
149444c061aSmrg    retval = pd->hook_object;
150444c061aSmrg    UNLOCK_APP(app);
151444c061aSmrg    return retval;
152444c061aSmrg}
153