EventUtil.c revision 444c061a
1/* $Xorg: EventUtil.c,v 1.4 2001/02/09 02:03:54 xorgcvs Exp $ */
2
3/********************************************************
4
5Copyright 1988 by Hewlett-Packard Company
6Copyright 1987, 1988, 1989 by Digital Equipment Corporation, Maynard, Massachusetts
7Copyright 1993 by Sun Microsystems, Inc. Mountain View, CA.
8
9Permission to use, copy, modify, and distribute this software
10and its documentation for any purpose and without fee is hereby
11granted, provided that the above copyright notice appear in all
12copies and that both that copyright notice and this permission
13notice appear in supporting documentation, and that the names of
14Hewlett-Packard, Digital, or Sun  not be used in advertising or
15publicity pertaining to distribution of the software without specific,
16written prior permission.
17
18DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
19ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
20DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
21ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
23ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
24SOFTWARE.
25
26SUN DISCLAIMS ALL WARRANTIES WITH REGARD TO  THIS  SOFTWARE,
27INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FIT-
28NESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SUN BE  LI-
29ABLE  FOR  ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
30ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,  DATA  OR
31PROFITS,  WHETHER  IN  AN  ACTION OF CONTRACT, NEGLIGENCE OR
32OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION  WITH
33THE USE OR PERFORMANCE OF THIS SOFTWARE.
34
35********************************************************/
36
37/*
38
39Copyright 1987, 1988, 1989, 1998  The Open Group
40
41Permission to use, copy, modify, distribute, and sell this software and its
42documentation for any purpose is hereby granted without fee, provided that
43the above copyright notice appear in all copies and that both that
44copyright notice and this permission notice appear in supporting
45documentation.
46
47The above copyright notice and this permission notice shall be included in
48all copies or substantial portions of the Software.
49
50THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
53OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
54AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
55CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
56
57Except as contained in this notice, the name of The Open Group shall not be
58used in advertising or otherwise to promote the sale, use or other dealings
59in this Software without prior written authorization from The Open Group.
60
61*/
62/* $XFree86: xc/lib/Xt/EventUtil.c,v 1.6 2001/12/14 19:56:13 dawes Exp $ */
63
64#ifdef HAVE_CONFIG_H
65#include <config.h>
66#endif
67#include "IntrinsicI.h"
68#include "PassivGraI.h"
69#include "StringDefs.h"
70#include "EventI.h"
71
72static XContext 	perWidgetInputContext = 0;
73
74void _XtFreePerWidgetInput(
75    Widget 		w,
76    XtPerWidgetInput	pwi)
77{
78    LOCK_PROCESS;
79    XDeleteContext(XtDisplay(w),
80		   (Window)w,
81		   perWidgetInputContext);
82
83    XtFree((char *)pwi);
84    UNLOCK_PROCESS;
85}
86
87/*
88 * This routine gets the passive list associated with the widget
89 * from the context manager.
90 */
91XtPerWidgetInput _XtGetPerWidgetInput(
92    Widget	widget,
93    _XtBoolean	create)
94{
95    XtPerWidgetInput	pwi = NULL;
96    Display		*dpy = widget->core.screen->display;
97
98    LOCK_PROCESS;
99    if (! perWidgetInputContext)
100      perWidgetInputContext = XUniqueContext();
101
102    if (XFindContext(dpy,
103		     (Window)widget,
104		     perWidgetInputContext,
105		     (XPointer *)&pwi) &&
106	create)
107      {
108	  pwi = (XtPerWidgetInput)
109	    __XtMalloc((unsigned) sizeof(XtPerWidgetInputRec));
110
111	  pwi->focusKid = NULL;
112	  pwi->queryEventDescendant = NULL;
113	  pwi->focalPoint = XtUnrelated;
114	  pwi->keyList =
115	    pwi->ptrList = NULL;
116
117	  pwi->haveFocus =
118	      pwi->map_handler_added =
119		  pwi->realize_handler_added =
120		      pwi->active_handler_added = FALSE;
121
122	  XtAddCallback(widget, XtNdestroyCallback,
123			_XtDestroyServerGrabs, (XtPointer)pwi);
124
125	  (void) XSaveContext(dpy,
126			      (Window)widget,
127			      perWidgetInputContext,
128			      (char *) pwi);
129      }
130    UNLOCK_PROCESS;
131    return pwi;
132}
133
134
135void _XtFillAncestorList(
136    Widget	**listPtr,
137    int		*maxElemsPtr,
138    int		*numElemsPtr,
139    Widget	start,
140    Widget	breakWidget)
141{
142#define CACHESIZE 16
143    Cardinal	i;
144    Widget	w;
145    Widget	*trace = *listPtr;
146
147    /* First time in, allocate the ancestor list */
148    if (trace == NULL)
149      {
150	  trace = (Widget *) __XtMalloc(CACHESIZE * sizeof(Widget));
151	  *maxElemsPtr = CACHESIZE;
152      }
153    /* First fill in the ancestor list */
154
155    trace[0] = start;
156
157    for (i = 1, w = XtParent(start);
158	 w != NULL && !XtIsShell(trace[i-1]) && trace[i-1] != breakWidget;
159	 w = XtParent(w), i++) {
160	if (i == (Cardinal) *maxElemsPtr) {
161	    /* This should rarely happen, but if it does it'll probably
162	       happen again, so grow the ancestor list */
163	    *maxElemsPtr += CACHESIZE;
164	    trace = (Widget *) XtRealloc((char*)trace,
165					 sizeof(Widget) * (*maxElemsPtr));
166	}
167	trace[i] = w;
168    }
169    *listPtr = trace;
170    *numElemsPtr = i;
171#undef CACHESIZE
172}
173
174
175Widget _XtFindRemapWidget(
176    XEvent	*event,
177    Widget	widget,
178    EventMask	mask,
179    XtPerDisplayInput pdi)
180{
181    Widget		dspWidget = widget;
182
183    if (!pdi->traceDepth || !(widget == pdi->trace[0]))
184      {
185	  _XtFillAncestorList(&pdi->trace, &pdi->traceMax,
186			      &pdi->traceDepth, widget, NULL);
187	  pdi->focusWidget = NULL; /* invalidate the focus
188				      cache */
189      }
190    if (mask & (KeyPressMask | KeyReleaseMask))
191	  dspWidget = _XtProcessKeyboardEvent((XKeyEvent*)event, widget, pdi);
192    else if (mask &(ButtonPressMask | ButtonReleaseMask))
193	  dspWidget = _XtProcessPointerEvent((XButtonEvent*)event, widget,pdi);
194
195    return dspWidget;
196}
197
198void _XtUngrabBadGrabs(
199    XEvent	*event,
200    Widget	widget,
201    EventMask	mask,
202    XtPerDisplayInput pdi)
203{
204    XKeyEvent	* ke = (XKeyEvent *) event;
205
206    if (mask & (KeyPressMask | KeyReleaseMask))
207      {
208	  if (IsServerGrab(pdi->keyboard.grabType) &&
209	      !_XtOnGrabList(pdi->keyboard.grab.widget,
210			     pdi->grabList))
211	    XtUngrabKeyboard(widget, ke->time);
212
213      }
214    else
215      {
216	  if (IsServerGrab(pdi->pointer.grabType) &&
217	      !_XtOnGrabList(pdi->pointer.grab.widget,
218			     pdi->grabList))
219	    XtUngrabPointer(widget, ke->time);
220      }
221}
222