| File: | src/PassivGrab.c |
| Location: | line 908, column 10 |
| 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 | } |