File: | src/PassivGrab.c |
Location: | line 804, column 9 |
Description: | Dereference of null pointer |
1 | /* | |||||
2 | ||||||
3 | Copyright (c) 1993, Oracle and/or its affiliates. All rights reserved. | |||||
4 | ||||||
5 | Permission is hereby granted, free of charge, to any person obtaining a | |||||
6 | copy of this software and associated documentation files (the "Software"), | |||||
7 | to deal in the Software without restriction, including without limitation | |||||
8 | the rights to use, copy, modify, merge, publish, distribute, sublicense, | |||||
9 | and/or sell copies of the Software, and to permit persons to whom the | |||||
10 | Software is furnished to do so, subject to the following conditions: | |||||
11 | ||||||
12 | The above copyright notice and this permission notice (including the next | |||||
13 | paragraph) shall be included in all copies or substantial portions of the | |||||
14 | Software. | |||||
15 | ||||||
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |||||
19 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||||
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||||
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | |||||
22 | DEALINGS IN THE SOFTWARE. | |||||
23 | ||||||
24 | */ | |||||
25 | /******************************************************** | |||||
26 | ||||||
27 | Copyright 1988 by Hewlett-Packard Company | |||||
28 | Copyright 1987, 1988, 1989,1990 by Digital Equipment Corporation, Maynard, Massachusetts | |||||
29 | ||||||
30 | Permission to use, copy, modify, and distribute this software | |||||
31 | and its documentation for any purpose and without fee is hereby | |||||
32 | granted, provided that the above copyright notice appear in all | |||||
33 | copies and that both that copyright notice and this permission | |||||
34 | notice appear in supporting documentation, and that the names of | |||||
35 | Hewlett-Packard or Digital not be used in advertising or | |||||
36 | publicity pertaining to distribution of the software without specific, | |||||
37 | written prior permission. | |||||
38 | ||||||
39 | DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING | |||||
40 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL | |||||
41 | DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR | |||||
42 | ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, | |||||
43 | WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, | |||||
44 | ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS | |||||
45 | SOFTWARE. | |||||
46 | ||||||
47 | ********************************************************/ | |||||
48 | ||||||
49 | /* | |||||
50 | ||||||
51 | Copyright 1987, 1988, 1989, 1990, 1994, 1998 The Open Group | |||||
52 | ||||||
53 | Permission to use, copy, modify, distribute, and sell this software and its | |||||
54 | documentation for any purpose is hereby granted without fee, provided that | |||||
55 | the above copyright notice appear in all copies and that both that | |||||
56 | copyright notice and this permission notice appear in supporting | |||||
57 | documentation. | |||||
58 | ||||||
59 | The above copyright notice and this permission notice shall be included in | |||||
60 | all copies or substantial portions of the Software. | |||||
61 | ||||||
62 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||||
63 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||||
64 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||||
65 | OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN | |||||
66 | AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | |||||
67 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | |||||
68 | ||||||
69 | Except as contained in this notice, the name of The Open Group shall not be | |||||
70 | used in advertising or otherwise to promote the sale, use or other dealings | |||||
71 | in this Software without prior written authorization from The Open Group. | |||||
72 | ||||||
73 | */ | |||||
74 | ||||||
75 | #ifdef HAVE_CONFIG_H1 | |||||
76 | #include <config.h> | |||||
77 | #endif | |||||
78 | #include "IntrinsicI.h" | |||||
79 | #include "StringDefs.h" | |||||
80 | #include "PassivGraI.h" | |||||
81 | ||||||
82 | /* typedef unsigned long Mask; */ | |||||
83 | #define BITMASK(i)(((Mask)1) << ((i) & 31)) (((Mask)1) << ((i) & 31)) | |||||
84 | #define MASKIDX(i)((i) >> 5) ((i) >> 5) | |||||
85 | #define MASKWORD(buf, i)buf[((i) >> 5)] buf[MASKIDX(i)((i) >> 5)] | |||||
86 | #define BITSET(buf, i)buf[((i) >> 5)] |= (((Mask)1) << ((i) & 31)) MASKWORD(buf, i)buf[((i) >> 5)] |= BITMASK(i)(((Mask)1) << ((i) & 31)) | |||||
87 | #define BITCLEAR(buf, i)buf[((i) >> 5)] &= ~(((Mask)1) << ((i) & 31 )) MASKWORD(buf, i)buf[((i) >> 5)] &= ~BITMASK(i)(((Mask)1) << ((i) & 31)) | |||||
88 | #define GETBIT(buf, i)(buf[((i) >> 5)] & (((Mask)1) << ((i) & 31 ))) (MASKWORD(buf, i)buf[((i) >> 5)] & BITMASK(i)(((Mask)1) << ((i) & 31))) | |||||
89 | #define MasksPerDetailMask8 8 | |||||
90 | ||||||
91 | #define pDisplay(grabPtr)(((grabPtr)->widget)->core.screen->display) (((grabPtr)->widget)->core.screen->display) | |||||
92 | #define pWindow(grabPtr)(((grabPtr)->widget)->core.window) (((grabPtr)->widget)->core.window) | |||||
93 | ||||||
94 | ||||||
95 | /***************************************************************************/ | |||||
96 | /*********************** Internal Support Routines *************************/ | |||||
97 | /***************************************************************************/ | |||||
98 | ||||||
99 | /* | |||||
100 | * Turn off (clear) the bit in the specified detail mask which is associated | |||||
101 | * with the detail. | |||||
102 | */ | |||||
103 | ||||||
104 | static void DeleteDetailFromMask( | |||||
105 | Mask **ppDetailMask, | |||||
106 | unsigned short detail) | |||||
107 | { | |||||
108 | Mask *pDetailMask = *ppDetailMask; | |||||
109 | ||||||
110 | if (!pDetailMask) { | |||||
111 | int i; | |||||
112 | pDetailMask = (Mask *)__XtMalloc(sizeof(Mask) * MasksPerDetailMask8); | |||||
113 | for (i = MasksPerDetailMask8; --i >= 0; ) | |||||
114 | pDetailMask[i] = ~0; | |||||
115 | *ppDetailMask = pDetailMask; | |||||
116 | } | |||||
117 | BITCLEAR((pDetailMask), detail)(pDetailMask)[((detail) >> 5)] &= ~(((Mask)1) << ((detail) & 31)); | |||||
118 | } | |||||
119 | ||||||
120 | ||||||
121 | /* | |||||
122 | * Make an exact copy of the specified detail mask. | |||||
123 | */ | |||||
124 | ||||||
125 | static Mask *CopyDetailMask( | |||||
126 | Mask *pOriginalDetailMask) | |||||
127 | { | |||||
128 | Mask *pTempMask; | |||||
129 | int i; | |||||
130 | ||||||
131 | if (!pOriginalDetailMask) | |||||
132 | return NULL((void*)0); | |||||
133 | ||||||
134 | pTempMask = (Mask *)__XtMalloc(sizeof(Mask) * MasksPerDetailMask8); | |||||
135 | ||||||
136 | for ( i = 0; i < MasksPerDetailMask8; i++) | |||||
137 | pTempMask[i]= pOriginalDetailMask[i]; | |||||
138 | ||||||
139 | return pTempMask; | |||||
140 | } | |||||
141 | ||||||
142 | ||||||
143 | /* | |||||
144 | * Allocate a new grab entry, and fill in all of the fields using the | |||||
145 | * specified parameters. | |||||
146 | */ | |||||
147 | ||||||
148 | static XtServerGrabPtr CreateGrab( | |||||
149 | Widget widget, | |||||
150 | Boolean ownerEvents, | |||||
151 | Modifiers modifiers, | |||||
152 | KeyCode keybut, | |||||
153 | int pointer_mode, | |||||
154 | int keyboard_mode, | |||||
155 | Mask event_mask, | |||||
156 | Window confine_to, | |||||
157 | Cursor cursor, | |||||
158 | Boolean need_ext) | |||||
159 | { | |||||
160 | XtServerGrabPtr grab; | |||||
161 | ||||||
162 | if (confine_to || cursor) | |||||
163 | need_ext = True1; | |||||
164 | grab = (XtServerGrabPtr)__XtMalloc(sizeof(XtServerGrabRec) + | |||||
165 | (need_ext ? sizeof(XtServerGrabExtRec) | |||||
166 | : 0)); | |||||
167 | grab->next = NULL((void*)0); | |||||
168 | grab->widget = widget; | |||||
169 | grab->ownerEvents = ownerEvents; | |||||
170 | grab->pointerMode = pointer_mode; | |||||
171 | grab->keyboardMode = keyboard_mode; | |||||
172 | grab->eventMask = event_mask; | |||||
173 | grab->hasExt = need_ext; | |||||
174 | grab->confineToIsWidgetWin = (XtWindow (widget)((widget)->core.window) == confine_to); | |||||
175 | grab->modifiers = modifiers; | |||||
176 | grab->keybut = keybut; | |||||
177 | if (need_ext) { | |||||
178 | XtServerGrabExtPtr ext = GRABEXT(grab)((XtServerGrabExtPtr)((grab)+1)); | |||||
179 | ext->pModifiersMask = NULL((void*)0); | |||||
180 | ext->pKeyButMask = NULL((void*)0); | |||||
181 | ext->confineTo = confine_to; | |||||
182 | ext->cursor = cursor; | |||||
183 | } | |||||
184 | return grab; | |||||
185 | } | |||||
186 | ||||||
187 | ||||||
188 | /* | |||||
189 | * Free up the space occupied by a grab entry. | |||||
190 | */ | |||||
191 | ||||||
192 | static void FreeGrab( | |||||
193 | XtServerGrabPtr pGrab) | |||||
194 | { | |||||
195 | if (pGrab->hasExt) { | |||||
196 | XtServerGrabExtPtr ext = GRABEXT(pGrab)((XtServerGrabExtPtr)((pGrab)+1)); | |||||
197 | if (ext->pModifiersMask) | |||||
198 | XtFree((char *)ext->pModifiersMask); | |||||
199 | if (ext->pKeyButMask) | |||||
200 | XtFree((char *)ext->pKeyButMask); | |||||
201 | } | |||||
202 | XtFree((char *)pGrab); | |||||
203 | } | |||||
204 | ||||||
205 | typedef struct _DetailRec { | |||||
206 | unsigned short exact; | |||||
207 | Mask *pMask; | |||||
208 | } DetailRec, *DetailPtr; | |||||
209 | ||||||
210 | /* | |||||
211 | * If the first detail is set to 'exception' and the second detail | |||||
212 | * is contained in the mask of the first, then TRUE is returned. | |||||
213 | */ | |||||
214 | ||||||
215 | static Boolint IsInGrabMask( | |||||
216 | register DetailPtr firstDetail, | |||||
217 | register DetailPtr secondDetail, | |||||
218 | unsigned short exception) | |||||
219 | { | |||||
220 | if (firstDetail->exact == exception) { | |||||
221 | if (!firstDetail->pMask) | |||||
222 | return TRUE1; | |||||
223 | ||||||
224 | /* (at present) never called with two non-null pMasks */ | |||||
225 | if (secondDetail->exact == exception) | |||||
226 | return FALSE0; | |||||
227 | ||||||
228 | if (GETBIT(firstDetail->pMask, secondDetail->exact)(firstDetail->pMask[((secondDetail->exact) >> 5)] & (((Mask)1) << ((secondDetail->exact) & 31 )))) | |||||
229 | return TRUE1; | |||||
230 | } | |||||
231 | ||||||
232 | return FALSE0; | |||||
233 | } | |||||
234 | ||||||
235 | ||||||
236 | /* | |||||
237 | * If neither of the details is set to 'exception', and they match | |||||
238 | * exactly, then TRUE is returned. | |||||
239 | */ | |||||
240 | ||||||
241 | static Boolint IdenticalExactDetails( | |||||
242 | unsigned short firstExact, | |||||
243 | unsigned short secondExact, | |||||
244 | unsigned short exception) | |||||
245 | { | |||||
246 | if ((firstExact == exception) || (secondExact == exception)) | |||||
247 | return FALSE0; | |||||
248 | ||||||
249 | if (firstExact == secondExact) | |||||
250 | return TRUE1; | |||||
251 | ||||||
252 | return FALSE0; | |||||
253 | } | |||||
254 | ||||||
255 | ||||||
256 | /* | |||||
257 | * If the first detail is set to 'exception', and its mask has the bit | |||||
258 | * enabled which corresponds to the second detail, OR if neither of the | |||||
259 | * details is set to 'exception' and the details match exactly, then | |||||
260 | * TRUE is returned. | |||||
261 | */ | |||||
262 | ||||||
263 | static Boolint DetailSupersedesSecond( | |||||
264 | register DetailPtr firstDetail, | |||||
265 | register DetailPtr secondDetail, | |||||
266 | unsigned short exception) | |||||
267 | { | |||||
268 | if (IsInGrabMask(firstDetail, secondDetail, exception)) | |||||
269 | return TRUE1; | |||||
270 | ||||||
271 | if (IdenticalExactDetails(firstDetail->exact, secondDetail->exact, | |||||
272 | exception)) | |||||
273 | return TRUE1; | |||||
274 | ||||||
275 | return FALSE0; | |||||
276 | } | |||||
277 | ||||||
278 | ||||||
279 | /* | |||||
280 | * If the two grab events match exactly, or if the first grab entry | |||||
281 | * 'encompasses' the second grab entry, then TRUE is returned. | |||||
282 | */ | |||||
283 | ||||||
284 | static Boolint GrabSupersedesSecond( | |||||
285 | register XtServerGrabPtr pFirstGrab, | |||||
286 | register XtServerGrabPtr pSecondGrab) | |||||
287 | { | |||||
288 | DetailRec first, second; | |||||
289 | ||||||
290 | first.exact = pFirstGrab->modifiers; | |||||
291 | if (pFirstGrab->hasExt) | |||||
292 | first.pMask = GRABEXT(pFirstGrab)((XtServerGrabExtPtr)((pFirstGrab)+1))->pModifiersMask; | |||||
293 | else | |||||
294 | first.pMask = NULL((void*)0); | |||||
295 | second.exact = pSecondGrab->modifiers; | |||||
296 | if (pSecondGrab->hasExt) | |||||
297 | second.pMask = GRABEXT(pSecondGrab)((XtServerGrabExtPtr)((pSecondGrab)+1))->pModifiersMask; | |||||
298 | else | |||||
299 | second.pMask = NULL((void*)0); | |||||
300 | if (!DetailSupersedesSecond(&first, &second, (unsigned short)AnyModifier(1<<15))) | |||||
301 | return FALSE0; | |||||
302 | ||||||
303 | first.exact = pFirstGrab->keybut; | |||||
304 | if (pFirstGrab->hasExt) | |||||
305 | first.pMask = GRABEXT(pFirstGrab)((XtServerGrabExtPtr)((pFirstGrab)+1))->pKeyButMask; | |||||
306 | else | |||||
307 | first.pMask = NULL((void*)0); | |||||
308 | second.exact = pSecondGrab->keybut; | |||||
309 | if (pSecondGrab->hasExt) | |||||
310 | second.pMask = GRABEXT(pSecondGrab)((XtServerGrabExtPtr)((pSecondGrab)+1))->pKeyButMask; | |||||
311 | else | |||||
312 | second.pMask = NULL((void*)0); | |||||
313 | if (DetailSupersedesSecond(&first, &second, (unsigned short)AnyKey0L)) | |||||
314 | return TRUE1; | |||||
315 | ||||||
316 | return FALSE0; | |||||
317 | } | |||||
318 | ||||||
319 | ||||||
320 | /* | |||||
321 | * Two grabs are considered to be matching if either of the following are true: | |||||
322 | * | |||||
323 | * 1) The two grab entries match exactly, or the first grab entry | |||||
324 | * encompasses the second grab entry. | |||||
325 | * 2) The second grab entry encompasses the first grab entry. | |||||
326 | * 3) The keycodes match exactly, and one entry's modifiers encompasses | |||||
327 | * the others. | |||||
328 | * 4) The keycode for one entry encompasses the other, and the detail | |||||
329 | * for the other entry encompasses the first. | |||||
330 | */ | |||||
331 | ||||||
332 | static Boolint GrabMatchesSecond( | |||||
333 | register XtServerGrabPtr pFirstGrab, | |||||
334 | register XtServerGrabPtr pSecondGrab) | |||||
335 | { | |||||
336 | DetailRec firstD, firstM, secondD, secondM; | |||||
337 | ||||||
338 | if (pDisplay(pFirstGrab)(((pFirstGrab)->widget)->core.screen->display) != pDisplay(pSecondGrab)(((pSecondGrab)->widget)->core.screen->display)) | |||||
339 | return FALSE0; | |||||
340 | ||||||
341 | if (GrabSupersedesSecond(pFirstGrab, pSecondGrab)) | |||||
342 | return TRUE1; | |||||
343 | ||||||
344 | if (GrabSupersedesSecond(pSecondGrab, pFirstGrab)) | |||||
345 | return TRUE1; | |||||
346 | ||||||
347 | firstD.exact = pFirstGrab->keybut; | |||||
348 | firstM.exact = pFirstGrab->modifiers; | |||||
349 | if (pFirstGrab->hasExt) { | |||||
350 | firstD.pMask = GRABEXT(pFirstGrab)((XtServerGrabExtPtr)((pFirstGrab)+1))->pKeyButMask; | |||||
351 | firstM.pMask = GRABEXT(pFirstGrab)((XtServerGrabExtPtr)((pFirstGrab)+1))->pModifiersMask; | |||||
352 | } else { | |||||
353 | firstD.pMask = NULL((void*)0); | |||||
354 | firstM.pMask = NULL((void*)0); | |||||
355 | } | |||||
356 | secondD.exact = pSecondGrab->keybut; | |||||
357 | secondM.exact = pSecondGrab->modifiers; | |||||
358 | if (pSecondGrab->hasExt) { | |||||
359 | secondD.pMask = GRABEXT(pSecondGrab)((XtServerGrabExtPtr)((pSecondGrab)+1))->pKeyButMask; | |||||
360 | secondM.pMask = GRABEXT(pSecondGrab)((XtServerGrabExtPtr)((pSecondGrab)+1))->pModifiersMask; | |||||
361 | } else { | |||||
362 | secondD.pMask = NULL((void*)0); | |||||
363 | secondM.pMask = NULL((void*)0); | |||||
364 | } | |||||
365 | ||||||
366 | if (DetailSupersedesSecond(&secondD, &firstD, (unsigned short)AnyKey0L) && | |||||
367 | DetailSupersedesSecond(&firstM, &secondM, (unsigned short)AnyModifier(1<<15))) | |||||
368 | return TRUE1; | |||||
369 | ||||||
370 | if (DetailSupersedesSecond(&firstD, &secondD, (unsigned short)AnyKey0L) && | |||||
371 | DetailSupersedesSecond(&secondM, &firstM, (unsigned short)AnyModifier(1<<15))) | |||||
372 | return TRUE1; | |||||
373 | ||||||
374 | return FALSE0; | |||||
375 | } | |||||
376 | ||||||
377 | ||||||
378 | /* | |||||
379 | * Delete a grab combination from the passive grab list. Each entry will | |||||
380 | * be checked to see if it is affected by the grab being deleted. This | |||||
381 | * may result in multiple entries being modified/deleted. | |||||
382 | */ | |||||
383 | ||||||
384 | static void DeleteServerGrabFromList( | |||||
385 | XtServerGrabPtr *passiveListPtr, | |||||
386 | XtServerGrabPtr pMinuendGrab) | |||||
387 | { | |||||
388 | register XtServerGrabPtr *next; | |||||
389 | register XtServerGrabPtr grab; | |||||
390 | register XtServerGrabExtPtr ext; | |||||
391 | ||||||
392 | for (next = passiveListPtr; (grab = *next); ) | |||||
393 | { | |||||
394 | if (GrabMatchesSecond(grab, pMinuendGrab) && | |||||
395 | (pDisplay(grab)(((grab)->widget)->core.screen->display) == pDisplay(pMinuendGrab)(((pMinuendGrab)->widget)->core.screen->display))) | |||||
396 | { | |||||
397 | if (GrabSupersedesSecond(pMinuendGrab, grab)) | |||||
398 | { | |||||
399 | /* | |||||
400 | * The entry being deleted encompasses the list entry, | |||||
401 | * so delete the list entry. | |||||
402 | */ | |||||
403 | *next = grab->next; | |||||
404 | FreeGrab(grab); | |||||
405 | continue; | |||||
406 | } | |||||
407 | ||||||
408 | if (!grab->hasExt) { | |||||
409 | grab = (XtServerGrabPtr) | |||||
410 | XtRealloc((char *)grab, (sizeof(XtServerGrabRec) + | |||||
411 | sizeof(XtServerGrabExtRec))); | |||||
412 | *next = grab; | |||||
413 | grab->hasExt = True1; | |||||
414 | ext = GRABEXT(grab)((XtServerGrabExtPtr)((grab)+1)); | |||||
415 | ext->pKeyButMask = NULL((void*)0); | |||||
416 | ext->pModifiersMask = NULL((void*)0); | |||||
417 | ext->confineTo = None0L; | |||||
418 | ext->cursor = None0L; | |||||
419 | } else | |||||
420 | ext = GRABEXT(grab)((XtServerGrabExtPtr)((grab)+1)); | |||||
421 | if ((grab->keybut == AnyKey0L) && (grab->modifiers != AnyModifier(1<<15))) | |||||
422 | { | |||||
423 | /* | |||||
424 | * If the list entry has the key detail of AnyKey, and | |||||
425 | * a modifier detail not set to AnyModifier, then we | |||||
426 | * simply need to turn off the key detail bit in the | |||||
427 | * list entry's key detail mask. | |||||
428 | */ | |||||
429 | DeleteDetailFromMask(&ext->pKeyButMask, pMinuendGrab->keybut); | |||||
430 | } else if ((grab->modifiers == AnyModifier(1<<15)) && | |||||
431 | (grab->keybut != AnyKey0L)) { | |||||
432 | /* | |||||
433 | * The list entry has a specific key detail, but its | |||||
434 | * modifier detail is set to AnyModifier; so, we only | |||||
435 | * need to turn off the specified modifier combination | |||||
436 | * in the list entry's modifier mask. | |||||
437 | */ | |||||
438 | DeleteDetailFromMask(&ext->pModifiersMask, | |||||
439 | pMinuendGrab->modifiers); | |||||
440 | } else if ((pMinuendGrab->keybut != AnyKey0L) && | |||||
441 | (pMinuendGrab->modifiers != AnyModifier(1<<15))) { | |||||
442 | /* | |||||
443 | * The list entry has a key detail of AnyKey and a | |||||
444 | * modifier detail of AnyModifier; the entry being | |||||
445 | * deleted has a specific key and a specific modifier | |||||
446 | * combination. Therefore, we need to mask off the | |||||
447 | * keycode from the list entry, and also create a | |||||
448 | * new entry for this keycode, which has a modifier | |||||
449 | * mask set to AnyModifier & ~(deleted modifiers). | |||||
450 | */ | |||||
451 | XtServerGrabPtr pNewGrab; | |||||
452 | ||||||
453 | DeleteDetailFromMask(&ext->pKeyButMask, pMinuendGrab->keybut); | |||||
454 | pNewGrab = CreateGrab(grab->widget, | |||||
455 | (Boolean)grab->ownerEvents, | |||||
456 | (Modifiers)AnyModifier(1<<15), | |||||
457 | pMinuendGrab->keybut, | |||||
458 | (int)grab->pointerMode, | |||||
459 | (int)grab->keyboardMode, | |||||
460 | (Mask)0, (Window)0, (Cursor)0, True1); | |||||
461 | GRABEXT(pNewGrab)((XtServerGrabExtPtr)((pNewGrab)+1))->pModifiersMask = | |||||
462 | CopyDetailMask(ext->pModifiersMask); | |||||
463 | ||||||
464 | DeleteDetailFromMask(&GRABEXT(pNewGrab)((XtServerGrabExtPtr)((pNewGrab)+1))->pModifiersMask, | |||||
465 | pMinuendGrab->modifiers); | |||||
466 | ||||||
467 | pNewGrab->next = *passiveListPtr; | |||||
468 | *passiveListPtr = pNewGrab; | |||||
469 | } else if (pMinuendGrab->keybut == AnyKey0L) { | |||||
470 | /* | |||||
471 | * The list entry has keycode AnyKey and modifier | |||||
472 | * AnyModifier; the entry being deleted has | |||||
473 | * keycode AnyKey and specific modifiers. So we | |||||
474 | * simply need to mask off the specified modifier | |||||
475 | * combination. | |||||
476 | */ | |||||
477 | DeleteDetailFromMask(&ext->pModifiersMask, | |||||
478 | pMinuendGrab->modifiers); | |||||
479 | } else { | |||||
480 | /* | |||||
481 | * The list entry has keycode AnyKey and modifier | |||||
482 | * AnyModifier; the entry being deleted has a | |||||
483 | * specific keycode and modifier AnyModifier. So | |||||
484 | * we simply need to mask off the specified | |||||
485 | * keycode. | |||||
486 | */ | |||||
487 | DeleteDetailFromMask(&ext->pKeyButMask, pMinuendGrab->keybut); | |||||
488 | } | |||||
489 | } | |||||
490 | next = &(*next)->next; | |||||
491 | } | |||||
492 | } | |||||
493 | ||||||
494 | static void DestroyPassiveList( | |||||
495 | XtServerGrabPtr *passiveListPtr) | |||||
496 | { | |||||
497 | XtServerGrabPtr next, grab; | |||||
498 | ||||||
499 | for (next = *passiveListPtr; next; ) { | |||||
500 | grab = next; | |||||
501 | next = grab->next; | |||||
502 | ||||||
503 | /* not necessary to explicitly ungrab key or button; | |||||
504 | * window is being destroyed so server will take care of it. | |||||
505 | */ | |||||
506 | ||||||
507 | FreeGrab(grab); | |||||
508 | } | |||||
509 | } | |||||
510 | ||||||
511 | ||||||
512 | /* | |||||
513 | * This function is called at widget destroy time to clean up | |||||
514 | */ | |||||
515 | /*ARGSUSED*/ | |||||
516 | void _XtDestroyServerGrabs( | |||||
517 | Widget w, | |||||
518 | XtPointer closure, | |||||
519 | XtPointer call_data) /* unused */ | |||||
520 | { | |||||
521 | XtPerWidgetInput pwi = (XtPerWidgetInput)closure; | |||||
522 | XtPerDisplayInput pdi; | |||||
523 | ||||||
524 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||||
525 | pdi = _XtGetPerDisplayInput(XtDisplay(w)(((w)->core.screen)->display)); | |||||
526 | _XtClearAncestorCache(w); | |||||
527 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||||
528 | ||||||
529 | /* Remove the active grab, if necessary */ | |||||
530 | if ((pdi->keyboard.grabType != XtNoServerGrab) && | |||||
531 | (pdi->keyboard.grab.widget == w)) { | |||||
532 | pdi->keyboard.grabType = XtNoServerGrab; | |||||
533 | pdi->activatingKey = (KeyCode)0; | |||||
534 | } | |||||
535 | if ((pdi->pointer.grabType != XtNoServerGrab) && | |||||
536 | (pdi->pointer.grab.widget == w)) | |||||
537 | pdi->pointer.grabType = XtNoServerGrab; | |||||
538 | ||||||
539 | DestroyPassiveList(&pwi->keyList); | |||||
540 | DestroyPassiveList(&pwi->ptrList); | |||||
541 | ||||||
542 | _XtFreePerWidgetInput(w, pwi); | |||||
543 | } | |||||
544 | ||||||
545 | /* | |||||
546 | * If the incoming event is on the passive grab list, then activate | |||||
547 | * the grab. The grab will remain in effect until the key is released. | |||||
548 | */ | |||||
549 | ||||||
550 | XtServerGrabPtr _XtCheckServerGrabsOnWidget ( | |||||
551 | XEvent *event, | |||||
552 | Widget widget, | |||||
553 | _XtBooleanint isKeyboard) | |||||
554 | { | |||||
555 | register XtServerGrabPtr grab; | |||||
556 | XtServerGrabRec tempGrab; | |||||
557 | XtServerGrabPtr *passiveListPtr; | |||||
558 | XtPerWidgetInput pwi; | |||||
559 | ||||||
560 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||||
561 | pwi = _XtGetPerWidgetInput(widget, FALSE0); | |||||
562 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||||
563 | if (!pwi) | |||||
564 | return (XtServerGrabPtr)NULL((void*)0); | |||||
565 | if (isKeyboard) | |||||
566 | passiveListPtr = &pwi->keyList; | |||||
567 | else | |||||
568 | passiveListPtr = &pwi->ptrList; | |||||
569 | ||||||
570 | /* | |||||
571 | * if either there is no entry in the context manager or the entry | |||||
572 | * is empty, or the keyboard is grabed, then no work to be done | |||||
573 | */ | |||||
574 | if (!*passiveListPtr) | |||||
575 | return (XtServerGrabPtr)NULL((void*)0); | |||||
576 | ||||||
577 | /* Take only the lower thirteen bits as modifier state. The X Keyboard | |||||
578 | * Extension may be representing keyboard group state in two upper bits. | |||||
579 | */ | |||||
580 | tempGrab.widget = widget; | |||||
581 | tempGrab.keybut = event->xkey.keycode; /* also xbutton.button */ | |||||
582 | tempGrab.modifiers = event->xkey.state & 0x1FFF; /*also xbutton.state*/ | |||||
583 | tempGrab.hasExt = False0; | |||||
584 | ||||||
585 | for (grab = *passiveListPtr; grab; grab = grab->next) { | |||||
586 | if (GrabMatchesSecond(&tempGrab, grab)) | |||||
587 | return (grab); | |||||
588 | } | |||||
589 | return (XtServerGrabPtr)NULL((void*)0); | |||||
590 | } | |||||
591 | ||||||
592 | /* | |||||
593 | * This handler is needed to guarantee that we see releases on passive | |||||
594 | * button grabs for widgets that haven't selected for button release. | |||||
595 | */ | |||||
596 | ||||||
597 | /*ARGSUSED*/ | |||||
598 | static void ActiveHandler ( | |||||
599 | Widget widget, | |||||
600 | XtPointer pdi, | |||||
601 | XEvent *event, | |||||
602 | Boolean *cont) | |||||
603 | { | |||||
604 | /* nothing */ | |||||
605 | } | |||||
606 | ||||||
607 | ||||||
608 | /* | |||||
609 | * MakeGrab | |||||
610 | */ | |||||
611 | static void MakeGrab( | |||||
612 | XtServerGrabPtr grab, | |||||
613 | XtServerGrabPtr *passiveListPtr, | |||||
614 | Boolean isKeyboard, | |||||
615 | XtPerDisplayInput pdi, | |||||
616 | XtPerWidgetInput pwi) | |||||
617 | { | |||||
618 | if (!isKeyboard && !pwi->active_handler_added) { | |||||
619 | XtAddEventHandler(grab->widget, ButtonReleaseMask(1L<<3), FALSE0, | |||||
620 | ActiveHandler, (XtPointer)pdi); | |||||
621 | pwi->active_handler_added = TRUE1; | |||||
622 | } | |||||
623 | ||||||
624 | if (isKeyboard) { | |||||
625 | XGrabKey(pDisplay(grab)(((grab)->widget)->core.screen->display), | |||||
626 | grab->keybut, grab->modifiers, | |||||
627 | pWindow(grab)(((grab)->widget)->core.window), grab->ownerEvents, | |||||
628 | grab->pointerMode, grab->keyboardMode); | |||||
629 | } else { | |||||
630 | Window confineTo = None0L; | |||||
631 | Cursor cursor = None0L; | |||||
632 | ||||||
633 | if (grab->hasExt) { | |||||
634 | if (grab->confineToIsWidgetWin) | |||||
635 | confineTo = XtWindow (grab->widget)((grab->widget)->core.window); | |||||
636 | else | |||||
637 | confineTo = GRABEXT(grab)((XtServerGrabExtPtr)((grab)+1))->confineTo; | |||||
638 | cursor = GRABEXT(grab)((XtServerGrabExtPtr)((grab)+1))->cursor; | |||||
639 | } | |||||
640 | XGrabButton(pDisplay(grab)(((grab)->widget)->core.screen->display), | |||||
641 | grab->keybut, grab->modifiers, | |||||
642 | pWindow(grab)(((grab)->widget)->core.window), grab->ownerEvents, grab->eventMask, | |||||
643 | grab->pointerMode, grab->keyboardMode, | |||||
644 | confineTo, cursor); | |||||
645 | } | |||||
646 | ||||||
647 | /* Add the new grab entry to the passive key grab list */ | |||||
648 | grab->next = *passiveListPtr; | |||||
649 | *passiveListPtr = grab; | |||||
650 | } | |||||
651 | ||||||
652 | static void MakeGrabs( | |||||
653 | XtServerGrabPtr *passiveListPtr, | |||||
654 | Boolean isKeyboard, | |||||
655 | XtPerDisplayInput pdi) | |||||
656 | { | |||||
657 | XtServerGrabPtr next = *passiveListPtr; | |||||
658 | XtServerGrabPtr grab; | |||||
659 | XtPerWidgetInput pwi; | |||||
660 | /* | |||||
661 | * make MakeGrab build a new list that has had the merge | |||||
662 | * processing done on it. Start with an empty list | |||||
663 | * (passiveListPtr). | |||||
664 | */ | |||||
665 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||||
666 | *passiveListPtr = NULL((void*)0); | |||||
667 | while (next) | |||||
668 | { | |||||
669 | grab = next; | |||||
670 | next = grab->next; | |||||
671 | pwi = _XtGetPerWidgetInput(grab->widget, FALSE0); | |||||
672 | MakeGrab(grab, passiveListPtr, isKeyboard, pdi, pwi); | |||||
673 | } | |||||
674 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||||
675 | } | |||||
676 | ||||||
677 | /* | |||||
678 | * This function is the event handler attached to the associated widget | |||||
679 | * when grabs need to be added, but the widget is not yet realized. When | |||||
680 | * it is first mapped, this handler will be invoked, and it will add all | |||||
681 | * needed grabs. | |||||
682 | */ | |||||
683 | ||||||
684 | /*ARGSUSED*/ | |||||
685 | static void RealizeHandler ( | |||||
686 | Widget widget, | |||||
687 | XtPointer closure, | |||||
688 | XEvent *event, /* unused */ | |||||
689 | Boolean *cont) /* unused */ | |||||
690 | { | |||||
691 | XtPerWidgetInput pwi = (XtPerWidgetInput)closure; | |||||
692 | XtPerDisplayInput pdi; | |||||
693 | ||||||
694 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||||
695 | pdi = _XtGetPerDisplayInput(XtDisplay(widget)(((widget)->core.screen)->display)); | |||||
696 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||||
697 | MakeGrabs(&pwi->keyList, KEYBOARD1, pdi); | |||||
698 | MakeGrabs(&pwi->ptrList, POINTER0, pdi); | |||||
699 | ||||||
700 | XtRemoveEventHandler(widget, XtAllEvents((EventMask) -1L), True1, | |||||
701 | RealizeHandler, (XtPointer)pwi); | |||||
702 | pwi->realize_handler_added = FALSE0; | |||||
703 | } | |||||
704 | ||||||
705 | /***************************************************************************/ | |||||
706 | /**************************** Global Routines ******************************/ | |||||
707 | /***************************************************************************/ | |||||
708 | ||||||
709 | ||||||
710 | /* | |||||
711 | * Routine used by an application to set up a passive grab for a key/modifier | |||||
712 | * combination. | |||||
713 | */ | |||||
714 | ||||||
715 | static | |||||
716 | void GrabKeyOrButton ( | |||||
717 | Widget widget, | |||||
718 | KeyCode keyOrButton, | |||||
719 | Modifiers modifiers, | |||||
720 | Boolean owner_events, | |||||
721 | int pointer_mode, | |||||
722 | int keyboard_mode, | |||||
723 | Mask event_mask, | |||||
724 | Window confine_to, | |||||
725 | Cursor cursor, | |||||
726 | Boolean isKeyboard) | |||||
727 | { | |||||
728 | XtServerGrabPtr *passiveListPtr; | |||||
729 | XtServerGrabPtr newGrab; | |||||
730 | XtPerWidgetInput pwi; | |||||
731 | XtPerDisplayInput pdi; | |||||
732 | ||||||
733 | ||||||
734 | XtCheckSubclass(widget, coreWidgetClass, "in XtGrabKey or XtGrabButton"); | |||||
735 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||||
736 | pwi = _XtGetPerWidgetInput(widget, TRUE1); | |||||
737 | if (isKeyboard) | |||||
738 | passiveListPtr = &pwi->keyList; | |||||
739 | else | |||||
740 | passiveListPtr = &pwi->ptrList; | |||||
741 | pdi = _XtGetPerDisplayInput(XtDisplay(widget)(((widget)->core.screen)->display)); | |||||
742 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||||
743 | newGrab = CreateGrab(widget, owner_events, modifiers, | |||||
744 | keyOrButton, pointer_mode, keyboard_mode, | |||||
745 | event_mask, confine_to, cursor, False0); | |||||
746 | /* | |||||
747 | * if the widget is realized then process the entry into the grab | |||||
748 | * list. else if the list is empty (i.e. first time) then add the | |||||
749 | * event handler. then add the raw entry to the list for processing | |||||
750 | * in the handler at realize time. | |||||
751 | */ | |||||
752 | if (XtIsRealized(widget)((((((Object)(widget))->object.widget_class->core_class .class_inited & 0x04) ? (widget) : _XtWindowedAncestor(widget )) ->core.window) != 0L)) | |||||
753 | MakeGrab(newGrab, passiveListPtr, isKeyboard, pdi, pwi); | |||||
754 | else { | |||||
755 | if (!pwi->realize_handler_added) | |||||
756 | { | |||||
757 | XtAddEventHandler(widget, StructureNotifyMask(1L<<17), FALSE0, | |||||
758 | RealizeHandler, | |||||
759 | (XtPointer)pwi); | |||||
760 | pwi->realize_handler_added = TRUE1; | |||||
761 | } | |||||
762 | ||||||
763 | while (*passiveListPtr) | |||||
764 | passiveListPtr = &(*passiveListPtr)->next; | |||||
765 | *passiveListPtr = newGrab; | |||||
766 | } | |||||
767 | } | |||||
768 | ||||||
769 | ||||||
770 | static | |||||
771 | void UngrabKeyOrButton ( | |||||
772 | Widget widget, | |||||
773 | int keyOrButton, | |||||
774 | Modifiers modifiers, | |||||
775 | Boolean isKeyboard) | |||||
776 | { | |||||
777 | XtServerGrabRec tempGrab; | |||||
778 | XtPerWidgetInput pwi; | |||||
779 | ||||||
780 | XtCheckSubclass(widget, coreWidgetClass, | |||||
781 | "in XtUngrabKey or XtUngrabButton"); | |||||
782 | ||||||
783 | /* Build a temporary grab list entry */ | |||||
784 | tempGrab.widget = widget; | |||||
785 | tempGrab.modifiers = modifiers; | |||||
786 | tempGrab.keybut = keyOrButton; | |||||
787 | tempGrab.hasExt = False0; | |||||
788 | ||||||
789 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||||
790 | pwi = _XtGetPerWidgetInput(widget, FALSE0); | |||||
791 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||||
792 | /* | |||||
793 | * if there is no entry in the context manager then somethings wrong | |||||
794 | */ | |||||
795 | if (!pwi) | |||||
796 | { | |||||
797 | XtAppWarningMsg(XtWidgetToApplicationContext(widget), | |||||
798 | "invalidGrab", "ungrabKeyOrButton", XtCXtToolkitError, | |||||
799 | "Attempt to remove nonexistent passive grab", | |||||
800 | (String *)NULL((void*)0), (Cardinal *)NULL((void*)0)); | |||||
801 | return; | |||||
802 | } | |||||
803 | ||||||
804 | if (XtIsRealized(widget)((((((Object)(widget))->object.widget_class->core_class .class_inited & 0x04) ? (widget) : _XtWindowedAncestor(widget )) ->core.window) != 0L)) | |||||
| ||||||
805 | { | |||||
806 | if (isKeyboard) | |||||
807 | XUngrabKey(widget->core.screen->display, | |||||
808 | keyOrButton, (unsigned int)modifiers, | |||||
809 | widget->core.window); | |||||
810 | else | |||||
811 | XUngrabButton(widget->core.screen->display, | |||||
812 | keyOrButton, (unsigned int)modifiers, | |||||
813 | widget->core.window); | |||||
814 | } | |||||
815 | ||||||
816 | ||||||
817 | /* Delete all entries which are encompassed by the specified grab. */ | |||||
818 | DeleteServerGrabFromList(isKeyboard ? &pwi->keyList : &pwi->ptrList, | |||||
819 | &tempGrab); | |||||
820 | } | |||||
821 | ||||||
822 | void XtGrabKey ( | |||||
823 | Widget widget, | |||||
824 | _XtKeyCodeunsigned int keycode, | |||||
825 | Modifiers modifiers, | |||||
826 | _XtBooleanint owner_events, | |||||
827 | int pointer_mode, | |||||
828 | int keyboard_mode) | |||||
829 | { | |||||
830 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); | |||||
831 | ||||||
832 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | |||||
833 | GrabKeyOrButton(widget, (KeyCode)keycode, modifiers, owner_events, | |||||
834 | pointer_mode, keyboard_mode, | |||||
835 | (Mask)0, (Window)None0L, (Cursor)None0L, KEYBOARD1); | |||||
836 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||||
837 | } | |||||
838 | ||||||
839 | void XtGrabButton( | |||||
840 | Widget widget, | |||||
841 | int button, | |||||
842 | Modifiers modifiers, | |||||
843 | _XtBooleanint owner_events, | |||||
844 | unsigned int event_mask, | |||||
845 | int pointer_mode, | |||||
846 | int keyboard_mode, | |||||
847 | Window confine_to, | |||||
848 | Cursor cursor) | |||||
849 | { | |||||
850 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); | |||||
851 | ||||||
852 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | |||||
853 | GrabKeyOrButton(widget, (KeyCode)button, modifiers, owner_events, | |||||
854 | pointer_mode, keyboard_mode, | |||||
855 | (Mask)event_mask, confine_to, cursor, POINTER0); | |||||
856 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||||
857 | } | |||||
858 | ||||||
859 | ||||||
860 | /* | |||||
861 | * Routine used by an application to clear a passive grab for a key/modifier | |||||
862 | * combination. | |||||
863 | */ | |||||
864 | ||||||
865 | void XtUngrabKey ( | |||||
866 | Widget widget, | |||||
867 | _XtKeyCodeunsigned int keycode, | |||||
868 | Modifiers modifiers) | |||||
869 | { | |||||
870 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); | |||||
871 | ||||||
872 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | |||||
873 | UngrabKeyOrButton(widget, (int)keycode, modifiers, KEYBOARD1); | |||||
874 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||||
875 | } | |||||
876 | ||||||
877 | void XtUngrabButton ( | |||||
878 | Widget widget, | |||||
879 | unsigned int button, | |||||
880 | Modifiers modifiers) | |||||
881 | { | |||||
882 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); | |||||
| ||||||
883 | ||||||
884 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | |||||
885 | UngrabKeyOrButton(widget, (KeyCode)button, modifiers, POINTER0); | |||||
886 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||||
887 | } | |||||
888 | ||||||
889 | /* | |||||
890 | * Active grab of Device. clear any client side grabs so we dont lock | |||||
891 | */ | |||||
892 | static int GrabDevice ( | |||||
893 | Widget widget, | |||||
894 | Boolean owner_events, | |||||
895 | int pointer_mode, | |||||
896 | int keyboard_mode, | |||||
897 | Mask event_mask, | |||||
898 | Window confine_to, | |||||
899 | Cursor cursor, | |||||
900 | Time time, | |||||
901 | Boolean isKeyboard) | |||||
902 | { | |||||
903 | XtPerDisplayInput pdi; | |||||
904 | int returnVal; | |||||
905 | ||||||
906 | XtCheckSubclass(widget, coreWidgetClass, | |||||
907 | "in XtGrabKeyboard or XtGrabPointer"); | |||||
908 | if (!XtIsRealized(widget)((((((Object)(widget))->object.widget_class->core_class .class_inited & 0x04) ? (widget) : _XtWindowedAncestor(widget )) ->core.window) != 0L)) | |||||
909 | return GrabNotViewable3; | |||||
910 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||||
911 | pdi = _XtGetPerDisplayInput(XtDisplay(widget)(((widget)->core.screen)->display)); | |||||
912 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||||
913 | if (!isKeyboard) | |||||
914 | returnVal = XGrabPointer(XtDisplay(widget)(((widget)->core.screen)->display), XtWindow(widget)((widget)->core.window), | |||||
915 | owner_events, event_mask, | |||||
916 | pointer_mode, keyboard_mode, | |||||
917 | confine_to, cursor, time); | |||||
918 | else | |||||
919 | returnVal = XGrabKeyboard(XtDisplay(widget)(((widget)->core.screen)->display), XtWindow(widget)((widget)->core.window), | |||||
920 | owner_events, pointer_mode, | |||||
921 | keyboard_mode, time); | |||||
922 | ||||||
923 | if (returnVal == GrabSuccess0) { | |||||
924 | XtDevice device; | |||||
925 | ||||||
926 | device = isKeyboard ? &pdi->keyboard : &pdi->pointer; | |||||
927 | /* fill in the server grab rec */ | |||||
928 | device->grab.widget = widget; | |||||
929 | device->grab.modifiers = 0; | |||||
930 | device->grab.keybut = 0; | |||||
931 | device->grab.ownerEvents = owner_events; | |||||
932 | device->grab.pointerMode = pointer_mode; | |||||
933 | device->grab.keyboardMode = keyboard_mode; | |||||
934 | device->grab.hasExt = False0; | |||||
935 | device->grabType = XtActiveServerGrab; | |||||
936 | pdi->activatingKey = (KeyCode)0; | |||||
937 | } | |||||
938 | return returnVal; | |||||
939 | } | |||||
940 | ||||||
941 | static void UngrabDevice( | |||||
942 | Widget widget, | |||||
943 | Time time, | |||||
944 | Boolean isKeyboard) | |||||
945 | { | |||||
946 | XtPerDisplayInput pdi; | |||||
947 | XtDevice device; | |||||
948 | ||||||
949 | LOCK_PROCESSif(_XtProcessLock)(*_XtProcessLock)(); | |||||
950 | pdi = _XtGetPerDisplayInput(XtDisplay(widget)(((widget)->core.screen)->display)); | |||||
951 | UNLOCK_PROCESSif(_XtProcessUnlock)(*_XtProcessUnlock)(); | |||||
952 | device = isKeyboard ? &pdi->keyboard : &pdi->pointer; | |||||
953 | XtCheckSubclass(widget, coreWidgetClass, | |||||
954 | "in XtUngrabKeyboard or XtUngrabPointer"); | |||||
955 | ||||||
956 | if (device->grabType != XtNoServerGrab) { | |||||
957 | ||||||
958 | if (device->grabType != XtPseudoPassiveServerGrab | |||||
959 | && XtIsRealized(widget)((((((Object)(widget))->object.widget_class->core_class .class_inited & 0x04) ? (widget) : _XtWindowedAncestor(widget )) ->core.window) != 0L)) { | |||||
960 | if (isKeyboard) | |||||
961 | XUngrabKeyboard(XtDisplay(widget)(((widget)->core.screen)->display), time); | |||||
962 | else | |||||
963 | XUngrabPointer(XtDisplay(widget)(((widget)->core.screen)->display), time); | |||||
964 | } | |||||
965 | device->grabType = XtNoServerGrab; | |||||
966 | pdi->activatingKey = (KeyCode)0; | |||||
967 | } | |||||
968 | } | |||||
969 | ||||||
970 | ||||||
971 | /* | |||||
972 | * Active grab of keyboard. clear any client side grabs so we dont lock | |||||
973 | */ | |||||
974 | int XtGrabKeyboard ( | |||||
975 | Widget widget, | |||||
976 | _XtBooleanint owner_events, | |||||
977 | int pointer_mode, | |||||
978 | int keyboard_mode, | |||||
979 | Time time) | |||||
980 | { | |||||
981 | int retval; | |||||
982 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); | |||||
983 | ||||||
984 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | |||||
985 | retval = GrabDevice (widget, owner_events, | |||||
986 | pointer_mode, keyboard_mode, | |||||
987 | (Mask)0, (Window)None0L, (Cursor)None0L, time, KEYBOARD1); | |||||
988 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||||
989 | return retval; | |||||
990 | } | |||||
991 | ||||||
992 | ||||||
993 | /* | |||||
994 | * Ungrab the keyboard | |||||
995 | */ | |||||
996 | ||||||
997 | void XtUngrabKeyboard( | |||||
998 | Widget widget, | |||||
999 | Time time) | |||||
1000 | { | |||||
1001 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); | |||||
1002 | ||||||
1003 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | |||||
1004 | UngrabDevice(widget, time, KEYBOARD1); | |||||
1005 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||||
1006 | } | |||||
1007 | ||||||
1008 | ||||||
1009 | ||||||
1010 | ||||||
1011 | /* | |||||
1012 | * grab the pointer | |||||
1013 | */ | |||||
1014 | int XtGrabPointer ( | |||||
1015 | Widget widget, | |||||
1016 | _XtBooleanint owner_events, | |||||
1017 | unsigned int event_mask, | |||||
1018 | int pointer_mode, | |||||
1019 | int keyboard_mode, | |||||
1020 | Window confine_to, | |||||
1021 | Cursor cursor, | |||||
1022 | Time time) | |||||
1023 | { | |||||
1024 | int retval; | |||||
1025 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); | |||||
1026 | ||||||
1027 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | |||||
1028 | retval = GrabDevice (widget, owner_events, | |||||
1029 | pointer_mode, keyboard_mode, | |||||
1030 | (Mask)event_mask, confine_to, | |||||
1031 | cursor, time, POINTER0); | |||||
1032 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||||
1033 | return retval; | |||||
1034 | } | |||||
1035 | ||||||
1036 | ||||||
1037 | /* | |||||
1038 | * Ungrab the pointer | |||||
1039 | */ | |||||
1040 | ||||||
1041 | void XtUngrabPointer( | |||||
1042 | Widget widget, | |||||
1043 | Time time) | |||||
1044 | { | |||||
1045 | WIDGET_TO_APPCON(widget)XtAppContext app = (widget && _XtProcessLock ? XtWidgetToApplicationContext (widget) : ((void*)0)); | |||||
1046 | ||||||
1047 | LOCK_APP(app)if(app && app->lock)(*app->lock)(app); | |||||
1048 | UngrabDevice(widget, time, POINTER0); | |||||
1049 | UNLOCK_APP(app)if(app && app->unlock)(*app->unlock)(app); | |||||
1050 | } | |||||
1051 | ||||||
1052 | ||||||
1053 | void _XtRegisterPassiveGrabs ( | |||||
1054 | Widget widget) | |||||
1055 | { | |||||
1056 | XtPerWidgetInput pwi = _XtGetPerWidgetInput (widget, FALSE0); | |||||
1057 | ||||||
1058 | if (pwi != NULL((void*)0) && !pwi->realize_handler_added) { | |||||
1059 | XtAddEventHandler(widget, StructureNotifyMask(1L<<17), FALSE0, | |||||
1060 | RealizeHandler, | |||||
1061 | (XtPointer)pwi); | |||||
1062 | pwi->realize_handler_added = TRUE1; | |||||
1063 | } | |||||
1064 | } |