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