Home | History | Annotate | Line # | Download | only in src
      1 /*
      2 
      3 Copyright 1994, 1998  The Open Group
      4 
      5 Permission to use, copy, modify, distribute, and sell this software and its
      6 documentation for any purpose is hereby granted without fee, provided that
      7 the above copyright notice appear in all copies and that both that
      8 copyright notice and this permission notice appear in supporting
      9 documentation.
     10 
     11 The above copyright notice and this permission notice shall be included in
     12 all copies or substantial portions of the Software.
     13 
     14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
     17 OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
     18 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
     19 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     20 
     21 Except as contained in this notice, the name of The Open Group shall not be
     22 used in advertising or otherwise to promote the sale, use or other dealings
     23 in this Software without prior written authorization from The Open Group.
     24 
     25 */
     26 
     27 #ifdef HAVE_CONFIG_H
     28 #include <config.h>
     29 #endif
     30 #include "IntrinsicI.h"
     31 #include "CreateI.h"
     32 
     33 static void
     34 FreeBlockHookList(Widget widget _X_UNUSED,
     35                   XtPointer closure, /* ActionHook* */
     36                   XtPointer call_data _X_UNUSED)
     37 {
     38     BlockHook list = *(BlockHook *) closure;
     39 
     40     while (list != NULL) {
     41         BlockHook next = list->next;
     42 
     43         XtFree((XtPointer) list);
     44         list = next;
     45     }
     46 }
     47 
     48 XtBlockHookId
     49 XtAppAddBlockHook(XtAppContext app, XtBlockHookProc proc, XtPointer closure)
     50 {
     51     BlockHook hook = XtNew(BlockHookRec);
     52 
     53     LOCK_APP(app);
     54     hook->next = app->block_hook_list;
     55     hook->app = app;
     56     hook->proc = proc;
     57     hook->closure = closure;
     58     if (app->block_hook_list == NULL) {
     59         _XtAddCallback(&app->destroy_callbacks,
     60                        FreeBlockHookList, (XtPointer) &app->block_hook_list);
     61     }
     62     app->block_hook_list = hook;
     63     UNLOCK_APP(app);
     64     return (XtBlockHookId) hook;
     65 }
     66 
     67 void
     68 XtRemoveBlockHook(XtBlockHookId id)
     69 {
     70     BlockHook *p, hook = (BlockHook) id;
     71     XtAppContext app = hook->app;
     72 
     73     LOCK_APP(app);
     74     for (p = &app->block_hook_list; p != NULL && *p != hook; p = &(*p)->next);
     75     if (p == NULL) {
     76 #ifdef DEBUG
     77         XtAppWarningMsg(app, "badId", "xtRemoveBlockHook", XtCXtToolkitError,
     78                         "XtRemoveBlockHook called with bad or old hook id",
     79                         NULL, NULL);
     80 #endif   /*DEBUG*/
     81             UNLOCK_APP(app);
     82         return;
     83     }
     84     *p = hook->next;
     85     XtFree((XtPointer) hook);
     86     UNLOCK_APP(app);
     87 }
     88 
     89 static void
     90 DeleteShellFromHookObj(const Widget shell,
     91                        XtPointer closure,
     92                        XtPointer call_data _X_UNUSED)
     93 {
     94     /* app_con is locked when this function is called */
     95     Cardinal ii, jj;
     96     HookObject ho = (HookObject) closure;
     97 
     98     for (ii = 0; ii < ho->hooks.num_shells; ii++)
     99         if (ho->hooks.shells[ii] == shell) {
    100             /* collapse the list */
    101             for (jj = ii; jj < ho->hooks.num_shells; jj++) {
    102                 if ((jj + 1) < ho->hooks.num_shells)
    103                     ho->hooks.shells[jj] = ho->hooks.shells[jj + 1];
    104             }
    105             break;
    106         }
    107     ho->hooks.num_shells--;
    108 }
    109 
    110 #define SHELL_INCR 4
    111 
    112 void
    113 _XtAddShellToHookObj(Widget shell)
    114 {
    115     /* app_con is locked when this function is called */
    116     HookObject ho = (HookObject) XtHooksOfDisplay(XtDisplay(shell));
    117 
    118     if (ho->hooks.num_shells == ho->hooks.max_shells) {
    119         ho->hooks.max_shells += SHELL_INCR;
    120         ho->hooks.shells = XtReallocArray(ho->hooks.shells,
    121                                           (Cardinal) ho->hooks.max_shells,
    122                                           (Cardinal) sizeof(Widget));
    123     }
    124     ho->hooks.shells[ho->hooks.num_shells++] = shell;
    125 
    126     XtAddCallback(shell, XtNdestroyCallback, DeleteShellFromHookObj,
    127                   (XtPointer) ho);
    128 }
    129 
    130 Boolean
    131 _XtIsHookObject(Widget widget)
    132 {
    133     return (widget->core.widget_class == hookObjectClass);
    134 }
    135 
    136 Widget
    137 XtHooksOfDisplay(Display *dpy)
    138 {
    139     Widget retval;
    140     XtPerDisplay pd;
    141 
    142     DPY_TO_APPCON(dpy);
    143 
    144     LOCK_APP(app);
    145     pd = _XtGetPerDisplay(dpy);
    146     if (pd->hook_object == NULL)
    147         pd->hook_object =
    148             _XtCreateHookObj((Screen *) DefaultScreenOfDisplay(dpy));
    149     retval = pd->hook_object;
    150     UNLOCK_APP(app);
    151     return retval;
    152 }
    153