|
|
1.1 ! root 1: /************************************************************ ! 2: Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, ! 3: and the Massachusetts Institute of Technology, Cambridge, Massachusetts. ! 4: ! 5: All Rights Reserved ! 6: ! 7: Permission to use, copy, modify, and distribute this software and its ! 8: documentation for any purpose and without fee is hereby granted, ! 9: provided that the above copyright notice appear in all copies and that ! 10: both that copyright notice and this permission notice appear in ! 11: supporting documentation, and that the names of Digital or MIT not be ! 12: used in advertising or publicity pertaining to distribution of the ! 13: software without specific, written prior permission. ! 14: ! 15: DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ! 16: ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL ! 17: DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ! 18: ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, ! 19: WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ! 20: ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ! 21: SOFTWARE. ! 22: ! 23: ********************************************************/ ! 24: ! 25: ! 26: /* $Header: events.c,v 1.108 87/09/09 10:18:23 toddb Exp $ */ ! 27: ! 28: #include "X.h" ! 29: #include "misc.h" ! 30: #include "resource.h" ! 31: #define NEED_EVENTS ! 32: #define NEED_REPLIES ! 33: #include "Xproto.h" ! 34: #include "windowstr.h" ! 35: #include "inputstr.h" ! 36: #include "scrnintstr.h" ! 37: #include "cursorstr.h" ! 38: ! 39: #include "dixstruct.h" ! 40: ! 41: extern WindowRec WindowTable[]; ! 42: ! 43: extern void (* EventSwapVector[128]) (); ! 44: extern void (* ReplySwapVector[256]) (); ! 45: extern void CopySwap32Write(), SwapTimeCoordWrite(); ! 46: ! 47: #define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */ ! 48: #define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask ) ! 49: #define AllButtonsMask ( \ ! 50: Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask ) ! 51: #define MotionMask ( \ ! 52: PointerMotionMask | PointerMotionHintMask | Button1MotionMask | \ ! 53: Button2MotionMask | Button3MotionMask | Button4MotionMask | \ ! 54: Button5MotionMask | ButtonMotionMask ) ! 55: #define PropagateMask ( \ ! 56: KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \ ! 57: MotionMask ) ! 58: #define AllModifiersMask ( \ ! 59: ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \ ! 60: Mod3Mask | Mod4Mask | Mod5Mask ) ! 61: #define Motion_Filter(state) (PointerMotionMask | \ ! 62: (AllButtonsMask & state) | buttonMotionMask) ! 63: ! 64: ! 65: #define WID(w) ((w) ? ((w)->wid) : 0) ! 66: ! 67: #define IsOn(ptr, bit) \ ! 68: (((BYTE *) (ptr))[(bit)>>3] & (1 << ((bit) & 7))) ! 69: ! 70: static debug_events = 0; ! 71: static debug_modifiers = 0; ! 72: static InputInfo inputInfo; ! 73: ! 74: static int keyThatActivatedPassiveGrab; /* The key that activated the ! 75: current passive grab must be ! 76: recorded, so that the grab may ! 77: be deactivated upon that key's ! 78: release. PRH ! 79: */ ! 80: ! 81: static lastInputFocusChangeMode = NotifyNormal; /* Useful for avoiding sending ! 82: focus events when the input ! 83: focus is sent twice to the ! 84: same window. PRH ! 85: */ ! 86: ! 87: static KeySymsRec curKeySyms; ! 88: ! 89: static GrabRec keybdGrab; /* used for active grabs */ ! 90: static GrabRec ptrGrab; ! 91: ! 92: #define MAX_QUEUED_EVENTS 100 ! 93: static struct { ! 94: unsigned int num; ! 95: QdEventRec pending, free; /* only forw, back used */ ! 96: DeviceIntPtr replayDev; /* kludgy rock to put flag for */ ! 97: WindowPtr replayWin; /* ComputeFreezes */ ! 98: Bool playingEvents; ! 99: } syncEvents; ! 100: ! 101: /* ! 102: * The window trace information is used to avoid having to compute all the ! 103: * windows between the root and the current pointer window each time a button ! 104: * or key goes down. The grabs on each of those windows must be checked. ! 105: */ ! 106: static WindowPtr *spriteTrace = (WindowPtr *)NULL; ! 107: #define ROOT spriteTrace[0] ! 108: static int spriteTraceSize = 0; ! 109: static int spriteTraceGood; ! 110: ! 111: static WindowPtr *focusTrace = (WindowPtr *)NULL; ! 112: static int focusTraceSize = 0; ! 113: static int focusTraceGood; ! 114: ! 115: static CARD16 keyButtonState = 0; ! 116: /* ! 117: * For each modifier, we keep a count of the number of keys that ! 118: * are currently setting it. ! 119: */ ! 120: static int modifierKeyCount[8]; ! 121: static int buttonsDown = 0; /* number of buttons currently down */ ! 122: static Mask buttonMotionMask = 0; ! 123: ! 124: typedef struct { ! 125: int x, y; ! 126: } HotSpot; ! 127: ! 128: static struct { ! 129: CursorPtr current; ! 130: BoxRec hotLimits; /* logical constraints */ ! 131: BoxRec physLimits; /* of hot spot due to hardware limits */ ! 132: WindowPtr win; ! 133: HotSpot hot; ! 134: } sprite; /* info about the cursor sprite */ ! 135: ! 136: static Bool lastWasMotion; ! 137: ! 138: extern void DoEnterLeaveEvents(); /* merely forward declarations */ ! 139: extern WindowPtr XYToWindow(); ! 140: extern Bool CheckKeyboardGrabs(); ! 141: extern void NormalKeyboardEvent(); ! 142: extern int DeliverDeviceEvents(); ! 143: extern void DoFocusEvents(); ! 144: ! 145: extern GrabPtr CreateGrab(); /* Defined in grabs.c */ ! 146: extern void DeleteGrab(); ! 147: extern BOOL GrabMatchesSecond(); ! 148: extern void DeletePassiveGrabsFromList(); ! 149: extern void AddPassiveGrabToWindowList(); ! 150: ! 151: static ScreenPtr currentScreen; ! 152: ! 153: /* ! 154: * For each key, we keep a bitmap showing the modifiers it sets ! 155: * This is a CARD16 bitmap 'cos it includes the mouse buttons to ! 156: * make grab processing simpler. ! 157: */ ! 158: static CARD16 keyModifiersList[MAP_LENGTH]; ! 159: static CARD16 maxKeysPerModifier; ! 160: /* ! 161: * We also keep a copy of the modifier map in the format ! 162: * used by the protocol. ! 163: */ ! 164: static KeyCode *modifierKeyMap; ! 165: ! 166: static int lastEventMask; ! 167: ! 168: #define CantBeFiltered NoEventMask ! 169: static int filters[128] = ! 170: { ! 171: NoSuchEvent, /* 0 */ ! 172: NoSuchEvent, /* 1 */ ! 173: KeyPressMask, /* KeyPress */ ! 174: KeyReleaseMask, /* KeyRelease */ ! 175: ButtonPressMask, /* ButtonPress */ ! 176: ButtonReleaseMask, /* ButtonRelease */ ! 177: MotionMask, /* MotionNotify - special cased */ ! 178: EnterWindowMask, /* EnterNotify */ ! 179: LeaveWindowMask, /* LeaveNotify */ ! 180: FocusChangeMask, /* FocusIn */ ! 181: FocusChangeMask, /* FocusOut */ ! 182: KeymapStateMask, /* KeymapNotify */ ! 183: ExposureMask, /* Expose */ ! 184: CantBeFiltered, /* GraphicsExpose */ ! 185: CantBeFiltered, /* NoExpose */ ! 186: VisibilityChangeMask, /* VisibilityNotify */ ! 187: SubstructureNotifyMask, /* CreateNotify */ ! 188: StructureAndSubMask, /* DestroyNotify */ ! 189: StructureAndSubMask, /* UnmapNotify */ ! 190: StructureAndSubMask, /* MapNotify */ ! 191: SubstructureRedirectMask, /* MapRequest */ ! 192: SubstructureNotifyMask, /* ReparentNotify */ ! 193: StructureAndSubMask, /* ConfigureNotify */ ! 194: SubstructureRedirectMask, /* ConfigureRequest */ ! 195: StructureAndSubMask, /* GravityNotify */ ! 196: ResizeRedirectMask, /* ResizeRequest */ ! 197: StructureAndSubMask, /* CirculateNotify */ ! 198: SubstructureRedirectMask, /* CirculateRequest */ ! 199: PropertyChangeMask, /* PropertyNotify */ ! 200: CantBeFiltered, /* SelectionClear */ ! 201: CantBeFiltered, /* SelectionRequest */ ! 202: CantBeFiltered, /* SelectionNotify */ ! 203: ColormapChangeMask, /* ColormapNotify */ ! 204: CantBeFiltered /* InterpretNotify */ ! 205: }; ! 206: ! 207: Mask ! 208: GetNextEventMask() ! 209: { ! 210: lastEventMask <<= 1; ! 211: return lastEventMask; ! 212: } ! 213: ! 214: void ! 215: SetMaskForEvent(mask, event) ! 216: Mask mask; ! 217: int event; ! 218: { ! 219: if ((event < LASTEvent) || (event >= 128)) ! 220: FatalError("MaskForEvent: bogus event number"); ! 221: filters[event] = mask; ! 222: } ! 223: ! 224: static void ! 225: CheckPhysLimits(cursor) ! 226: CursorPtr cursor; ! 227: { ! 228: HotSpot old; ! 229: ! 230: if (!cursor) ! 231: return; ! 232: old = sprite.hot; ! 233: (*currentScreen->CursorLimits) ( ! 234: currentScreen, cursor, &sprite.hotLimits, &sprite.physLimits); ! 235: /* ! 236: * Notice that the following adjustments leave the hot spot not really where ! 237: * it would be if you looked at the screen. This is probably the right thing ! 238: * to do since the user does not want the hot spot to move just because the ! 239: * hardware cannot display the physical sprite where we would like it. The ! 240: * next time the pointer device moves, the hot spot will then "jump" to its ! 241: * visual position. ! 242: */ ! 243: if (sprite.hot.x < sprite.physLimits.x1) ! 244: sprite.hot.x = sprite.physLimits.x1; ! 245: else ! 246: if (sprite.hot.x >= sprite.physLimits.x2) ! 247: sprite.hot.x = sprite.physLimits.x2 - 1; ! 248: if (sprite.hot.y < sprite.physLimits.y1) ! 249: sprite.hot.y = sprite.physLimits.y1; ! 250: else ! 251: if (sprite.hot.y >= sprite.physLimits.y2) ! 252: sprite.hot.y = sprite.physLimits.y2 - 1; ! 253: if ((old.x != sprite.hot.x) || (old.y != sprite.hot.y)) ! 254: (*currentScreen->SetCursorPosition) ( ! 255: currentScreen, sprite.hot.x, sprite.hot.y, FALSE); ! 256: } ! 257: ! 258: static void ! 259: NewCursorConfines(x1, x2, y1, y2) ! 260: int x1, x2, y1, y2; ! 261: { ! 262: sprite.hotLimits.x1 = x1; ! 263: sprite.hotLimits.x2 = x2; ! 264: sprite.hotLimits.y1 = y1; ! 265: sprite.hotLimits.y2 = y2; ! 266: CheckPhysLimits(sprite.current); ! 267: (* currentScreen->ConstrainCursor)(currentScreen, &sprite.physLimits); ! 268: } ! 269: ! 270: static void ! 271: ChangeToCursor(cursor) ! 272: CursorPtr cursor; ! 273: { ! 274: if (!cursor) ! 275: FatalError("Somebody is setting NullCursor"); ! 276: if (cursor != sprite.current) ! 277: { ! 278: if ((sprite.current->xhot != cursor->xhot) || ! 279: (sprite.current->yhot != cursor->yhot)) ! 280: CheckPhysLimits(cursor); ! 281: (*currentScreen->DisplayCursor) (currentScreen, cursor); ! 282: sprite.current = cursor; ! 283: } ! 284: } ! 285: ! 286: static void ! 287: PostNewCursor() ! 288: { ! 289: register WindowPtr win; ! 290: register GrabPtr grab = inputInfo.pointer->grab; ! 291: if (grab) ! 292: { ! 293: if (grab->u.ptr.cursor) ! 294: { ! 295: ChangeToCursor(grab->u.ptr.cursor); ! 296: return; ! 297: } ! 298: if (IsParent(grab->window, sprite.win)) ! 299: win = sprite.win; ! 300: else ! 301: win = grab->window; ! 302: } ! 303: else ! 304: win = sprite.win; ! 305: for (; win; win = win->parent) ! 306: if (win->cursor != NullCursor) ! 307: { ! 308: ChangeToCursor(win->cursor); ! 309: return; ! 310: } ! 311: } ! 312: ! 313: /************************************************************************** ! 314: * The following procedures deal with synchronous events * ! 315: **************************************************************************/ ! 316: ! 317: static void ! 318: EnqueueEvent(device, event) ! 319: xEvent *event; ! 320: DeviceIntPtr device; ! 321: { ! 322: register QdEventPtr tail = syncEvents.pending.back; ! 323: register QdEventPtr new; ! 324: /* ! 325: * Collapsing of mouse events does not bother to test if qdEvents.num == 0, ! 326: * since there will never be MotionNotify in the type of the head event which ! 327: * is what last points at when num == 0. ! 328: */ ! 329: if ((event->u.u.type == MotionNotify) && ! 330: (tail->event.u.u.type == MotionNotify)) ! 331: { ! 332: tail->event = *event; ! 333: return; ! 334: } ! 335: syncEvents.num++; ! 336: if (syncEvents.free.forw == &syncEvents.free) ! 337: new = (QdEventPtr)Xalloc(sizeof(QdEventRec)); ! 338: else ! 339: { ! 340: new = syncEvents.free.forw; ! 341: remque(new); ! 342: } ! 343: new->device = device; ! 344: new->event = *event; ! 345: insque(new, tail); ! 346: if (syncEvents.num > MAX_QUEUED_EVENTS) ! 347: { ! 348: /* XXX here we send all the pending events and break the locks */ ! 349: return; ! 350: } ! 351: } ! 352: ! 353: static void ! 354: PlayReleasedEvents() ! 355: { ! 356: register QdEventPtr qe = syncEvents.pending.forw; ! 357: QdEventPtr next; ! 358: while (qe != &syncEvents.pending) ! 359: { ! 360: register DeviceIntPtr device = qe->device; ! 361: if (!device->sync.frozen) ! 362: { ! 363: next = qe->forw;; ! 364: remque(qe); ! 365: (*device->public.processInputProc)(&qe->event, device); ! 366: insque(qe, &syncEvents.free); ! 367: qe = next; ! 368: } ! 369: else ! 370: qe = qe->forw; ! 371: } ! 372: } ! 373: ! 374: static void ! 375: ComputeFreezes(dev1, dev2) ! 376: DeviceIntPtr dev1, dev2; ! 377: { ! 378: register DeviceIntPtr replayDev = syncEvents.replayDev; ! 379: int i; ! 380: WindowPtr w; ! 381: Bool isKbd ; ! 382: register xEvent *xE ; ! 383: ! 384: dev1->sync.frozen = ! 385: ((dev1->sync.other != NullGrab) || (dev1->sync.state >= FROZEN)); ! 386: dev2->sync.frozen = ! 387: ((dev2->sync.other != NullGrab) || (dev2->sync.state >= FROZEN)); ! 388: if (syncEvents.playingEvents) ! 389: return; ! 390: syncEvents.playingEvents = TRUE; ! 391: if (replayDev) ! 392: { ! 393: isKbd = (replayDev == inputInfo.keyboard); ! 394: xE = &replayDev->sync.event; ! 395: syncEvents.replayDev = (DeviceIntPtr)NULL; ! 396: w = XYToWindow( ! 397: xE->u.keyButtonPointer.rootX, xE->u.keyButtonPointer.rootY); ! 398: for (i = 0; i < spriteTraceGood; i++) ! 399: if (syncEvents.replayWin == spriteTrace[i]) ! 400: { ! 401: if (!CheckDeviceGrabs(replayDev, xE, i+1, isKbd)) ! 402: if (isKbd) ! 403: NormalKeyboardEvent(replayDev, xE, w); ! 404: else ! 405: DeliverDeviceEvents(w, xE, NullGrab, NullWindow); ! 406: goto playmore; ! 407: } ! 408: /* must not still be in the same stack */ ! 409: if (isKbd) ! 410: NormalKeyboardEvent(replayDev, xE, w); ! 411: else ! 412: DeliverDeviceEvents(w, xE, NullGrab, NullWindow); ! 413: } ! 414: playmore: ! 415: if (!dev1->sync.frozen || !dev2->sync.frozen) ! 416: PlayReleasedEvents(); ! 417: syncEvents.playingEvents = FALSE; ! 418: } ! 419: ! 420: CheckGrabForSyncs(grab, thisDev, thisMode, otherDev, otherMode) ! 421: GrabPtr grab; ! 422: DeviceIntPtr thisDev, otherDev; ! 423: int thisMode, otherMode; ! 424: { ! 425: if (thisMode == GrabModeSync) ! 426: thisDev->sync.state = FROZEN_NO_EVENT; ! 427: else ! 428: { /* free both if same client owns both */ ! 429: thisDev->sync.state = THAWED; ! 430: if (thisDev->sync.other && ! 431: (thisDev->sync.other->client == grab->client)) ! 432: thisDev->sync.other = NullGrab; ! 433: } ! 434: if (otherMode == GrabModeSync) ! 435: otherDev->sync.other = grab; ! 436: else ! 437: { /* free both if same client owns both */ ! 438: if (otherDev->sync.other && ! 439: (otherDev->sync.other->client == grab->client)) ! 440: otherDev->sync.other = NullGrab; ! 441: } ! 442: ComputeFreezes(thisDev, otherDev); ! 443: } ! 444: ! 445: static void ! 446: ActivatePointerGrab(mouse, grab, time, autoGrab) ! 447: GrabPtr grab; ! 448: register DeviceIntPtr mouse; ! 449: TimeStamp time; ! 450: Bool autoGrab; ! 451: { ! 452: WindowPtr w; ! 453: ! 454: mouse->grabTime = time; ! 455: ptrGrab = *grab; ! 456: mouse->grab = &ptrGrab; ! 457: mouse->u.ptr.autoReleaseGrab = autoGrab; ! 458: CheckGrabForSyncs( ! 459: mouse->grab, mouse, grab->pointerMode, ! 460: inputInfo.keyboard, grab->keyboardMode); ! 461: PostNewCursor(); ! 462: if (w = grab->u.ptr.confineTo) ! 463: { ! 464: NewCursorConfines( ! 465: w->absCorner.x, w->absCorner.x + w->clientWinSize.width, ! 466: w->absCorner.y, w->absCorner.y + w->clientWinSize.height); ! 467: } ! 468: DoEnterLeaveEvents(sprite.win, grab->window, NotifyGrab); ! 469: } ! 470: ! 471: static void ! 472: DeactivatePointerGrab(mouse) ! 473: DeviceIntPtr mouse; ! 474: { ! 475: GrabPtr grab = mouse->grab; ! 476: DeviceIntPtr keybd = inputInfo.keyboard; ! 477: ! 478: DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab); ! 479: mouse->grab = NullGrab; ! 480: mouse->sync.state = NOT_GRABBED; ! 481: mouse->u.ptr.autoReleaseGrab = FALSE; ! 482: if (keybd->sync.other == grab) ! 483: keybd->sync.other = NullGrab; ! 484: ComputeFreezes(keybd, mouse); ! 485: if (grab->u.ptr.confineTo) ! 486: NewCursorConfines(0, currentScreen->width, 0, currentScreen->height); ! 487: PostNewCursor(); ! 488: } ! 489: ! 490: static void ! 491: ActivateKeyboardGrab(keybd, grab, time, passive) ! 492: GrabPtr grab; ! 493: register DeviceIntPtr keybd; ! 494: TimeStamp time; ! 495: Bool passive; ! 496: { ! 497: keybd->grabTime = time; ! 498: keybdGrab = *grab; ! 499: keybd->grab = &keybdGrab; ! 500: keybd->u.keybd.passiveGrab = passive; ! 501: CheckGrabForSyncs( ! 502: keybd->grab, keybd, grab->keyboardMode, ! 503: inputInfo.pointer, grab->pointerMode); ! 504: } ! 505: ! 506: static void ! 507: DeactivateKeyboardGrab(keybd) ! 508: DeviceIntPtr keybd; ! 509: { ! 510: DeviceIntPtr mouse = inputInfo.pointer; ! 511: GrabPtr grab = keybd->grab; ! 512: ! 513: keybd->grab = NullGrab; ! 514: keybd->sync.state = NOT_GRABBED; ! 515: keybd->u.keybd.passiveGrab = FALSE; ! 516: if (mouse->sync.other == grab) ! 517: mouse->sync.other = NullGrab; ! 518: ComputeFreezes(keybd, mouse); ! 519: } ! 520: ! 521: static void ! 522: AllowSome(client, time, thisDev, otherDev, newState) ! 523: ClientPtr client; ! 524: TimeStamp time; ! 525: DeviceIntPtr thisDev, otherDev; ! 526: int newState; ! 527: { ! 528: Bool thisGrabbed, otherGrabbed; ! 529: TimeStamp grabTime; ! 530: ! 531: thisGrabbed = thisDev->grab && (thisDev->grab->client == client); ! 532: otherGrabbed = otherDev->grab && (otherDev->grab->client == client); ! 533: if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || ! 534: (otherGrabbed && thisDev->sync.other))) ! 535: return; ! 536: if (thisGrabbed && ! 537: (!otherGrabbed || ! 538: (CompareTimeStamps(otherDev->grabTime, thisDev->grabTime) == EARLIER))) ! 539: grabTime = thisDev->grabTime; ! 540: else ! 541: grabTime = otherDev->grabTime; ! 542: if ((CompareTimeStamps(time, currentTime) == LATER) || ! 543: (CompareTimeStamps(time, grabTime) == EARLIER)) ! 544: return; ! 545: switch (newState) ! 546: { ! 547: case THAWED: /* Async */ ! 548: if (thisGrabbed) ! 549: thisDev->sync.state = THAWED; ! 550: if (otherGrabbed) ! 551: thisDev->sync.other = NullGrab; ! 552: ComputeFreezes(thisDev, otherDev); ! 553: break; ! 554: case FREEZE_NEXT_EVENT: /* Sync */ ! 555: if (thisGrabbed) ! 556: { ! 557: thisDev->sync.state = FREEZE_NEXT_EVENT; ! 558: if (otherGrabbed) ! 559: thisDev->sync.other = NullGrab; ! 560: ComputeFreezes(thisDev, otherDev); ! 561: } ! 562: break; ! 563: case THAWED_BOTH: /* AsyncBoth */ ! 564: if ((otherGrabbed && otherDev->sync.state >= FROZEN) || ! 565: (thisGrabbed && otherDev->sync.other)) ! 566: { ! 567: if (thisGrabbed) ! 568: { ! 569: thisDev->sync.state = THAWED; ! 570: otherDev->sync.other = NullGrab; ! 571: } ! 572: if (otherGrabbed) ! 573: { ! 574: otherDev->sync.state = THAWED; ! 575: thisDev->sync.other = NullGrab; ! 576: } ! 577: ComputeFreezes(thisDev, otherDev); ! 578: } ! 579: break; ! 580: case FREEZE_BOTH_NEXT_EVENT: /* SyncBoth */ ! 581: if ((otherGrabbed && otherDev->sync.state >= FROZEN) || ! 582: (thisGrabbed && otherDev->sync.other)) ! 583: { ! 584: if (thisGrabbed) ! 585: { ! 586: thisDev->sync.state = FREEZE_BOTH_NEXT_EVENT; ! 587: otherDev->sync.other = NullGrab; ! 588: } ! 589: if (otherGrabbed) ! 590: { ! 591: otherDev->sync.state = FREEZE_BOTH_NEXT_EVENT; ! 592: thisDev->sync.other = NullGrab; ! 593: } ! 594: ComputeFreezes(thisDev, otherDev); ! 595: } ! 596: break; ! 597: case NOT_GRABBED: /* Replay */ ! 598: if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT) ! 599: { ! 600: syncEvents.replayDev = thisDev; ! 601: syncEvents.replayWin = thisDev->grab->window; ! 602: if (thisDev == inputInfo.pointer) ! 603: DeactivatePointerGrab(thisDev); ! 604: else ! 605: { ! 606: /* Deactivating a keyboard grab should cause focus ! 607: events. */ ! 608: DoFocusEvents(thisDev->grab->window, ! 609: thisDev->u.keybd.focus.win, NotifyUngrab); ! 610: DeactivateKeyboardGrab(thisDev); ! 611: } ! 612: syncEvents.replayDev = (DeviceIntPtr)NULL; ! 613: } ! 614: break; ! 615: } ! 616: } ! 617: ! 618: int ! 619: ProcAllowEvents(client) ! 620: register ClientPtr client; ! 621: { ! 622: TimeStamp time; ! 623: DeviceIntPtr mouse = inputInfo.pointer; ! 624: DeviceIntPtr keybd = inputInfo.keyboard; ! 625: REQUEST(xAllowEventsReq); ! 626: ! 627: REQUEST_SIZE_MATCH(xAllowEventsReq); ! 628: time = ClientTimeToServerTime(stuff->time); ! 629: switch (stuff->mode) ! 630: { ! 631: case ReplayPointer: ! 632: AllowSome(client, time, mouse, keybd, NOT_GRABBED); ! 633: break; ! 634: case SyncPointer: ! 635: AllowSome(client, time, mouse, keybd, FREEZE_NEXT_EVENT); ! 636: break; ! 637: case AsyncPointer: ! 638: AllowSome(client, time, mouse, keybd, THAWED); ! 639: break; ! 640: case ReplayKeyboard: ! 641: AllowSome(client, time, keybd, mouse, NOT_GRABBED); ! 642: break; ! 643: case SyncKeyboard: ! 644: AllowSome(client, time, keybd, mouse, FREEZE_NEXT_EVENT); ! 645: break; ! 646: case AsyncKeyboard: ! 647: AllowSome(client, time, keybd, mouse, THAWED); ! 648: break; ! 649: case SyncBoth: ! 650: AllowSome(client, time, keybd, mouse, FREEZE_BOTH_NEXT_EVENT); ! 651: break; ! 652: case AsyncBoth: ! 653: AllowSome(client, time, keybd, mouse, THAWED_BOTH); ! 654: break; ! 655: default: ! 656: client->errorValue = stuff->mode; ! 657: return BadValue; ! 658: } ! 659: return Success; ! 660: } ! 661: ! 662: /* I don't see this function called from anywhere. Should it's ! 663: DeactivateKeyboardGrab cause focus events? PRH. */ ! 664: ! 665: void ! 666: ReleaseActiveGrabs(client) ! 667: ClientPtr client; ! 668: { ! 669: int i; ! 670: register DeviceIntPtr d; ! 671: for (i = 0; i < inputInfo.numDevices; i++) ! 672: { ! 673: d = inputInfo.devices[i]; ! 674: if (d->grab && (d->grab->client == client)) ! 675: { ! 676: if (d == inputInfo.keyboard) ! 677: DeactivateKeyboardGrab(d); ! 678: else if (d == inputInfo.pointer) ! 679: DeactivatePointerGrab(d); ! 680: else ! 681: d->grab = NullGrab; ! 682: } ! 683: } ! 684: } ! 685: ! 686: /************************************************************************** ! 687: * The following procedures deal with delivering events * ! 688: **************************************************************************/ ! 689: ! 690: int ! 691: TryClientEvents (client, pEvents, count, mask, filter, grab) ! 692: ClientPtr client; ! 693: GrabPtr grab; ! 694: xEvent *pEvents; ! 695: int count; ! 696: Mask mask, filter; ! 697: { ! 698: int i; ! 699: ! 700: if (debug_events) ErrorF( ! 701: "Event([%d, %d], mask=0x%x), client=%d", ! 702: pEvents->u.u.type, pEvents->u.u.detail, mask, client->index); ! 703: if ((client) && (client != serverClient) && (!client->clientGone) && ! 704: ((filter == CantBeFiltered) || (mask & filter)) && ! 705: ((!grab) || (client == grab->client))) ! 706: { ! 707: for (i = 0; i < count; i++) ! 708: pEvents[i].u.u.sequenceNumber = client->sequence; ! 709: WriteEventsToClient(client, count, pEvents); ! 710: if (debug_events) ErrorF( " delivered\n"); ! 711: return 1; ! 712: } ! 713: else ! 714: { ! 715: if (debug_events) ErrorF("\n"); ! 716: return 0; ! 717: } ! 718: } ! 719: ! 720: static int ! 721: DeliverEventsToWindow(pWin, pEvents, count, filter, grab) ! 722: WindowPtr pWin; ! 723: GrabPtr grab; ! 724: xEvent *pEvents; ! 725: int count; ! 726: Mask filter; ! 727: { ! 728: int deliveries = 0; ! 729: OtherClients *other; ! 730: ClientPtr client = NullClient; ! 731: Mask deliveryMask; /* If a grab occurs due to a button press, then ! 732: this mask is the mask of the grab. */ ! 733: ! 734: /* ! 735: * The following relies on the fact that the Button<n>MotionMasks are equal ! 736: * to the corresponding Button<n>Masks from the current modifier/button state. ! 737: * If the client only selected one of the Button<n>Motion events, then she ! 738: * should only get those. ! 739: */ ! 740: ! 741: if (pEvents->u.u.type == MotionNotify) ! 742: { ! 743: if (pWin->allEventMasks & PointerMotionHintMask) ! 744: { ! 745: if (lastWasMotion) ! 746: return 0; ! 747: else ! 748: pEvents->u.u.detail = NotifyHint; ! 749: } ! 750: else ! 751: pEvents->u.u.detail = NotifyNormal; ! 752: lastWasMotion = TRUE; ! 753: filter = Motion_Filter(keyButtonState); ! 754: } ! 755: ! 756: /* if nobody ever wants to see this event, skip some work */ ! 757: if ((filter != CantBeFiltered) && !(pWin->allEventMasks & filter)) ! 758: return 0; ! 759: if (TryClientEvents( ! 760: pWin->client, pEvents, count, pWin->eventMask, filter, grab)) ! 761: { ! 762: deliveries++; ! 763: client = pWin->client; ! 764: deliveryMask = pWin->eventMask; ! 765: } ! 766: if (filter) /* CantBeFiltered means only window owner gets the event */ ! 767: for (other = OTHERCLIENTS(pWin); other; other = other->next) ! 768: { ! 769: if (TryClientEvents( ! 770: other->client, pEvents, count, other->mask, filter, grab)) ! 771: { ! 772: deliveries++; ! 773: client = other->client; ! 774: deliveryMask = other->mask; ! 775: } ! 776: } ! 777: if ((pEvents->u.u.type == ButtonPress) && deliveries && (!grab)) ! 778: { ! 779: ptrGrab.device = inputInfo.pointer; ! 780: ptrGrab.client = client; ! 781: ptrGrab.window = pWin; ! 782: ptrGrab.ownerEvents = deliveryMask & OwnerGrabButtonMask; ! 783: ptrGrab.eventMask = deliveryMask; ! 784: ptrGrab.keyboardMode = GrabModeAsync; ! 785: ptrGrab.pointerMode = GrabModeAsync; ! 786: ptrGrab.u.ptr.confineTo = NullWindow; ! 787: ptrGrab.u.ptr.cursor = NullCursor; ! 788: ActivatePointerGrab(inputInfo.pointer, &ptrGrab, currentTime, TRUE); ! 789: } ! 790: return deliveries; ! 791: } ! 792: ! 793: /* If the event goes to dontDeliverToMe, don't send it and return 0. if ! 794: send works, return 1 or if send didn't work, return 2. ! 795: */ ! 796: ! 797: int ! 798: MaybeDeliverEventsToClient(pWin, pEvents, count, filter, dontDeliverToMe) ! 799: WindowPtr pWin; ! 800: xEvent *pEvents; ! 801: int count; ! 802: Mask filter; ! 803: ClientPtr dontDeliverToMe; ! 804: { ! 805: OtherClients * other; ! 806: ! 807: if (pWin->eventMask & filter) ! 808: { ! 809: if (pWin->client == dontDeliverToMe) ! 810: return 0; ! 811: return TryClientEvents( ! 812: pWin->client, pEvents, count, pWin->eventMask, filter, NullGrab); ! 813: } ! 814: for (other = OTHERCLIENTS(pWin); other; other = other->next) ! 815: if (other->mask & filter) ! 816: { ! 817: if (other->client == dontDeliverToMe) ! 818: return 0; ! 819: return TryClientEvents( ! 820: other->client, pEvents, count, other->mask, filter, NullGrab); ! 821: } ! 822: return 2; ! 823: } ! 824: ! 825: static WindowPtr ! 826: RootForWindow(pWin) ! 827: WindowPtr pWin; ! 828: { ! 829: return &WindowTable[pWin->drawable.pScreen->myNum]; ! 830: } ! 831: ! 832: static void ! 833: FixUpEventFromWindow(xE, pWin, child, calcChild) ! 834: xEvent *xE; ! 835: WindowPtr pWin; ! 836: Window child; ! 837: Bool calcChild; ! 838: { ! 839: if (calcChild) ! 840: { ! 841: WindowPtr w=spriteTrace[spriteTraceGood-1]; ! 842: ! 843: /* If the search ends up past the root should the child field be ! 844: set to none or should the value in the argument be passed ! 845: through. It probably doesn't matter since everyone calls ! 846: this function with child == None anyway. */ ! 847: ! 848: while (w) ! 849: { ! 850: /* If the source window is same as event window, child should be ! 851: none. Don't bother going all all the way back to the root. */ ! 852: ! 853: if (w == pWin) ! 854: { ! 855: child = None; ! 856: break; ! 857: } ! 858: ! 859: if (w->parent == pWin) ! 860: { ! 861: child = w->wid; ! 862: break; ! 863: } ! 864: w = w->parent; ! 865: } ! 866: } ! 867: xE->u.keyButtonPointer.root = ROOT->wid; ! 868: xE->u.keyButtonPointer.child = child; ! 869: xE->u.keyButtonPointer.event = pWin->wid; ! 870: xE->u.keyButtonPointer.eventX = ! 871: xE->u.keyButtonPointer.rootX - pWin->absCorner.x; ! 872: xE->u.keyButtonPointer.eventY = ! 873: xE->u.keyButtonPointer.rootY - pWin->absCorner.y; ! 874: } ! 875: ! 876: ! 877: int ! 878: DeliverDeviceEvents(pWin, xE, grab, stopAt) ! 879: register WindowPtr pWin, stopAt; ! 880: register xEvent *xE; ! 881: GrabPtr grab; ! 882: { ! 883: Mask filter; ! 884: int deliveries; ! 885: Window child = None; ! 886: ! 887: filter = filters[xE->u.u.type]; ! 888: if ((filter != CantBeFiltered) && !(filter & pWin->deliverableEvents)) ! 889: return 0; ! 890: while (pWin) ! 891: { ! 892: FixUpEventFromWindow(xE, pWin, child, FALSE); ! 893: deliveries = DeliverEventsToWindow(pWin, xE, 1, filter, grab); ! 894: if ((deliveries > 0) || (filter & pWin->dontPropagateMask)) ! 895: return deliveries; ! 896: if (pWin == stopAt) ! 897: return 0; ! 898: child = pWin->wid; ! 899: pWin = pWin->parent; ! 900: } ! 901: return 0; ! 902: } ! 903: ! 904: int ! 905: DeliverEvents(pWin, xE, count, otherParent) ! 906: /* not useful for events that propagate up the tree */ ! 907: register WindowPtr pWin, otherParent; ! 908: register xEvent *xE; ! 909: int count; ! 910: { ! 911: Mask filter; ! 912: int deliveries; ! 913: ! 914: if (!count) ! 915: return 0; ! 916: filter = filters[xE->u.u.type]; ! 917: if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify)) ! 918: xE->u.destroyNotify.event = pWin->wid; ! 919: if (filter != StructureAndSubMask) ! 920: return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab); ! 921: deliveries = DeliverEventsToWindow( ! 922: pWin, xE, count, StructureNotifyMask, NullGrab); ! 923: if (pWin->parent) ! 924: { ! 925: xE->u.destroyNotify.event = pWin->parent->wid; ! 926: deliveries += DeliverEventsToWindow( ! 927: pWin->parent, xE, count, SubstructureNotifyMask, NullGrab); ! 928: if (xE->u.u.type == ReparentNotify) ! 929: { ! 930: xE->u.destroyNotify.event = otherParent->wid; ! 931: deliveries += DeliverEventsToWindow( ! 932: otherParent, xE, count, SubstructureNotifyMask, NullGrab); ! 933: } ! 934: } ! 935: return deliveries; ! 936: } ! 937: ! 938: /* check root -- this fails in Zaphod mode XXX */ ! 939: /* ! 940: * XYToWindow is only called by CheckMotion after it has determined that ! 941: * the current cache is not accurate. ! 942: */ ! 943: static WindowPtr ! 944: XYToWindow(x, y) ! 945: int x, y; ! 946: { ! 947: register WindowPtr pWin; ! 948: ! 949: spriteTraceGood = 1; /* root window still there */ ! 950: pWin = ROOT->firstChild; ! 951: while (pWin) ! 952: { ! 953: if ((pWin->mapped) && ! 954: (x >= pWin->absCorner.x - pWin->borderWidth) && ! 955: (x < pWin->absCorner.x + pWin->clientWinSize.width + ! 956: pWin->borderWidth) && ! 957: (y >= pWin->absCorner.y - pWin->borderWidth) && ! 958: (y < pWin->absCorner.y + pWin->clientWinSize.height + ! 959: pWin->borderWidth)) ! 960: { ! 961: if (spriteTraceGood >= spriteTraceSize) ! 962: { ! 963: spriteTraceSize += 10; ! 964: spriteTrace = (WindowPtr *)Xrealloc( ! 965: spriteTrace, spriteTraceSize*sizeof(WindowPtr)); ! 966: } ! 967: spriteTrace[spriteTraceGood] = pWin; ! 968: pWin = spriteTrace[spriteTraceGood++]->firstChild; ! 969: } ! 970: else ! 971: pWin = pWin->nextSib; ! 972: } ! 973: return spriteTrace[spriteTraceGood-1]; ! 974: } ! 975: ! 976: static WindowPtr ! 977: CheckMotion(x, y, ignoreCache) ! 978: int x, y; ! 979: Bool ignoreCache; ! 980: { ! 981: WindowPtr prevSpriteWin = sprite.win; ! 982: ! 983: if ((x != sprite.hot.x) || (y != sprite.hot.y)) ! 984: { ! 985: sprite.win = XYToWindow(x, y); ! 986: sprite.hot.x = x; ! 987: sprite.hot.y = y; ! 988: /* XXX Do PointerNonInterestBox here */ ! 989: /* ! 990: if (!(sprite.win->deliverableEvents & Motion_Filter(keyButtonState))) ! 991: { ! 992: ! 993: } ! 994: */ ! 995: } ! 996: else ! 997: { ! 998: if ((ignoreCache) || (!sprite.win)) ! 999: sprite.win = XYToWindow(x, y); ! 1000: } ! 1001: if (sprite.win != prevSpriteWin) ! 1002: { ! 1003: if (prevSpriteWin != NullWindow) ! 1004: DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal); ! 1005: lastWasMotion = FALSE; ! 1006: PostNewCursor(); ! 1007: return NullWindow; ! 1008: } ! 1009: return sprite.win; ! 1010: } ! 1011: ! 1012: WindowsRestructured() ! 1013: { ! 1014: (void) CheckMotion(sprite.hot.x, sprite.hot.y, TRUE); ! 1015: } ! 1016: ! 1017: void ! 1018: DefineInitialRootWindow(win) ! 1019: WindowPtr win; ! 1020: { ! 1021: register CursorPtr c = win->cursor; ! 1022: ! 1023: sprite.hot.x = currentScreen->width / 2; ! 1024: sprite.hot.y = currentScreen->height / 2; ! 1025: sprite.win = win; ! 1026: sprite.current = c; ! 1027: spriteTraceGood = 1; ! 1028: ROOT = win; ! 1029: (*currentScreen->CursorLimits) ( ! 1030: currentScreen, win->cursor, &sprite.hotLimits, &sprite.physLimits); ! 1031: (*currentScreen->SetCursorPosition) ( ! 1032: currentScreen, sprite.hot.x, sprite.hot.y, FALSE); ! 1033: (*currentScreen->ConstrainCursor) ( ! 1034: currentScreen, &sprite.physLimits); ! 1035: (*currentScreen->DisplayCursor) (currentScreen, c); ! 1036: } ! 1037: ! 1038: /* ! 1039: * This does not take any shortcuts, and even ignores its argument, since ! 1040: * it does not happen very often, and one has to walk up the tree since ! 1041: * this might be a newly instantiated cursor for an intermediate window ! 1042: * between the one the pointer is in and the one that the last cursor was ! 1043: * instantiated from. ! 1044: */ ! 1045: void ! 1046: WindowHasNewCursor(pWin) ! 1047: WindowPtr pWin; ! 1048: { ! 1049: PostNewCursor(); ! 1050: } ! 1051: ! 1052: void ! 1053: NewCurrentScreen(newScreen, x, y) ! 1054: ScreenPtr newScreen; ! 1055: int x,y; ! 1056: { ! 1057: if (newScreen == currentScreen) ! 1058: return; ! 1059: ROOT = &WindowTable[newScreen->myNum]; ! 1060: currentScreen = newScreen; ! 1061: (void) CheckMotion(x, y, TRUE); ! 1062: } ! 1063: ! 1064: int ! 1065: ProcWarpPointer(client) ! 1066: ClientPtr client; ! 1067: { ! 1068: WindowPtr dest = NULL; ! 1069: int x, y; ! 1070: ! 1071: REQUEST(xWarpPointerReq); ! 1072: ! 1073: REQUEST_SIZE_MATCH(xWarpPointerReq); ! 1074: dest = LookupWindow(stuff->dstWid, client); ! 1075: if (!dest) ! 1076: { ! 1077: client->errorValue = stuff->dstWid; ! 1078: return BadWindow; ! 1079: } ! 1080: if (stuff->dstWid != None) ! 1081: { ! 1082: dest = LookupWindow(stuff->dstWid, client); ! 1083: if (!dest) ! 1084: { ! 1085: client->errorValue = stuff->dstWid; ! 1086: return BadWindow; ! 1087: } ! 1088: } ! 1089: if (stuff->srcWid != None) ! 1090: { ! 1091: int winX, winY; ! 1092: WindowPtr source = LookupWindow(stuff->srcWid, client); ! 1093: if (!source) ! 1094: { ! 1095: client->errorValue = stuff->srcWid; ! 1096: return BadWindow; ! 1097: } ! 1098: winX = source->absCorner.x; ! 1099: winY = source->absCorner.y; ! 1100: if ( ! 1101: (sprite.hot.x < (winX + stuff->srcX)) || ! 1102: (sprite.hot.y < (winY + stuff->srcY)) || ! 1103: ((stuff->srcWidth != 0) && ! 1104: (winX + stuff->srcX + stuff->srcWidth < sprite.hot.x)) || ! 1105: ((stuff->srcHeight != 0) && ! 1106: (winY + stuff->srcY + stuff->srcHeight < sprite.hot.y)) || ! 1107: (!PointInWindowIsVisible(source, sprite.hot.x, sprite.hot.y))) ! 1108: return Success; ! 1109: } ! 1110: if (dest) ! 1111: { ! 1112: if (currentScreen != dest->drawable.pScreen) ! 1113: NewCurrentScreen(dest->drawable.pScreen, ! 1114: dest->absCorner.x + stuff->dstX, ! 1115: dest->absCorner.y + stuff->dstY); ! 1116: ! 1117: x = dest->absCorner.x + stuff->dstX; ! 1118: y = dest->absCorner.y + stuff->dstY; ! 1119: ! 1120: } else { ! 1121: x = sprite.hot.x + stuff->dstX; ! 1122: y = sprite.hot.y + stuff->dstY; ! 1123: } ! 1124: ! 1125: /* Send a pointer motion event to ProcessPointerEvent, just as the ! 1126: device dependent driver does when the hardware moves the pointer. */ ! 1127: ! 1128: (*currentScreen->SetCursorPosition)( currentScreen, x, y, TRUE); ! 1129: ! 1130: return Success; ! 1131: } ! 1132: ! 1133: static void ! 1134: NoticeTimeAndState(xE) ! 1135: register xEvent *xE; ! 1136: { ! 1137: if (xE->u.keyButtonPointer.time < currentTime.milliseconds) ! 1138: currentTime.months++; ! 1139: currentTime.milliseconds = xE->u.keyButtonPointer.time; ! 1140: xE->u.keyButtonPointer.pad1 = 0; ! 1141: xE->u.keyButtonPointer.state = keyButtonState; ! 1142: xE->u.keyButtonPointer.sameScreen = TRUE; /* XXX */ ! 1143: } ! 1144: ! 1145: /* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a ! 1146: passive grab set on the window to be activated. */ ! 1147: ! 1148: static Bool ! 1149: CheckPassiveGrabsOnWindow(pWin, device, xE, isKeyboard) ! 1150: WindowPtr pWin; ! 1151: register DeviceIntPtr device; ! 1152: register xEvent *xE; ! 1153: int isKeyboard; ! 1154: { ! 1155: GrabPtr grab; ! 1156: GrabRec temporaryGrab; ! 1157: ! 1158: temporaryGrab.window = pWin; ! 1159: temporaryGrab.device = device; ! 1160: temporaryGrab.u.keybd.keyDetail.exact = xE->u.u.detail; ! 1161: temporaryGrab.modifiersDetail.exact = xE->u.keyButtonPointer.state ! 1162: & AllModifiersMask; ! 1163: ! 1164: for (grab = PASSIVEGRABS(pWin); grab; grab = grab->next) ! 1165: { ! 1166: if (GrabMatchesSecond(&temporaryGrab, grab)) ! 1167: { ! 1168: if (isKeyboard) ! 1169: ActivateKeyboardGrab(device, grab, currentTime, TRUE); ! 1170: else ! 1171: ActivatePointerGrab(device, grab, currentTime, TRUE); ! 1172: ! 1173: FixUpEventFromWindow(xE, grab->window, None, TRUE); ! 1174: ! 1175: TryClientEvents(grab->client, xE, 1, grab->eventMask, ! 1176: filters[xE->u.u.type], grab); ! 1177: ! 1178: if (device->sync.state == FROZEN_NO_EVENT) ! 1179: { ! 1180: device->sync.event = *xE; ! 1181: device->sync.state = FROZEN_WITH_EVENT; ! 1182: } ! 1183: ! 1184: return TRUE; ! 1185: } ! 1186: } ! 1187: ! 1188: return FALSE; ! 1189: } ! 1190: ! 1191: /* ! 1192: "CheckDeviceGrabs" handles both keyboard and pointer events that may cause ! 1193: a passive grab to be activated. If the event is a keyboard event, the ! 1194: ancestors of the focus window are traced down and tried to see if they have ! 1195: any passive grabs to be activated. If the focus window itself is reached and ! 1196: it's descendants contain they pointer, the ancestors of the window that the ! 1197: pointer is in are then traced down starting at the focus window, otherwise no ! 1198: grabs are activated. If the event is a pointer event, the ancestors of the ! 1199: window that the pointer is in are traced down starting at the root until ! 1200: CheckPassiveGrabs causes a passive grab to activate or all the windows are ! 1201: tried. PRH ! 1202: */ ! 1203: ! 1204: static Bool ! 1205: CheckDeviceGrabs(device, xE, checkFirst, isKeyboard) ! 1206: register DeviceIntPtr device; ! 1207: register xEvent *xE; ! 1208: int checkFirst; ! 1209: { ! 1210: int i; ! 1211: WindowPtr pWin; ! 1212: ! 1213: i = checkFirst; ! 1214: ! 1215: if (isKeyboard) ! 1216: { ! 1217: for (; i < focusTraceGood; i++) ! 1218: { ! 1219: pWin = focusTrace[i]; ! 1220: if (CheckPassiveGrabsOnWindow(pWin, device, xE, isKeyboard)) ! 1221: return TRUE; ! 1222: } ! 1223: ! 1224: if ((device->u.keybd.focus.win == NoneWin) || ! 1225: (i >= spriteTraceGood) || ! 1226: ((i > 0) && (pWin != spriteTrace[i-1]))) ! 1227: return FALSE; ! 1228: } ! 1229: ! 1230: for (; i < spriteTraceGood; i++) ! 1231: { ! 1232: pWin = spriteTrace[i]; ! 1233: if (CheckPassiveGrabsOnWindow(pWin, device, xE, isKeyboard)) ! 1234: return TRUE; ! 1235: } ! 1236: ! 1237: return FALSE; ! 1238: } ! 1239: ! 1240: static void ! 1241: NormalKeyboardEvent(keybd, xE, window) ! 1242: xEvent *xE; ! 1243: DeviceIntPtr keybd; ! 1244: WindowPtr window; ! 1245: { ! 1246: WindowPtr focus = keybd->u.keybd.focus.win; ! 1247: if (focus == NullWindow) ! 1248: return; ! 1249: if (focus == PointerRootWin) ! 1250: { ! 1251: DeliverDeviceEvents(window, xE, NullGrab, NullWindow); ! 1252: return; ! 1253: } ! 1254: if ((focus == window) || IsParent(focus, window)) ! 1255: { ! 1256: if (DeliverDeviceEvents(window, xE, NullGrab, focus)) ! 1257: return; ! 1258: } ! 1259: /* just deliver it to the focus window */ ! 1260: FixUpEventFromWindow(xE, focus, None, FALSE); ! 1261: DeliverEventsToWindow(focus, xE, 1, filters[xE->u.u.type], NullGrab); ! 1262: } ! 1263: ! 1264: static void ! 1265: DeliverGrabbedEvent(xE, thisDev, otherDev, deactivateGrab) ! 1266: register xEvent *xE; ! 1267: register DeviceIntPtr thisDev; ! 1268: DeviceIntPtr otherDev; ! 1269: Bool deactivateGrab; ! 1270: { ! 1271: register GrabPtr grab = thisDev->grab; ! 1272: Bool syncIt; ! 1273: Mask filterToUse; ! 1274: ! 1275: if ((!grab->ownerEvents) || ! 1276: (!(syncIt = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow)))) ! 1277: { ! 1278: FixUpEventFromWindow(xE, grab->window, None, TRUE); ! 1279: if (xE->u.u.type == MotionNotify) ! 1280: filterToUse = Motion_Filter(keyButtonState); ! 1281: else ! 1282: filterToUse = filters[xE->u.u.type]; ! 1283: syncIt = TryClientEvents(grab->client, xE, 1, grab->eventMask, ! 1284: filterToUse, grab); ! 1285: } ! 1286: if (syncIt && !deactivateGrab && (xE->u.u.type != MotionNotify)) ! 1287: switch (thisDev->sync.state) ! 1288: { ! 1289: case FREEZE_BOTH_NEXT_EVENT: ! 1290: otherDev->sync.frozen = TRUE; ! 1291: if ((otherDev->sync.state == FREEZE_BOTH_NEXT_EVENT) && ! 1292: (otherDev->grab->client == thisDev->grab->client)) ! 1293: otherDev->sync.state = FROZEN_NO_EVENT; ! 1294: else ! 1295: otherDev->sync.other = thisDev->grab; ! 1296: /* fall through */ ! 1297: case FREEZE_NEXT_EVENT: ! 1298: thisDev->sync.state = FROZEN_WITH_EVENT; ! 1299: thisDev->sync.frozen = TRUE; ! 1300: thisDev->sync.event = *xE; ! 1301: break; ! 1302: } ! 1303: } ! 1304: ! 1305: void ! 1306: ProcessKeyboardEvent (xE, keybd) ! 1307: register xEvent *xE; ! 1308: register DeviceIntPtr keybd; ! 1309: { ! 1310: int key, bit; ! 1311: register BYTE *kptr; ! 1312: register int i; ! 1313: register CARD16 modifiers; ! 1314: register CARD16 mask; ! 1315: ! 1316: GrabPtr grab = keybd->grab; ! 1317: Bool deactivateGrab = FALSE; ! 1318: ! 1319: if (keybd->sync.frozen) ! 1320: { ! 1321: EnqueueEvent(keybd, xE); ! 1322: return; ! 1323: } ! 1324: NoticeTimeAndState(xE); ! 1325: key = xE->u.u.detail; ! 1326: kptr = &keybd->down[key >> 3]; ! 1327: bit = 1 << (key & 7); ! 1328: modifiers = keyModifiersList[key]; ! 1329: lastWasMotion = FALSE; ! 1330: switch (xE->u.u.type) ! 1331: { ! 1332: case KeyPress: ! 1333: if (*kptr & bit) /* allow ddx to generate multiple downs */ ! 1334: { ! 1335: if (!modifiers) ! 1336: { ! 1337: xE->u.u.type = KeyRelease; ! 1338: ProcessKeyboardEvent(xE, keybd); ! 1339: xE->u.u.type = KeyPress; ! 1340: /* release can have side effects, don't fall through */ ! 1341: ProcessKeyboardEvent(xE, keybd); ! 1342: } ! 1343: return; ! 1344: } ! 1345: *kptr |= bit; ! 1346: for (i = 0, mask = 1; modifiers; i++, mask <<= 1) ! 1347: { ! 1348: if (mask & modifiers) { ! 1349: /* This key affects modifier "i" */ ! 1350: modifierKeyCount[i]++; ! 1351: keyButtonState |= mask; ! 1352: modifiers &= ~mask; ! 1353: } ! 1354: } ! 1355: if (!grab && CheckDeviceGrabs(keybd, xE, 0, TRUE)) ! 1356: { ! 1357: keyThatActivatedPassiveGrab = key; ! 1358: return; ! 1359: } ! 1360: break; ! 1361: case KeyRelease: ! 1362: if (!(*kptr & bit)) /* guard against duplicates */ ! 1363: return; ! 1364: *kptr &= ~bit; ! 1365: for (i = 0, mask = 1; modifiers; i++, mask <<= 1) ! 1366: { ! 1367: if (mask & modifiers) { ! 1368: /* This key affects modifier "i" */ ! 1369: if (--modifierKeyCount[i] <= 0) { ! 1370: keyButtonState &= ~mask; ! 1371: modifierKeyCount[i] = 0; ! 1372: } ! 1373: modifiers &= ~mask; ! 1374: } ! 1375: } ! 1376: if ((keybd->u.keybd.passiveGrab) && ! 1377: (key == keyThatActivatedPassiveGrab)) ! 1378: deactivateGrab = TRUE; ! 1379: break; ! 1380: default: ! 1381: FatalError("Impossible keyboard event"); ! 1382: } ! 1383: if (grab) ! 1384: DeliverGrabbedEvent(xE, keybd, inputInfo.pointer, deactivateGrab); ! 1385: else ! 1386: NormalKeyboardEvent(keybd, xE, sprite.win); ! 1387: if (deactivateGrab) ! 1388: DeactivateKeyboardGrab(keybd); ! 1389: } ! 1390: ! 1391: void ! 1392: ProcessPointerEvent (xE, mouse) ! 1393: register xEvent *xE; ! 1394: register DeviceIntPtr mouse; ! 1395: { ! 1396: register int key; ! 1397: register GrabPtr grab = mouse->grab; ! 1398: Bool moveIt = FALSE; ! 1399: Bool deactivateGrab = FALSE; ! 1400: ! 1401: if (xE->u.keyButtonPointer.rootX < sprite.physLimits.x1) ! 1402: { ! 1403: xE->u.keyButtonPointer.rootX = sprite.physLimits.x1; ! 1404: moveIt = TRUE; ! 1405: } ! 1406: else if (xE->u.keyButtonPointer.rootX >= sprite.physLimits.x2) ! 1407: { ! 1408: xE->u.keyButtonPointer.rootX = sprite.physLimits.x2 - 1; ! 1409: moveIt = TRUE; ! 1410: } ! 1411: if (xE->u.keyButtonPointer.rootY < sprite.physLimits.y1) ! 1412: { ! 1413: xE->u.keyButtonPointer.rootY = sprite.physLimits.y1; ! 1414: moveIt = TRUE; ! 1415: } ! 1416: else if (xE->u.keyButtonPointer.rootY >= sprite.physLimits.y2) ! 1417: { ! 1418: xE->u.keyButtonPointer.rootY = sprite.physLimits.y2 - 1; ! 1419: moveIt = TRUE; ! 1420: } ! 1421: if (moveIt) ! 1422: (*currentScreen->SetCursorPosition)( ! 1423: currentScreen, xE->u.keyButtonPointer.rootX, ! 1424: xE->u.keyButtonPointer.rootY, FALSE); ! 1425: if (mouse->sync.frozen) ! 1426: { ! 1427: EnqueueEvent(mouse, xE); ! 1428: return; ! 1429: } ! 1430: NoticeTimeAndState(xE); ! 1431: key = xE->u.u.detail; ! 1432: switch (xE->u.u.type) ! 1433: { ! 1434: case ButtonPress: ! 1435: lastWasMotion = FALSE; ! 1436: buttonsDown++; ! 1437: xE->u.u.detail = mouse->u.ptr.map[key]; ! 1438: if (xE->u.u.detail <= 5) ! 1439: keyButtonState |= keyModifiersList[xE->u.u.detail]; ! 1440: if (!grab) ! 1441: if (CheckDeviceGrabs(mouse, xE, 0, FALSE)) ! 1442: return; ! 1443: break; ! 1444: case ButtonRelease: ! 1445: lastWasMotion = FALSE; ! 1446: buttonsDown--; ! 1447: xE->u.u.detail = mouse->u.ptr.map[key]; ! 1448: if (xE->u.u.detail <= 5) ! 1449: keyButtonState &= ~keyModifiersList[xE->u.u.detail]; ! 1450: if ((!(keyButtonState & AllButtonsMask)) && ! 1451: (mouse->u.ptr.autoReleaseGrab)) ! 1452: deactivateGrab = TRUE; ! 1453: break; ! 1454: case MotionNotify: ! 1455: if (!CheckMotion(xE->u.keyButtonPointer.rootX, ! 1456: xE->u.keyButtonPointer.rootY, ! 1457: FALSE)) ! 1458: return; ! 1459: break; ! 1460: default: ! 1461: FatalError("bogus pointer event from ddx"); ! 1462: } ! 1463: buttonMotionMask = (buttonsDown) ? ButtonMotionMask : 0; ! 1464: if (grab) ! 1465: DeliverGrabbedEvent(xE, mouse, inputInfo.keyboard, deactivateGrab); ! 1466: else ! 1467: DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow); ! 1468: if (deactivateGrab) ! 1469: DeactivatePointerGrab(mouse); ! 1470: } ! 1471: ! 1472: void ! 1473: ProcessOtherEvent (xE, pDevice) ! 1474: xEvent *xE; ! 1475: DevicePtr pDevice; ! 1476: { ! 1477: /* XXX What should be done here ? ! 1478: Bool propogate = filters[xE->type]; ! 1479: */ ! 1480: } ! 1481: ! 1482: #define AtMostOneClient \ ! 1483: (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask) ! 1484: ! 1485: void ! 1486: RecalculateDeliverableEvents(pWin) ! 1487: WindowPtr pWin; ! 1488: { ! 1489: OtherClients * others; ! 1490: WindowPtr child; ! 1491: ! 1492: pWin->allEventMasks = pWin->eventMask; ! 1493: for (others = OTHERCLIENTS(pWin); others; others = others->next) ! 1494: { ! 1495: pWin->allEventMasks |= others->mask; ! 1496: } ! 1497: if (pWin->parent) ! 1498: pWin->deliverableEvents = pWin->allEventMasks | ! 1499: (pWin->parent->deliverableEvents & ~pWin->dontPropagateMask & ! 1500: PropagateMask); ! 1501: else ! 1502: pWin->deliverableEvents = pWin->allEventMasks; ! 1503: for (child = pWin->firstChild; child; child = child->nextSib) ! 1504: RecalculateDeliverableEvents(child); ! 1505: } ! 1506: ! 1507: static void ! 1508: OtherClientGone(pWin, id) ! 1509: WindowPtr pWin; ! 1510: long id; ! 1511: { ! 1512: register OtherClientsPtr *next; ! 1513: register OtherClientsPtr other; ! 1514: ! 1515: for (next = (OtherClientsPtr *)&(pWin->otherClients); ! 1516: *next; next = &((*next)->next)) ! 1517: { ! 1518: if ((other = *next)->resource == id) ! 1519: { ! 1520: *next = other->next; ! 1521: Xfree(other); ! 1522: RecalculateDeliverableEvents(pWin); ! 1523: return; ! 1524: } ! 1525: } ! 1526: FatalError("client not on event list"); ! 1527: } ! 1528: ! 1529: void ! 1530: PassiveClientGone(pWin, id) ! 1531: WindowPtr pWin; ! 1532: long id; ! 1533: { ! 1534: register GrabPtr *next; ! 1535: register GrabPtr grab; ! 1536: ! 1537: for (next = (GrabPtr *)&(pWin->passiveGrabs); ! 1538: *next; next = &((*next)->next)) ! 1539: { ! 1540: if ((grab = *next)->resource == id) ! 1541: { ! 1542: *next = grab->next; ! 1543: Xfree(grab); ! 1544: return; ! 1545: } ! 1546: } ! 1547: FatalError("client not on passive grab list"); ! 1548: } ! 1549: ! 1550: int ! 1551: EventSelectForWindow(pWin, client, mask) ! 1552: WindowPtr pWin; ! 1553: ClientPtr client; ! 1554: Mask mask; ! 1555: { ! 1556: Mask check; ! 1557: OtherClients * others; ! 1558: ! 1559: check = (mask & AtMostOneClient); ! 1560: if (check & pWin->allEventMasks) ! 1561: { /* It is illegal for two different ! 1562: clients to select on any of the ! 1563: events for AtMostOneClient. However, ! 1564: it is OK, for some client to ! 1565: continue selecting on one of those ! 1566: events. */ ! 1567: if ((pWin->client != client) && (check & pWin->eventMask)) ! 1568: return BadAccess; ! 1569: for (others = OTHERCLIENTS(pWin); others; others = others->next) ! 1570: { ! 1571: if ((others->client != client) && (check & others->mask)) ! 1572: return BadAccess; ! 1573: } ! 1574: } ! 1575: if (pWin->client == client) ! 1576: pWin->eventMask = mask; ! 1577: else ! 1578: { ! 1579: for (others = OTHERCLIENTS(pWin); others; others = others->next) ! 1580: { ! 1581: if (others->client == client) ! 1582: { ! 1583: if (mask == 0) ! 1584: { ! 1585: FreeResource(others->resource, RC_NONE); ! 1586: return Success; ! 1587: } ! 1588: else ! 1589: others->mask = mask; ! 1590: goto maskSet; ! 1591: } ! 1592: } ! 1593: others = (OtherClients *) Xalloc(sizeof(OtherClients)); ! 1594: others->client = client; ! 1595: others->mask = mask; ! 1596: others->resource = FakeClientID(client->index); ! 1597: others->next = OTHERCLIENTS(pWin); ! 1598: pWin->otherClients = (pointer)others; ! 1599: AddResource(others->resource, RT_FAKE, pWin, OtherClientGone, RC_CORE); ! 1600: } ! 1601: maskSet: ! 1602: RecalculateDeliverableEvents(pWin); ! 1603: return Success; ! 1604: } ! 1605: ! 1606: int ! 1607: EventSuppressForWindow(pWin, client, mask) ! 1608: WindowPtr pWin; ! 1609: ClientPtr client; ! 1610: Mask mask; ! 1611: { ! 1612: pWin->dontPropagateMask = mask; ! 1613: RecalculateDeliverableEvents(pWin); ! 1614: return Success; ! 1615: } ! 1616: ! 1617: ! 1618: /* returns true if b is a descendent of a */ ! 1619: static Bool ! 1620: IsParent(a, b) ! 1621: register WindowPtr a, b; ! 1622: { ! 1623: for (b = b->parent; b; b = b->parent) ! 1624: if (b == a) return TRUE; ! 1625: return FALSE; ! 1626: } ! 1627: ! 1628: static WindowPtr ! 1629: CommonAncestor(a, b) ! 1630: register WindowPtr a, b; ! 1631: { ! 1632: for (b = b->parent; b; b = b->parent) ! 1633: if (IsParent(b, a)) return b; ! 1634: return NullWindow; ! 1635: } ! 1636: ! 1637: static void ! 1638: EnterLeaveEvent(type, mode, detail, pWin) ! 1639: int type, mode, detail; ! 1640: WindowPtr pWin; ! 1641: { ! 1642: xEvent event; ! 1643: DeviceIntPtr keybd = inputInfo.keyboard; ! 1644: WindowPtr focus = keybd->u.keybd.focus.win; ! 1645: ! 1646: event.u.u.type = type; ! 1647: event.u.u.detail = detail; ! 1648: event.u.enterLeave.time = currentTime.milliseconds; ! 1649: event.u.enterLeave.rootX = sprite.hot.x; ! 1650: event.u.enterLeave.rootY = sprite.hot.y; ! 1651: FixUpEventFromWindow(&event, pWin, None, TRUE); ! 1652: /* This call counts on same initial structure beween enter & button events */ ! 1653: event.u.enterLeave.state = keyButtonState; ! 1654: event.u.enterLeave.mode = mode; ! 1655: event.u.enterLeave.flags = ELFlagSameScreen; /* XXX */ ! 1656: if ((focus != NoneWin) && ! 1657: ((pWin == focus) || (focus == PointerRootWin) || ! 1658: IsParent(focus, pWin))) ! 1659: event.u.enterLeave.flags |= ELFlagFocus; ! 1660: DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab); ! 1661: if (type == EnterNotify) ! 1662: { ! 1663: xKeymapEvent ke; ! 1664: ke.type = KeymapNotify; ! 1665: bcopy(&keybd->down[1], &ke.map[0], 31); ! 1666: } ! 1667: } ! 1668: ! 1669: static void ! 1670: EnterNotifies(ancestor, child, mode, detail) ! 1671: WindowPtr ancestor, child; ! 1672: int mode, detail; ! 1673: { ! 1674: if (!child || (ancestor == child)) ! 1675: return; ! 1676: EnterNotifies(ancestor, child->parent, mode, detail); ! 1677: EnterLeaveEvent(EnterNotify, mode, detail, child); ! 1678: } ! 1679: ! 1680: /* dies horribly if ancestor is not an ancestor of child */ ! 1681: static void ! 1682: LeaveNotifies(child, ancestor, mode, detail, doAncestor) ! 1683: WindowPtr child, ancestor; ! 1684: int detail, mode; ! 1685: { ! 1686: register WindowPtr pWin; ! 1687: ! 1688: if (ancestor == child) ! 1689: return; ! 1690: for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent) ! 1691: EnterLeaveEvent(LeaveNotify, mode, detail, pWin); ! 1692: if (doAncestor) ! 1693: EnterLeaveEvent(LeaveNotify, mode, detail, ancestor); ! 1694: } ! 1695: ! 1696: static void ! 1697: DoEnterLeaveEvents(fromWin, toWin, mode) ! 1698: WindowPtr fromWin, toWin; ! 1699: int mode; ! 1700: { ! 1701: if (fromWin == toWin) ! 1702: return; ! 1703: if (IsParent(fromWin, toWin)) ! 1704: { ! 1705: EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin); ! 1706: EnterNotifies(fromWin, toWin->parent, mode, NotifyVirtual); ! 1707: EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin); ! 1708: } ! 1709: else if (IsParent(toWin, fromWin)) ! 1710: { ! 1711: EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin); ! 1712: LeaveNotifies(fromWin, toWin, mode, NotifyVirtual, FALSE); ! 1713: EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin); ! 1714: } ! 1715: else ! 1716: { /* neither fromWin nor toWin is descendent of the other */ ! 1717: WindowPtr common = CommonAncestor(toWin, fromWin); ! 1718: /* common == NullWindow ==> different screens */ ! 1719: EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin); ! 1720: if (common) ! 1721: { ! 1722: LeaveNotifies( ! 1723: fromWin, common, mode, NotifyNonlinearVirtual, FALSE); ! 1724: EnterNotifies(common, toWin->parent, mode, NotifyNonlinearVirtual); ! 1725: } ! 1726: else ! 1727: { ! 1728: LeaveNotifies( ! 1729: fromWin, RootForWindow(fromWin), mode, ! 1730: NotifyNonlinearVirtual, TRUE); ! 1731: EnterNotifies( ! 1732: RootForWindow(toWin), toWin->parent, mode, NotifyNonlinearVirtual); ! 1733: } ! 1734: EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin); ! 1735: } ! 1736: } ! 1737: ! 1738: static void ! 1739: FocusEvent(type, mode, detail, pWin) ! 1740: int type, mode, detail; ! 1741: WindowPtr pWin; ! 1742: { ! 1743: xEvent event; ! 1744: DeviceIntPtr keybd = inputInfo.keyboard; ! 1745: ! 1746: event.u.focus.mode = mode; ! 1747: event.u.u.type = type; ! 1748: event.u.u.detail = detail; ! 1749: event.u.focus.window = pWin->wid; ! 1750: DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab); ! 1751: if (type == FocusIn) ! 1752: { ! 1753: xKeymapEvent ke; ! 1754: ke.type = KeymapNotify; ! 1755: bcopy(keybd->down, &ke.map[0], 31); ! 1756: DeliverEventsToWindow(pWin, &event, 1, KeymapStateMask, NullGrab); ! 1757: } ! 1758: } ! 1759: ! 1760: /* ! 1761: * recursive because it is easier ! 1762: * no-op if child not descended from ancestor ! 1763: */ ! 1764: static Bool ! 1765: FocusInEvents(ancestor, child, skipChild, mode, detail, doAncestor) ! 1766: WindowPtr ancestor, child, skipChild; ! 1767: int mode, detail; ! 1768: Bool doAncestor; ! 1769: { ! 1770: if (child == NullWindow) ! 1771: return FALSE; ! 1772: if (ancestor == child) ! 1773: { ! 1774: if (doAncestor) ! 1775: FocusEvent(FocusIn, mode, detail, child); ! 1776: return TRUE; ! 1777: } ! 1778: if (FocusInEvents( ! 1779: ancestor, child->parent, skipChild, mode, detail, doAncestor)) ! 1780: { ! 1781: if (child != skipChild) ! 1782: FocusEvent(FocusIn, mode, detail, child); ! 1783: return TRUE; ! 1784: } ! 1785: return FALSE; ! 1786: } ! 1787: ! 1788: /* dies horribly if ancestor is not an ancestor of child */ ! 1789: static void ! 1790: FocusOutEvents(child, ancestor, mode, detail, doAncestor) ! 1791: WindowPtr child, ancestor; ! 1792: int detail; ! 1793: Bool doAncestor; ! 1794: { ! 1795: register WindowPtr pWin; ! 1796: ! 1797: for (pWin = child; pWin != ancestor; pWin = pWin->parent) ! 1798: FocusEvent(FocusOut, mode, detail, pWin); ! 1799: if (doAncestor) ! 1800: FocusEvent(FocusOut, mode, detail, ancestor); ! 1801: } ! 1802: ! 1803: static void ! 1804: DoFocusEvents(fromWin, toWin, mode) ! 1805: WindowPtr fromWin, toWin; ! 1806: int mode; ! 1807: { ! 1808: int out, in; /* for holding details for to/from ! 1809: PointerRoot/None */ ! 1810: int i; ! 1811: ! 1812: out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot; ! 1813: in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot; ! 1814: /* wrong values if neither, but then not referenced */ ! 1815: ! 1816: if ((toWin == NullWindow) || (toWin == PointerRootWin)) ! 1817: { ! 1818: if ((fromWin == NullWindow) || (fromWin == PointerRootWin)) ! 1819: { ! 1820: if (fromWin == PointerRootWin) ! 1821: FocusOutEvents(sprite.win, ROOT, mode, NotifyPointer, TRUE); ! 1822: /* Notify all the roots */ ! 1823: for (i=0; i<screenInfo.numScreens; i++) ! 1824: FocusEvent(FocusOut, mode, out, &WindowTable[i]); ! 1825: } ! 1826: else ! 1827: { ! 1828: if (IsParent(fromWin, sprite.win)) ! 1829: FocusOutEvents(sprite.win, fromWin, mode, NotifyPointer, FALSE); ! 1830: FocusEvent(FocusOut, mode, NotifyNonlinear, fromWin); ! 1831: /* next call catches the root too, if the screen changed */ ! 1832: FocusOutEvents( fromWin->parent, NullWindow, mode, ! 1833: NotifyNonlinearVirtual, FALSE); ! 1834: } ! 1835: /* Notify all the roots */ ! 1836: for (i=0; i<screenInfo.numScreens; i++) ! 1837: FocusEvent(FocusIn, mode, in, &WindowTable[i]); ! 1838: if (toWin == PointerRootWin) ! 1839: FocusInEvents( ! 1840: ROOT, sprite.win, NullWindow, mode, NotifyPointer, TRUE); ! 1841: } ! 1842: else ! 1843: { ! 1844: if ((fromWin == NullWindow) || (fromWin == PointerRootWin)) ! 1845: { ! 1846: if (fromWin == PointerRootWin) ! 1847: FocusOutEvents(sprite.win, ROOT, mode, NotifyPointer, TRUE); ! 1848: for (i=0; i<screenInfo.numScreens; i++) ! 1849: FocusEvent(FocusOut, mode, out, &WindowTable[i]); ! 1850: if (toWin->parent != NullWindow) ! 1851: FocusInEvents( ! 1852: ROOT, toWin, toWin, mode, NotifyNonlinearVirtual, TRUE); ! 1853: FocusEvent(FocusIn, mode, NotifyNonlinear, toWin); ! 1854: if (IsParent(toWin, sprite.win)) ! 1855: FocusInEvents( ! 1856: toWin, sprite.win, NullWindow, mode, NotifyPointer, FALSE); ! 1857: } ! 1858: else ! 1859: { ! 1860: if (IsParent(toWin, fromWin)) ! 1861: { ! 1862: FocusEvent(FocusOut, mode, NotifyAncestor, fromWin); ! 1863: FocusOutEvents( ! 1864: fromWin->parent, toWin, mode, NotifyVirtual, FALSE); ! 1865: FocusEvent(FocusIn, mode, NotifyInferior, toWin); ! 1866: if ((IsParent(toWin, sprite.win)) && ! 1867: (sprite.win != fromWin) && ! 1868: (!IsParent(fromWin, sprite.win)) && ! 1869: (!IsParent(sprite.win, fromWin))) ! 1870: FocusInEvents( ! 1871: toWin, sprite.win, NullWindow, mode, ! 1872: NotifyPointer, FALSE); ! 1873: } ! 1874: else ! 1875: if (IsParent(fromWin, toWin)) ! 1876: { ! 1877: if ((IsParent(fromWin, sprite.win)) && ! 1878: (sprite.win != fromWin) && ! 1879: (!IsParent(toWin, sprite.win)) && ! 1880: (!IsParent(sprite.win, toWin))) ! 1881: FocusOutEvents( ! 1882: sprite.win, fromWin, mode, NotifyPointer, FALSE); ! 1883: FocusEvent(FocusOut, mode, NotifyInferior, fromWin); ! 1884: FocusInEvents( ! 1885: fromWin, toWin, toWin, mode, NotifyVirtual, FALSE); ! 1886: FocusEvent(FocusIn, mode, NotifyAncestor, toWin); ! 1887: } ! 1888: else ! 1889: { ! 1890: /* neither fromWin or toWin is child of other */ ! 1891: WindowPtr common = CommonAncestor(toWin, fromWin); ! 1892: /* common == NullWindow ==> different screens XXX */ ! 1893: if (IsParent(fromWin, sprite.win)) ! 1894: FocusOutEvents( ! 1895: sprite.win, fromWin, mode, NotifyPointer, FALSE); ! 1896: FocusEvent(FocusOut, mode, NotifyNonlinear, fromWin); ! 1897: if (fromWin->parent != NullWindow) ! 1898: FocusOutEvents( ! 1899: fromWin->parent, common, mode, NotifyNonlinearVirtual, ! 1900: FALSE); ! 1901: if (toWin->parent != NullWindow) ! 1902: FocusInEvents( ! 1903: common, toWin, toWin, mode, NotifyNonlinearVirtual, ! 1904: FALSE); ! 1905: FocusEvent(FocusIn, mode, NotifyNonlinear, toWin); ! 1906: if (IsParent(toWin, sprite.win)) ! 1907: FocusInEvents( ! 1908: toWin, sprite.win, NullWindow, mode, ! 1909: NotifyPointer, FALSE); ! 1910: } ! 1911: } ! 1912: } ! 1913: } ! 1914: ! 1915: /* XXX SetInputFocus does not enumerate all roots, handle screen crossings */ ! 1916: int ! 1917: ProcSetInputFocus(client) ! 1918: ClientPtr client; ! 1919: { ! 1920: TimeStamp time; ! 1921: WindowPtr focusWin; ! 1922: int mode; ! 1923: register DeviceIntPtr kbd = inputInfo.keyboard; ! 1924: register FocusPtr focus = &kbd->u.keybd.focus; ! 1925: REQUEST(xSetInputFocusReq); ! 1926: ! 1927: REQUEST_SIZE_MATCH(xSetInputFocusReq); ! 1928: if ((stuff->revertTo != RevertToParent) && ! 1929: (stuff->revertTo != RevertToPointerRoot) && ! 1930: (stuff->revertTo != RevertToNone)) ! 1931: { ! 1932: client->errorValue = stuff->revertTo; ! 1933: return BadValue; ! 1934: } ! 1935: time = ClientTimeToServerTime(stuff->time); ! 1936: if ((stuff->focus == None) || (stuff->focus == PointerRoot)) ! 1937: focusWin = (WindowPtr)(stuff->focus); ! 1938: else if (!(focusWin = LookupWindow(stuff->focus, client))) ! 1939: { ! 1940: client->errorValue = stuff->focus; ! 1941: return BadWindow; ! 1942: } ! 1943: else ! 1944: { ! 1945: /* It is a match error to try to set the input focus to an ! 1946: unviewable window. */ ! 1947: ! 1948: if(!focusWin->realized) ! 1949: return(BadMatch); ! 1950: } ! 1951: ! 1952: if ((CompareTimeStamps(time, currentTime) == LATER) || ! 1953: (CompareTimeStamps(time, focus->time) == EARLIER)) ! 1954: return Success; ! 1955: ! 1956: mode = (kbd->grab) ? NotifyWhileGrabbed : NotifyNormal; ! 1957: ! 1958: /* If the client attempts to set the input focus to the window that already ! 1959: is the focus window and the mode of the focus events that would be ! 1960: reported are the same as the the mode of the focus events caused by ! 1961: the last ProcSetInputFocus, then this routine does nothing. It's ! 1962: unclear what the protocol document intends when the input focus is set ! 1963: to the same window, but at least the number of events reported is kept ! 1964: to a mininum. PRH */ ! 1965: ! 1966: if ((focusWin == focus->win) && (mode == lastInputFocusChangeMode)) ! 1967: return Success; ! 1968: ! 1969: lastInputFocusChangeMode = mode; ! 1970: ! 1971: DoFocusEvents(focus->win, focusWin, mode); ! 1972: focus->time = time; ! 1973: focus->revert = stuff->revertTo; ! 1974: focus->win = focusWin; ! 1975: if ((focusWin == NoneWin) || (focusWin == PointerRootWin)) ! 1976: focusTraceGood = 0; ! 1977: else ! 1978: { ! 1979: int depth=0; ! 1980: WindowPtr pWin; ! 1981: for (pWin = focusWin; pWin; pWin = pWin->parent) depth++; ! 1982: if (depth > focusTraceSize) ! 1983: { ! 1984: focusTraceSize = depth+1; ! 1985: focusTrace = (WindowPtr *)Xrealloc( ! 1986: focusTrace, focusTraceSize*sizeof(WindowPtr)); ! 1987: } ! 1988: ! 1989: focusTraceGood = depth; ! 1990: ! 1991: for (pWin = focusWin; pWin; pWin = pWin->parent, depth--) ! 1992: focusTrace[depth-1] = pWin; ! 1993: } ! 1994: return Success; ! 1995: } ! 1996: ! 1997: int ! 1998: ProcGetInputFocus(client) ! 1999: ClientPtr client; ! 2000: { ! 2001: xGetInputFocusReply rep; ! 2002: REQUEST(xReq); ! 2003: FocusPtr focus = &(inputInfo.keyboard->u.keybd.focus); ! 2004: ! 2005: REQUEST_SIZE_MATCH(xReq); ! 2006: rep.type = X_Reply; ! 2007: rep.length = 0; ! 2008: rep.sequenceNumber = client->sequence; ! 2009: if (focus->win == NoneWin) ! 2010: rep.focus = None; ! 2011: else if (focus->win == PointerRootWin) ! 2012: rep.focus = PointerRoot; ! 2013: else rep.focus = focus->win->wid; ! 2014: rep.revertTo = focus->revert; ! 2015: WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep); ! 2016: return Success; ! 2017: } ! 2018: ! 2019: int ! 2020: ProcGrabPointer(client) ! 2021: ClientPtr client; ! 2022: { ! 2023: xGrabPointerReply rep; ! 2024: DeviceIntPtr device = inputInfo.pointer; ! 2025: GrabPtr grab = device->grab; ! 2026: WindowPtr pWin, confineTo; ! 2027: CursorPtr cursor; ! 2028: REQUEST(xGrabPointerReq); ! 2029: TimeStamp time; ! 2030: ! 2031: REQUEST_SIZE_MATCH(xGrabPointerReq); ! 2032: if ((stuff->pointerMode != GrabModeSync) && ! 2033: (stuff->pointerMode != GrabModeAsync) && ! 2034: (stuff->keyboardMode != GrabModeSync) && ! 2035: (stuff->keyboardMode != GrabModeAsync)) ! 2036: return BadValue; ! 2037: ! 2038: pWin = LookupWindow(stuff->grabWindow, client); ! 2039: if (!pWin) ! 2040: { ! 2041: client->errorValue = stuff->grabWindow; ! 2042: return BadWindow; ! 2043: } ! 2044: if (stuff->confineTo == None) ! 2045: confineTo = NullWindow; ! 2046: else ! 2047: { ! 2048: confineTo = LookupWindow(stuff->grabWindow, client); ! 2049: if (!confineTo) ! 2050: { ! 2051: client->errorValue = stuff->grabWindow; ! 2052: return BadWindow; ! 2053: } ! 2054: } ! 2055: if (stuff->cursor == None) ! 2056: cursor = NullCursor; ! 2057: else ! 2058: { ! 2059: cursor = (CursorPtr)LookupID(stuff->cursor, RT_CURSOR, RC_CORE); ! 2060: if (!cursor) ! 2061: return BadCursor; ! 2062: } ! 2063: /* at this point, some sort of reply is guaranteed. */ ! 2064: time = ClientTimeToServerTime(stuff->time); ! 2065: rep.type = X_Reply; ! 2066: rep.sequenceNumber = client->sequence; ! 2067: rep.length = 0; ! 2068: if ((grab) && (grab->client != client)) ! 2069: rep.status = AlreadyGrabbed; ! 2070: else if (!pWin->realized) ! 2071: rep.status = GrabNotViewable; ! 2072: else if (device->sync.frozen && ! 2073: ((device->sync.other && (device->sync.other->client != client)) || ! 2074: ((device->sync.state >= FROZEN) && ! 2075: (device->grab->client != client)))) ! 2076: rep.status = GrabFrozen; ! 2077: else if ((CompareTimeStamps(time, currentTime) == LATER) || ! 2078: (device->grab && ! 2079: (CompareTimeStamps(time, device->grabTime) == EARLIER))) ! 2080: rep.status = GrabInvalidTime; ! 2081: else ! 2082: { ! 2083: ptrGrab.u.ptr.cursor = cursor; ! 2084: ptrGrab.client = client; ! 2085: ptrGrab.ownerEvents = stuff->ownerEvents; ! 2086: ptrGrab.eventMask = stuff->eventMask; ! 2087: ptrGrab.u.ptr.confineTo = confineTo; ! 2088: ptrGrab.window = pWin; ! 2089: ptrGrab.keyboardMode = stuff->keyboardMode; ! 2090: ptrGrab.pointerMode = stuff->pointerMode; ! 2091: ptrGrab.device = inputInfo.pointer; ! 2092: ActivatePointerGrab(inputInfo.pointer, &ptrGrab, time, FALSE); ! 2093: rep.status = GrabSuccess; ! 2094: } ! 2095: WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep); ! 2096: if (cursor) ! 2097: ChangeToCursor(cursor); ! 2098: return Success; ! 2099: } ! 2100: ! 2101: int ! 2102: ProcChangeActivePointerGrab(client) ! 2103: ClientPtr client; ! 2104: { ! 2105: DeviceIntPtr device = inputInfo.pointer; ! 2106: register GrabPtr grab = device->grab; ! 2107: CursorPtr newCursor; ! 2108: REQUEST(xChangeActivePointerGrabReq); ! 2109: TimeStamp time; ! 2110: ! 2111: REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq); ! 2112: if (!grab) ! 2113: return Success; ! 2114: if (grab->client != client) ! 2115: return BadAccess; ! 2116: if (stuff->cursor == None) ! 2117: grab->u.ptr.cursor = NullCursor; ! 2118: else ! 2119: { ! 2120: newCursor = (CursorPtr)LookupID(stuff->cursor, RT_CURSOR, RC_CORE); ! 2121: if (!newCursor) ! 2122: return BadCursor; ! 2123: } ! 2124: time = ClientTimeToServerTime(stuff->time); ! 2125: if ((CompareTimeStamps(time, currentTime) == LATER) || ! 2126: (CompareTimeStamps(time, device->grabTime) == EARLIER)) ! 2127: return Success; ! 2128: grab->u.ptr.cursor = newCursor; ! 2129: PostNewCursor(); ! 2130: /* if mouse motion is newly turned on, it should probably send a motion ! 2131: event */ ! 2132: grab->eventMask = stuff->eventMask; ! 2133: return Success; ! 2134: } ! 2135: ! 2136: int ! 2137: ProcUngrabPointer(client) ! 2138: ClientPtr client; ! 2139: { ! 2140: DeviceIntPtr device = inputInfo.pointer; ! 2141: GrabPtr grab = device->grab; ! 2142: TimeStamp time; ! 2143: REQUEST(xResourceReq); ! 2144: ! 2145: REQUEST_SIZE_MATCH(xResourceReq); ! 2146: time = ClientTimeToServerTime(stuff->id); ! 2147: if ((CompareTimeStamps(time, currentTime) != LATER) && ! 2148: (CompareTimeStamps(time, device->grabTime) != EARLIER) && ! 2149: (grab) && (grab->client == client)) ! 2150: DeactivatePointerGrab(inputInfo.pointer); ! 2151: return Success; ! 2152: } ! 2153: ! 2154: int ! 2155: ProcGrabKeyboard(client) ! 2156: ClientPtr client; ! 2157: { ! 2158: xGrabKeyboardReply rep; ! 2159: DeviceIntPtr device = inputInfo.keyboard; ! 2160: GrabPtr grab = device->grab; ! 2161: WindowPtr pWin, oldWin; ! 2162: TimeStamp time; ! 2163: REQUEST(xGrabKeyboardReq); ! 2164: ! 2165: REQUEST_SIZE_MATCH(xGrabKeyboardReq); ! 2166: if ((stuff->pointerMode != GrabModeSync) && ! 2167: (stuff->pointerMode != GrabModeAsync) && ! 2168: (stuff->keyboardMode != GrabModeSync) && ! 2169: (stuff->keyboardMode != GrabModeAsync)) ! 2170: return BadValue; ! 2171: pWin = LookupWindow(stuff->grabWindow, client); ! 2172: if (!pWin) ! 2173: { ! 2174: client->errorValue = stuff->grabWindow; ! 2175: return BadWindow; ! 2176: } ! 2177: time = ClientTimeToServerTime(stuff->time); ! 2178: rep.type = X_Reply; ! 2179: rep.sequenceNumber = client->sequence; ! 2180: rep.length = 0; ! 2181: if ((grab) && (grab->client != client)) ! 2182: rep.status = AlreadyGrabbed; ! 2183: else if (!pWin->realized) ! 2184: rep.status = GrabNotViewable; ! 2185: else if ((CompareTimeStamps(time, currentTime) == LATER) || ! 2186: (device->grab && ! 2187: (CompareTimeStamps(time, device->grabTime) == EARLIER))) ! 2188: rep.status = GrabInvalidTime; ! 2189: else if (device->sync.frozen && ! 2190: ((device->sync.other && (device->sync.other->client != client)) || ! 2191: ((device->sync.state >= FROZEN) && ! 2192: (device->grab->client != client)))) ! 2193: rep.status = GrabFrozen; ! 2194: else ! 2195: { ! 2196: /* If a keyboard grab is already in effect, store the old grab window.*/ ! 2197: ! 2198: oldWin = (grab) ? keybdGrab.window : device->u.keybd.focus.win; ! 2199: keybdGrab.window = pWin; ! 2200: keybdGrab.client = client; ! 2201: keybdGrab.ownerEvents = stuff->ownerEvents; ! 2202: keybdGrab.keyboardMode = stuff->keyboardMode; ! 2203: keybdGrab.pointerMode = stuff->pointerMode; ! 2204: keybdGrab.eventMask = KeyPressMask | KeyReleaseMask; ! 2205: keybdGrab.device = inputInfo.keyboard; ! 2206: ActivateKeyboardGrab( ! 2207: device, &keybdGrab, ClientTimeToServerTime(stuff->time), FALSE); ! 2208: ! 2209: /* If the grab is a regrab on the same window as previous grab, don't ! 2210: generate any change of focus events. */ ! 2211: ! 2212: if (oldWin != pWin) ! 2213: DoFocusEvents(oldWin, pWin, NotifyGrab); ! 2214: rep.status = GrabSuccess; ! 2215: } ! 2216: WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep); ! 2217: return Success; ! 2218: } ! 2219: ! 2220: int ! 2221: ProcUngrabKeyboard(client) ! 2222: ClientPtr client; ! 2223: { ! 2224: DeviceIntPtr device = inputInfo.keyboard; ! 2225: GrabPtr grab = device->grab; ! 2226: TimeStamp time; ! 2227: REQUEST(xResourceReq); ! 2228: ! 2229: REQUEST_SIZE_MATCH(xResourceReq); ! 2230: time = ClientTimeToServerTime(stuff->id); ! 2231: if ((CompareTimeStamps(time, currentTime) != LATER) && ! 2232: (CompareTimeStamps(time, device->grabTime) != EARLIER) && ! 2233: (grab) && (grab->client == client)) ! 2234: { ! 2235: DoFocusEvents(grab->window, device->u.keybd.focus.win, NotifyUngrab); ! 2236: DeactivateKeyboardGrab(device); ! 2237: } ! 2238: return Success; ! 2239: } ! 2240: ! 2241: static void ! 2242: SetPointerStateMasks(ptr) ! 2243: DevicePtr ptr; ! 2244: { ! 2245: /* all have to be defined since some button might be mapped here */ ! 2246: keyModifiersList[1] = Button1Mask; ! 2247: keyModifiersList[2] = Button2Mask; ! 2248: keyModifiersList[3] = Button3Mask; ! 2249: keyModifiersList[4] = Button4Mask; ! 2250: keyModifiersList[5] = Button5Mask; ! 2251: } ! 2252: ! 2253: static void ! 2254: SetKeyboardStateMasks(keybd) ! 2255: DeviceIntPtr keybd; ! 2256: { ! 2257: int i; ! 2258: ! 2259: /* ! 2260: * For all valid keys (from 8 up) copy the bitmap of the modifiers ! 2261: * it sets from the keyboard info into the array we use internally. ! 2262: * No need to test for bad entries - these are detected when the ! 2263: * array in the kbd struct is built. ! 2264: */ ! 2265: for (i = 8; i < MAP_LENGTH; i++) ! 2266: keyModifiersList[i] = (CARD16) keybd->u.keybd.modifierMap[i]; ! 2267: } ! 2268: ! 2269: DevicePtr ! 2270: AddInputDevice(deviceProc, autoStart) ! 2271: DeviceProc deviceProc; ! 2272: Bool autoStart; ! 2273: { ! 2274: DeviceIntPtr d; ! 2275: if (inputInfo.numDevices == inputInfo.arraySize) ! 2276: { ! 2277: inputInfo.arraySize += 5; ! 2278: inputInfo.devices = (DeviceIntPtr *)Xrealloc( ! 2279: inputInfo.devices, inputInfo.arraySize * sizeof(DeviceIntPtr)); ! 2280: } ! 2281: d = (DeviceIntPtr) Xalloc(sizeof(DeviceIntRec)); ! 2282: inputInfo.devices[inputInfo.numDevices++] = d; ! 2283: d->public.on = FALSE; ! 2284: d->public.processInputProc = NoopDDA; ! 2285: d->deviceProc = deviceProc; ! 2286: d->startup = autoStart; ! 2287: d->sync.frozen = FALSE; ! 2288: d->sync.other = NullGrab; ! 2289: d->sync.state = NOT_GRABBED; ! 2290: return &d->public; ! 2291: } ! 2292: ! 2293: DevicesDescriptor ! 2294: GetInputDevices() ! 2295: { ! 2296: DevicesDescriptor devs; ! 2297: devs.count = inputInfo.numDevices; ! 2298: devs.devices = (DevicePtr *)inputInfo.devices; ! 2299: return devs; ! 2300: } ! 2301: ! 2302: void ! 2303: InitEvents() ! 2304: { ! 2305: curKeySyms.map = (KeySym *)NULL; ! 2306: curKeySyms.minKeyCode = 0; ! 2307: curKeySyms.maxKeyCode = 0; ! 2308: curKeySyms.mapWidth = 0; ! 2309: ! 2310: currentScreen = &screenInfo.screen[0]; ! 2311: inputInfo.numDevices = 0; ! 2312: if (spriteTraceSize == 0) ! 2313: { ! 2314: spriteTraceSize = 20; ! 2315: spriteTrace = (WindowPtr *)Xalloc(20*sizeof(WindowPtr)); ! 2316: } ! 2317: spriteTraceGood = 0; ! 2318: if (focusTraceSize == 0) ! 2319: { ! 2320: focusTraceSize = 20; ! 2321: focusTrace = (WindowPtr *)Xalloc(20*sizeof(WindowPtr)); ! 2322: } ! 2323: focusTraceGood = 0; ! 2324: lastEventMask = OwnerGrabButtonMask; ! 2325: sprite.win = NullWindow; ! 2326: sprite.current = NullCursor; ! 2327: sprite.hotLimits.x1 = 0; ! 2328: sprite.hotLimits.y1 = 0; ! 2329: sprite.hotLimits.x2 = currentScreen->width; ! 2330: sprite.hotLimits.y2 = currentScreen->height; ! 2331: lastWasMotion = FALSE; ! 2332: syncEvents.replayDev = (DeviceIntPtr)NULL; ! 2333: syncEvents.pending.forw = &syncEvents.pending; ! 2334: syncEvents.pending.back = &syncEvents.pending; ! 2335: syncEvents.free.forw = &syncEvents.free; ! 2336: syncEvents.free.back = &syncEvents.free; ! 2337: syncEvents.num = 0; ! 2338: syncEvents.playingEvents = FALSE; ! 2339: currentTime.months = 0; ! 2340: currentTime.milliseconds = GetTimeInMillis(); ! 2341: } ! 2342: ! 2343: int ! 2344: InitAndStartDevices(argc, argv) ! 2345: int argc; ! 2346: char *argv[]; ! 2347: { ! 2348: int i; ! 2349: DeviceIntPtr d; ! 2350: ! 2351: for (i=0; i<8; i++) ! 2352: modifierKeyCount[i] = 0; ! 2353: ! 2354: keyButtonState = 0; ! 2355: buttonsDown = 0; ! 2356: buttonMotionMask = 0; ! 2357: ! 2358: for (i = 0; i < inputInfo.numDevices; i++) ! 2359: { ! 2360: d = inputInfo.devices[i]; ! 2361: if ((*d->deviceProc) (d, DEVICE_INIT, argc, argv) == Success) ! 2362: d->inited = TRUE; ! 2363: else ! 2364: d->inited = FALSE; ! 2365: } ! 2366: /* do not turn any devices on until all have been inited */ ! 2367: for (i = 0; i < inputInfo.numDevices; i++) ! 2368: { ! 2369: d = inputInfo.devices[i]; ! 2370: if ((d->startup) && (d->inited)) ! 2371: (*d->deviceProc) (d, DEVICE_ON, argc, argv); ! 2372: } ! 2373: if (inputInfo.pointer && inputInfo.pointer->inited && ! 2374: inputInfo.keyboard && inputInfo.keyboard->inited) ! 2375: return Success; ! 2376: return BadImplementation; ! 2377: } ! 2378: ! 2379: void ! 2380: CloseDownDevices(argc, argv) ! 2381: int argc; ! 2382: char *argv[]; ! 2383: { ! 2384: int i; ! 2385: DeviceIntPtr d; ! 2386: ! 2387: Xfree(curKeySyms.map); ! 2388: ! 2389: for (i = inputInfo.numDevices - 1; i >= 0; i--) ! 2390: { ! 2391: d = inputInfo.devices[i]; ! 2392: if (d->inited) ! 2393: (*d->deviceProc) (d, DEVICE_CLOSE, argc, argv); ! 2394: Xfree(inputInfo.devices[i]); ! 2395: } ! 2396: ! 2397: /* The array inputInfo.devices doesn't need to be freed here since it ! 2398: will be reused when AddInputDevice is called when the server ! 2399: resets again.*/ ! 2400: } ! 2401: ! 2402: int ! 2403: NumMotionEvents() ! 2404: { ! 2405: return inputInfo.numMotionEvents; ! 2406: } ! 2407: ! 2408: void ! 2409: RegisterPointerDevice(device, numMotionEvents) ! 2410: DevicePtr device; ! 2411: int numMotionEvents; ! 2412: { ! 2413: inputInfo.pointer = (DeviceIntPtr)device; ! 2414: inputInfo.numMotionEvents = numMotionEvents; ! 2415: device->processInputProc = ProcessPointerEvent; ! 2416: } ! 2417: ! 2418: void ! 2419: RegisterKeyboardDevice(device) ! 2420: DevicePtr device; ! 2421: { ! 2422: inputInfo.keyboard = (DeviceIntPtr)device; ! 2423: device->processInputProc = ProcessKeyboardEvent; ! 2424: } ! 2425: ! 2426: void ! 2427: InitPointerDeviceStruct(device, map, mapLength, motionProc, controlProc) ! 2428: DevicePtr device; ! 2429: BYTE *map; ! 2430: int mapLength; ! 2431: void (*controlProc)(); ! 2432: int (*motionProc)(); ! 2433: { ! 2434: int i; ! 2435: DeviceIntPtr mouse = (DeviceIntPtr)device; ! 2436: ! 2437: mouse->grab = NullGrab; ! 2438: mouse->public.on = FALSE; ! 2439: mouse->u.ptr.mapLength = mapLength; ! 2440: mouse->u.ptr.map[0] = 0; ! 2441: for (i = 1; i <= mapLength; i++) ! 2442: mouse->u.ptr.map[i] = map[i]; ! 2443: mouse->u.ptr.ctrl = defaultPointerControl; ! 2444: mouse->u.ptr.GetMotionProc = motionProc; ! 2445: mouse->u.ptr.CtrlProc = controlProc; ! 2446: mouse->u.ptr.autoReleaseGrab = FALSE; ! 2447: if (mouse == inputInfo.pointer) ! 2448: SetPointerStateMasks(mouse); ! 2449: } ! 2450: ! 2451: void ! 2452: QueryMinMaxKeyCodes(minCode, maxCode) ! 2453: KeyCode *minCode, *maxCode; ! 2454: { ! 2455: *minCode = curKeySyms.minKeyCode; ! 2456: *maxCode = curKeySyms.maxKeyCode; ! 2457: } ! 2458: ! 2459: static void ! 2460: SetKeySymsMap(pKeySyms) ! 2461: KeySymsPtr pKeySyms; ! 2462: { ! 2463: int i, j; ! 2464: int rowDif = pKeySyms->minKeyCode - curKeySyms.minKeyCode; ! 2465: /* if keysym map size changes, grow map first */ ! 2466: ! 2467: if (pKeySyms->mapWidth < curKeySyms.mapWidth) ! 2468: { ! 2469: for (i = pKeySyms->minKeyCode; i <= pKeySyms->maxKeyCode; i++) ! 2470: { ! 2471: #define SI(r, c) (((r-pKeySyms->minKeyCode)*pKeySyms->mapWidth) + (c)) ! 2472: #define DI(r, c) (((r - curKeySyms.minKeyCode)*curKeySyms.mapWidth) + (c)) ! 2473: for (j = 0; j < pKeySyms->mapWidth; j++) ! 2474: curKeySyms.map[DI(i, j)] = pKeySyms->map[SI(i, j)]; ! 2475: for (j = pKeySyms->mapWidth; j < curKeySyms.mapWidth; j++) ! 2476: curKeySyms.map[DI(i, j)] = NoSymbol; ! 2477: #undef SI ! 2478: #undef DI ! 2479: } ! 2480: return; ! 2481: } ! 2482: else if (pKeySyms->mapWidth > curKeySyms.mapWidth) ! 2483: { ! 2484: KeySym *map; ! 2485: int bytes = sizeof(KeySym) * pKeySyms->mapWidth * ! 2486: (curKeySyms.maxKeyCode - curKeySyms.minKeyCode + 1); ! 2487: map = (KeySym *)Xalloc(bytes); ! 2488: bzero(map, bytes); ! 2489: if (curKeySyms.map) ! 2490: { ! 2491: for (i = 0; i <= curKeySyms.maxKeyCode-curKeySyms.minKeyCode; i++) ! 2492: bcopy( ! 2493: &curKeySyms.map[i*curKeySyms.mapWidth], ! 2494: &map[i*pKeySyms->mapWidth], ! 2495: curKeySyms.mapWidth * sizeof(KeySym)); ! 2496: Xfree(curKeySyms.map); ! 2497: } ! 2498: curKeySyms.mapWidth = pKeySyms->mapWidth; ! 2499: curKeySyms.map = map; ! 2500: } ! 2501: bcopy( ! 2502: pKeySyms->map, ! 2503: &curKeySyms.map[rowDif], ! 2504: (pKeySyms->maxKeyCode - pKeySyms->minKeyCode + 1) * ! 2505: curKeySyms.mapWidth * sizeof(KeySym)); ! 2506: } ! 2507: ! 2508: static int ! 2509: WidthOfModifierTable(modifierMap) ! 2510: CARD8 modifierMap[]; ! 2511: { ! 2512: int i, keysPerModifier[8], maxKeysPerModifier; ! 2513: ! 2514: maxKeysPerModifier = 0; ! 2515: bzero((char *)keysPerModifier, sizeof keysPerModifier); ! 2516: ! 2517: for (i = 8; i < MAP_LENGTH; i++) { ! 2518: int j; ! 2519: CARD8 mask; ! 2520: ! 2521: for (j = 0, mask = 1; j < 8; j++, mask <<= 1) { ! 2522: if (mask & modifierMap[i]) { ! 2523: if (++keysPerModifier[j] > maxKeysPerModifier) { ! 2524: maxKeysPerModifier = keysPerModifier[j]; ! 2525: } ! 2526: if (debug_modifiers) ! 2527: ErrorF("Key 0x%x modifier %d sequence %d\n", ! 2528: i, j, keysPerModifier[j]); ! 2529: } ! 2530: } ! 2531: } ! 2532: if (debug_modifiers) ! 2533: ErrorF("Max Keys per Modifier = %d\n", maxKeysPerModifier); ! 2534: if (modifierKeyMap) ! 2535: Xfree(modifierKeyMap); ! 2536: modifierKeyMap = (KeyCode *)Xalloc(8*maxKeysPerModifier); ! 2537: bzero((char *)modifierKeyMap, 8*maxKeysPerModifier); ! 2538: bzero((char *)keysPerModifier, sizeof keysPerModifier); ! 2539: ! 2540: for (i = 8; i < MAP_LENGTH; i++) { ! 2541: int j; ! 2542: CARD8 mask; ! 2543: ! 2544: for (j = 0, mask = 1; j < 8; j++, mask <<= 1) { ! 2545: if (mask & modifierMap[i]) { ! 2546: if (debug_modifiers) ! 2547: ErrorF("Key 0x%x modifier %d index %d\n", i, j, ! 2548: j*maxKeysPerModifier+keysPerModifier[j]); ! 2549: modifierKeyMap[j*maxKeysPerModifier+keysPerModifier[j]] = i; ! 2550: keysPerModifier[j]++; ! 2551: } ! 2552: } ! 2553: } ! 2554: ! 2555: return (maxKeysPerModifier); ! 2556: } ! 2557: ! 2558: void ! 2559: InitKeyboardDeviceStruct(device, pKeySyms, pModifiers, ! 2560: bellProc, controlProc) ! 2561: DevicePtr device; ! 2562: KeySymsPtr pKeySyms; ! 2563: CARD8 pModifiers[]; ! 2564: void (*bellProc)(); ! 2565: void (*controlProc)(); ! 2566: { ! 2567: DeviceIntPtr keybd = (DeviceIntPtr)device; ! 2568: ! 2569: keybd->grab = NullGrab; ! 2570: keybd->public.on = FALSE; ! 2571: ! 2572: keybd->u.keybd.ctrl = defaultKeyboardControl; ! 2573: keybd->u.keybd.BellProc = bellProc; ! 2574: keybd->u.keybd.CtrlProc = controlProc; ! 2575: keybd->u.keybd.focus.win = PointerRootWin; ! 2576: keybd->u.keybd.focus.revert = None; ! 2577: keybd->u.keybd.focus.time = currentTime; ! 2578: keybd->u.keybd.passiveGrab = FALSE; ! 2579: curKeySyms.minKeyCode = pKeySyms->minKeyCode; ! 2580: curKeySyms.maxKeyCode = pKeySyms->maxKeyCode; ! 2581: /* ! 2582: * Copy the modifier info into the kdb stuct. ! 2583: */ ! 2584: { ! 2585: int i; ! 2586: ! 2587: for (i = 8; i < MAP_LENGTH; i++) { ! 2588: keybd->u.keybd.modifierMap[i] = pModifiers[i]; ! 2589: } ! 2590: maxKeysPerModifier = WidthOfModifierTable(pModifiers); ! 2591: } ! 2592: if (keybd == inputInfo.keyboard) ! 2593: { ! 2594: SetKeyboardStateMasks(keybd); ! 2595: SetKeySymsMap(pKeySyms); ! 2596: (*keybd->u.keybd.CtrlProc)(keybd, &keybd->u.keybd.ctrl); ! 2597: } ! 2598: } ! 2599: ! 2600: void ! 2601: InitOtherDeviceStruct(device, map, mapLength) ! 2602: DevicePtr device; ! 2603: BYTE *map; ! 2604: int mapLength; ! 2605: { ! 2606: int i; ! 2607: DeviceIntPtr other = (DeviceIntPtr)device; ! 2608: ! 2609: other->grab = NullGrab; ! 2610: other->public.on = FALSE; ! 2611: other->u.other.mapLength = mapLength; ! 2612: other->u.other.map[0] = 0; ! 2613: for (i = 1; i <= mapLength; i++) ! 2614: other->u.other.map[i] = map[i]; ! 2615: other->u.other.focus.win = NoneWin; ! 2616: other->u.other.focus.revert = None; ! 2617: other->u.other.focus.time = currentTime; ! 2618: } ! 2619: ! 2620: GrabPtr ! 2621: SetDeviceGrab(device, grab) ! 2622: DevicePtr device; ! 2623: GrabPtr grab; ! 2624: { ! 2625: register DeviceIntPtr dev = (DeviceIntPtr)device; ! 2626: GrabPtr oldGrab = dev->grab; ! 2627: dev->grab = grab; /* must not be deallocated */ ! 2628: return oldGrab; ! 2629: } ! 2630: ! 2631: /* ! 2632: * Devices can't be resources since the bit patterns don't fit very well. ! 2633: * For one, where the client field would be, is random bits and the client ! 2634: * object might not be defined. For another, the "server" bit might be on. ! 2635: */ ! 2636: ! 2637: #ifdef INPUT_EXTENSION ! 2638: ! 2639: DevicePtr ! 2640: LookupInputDevice(deviceID) ! 2641: Device deviceID; ! 2642: { ! 2643: int i; ! 2644: for (i = 0; i < inputInfo.numDevices; i++) ! 2645: if (inputInfo.devices[i]->public.deviceID == deviceID) ! 2646: return &(inputInfo.devices[i]->public); ! 2647: return NullDevice; ! 2648: } ! 2649: #endif /* INTPUT_EXTENSION */ ! 2650: ! 2651: DevicePtr ! 2652: LookupKeyboardDevice() ! 2653: { ! 2654: return &inputInfo.keyboard->public; ! 2655: } ! 2656: ! 2657: DevicePtr ! 2658: LookupPointerDevice() ! 2659: { ! 2660: return &inputInfo.pointer->public; ! 2661: } ! 2662: ! 2663: ! 2664: static int ! 2665: SendMappingNotify(request, firstKeyCode, count) ! 2666: BYTE request, firstKeyCode, count; ! 2667: { ! 2668: int i; ! 2669: xEvent event; ! 2670: ! 2671: event.u.u.type = MappingNotify; ! 2672: event.u.mappingNotify.request = request; ! 2673: if (request == MappingKeyboard) ! 2674: { ! 2675: event.u.mappingNotify.firstKeyCode = firstKeyCode; ! 2676: event.u.mappingNotify.count = count; ! 2677: } ! 2678: /* 0 is the server client */ ! 2679: for (i=1; i<currentMaxClients; i++) ! 2680: if (clients[i] && ! clients[i]->clientGone) ! 2681: WriteEventsToClient(clients[i], 1, &event); ! 2682: } ! 2683: ! 2684: /* ! 2685: * n-sqared algorithm. n < 255 and don't want to copy the whole thing and ! 2686: * sort it to do the checking. How often is it called? Just being lazy? ! 2687: */ ! 2688: static Bool ! 2689: BadDeviceMap(buff, length, low, high) ! 2690: BYTE *buff; ! 2691: int length; ! 2692: unsigned low, high; ! 2693: { ! 2694: int i, j; ! 2695: ! 2696: for (i = 0; i < length; i++) ! 2697: if (buff[i]) /* only check non-zero elements */ ! 2698: { ! 2699: if ((low > buff[i]) || (high < buff[i])) ! 2700: return TRUE; ! 2701: for (j = i + 1; j < length; j++) ! 2702: if (buff[i] == buff[j]) ! 2703: return TRUE; ! 2704: } ! 2705: return FALSE; ! 2706: } ! 2707: ! 2708: static Bool ! 2709: AllModifierKeysAreUp(map, len) ! 2710: CARD8 *map; ! 2711: int len; ! 2712: { ! 2713: while (len--) { ! 2714: if (*map && IsOn(inputInfo.keyboard->down, *map)) ! 2715: return FALSE; ! 2716: map++; ! 2717: } ! 2718: return TRUE; ! 2719: } ! 2720: ! 2721: int ! 2722: ProcSetModifierMapping(client) ! 2723: ClientPtr client; ! 2724: { ! 2725: xSetModifierMappingReply rep; ! 2726: REQUEST(xSetModifierMappingReq); ! 2727: KeyCode *inputMap; ! 2728: int inputMapLen; ! 2729: int i; ! 2730: ! 2731: REQUEST_AT_LEAST_SIZE(xSetModifierMappingReq); ! 2732: ! 2733: if (stuff->length != ((stuff->numKeyPerModifier<<1) + ! 2734: (sizeof (xSetModifierMappingReq)>>2))) ! 2735: return BadLength; ! 2736: ! 2737: inputMapLen = 8*stuff->numKeyPerModifier; ! 2738: inputMap = (KeyCode *)&stuff[1]; ! 2739: ! 2740: /* ! 2741: * Now enforce the restriction that "all of the non-zero keycodes must be ! 2742: * in the range specified by min-keycode and max-keycode in the ! 2743: * connection setup (else a Value error)" ! 2744: */ ! 2745: i = inputMapLen; ! 2746: while (i--) { ! 2747: if (inputMap[i] ! 2748: && (inputMap[i] < curKeySyms.minKeyCode ! 2749: || inputMap[i] > curKeySyms.maxKeyCode)) { ! 2750: return BadValue; ! 2751: } ! 2752: } ! 2753: rep.type = X_Reply; ! 2754: rep.length = 0; ! 2755: rep.sequenceNumber = client->sequence; ! 2756: rep.success = MappingSuccess; ! 2757: ! 2758: /* ! 2759: * Now enforce the restriction that none of the old or new ! 2760: * modifier keys may be down while we change the mapping, and ! 2761: * that the DDX layer likes the choice. ! 2762: */ ! 2763: if (!AllModifierKeysAreUp(modifierKeyMap, 8*maxKeysPerModifier) ! 2764: || !AllModifierKeysAreUp(inputMap, inputMapLen)) { ! 2765: if (debug_modifiers) ! 2766: ErrorF("Busy\n"); ! 2767: rep.success = MappingBusy; ! 2768: } else { ! 2769: register int i; ! 2770: ! 2771: for (i = 0; i < inputMapLen; i++) { ! 2772: if (inputMap[i] && !LegalModifier(inputMap[i])) { ! 2773: if (debug_modifiers) ! 2774: ErrorF("Key 0x%x refused\n", inputMap[i]); ! 2775: rep.success = MappingFailed; ! 2776: break; ! 2777: } ! 2778: } ! 2779: } ! 2780: ! 2781: WriteReplyToClient(client, sizeof(xSetModifierMappingReply), &rep); ! 2782: ! 2783: if (rep.success == MappingSuccess) ! 2784: { ! 2785: /* ! 2786: * Now build the keyboard's modifier bitmap from the ! 2787: * list of keycodes. ! 2788: */ ! 2789: register int i; ! 2790: ! 2791: if (modifierKeyMap) ! 2792: Xfree(modifierKeyMap); ! 2793: modifierKeyMap = (KeyCode *)Xalloc(inputMapLen); ! 2794: bcopy(inputMap, modifierKeyMap, inputMapLen); ! 2795: ! 2796: maxKeysPerModifier = stuff->numKeyPerModifier; ! 2797: for (i = 0; i < MAP_LENGTH; i++) ! 2798: inputInfo.keyboard->u.keybd.modifierMap[i] = 0; ! 2799: for (i = 0; i < inputMapLen; i++) if (inputMap[i]) { ! 2800: inputInfo.keyboard->u.keybd.modifierMap[inputMap[i]] ! 2801: |= (1<<(i/maxKeysPerModifier)); ! 2802: if (debug_modifiers) ! 2803: ErrorF("Key 0x%x mod %d\n", inputMap[i], i/maxKeysPerModifier); ! 2804: } ! 2805: SetKeyboardStateMasks(inputInfo.keyboard); ! 2806: SendMappingNotify(MappingModifier, 0, 0); ! 2807: } ! 2808: return(client->noClientException); ! 2809: } ! 2810: ! 2811: int ! 2812: ProcGetModifierMapping(client) ! 2813: ClientPtr client; ! 2814: { ! 2815: xGetModifierMappingReply rep; ! 2816: REQUEST(xReq); ! 2817: ! 2818: REQUEST_SIZE_MATCH(xReq); ! 2819: rep.type = X_Reply; ! 2820: rep.numKeyPerModifier = maxKeysPerModifier; ! 2821: rep.sequenceNumber = client->sequence; ! 2822: /* length counts 4 byte quantities - there are 8 modifiers 1 byte big */ ! 2823: rep.length = 2*maxKeysPerModifier; ! 2824: ! 2825: WriteReplyToClient(client, sizeof(xGetModifierMappingReply), &rep); ! 2826: ! 2827: /* Reply with the (modified by DDX) map that SetModifierMapping passed in */ ! 2828: WriteToClient(client, 8*maxKeysPerModifier, modifierKeyMap); ! 2829: return client->noClientException; ! 2830: } ! 2831: ! 2832: int ! 2833: ProcChangeKeyboardMapping(client) ! 2834: ClientPtr client; ! 2835: { ! 2836: REQUEST(xChangeKeyboardMappingReq); ! 2837: int len; ! 2838: int count; ! 2839: KeySymsRec keysyms; ! 2840: ! 2841: REQUEST_AT_LEAST_SIZE(xChangeKeyboardMappingReq); ! 2842: ! 2843: len = stuff->length - (sizeof(xChangeKeyboardMappingReq) >> 2); ! 2844: if (len != (stuff->keyCodes * stuff->keySymsPerKeyCode)) ! 2845: return BadLength; ! 2846: count = len / stuff->keySymsPerKeyCode; ! 2847: if ((stuff->firstKeyCode < curKeySyms.minKeyCode) || ! 2848: (stuff->firstKeyCode + count - 1 > curKeySyms.maxKeyCode) || ! 2849: (stuff->keySymsPerKeyCode == 0)) ! 2850: return BadValue; ! 2851: keysyms.minKeyCode = stuff->firstKeyCode; ! 2852: keysyms.maxKeyCode = stuff->firstKeyCode + count - 1; ! 2853: keysyms.mapWidth = stuff->keySymsPerKeyCode; ! 2854: keysyms.map = (KeySym *)&stuff[1]; ! 2855: SetKeySymsMap(&keysyms); ! 2856: SendMappingNotify(MappingKeyboard, stuff->firstKeyCode, count); ! 2857: return client->noClientException; ! 2858: ! 2859: } ! 2860: ! 2861: int ! 2862: ProcSetPointerMapping(client) ! 2863: ClientPtr client; ! 2864: { ! 2865: REQUEST(xSetPointerMappingReq); ! 2866: BYTE *map; ! 2867: xSetPointerMappingReply rep; ! 2868: register int i; ! 2869: ! 2870: REQUEST_AT_LEAST_SIZE(xSetPointerMappingReq); ! 2871: if (stuff->length != (sizeof(xSetPointerMappingReq) + stuff->nElts + 3)>>2) ! 2872: return BadLength; ! 2873: rep.type = X_Reply; ! 2874: rep.length = 0; ! 2875: rep.sequenceNumber = client->sequence; ! 2876: rep.success = MappingSuccess; ! 2877: map = (BYTE *)&stuff[1]; ! 2878: if (stuff->nElts != inputInfo.pointer->u.ptr.mapLength) ! 2879: return BadValue; ! 2880: if (BadDeviceMap(&map[0], stuff->nElts, 1, 255)) ! 2881: return BadValue; ! 2882: for (i=0; i < stuff->nElts; i++) ! 2883: if ((inputInfo.pointer->u.ptr.map[i + 1] != map[i]) && ! 2884: IsOn(inputInfo.pointer->down, i + 1)) ! 2885: { ! 2886: rep.success = MappingBusy; ! 2887: WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep); ! 2888: return Success; ! 2889: } ! 2890: for (i = 0; i < stuff->nElts; i++) ! 2891: inputInfo.pointer->u.ptr.map[i + 1] = map[i]; ! 2892: SetPointerStateMasks(inputInfo.pointer); ! 2893: WriteReplyToClient(client, sizeof(xSetPointerMappingReply), &rep); ! 2894: SendMappingNotify(MappingPointer, 0, 0); ! 2895: return Success; ! 2896: } ! 2897: ! 2898: int ! 2899: ProcGetKeyboardMapping(client) ! 2900: ClientPtr client; ! 2901: { ! 2902: xGetKeyboardMappingReply rep; ! 2903: REQUEST(xGetKeyboardMappingReq); ! 2904: ! 2905: REQUEST_SIZE_MATCH(xGetKeyboardMappingReq); ! 2906: ! 2907: if ((stuff->firstKeyCode < curKeySyms.minKeyCode) || ! 2908: (stuff->firstKeyCode > curKeySyms.maxKeyCode) || ! 2909: (stuff->firstKeyCode + stuff->count > curKeySyms.maxKeyCode + 1)) ! 2910: return BadValue; ! 2911: ! 2912: rep.type = X_Reply; ! 2913: rep.sequenceNumber = client->sequence; ! 2914: rep.keySymsPerKeyCode = curKeySyms.mapWidth; ! 2915: /* length is a count of 4 byte quantities and KeySyms are 4 bytes */ ! 2916: rep.length = (curKeySyms.mapWidth * stuff->count); ! 2917: WriteReplyToClient(client, sizeof(xGetKeyboardMappingReply), &rep); ! 2918: client->pSwapReplyFunc = CopySwap32Write; ! 2919: WriteSwappedDataToClient( ! 2920: client, ! 2921: curKeySyms.mapWidth * stuff->count * sizeof(KeySym), ! 2922: &curKeySyms.map[stuff->firstKeyCode - curKeySyms.minKeyCode]); ! 2923: ! 2924: return client->noClientException; ! 2925: } ! 2926: ! 2927: int ! 2928: ProcGetPointerMapping(client) ! 2929: ClientPtr client; ! 2930: { ! 2931: xGetPointerMappingReply rep; ! 2932: REQUEST(xReq); ! 2933: ! 2934: REQUEST_SIZE_MATCH(xReq); ! 2935: rep.type = X_Reply; ! 2936: rep.sequenceNumber = client->sequence; ! 2937: rep.nElts = inputInfo.pointer->u.ptr.mapLength; ! 2938: rep.length = (rep.nElts + (4-1))/4; ! 2939: WriteReplyToClient(client, sizeof(xGetPointerMappingReply), &rep); ! 2940: WriteToClient(client, rep.nElts, &inputInfo.pointer->u.ptr.map[1]); ! 2941: return Success; ! 2942: } ! 2943: ! 2944: int ! 2945: Ones(mask) /* HACKMEM 169 */ ! 2946: Mask mask; ! 2947: { ! 2948: register int y; ! 2949: ! 2950: y = (mask >> 1) &033333333333; ! 2951: y = mask - y - ((y >>1) & 033333333333); ! 2952: return (((y + (y >> 3)) & 030707070707) % 077); ! 2953: } ! 2954: ! 2955: void ! 2956: NoteLedState(keybd, led, on) ! 2957: DeviceIntPtr keybd; ! 2958: int led; ! 2959: Bool on; ! 2960: { ! 2961: KeybdCtrl *ctrl = &keybd->u.keybd.ctrl; ! 2962: if (on) ! 2963: ctrl->leds |= (1 << (led - 1)); ! 2964: else ! 2965: ctrl->leds &= ~(1 << (led - 1)); /* assumes 32-bit longs XXX */ ! 2966: } ! 2967: ! 2968: int ! 2969: ProcChangeKeyboardControl (client) ! 2970: ClientPtr client; ! 2971: { ! 2972: #define DO_ALL 0xffffffff ! 2973: KeybdCtrl ctrl; ! 2974: DeviceIntPtr keybd = inputInfo.keyboard; ! 2975: long *vlist; ! 2976: int t; ! 2977: int led = DO_ALL; ! 2978: int key = DO_ALL; ! 2979: REQUEST(xChangeKeyboardControlReq); ! 2980: ! 2981: REQUEST_AT_LEAST_SIZE(xChangeKeyboardControlReq); ! 2982: if (stuff->length !=(sizeof(xChangeKeyboardControlReq)>>2) + Ones(stuff->mask)) ! 2983: return BadLength; ! 2984: vlist = (long *)&stuff[1]; /* first word of values */ ! 2985: ctrl = keybd->u.keybd.ctrl; ! 2986: if (stuff->mask & KBKeyClickPercent) ! 2987: { ! 2988: t = (INT8)*vlist; ! 2989: vlist++; ! 2990: if (t == -1) ! 2991: t = defaultKeyboardControl.click; ! 2992: else if (t < 0 || t > 100) ! 2993: return BadValue; ! 2994: ctrl.click = t; ! 2995: } ! 2996: if (stuff->mask & KBBellPercent) ! 2997: { ! 2998: t = (INT8)*vlist; ! 2999: vlist++; ! 3000: if (t == -1) ! 3001: t = defaultKeyboardControl.bell; ! 3002: else if (t < 0 || t > 100) ! 3003: return BadValue; ! 3004: ctrl.bell = t; ! 3005: } ! 3006: if (stuff->mask & KBBellPitch) ! 3007: { ! 3008: t = (INT16)*vlist; ! 3009: vlist++; ! 3010: if (t == -1) ! 3011: t = defaultKeyboardControl.bell_pitch; ! 3012: else if (t < 0) ! 3013: return BadValue; ! 3014: ctrl.bell_pitch = t; ! 3015: } ! 3016: if (stuff->mask & KBBellDuration) ! 3017: { ! 3018: t = (INT16)*vlist; ! 3019: vlist++; ! 3020: if (t == -1) ! 3021: t = defaultKeyboardControl.bell_duration; ! 3022: else if (t < 0) ! 3023: return BadValue; ! 3024: ctrl.bell_duration = t; ! 3025: } ! 3026: if (stuff->mask & KBLed) ! 3027: { ! 3028: led = (CARD8)*vlist; ! 3029: vlist++; ! 3030: if (led < 1 || led > 32) ! 3031: return BadValue; ! 3032: if (!(stuff->mask & KBLedMode)) ! 3033: return BadMatch; ! 3034: } ! 3035: if (stuff->mask & KBLedMode) ! 3036: { ! 3037: t = (CARD8)*vlist; ! 3038: vlist++; ! 3039: if (t == LedModeOff) ! 3040: { ! 3041: if (led == DO_ALL) ! 3042: ctrl.leds = 0x0; ! 3043: else ! 3044: ctrl.leds &= ~(1 << (led - 1)); /* assumes 32-bit longs XXX */ ! 3045: } ! 3046: else if (t == LedModeOn) ! 3047: { ! 3048: if (led == DO_ALL) ! 3049: ctrl.leds = DO_ALL; ! 3050: else ! 3051: ctrl.leds |= (1 << (led - 1)); ! 3052: } ! 3053: else ! 3054: return BadValue; ! 3055: } ! 3056: if (stuff->mask & KBKey) ! 3057: { ! 3058: key = (KeyCode)*vlist; ! 3059: vlist++; ! 3060: if (key < 8 || key > 255) ! 3061: return BadValue; ! 3062: if (!(stuff->mask & KBAutoRepeatMode)) ! 3063: return BadMatch; ! 3064: } ! 3065: if (stuff->mask & KBAutoRepeatMode) ! 3066: { ! 3067: int index = (key >> 3); ! 3068: int mask = (1 << (key & 7)); ! 3069: t = (CARD8)*vlist; ! 3070: vlist++; ! 3071: if (t == AutoRepeatModeOff) ! 3072: { ! 3073: if (key == DO_ALL) ! 3074: ctrl.autoRepeat = FALSE; ! 3075: else ! 3076: ctrl.autoRepeats[index] &= ~mask; ! 3077: } ! 3078: else if (t == AutoRepeatModeOn) ! 3079: { ! 3080: if (key == DO_ALL) ! 3081: ctrl.autoRepeat = TRUE; ! 3082: else ! 3083: ctrl.autoRepeats[index] |= mask; ! 3084: } ! 3085: else if (t == AutoRepeatModeDefault) ! 3086: { ! 3087: if (key == DO_ALL) ! 3088: ctrl.autoRepeat = defaultKeyboardControl.autoRepeat; ! 3089: else ! 3090: ctrl.autoRepeats[index] &= ~mask; ! 3091: ctrl.autoRepeats[index] = ! 3092: (ctrl.autoRepeats[index] & ~mask) | ! 3093: (defaultKeyboardControl.autoRepeats[index] & mask); ! 3094: } ! 3095: else ! 3096: return BadValue; ! 3097: } ! 3098: keybd->u.keybd.ctrl = ctrl; ! 3099: (*keybd->u.keybd.CtrlProc)(keybd, &keybd->u.keybd.ctrl); ! 3100: return Success; ! 3101: #undef DO_ALL ! 3102: } ! 3103: ! 3104: int ! 3105: ProcGetKeyboardControl (client) ! 3106: ClientPtr client; ! 3107: { ! 3108: int i; ! 3109: DeviceIntPtr keybd = inputInfo.keyboard; ! 3110: xGetKeyboardControlReply rep; ! 3111: REQUEST(xReq); ! 3112: ! 3113: REQUEST_SIZE_MATCH(xReq); ! 3114: rep.type = X_Reply; ! 3115: rep.length = 5; ! 3116: rep.sequenceNumber = client->sequence; ! 3117: rep.globalAutoRepeat = keybd->u.keybd.ctrl.autoRepeat; ! 3118: rep.keyClickPercent = keybd->u.keybd.ctrl.click; ! 3119: rep.bellPercent = keybd->u.keybd.ctrl.bell; ! 3120: rep.bellPitch = keybd->u.keybd.ctrl.bell_pitch; ! 3121: rep.bellDuration = keybd->u.keybd.ctrl.bell_duration; ! 3122: rep.ledMask = keybd->u.keybd.ctrl.leds; ! 3123: for (i = 0; i < 32; i++) ! 3124: rep.map[i] = keybd->u.keybd.ctrl.autoRepeats[i]; ! 3125: WriteReplyToClient(client, sizeof(xGetKeyboardControlReply), &rep); ! 3126: return Success; ! 3127: } ! 3128: ! 3129: int ! 3130: ProcBell(client) ! 3131: ClientPtr client; ! 3132: { ! 3133: register DeviceIntPtr keybd = inputInfo.keyboard; ! 3134: int base = keybd->u.keybd.ctrl.bell; ! 3135: int newpercent; ! 3136: REQUEST(xBellReq); ! 3137: REQUEST_SIZE_MATCH(xBellReq); ! 3138: if (stuff->percent < -100 || stuff->percent > 100) ! 3139: return BadValue; ! 3140: newpercent = (base * stuff->percent) / 100; ! 3141: if (stuff->percent < 0) ! 3142: newpercent = base + newpercent; ! 3143: else ! 3144: newpercent = base - newpercent + stuff->percent; ! 3145: (*keybd->u.keybd.BellProc)(newpercent, keybd); ! 3146: return Success; ! 3147: } ! 3148: ! 3149: int ! 3150: ProcChangePointerControl(client) ! 3151: ClientPtr client; ! 3152: { ! 3153: DeviceIntPtr mouse = inputInfo.pointer; ! 3154: PtrCtrl ctrl; /* might get BadValue part way through */ ! 3155: REQUEST(xChangePointerControlReq); ! 3156: ! 3157: REQUEST_SIZE_MATCH(xChangePointerControlReq); ! 3158: ctrl = mouse->u.ptr.ctrl; ! 3159: if (stuff->doAccel) ! 3160: { ! 3161: if (stuff->accelNum == -1) ! 3162: ctrl.num = defaultPointerControl.num; ! 3163: else if (stuff->accelNum < 0) ! 3164: { ! 3165: client->errorValue = stuff->accelNum; ! 3166: return BadValue; ! 3167: } ! 3168: else ctrl.num = stuff->accelNum; ! 3169: if (stuff->accelDenum == -1) ! 3170: ctrl.den = defaultPointerControl.den; ! 3171: else if (stuff->accelDenum <= 0) ! 3172: { ! 3173: client->errorValue = stuff->accelDenum; ! 3174: return BadValue; ! 3175: } ! 3176: else ctrl.den = stuff->accelDenum; ! 3177: } ! 3178: if (stuff->doThresh) ! 3179: { ! 3180: if (stuff->threshold == -1) ! 3181: ctrl.threshold = defaultPointerControl.threshold; ! 3182: else if (stuff->threshold <= 0) ! 3183: { ! 3184: client->errorValue = stuff->threshold; ! 3185: return BadValue; ! 3186: } ! 3187: else ctrl.threshold = stuff->threshold; ! 3188: } ! 3189: mouse->u.ptr.ctrl = ctrl; ! 3190: (*mouse->u.ptr.CtrlProc)(mouse, &mouse->u.ptr.ctrl); ! 3191: return Success; ! 3192: } ! 3193: ! 3194: int ! 3195: ProcGetPointerControl(client) ! 3196: ClientPtr client; ! 3197: { ! 3198: register DeviceIntPtr mouse = inputInfo.pointer; ! 3199: REQUEST(xReq); ! 3200: xGetPointerControlReply rep; ! 3201: ! 3202: REQUEST_SIZE_MATCH(xReq); ! 3203: rep.type = X_Reply; ! 3204: rep.length = 0; ! 3205: rep.sequenceNumber = client->sequence; ! 3206: rep.threshold = mouse->u.ptr.ctrl.threshold; ! 3207: rep.accelNumerator = mouse->u.ptr.ctrl.num; ! 3208: rep.accelDenominator = mouse->u.ptr.ctrl.den; ! 3209: WriteReplyToClient(client, sizeof(xGenericReply), &rep); ! 3210: return Success; ! 3211: } ! 3212: ! 3213: int ! 3214: ProcGetMotionEvents(client) ! 3215: ClientPtr client; ! 3216: { ! 3217: WindowPtr pWin; ! 3218: xTimecoord * coords; ! 3219: xGetMotionEventsReply rep; ! 3220: int i, count, nEvents, xmin, xmax, ymin, ymax; ! 3221: DeviceIntPtr mouse = inputInfo.pointer; ! 3222: TimeStamp start, stop; ! 3223: REQUEST(xGetMotionEventsReq); ! 3224: ! 3225: REQUEST_SIZE_MATCH(xGetMotionEventsReq); ! 3226: pWin = LookupWindow(stuff->window, client); ! 3227: if (!pWin) ! 3228: { ! 3229: client->errorValue = stuff->window; ! 3230: return BadWindow; ! 3231: } ! 3232: lastWasMotion = FALSE; ! 3233: rep.type = X_Reply; ! 3234: rep.sequenceNumber = client->sequence; ! 3235: rep.nEvents = 0; ! 3236: start = ClientTimeToServerTime(stuff->start); ! 3237: stop = ClientTimeToServerTime(stuff->stop); ! 3238: if (CompareTimeStamps(start, stop) == LATER) ! 3239: return Success; ! 3240: if (CompareTimeStamps(start, currentTime) == LATER) ! 3241: return Success; ! 3242: if (CompareTimeStamps(stop, currentTime) == LATER) ! 3243: stop = currentTime; ! 3244: if (inputInfo.numMotionEvents) ! 3245: { ! 3246: coords = (xTimecoord *) Xalloc( ! 3247: inputInfo.numMotionEvents * sizeof(xTimecoord)); ! 3248: count = (*mouse->u.ptr.GetMotionProc) ( ! 3249: mouse, coords, start.milliseconds, stop.milliseconds); ! 3250: xmin = pWin->absCorner.x - pWin->borderWidth; ! 3251: xmax = ! 3252: pWin->absCorner.x + pWin->clientWinSize.width + pWin->borderWidth; ! 3253: ymin = pWin->absCorner.y - pWin->borderWidth; ! 3254: ymax = ! 3255: pWin->absCorner.y + pWin->clientWinSize.height + pWin->borderWidth; ! 3256: for (i = 0; i < count; i++) ! 3257: if ((xmin <= coords[i].x) && (coords[i].x < xmax) && ! 3258: (ymin <= coords[i].y) && (coords[i].y < ymax)) ! 3259: { ! 3260: coords[rep.nEvents].x = coords[i].x - pWin->absCorner.x; ! 3261: coords[rep.nEvents].y = coords[i].y - pWin->absCorner.y; ! 3262: rep.nEvents++; ! 3263: } ! 3264: } ! 3265: rep.length = rep.nEvents * sizeof(xTimecoord) / 4; ! 3266: nEvents = rep.nEvents; ! 3267: WriteReplyToClient(client, sizeof(xGetMotionEventsReply), &rep); ! 3268: if (inputInfo.numMotionEvents) ! 3269: { ! 3270: client->pSwapReplyFunc = SwapTimeCoordWrite; ! 3271: WriteSwappedDataToClient(client, nEvents * sizeof(xTimecoord), coords); ! 3272: Xfree(coords); ! 3273: } ! 3274: return Success; ! 3275: } ! 3276: ! 3277: int ! 3278: ProcQueryPointer(client) ! 3279: ClientPtr client; ! 3280: { ! 3281: xQueryPointerReply rep; ! 3282: WindowPtr pWin, t; ! 3283: REQUEST(xResourceReq); ! 3284: ! 3285: REQUEST_SIZE_MATCH(xResourceReq); ! 3286: pWin = LookupWindow(stuff->id, client); ! 3287: if (!pWin) ! 3288: { ! 3289: client->errorValue = stuff->id; ! 3290: return BadWindow; ! 3291: } ! 3292: lastWasMotion = FALSE; ! 3293: rep.type = X_Reply; ! 3294: rep.sequenceNumber = client->sequence; ! 3295: rep.sameScreen = xTrue; /* XXX */ ! 3296: rep.mask = keyButtonState; ! 3297: rep.length = 0; ! 3298: rep.root = (ROOT)->wid; ! 3299: rep.rootX = sprite.hot.x; ! 3300: rep.rootY = sprite.hot.y; ! 3301: rep.winX = sprite.hot.x - pWin->absCorner.x; ! 3302: rep.winY = sprite.hot.y - pWin->absCorner.y; ! 3303: rep.child = None; ! 3304: for (t = sprite.win; t; t = t->parent) ! 3305: if (t->parent == pWin) ! 3306: { ! 3307: rep.child = t->wid; ! 3308: break; ! 3309: } ! 3310: WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep); ! 3311: ! 3312: return(Success); ! 3313: } ! 3314: ! 3315: int ! 3316: ProcQueryKeymap(client) ! 3317: ClientPtr client; ! 3318: { ! 3319: xQueryKeymapReply rep; ! 3320: int i; ! 3321: ! 3322: rep.type = X_Reply; ! 3323: rep.sequenceNumber = client->sequence; ! 3324: rep.length = 2; ! 3325: for (i = 0; i<32; i++) ! 3326: rep.map[i] = inputInfo.keyboard->down[i]; ! 3327: WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep); ! 3328: return Success; ! 3329: } ! 3330: ! 3331: /* This define is taken from extension.c and must be consistent with it. ! 3332: This is probably not the best programming practice. PRH */ ! 3333: ! 3334: #define EXTENSION_EVENT_BASE 64 ! 3335: int ! 3336: ProcSendEvent(client) ! 3337: ClientPtr client; ! 3338: { ! 3339: extern int lastEvent; /* Defined in extension.c */ ! 3340: WindowPtr pWin; ! 3341: WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */ ! 3342: REQUEST(xSendEventReq); ! 3343: ! 3344: REQUEST_SIZE_MATCH(xSendEventReq); ! 3345: ! 3346: /* The client's event type must be a core event type or one defined by an ! 3347: extension. */ ! 3348: ! 3349: if ( ! ((stuff->event.u.u.type < LASTEvent) || ! 3350: ((EXTENSION_EVENT_BASE <= stuff->event.u.u.type) && ! 3351: (stuff->event.u.u.type < lastEvent))) ) ! 3352: return BadValue; ! 3353: ! 3354: if (stuff->destination == PointerWindow) ! 3355: pWin = sprite.win; ! 3356: else if (stuff->destination == InputFocus) ! 3357: { ! 3358: WindowPtr inputFocus = inputInfo.keyboard->u.keybd.focus.win; ! 3359: ! 3360: if (inputFocus == NoneWin) ! 3361: return Success; ! 3362: ! 3363: /* If the input focus is PointerRootWin, send the event to where ! 3364: the pointer is if possible, then perhaps propogate up to root. */ ! 3365: if (inputFocus == PointerRootWin) ! 3366: inputFocus = ROOT; ! 3367: ! 3368: if (IsParent(inputFocus, sprite.win)) ! 3369: { ! 3370: effectiveFocus = inputFocus; ! 3371: pWin = sprite.win; ! 3372: } ! 3373: else ! 3374: effectiveFocus = pWin = inputFocus; ! 3375: } ! 3376: else ! 3377: pWin = LookupWindow(stuff->destination, client); ! 3378: if (!pWin) ! 3379: { ! 3380: client->errorValue = stuff->destination; ! 3381: return BadWindow; ! 3382: } ! 3383: stuff->event.u.u.type |= 0x80; ! 3384: if (stuff->propagate) ! 3385: { ! 3386: for (;pWin; pWin = pWin->parent) ! 3387: { ! 3388: if (DeliverEventsToWindow( ! 3389: pWin, &stuff->event, 1, stuff->eventMask, NullGrab)) ! 3390: return Success; ! 3391: if (pWin == effectiveFocus) ! 3392: return Success; ! 3393: stuff->eventMask &= ~pWin->dontPropagateMask; ! 3394: } ! 3395: } ! 3396: else ! 3397: DeliverEventsToWindow( ! 3398: pWin, &stuff->event, 1, stuff->eventMask, NullGrab); ! 3399: return Success; ! 3400: } ! 3401: ! 3402: int ! 3403: ProcUngrabKey(client) ! 3404: ClientPtr client; ! 3405: { ! 3406: REQUEST(xUngrabKeyReq); ! 3407: WindowPtr pWin; ! 3408: GrabRec temporaryGrab; ! 3409: ! 3410: REQUEST_SIZE_MATCH(xUngrabKeyReq); ! 3411: pWin = LookupWindow(stuff->grabWindow, client); ! 3412: if (!pWin) ! 3413: { ! 3414: client->errorValue = stuff->grabWindow; ! 3415: return BadWindow; ! 3416: } ! 3417: ! 3418: temporaryGrab.client = client; ! 3419: temporaryGrab.device = inputInfo.keyboard; ! 3420: temporaryGrab.window = pWin; ! 3421: temporaryGrab.modifiersDetail.exact = stuff->modifiers; ! 3422: temporaryGrab.modifiersDetail.pMask = NULL; ! 3423: temporaryGrab.u.keybd.keyDetail.exact = stuff->key; ! 3424: temporaryGrab.u.keybd.keyDetail.pMask = NULL; ! 3425: ! 3426: DeletePassiveGrabFromList(&temporaryGrab); ! 3427: ! 3428: return(Success); ! 3429: } ! 3430: ! 3431: int ! 3432: ProcGrabKey(client) ! 3433: ClientPtr client; ! 3434: { ! 3435: WindowPtr pWin; ! 3436: REQUEST(xGrabKeyReq); ! 3437: GrabPtr grab; ! 3438: GrabPtr temporaryGrab; ! 3439: ! 3440: REQUEST_SIZE_MATCH(xGrabKeyReq); ! 3441: if (((stuff->key > curKeySyms.maxKeyCode) || (stuff->key < curKeySyms.minKeyCode)) ! 3442: && (stuff->key != AnyKey)) ! 3443: return BadValue; ! 3444: pWin = LookupWindow(stuff->grabWindow, client); ! 3445: client->errorValue = stuff->grabWindow; ! 3446: if (!pWin) ! 3447: { ! 3448: client->errorValue = stuff->grabWindow; ! 3449: return BadWindow; ! 3450: } ! 3451: ! 3452: temporaryGrab = CreateGrab(client, inputInfo.keyboard, pWin, ! 3453: (KeyPressMask | KeyReleaseMask), stuff->ownerEvents, ! 3454: stuff->keyboardMode, stuff->pointerMode, stuff->modifiers, stuff->key); ! 3455: ! 3456: for (grab = PASSIVEGRABS(pWin); grab; grab = grab->next) ! 3457: { ! 3458: if (GrabMatchesSecond(temporaryGrab, grab)) ! 3459: { ! 3460: if (client != grab->client) ! 3461: { ! 3462: DeleteGrab(temporaryGrab); ! 3463: return BadAccess; ! 3464: } ! 3465: } ! 3466: } ! 3467: ! 3468: DeletePassiveGrabFromList(temporaryGrab); ! 3469: ! 3470: AddPassiveGrabToWindowList(temporaryGrab); ! 3471: ! 3472: return(Success); ! 3473: } ! 3474: ! 3475: int ! 3476: ProcGrabButton(client) ! 3477: ClientPtr client; ! 3478: { ! 3479: WindowPtr pWin, confineTo; ! 3480: REQUEST(xGrabButtonReq); ! 3481: GrabPtr grab; ! 3482: CursorPtr cursor; ! 3483: GrabPtr temporaryGrab; ! 3484: ! 3485: REQUEST_SIZE_MATCH(xGrabButtonReq); ! 3486: if ((stuff->pointerMode != GrabModeSync) && ! 3487: (stuff->pointerMode != GrabModeAsync) && ! 3488: (stuff->keyboardMode != GrabModeSync) && ! 3489: (stuff->keyboardMode != GrabModeAsync)) ! 3490: return BadValue; ! 3491: ! 3492: pWin = LookupWindow(stuff->grabWindow, client); ! 3493: if (!pWin) ! 3494: { ! 3495: client->errorValue = stuff->grabWindow; ! 3496: return BadWindow; ! 3497: } ! 3498: if (stuff->confineTo == None) ! 3499: confineTo = NullWindow; ! 3500: else ! 3501: { ! 3502: confineTo = LookupWindow(stuff->confineTo, client); ! 3503: if (!confineTo) ! 3504: { ! 3505: client->errorValue = stuff->confineTo; ! 3506: return BadWindow; ! 3507: } ! 3508: } ! 3509: if (stuff->cursor == None) ! 3510: cursor = NullCursor; ! 3511: else ! 3512: { ! 3513: cursor = (CursorPtr)LookupID(stuff->cursor, RT_CURSOR, RC_CORE); ! 3514: if (!cursor) ! 3515: { ! 3516: client->errorValue = stuff->cursor; ! 3517: return BadCursor; ! 3518: } ! 3519: } ! 3520: ! 3521: ! 3522: temporaryGrab = CreateGrab(client, inputInfo.pointer, pWin, ! 3523: (stuff->eventMask | ButtonPressMask | ButtonReleaseMask), stuff->ownerEvents, ! 3524: stuff->keyboardMode, stuff->pointerMode, stuff->modifiers, stuff->button); ! 3525: ! 3526: temporaryGrab->u.ptr.confineTo = confineTo; ! 3527: temporaryGrab->u.ptr.cursor = cursor; ! 3528: ! 3529: for (grab = PASSIVEGRABS(pWin); grab; grab = grab->next) ! 3530: { ! 3531: if (GrabMatchesSecond(temporaryGrab, grab)) ! 3532: { ! 3533: if (client != grab->client) ! 3534: { ! 3535: DeleteGrab(temporaryGrab); ! 3536: return BadAccess; ! 3537: } ! 3538: } ! 3539: } ! 3540: ! 3541: DeletePassiveGrabFromList(temporaryGrab); ! 3542: ! 3543: AddPassiveGrabToWindowList(temporaryGrab); ! 3544: ! 3545: return(Success); ! 3546: } ! 3547: ! 3548: int ! 3549: ProcUngrabButton(client) ! 3550: ClientPtr client; ! 3551: { ! 3552: REQUEST(xUngrabButtonReq); ! 3553: WindowPtr pWin; ! 3554: GrabRec temporaryGrab; ! 3555: ! 3556: REQUEST_SIZE_MATCH(xUngrabButtonReq); ! 3557: pWin = LookupWindow(stuff->grabWindow, client); ! 3558: if (!pWin) ! 3559: { ! 3560: client->errorValue = stuff->grabWindow; ! 3561: return BadWindow; ! 3562: } ! 3563: ! 3564: temporaryGrab.client = client; ! 3565: temporaryGrab.device = inputInfo.pointer; ! 3566: temporaryGrab.window = pWin; ! 3567: temporaryGrab.modifiersDetail.exact = stuff->modifiers; ! 3568: temporaryGrab.modifiersDetail.pMask = NULL; ! 3569: temporaryGrab.u.ptr.buttonDetail.exact = stuff->button; ! 3570: temporaryGrab.u.ptr.buttonDetail.pMask = NULL; ! 3571: ! 3572: DeletePassiveGrabFromList(&temporaryGrab); ! 3573: ! 3574: return(Success); ! 3575: } ! 3576: ! 3577: void ! 3578: DeleteWindowFromAnyEvents(pWin, freeResources) ! 3579: WindowPtr pWin; ! 3580: Bool freeResources; ! 3581: { ! 3582: WindowPtr parent; ! 3583: FocusPtr focus = &inputInfo.keyboard->u.keybd.focus; ! 3584: DeviceIntPtr mouse = inputInfo.pointer; ! 3585: OtherClientsPtr oc; ! 3586: GrabPtr passive; ! 3587: ! 3588: ! 3589: /* Deactivate any grabs performed on this window, before making any ! 3590: input focus changes. */ ! 3591: ! 3592: if ((mouse->grab) && (mouse->grab->window == pWin)) ! 3593: DeactivatePointerGrab(mouse); ! 3594: ! 3595: /* Deactivating a keyboard grab should cause focus events. */ ! 3596: ! 3597: if ((inputInfo.keyboard->grab) && ! 3598: (inputInfo.keyboard->grab->window == pWin)) ! 3599: { ! 3600: DoFocusEvents(inputInfo.keyboard->grab->window, focus->win, NotifyUngrab); ! 3601: DeactivateKeyboardGrab(inputInfo.keyboard); ! 3602: } ! 3603: ! 3604: /* If the focus window is a root window (ie. has no parent) then don't ! 3605: delete the focus from it. */ ! 3606: ! 3607: if ((pWin == focus->win) && (pWin->parent != NullWindow)) ! 3608: { ! 3609: int focusEventMode = NotifyNormal; ! 3610: ! 3611: /* If a grab is in progress, then alter the mode of focus events. */ ! 3612: ! 3613: if (inputInfo.keyboard->grab) ! 3614: focusEventMode = NotifyWhileGrabbed; ! 3615: ! 3616: switch (focus->revert) ! 3617: { ! 3618: case RevertToNone: ! 3619: DoFocusEvents(pWin, NoneWin, focusEventMode); ! 3620: focus->win = NoneWin; ! 3621: focusTraceGood = 0; ! 3622: break; ! 3623: case RevertToParent: ! 3624: for ( ! 3625: parent = pWin->parent; ! 3626: !parent->realized; ! 3627: parent = parent->parent) ! 3628: focusTraceGood--; ! 3629: DoFocusEvents(pWin, parent, focusEventMode); ! 3630: focus->win = parent; ! 3631: focus->revert = RevertToNone; ! 3632: break; ! 3633: case RevertToPointerRoot: ! 3634: DoFocusEvents(pWin, PointerRootWin, focusEventMode); ! 3635: focus->win = PointerRootWin; ! 3636: focusTraceGood = 0; ! 3637: break; ! 3638: } ! 3639: } ! 3640: ! 3641: if (freeResources) ! 3642: { ! 3643: while (oc = OTHERCLIENTS(pWin)) ! 3644: FreeResource(oc->resource, RC_NONE); ! 3645: while (passive = PASSIVEGRABS(pWin)) ! 3646: FreeResource(passive->resource, RC_NONE); ! 3647: } ! 3648: } ! 3649: ! 3650: Mask ! 3651: EventMaskForClient(win, client, allMask) ! 3652: WindowPtr win; ! 3653: ClientPtr client; ! 3654: Mask *allMask; ! 3655: { ! 3656: OtherClientsPtr other; ! 3657: Mask him; ! 3658: if (win->client == client) ! 3659: him = win->eventMask; ! 3660: *allMask = win->eventMask; ! 3661: for (other = OTHERCLIENTS(win); other; other = other->next) ! 3662: { ! 3663: if (other->client == client) ! 3664: him = other->mask; ! 3665: *allMask |= other->mask; ! 3666: } ! 3667: return him; ! 3668: } ! 3669: ! 3670: ! 3671: int ! 3672: ProcRecolorCursor(client) ! 3673: ClientPtr client; ! 3674: { ! 3675: CursorPtr pCursor; ! 3676: int nscr; ! 3677: ScreenPtr pscr; ! 3678: REQUEST(xRecolorCursorReq); ! 3679: ! 3680: REQUEST_SIZE_MATCH(xRecolorCursorReq); ! 3681: pCursor = (CursorPtr)LookupID(stuff->cursor, RT_CURSOR, RC_CORE); ! 3682: if ( !pCursor) ! 3683: { ! 3684: client->errorValue = stuff->cursor; ! 3685: return (BadCursor); ! 3686: } ! 3687: ! 3688: pCursor->foreRed = stuff->foreRed; ! 3689: pCursor->foreGreen = stuff->foreGreen; ! 3690: pCursor->foreBlue = stuff->foreBlue; ! 3691: ! 3692: pCursor->backRed = stuff->backRed; ! 3693: pCursor->backGreen = stuff->backGreen; ! 3694: pCursor->backBlue = stuff->backBlue; ! 3695: ! 3696: for ( nscr=0, pscr=screenInfo.screen; ! 3697: nscr<screenInfo.numScreens; ! 3698: nscr++, pscr++) ! 3699: { ! 3700: ( *pscr->RecolorCursor)(pscr, pCursor, ! 3701: (pCursor == sprite.current) && (pscr == currentScreen)); ! 3702: } ! 3703: return (Success); ! 3704: } ! 3705: ! 3706: void ! 3707: WriteEventsToClient(pClient, count, events) ! 3708: ClientPtr pClient; ! 3709: int count; ! 3710: xEvent *events; ! 3711: { ! 3712: if(pClient->swapped) ! 3713: { ! 3714: int i; ! 3715: xEvent eventTo, *eventFrom; ! 3716: ! 3717: for(i = 0; i < count; i++) ! 3718: { ! 3719: eventFrom = &events[i]; ! 3720: /* Remember to strip off the leading bit of type in case ! 3721: this event was sent with "SendEvent." */ ! 3722: (*EventSwapVector[eventFrom->u.u.type & 0177]) ! 3723: (eventFrom, &eventTo); ! 3724: WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo); ! 3725: } ! 3726: } ! 3727: ! 3728: else ! 3729: { ! 3730: WriteToClient(pClient, count * sizeof(xEvent), (char *) events); ! 3731: } ! 3732: } ! 3733:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.