|
|
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.