EventUtil.c revision 0568f49b
11477040fSmrg/*
21477040fSmrg
3249c3046SmrgCopyright (c) 1993, Oracle and/or its affiliates. All rights reserved.
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
83444c061aSmrgstatic XContext 	perWidgetInputContext = 0;
84444c061aSmrg
85444c061aSmrgvoid _XtFreePerWidgetInput(
86444c061aSmrg    Widget 		w,
87444c061aSmrg    XtPerWidgetInput	pwi)
88444c061aSmrg{
89444c061aSmrg    LOCK_PROCESS;
90444c061aSmrg    XDeleteContext(XtDisplay(w),
91444c061aSmrg		   (Window)w,
92444c061aSmrg		   perWidgetInputContext);
93444c061aSmrg
94444c061aSmrg    XtFree((char *)pwi);
95444c061aSmrg    UNLOCK_PROCESS;
96444c061aSmrg}
97444c061aSmrg
98444c061aSmrg/*
99444c061aSmrg * This routine gets the passive list associated with the widget
100444c061aSmrg * from the context manager.
101444c061aSmrg */
102444c061aSmrgXtPerWidgetInput _XtGetPerWidgetInput(
103444c061aSmrg    Widget	widget,
104444c061aSmrg    _XtBoolean	create)
105444c061aSmrg{
106444c061aSmrg    XtPerWidgetInput	pwi = NULL;
107444c061aSmrg    Display		*dpy = widget->core.screen->display;
108444c061aSmrg
109444c061aSmrg    LOCK_PROCESS;
110444c061aSmrg    if (! perWidgetInputContext)
111444c061aSmrg      perWidgetInputContext = XUniqueContext();
112444c061aSmrg
113444c061aSmrg    if (XFindContext(dpy,
114444c061aSmrg		     (Window)widget,
115444c061aSmrg		     perWidgetInputContext,
116444c061aSmrg		     (XPointer *)&pwi) &&
117444c061aSmrg	create)
118444c061aSmrg      {
119444c061aSmrg	  pwi = (XtPerWidgetInput)
120444c061aSmrg	    __XtMalloc((unsigned) sizeof(XtPerWidgetInputRec));
121444c061aSmrg
122444c061aSmrg	  pwi->focusKid = NULL;
123444c061aSmrg	  pwi->queryEventDescendant = NULL;
124444c061aSmrg	  pwi->focalPoint = XtUnrelated;
125444c061aSmrg	  pwi->keyList =
126444c061aSmrg	    pwi->ptrList = NULL;
127444c061aSmrg
128444c061aSmrg	  pwi->haveFocus =
129444c061aSmrg	      pwi->map_handler_added =
130444c061aSmrg		  pwi->realize_handler_added =
131444c061aSmrg		      pwi->active_handler_added = FALSE;
132444c061aSmrg
133444c061aSmrg	  XtAddCallback(widget, XtNdestroyCallback,
134444c061aSmrg			_XtDestroyServerGrabs, (XtPointer)pwi);
135444c061aSmrg
136444c061aSmrg	  (void) XSaveContext(dpy,
137444c061aSmrg			      (Window)widget,
138444c061aSmrg			      perWidgetInputContext,
139444c061aSmrg			      (char *) pwi);
140444c061aSmrg      }
141444c061aSmrg    UNLOCK_PROCESS;
142444c061aSmrg    return pwi;
143444c061aSmrg}
144444c061aSmrg
145444c061aSmrg
146444c061aSmrgvoid _XtFillAncestorList(
147444c061aSmrg    Widget	**listPtr,
148444c061aSmrg    int		*maxElemsPtr,
149444c061aSmrg    int		*numElemsPtr,
150444c061aSmrg    Widget	start,
151444c061aSmrg    Widget	breakWidget)
152444c061aSmrg{
153444c061aSmrg#define CACHESIZE 16
154444c061aSmrg    Cardinal	i;
155444c061aSmrg    Widget	w;
156444c061aSmrg    Widget	*trace = *listPtr;
157444c061aSmrg
158444c061aSmrg    /* First time in, allocate the ancestor list */
159444c061aSmrg    if (trace == NULL)
160444c061aSmrg      {
161444c061aSmrg	  trace = (Widget *) __XtMalloc(CACHESIZE * sizeof(Widget));
162444c061aSmrg	  *maxElemsPtr = CACHESIZE;
163444c061aSmrg      }
164444c061aSmrg    /* First fill in the ancestor list */
165444c061aSmrg
166444c061aSmrg    trace[0] = start;
167444c061aSmrg
168444c061aSmrg    for (i = 1, w = XtParent(start);
169444c061aSmrg	 w != NULL && !XtIsShell(trace[i-1]) && trace[i-1] != breakWidget;
170444c061aSmrg	 w = XtParent(w), i++) {
171444c061aSmrg	if (i == (Cardinal) *maxElemsPtr) {
172444c061aSmrg	    /* This should rarely happen, but if it does it'll probably
173444c061aSmrg	       happen again, so grow the ancestor list */
174444c061aSmrg	    *maxElemsPtr += CACHESIZE;
175444c061aSmrg	    trace = (Widget *) XtRealloc((char*)trace,
1760568f49bSmrg					 (Cardinal)(sizeof(Widget) * (size_t)(*maxElemsPtr)));
177444c061aSmrg	}
178444c061aSmrg	trace[i] = w;
179444c061aSmrg    }
180444c061aSmrg    *listPtr = trace;
1810568f49bSmrg    *numElemsPtr = (int) i;
182444c061aSmrg#undef CACHESIZE
183444c061aSmrg}
184444c061aSmrg
185444c061aSmrg
186444c061aSmrgWidget _XtFindRemapWidget(
187444c061aSmrg    XEvent	*event,
188444c061aSmrg    Widget	widget,
189444c061aSmrg    EventMask	mask,
190444c061aSmrg    XtPerDisplayInput pdi)
191444c061aSmrg{
192444c061aSmrg    Widget		dspWidget = widget;
193444c061aSmrg
194444c061aSmrg    if (!pdi->traceDepth || !(widget == pdi->trace[0]))
195444c061aSmrg      {
196444c061aSmrg	  _XtFillAncestorList(&pdi->trace, &pdi->traceMax,
197444c061aSmrg			      &pdi->traceDepth, widget, NULL);
198444c061aSmrg	  pdi->focusWidget = NULL; /* invalidate the focus
199444c061aSmrg				      cache */
200444c061aSmrg      }
201444c061aSmrg    if (mask & (KeyPressMask | KeyReleaseMask))
202444c061aSmrg	  dspWidget = _XtProcessKeyboardEvent((XKeyEvent*)event, widget, pdi);
203444c061aSmrg    else if (mask &(ButtonPressMask | ButtonReleaseMask))
204444c061aSmrg	  dspWidget = _XtProcessPointerEvent((XButtonEvent*)event, widget,pdi);
205444c061aSmrg
206444c061aSmrg    return dspWidget;
207444c061aSmrg}
208444c061aSmrg
209444c061aSmrgvoid _XtUngrabBadGrabs(
210444c061aSmrg    XEvent	*event,
211444c061aSmrg    Widget	widget,
212444c061aSmrg    EventMask	mask,
213444c061aSmrg    XtPerDisplayInput pdi)
214444c061aSmrg{
215444c061aSmrg    XKeyEvent	* ke = (XKeyEvent *) event;
216444c061aSmrg
217444c061aSmrg    if (mask & (KeyPressMask | KeyReleaseMask))
218444c061aSmrg      {
219444c061aSmrg	  if (IsServerGrab(pdi->keyboard.grabType) &&
220444c061aSmrg	      !_XtOnGrabList(pdi->keyboard.grab.widget,
221444c061aSmrg			     pdi->grabList))
222444c061aSmrg	    XtUngrabKeyboard(widget, ke->time);
223444c061aSmrg
224444c061aSmrg      }
225444c061aSmrg    else
226444c061aSmrg      {
227444c061aSmrg	  if (IsServerGrab(pdi->pointer.grabType) &&
228444c061aSmrg	      !_XtOnGrabList(pdi->pointer.grab.widget,
229444c061aSmrg			     pdi->grabList))
230444c061aSmrg	    XtUngrabPointer(widget, ke->time);
231444c061aSmrg      }
232444c061aSmrg}
233