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