EventUtil.c revision 1477040f
1444c061aSmrg/* $Xorg: EventUtil.c,v 1.4 2001/02/09 02:03:54 xorgcvs Exp $ */
21477040fSmrg/*
31477040fSmrg
41477040fSmrgCopyright 1993 Sun Microsystems, Inc.  All rights reserved.
51477040fSmrg
61477040fSmrgPermission is hereby granted, free of charge, to any person obtaining a
71477040fSmrgcopy of this software and associated documentation files (the "Software"),
81477040fSmrgto deal in the Software without restriction, including without limitation
91477040fSmrgthe rights to use, copy, modify, merge, publish, distribute, sublicense,
101477040fSmrgand/or sell copies of the Software, and to permit persons to whom the
111477040fSmrgSoftware is furnished to do so, subject to the following conditions:
121477040fSmrg
131477040fSmrgThe above copyright notice and this permission notice (including the next
141477040fSmrgparagraph) shall be included in all copies or substantial portions of the
151477040fSmrgSoftware.
16444c061aSmrg
171477040fSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
181477040fSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
191477040fSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
201477040fSmrgTHE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
211477040fSmrgLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
221477040fSmrgFROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
231477040fSmrgDEALINGS IN THE SOFTWARE.
241477040fSmrg
251477040fSmrg*/
26444c061aSmrg/********************************************************
27444c061aSmrg
28444c061aSmrgCopyright 1988 by Hewlett-Packard Company
29444c061aSmrgCopyright 1987, 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts
30444c061aSmrg
31444c061aSmrgPermission to use, copy, modify, and distribute this software
32444c061aSmrgand its documentation for any purpose and without fee is hereby
33444c061aSmrggranted, provided that the above copyright notice appear in all
34444c061aSmrgcopies and that both that copyright notice and this permission
35444c061aSmrgnotice appear in supporting documentation, and that the names of
361477040fSmrgHewlett-Packard or Digital not be used in advertising or
37444c061aSmrgpublicity pertaining to distribution of the software without specific,
38444c061aSmrgwritten prior permission.
39444c061aSmrg
40444c061aSmrgDIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
41444c061aSmrgALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
42444c061aSmrgDIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
43444c061aSmrgANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
44444c061aSmrgWHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
45444c061aSmrgARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
46444c061aSmrgSOFTWARE.
47444c061aSmrg
48444c061aSmrg********************************************************/
49444c061aSmrg
50444c061aSmrg/*
51444c061aSmrg
52444c061aSmrgCopyright 1987, 1988, 1989, 1998  The Open Group
53444c061aSmrg
54444c061aSmrgPermission to use, copy, modify, distribute, and sell this software and its
55444c061aSmrgdocumentation for any purpose is hereby granted without fee, provided that
56444c061aSmrgthe above copyright notice appear in all copies and that both that
57444c061aSmrgcopyright notice and this permission notice appear in supporting
58444c061aSmrgdocumentation.
59444c061aSmrg
60444c061aSmrgThe above copyright notice and this permission notice shall be included in
61444c061aSmrgall copies or substantial portions of the Software.
62444c061aSmrg
63444c061aSmrgTHE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
64444c061aSmrgIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
65444c061aSmrgFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
66444c061aSmrgOPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
67444c061aSmrgAN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
68444c061aSmrgCONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
69444c061aSmrg
70444c061aSmrgExcept as contained in this notice, the name of The Open Group shall not be
71444c061aSmrgused in advertising or otherwise to promote the sale, use or other dealings
72444c061aSmrgin this Software without prior written authorization from The Open Group.
73444c061aSmrg
74444c061aSmrg*/
75444c061aSmrg/* $XFree86: xc/lib/Xt/EventUtil.c,v 1.6 2001/12/14 19:56:13 dawes Exp $ */
76444c061aSmrg
77444c061aSmrg#ifdef HAVE_CONFIG_H
78444c061aSmrg#include <config.h>
79444c061aSmrg#endif
80444c061aSmrg#include "IntrinsicI.h"
81444c061aSmrg#include "PassivGraI.h"
82444c061aSmrg#include "StringDefs.h"
83444c061aSmrg#include "EventI.h"
84444c061aSmrg
85444c061aSmrgstatic XContext 	perWidgetInputContext = 0;
86444c061aSmrg
87444c061aSmrgvoid _XtFreePerWidgetInput(
88444c061aSmrg    Widget 		w,
89444c061aSmrg    XtPerWidgetInput	pwi)
90444c061aSmrg{
91444c061aSmrg    LOCK_PROCESS;
92444c061aSmrg    XDeleteContext(XtDisplay(w),
93444c061aSmrg		   (Window)w,
94444c061aSmrg		   perWidgetInputContext);
95444c061aSmrg
96444c061aSmrg    XtFree((char *)pwi);
97444c061aSmrg    UNLOCK_PROCESS;
98444c061aSmrg}
99444c061aSmrg
100444c061aSmrg/*
101444c061aSmrg * This routine gets the passive list associated with the widget
102444c061aSmrg * from the context manager.
103444c061aSmrg */
104444c061aSmrgXtPerWidgetInput _XtGetPerWidgetInput(
105444c061aSmrg    Widget	widget,
106444c061aSmrg    _XtBoolean	create)
107444c061aSmrg{
108444c061aSmrg    XtPerWidgetInput	pwi = NULL;
109444c061aSmrg    Display		*dpy = widget->core.screen->display;
110444c061aSmrg
111444c061aSmrg    LOCK_PROCESS;
112444c061aSmrg    if (! perWidgetInputContext)
113444c061aSmrg      perWidgetInputContext = XUniqueContext();
114444c061aSmrg
115444c061aSmrg    if (XFindContext(dpy,
116444c061aSmrg		     (Window)widget,
117444c061aSmrg		     perWidgetInputContext,
118444c061aSmrg		     (XPointer *)&pwi) &&
119444c061aSmrg	create)
120444c061aSmrg      {
121444c061aSmrg	  pwi = (XtPerWidgetInput)
122444c061aSmrg	    __XtMalloc((unsigned) sizeof(XtPerWidgetInputRec));
123444c061aSmrg
124444c061aSmrg	  pwi->focusKid = NULL;
125444c061aSmrg	  pwi->queryEventDescendant = NULL;
126444c061aSmrg	  pwi->focalPoint = XtUnrelated;
127444c061aSmrg	  pwi->keyList =
128444c061aSmrg	    pwi->ptrList = NULL;
129444c061aSmrg
130444c061aSmrg	  pwi->haveFocus =
131444c061aSmrg	      pwi->map_handler_added =
132444c061aSmrg		  pwi->realize_handler_added =
133444c061aSmrg		      pwi->active_handler_added = FALSE;
134444c061aSmrg
135444c061aSmrg	  XtAddCallback(widget, XtNdestroyCallback,
136444c061aSmrg			_XtDestroyServerGrabs, (XtPointer)pwi);
137444c061aSmrg
138444c061aSmrg	  (void) XSaveContext(dpy,
139444c061aSmrg			      (Window)widget,
140444c061aSmrg			      perWidgetInputContext,
141444c061aSmrg			      (char *) pwi);
142444c061aSmrg      }
143444c061aSmrg    UNLOCK_PROCESS;
144444c061aSmrg    return pwi;
145444c061aSmrg}
146444c061aSmrg
147444c061aSmrg
148444c061aSmrgvoid _XtFillAncestorList(
149444c061aSmrg    Widget	**listPtr,
150444c061aSmrg    int		*maxElemsPtr,
151444c061aSmrg    int		*numElemsPtr,
152444c061aSmrg    Widget	start,
153444c061aSmrg    Widget	breakWidget)
154444c061aSmrg{
155444c061aSmrg#define CACHESIZE 16
156444c061aSmrg    Cardinal	i;
157444c061aSmrg    Widget	w;
158444c061aSmrg    Widget	*trace = *listPtr;
159444c061aSmrg
160444c061aSmrg    /* First time in, allocate the ancestor list */
161444c061aSmrg    if (trace == NULL)
162444c061aSmrg      {
163444c061aSmrg	  trace = (Widget *) __XtMalloc(CACHESIZE * sizeof(Widget));
164444c061aSmrg	  *maxElemsPtr = CACHESIZE;
165444c061aSmrg      }
166444c061aSmrg    /* First fill in the ancestor list */
167444c061aSmrg
168444c061aSmrg    trace[0] = start;
169444c061aSmrg
170444c061aSmrg    for (i = 1, w = XtParent(start);
171444c061aSmrg	 w != NULL && !XtIsShell(trace[i-1]) && trace[i-1] != breakWidget;
172444c061aSmrg	 w = XtParent(w), i++) {
173444c061aSmrg	if (i == (Cardinal) *maxElemsPtr) {
174444c061aSmrg	    /* This should rarely happen, but if it does it'll probably
175444c061aSmrg	       happen again, so grow the ancestor list */
176444c061aSmrg	    *maxElemsPtr += CACHESIZE;
177444c061aSmrg	    trace = (Widget *) XtRealloc((char*)trace,
178444c061aSmrg					 sizeof(Widget) * (*maxElemsPtr));
179444c061aSmrg	}
180444c061aSmrg	trace[i] = w;
181444c061aSmrg    }
182444c061aSmrg    *listPtr = trace;
183444c061aSmrg    *numElemsPtr = i;
184444c061aSmrg#undef CACHESIZE
185444c061aSmrg}
186444c061aSmrg
187444c061aSmrg
188444c061aSmrgWidget _XtFindRemapWidget(
189444c061aSmrg    XEvent	*event,
190444c061aSmrg    Widget	widget,
191444c061aSmrg    EventMask	mask,
192444c061aSmrg    XtPerDisplayInput pdi)
193444c061aSmrg{
194444c061aSmrg    Widget		dspWidget = widget;
195444c061aSmrg
196444c061aSmrg    if (!pdi->traceDepth || !(widget == pdi->trace[0]))
197444c061aSmrg      {
198444c061aSmrg	  _XtFillAncestorList(&pdi->trace, &pdi->traceMax,
199444c061aSmrg			      &pdi->traceDepth, widget, NULL);
200444c061aSmrg	  pdi->focusWidget = NULL; /* invalidate the focus
201444c061aSmrg				      cache */
202444c061aSmrg      }
203444c061aSmrg    if (mask & (KeyPressMask | KeyReleaseMask))
204444c061aSmrg	  dspWidget = _XtProcessKeyboardEvent((XKeyEvent*)event, widget, pdi);
205444c061aSmrg    else if (mask &(ButtonPressMask | ButtonReleaseMask))
206444c061aSmrg	  dspWidget = _XtProcessPointerEvent((XButtonEvent*)event, widget,pdi);
207444c061aSmrg
208444c061aSmrg    return dspWidget;
209444c061aSmrg}
210444c061aSmrg
211444c061aSmrgvoid _XtUngrabBadGrabs(
212444c061aSmrg    XEvent	*event,
213444c061aSmrg    Widget	widget,
214444c061aSmrg    EventMask	mask,
215444c061aSmrg    XtPerDisplayInput pdi)
216444c061aSmrg{
217444c061aSmrg    XKeyEvent	* ke = (XKeyEvent *) event;
218444c061aSmrg
219444c061aSmrg    if (mask & (KeyPressMask | KeyReleaseMask))
220444c061aSmrg      {
221444c061aSmrg	  if (IsServerGrab(pdi->keyboard.grabType) &&
222444c061aSmrg	      !_XtOnGrabList(pdi->keyboard.grab.widget,
223444c061aSmrg			     pdi->grabList))
224444c061aSmrg	    XtUngrabKeyboard(widget, ke->time);
225444c061aSmrg
226444c061aSmrg      }
227444c061aSmrg    else
228444c061aSmrg      {
229444c061aSmrg	  if (IsServerGrab(pdi->pointer.grabType) &&
230444c061aSmrg	      !_XtOnGrabList(pdi->pointer.grab.widget,
231444c061aSmrg			     pdi->grabList))
232444c061aSmrg	    XtUngrabPointer(widget, ke->time);
233444c061aSmrg      }
234444c061aSmrg}
235