11477040fSmrg/*
21477040fSmrg
3fdf6a26fSmrgCopyright (c) 1993, Oracle and/or its affiliates.
41477040fSmrg
51477040fSmrgPermission is hereby granted, free of charge, to any person obtaining a
61477040fSmrgcopy of this software and associated documentation files (the "Software"),
71477040fSmrgto deal in the Software without restriction, including without limitation
81477040fSmrgthe rights to use, copy, modify, merge, publish, distribute, sublicense,
91477040fSmrgand/or sell copies of the Software, and to permit persons to whom the
101477040fSmrgSoftware is furnished to do so, subject to the following conditions:
111477040fSmrg
121477040fSmrgThe above copyright notice and this permission notice (including the next
131477040fSmrgparagraph) shall be included in all copies or substantial portions of the
141477040fSmrgSoftware.
15444c061aSmrg
161477040fSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
171477040fSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
181477040fSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
191477040fSmrgTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
201477040fSmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
211477040fSmrgFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
221477040fSmrgDEALINGS IN THE SOFTWARE.
231477040fSmrg
241477040fSmrg*/
25444c061aSmrg/********************************************************
26444c061aSmrg
27444c061aSmrgCopyright 1988 by Hewlett-Packard Company
28444c061aSmrgCopyright 1987, 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts
29444c061aSmrg
30444c061aSmrgPermission to use, copy, modify, and distribute this software
31444c061aSmrgand its documentation for any purpose and without fee is hereby
32444c061aSmrggranted, provided that the above copyright notice appear in all
33444c061aSmrgcopies and that both that copyright notice and this permission
34444c061aSmrgnotice appear in supporting documentation, and that the names of
351477040fSmrgHewlett-Packard or Digital not be used in advertising or
36444c061aSmrgpublicity pertaining to distribution of the software without specific,
37444c061aSmrgwritten prior permission.
38444c061aSmrg
39444c061aSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
40444c061aSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
41444c061aSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
42444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
43444c061aSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
44444c061aSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
45444c061aSmrgSOFTWARE.
46444c061aSmrg
47444c061aSmrg********************************************************/
48444c061aSmrg
49444c061aSmrg/*
50444c061aSmrg
51444c061aSmrgCopyright 1987, 1988, 1989, 1998  The Open Group
52444c061aSmrg
53444c061aSmrgPermission to use, copy, modify, distribute, and sell this software and its
54444c061aSmrgdocumentation for any purpose is hereby granted without fee, provided that
55444c061aSmrgthe above copyright notice appear in all copies and that both that
56444c061aSmrgcopyright notice and this permission notice appear in supporting
57444c061aSmrgdocumentation.
58444c061aSmrg
59444c061aSmrgThe above copyright notice and this permission notice shall be included in
60444c061aSmrgall copies or substantial portions of the Software.
61444c061aSmrg
62444c061aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
63444c061aSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
64444c061aSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
65444c061aSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
66444c061aSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
67444c061aSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
68444c061aSmrg
69444c061aSmrgExcept as contained in this notice, the name of The Open Group shall not be
70444c061aSmrgused in advertising or otherwise to promote the sale, use or other dealings
71444c061aSmrgin this Software without prior written authorization from The Open Group.
72444c061aSmrg
73444c061aSmrg*/
74444c061aSmrg
75444c061aSmrg#ifdef HAVE_CONFIG_H
76444c061aSmrg#include <config.h>
77444c061aSmrg#endif
78444c061aSmrg#include "IntrinsicI.h"
79444c061aSmrg#include "PassivGraI.h"
80444c061aSmrg#include "StringDefs.h"
81444c061aSmrg#include "EventI.h"
82444c061aSmrg
83a3bd7f05Smrgstatic XContext perWidgetInputContext = 0;
84444c061aSmrg
85a3bd7f05Smrgvoid
86a3bd7f05Smrg_XtFreePerWidgetInput(Widget w, XtPerWidgetInput pwi)
87444c061aSmrg{
88444c061aSmrg    LOCK_PROCESS;
89a3bd7f05Smrg    XDeleteContext(XtDisplay(w), (Window) w, perWidgetInputContext);
90444c061aSmrg
91a3bd7f05Smrg    XtFree((char *) pwi);
92444c061aSmrg    UNLOCK_PROCESS;
93444c061aSmrg}
94444c061aSmrg
95444c061aSmrg/*
96444c061aSmrg * This routine gets the passive list associated with the widget
97444c061aSmrg * from the context manager.
98444c061aSmrg */
99a3bd7f05SmrgXtPerWidgetInput
100a3bd7f05Smrg_XtGetPerWidgetInput(Widget widget, _XtBoolean create)
101444c061aSmrg{
102a3bd7f05Smrg    XtPerWidgetInput pwi = NULL;
103a3bd7f05Smrg    Display *dpy = widget->core.screen->display;
104444c061aSmrg
105444c061aSmrg    LOCK_PROCESS;
106a3bd7f05Smrg    if (!perWidgetInputContext)
107a3bd7f05Smrg        perWidgetInputContext = XUniqueContext();
108444c061aSmrg
109444c061aSmrg    if (XFindContext(dpy,
110a3bd7f05Smrg                     (Window) widget,
111a3bd7f05Smrg                     perWidgetInputContext, (XPointer *) &pwi) && create) {
112a3bd7f05Smrg        pwi = (XtPerWidgetInput)
113a3bd7f05Smrg            __XtMalloc((unsigned) sizeof(XtPerWidgetInputRec));
114a3bd7f05Smrg
115a3bd7f05Smrg        pwi->focusKid = NULL;
116a3bd7f05Smrg        pwi->queryEventDescendant = NULL;
117a3bd7f05Smrg        pwi->focalPoint = XtUnrelated;
118a3bd7f05Smrg        pwi->keyList = pwi->ptrList = NULL;
119a3bd7f05Smrg
120a3bd7f05Smrg        pwi->haveFocus =
121a3bd7f05Smrg            pwi->map_handler_added =
122a3bd7f05Smrg            pwi->realize_handler_added = pwi->active_handler_added = FALSE;
123a3bd7f05Smrg
124a3bd7f05Smrg        XtAddCallback(widget, XtNdestroyCallback,
125a3bd7f05Smrg                      _XtDestroyServerGrabs, (XtPointer) pwi);
126a3bd7f05Smrg
127a3bd7f05Smrg        (void) XSaveContext(dpy,
128a3bd7f05Smrg                            (Window) widget,
129a3bd7f05Smrg                            perWidgetInputContext, (char *) pwi);
130a3bd7f05Smrg    }
131444c061aSmrg    UNLOCK_PROCESS;
132444c061aSmrg    return pwi;
133444c061aSmrg}
134444c061aSmrg
135a3bd7f05Smrgvoid
136a3bd7f05Smrg_XtFillAncestorList(Widget **listPtr,
137a3bd7f05Smrg                    int *maxElemsPtr,
138a3bd7f05Smrg                    int *numElemsPtr,
139a3bd7f05Smrg                    Widget start,
140a3bd7f05Smrg                    Widget breakWidget)
141444c061aSmrg{
142444c061aSmrg#define CACHESIZE 16
143a3bd7f05Smrg    Cardinal i;
144a3bd7f05Smrg    Widget w;
145a3bd7f05Smrg    Widget *trace = *listPtr;
146444c061aSmrg
147444c061aSmrg    /* First time in, allocate the ancestor list */
148a3bd7f05Smrg    if (trace == NULL) {
149fdf6a26fSmrg        trace = XtMallocArray(CACHESIZE, (Cardinal) sizeof(Widget));
150a3bd7f05Smrg        *maxElemsPtr = CACHESIZE;
151a3bd7f05Smrg    }
152444c061aSmrg    /* First fill in the ancestor list */
153444c061aSmrg
154444c061aSmrg    trace[0] = start;
155444c061aSmrg
156444c061aSmrg    for (i = 1, w = XtParent(start);
157a3bd7f05Smrg         w != NULL && !XtIsShell(trace[i - 1]) && trace[i - 1] != breakWidget;
158a3bd7f05Smrg         w = XtParent(w), i++) {
159a3bd7f05Smrg        if (i == (Cardinal) *maxElemsPtr) {
160a3bd7f05Smrg            /* This should rarely happen, but if it does it'll probably
161a3bd7f05Smrg               happen again, so grow the ancestor list */
162a3bd7f05Smrg            *maxElemsPtr += CACHESIZE;
163fdf6a26fSmrg            trace = XtReallocArray(trace, (Cardinal) *maxElemsPtr,
164fdf6a26fSmrg                                   (Cardinal) sizeof(Widget));
165a3bd7f05Smrg        }
166a3bd7f05Smrg        trace[i] = w;
167444c061aSmrg    }
168444c061aSmrg    *listPtr = trace;
1690568f49bSmrg    *numElemsPtr = (int) i;
170444c061aSmrg#undef CACHESIZE
171444c061aSmrg}
172444c061aSmrg
173a3bd7f05SmrgWidget
174a3bd7f05Smrg_XtFindRemapWidget(XEvent *event,
175a3bd7f05Smrg                   Widget widget,
176a3bd7f05Smrg                   EventMask mask,
177a3bd7f05Smrg                   XtPerDisplayInput pdi)
178444c061aSmrg{
179a3bd7f05Smrg    Widget dspWidget = widget;
180a3bd7f05Smrg
181a3bd7f05Smrg    if (!pdi->traceDepth || !(widget == pdi->trace[0])) {
182a3bd7f05Smrg        _XtFillAncestorList(&pdi->trace, &pdi->traceMax,
183a3bd7f05Smrg                            &pdi->traceDepth, widget, NULL);
184a3bd7f05Smrg        pdi->focusWidget = NULL;        /* invalidate the focus
185a3bd7f05Smrg                                           cache */
186a3bd7f05Smrg    }
187444c061aSmrg    if (mask & (KeyPressMask | KeyReleaseMask))
188a3bd7f05Smrg        dspWidget = _XtProcessKeyboardEvent((XKeyEvent *) event, widget, pdi);
189a3bd7f05Smrg    else if (mask & (ButtonPressMask | ButtonReleaseMask))
190a3bd7f05Smrg        dspWidget = _XtProcessPointerEvent((XButtonEvent *) event, widget, pdi);
191444c061aSmrg
192444c061aSmrg    return dspWidget;
193444c061aSmrg}
194444c061aSmrg
195a3bd7f05Smrgvoid
196a3bd7f05Smrg_XtUngrabBadGrabs(XEvent *event,
197a3bd7f05Smrg                  Widget widget,
198a3bd7f05Smrg                  EventMask mask,
199a3bd7f05Smrg                  XtPerDisplayInput pdi)
200444c061aSmrg{
201a3bd7f05Smrg    XKeyEvent *ke = (XKeyEvent *) event;
202444c061aSmrg
203a3bd7f05Smrg    if (mask & (KeyPressMask | KeyReleaseMask)) {
204a3bd7f05Smrg        if (IsServerGrab(pdi->keyboard.grabType) &&
205a3bd7f05Smrg            !_XtOnGrabList(pdi->keyboard.grab.widget, pdi->grabList))
206a3bd7f05Smrg            XtUngrabKeyboard(widget, ke->time);
207a3bd7f05Smrg
208a3bd7f05Smrg    }
209a3bd7f05Smrg    else {
210a3bd7f05Smrg        if (IsServerGrab(pdi->pointer.grabType) &&
211a3bd7f05Smrg            !_XtOnGrabList(pdi->pointer.grab.widget, pdi->grabList))
212a3bd7f05Smrg             XtUngrabPointer(widget, ke->time);
213a3bd7f05Smrg    }
214444c061aSmrg}
215