1
/* $XFree86: xc/programs/Xserver/dix/events.c,v 3.46 2002/09/17 01:15:09 dawes Exp $ */
2
/************************************************************
4
Copyright 1987, 1998 The Open Group
6
Permission to use, copy, modify, distribute, and sell this software and its
7
documentation for any purpose is hereby granted without fee, provided that
8
the above copyright notice appear in all copies and that both that
9
copyright notice and this permission notice appear in supporting
12
The above copyright notice and this permission notice shall be included in
13
all copies or substantial portions of the Software.
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19
AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
Except as contained in this notice, the name of The Open Group shall not be
23
used in advertising or otherwise to promote the sale, use or other dealings
24
in this Software without prior written authorization from The Open Group.
27
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
31
Permission to use, copy, modify, and distribute this software and its
32
documentation for any purpose and without fee is hereby granted,
33
provided that the above copyright notice appear in all copies and that
34
both that copyright notice and this permission notice appear in
35
supporting documentation, and that the name of Digital not be
36
used in advertising or publicity pertaining to distribution of the
37
software without specific, written prior permission.
39
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
40
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
41
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
42
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
43
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
44
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
47
********************************************************/
49
/* The panoramix components contained the following notice */
50
/****************************************************************
52
* Copyright (c) Digital Equipment Corporation, 1991, 1997 *
54
* All Rights Reserved. Unpublished rights reserved under *
55
* the copyright laws of the United States. *
57
* The software contained on this media is proprietary to *
58
* and embodies the confidential technology of Digital *
59
* Equipment Corporation. Possession, use, duplication or *
60
* dissemination of the software and media is authorized only *
61
* pursuant to a valid written license from Digital Equipment *
64
* RESTRICTED RIGHTS LEGEND Use, duplication, or disclosure *
65
* by the U.S. Government is subject to restrictions as set *
66
* forth in Subparagraph (c)(1)(ii) of DFARS 252.227-7013, *
67
* or in FAR 52.227-19, as applicable. *
69
*****************************************************************/
71
/* $Xorg: events.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
79
#include "windowstr.h"
81
#include "scrnintstr.h"
82
#include "cursorstr.h"
84
#include "dixstruct.h"
86
#include "panoramiX.h"
87
#include "panoramiXsrv.h"
93
#if NeedFunctionPrototypes
94
extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
96
extern Bool XkbFilterEvents();
101
#define _SECURITY_SERVER
102
#include "security.h"
106
#include "exevents.h"
107
#include "extnsionst.h"
109
#include "dixevents.h"
110
#include "dixgrabs.h"
111
#include "dispatch.h"
113
#define EXTENSION_EVENT_BASE 64
115
#define NoSuchEvent 0x80000000 /* so doesn't match NoEventMask */
116
#define StructureAndSubMask ( StructureNotifyMask | SubstructureNotifyMask )
117
#define AllButtonsMask ( \
118
Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
119
#define MotionMask ( \
120
PointerMotionMask | Button1MotionMask | \
121
Button2MotionMask | Button3MotionMask | Button4MotionMask | \
122
Button5MotionMask | ButtonMotionMask )
123
#define PropagateMask ( \
124
KeyPressMask | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | \
126
#define PointerGrabMask ( \
127
ButtonPressMask | ButtonReleaseMask | \
128
EnterWindowMask | LeaveWindowMask | \
129
PointerMotionHintMask | KeymapStateMask | \
131
#define AllModifiersMask ( \
132
ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
133
Mod3Mask | Mod4Mask | Mod5Mask )
134
#define AllEventMasks (lastEventMask|(lastEventMask-1))
136
* The following relies on the fact that the Button<n>MotionMasks are equal
137
* to the corresponding Button<n>Masks from the current modifier/button state.
139
#define Motion_Filter(class) (PointerMotionMask | \
140
(class)->state | (class)->motionMask)
143
#define WID(w) ((w) ? ((w)->drawable.id) : 0)
145
#define XE_KBPTR (xE->u.keyButtonPointer)
148
#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
150
CallbackListPtr EventCallback;
151
CallbackListPtr DeviceEventCallback;
155
Mask DontPropagateMasks[DNPMCOUNT];
156
static int DontPropagateRefCnts[DNPMCOUNT];
159
static debug_events = 0;
164
QdEventPtr pending, *pendtail;
165
DeviceIntPtr replayDev; /* kludgy rock to put flag for */
166
WindowPtr replayWin; /* ComputeFreezes */
172
* The window trace information is used to avoid having to compute all the
173
* windows between the root and the current pointer window each time a button
174
* or key goes down. The grabs on each of those windows must be checked.
176
static WindowPtr *spriteTrace = (WindowPtr *)NULL;
177
#define ROOT spriteTrace[0]
178
static int spriteTraceSize = 0;
179
static int spriteTraceGood;
188
BoxRec hotLimits; /* logical constraints of hot spot */
189
Bool confined; /* confined to screen */
190
#if defined(SHAPE) || defined(PANORAMIX)
191
RegionPtr hotShape; /* additional logical shape constraint */
193
BoxRec physLimits; /* physical constraints of hot spot */
194
WindowPtr win; /* window of logical position */
195
HotSpot hot; /* logical pointer position */
196
HotSpot hotPhys; /* physical pointer position */
198
ScreenPtr screen; /* all others are in Screen 0 coordinates */
199
RegionRec Reg1; /* Region 1 for confining motion */
200
RegionRec Reg2; /* Region 2 for confining virtual motion */
201
WindowPtr windows[MAXSCREENS];
202
WindowPtr confineWin; /* confine window */
204
} sprite; /* info about the cursor sprite */
206
static void DoEnterLeaveEvents(
207
#if NeedFunctionPrototypes
208
WindowPtr /*fromWin*/,
214
static WindowPtr XYToWindow(
215
#if NeedFunctionPrototypes
221
extern int lastEvent;
223
static Mask lastEventMask;
226
extern int DeviceMotionNotify;
229
#define CantBeFiltered NoEventMask
230
static Mask filters[128] =
234
KeyPressMask, /* KeyPress */
235
KeyReleaseMask, /* KeyRelease */
236
ButtonPressMask, /* ButtonPress */
237
ButtonReleaseMask, /* ButtonRelease */
238
PointerMotionMask, /* MotionNotify (initial state) */
239
EnterWindowMask, /* EnterNotify */
240
LeaveWindowMask, /* LeaveNotify */
241
FocusChangeMask, /* FocusIn */
242
FocusChangeMask, /* FocusOut */
243
KeymapStateMask, /* KeymapNotify */
244
ExposureMask, /* Expose */
245
CantBeFiltered, /* GraphicsExpose */
246
CantBeFiltered, /* NoExpose */
247
VisibilityChangeMask, /* VisibilityNotify */
248
SubstructureNotifyMask, /* CreateNotify */
249
StructureAndSubMask, /* DestroyNotify */
250
StructureAndSubMask, /* UnmapNotify */
251
StructureAndSubMask, /* MapNotify */
252
SubstructureRedirectMask, /* MapRequest */
253
StructureAndSubMask, /* ReparentNotify */
254
StructureAndSubMask, /* ConfigureNotify */
255
SubstructureRedirectMask, /* ConfigureRequest */
256
StructureAndSubMask, /* GravityNotify */
257
ResizeRedirectMask, /* ResizeRequest */
258
StructureAndSubMask, /* CirculateNotify */
259
SubstructureRedirectMask, /* CirculateRequest */
260
PropertyChangeMask, /* PropertyNotify */
261
CantBeFiltered, /* SelectionClear */
262
CantBeFiltered, /* SelectionRequest */
263
CantBeFiltered, /* SelectionNotify */
264
ColormapChangeMask, /* ColormapNotify */
265
CantBeFiltered, /* ClientMessage */
266
CantBeFiltered /* MappingNotify */
269
static CARD8 criticalEvents[32] =
271
0x7c /* key and button events */
276
static void ConfineToShape(RegionPtr shape, int *px, int *py);
277
static void SyntheticMotion(int x, int y);
278
static void PostNewCursor(void);
281
XineramaSetCursorPosition(
290
/* x,y are in Screen 0 coordinates. We need to decide what Screen
291
to send the message too and what the coordinates relative to
294
pScreen = sprite.screen;
295
x += panoramiXdataPtr[0].x;
296
y += panoramiXdataPtr[0].y;
298
if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
303
if(i == pScreen->myNum)
305
if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box))
307
pScreen = screenInfo.screens[i];
313
sprite.screen = pScreen;
314
sprite.hotPhys.x = x - panoramiXdataPtr[0].x;
315
sprite.hotPhys.y = y - panoramiXdataPtr[0].y;
316
x -= panoramiXdataPtr[pScreen->myNum].x;
317
y -= panoramiXdataPtr[pScreen->myNum].y;
319
return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
324
XineramaConstrainCursor(void)
326
ScreenPtr pScreen = sprite.screen;
327
BoxRec newBox = sprite.physLimits;
329
/* Translate the constraining box to the screen
330
the sprite is actually on */
331
newBox.x1 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
332
newBox.x2 += panoramiXdataPtr[0].x - panoramiXdataPtr[pScreen->myNum].x;
333
newBox.y1 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
334
newBox.y2 += panoramiXdataPtr[0].y - panoramiXdataPtr[pScreen->myNum].y;
336
(* pScreen->ConstrainCursor)(pScreen, &newBox);
340
XineramaCheckPhysLimits(
349
new = sprite.hotPhys;
351
/* I don't care what the DDX has to say about it */
352
sprite.physLimits = sprite.hotLimits;
354
/* constrain the pointer to those limits */
355
if (new.x < sprite.physLimits.x1)
356
new.x = sprite.physLimits.x1;
358
if (new.x >= sprite.physLimits.x2)
359
new.x = sprite.physLimits.x2 - 1;
360
if (new.y < sprite.physLimits.y1)
361
new.y = sprite.physLimits.y1;
363
if (new.y >= sprite.physLimits.y2)
364
new.y = sprite.physLimits.y2 - 1;
366
if (sprite.hotShape) /* more work if the shape is a mess */
367
ConfineToShape(sprite.hotShape, &new.x, &new.y);
369
if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
371
XineramaSetCursorPosition (new.x, new.y, generateEvents);
373
SyntheticMotion(new.x, new.y);
376
/* Tell DDX what the limits are */
377
XineramaConstrainCursor();
382
XineramaSetWindowPntrs(WindowPtr pWin)
384
if(pWin == WindowTable[0]) {
385
memcpy(sprite.windows, WindowTable,
386
PanoramiXNumScreens*sizeof(WindowPtr));
391
win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW);
396
for(i = 0; i < PanoramiXNumScreens; i++) {
397
sprite.windows[i] = LookupIDByType(win->info[i].id, RT_WINDOW);
398
if(!sprite.windows[i]) /* window is being unmapped */
406
XineramaCheckVirtualMotion(
413
sprite.hot.pScreen = qe->pScreen; /* should always be Screen 0 */
414
sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
415
sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
416
pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
421
int x, y, off_x, off_y, i;
424
if(!XineramaSetWindowPntrs(pWin))
427
i = PanoramiXNumScreens - 1;
429
REGION_COPY(sprite.screen, &sprite.Reg2,
430
&sprite.windows[i]->borderSize);
431
off_x = panoramiXdataPtr[i].x;
432
off_y = panoramiXdataPtr[i].y;
435
x = off_x - panoramiXdataPtr[i].x;
436
y = off_y - panoramiXdataPtr[i].y;
439
REGION_TRANSLATE(sprite.screen, &sprite.Reg2, x, y);
441
REGION_UNION(sprite.screen, &sprite.Reg2, &sprite.Reg2,
442
&sprite.windows[i]->borderSize);
444
off_x = panoramiXdataPtr[i].x;
445
off_y = panoramiXdataPtr[i].y;
448
lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2);
450
if (sprite.hot.x < lims.x1)
451
sprite.hot.x = lims.x1;
452
else if (sprite.hot.x >= lims.x2)
453
sprite.hot.x = lims.x2 - 1;
454
if (sprite.hot.y < lims.y1)
455
sprite.hot.y = lims.y1;
456
else if (sprite.hot.y >= lims.y2)
457
sprite.hot.y = lims.y2 - 1;
459
if (REGION_NUM_RECTS(&sprite.Reg2) > 1)
460
ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y);
464
qe->pScreen = sprite.hot.pScreen;
465
qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
466
qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
473
XineramaCheckMotion(xEvent *xE)
475
WindowPtr prevSpriteWin = sprite.win;
477
if (xE && !syncEvents.playingEvents)
479
/* Motion events entering DIX get translated to Screen 0
480
coordinates. Replayed events have already been
481
translated since they've entered DIX before */
482
XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
483
panoramiXdataPtr[0].x;
484
XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
485
panoramiXdataPtr[0].y;
487
sprite.hot.x = XE_KBPTR.rootX;
488
sprite.hot.y = XE_KBPTR.rootY;
489
if (sprite.hot.x < sprite.physLimits.x1)
490
sprite.hot.x = sprite.physLimits.x1;
491
else if (sprite.hot.x >= sprite.physLimits.x2)
492
sprite.hot.x = sprite.physLimits.x2 - 1;
493
if (sprite.hot.y < sprite.physLimits.y1)
494
sprite.hot.y = sprite.physLimits.y1;
495
else if (sprite.hot.y >= sprite.physLimits.y2)
496
sprite.hot.y = sprite.physLimits.y2 - 1;
499
ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
501
sprite.hotPhys = sprite.hot;
502
if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
503
(sprite.hotPhys.y != XE_KBPTR.rootY))
505
XineramaSetCursorPosition(
506
sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
508
XE_KBPTR.rootX = sprite.hot.x;
509
XE_KBPTR.rootY = sprite.hot.y;
512
sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
514
if (sprite.win != prevSpriteWin)
516
if (prevSpriteWin != NullWindow) {
518
UpdateCurrentTimeIf();
519
DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
529
XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
532
if (syncEvents.playingEvents)
534
XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin);
535
SyntheticMotion(sprite.hot.x, sprite.hot.y);
539
int x, y, off_x, off_y, i;
541
if(!XineramaSetWindowPntrs(pWin))
544
i = PanoramiXNumScreens - 1;
546
REGION_COPY(sprite.screen, &sprite.Reg1,
547
&sprite.windows[i]->borderSize);
548
off_x = panoramiXdataPtr[i].x;
549
off_y = panoramiXdataPtr[i].y;
552
x = off_x - panoramiXdataPtr[i].x;
553
y = off_y - panoramiXdataPtr[i].y;
556
REGION_TRANSLATE(sprite.screen, &sprite.Reg1, x, y);
558
REGION_UNION(sprite.screen, &sprite.Reg1, &sprite.Reg1,
559
&sprite.windows[i]->borderSize);
561
off_x = panoramiXdataPtr[i].x;
562
off_y = panoramiXdataPtr[i].y;
565
sprite.hotLimits = *REGION_EXTENTS(sprite.screen, &sprite.Reg1);
567
if(REGION_NUM_RECTS(&sprite.Reg1) > 1)
568
sprite.hotShape = &sprite.Reg1;
570
sprite.hotShape = NullRegion;
572
sprite.confined = FALSE;
573
sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
575
XineramaCheckPhysLimits(sprite.current, generateEvents);
581
XineramaChangeToCursor(CursorPtr cursor)
583
if (cursor != sprite.current)
585
if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
586
(sprite.current->bits->yhot != cursor->bits->yhot))
587
XineramaCheckPhysLimits(cursor, FALSE);
588
(*sprite.screen->DisplayCursor)(sprite.screen, cursor);
589
sprite.current = cursor;
594
#endif /* PANORAMIX */
597
SetMaskForEvent(mask, event)
601
if ((event < LASTEvent) || (event >= 128))
602
FatalError("SetMaskForEvent: bogus event number");
603
filters[event] = mask;
607
SetCriticalEvent(event)
611
FatalError("SetCriticalEvent: bogus event number");
612
criticalEvents[event >> 3] |= 1 << (event & 7);
616
#if NeedFunctionPrototypes
617
SyntheticMotion(int x, int y)
619
SyntheticMotion(x, y)
626
/* Translate back to the sprite screen since processInputProc
627
will translate from sprite screen to screen 0 upon reentry
629
if(!noPanoramiXExtension) {
630
x += panoramiXdataPtr[0].x - panoramiXdataPtr[sprite.screen->myNum].x;
631
y += panoramiXdataPtr[0].y - panoramiXdataPtr[sprite.screen->myNum].y;
634
xE.u.keyButtonPointer.rootX = x;
635
xE.u.keyButtonPointer.rootY = y;
636
if (syncEvents.playingEvents)
637
xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
639
xE.u.keyButtonPointer.time = currentTime.milliseconds;
640
xE.u.u.type = MotionNotify;
641
(*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
646
#if NeedFunctionPrototypes
647
ConfineToShape(RegionPtr shape, int *px, int *py)
649
ConfineToShape(shape, px, py)
655
int x = *px, y = *py;
656
int incx = 1, incy = 1;
658
if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box))
660
box = *REGION_EXTENTS(sprite.hot.pScreen, shape);
661
/* this is rather crude */
680
return; /* should never get here! */
682
} while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box));
689
#if NeedFunctionPrototypes
693
Bool confineToScreen,
696
CheckPhysLimits(cursor, generateEvents, confineToScreen, pScreen)
699
Bool confineToScreen;
707
new = sprite.hotPhys;
709
new.pScreen = pScreen;
711
pScreen = new.pScreen;
712
(*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
714
sprite.confined = confineToScreen;
715
(* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
716
if (new.x < sprite.physLimits.x1)
717
new.x = sprite.physLimits.x1;
719
if (new.x >= sprite.physLimits.x2)
720
new.x = sprite.physLimits.x2 - 1;
721
if (new.y < sprite.physLimits.y1)
722
new.y = sprite.physLimits.y1;
724
if (new.y >= sprite.physLimits.y2)
725
new.y = sprite.physLimits.y2 - 1;
728
ConfineToShape(sprite.hotShape, &new.x, &new.y);
730
if ((pScreen != sprite.hotPhys.pScreen) ||
731
(new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
733
if (pScreen != sprite.hotPhys.pScreen)
734
sprite.hotPhys = new;
735
(*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
737
SyntheticMotion(new.x, new.y);
742
#if NeedFunctionPrototypes
744
register QdEventPtr qe,
745
register WindowPtr pWin)
747
CheckVirtualMotion(qe, pWin)
748
register QdEventPtr qe;
749
register WindowPtr pWin;
753
if(!noPanoramiXExtension) {
754
XineramaCheckVirtualMotion(qe, pWin);
760
sprite.hot.pScreen = qe->pScreen;
761
sprite.hot.x = qe->event->u.keyButtonPointer.rootX;
762
sprite.hot.y = qe->event->u.keyButtonPointer.rootY;
763
pWin = inputInfo.pointer->grab ? inputInfo.pointer->grab->confineTo :
770
if (sprite.hot.pScreen != pWin->drawable.pScreen)
772
sprite.hot.pScreen = pWin->drawable.pScreen;
773
sprite.hot.x = sprite.hot.y = 0;
775
lims = *REGION_EXTENTS(pWin->drawable.pScreen, &pWin->borderSize);
776
if (sprite.hot.x < lims.x1)
777
sprite.hot.x = lims.x1;
778
else if (sprite.hot.x >= lims.x2)
779
sprite.hot.x = lims.x2 - 1;
780
if (sprite.hot.y < lims.y1)
781
sprite.hot.y = lims.y1;
782
else if (sprite.hot.y >= lims.y2)
783
sprite.hot.y = lims.y2 - 1;
785
if (wBoundingShape(pWin))
786
ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
790
qe->pScreen = sprite.hot.pScreen;
791
qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
792
qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
795
ROOT = WindowTable[sprite.hot.pScreen->myNum];
799
ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
801
ScreenPtr pScreen = pWin->drawable.pScreen;
804
if(!noPanoramiXExtension) {
805
XineramaConfineCursorToWindow(pWin, generateEvents);
810
if (syncEvents.playingEvents)
812
CheckVirtualMotion((QdEventPtr)NULL, pWin);
813
SyntheticMotion(sprite.hot.x, sprite.hot.y);
817
sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
819
sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
822
CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
828
PointerConfinedToScreen()
830
return sprite.confined;
834
#if NeedFunctionPrototypes
835
ChangeToCursor(CursorPtr cursor)
837
ChangeToCursor(cursor)
842
if(!noPanoramiXExtension) {
843
XineramaChangeToCursor(cursor);
848
if (cursor != sprite.current)
850
if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
851
(sprite.current->bits->yhot != cursor->bits->yhot))
852
CheckPhysLimits(cursor, FALSE, sprite.confined,
854
(*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
856
sprite.current = cursor;
860
/* returns true if b is a descendent of a */
863
register WindowPtr a, b;
865
for (b = b->parent; b; b = b->parent)
866
if (b == a) return TRUE;
871
#if NeedFunctionPrototypes
877
register WindowPtr win;
878
register GrabPtr grab = inputInfo.pointer->grab;
880
if (syncEvents.playingEvents)
886
ChangeToCursor(grab->cursor);
889
if (IsParent(grab->window, sprite.win))
896
for (; win; win = win->parent)
897
if (win->optional && win->optional->cursor != NullCursor)
899
ChangeToCursor(win->optional->cursor);
905
GetCurrentRootWindow()
919
return sprite.current;
923
GetSpritePosition(px, py)
926
*px = sprite.hotPhys.x;
927
*py = sprite.hotPhys.y;
932
XineramaGetCursorScreen()
934
if(!noPanoramiXExtension) {
935
return sprite.screen->myNum;
940
#endif /* PANORAMIX */
942
#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
945
#if NeedFunctionPrototypes
946
MonthChangedOrBadTime(register xEvent *xE)
948
MonthChangedOrBadTime(xE)
952
/* If the ddx/OS is careless about not processing timestamped events from
953
* different sources in sorted order, then it's possible for time to go
954
* backwards when it should not. Here we ensure a decent time.
956
if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP)
957
currentTime.months++;
959
XE_KBPTR.time = currentTime.milliseconds;
962
#define NoticeTime(xE) { \
963
if ((xE)->u.keyButtonPointer.time < currentTime.milliseconds) \
964
MonthChangedOrBadTime(xE); \
965
currentTime.milliseconds = (xE)->u.keyButtonPointer.time; \
966
lastDeviceEventTime = currentTime; }
972
if (!syncEvents.playingEvents)
976
/**************************************************************************
977
* The following procedures deal with synchronous events *
978
**************************************************************************/
981
EnqueueEvent(xE, device, count)
986
register QdEventPtr tail = *syncEvents.pendtail;
987
register QdEventPtr qe;
991
if (DeviceEventCallback)
993
DeviceEventInfoRec eventinfo;
994
/* The RECORD spec says that the root window field of motion events
995
* must be valid. At this point, it hasn't been filled in yet, so
996
* we do it here. The long expression below is necessary to get
997
* the current root window; the apparently reasonable alternative
998
* GetCurrentRootWindow()->drawable.id doesn't give you the right
999
* answer on the first motion event after a screen change because
1000
* the data that GetCurrentRootWindow relies on hasn't been
1003
if (xE->u.u.type == MotionNotify)
1005
WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
1006
eventinfo.events = xE;
1007
eventinfo.count = count;
1008
CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
1010
if (xE->u.u.type == MotionNotify)
1013
if(!noPanoramiXExtension) {
1014
XE_KBPTR.rootX += panoramiXdataPtr[sprite.screen->myNum].x -
1015
panoramiXdataPtr[0].x;
1016
XE_KBPTR.rootY += panoramiXdataPtr[sprite.screen->myNum].y -
1017
panoramiXdataPtr[0].y;
1020
sprite.hotPhys.x = XE_KBPTR.rootX;
1021
sprite.hotPhys.y = XE_KBPTR.rootY;
1022
/* do motion compression */
1024
(tail->event->u.u.type == MotionNotify) &&
1025
(tail->pScreen == sprite.hotPhys.pScreen))
1027
tail->event->u.keyButtonPointer.rootX = sprite.hotPhys.x;
1028
tail->event->u.keyButtonPointer.rootY = sprite.hotPhys.y;
1029
tail->event->u.keyButtonPointer.time = XE_KBPTR.time;
1030
tail->months = currentTime.months;
1034
qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
1037
qe->next = (QdEventPtr)NULL;
1038
qe->device = device;
1039
qe->pScreen = sprite.hotPhys.pScreen;
1040
qe->months = currentTime.months;
1041
qe->event = (xEvent *)(qe + 1);
1042
qe->evcount = count;
1043
for (qxE = qe->event; --count >= 0; qxE++, xE++)
1046
syncEvents.pendtail = &tail->next;
1047
*syncEvents.pendtail = qe;
1051
#if NeedFunctionPrototypes
1052
PlayReleasedEvents(void)
1054
PlayReleasedEvents()
1057
register QdEventPtr *prev, qe;
1058
register DeviceIntPtr dev;
1060
prev = &syncEvents.pending;
1061
while ( (qe = *prev) )
1063
if (!qe->device->sync.frozen)
1066
if (*syncEvents.pendtail == *prev)
1067
syncEvents.pendtail = prev;
1068
if (qe->event->u.u.type == MotionNotify)
1069
CheckVirtualMotion(qe, NullWindow);
1070
syncEvents.time.months = qe->months;
1071
syncEvents.time.milliseconds = qe->event->u.keyButtonPointer.time;
1073
/* Translate back to the sprite screen since processInputProc
1074
will translate from sprite screen to screen 0 upon reentry
1076
if(!noPanoramiXExtension) {
1077
qe->event->u.keyButtonPointer.rootX +=
1078
panoramiXdataPtr[0].x -
1079
panoramiXdataPtr[sprite.screen->myNum].x;
1080
qe->event->u.keyButtonPointer.rootY +=
1081
panoramiXdataPtr[0].y -
1082
panoramiXdataPtr[sprite.screen->myNum].y;
1085
(*qe->device->public.processInputProc)(qe->event, qe->device,
1088
for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next)
1092
/* Playing the event may have unfrozen another device. */
1093
/* So to play it safe, restart at the head of the queue */
1094
prev = &syncEvents.pending;
1102
#if NeedFunctionPrototypes
1103
FreezeThaw(register DeviceIntPtr dev, Bool frozen)
1105
FreezeThaw(dev, frozen)
1106
register DeviceIntPtr dev;
1110
dev->sync.frozen = frozen;
1112
dev->public.processInputProc = dev->public.enqueueInputProc;
1114
dev->public.processInputProc = dev->public.realInputProc;
1120
register DeviceIntPtr replayDev = syncEvents.replayDev;
1123
register xEvent *xE;
1126
register DeviceIntPtr dev;
1128
for (dev = inputInfo.devices; dev; dev = dev->next)
1129
FreezeThaw(dev, dev->sync.other || (dev->sync.state >= FROZEN));
1130
if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
1132
syncEvents.playingEvents = TRUE;
1135
xE = replayDev->sync.event;
1136
count = replayDev->sync.evcount;
1137
syncEvents.replayDev = (DeviceIntPtr)NULL;
1139
w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
1140
for (i = 0; i < spriteTraceGood; i++)
1142
if (syncEvents.replayWin == spriteTrace[i])
1144
if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
1145
if (replayDev->focus)
1146
DeliverFocusedEvent(replayDev, xE, w, count);
1148
DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
1154
/* must not still be in the same stack */
1155
if (replayDev->focus)
1156
DeliverFocusedEvent(replayDev, xE, w, count);
1158
DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
1161
for (dev = inputInfo.devices; dev; dev = dev->next)
1163
if (!dev->sync.frozen)
1165
PlayReleasedEvents();
1169
syncEvents.playingEvents = FALSE;
1170
/* the following may have been skipped during replay, so do it now */
1171
if ((grab = inputInfo.pointer->grab) && grab->confineTo)
1173
if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
1174
sprite.hotPhys.x = sprite.hotPhys.y = 0;
1175
ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
1178
ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
1185
ScreenRestructured (ScreenPtr pScreen)
1189
if ((grab = inputInfo.pointer->grab) && grab->confineTo)
1191
if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
1192
sprite.hotPhys.x = sprite.hotPhys.y = 0;
1193
ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
1196
ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
1202
CheckGrabForSyncs(thisDev, thisMode, otherMode)
1203
register DeviceIntPtr thisDev;
1204
Bool thisMode, otherMode;
1206
register GrabPtr grab = thisDev->grab;
1207
register DeviceIntPtr dev;
1209
if (thisMode == GrabModeSync)
1210
thisDev->sync.state = FROZEN_NO_EVENT;
1212
{ /* free both if same client owns both */
1213
thisDev->sync.state = THAWED;
1214
if (thisDev->sync.other &&
1215
(CLIENT_BITS(thisDev->sync.other->resource) ==
1216
CLIENT_BITS(grab->resource)))
1217
thisDev->sync.other = NullGrab;
1219
for (dev = inputInfo.devices; dev; dev = dev->next)
1223
if (otherMode == GrabModeSync)
1224
dev->sync.other = grab;
1226
{ /* free both if same client owns both */
1227
if (dev->sync.other &&
1228
(CLIENT_BITS(dev->sync.other->resource) ==
1229
CLIENT_BITS(grab->resource)))
1230
dev->sync.other = NullGrab;
1238
ActivatePointerGrab(mouse, grab, time, autoGrab)
1239
register GrabPtr grab;
1240
register DeviceIntPtr mouse;
1244
WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
1247
if (grab->confineTo)
1249
if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
1250
sprite.hotPhys.x = sprite.hotPhys.y = 0;
1251
ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
1253
DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
1254
mouse->valuator->motionHintWindow = NullWindow;
1255
if (syncEvents.playingEvents)
1256
mouse->grabTime = syncEvents.time;
1258
mouse->grabTime = time;
1260
grab->cursor->refcnt++;
1261
mouse->activeGrab = *grab;
1262
mouse->grab = &mouse->activeGrab;
1263
mouse->fromPassiveGrab = autoGrab;
1265
CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
1269
DeactivatePointerGrab(mouse)
1270
register DeviceIntPtr mouse;
1272
register GrabPtr grab = mouse->grab;
1273
register DeviceIntPtr dev;
1275
mouse->valuator->motionHintWindow = NullWindow;
1276
mouse->grab = NullGrab;
1277
mouse->sync.state = NOT_GRABBED;
1278
mouse->fromPassiveGrab = FALSE;
1279
for (dev = inputInfo.devices; dev; dev = dev->next)
1281
if (dev->sync.other == grab)
1282
dev->sync.other = NullGrab;
1284
DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
1285
if (grab->confineTo)
1286
ConfineCursorToWindow(ROOT, FALSE, FALSE);
1289
FreeCursor(grab->cursor, (Cursor)0);
1294
ActivateKeyboardGrab(keybd, grab, time, passive)
1295
register DeviceIntPtr keybd;
1303
oldWin = keybd->grab->window;
1304
else if (keybd->focus)
1305
oldWin = keybd->focus->win;
1307
oldWin = sprite.win;
1308
if (oldWin == FollowKeyboardWin)
1309
oldWin = inputInfo.keyboard->focus->win;
1310
if (keybd->valuator)
1311
keybd->valuator->motionHintWindow = NullWindow;
1312
DoFocusEvents(keybd, oldWin, grab->window, NotifyGrab);
1313
if (syncEvents.playingEvents)
1314
keybd->grabTime = syncEvents.time;
1316
keybd->grabTime = time;
1317
keybd->activeGrab = *grab;
1318
keybd->grab = &keybd->activeGrab;
1319
keybd->fromPassiveGrab = passive;
1320
CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
1324
DeactivateKeyboardGrab(keybd)
1325
register DeviceIntPtr keybd;
1327
register GrabPtr grab = keybd->grab;
1328
register DeviceIntPtr dev;
1329
register WindowPtr focusWin = keybd->focus ? keybd->focus->win
1332
if (focusWin == FollowKeyboardWin)
1333
focusWin = inputInfo.keyboard->focus->win;
1334
if (keybd->valuator)
1335
keybd->valuator->motionHintWindow = NullWindow;
1336
keybd->grab = NullGrab;
1337
keybd->sync.state = NOT_GRABBED;
1338
keybd->fromPassiveGrab = FALSE;
1339
for (dev = inputInfo.devices; dev; dev = dev->next)
1341
if (dev->sync.other == grab)
1342
dev->sync.other = NullGrab;
1344
DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
1349
AllowSome(client, time, thisDev, newState)
1352
register DeviceIntPtr thisDev;
1355
Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
1357
register DeviceIntPtr dev;
1359
thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
1361
otherGrabbed = FALSE;
1362
othersFrozen = TRUE;
1363
grabTime = thisDev->grabTime;
1364
for (dev = inputInfo.devices; dev; dev = dev->next)
1368
if (dev->grab && SameClient(dev->grab, client))
1370
if (!(thisGrabbed || otherGrabbed) ||
1371
(CompareTimeStamps(dev->grabTime, grabTime) == LATER))
1372
grabTime = dev->grabTime;
1373
otherGrabbed = TRUE;
1374
if (thisDev->sync.other == dev->grab)
1376
if (dev->sync.state < FROZEN)
1377
othersFrozen = FALSE;
1379
else if (!dev->sync.other || !SameClient(dev->sync.other, client))
1380
othersFrozen = FALSE;
1382
if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
1384
if ((CompareTimeStamps(time, currentTime) == LATER) ||
1385
(CompareTimeStamps(time, grabTime) == EARLIER))
1389
case THAWED: /* Async */
1391
thisDev->sync.state = THAWED;
1393
thisDev->sync.other = NullGrab;
1396
case FREEZE_NEXT_EVENT: /* Sync */
1399
thisDev->sync.state = FREEZE_NEXT_EVENT;
1401
thisDev->sync.other = NullGrab;
1405
case THAWED_BOTH: /* AsyncBoth */
1408
for (dev = inputInfo.devices; dev; dev = dev->next)
1410
if (dev->grab && SameClient(dev->grab, client))
1411
dev->sync.state = THAWED;
1412
if (dev->sync.other && SameClient(dev->sync.other, client))
1413
dev->sync.other = NullGrab;
1418
case FREEZE_BOTH_NEXT_EVENT: /* SyncBoth */
1421
for (dev = inputInfo.devices; dev; dev = dev->next)
1423
if (dev->grab && SameClient(dev->grab, client))
1424
dev->sync.state = FREEZE_BOTH_NEXT_EVENT;
1425
if (dev->sync.other && SameClient(dev->sync.other, client))
1426
dev->sync.other = NullGrab;
1431
case NOT_GRABBED: /* Replay */
1432
if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
1435
thisDev->sync.other = NullGrab;
1436
syncEvents.replayDev = thisDev;
1437
syncEvents.replayWin = thisDev->grab->window;
1438
(*thisDev->DeactivateGrab)(thisDev);
1439
syncEvents.replayDev = (DeviceIntPtr)NULL;
1442
case THAW_OTHERS: /* AsyncOthers */
1445
for (dev = inputInfo.devices; dev; dev = dev->next)
1449
if (dev->grab && SameClient(dev->grab, client))
1450
dev->sync.state = THAWED;
1451
if (dev->sync.other && SameClient(dev->sync.other, client))
1452
dev->sync.other = NullGrab;
1461
ProcAllowEvents(client)
1462
register ClientPtr client;
1465
DeviceIntPtr mouse = inputInfo.pointer;
1466
DeviceIntPtr keybd = inputInfo.keyboard;
1467
REQUEST(xAllowEventsReq);
1469
REQUEST_SIZE_MATCH(xAllowEventsReq);
1470
time = ClientTimeToServerTime(stuff->time);
1471
switch (stuff->mode)
1474
AllowSome(client, time, mouse, NOT_GRABBED);
1477
AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
1480
AllowSome(client, time, mouse, THAWED);
1482
case ReplayKeyboard:
1483
AllowSome(client, time, keybd, NOT_GRABBED);
1486
AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
1489
AllowSome(client, time, keybd, THAWED);
1492
AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
1495
AllowSome(client, time, keybd, THAWED_BOTH);
1498
client->errorValue = stuff->mode;
1505
ReleaseActiveGrabs(client)
1508
register DeviceIntPtr dev;
1511
/* XXX CloseDownClient should remove passive grabs before
1512
* releasing active grabs.
1516
for (dev = inputInfo.devices; dev; dev = dev->next)
1518
if (dev->grab && SameClient(dev->grab, client))
1520
(*dev->DeactivateGrab)(dev);
1527
/**************************************************************************
1528
* The following procedures deal with delivering events *
1529
**************************************************************************/
1532
TryClientEvents (client, pEvents, count, mask, filter, grab)
1543
if (debug_events) ErrorF(
1544
"Event([%d, %d], mask=0x%x), client=%d",
1545
pEvents->u.u.type, pEvents->u.u.detail, mask, client->index);
1547
if ((client) && (client != serverClient) && (!client->clientGone) &&
1548
((filter == CantBeFiltered) || (mask & filter)))
1550
if (grab && !SameClient(grab, client))
1551
return -1; /* don't send, but notify caller */
1552
type = pEvents->u.u.type;
1553
if (type == MotionNotify)
1555
if (mask & PointerMotionHintMask)
1557
if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
1558
pEvents->u.keyButtonPointer.event)
1561
if (debug_events) ErrorF("\n");
1562
fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
1564
return 1; /* don't send, but pretend we did */
1566
pEvents->u.u.detail = NotifyHint;
1570
pEvents->u.u.detail = NotifyNormal;
1576
if ((type == DeviceMotionNotify) &&
1577
MaybeSendDeviceMotionNotifyHint
1578
((deviceKeyButtonPointer*)pEvents, mask) != 0)
1583
if (type != KeymapNotify)
1585
/* all extension events must have a sequence number */
1586
for (i = 0; i < count; i++)
1587
pEvents[i].u.u.sequenceNumber = client->sequence;
1590
if (BitIsOn(criticalEvents, type))
1592
#ifdef SMART_SCHEDULE
1593
if (client->smart_priority < SMART_MAX_PRIORITY)
1594
client->smart_priority++;
1596
SetCriticalOutputPending();
1599
WriteEventsToClient(client, count, pEvents);
1601
if (debug_events) ErrorF( " delivered\n");
1608
if (debug_events) ErrorF("\n");
1615
DeliverEventsToWindow(pWin, pEvents, count, filter, grab, mskidx)
1616
register WindowPtr pWin;
1623
int deliveries = 0, nondeliveries = 0;
1625
register InputClients *other;
1626
ClientPtr client = NullClient;
1627
Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
1628
this mask is the mask of the grab. */
1629
int type = pEvents->u.u.type;
1631
/* CantBeFiltered means only window owner gets the event */
1632
if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
1634
/* if nobody ever wants to see this event, skip some work */
1635
if (filter != CantBeFiltered &&
1636
!((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
1638
if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
1639
pWin->eventMask, filter, grab)) )
1644
client = wClient(pWin);
1645
deliveryMask = pWin->eventMask;
1650
if (filter != CantBeFiltered)
1652
if (type & EXTENSION_EVENT_BASE)
1654
OtherInputMasks *inputMasks;
1656
inputMasks = wOtherInputMasks(pWin);
1658
!(inputMasks->inputEvents[mskidx] & filter))
1660
other = inputMasks->inputClients;
1663
other = (InputClients *)wOtherClients(pWin);
1664
for (; other; other = other->next)
1666
if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
1667
other->mask[mskidx], filter, grab)) )
1672
client = rClient(other);
1673
deliveryMask = other->mask[mskidx];
1679
if ((type == ButtonPress) && deliveries && (!grab))
1683
tempGrab.device = inputInfo.pointer;
1684
tempGrab.resource = client->clientAsMask;
1685
tempGrab.window = pWin;
1686
tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
1687
tempGrab.eventMask = deliveryMask;
1688
tempGrab.keyboardMode = GrabModeAsync;
1689
tempGrab.pointerMode = GrabModeAsync;
1690
tempGrab.confineTo = NullWindow;
1691
tempGrab.cursor = NullCursor;
1692
(*inputInfo.pointer->ActivateGrab)(inputInfo.pointer, &tempGrab,
1695
else if ((type == MotionNotify) && deliveries)
1696
inputInfo.pointer->valuator->motionHintWindow = pWin;
1700
if (((type == DeviceMotionNotify) || (type == DeviceButtonPress)) &&
1702
CheckDeviceGrabAndHintWindow (pWin, type,
1703
(deviceKeyButtonPointer*) pEvents,
1704
grab, client, deliveryMask);
1709
return nondeliveries;
1712
/* If the event goes to dontClient, don't send it and return 0. if
1713
send works, return 1 or if send didn't work, return 2.
1714
Only works for core events.
1719
XineramaTryClientEventsResult(
1725
if ((client) && (client != serverClient) && (!client->clientGone) &&
1726
((filter == CantBeFiltered) || (mask & filter)))
1728
if (grab && !SameClient(grab, client)) return -1;
1736
MaybeDeliverEventsToClient(pWin, pEvents, count, filter, dontClient)
1737
register WindowPtr pWin;
1741
ClientPtr dontClient;
1743
register OtherClients *other;
1746
if (pWin->eventMask & filter)
1748
if (wClient(pWin) == dontClient)
1751
if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
1752
return XineramaTryClientEventsResult(
1753
wClient(pWin), NullGrab, pWin->eventMask, filter);
1755
return TryClientEvents(wClient(pWin), pEvents, count,
1756
pWin->eventMask, filter, NullGrab);
1758
for (other = wOtherClients(pWin); other; other = other->next)
1760
if (other->mask & filter)
1762
if (SameClient(other, dontClient))
1765
if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
1766
return XineramaTryClientEventsResult(
1767
rClient(other), NullGrab, other->mask, filter);
1769
return TryClientEvents(rClient(other), pEvents, count,
1770
other->mask, filter, NullGrab);
1777
#if NeedFunctionPrototypes
1778
FixUpEventFromWindow(
1784
FixUpEventFromWindow(xE, pWin, child, calcChild)
1793
WindowPtr w=spriteTrace[spriteTraceGood-1];
1794
/* If the search ends up past the root should the child field be
1795
set to none or should the value in the argument be passed
1796
through. It probably doesn't matter since everyone calls
1797
this function with child == None anyway. */
1801
/* If the source window is same as event window, child should be
1802
none. Don't bother going all all the way back to the root. */
1810
if (w->parent == pWin)
1812
child = w->drawable.id;
1818
XE_KBPTR.root = ROOT->drawable.id;
1819
XE_KBPTR.event = pWin->drawable.id;
1820
if (sprite.hot.pScreen == pWin->drawable.pScreen)
1822
XE_KBPTR.sameScreen = xTrue;
1823
XE_KBPTR.child = child;
1825
XE_KBPTR.rootX - pWin->drawable.x;
1827
XE_KBPTR.rootY - pWin->drawable.y;
1831
XE_KBPTR.sameScreen = xFalse;
1832
XE_KBPTR.child = None;
1833
XE_KBPTR.eventX = 0;
1834
XE_KBPTR.eventY = 0;
1839
DeliverDeviceEvents(pWin, xE, grab, stopAt, dev, count)
1840
register WindowPtr pWin, stopAt;
1841
register xEvent *xE;
1846
Window child = None;
1847
int type = xE->u.u.type;
1848
Mask filter = filters[type];
1851
if (type & EXTENSION_EVENT_BASE)
1853
register OtherInputMasks *inputMasks;
1854
int mskidx = dev->id;
1856
inputMasks = wOtherInputMasks(pWin);
1857
if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
1861
if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
1863
FixUpEventFromWindow(xE, pWin, child, FALSE);
1864
deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
1869
if ((deliveries < 0) ||
1872
(filter & inputMasks->dontPropagateMask[mskidx])))
1874
child = pWin->drawable.id;
1875
pWin = pWin->parent;
1877
inputMasks = wOtherInputMasks(pWin);
1882
if (!(filter & pWin->deliverableEvents))
1886
if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
1888
FixUpEventFromWindow(xE, pWin, child, FALSE);
1889
deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
1894
if ((deliveries < 0) ||
1896
(filter & wDontPropagateMask(pWin)))
1898
child = pWin->drawable.id;
1899
pWin = pWin->parent;
1905
/* not useful for events that propagate up the tree or extension events */
1907
DeliverEvents(pWin, xE, count, otherParent)
1908
register WindowPtr pWin, otherParent;
1909
register xEvent *xE;
1916
if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
1922
filter = filters[xE->u.u.type];
1923
if ((filter & SubstructureNotifyMask) && (xE->u.u.type != CreateNotify))
1924
xE->u.destroyNotify.event = pWin->drawable.id;
1925
if (filter != StructureAndSubMask)
1926
return DeliverEventsToWindow(pWin, xE, count, filter, NullGrab, 0);
1927
deliveries = DeliverEventsToWindow(pWin, xE, count, StructureNotifyMask,
1931
xE->u.destroyNotify.event = pWin->parent->drawable.id;
1932
deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
1933
SubstructureNotifyMask, NullGrab,
1935
if (xE->u.u.type == ReparentNotify)
1937
xE->u.destroyNotify.event = otherParent->drawable.id;
1938
deliveries += DeliverEventsToWindow(otherParent, xE, count,
1939
SubstructureNotifyMask,
1948
PointInBorderSize(WindowPtr pWin, int x, int y)
1952
if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box))
1956
if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
1959
for(i = 1; i < PanoramiXNumScreens; i++) {
1960
if(POINT_IN_REGION(sprite.screen,
1961
&sprite.windows[i]->borderSize,
1962
x + panoramiXdataPtr[0].x - panoramiXdataPtr[i].x,
1963
y + panoramiXdataPtr[0].y - panoramiXdataPtr[i].y,
1973
#if NeedFunctionPrototypes
1974
XYToWindow(int x, int y)
1980
register WindowPtr pWin;
1982
spriteTraceGood = 1; /* root window still there */
1983
pWin = ROOT->firstChild;
1986
if ((pWin->mapped) &&
1987
(x >= pWin->drawable.x - wBorderWidth (pWin)) &&
1988
(x < pWin->drawable.x + (int)pWin->drawable.width +
1989
wBorderWidth(pWin)) &&
1990
(y >= pWin->drawable.y - wBorderWidth (pWin)) &&
1991
(y < pWin->drawable.y + (int)pWin->drawable.height +
1992
wBorderWidth (pWin))
1994
/* When a window is shaped, a further check
1995
* is made to see if the point is inside
1998
&& (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
2002
if (spriteTraceGood >= spriteTraceSize)
2004
spriteTraceSize += 10;
2005
Must_have_memory = TRUE; /* XXX */
2006
spriteTrace = (WindowPtr *)xrealloc(
2007
spriteTrace, spriteTraceSize*sizeof(WindowPtr));
2008
Must_have_memory = FALSE; /* XXX */
2010
spriteTrace[spriteTraceGood++] = pWin;
2011
pWin = pWin->firstChild;
2014
pWin = pWin->nextSib;
2016
return spriteTrace[spriteTraceGood-1];
2020
#if NeedFunctionPrototypes
2021
CheckMotion(xEvent *xE)
2027
WindowPtr prevSpriteWin = sprite.win;
2030
if(!noPanoramiXExtension)
2031
return XineramaCheckMotion(xE);
2034
if (xE && !syncEvents.playingEvents)
2036
if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
2038
sprite.hot.pScreen = sprite.hotPhys.pScreen;
2039
ROOT = WindowTable[sprite.hot.pScreen->myNum];
2041
sprite.hot.x = XE_KBPTR.rootX;
2042
sprite.hot.y = XE_KBPTR.rootY;
2043
if (sprite.hot.x < sprite.physLimits.x1)
2044
sprite.hot.x = sprite.physLimits.x1;
2045
else if (sprite.hot.x >= sprite.physLimits.x2)
2046
sprite.hot.x = sprite.physLimits.x2 - 1;
2047
if (sprite.hot.y < sprite.physLimits.y1)
2048
sprite.hot.y = sprite.physLimits.y1;
2049
else if (sprite.hot.y >= sprite.physLimits.y2)
2050
sprite.hot.y = sprite.physLimits.y2 - 1;
2052
if (sprite.hotShape)
2053
ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
2055
sprite.hotPhys = sprite.hot;
2056
if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
2057
(sprite.hotPhys.y != XE_KBPTR.rootY))
2059
(*sprite.hotPhys.pScreen->SetCursorPosition)(
2060
sprite.hotPhys.pScreen,
2061
sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
2063
XE_KBPTR.rootX = sprite.hot.x;
2064
XE_KBPTR.rootY = sprite.hot.y;
2067
sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
2069
if (!(sprite.win->deliverableEvents &
2070
Motion_Filter(inputInfo.pointer->button))
2071
!syncEvents.playingEvents)
2073
/* XXX Do PointerNonInterestBox here */
2076
if (sprite.win != prevSpriteWin)
2078
if (prevSpriteWin != NullWindow) {
2080
UpdateCurrentTimeIf();
2081
DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
2090
WindowsRestructured()
2092
(void) CheckMotion((xEvent *)NULL);
2096
DefineInitialRootWindow(win)
2097
register WindowPtr win;
2099
register ScreenPtr pScreen = win->drawable.pScreen;
2101
sprite.hotPhys.pScreen = pScreen;
2102
sprite.hotPhys.x = pScreen->width / 2;
2103
sprite.hotPhys.y = pScreen->height / 2;
2104
sprite.hot = sprite.hotPhys;
2105
sprite.hotLimits.x2 = pScreen->width;
2106
sprite.hotLimits.y2 = pScreen->height;
2108
sprite.current = wCursor (win);
2109
spriteTraceGood = 1;
2111
(*pScreen->CursorLimits) (
2112
pScreen, sprite.current, &sprite.hotLimits, &sprite.physLimits);
2113
sprite.confined = FALSE;
2114
(*pScreen->ConstrainCursor) (pScreen, &sprite.physLimits);
2115
(*pScreen->SetCursorPosition) (pScreen, sprite.hot.x, sprite.hot.y, FALSE);
2116
(*pScreen->DisplayCursor) (pScreen, sprite.current);
2119
if(!noPanoramiXExtension) {
2120
sprite.hotLimits.x1 = -panoramiXdataPtr[0].x;
2121
sprite.hotLimits.y1 = -panoramiXdataPtr[0].y;
2122
sprite.hotLimits.x2 = PanoramiXPixWidth - panoramiXdataPtr[0].x;
2123
sprite.hotLimits.y2 = PanoramiXPixHeight - panoramiXdataPtr[0].y;
2124
sprite.physLimits = sprite.hotLimits;
2125
sprite.confineWin = NullWindow;
2126
sprite.screen = pScreen;
2127
/* gotta UNINIT these someplace */
2128
REGION_INIT(pScreen, &sprite.Reg1, NullBox, 1);
2129
REGION_INIT(pScreen, &sprite.Reg2, NullBox, 1);
2135
* This does not take any shortcuts, and even ignores its argument, since
2136
* it does not happen very often, and one has to walk up the tree since
2137
* this might be a newly instantiated cursor for an intermediate window
2138
* between the one the pointer is in and the one that the last cursor was
2139
* instantiated from.
2143
WindowHasNewCursor(pWin)
2150
NewCurrentScreen(newScreen, x, y)
2151
ScreenPtr newScreen;
2154
sprite.hotPhys.x = x;
2155
sprite.hotPhys.y = y;
2157
if(!noPanoramiXExtension) {
2158
sprite.hotPhys.x += panoramiXdataPtr[newScreen->myNum].x -
2159
panoramiXdataPtr[0].x;
2160
sprite.hotPhys.y += panoramiXdataPtr[newScreen->myNum].y -
2161
panoramiXdataPtr[0].y;
2162
if (newScreen != sprite.screen) {
2163
sprite.screen = newScreen;
2164
/* Make sure we tell the DDX to update its copy of the screen */
2165
if(sprite.confineWin)
2166
XineramaConfineCursorToWindow(sprite.confineWin, TRUE);
2168
XineramaConfineCursorToWindow(WindowTable[0], TRUE);
2169
/* if the pointer wasn't confined, the DDX won't get
2170
told of the pointer warp so we reposition it here */
2171
if(!syncEvents.playingEvents)
2172
(*sprite.screen->SetCursorPosition)(sprite.screen,
2173
sprite.hotPhys.x + panoramiXdataPtr[0].x -
2174
panoramiXdataPtr[sprite.screen->myNum].x,
2175
sprite.hotPhys.y + panoramiXdataPtr[0].y -
2176
panoramiXdataPtr[sprite.screen->myNum].y, FALSE);
2180
if (newScreen != sprite.hotPhys.pScreen)
2181
ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
2187
XineramaPointInWindowIsVisible(
2193
ScreenPtr pScreen = pWin->drawable.pScreen;
2197
if (!pWin->realized) return FALSE;
2199
if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
2202
if(!XineramaSetWindowPntrs(pWin)) return FALSE;
2204
xoff = x + panoramiXdataPtr[0].x;
2205
yoff = y + panoramiXdataPtr[0].y;
2207
for(i = 1; i < PanoramiXNumScreens; i++) {
2208
pWin = sprite.windows[i];
2209
pScreen = pWin->drawable.pScreen;
2210
x = xoff - panoramiXdataPtr[i].x;
2211
y = yoff - panoramiXdataPtr[i].y;
2213
if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
2222
XineramaWarpPointer(ClientPtr client)
2224
WindowPtr dest = NULL;
2227
REQUEST(xWarpPointerReq);
2230
if (stuff->dstWid != None)
2232
dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
2236
x = sprite.hotPhys.x;
2237
y = sprite.hotPhys.y;
2239
if (stuff->srcWid != None)
2242
XID winID = stuff->srcWid;
2245
source = SecurityLookupWindow(winID, client, SecurityReadAccess);
2246
if (!source) return BadWindow;
2248
winX = source->drawable.x;
2249
winY = source->drawable.y;
2250
if(source == WindowTable[0]) {
2251
winX -= panoramiXdataPtr[0].x;
2252
winY -= panoramiXdataPtr[0].y;
2254
if (x < winX + stuff->srcX ||
2255
y < winY + stuff->srcY ||
2256
(stuff->srcWidth != 0 &&
2257
winX + stuff->srcX + (int)stuff->srcWidth < x) ||
2258
(stuff->srcHeight != 0 &&
2259
winY + stuff->srcY + (int)stuff->srcHeight < y) ||
2260
!XineramaPointInWindowIsVisible(source, x, y))
2264
x = dest->drawable.x;
2265
y = dest->drawable.y;
2266
if(dest == WindowTable[0]) {
2267
x -= panoramiXdataPtr[0].x;
2268
y -= panoramiXdataPtr[0].y;
2275
if (x < sprite.physLimits.x1)
2276
x = sprite.physLimits.x1;
2277
else if (x >= sprite.physLimits.x2)
2278
x = sprite.physLimits.x2 - 1;
2279
if (y < sprite.physLimits.y1)
2280
y = sprite.physLimits.y1;
2281
else if (y >= sprite.physLimits.y2)
2282
y = sprite.physLimits.y2 - 1;
2283
if (sprite.hotShape)
2284
ConfineToShape(sprite.hotShape, &x, &y);
2286
XineramaSetCursorPosition(x, y, TRUE);
2295
ProcWarpPointer(client)
2298
WindowPtr dest = NULL;
2300
ScreenPtr newScreen;
2302
REQUEST(xWarpPointerReq);
2304
REQUEST_SIZE_MATCH(xWarpPointerReq);
2307
if(!noPanoramiXExtension)
2308
return XineramaWarpPointer(client);
2311
if (stuff->dstWid != None)
2313
dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
2317
x = sprite.hotPhys.x;
2318
y = sprite.hotPhys.y;
2320
if (stuff->srcWid != None)
2323
XID winID = stuff->srcWid;
2326
source = SecurityLookupWindow(winID, client, SecurityReadAccess);
2327
if (!source) return BadWindow;
2329
winX = source->drawable.x;
2330
winY = source->drawable.y;
2331
if (source->drawable.pScreen != sprite.hotPhys.pScreen ||
2332
x < winX + stuff->srcX ||
2333
y < winY + stuff->srcY ||
2334
(stuff->srcWidth != 0 &&
2335
winX + stuff->srcX + (int)stuff->srcWidth < x) ||
2336
(stuff->srcHeight != 0 &&
2337
winY + stuff->srcY + (int)stuff->srcHeight < y) ||
2338
!PointInWindowIsVisible(source, x, y))
2343
x = dest->drawable.x;
2344
y = dest->drawable.y;
2345
newScreen = dest->drawable.pScreen;
2347
newScreen = sprite.hotPhys.pScreen;
2354
else if (x >= newScreen->width)
2355
x = newScreen->width - 1;
2358
else if (y >= newScreen->height)
2359
y = newScreen->height - 1;
2361
if (newScreen == sprite.hotPhys.pScreen)
2363
if (x < sprite.physLimits.x1)
2364
x = sprite.physLimits.x1;
2365
else if (x >= sprite.physLimits.x2)
2366
x = sprite.physLimits.x2 - 1;
2367
if (y < sprite.physLimits.y1)
2368
y = sprite.physLimits.y1;
2369
else if (y >= sprite.physLimits.y2)
2370
y = sprite.physLimits.y2 - 1;
2372
if (sprite.hotShape)
2373
ConfineToShape(sprite.hotShape, &x, &y);
2375
(*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
2377
else if (!PointerConfinedToScreen())
2379
NewCurrentScreen(newScreen, x, y);
2385
BorderSizeNotEmpty(WindowPtr pWin)
2387
if(REGION_NOTEMPTY(sprite.hotPhys.pScreen, &pWin->borderSize))
2391
if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
2394
for(i = 1; i < PanoramiXNumScreens; i++) {
2395
if(REGION_NOTEMPTY(sprite.screen, &sprite.windows[i]->borderSize))
2403
/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
2404
passive grab set on the window to be activated. */
2407
#if NeedFunctionPrototypes
2408
CheckPassiveGrabsOnWindow(
2410
register DeviceIntPtr device,
2411
register xEvent *xE,
2414
CheckPassiveGrabsOnWindow(pWin, device, xE, count)
2416
register DeviceIntPtr device;
2417
register xEvent *xE;
2421
register GrabPtr grab = wPassiveGrabs(pWin);
2423
register xEvent *dxE;
2427
tempGrab.window = pWin;
2428
tempGrab.device = device;
2429
tempGrab.type = xE->u.u.type;
2430
tempGrab.detail.exact = xE->u.u.detail;
2431
tempGrab.detail.pMask = NULL;
2432
tempGrab.modifiersDetail.pMask = NULL;
2433
for (; grab; grab = grab->next)
2439
gdev= grab->modifierDevice;
2440
xkbi= gdev->key->xkbInfo;
2442
tempGrab.modifierDevice = grab->modifierDevice;
2443
if (device == grab->modifierDevice &&
2444
(xE->u.u.type == KeyPress
2446
|| xE->u.u.type == DeviceKeyPress
2449
tempGrab.modifiersDetail.exact =
2451
(noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods);
2453
grab->modifierDevice->key->prev_state;
2456
tempGrab.modifiersDetail.exact =
2458
(noXkbExtension ? gdev->key->state : xkbi->state.grab_mods);
2460
grab->modifierDevice->key->state;
2462
if (GrabMatchesSecond(&tempGrab, grab) &&
2463
(!grab->confineTo ||
2464
(grab->confineTo->realized &&
2465
BorderSizeNotEmpty(grab->confineTo))))
2468
if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE))
2472
if (!noXkbExtension) {
2473
XE_KBPTR.state &= 0x1f00;
2475
tempGrab.modifiersDetail.exact&(~0x1f00);
2478
(*device->ActivateGrab)(device, grab, currentTime, TRUE);
2480
FixUpEventFromWindow(xE, grab->window, None, TRUE);
2482
(void) TryClientEvents(rClient(grab), xE, count,
2483
filters[xE->u.u.type],
2484
filters[xE->u.u.type], grab);
2486
if (device->sync.state == FROZEN_NO_EVENT)
2488
if (device->sync.evcount < count)
2490
Must_have_memory = TRUE; /* XXX */
2491
device->sync.event = (xEvent *)xrealloc(device->sync.event,
2494
Must_have_memory = FALSE; /* XXX */
2496
device->sync.evcount = count;
2497
for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
2499
device->sync.state = FROZEN_WITH_EVENT;
2508
"CheckDeviceGrabs" handles both keyboard and pointer events that may cause
2509
a passive grab to be activated. If the event is a keyboard event, the
2510
ancestors of the focus window are traced down and tried to see if they have
2511
any passive grabs to be activated. If the focus window itself is reached and
2512
it's descendants contain they pointer, the ancestors of the window that the
2513
pointer is in are then traced down starting at the focus window, otherwise no
2514
grabs are activated. If the event is a pointer event, the ancestors of the
2515
window that the pointer is in are traced down starting at the root until
2516
CheckPassiveGrabs causes a passive grab to activate or all the windows are
2521
CheckDeviceGrabs(device, xE, checkFirst, count)
2522
register DeviceIntPtr device;
2523
register xEvent *xE;
2528
register WindowPtr pWin = NULL;
2529
register FocusClassPtr focus = device->focus;
2531
if ((xE->u.u.type == ButtonPress
2533
|| xE->u.u.type == DeviceButtonPress
2535
) && device->button->buttonsDown != 1)
2542
for (; i < focus->traceGood; i++)
2544
pWin = focus->trace[i];
2545
if (pWin->optional &&
2546
CheckPassiveGrabsOnWindow(pWin, device, xE, count))
2550
if ((focus->win == NoneWin) ||
2551
(i >= spriteTraceGood) ||
2552
((i > checkFirst) && (pWin != spriteTrace[i-1])))
2556
for (; i < spriteTraceGood; i++)
2558
pWin = spriteTrace[i];
2559
if (pWin->optional &&
2560
CheckPassiveGrabsOnWindow(pWin, device, xE, count))
2568
DeliverFocusedEvent(keybd, xE, window, count)
2574
WindowPtr focus = keybd->focus->win;
2577
if (focus == FollowKeyboardWin)
2578
focus = inputInfo.keyboard->focus->win;
2581
if (focus == PointerRootWin)
2583
DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
2586
if ((focus == window) || IsParent(focus, window))
2588
if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
2591
/* just deliver it to the focus window */
2592
FixUpEventFromWindow(xE, focus, None, FALSE);
2593
if (xE->u.u.type & EXTENSION_EVENT_BASE)
2595
(void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
2600
DeliverGrabbedEvent(xE, thisDev, deactivateGrab, count)
2601
register xEvent *xE;
2602
register DeviceIntPtr thisDev;
2603
Bool deactivateGrab;
2606
register GrabPtr grab = thisDev->grab;
2608
register DeviceIntPtr dev;
2609
register xEvent *dxE;
2611
if (grab->ownerEvents)
2617
focus = thisDev->focus->win;
2618
if (focus == FollowKeyboardWin)
2619
focus = inputInfo.keyboard->focus->win;
2622
focus = PointerRootWin;
2623
if (focus == PointerRootWin)
2624
deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
2626
else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
2627
deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
2630
deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
2635
FixUpEventFromWindow(xE, grab->window, None, TRUE);
2636
deliveries = TryClientEvents(rClient(grab), xE, count,
2637
(Mask)grab->eventMask,
2638
filters[xE->u.u.type], grab);
2639
if (deliveries && (xE->u.u.type == MotionNotify
2641
|| xE->u.u.type == DeviceMotionNotify
2644
thisDev->valuator->motionHintWindow = grab->window;
2646
if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
2648
&& xE->u.u.type != DeviceMotionNotify
2651
switch (thisDev->sync.state)
2653
case FREEZE_BOTH_NEXT_EVENT:
2654
for (dev = inputInfo.devices; dev; dev = dev->next)
2658
FreezeThaw(dev, TRUE);
2659
if ((dev->sync.state == FREEZE_BOTH_NEXT_EVENT) &&
2660
(CLIENT_BITS(dev->grab->resource) ==
2661
CLIENT_BITS(thisDev->grab->resource)))
2662
dev->sync.state = FROZEN_NO_EVENT;
2664
dev->sync.other = thisDev->grab;
2667
case FREEZE_NEXT_EVENT:
2668
thisDev->sync.state = FROZEN_WITH_EVENT;
2669
FreezeThaw(thisDev, TRUE);
2670
if (thisDev->sync.evcount < count)
2672
Must_have_memory = TRUE; /* XXX */
2673
thisDev->sync.event = (xEvent *)xrealloc(thisDev->sync.event,
2674
count*sizeof(xEvent));
2675
Must_have_memory = FALSE; /* XXX */
2677
thisDev->sync.evcount = count;
2678
for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
2686
CoreProcessKeyboardEvent (xE, keybd, count)
2688
ProcessKeyboardEvent (xE, keybd, count)
2690
register xEvent *xE;
2691
register DeviceIntPtr keybd;
2695
register BYTE *kptr;
2697
register CARD8 modifiers;
2698
register CARD16 mask;
2699
GrabPtr grab = keybd->grab;
2700
Bool deactivateGrab = FALSE;
2701
register KeyClassPtr keyc = keybd->key;
2703
if (!syncEvents.playingEvents)
2706
if (DeviceEventCallback)
2708
DeviceEventInfoRec eventinfo;
2709
eventinfo.events = xE;
2710
eventinfo.count = count;
2711
CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
2714
XE_KBPTR.state = (keyc->state | inputInfo.pointer->button->state);
2715
XE_KBPTR.rootX = sprite.hot.x;
2716
XE_KBPTR.rootY = sprite.hot.y;
2717
key = xE->u.u.detail;
2718
kptr = &keyc->down[key >> 3];
2719
bit = 1 << (key & 7);
2720
modifiers = keyc->modifierMap[key];
2722
if ((xkbDebugFlags&0x4)&&
2723
((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
2724
ErrorF("CoreProcessKbdEvent: Key %d %s\n",key,
2725
(xE->u.u.type==KeyPress?"down":"up"));
2728
switch (xE->u.u.type)
2731
if (*kptr & bit) /* allow ddx to generate multiple downs */
2735
xE->u.u.type = KeyRelease;
2736
(*keybd->public.processInputProc)(xE, keybd, count);
2737
xE->u.u.type = KeyPress;
2738
/* release can have side effects, don't fall through */
2739
(*keybd->public.processInputProc)(xE, keybd, count);
2743
inputInfo.pointer->valuator->motionHintWindow = NullWindow;
2745
keyc->prev_state = keyc->state;
2746
for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
2748
if (mask & modifiers)
2750
/* This key affects modifier "i" */
2751
keyc->modifierKeyCount[i]++;
2752
keyc->state |= mask;
2756
if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
2758
keybd->activatingKey = key;
2763
if (!(*kptr & bit)) /* guard against duplicates */
2765
inputInfo.pointer->valuator->motionHintWindow = NullWindow;
2767
keyc->prev_state = keyc->state;
2768
for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
2770
if (mask & modifiers) {
2771
/* This key affects modifier "i" */
2772
if (--keyc->modifierKeyCount[i] <= 0) {
2773
keyc->state &= ~mask;
2774
keyc->modifierKeyCount[i] = 0;
2779
if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
2780
deactivateGrab = TRUE;
2783
FatalError("Impossible keyboard event");
2786
DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
2788
DeliverFocusedEvent(keybd, xE, sprite.win, count);
2790
(*keybd->DeactivateGrab)(keybd);
2794
/* This function is used to set the key pressed or key released state -
2795
this is only used when the pressing of keys does not cause
2796
CoreProcessKeyEvent to be called, as in for example Mouse Keys.
2799
FixKeyState (xE, keybd)
2800
register xEvent *xE;
2801
register DeviceIntPtr keybd;
2804
register BYTE *kptr;
2805
register KeyClassPtr keyc = keybd->key;
2807
key = xE->u.u.detail;
2808
kptr = &keyc->down[key >> 3];
2809
bit = 1 << (key & 7);
2811
if ((xkbDebugFlags&0x4)&&
2812
((xE->u.u.type==KeyPress)||(xE->u.u.type==KeyRelease))) {
2813
ErrorF("FixKeyState: Key %d %s\n",key,
2814
(xE->u.u.type==KeyPress?"down":"up"));
2817
switch (xE->u.u.type)
2826
FatalError("Impossible keyboard event");
2833
CoreProcessPointerEvent (xE, mouse, count)
2835
ProcessPointerEvent (xE, mouse, count)
2837
register xEvent *xE;
2838
register DeviceIntPtr mouse;
2841
register GrabPtr grab = mouse->grab;
2842
Bool deactivateGrab = FALSE;
2843
register ButtonClassPtr butc = mouse->button;
2845
XkbSrvInfoPtr xkbi= inputInfo.keyboard->key->xkbInfo;
2848
if (!syncEvents.playingEvents)
2850
XE_KBPTR.state = (butc->state | (
2853
inputInfo.keyboard->key->state :
2854
xkbi->state.grab_mods)
2856
inputInfo.keyboard->key->state
2861
if (DeviceEventCallback)
2863
DeviceEventInfoRec eventinfo;
2864
/* see comment in EnqueueEvents regarding the next three lines */
2865
if (xE->u.u.type == MotionNotify)
2867
WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
2868
eventinfo.events = xE;
2869
eventinfo.count = count;
2870
CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
2873
if (xE->u.u.type != MotionNotify)
2876
register BYTE *kptr;
2879
XE_KBPTR.rootX = sprite.hot.x;
2880
XE_KBPTR.rootY = sprite.hot.y;
2882
key = xE->u.u.detail;
2883
kptr = &butc->down[key >> 3];
2884
bit = 1 << (key & 7);
2885
switch (xE->u.u.type)
2888
mouse->valuator->motionHintWindow = NullWindow;
2890
butc->buttonsDown++;
2891
butc->motionMask = ButtonMotionMask;
2893
#if !defined(XFree86Server) || !defined(XINPUT)
2894
xE->u.u.detail = butc->map[key];
2896
if (xE->u.u.detail == 0)
2898
if (xE->u.u.detail <= 5)
2899
butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
2900
filters[MotionNotify] = Motion_Filter(butc);
2902
if (CheckDeviceGrabs(mouse, xE, 0, count))
2906
mouse->valuator->motionHintWindow = NullWindow;
2908
--butc->buttonsDown;
2909
if (!butc->buttonsDown)
2910
butc->motionMask = 0;
2912
#if !defined(XFree86Server) || !defined(XINPUT)
2913
xE->u.u.detail = butc->map[key];
2915
if (xE->u.u.detail == 0)
2917
if (xE->u.u.detail <= 5)
2918
butc->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
2919
filters[MotionNotify] = Motion_Filter(butc);
2920
if (!butc->state && mouse->fromPassiveGrab)
2921
deactivateGrab = TRUE;
2924
FatalError("bogus pointer event from ddx");
2927
else if (!CheckMotion(xE))
2930
DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
2932
DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
2935
(*mouse->DeactivateGrab)(mouse);
2938
#define AtMostOneClient \
2939
(SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
2942
RecalculateDeliverableEvents(pWin)
2943
register WindowPtr pWin;
2945
register OtherClients *others;
2946
register WindowPtr pChild;
2951
if (pChild->optional)
2953
pChild->optional->otherEventMasks = 0;
2954
for (others = wOtherClients(pChild); others; others = others->next)
2956
pChild->optional->otherEventMasks |= others->mask;
2959
pChild->deliverableEvents = pChild->eventMask|
2960
wOtherEventMasks(pChild);
2962
pChild->deliverableEvents |=
2963
(pChild->parent->deliverableEvents &
2964
~wDontPropagateMask(pChild) & PropagateMask);
2965
if (pChild->firstChild)
2967
pChild = pChild->firstChild;
2970
while (!pChild->nextSib && (pChild != pWin))
2971
pChild = pChild->parent;
2974
pChild = pChild->nextSib;
2979
OtherClientGone(value, id)
2980
pointer value; /* must conform to DeleteType */
2983
register OtherClientsPtr other, prev;
2984
register WindowPtr pWin = (WindowPtr)value;
2987
for (other = wOtherClients(pWin); other; other = other->next)
2989
if (other->resource == id)
2992
prev->next = other->next;
2995
if (!(pWin->optional->otherClients = other->next))
2996
CheckWindowOptionalNeed (pWin);
2999
RecalculateDeliverableEvents(pWin);
3004
FatalError("client not on event list");
3006
return -1; /* make compiler happy */
3010
EventSelectForWindow(pWin, client, mask)
3011
register WindowPtr pWin;
3012
register ClientPtr client;
3016
OtherClients * others;
3018
if (mask & ~AllEventMasks)
3020
client->errorValue = mask;
3023
check = (mask & AtMostOneClient);
3024
if (check & (pWin->eventMask|wOtherEventMasks(pWin)))
3025
{ /* It is illegal for two different
3026
clients to select on any of the
3027
events for AtMostOneClient. However,
3028
it is OK, for some client to
3029
continue selecting on one of those
3031
if ((wClient(pWin) != client) && (check & pWin->eventMask))
3033
for (others = wOtherClients (pWin); others; others = others->next)
3035
if (!SameClient(others, client) && (check & others->mask))
3039
if (wClient (pWin) == client)
3041
check = pWin->eventMask;
3044
(mask & ~SGIMiscSpecialDestroyMask) | (pWin->eventMask & SGIMiscSpecialDestroyMask);
3046
pWin->eventMask = mask;
3051
for (others = wOtherClients (pWin); others; others = others->next)
3053
if (SameClient(others, client))
3055
check = others->mask;
3057
mask = (mask & ~SGIMiscSpecialDestroyMask) | (others->mask & SGIMiscSpecialDestroyMask);
3061
FreeResource(others->resource, RT_NONE);
3065
others->mask = mask;
3070
if (!pWin->optional && !MakeWindowOptional (pWin))
3072
others = (OtherClients *) xalloc(sizeof(OtherClients));
3075
others->mask = mask;
3076
others->resource = FakeClientID(client->index);
3077
others->next = pWin->optional->otherClients;
3078
pWin->optional->otherClients = others;
3079
if (!AddResource(others->resource, RT_OTHERCLIENT, (pointer)pWin))
3083
if ((inputInfo.pointer->valuator->motionHintWindow == pWin) &&
3084
(mask & PointerMotionHintMask) &&
3085
!(check & PointerMotionHintMask) &&
3086
!inputInfo.pointer->grab)
3087
inputInfo.pointer->valuator->motionHintWindow = NullWindow;
3088
RecalculateDeliverableEvents(pWin);
3094
EventSuppressForWindow(pWin, client, mask, checkOptional)
3095
register WindowPtr pWin;
3096
register ClientPtr client;
3098
Bool *checkOptional;
3100
register int i, free;
3102
if ((mask & ~PropagateMask) && !permitOldBugs)
3104
client->errorValue = mask;
3107
if (pWin->dontPropagate)
3108
DontPropagateRefCnts[pWin->dontPropagate]--;
3113
for (i = DNPMCOUNT, free = 0; --i > 0; )
3115
if (!DontPropagateRefCnts[i])
3117
else if (mask == DontPropagateMasks[i])
3123
DontPropagateMasks[i] = mask;
3128
pWin->dontPropagate = i;
3130
DontPropagateRefCnts[i]++;
3133
pWin->optional->dontPropagateMask = mask;
3134
*checkOptional = TRUE;
3139
if (!pWin->optional && !MakeWindowOptional (pWin))
3141
if (pWin->dontPropagate)
3142
DontPropagateRefCnts[pWin->dontPropagate]++;
3145
pWin->dontPropagate = 0;
3146
pWin->optional->dontPropagateMask = mask;
3148
RecalculateDeliverableEvents(pWin);
3153
#if NeedFunctionPrototypes
3155
register WindowPtr a,
3156
register WindowPtr b)
3158
CommonAncestor(a, b)
3159
register WindowPtr a, b;
3162
for (b = b->parent; b; b = b->parent)
3163
if (IsParent(b, a)) return b;
3168
#if NeedFunctionPrototypes
3173
register WindowPtr pWin,
3176
EnterLeaveEvent(type, mode, detail, pWin, child)
3177
int type, mode, detail;
3178
register WindowPtr pWin;
3183
register DeviceIntPtr keybd = inputInfo.keyboard;
3185
register DeviceIntPtr mouse = inputInfo.pointer;
3186
register GrabPtr grab = mouse->grab;
3189
if ((pWin == mouse->valuator->motionHintWindow) &&
3190
(detail != NotifyInferior))
3191
mouse->valuator->motionHintWindow = NullWindow;
3194
mask = (pWin == grab->window) ? grab->eventMask : 0;
3195
if (grab->ownerEvents)
3196
mask |= EventMaskForClient(pWin, rClient(grab));
3200
mask = pWin->eventMask | wOtherEventMasks(pWin);
3202
if (mask & filters[type])
3204
event.u.u.type = type;
3205
event.u.u.detail = detail;
3206
event.u.enterLeave.time = currentTime.milliseconds;
3207
event.u.enterLeave.rootX = sprite.hot.x;
3208
event.u.enterLeave.rootY = sprite.hot.y;
3209
/* Counts on the same initial structure of crossing & button events! */
3210
FixUpEventFromWindow(&event, pWin, None, FALSE);
3211
/* Enter/Leave events always set child */
3212
event.u.enterLeave.child = child;
3213
event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
3214
ELFlagSameScreen : 0;
3216
if (!noXkbExtension) {
3217
event.u.enterLeave.state = mouse->button->state & 0x1f00;
3218
event.u.enterLeave.state |=
3219
XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
3222
event.u.enterLeave.state = keybd->key->state | mouse->button->state;
3223
event.u.enterLeave.mode = mode;
3224
focus = keybd->focus->win;
3225
if ((focus != NoneWin) &&
3226
((pWin == focus) || (focus == PointerRootWin) ||
3227
IsParent(focus, pWin)))
3228
event.u.enterLeave.flags |= ELFlagFocus;
3230
(void)TryClientEvents(rClient(grab), &event, 1, mask,
3231
filters[type], grab);
3233
(void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
3236
if ((type == EnterNotify) && (mask & KeymapStateMask))
3241
ClientPtr client = grab ? rClient(grab)
3242
: clients[CLIENT_ID(pWin->drawable.id)];
3243
if (!SecurityCheckDeviceAccess(client, keybd, FALSE))
3245
bzero((char *)&ke.map[0], 31);
3249
memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
3250
ke.type = KeymapNotify;
3252
(void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
3253
KeymapStateMask, grab);
3255
(void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
3256
KeymapStateMask, NullGrab, 0);
3261
#if NeedFunctionPrototypes
3262
EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
3264
EnterNotifies(ancestor, child, mode, detail)
3265
WindowPtr ancestor, child;
3269
WindowPtr parent = child->parent;
3271
if (ancestor == parent)
3273
EnterNotifies(ancestor, parent, mode, detail);
3274
EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
3278
#if NeedFunctionPrototypes
3279
LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
3281
LeaveNotifies(child, ancestor, mode, detail)
3282
WindowPtr child, ancestor;
3286
register WindowPtr pWin;
3288
if (ancestor == child)
3290
for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
3292
EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
3298
#if NeedFunctionPrototypes
3299
DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
3301
DoEnterLeaveEvents(fromWin, toWin, mode)
3302
WindowPtr fromWin, toWin;
3306
if (fromWin == toWin)
3308
if (IsParent(fromWin, toWin))
3310
EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
3311
EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
3312
EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
3314
else if (IsParent(toWin, fromWin))
3316
EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
3317
LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
3318
EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
3321
{ /* neither fromWin nor toWin is descendent of the other */
3322
WindowPtr common = CommonAncestor(toWin, fromWin);
3323
/* common == NullWindow ==> different screens */
3324
EnterLeaveEvent(LeaveNotify, mode, NotifyNonlinear, fromWin, None);
3325
LeaveNotifies(fromWin, common, mode, NotifyNonlinearVirtual);
3326
EnterNotifies(common, toWin, mode, NotifyNonlinearVirtual);
3327
EnterLeaveEvent(EnterNotify, mode, NotifyNonlinear, toWin, None);
3332
#if NeedFunctionPrototypes
3333
FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin)
3335
FocusEvent(dev, type, mode, detail, pWin)
3337
int type, mode, detail;
3338
register WindowPtr pWin;
3344
if (dev != inputInfo.keyboard)
3346
DeviceFocusEvent(dev, type, mode, detail, pWin);
3350
event.u.focus.mode = mode;
3351
event.u.u.type = type;
3352
event.u.u.detail = detail;
3353
event.u.focus.window = pWin->drawable.id;
3354
(void)DeliverEventsToWindow(pWin, &event, 1, filters[type], NullGrab,
3356
if ((type == FocusIn) &&
3357
((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
3361
ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
3362
if (!SecurityCheckDeviceAccess(client, dev, FALSE))
3364
bzero((char *)&ke.map[0], 31);
3368
memmove((char *)&ke.map[0], (char *)&dev->key->down[1], 31);
3369
ke.type = KeymapNotify;
3370
(void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
3371
KeymapStateMask, NullGrab, 0);
3376
* recursive because it is easier
3377
* no-op if child not descended from ancestor
3380
#if NeedFunctionPrototypes
3383
WindowPtr ancestor, WindowPtr child, WindowPtr skipChild,
3384
int mode, int detail,
3387
FocusInEvents(dev, ancestor, child, skipChild, mode, detail, doAncestor)
3389
WindowPtr ancestor, child, skipChild;
3394
if (child == NullWindow)
3395
return ancestor == NullWindow;
3396
if (ancestor == child)
3399
FocusEvent(dev, FocusIn, mode, detail, child);
3402
if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
3405
if (child != skipChild)
3406
FocusEvent(dev, FocusIn, mode, detail, child);
3412
/* dies horribly if ancestor is not an ancestor of child */
3414
#if NeedFunctionPrototypes
3417
WindowPtr child, WindowPtr ancestor,
3418
int mode, int detail,
3421
FocusOutEvents(dev, child, ancestor, mode, detail, doAncestor)
3423
WindowPtr child, ancestor;
3429
register WindowPtr pWin;
3431
for (pWin = child; pWin != ancestor; pWin = pWin->parent)
3432
FocusEvent(dev, FocusOut, mode, detail, pWin);
3434
FocusEvent(dev, FocusOut, mode, detail, ancestor);
3438
DoFocusEvents(dev, fromWin, toWin, mode)
3440
WindowPtr fromWin, toWin;
3443
int out, in; /* for holding details for to/from
3447
if (fromWin == toWin)
3449
out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
3450
in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
3451
/* wrong values if neither, but then not referenced */
3453
if ((toWin == NullWindow) || (toWin == PointerRootWin))
3455
if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
3457
if (fromWin == PointerRootWin)
3458
FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
3460
/* Notify all the roots */
3462
if ( !noPanoramiXExtension )
3463
FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
3466
for (i=0; i<screenInfo.numScreens; i++)
3467
FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
3471
if (IsParent(fromWin, sprite.win))
3472
FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
3474
FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
3475
/* next call catches the root too, if the screen changed */
3476
FocusOutEvents(dev, fromWin->parent, NullWindow, mode,
3477
NotifyNonlinearVirtual, FALSE);
3479
/* Notify all the roots */
3481
if ( !noPanoramiXExtension )
3482
FocusEvent(dev, FocusIn, mode, in, WindowTable[0]);
3485
for (i=0; i<screenInfo.numScreens; i++)
3486
FocusEvent(dev, FocusIn, mode, in, WindowTable[i]);
3487
if (toWin == PointerRootWin)
3488
(void)FocusInEvents(dev, ROOT, sprite.win, NullWindow, mode,
3489
NotifyPointer, TRUE);
3493
if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
3495
if (fromWin == PointerRootWin)
3496
FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
3499
if ( !noPanoramiXExtension )
3500
FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
3503
for (i=0; i<screenInfo.numScreens; i++)
3504
FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
3505
if (toWin->parent != NullWindow)
3506
(void)FocusInEvents(dev, ROOT, toWin, toWin, mode,
3507
NotifyNonlinearVirtual, TRUE);
3508
FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
3509
if (IsParent(toWin, sprite.win))
3510
(void)FocusInEvents(dev, toWin, sprite.win, NullWindow, mode,
3511
NotifyPointer, FALSE);
3515
if (IsParent(toWin, fromWin))
3517
FocusEvent(dev, FocusOut, mode, NotifyAncestor, fromWin);
3518
FocusOutEvents(dev, fromWin->parent, toWin, mode,
3519
NotifyVirtual, FALSE);
3520
FocusEvent(dev, FocusIn, mode, NotifyInferior, toWin);
3521
if ((IsParent(toWin, sprite.win)) &&
3522
(sprite.win != fromWin) &&
3523
(!IsParent(fromWin, sprite.win)) &&
3524
(!IsParent(sprite.win, fromWin)))
3525
(void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
3526
mode, NotifyPointer, FALSE);
3529
if (IsParent(fromWin, toWin))
3531
if ((IsParent(fromWin, sprite.win)) &&
3532
(sprite.win != fromWin) &&
3533
(!IsParent(toWin, sprite.win)) &&
3534
(!IsParent(sprite.win, toWin)))
3535
FocusOutEvents(dev, sprite.win, fromWin, mode,
3536
NotifyPointer, FALSE);
3537
FocusEvent(dev, FocusOut, mode, NotifyInferior, fromWin);
3538
(void)FocusInEvents(dev, fromWin, toWin, toWin, mode,
3539
NotifyVirtual, FALSE);
3540
FocusEvent(dev, FocusIn, mode, NotifyAncestor, toWin);
3544
/* neither fromWin or toWin is child of other */
3545
WindowPtr common = CommonAncestor(toWin, fromWin);
3546
/* common == NullWindow ==> different screens */
3547
if (IsParent(fromWin, sprite.win))
3548
FocusOutEvents(dev, sprite.win, fromWin, mode,
3549
NotifyPointer, FALSE);
3550
FocusEvent(dev, FocusOut, mode, NotifyNonlinear, fromWin);
3551
if (fromWin->parent != NullWindow)
3552
FocusOutEvents(dev, fromWin->parent, common, mode,
3553
NotifyNonlinearVirtual, FALSE);
3554
if (toWin->parent != NullWindow)
3555
(void)FocusInEvents(dev, common, toWin, toWin, mode,
3556
NotifyNonlinearVirtual, FALSE);
3557
FocusEvent(dev, FocusIn, mode, NotifyNonlinear, toWin);
3558
if (IsParent(toWin, sprite.win))
3559
(void)FocusInEvents(dev, toWin, sprite.win, NullWindow,
3560
mode, NotifyPointer, FALSE);
3567
#if NeedFunctionPrototypes
3576
SetInputFocus(client, dev, focusID, revertTo, ctime, followOK)
3585
register FocusClassPtr focus;
3586
register WindowPtr focusWin;
3590
UpdateCurrentTime();
3591
if ((revertTo != RevertToParent) &&
3592
(revertTo != RevertToPointerRoot) &&
3593
(revertTo != RevertToNone) &&
3594
((revertTo != RevertToFollowKeyboard) || !followOK))
3596
client->errorValue = revertTo;
3599
time = ClientTimeToServerTime(ctime);
3600
if ((focusID == None) || (focusID == PointerRoot))
3601
focusWin = (WindowPtr)(long)focusID;
3602
else if ((focusID == FollowKeyboard) && followOK)
3603
focusWin = inputInfo.keyboard->focus->win;
3604
else if (!(focusWin = SecurityLookupWindow(focusID, client,
3605
SecurityReadAccess)))
3609
/* It is a match error to try to set the input focus to an
3610
unviewable window. */
3612
if(!focusWin->realized)
3616
if ((CompareTimeStamps(time, currentTime) == LATER) ||
3617
(CompareTimeStamps(time, focus->time) == EARLIER))
3619
mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
3620
if (focus->win == FollowKeyboardWin)
3621
DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
3623
DoFocusEvents(dev, focus->win, focusWin, mode);
3625
focus->revert = revertTo;
3626
if (focusID == FollowKeyboard)
3627
focus->win = FollowKeyboardWin;
3629
focus->win = focusWin;
3630
if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
3631
focus->traceGood = 0;
3635
register WindowPtr pWin;
3637
for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
3638
if (depth > focus->traceSize)
3640
focus->traceSize = depth+1;
3641
Must_have_memory = TRUE; /* XXX */
3642
focus->trace = (WindowPtr *)xrealloc(focus->trace,
3645
Must_have_memory = FALSE; /* XXX */
3647
focus->traceGood = depth;
3648
for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--)
3649
focus->trace[depth] = pWin;
3655
ProcSetInputFocus(client)
3658
REQUEST(xSetInputFocusReq);
3660
REQUEST_SIZE_MATCH(xSetInputFocusReq);
3662
if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
3665
return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
3666
stuff->revertTo, stuff->time, FALSE);
3670
ProcGetInputFocus(client)
3673
xGetInputFocusReply rep;
3674
/* REQUEST(xReq); */
3675
FocusClassPtr focus = inputInfo.keyboard->focus;
3677
REQUEST_SIZE_MATCH(xReq);
3680
rep.sequenceNumber = client->sequence;
3681
if (focus->win == NoneWin)
3683
else if (focus->win == PointerRootWin)
3684
rep.focus = PointerRoot;
3685
else rep.focus = focus->win->drawable.id;
3686
rep.revertTo = focus->revert;
3687
WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
3692
ProcGrabPointer(client)
3695
xGrabPointerReply rep;
3696
DeviceIntPtr device = inputInfo.pointer;
3698
WindowPtr pWin, confineTo;
3699
CursorPtr cursor, oldCursor;
3700
REQUEST(xGrabPointerReq);
3703
REQUEST_SIZE_MATCH(xGrabPointerReq);
3704
UpdateCurrentTime();
3705
if ((stuff->pointerMode != GrabModeSync) &&
3706
(stuff->pointerMode != GrabModeAsync))
3708
client->errorValue = stuff->pointerMode;
3711
if ((stuff->keyboardMode != GrabModeSync) &&
3712
(stuff->keyboardMode != GrabModeAsync))
3714
client->errorValue = stuff->keyboardMode;
3717
if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
3719
client->errorValue = stuff->ownerEvents;
3722
if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
3724
client->errorValue = stuff->eventMask;
3727
pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
3730
if (stuff->confineTo == None)
3731
confineTo = NullWindow;
3734
confineTo = SecurityLookupWindow(stuff->confineTo, client,
3735
SecurityReadAccess);
3739
if (stuff->cursor == None)
3740
cursor = NullCursor;
3743
cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
3744
RT_CURSOR, SecurityReadAccess);
3747
client->errorValue = stuff->cursor;
3751
/* at this point, some sort of reply is guaranteed. */
3752
time = ClientTimeToServerTime(stuff->time);
3754
rep.sequenceNumber = client->sequence;
3756
grab = device->grab;
3757
if ((grab) && !SameClient(grab, client))
3758
rep.status = AlreadyGrabbed;
3759
else if ((!pWin->realized) ||
3761
!(confineTo->realized && BorderSizeNotEmpty(confineTo))))
3762
rep.status = GrabNotViewable;
3763
else if (device->sync.frozen &&
3764
device->sync.other && !SameClient(device->sync.other, client))
3765
rep.status = GrabFrozen;
3766
else if ((CompareTimeStamps(time, currentTime) == LATER) ||
3767
(CompareTimeStamps(time, device->grabTime) == EARLIER))
3768
rep.status = GrabInvalidTime;
3773
oldCursor = NullCursor;
3776
if (grab->confineTo && !confineTo)
3777
ConfineCursorToWindow(ROOT, FALSE, FALSE);
3778
oldCursor = grab->cursor;
3780
tempGrab.cursor = cursor;
3781
tempGrab.resource = client->clientAsMask;
3782
tempGrab.ownerEvents = stuff->ownerEvents;
3783
tempGrab.eventMask = stuff->eventMask;
3784
tempGrab.confineTo = confineTo;
3785
tempGrab.window = pWin;
3786
tempGrab.keyboardMode = stuff->keyboardMode;
3787
tempGrab.pointerMode = stuff->pointerMode;
3788
tempGrab.device = device;
3789
(*device->ActivateGrab)(device, &tempGrab, time, FALSE);
3791
FreeCursor (oldCursor, (Cursor)0);
3792
rep.status = GrabSuccess;
3794
WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
3799
ProcChangeActivePointerGrab(client)
3802
DeviceIntPtr device = inputInfo.pointer;
3803
register GrabPtr grab = device->grab;
3804
CursorPtr newCursor, oldCursor;
3805
REQUEST(xChangeActivePointerGrabReq);
3808
REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
3809
if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
3811
client->errorValue = stuff->eventMask;
3814
if (stuff->cursor == None)
3815
newCursor = NullCursor;
3818
newCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
3819
RT_CURSOR, SecurityReadAccess);
3822
client->errorValue = stuff->cursor;
3828
if (!SameClient(grab, client))
3830
time = ClientTimeToServerTime(stuff->time);
3831
if ((CompareTimeStamps(time, currentTime) == LATER) ||
3832
(CompareTimeStamps(time, device->grabTime) == EARLIER))
3834
oldCursor = grab->cursor;
3835
grab->cursor = newCursor;
3837
newCursor->refcnt++;
3840
FreeCursor(oldCursor, (Cursor)0);
3841
grab->eventMask = stuff->eventMask;
3846
ProcUngrabPointer(client)
3849
DeviceIntPtr device = inputInfo.pointer;
3852
REQUEST(xResourceReq);
3854
REQUEST_SIZE_MATCH(xResourceReq);
3855
UpdateCurrentTime();
3856
grab = device->grab;
3857
time = ClientTimeToServerTime(stuff->id);
3858
if ((CompareTimeStamps(time, currentTime) != LATER) &&
3859
(CompareTimeStamps(time, device->grabTime) != EARLIER) &&
3860
(grab) && SameClient(grab, client))
3861
(*device->DeactivateGrab)(device);
3866
GrabDevice(client, dev, this_mode, other_mode, grabWindow, ownerEvents, ctime,
3868
register ClientPtr client;
3869
register DeviceIntPtr dev;
3871
unsigned other_mode;
3873
unsigned ownerEvents;
3878
register WindowPtr pWin;
3879
register GrabPtr grab;
3882
UpdateCurrentTime();
3883
if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
3885
client->errorValue = this_mode;
3888
if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
3890
client->errorValue = other_mode;
3893
if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
3895
client->errorValue = ownerEvents;
3898
pWin = SecurityLookupWindow(grabWindow, client, SecurityReadAccess);
3901
time = ClientTimeToServerTime(ctime);
3903
if (grab && !SameClient(grab, client))
3904
*status = AlreadyGrabbed;
3905
else if (!pWin->realized)
3906
*status = GrabNotViewable;
3907
else if ((CompareTimeStamps(time, currentTime) == LATER) ||
3908
(CompareTimeStamps(time, dev->grabTime) == EARLIER))
3909
*status = GrabInvalidTime;
3910
else if (dev->sync.frozen &&
3911
dev->sync.other && !SameClient(dev->sync.other, client))
3912
*status = GrabFrozen;
3917
tempGrab.window = pWin;
3918
tempGrab.resource = client->clientAsMask;
3919
tempGrab.ownerEvents = ownerEvents;
3920
tempGrab.keyboardMode = this_mode;
3921
tempGrab.pointerMode = other_mode;
3922
tempGrab.eventMask = mask;
3923
tempGrab.device = dev;
3924
(*dev->ActivateGrab)(dev, &tempGrab, time, FALSE);
3925
*status = GrabSuccess;
3931
ProcGrabKeyboard(client)
3934
xGrabKeyboardReply rep;
3935
REQUEST(xGrabKeyboardReq);
3938
REQUEST_SIZE_MATCH(xGrabKeyboardReq);
3940
if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
3943
rep.status = AlreadyGrabbed;
3947
result = GrabDevice(client, inputInfo.keyboard, stuff->keyboardMode,
3948
stuff->pointerMode, stuff->grabWindow,
3949
stuff->ownerEvents, stuff->time,
3950
KeyPressMask | KeyReleaseMask, &rep.status);
3951
if (result != Success)
3954
rep.sequenceNumber = client->sequence;
3956
WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
3961
ProcUngrabKeyboard(client)
3964
DeviceIntPtr device = inputInfo.keyboard;
3967
REQUEST(xResourceReq);
3969
REQUEST_SIZE_MATCH(xResourceReq);
3970
UpdateCurrentTime();
3971
grab = device->grab;
3972
time = ClientTimeToServerTime(stuff->id);
3973
if ((CompareTimeStamps(time, currentTime) != LATER) &&
3974
(CompareTimeStamps(time, device->grabTime) != EARLIER) &&
3975
(grab) && SameClient(grab, client))
3976
(*device->DeactivateGrab)(device);
3981
ProcQueryPointer(client)
3984
xQueryPointerReply rep;
3986
REQUEST(xResourceReq);
3987
DeviceIntPtr mouse = inputInfo.pointer;
3989
REQUEST_SIZE_MATCH(xResourceReq);
3990
pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
3993
if (mouse->valuator->motionHintWindow)
3994
MaybeStopHint(mouse, client);
3996
rep.sequenceNumber = client->sequence;
3997
rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
3999
rep.root = (ROOT)->drawable.id;
4000
rep.rootX = sprite.hot.x;
4001
rep.rootY = sprite.hot.y;
4003
if (sprite.hot.pScreen == pWin->drawable.pScreen)
4005
rep.sameScreen = xTrue;
4006
rep.winX = sprite.hot.x - pWin->drawable.x;
4007
rep.winY = sprite.hot.y - pWin->drawable.y;
4008
for (t = sprite.win; t; t = t->parent)
4009
if (t->parent == pWin)
4011
rep.child = t->drawable.id;
4017
rep.sameScreen = xFalse;
4023
if(!noPanoramiXExtension) {
4024
rep.rootX += panoramiXdataPtr[0].x;
4025
rep.rootY += panoramiXdataPtr[0].y;
4026
if(stuff->id == rep.root) {
4027
rep.winX += panoramiXdataPtr[0].x;
4028
rep.winY += panoramiXdataPtr[0].y;
4033
WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
4043
sprite.hot.pScreen = sprite.hotPhys.pScreen = (ScreenPtr)NULL;
4044
inputInfo.numDevices = 0;
4045
inputInfo.devices = (DeviceIntPtr)NULL;
4046
inputInfo.off_devices = (DeviceIntPtr)NULL;
4047
inputInfo.keyboard = (DeviceIntPtr)NULL;
4048
inputInfo.pointer = (DeviceIntPtr)NULL;
4049
if (spriteTraceSize == 0)
4051
spriteTraceSize = 32;
4052
spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
4054
FatalError("failed to allocate spriteTrace");
4056
spriteTraceGood = 0;
4057
lastEventMask = OwnerGrabButtonMask;
4058
filters[MotionNotify] = PointerMotionMask;
4059
sprite.win = NullWindow;
4060
sprite.current = NullCursor;
4061
sprite.hotLimits.x1 = 0;
4062
sprite.hotLimits.y1 = 0;
4063
sprite.hotLimits.x2 = 0;
4064
sprite.hotLimits.y2 = 0;
4065
sprite.confined = FALSE;
4066
syncEvents.replayDev = (DeviceIntPtr)NULL;
4067
syncEvents.replayWin = NullWindow;
4068
while (syncEvents.pending)
4070
QdEventPtr next = syncEvents.pending->next;
4071
xfree(syncEvents.pending);
4072
syncEvents.pending = next;
4074
syncEvents.pendtail = &syncEvents.pending;
4075
syncEvents.playingEvents = FALSE;
4076
syncEvents.time.months = 0;
4077
syncEvents.time.milliseconds = 0; /* hardly matters */
4078
currentTime.months = 0;
4079
currentTime.milliseconds = GetTimeInMillis();
4080
lastDeviceEventTime = currentTime;
4081
for (i = 0; i < DNPMCOUNT; i++)
4083
DontPropagateMasks[i] = 0;
4084
DontPropagateRefCnts[i] = 0;
4089
CloseDownEvents(void)
4093
spriteTraceSize = 0;
4097
ProcSendEvent(client)
4101
WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
4102
REQUEST(xSendEventReq);
4104
REQUEST_SIZE_MATCH(xSendEventReq);
4106
/* The client's event type must be a core event type or one defined by an
4109
if ( ! ((stuff->event.u.u.type > X_Reply &&
4110
stuff->event.u.u.type < LASTEvent) ||
4111
(stuff->event.u.u.type >= EXTENSION_EVENT_BASE &&
4112
stuff->event.u.u.type < (unsigned)lastEvent)))
4114
client->errorValue = stuff->event.u.u.type;
4117
if (stuff->event.u.u.type == ClientMessage &&
4118
stuff->event.u.u.detail != 8 &&
4119
stuff->event.u.u.detail != 16 &&
4120
stuff->event.u.u.detail != 32 &&
4123
client->errorValue = stuff->event.u.u.detail;
4126
if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs)
4128
client->errorValue = stuff->eventMask;
4132
if (stuff->destination == PointerWindow)
4134
else if (stuff->destination == InputFocus)
4136
WindowPtr inputFocus = inputInfo.keyboard->focus->win;
4138
if (inputFocus == NoneWin)
4141
/* If the input focus is PointerRootWin, send the event to where
4142
the pointer is if possible, then perhaps propogate up to root. */
4143
if (inputFocus == PointerRootWin)
4146
if (IsParent(inputFocus, sprite.win))
4148
effectiveFocus = inputFocus;
4152
effectiveFocus = pWin = inputFocus;
4155
pWin = SecurityLookupWindow(stuff->destination, client,
4156
SecurityReadAccess);
4159
if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
4161
client->errorValue = stuff->propagate;
4164
stuff->event.u.u.type |= 0x80;
4165
if (stuff->propagate)
4167
for (;pWin; pWin = pWin->parent)
4169
if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
4172
if (pWin == effectiveFocus)
4174
stuff->eventMask &= ~wDontPropagateMask(pWin);
4175
if (!stuff->eventMask)
4180
(void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
4186
ProcUngrabKey(client)
4189
REQUEST(xUngrabKeyReq);
4192
DeviceIntPtr keybd = inputInfo.keyboard;
4194
REQUEST_SIZE_MATCH(xUngrabKeyReq);
4195
pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
4199
if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
4200
(stuff->key < keybd->key->curKeySyms.minKeyCode))
4201
&& (stuff->key != AnyKey))
4203
client->errorValue = stuff->key;
4206
if ((stuff->modifiers != AnyModifier) &&
4207
(stuff->modifiers & ~AllModifiersMask))
4209
client->errorValue = stuff->modifiers;
4212
tempGrab.resource = client->clientAsMask;
4213
tempGrab.device = keybd;
4214
tempGrab.window = pWin;
4215
tempGrab.modifiersDetail.exact = stuff->modifiers;
4216
tempGrab.modifiersDetail.pMask = NULL;
4217
tempGrab.modifierDevice = inputInfo.keyboard;
4218
tempGrab.type = KeyPress;
4219
tempGrab.detail.exact = stuff->key;
4220
tempGrab.detail.pMask = NULL;
4222
if (!DeletePassiveGrabFromList(&tempGrab))
4232
REQUEST(xGrabKeyReq);
4234
DeviceIntPtr keybd = inputInfo.keyboard;
4236
REQUEST_SIZE_MATCH(xGrabKeyReq);
4237
if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
4239
client->errorValue = stuff->ownerEvents;
4242
if ((stuff->pointerMode != GrabModeSync) &&
4243
(stuff->pointerMode != GrabModeAsync))
4245
client->errorValue = stuff->pointerMode;
4248
if ((stuff->keyboardMode != GrabModeSync) &&
4249
(stuff->keyboardMode != GrabModeAsync))
4251
client->errorValue = stuff->keyboardMode;
4254
if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
4255
(stuff->key < keybd->key->curKeySyms.minKeyCode))
4256
&& (stuff->key != AnyKey))
4258
client->errorValue = stuff->key;
4261
if ((stuff->modifiers != AnyModifier) &&
4262
(stuff->modifiers & ~AllModifiersMask))
4264
client->errorValue = stuff->modifiers;
4267
pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
4271
grab = CreateGrab(client->index, keybd, pWin,
4272
(Mask)(KeyPressMask | KeyReleaseMask), (Bool)stuff->ownerEvents,
4273
(Bool)stuff->keyboardMode, (Bool)stuff->pointerMode,
4274
keybd, stuff->modifiers, KeyPress, stuff->key,
4275
NullWindow, NullCursor);
4278
return AddPassiveGrabToList(grab);
4283
ProcGrabButton(client)
4286
WindowPtr pWin, confineTo;
4287
REQUEST(xGrabButtonReq);
4291
REQUEST_SIZE_MATCH(xGrabButtonReq);
4292
if ((stuff->pointerMode != GrabModeSync) &&
4293
(stuff->pointerMode != GrabModeAsync))
4295
client->errorValue = stuff->pointerMode;
4298
if ((stuff->keyboardMode != GrabModeSync) &&
4299
(stuff->keyboardMode != GrabModeAsync))
4301
client->errorValue = stuff->keyboardMode;
4304
if ((stuff->modifiers != AnyModifier) &&
4305
(stuff->modifiers & ~AllModifiersMask))
4307
client->errorValue = stuff->modifiers;
4310
if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
4312
client->errorValue = stuff->ownerEvents;
4315
if (stuff->eventMask & ~PointerGrabMask)
4317
client->errorValue = stuff->eventMask;
4320
pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
4323
if (stuff->confineTo == None)
4324
confineTo = NullWindow;
4326
confineTo = SecurityLookupWindow(stuff->confineTo, client,
4327
SecurityReadAccess);
4331
if (stuff->cursor == None)
4332
cursor = NullCursor;
4335
cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
4336
RT_CURSOR, SecurityReadAccess);
4339
client->errorValue = stuff->cursor;
4345
grab = CreateGrab(client->index, inputInfo.pointer, pWin,
4346
permitOldBugs ? (Mask)(stuff->eventMask |
4347
ButtonPressMask | ButtonReleaseMask) :
4348
(Mask)stuff->eventMask,
4349
(Bool)stuff->ownerEvents, (Bool) stuff->keyboardMode,
4350
(Bool)stuff->pointerMode, inputInfo.keyboard, stuff->modifiers,
4351
ButtonPress, stuff->button, confineTo, cursor);
4354
return AddPassiveGrabToList(grab);
4358
ProcUngrabButton(client)
4361
REQUEST(xUngrabButtonReq);
4365
REQUEST_SIZE_MATCH(xUngrabButtonReq);
4366
if ((stuff->modifiers != AnyModifier) &&
4367
(stuff->modifiers & ~AllModifiersMask))
4369
client->errorValue = stuff->modifiers;
4372
pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
4375
tempGrab.resource = client->clientAsMask;
4376
tempGrab.device = inputInfo.pointer;
4377
tempGrab.window = pWin;
4378
tempGrab.modifiersDetail.exact = stuff->modifiers;
4379
tempGrab.modifiersDetail.pMask = NULL;
4380
tempGrab.modifierDevice = inputInfo.keyboard;
4381
tempGrab.type = ButtonPress;
4382
tempGrab.detail.exact = stuff->button;
4383
tempGrab.detail.pMask = NULL;
4385
if (!DeletePassiveGrabFromList(&tempGrab))
4391
DeleteWindowFromAnyEvents(pWin, freeResources)
4396
DeviceIntPtr mouse = inputInfo.pointer;
4397
DeviceIntPtr keybd = inputInfo.keyboard;
4398
FocusClassPtr focus = keybd->focus;
4403
/* Deactivate any grabs performed on this window, before making any
4404
input focus changes. */
4407
((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
4408
(*mouse->DeactivateGrab)(mouse);
4410
/* Deactivating a keyboard grab should cause focus events. */
4412
if (keybd->grab && (keybd->grab->window == pWin))
4413
(*keybd->DeactivateGrab)(keybd);
4415
/* If the focus window is a root window (ie. has no parent) then don't
4416
delete the focus from it. */
4418
if ((pWin == focus->win) && (pWin->parent != NullWindow))
4420
int focusEventMode = NotifyNormal;
4422
/* If a grab is in progress, then alter the mode of focus events. */
4425
focusEventMode = NotifyWhileGrabbed;
4427
switch (focus->revert)
4430
DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
4431
focus->win = NoneWin;
4432
focus->traceGood = 0;
4434
case RevertToParent:
4438
parent = parent->parent;
4440
} while (!parent->realized
4441
/* This would be a good protocol change -- windows being reparented
4442
during SaveSet processing would cause the focus to revert to the
4443
nearest enclosing window which will survive the death of the exiting
4444
client, instead of ending up reverting to a dying window and thence
4448
|| clients[CLIENT_ID(parent->drawable.id)]->clientGone
4451
DoFocusEvents(keybd, pWin, parent, focusEventMode);
4452
focus->win = parent;
4453
focus->revert = RevertToNone;
4455
case RevertToPointerRoot:
4456
DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
4457
focus->win = PointerRootWin;
4458
focus->traceGood = 0;
4463
if (mouse->valuator->motionHintWindow == pWin)
4464
mouse->valuator->motionHintWindow = NullWindow;
4468
if (pWin->dontPropagate)
4469
DontPropagateRefCnts[pWin->dontPropagate]--;
4470
while ( (oc = wOtherClients(pWin)) )
4471
FreeResource(oc->resource, RT_NONE);
4472
while ( (passive = wPassiveGrabs(pWin)) )
4473
FreeResource(passive->resource, RT_NONE);
4476
DeleteWindowFromAnyExtEvents(pWin, freeResources);
4480
/* Call this whenever some window at or below pWin has changed geometry */
4484
CheckCursorConfinement(pWin)
4487
GrabPtr grab = inputInfo.pointer->grab;
4488
WindowPtr confineTo;
4491
if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
4494
if (grab && (confineTo = grab->confineTo))
4496
if (!BorderSizeNotEmpty(confineTo))
4497
(*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
4498
else if ((pWin == confineTo) || IsParent(pWin, confineTo))
4499
ConfineCursorToWindow(confineTo, TRUE, TRUE);
4504
EventMaskForClient(pWin, client)
4508
register OtherClientsPtr other;
4510
if (wClient (pWin) == client)
4511
return pWin->eventMask;
4512
for (other = wOtherClients(pWin); other; other = other->next)
4514
if (SameClient(other, client))
4521
ProcRecolorCursor(client)
4528
REQUEST(xRecolorCursorReq);
4530
REQUEST_SIZE_MATCH(xRecolorCursorReq);
4531
pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
4532
RT_CURSOR, SecurityWriteAccess);
4535
client->errorValue = stuff->cursor;
4539
pCursor->foreRed = stuff->foreRed;
4540
pCursor->foreGreen = stuff->foreGreen;
4541
pCursor->foreBlue = stuff->foreBlue;
4543
pCursor->backRed = stuff->backRed;
4544
pCursor->backGreen = stuff->backGreen;
4545
pCursor->backBlue = stuff->backBlue;
4547
for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
4549
pscr = screenInfo.screens[nscr];
4551
if(!noPanoramiXExtension)
4552
displayed = (pscr == sprite.screen);
4555
displayed = (pscr == sprite.hotPhys.pScreen);
4556
( *pscr->RecolorCursor)(pscr, pCursor,
4557
(pCursor == sprite.current) && displayed);
4563
WriteEventsToClient(pClient, count, events)
4571
xEvent eventTo, *eventFrom;
4575
if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
4580
if(!noPanoramiXExtension &&
4581
(panoramiXdataPtr[0].x || panoramiXdataPtr[0].y))
4583
switch(events->u.u.type) {
4592
When multiple clients want the same event DeliverEventsToWindow
4593
passes the same event structure multiple times so we can't
4594
modify the one passed to us
4596
count = 1; /* should always be 1 */
4597
memcpy(&eventCopy, events, sizeof(xEvent));
4598
eventCopy.u.keyButtonPointer.rootX += panoramiXdataPtr[0].x;
4599
eventCopy.u.keyButtonPointer.rootY += panoramiXdataPtr[0].y;
4600
if(eventCopy.u.keyButtonPointer.event ==
4601
eventCopy.u.keyButtonPointer.root)
4603
eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
4604
eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
4606
events = &eventCopy;
4615
EventInfoRec eventinfo;
4616
eventinfo.client = pClient;
4617
eventinfo.events = events;
4618
eventinfo.count = count;
4619
CallCallbacks(&EventCallback, (pointer)&eventinfo);
4621
if(pClient->swapped)
4623
for(i = 0; i < count; i++)
4625
eventFrom = &events[i];
4626
/* Remember to strip off the leading bit of type in case
4627
this event was sent with "SendEvent." */
4628
(*EventSwapVector[eventFrom->u.u.type & 0177])
4629
(eventFrom, &eventTo);
4630
(void)WriteToClient(pClient, sizeof(xEvent), (char *)&eventTo);
4635
(void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);