~ubuntu-branches/ubuntu/gutsy/vnc4/gutsy

« back to all changes in this revision

Viewing changes to unix/xc/programs/Xserver/dix/events.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2006-05-15 20:35:17 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060515203517-l4lre1ku942mn26k
Tags: 4.1.1+X4.3.0-10
* Correction of critical security issue. Thanks to Martin Kogler
  <e9925248@student.tuwien.ac.at> that informed me about the issue,
  and provided the patch.
  This flaw was originally found by Steve Wiseman of intelliadmin.com.
* Applied patch from Javier Kohen <jkohen@users.sourceforge.net> that
  inform the user that only 8 first characters of the password will
  actually be used when typing more than 8 characters, closes:
  #355619.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $XFree86: xc/programs/Xserver/dix/events.c,v 3.46 2002/09/17 01:15:09 dawes Exp $ */
 
2
/************************************************************
 
3
 
 
4
Copyright 1987, 1998  The Open Group
 
5
 
 
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
 
10
documentation.
 
11
 
 
12
The above copyright notice and this permission notice shall be included in
 
13
all copies or substantial portions of the Software.
 
14
 
 
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.
 
21
 
 
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.
 
25
 
 
26
 
 
27
Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
 
28
 
 
29
                        All Rights Reserved
 
30
 
 
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.  
 
38
 
 
39
DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 
40
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 
41
DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 
42
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
43
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 
44
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 
45
SOFTWARE.
 
46
 
 
47
********************************************************/
 
48
 
 
49
/* The panoramix components contained the following notice */
 
50
/****************************************************************
 
51
*                                                               *
 
52
*    Copyright (c) Digital Equipment Corporation, 1991, 1997    *
 
53
*                                                               *
 
54
*   All Rights Reserved.  Unpublished rights  reserved  under   *
 
55
*   the copyright laws of the United States.                    *
 
56
*                                                               *
 
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  *
 
62
*   Corporation.                                                *
 
63
*                                                               *
 
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.                       *
 
68
*                                                               *
 
69
*****************************************************************/
 
70
 
 
71
/* $Xorg: events.c,v 1.4 2001/02/09 02:04:40 xorgcvs Exp $ */
 
72
 
 
73
#include "X.h"
 
74
#include "misc.h"
 
75
#include "resource.h"
 
76
#define NEED_EVENTS
 
77
#define NEED_REPLIES
 
78
#include "Xproto.h"
 
79
#include "windowstr.h"
 
80
#include "inputstr.h"
 
81
#include "scrnintstr.h"
 
82
#include "cursorstr.h"
 
83
 
 
84
#include "dixstruct.h"
 
85
#ifdef PANORAMIX
 
86
#include "panoramiX.h"
 
87
#include "panoramiXsrv.h"
 
88
#endif
 
89
#include "globals.h"
 
90
 
 
91
#ifdef XKB
 
92
#include "XKBsrv.h"
 
93
#if NeedFunctionPrototypes
 
94
extern Bool XkbFilterEvents(ClientPtr, int, xEvent *);
 
95
#else
 
96
extern Bool XkbFilterEvents();
 
97
#endif
 
98
#endif
 
99
 
 
100
#ifdef XCSECURITY
 
101
#define _SECURITY_SERVER
 
102
#include "security.h"
 
103
#endif
 
104
 
 
105
#include "XIproto.h"
 
106
#include "exevents.h"
 
107
#include "extnsionst.h"
 
108
 
 
109
#include "dixevents.h"
 
110
#include "dixgrabs.h"
 
111
#include "dispatch.h"
 
112
 
 
113
#define EXTENSION_EVENT_BASE  64
 
114
 
 
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 | \
 
125
        MotionMask )
 
126
#define PointerGrabMask ( \
 
127
        ButtonPressMask | ButtonReleaseMask | \
 
128
        EnterWindowMask | LeaveWindowMask | \
 
129
        PointerMotionHintMask | KeymapStateMask | \
 
130
        MotionMask )
 
131
#define AllModifiersMask ( \
 
132
        ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
 
133
        Mod3Mask | Mod4Mask | Mod5Mask )
 
134
#define AllEventMasks (lastEventMask|(lastEventMask-1))
 
135
/*
 
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.
 
138
 */
 
139
#define Motion_Filter(class) (PointerMotionMask | \
 
140
                              (class)->state | (class)->motionMask)
 
141
 
 
142
 
 
143
#define WID(w) ((w) ? ((w)->drawable.id) : 0)
 
144
 
 
145
#define XE_KBPTR (xE->u.keyButtonPointer)
 
146
 
 
147
 
 
148
#define rClient(obj) (clients[CLIENT_ID((obj)->resource)])
 
149
 
 
150
CallbackListPtr EventCallback;
 
151
CallbackListPtr DeviceEventCallback;
 
152
 
 
153
#define DNPMCOUNT 8
 
154
 
 
155
Mask DontPropagateMasks[DNPMCOUNT];
 
156
static int DontPropagateRefCnts[DNPMCOUNT];
 
157
 
 
158
#ifdef DEBUG
 
159
static debug_events = 0;
 
160
#endif
 
161
InputInfo inputInfo;
 
162
 
 
163
static struct {
 
164
    QdEventPtr          pending, *pendtail;
 
165
    DeviceIntPtr        replayDev;      /* kludgy rock to put flag for */
 
166
    WindowPtr           replayWin;      /*   ComputeFreezes            */
 
167
    Bool                playingEvents;
 
168
    TimeStamp           time;
 
169
} syncEvents;
 
170
 
 
171
/*
 
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.
 
175
 */
 
176
static WindowPtr *spriteTrace = (WindowPtr *)NULL;
 
177
#define ROOT spriteTrace[0]
 
178
static int spriteTraceSize = 0;
 
179
static int spriteTraceGood;
 
180
 
 
181
typedef struct {
 
182
    int         x, y;
 
183
    ScreenPtr   pScreen;
 
184
} HotSpot;
 
185
 
 
186
static  struct {
 
187
    CursorPtr   current;
 
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 */
 
192
#endif
 
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 */
 
197
#ifdef PANORAMIX
 
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 */ 
 
203
#endif
 
204
} sprite;                       /* info about the cursor sprite */
 
205
 
 
206
static void DoEnterLeaveEvents(
 
207
#if NeedFunctionPrototypes
 
208
    WindowPtr /*fromWin*/,
 
209
    WindowPtr /*toWin*/,
 
210
    int /*mode*/
 
211
#endif
 
212
);
 
213
 
 
214
static WindowPtr XYToWindow(
 
215
#if NeedFunctionPrototypes
 
216
    int /*x*/,
 
217
    int /*y*/
 
218
#endif
 
219
);
 
220
 
 
221
extern int lastEvent;
 
222
 
 
223
static Mask lastEventMask;
 
224
 
 
225
#ifdef XINPUT
 
226
extern int DeviceMotionNotify;
 
227
#endif
 
228
 
 
229
#define CantBeFiltered NoEventMask
 
230
static Mask filters[128] =
 
231
{
 
232
        NoSuchEvent,                   /* 0 */
 
233
        NoSuchEvent,                   /* 1 */
 
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 */
 
267
};
 
268
 
 
269
static CARD8 criticalEvents[32] =
 
270
{
 
271
    0x7c                                /* key and button events */
 
272
};
 
273
 
 
274
#ifdef PANORAMIX
 
275
 
 
276
static void ConfineToShape(RegionPtr shape, int *px, int *py);
 
277
static void SyntheticMotion(int x, int y);
 
278
static void PostNewCursor(void);
 
279
 
 
280
static Bool
 
281
XineramaSetCursorPosition(
 
282
    int x, 
 
283
    int y, 
 
284
    Bool generateEvent
 
285
){
 
286
    ScreenPtr pScreen;
 
287
    BoxRec box;
 
288
    int i;
 
289
 
 
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 
 
292
       that screen are. */
 
293
 
 
294
    pScreen = sprite.screen;
 
295
    x += panoramiXdataPtr[0].x;
 
296
    y += panoramiXdataPtr[0].y;
 
297
 
 
298
    if(!POINT_IN_REGION(pScreen, &XineramaScreenRegions[pScreen->myNum],
 
299
                                                                x, y, &box)) 
 
300
    {
 
301
        FOR_NSCREENS(i) 
 
302
        {
 
303
            if(i == pScreen->myNum) 
 
304
                continue;
 
305
            if(POINT_IN_REGION(pScreen, &XineramaScreenRegions[i], x, y, &box))
 
306
            {
 
307
                pScreen = screenInfo.screens[i];
 
308
                break;
 
309
            }
 
310
        }
 
311
    }
 
312
 
 
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;
 
318
 
 
319
    return (*pScreen->SetCursorPosition)(pScreen, x, y, generateEvent);
 
320
}
 
321
 
 
322
 
 
323
static void
 
324
XineramaConstrainCursor(void)
 
325
{
 
326
    ScreenPtr pScreen = sprite.screen;
 
327
    BoxRec newBox = sprite.physLimits;
 
328
 
 
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;
 
335
 
 
336
    (* pScreen->ConstrainCursor)(pScreen, &newBox);
 
337
}
 
338
 
 
339
static void
 
340
XineramaCheckPhysLimits(
 
341
    CursorPtr cursor,
 
342
    Bool generateEvents
 
343
){
 
344
    HotSpot new;
 
345
 
 
346
    if (!cursor)
 
347
        return;
 
348
 
 
349
    new = sprite.hotPhys;
 
350
 
 
351
    /* I don't care what the DDX has to say about it */
 
352
    sprite.physLimits = sprite.hotLimits;
 
353
 
 
354
    /* constrain the pointer to those limits */
 
355
    if (new.x < sprite.physLimits.x1)
 
356
        new.x = sprite.physLimits.x1;
 
357
    else
 
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;
 
362
    else
 
363
        if (new.y >= sprite.physLimits.y2)
 
364
            new.y = sprite.physLimits.y2 - 1;
 
365
 
 
366
    if (sprite.hotShape)  /* more work if the shape is a mess */
 
367
        ConfineToShape(sprite.hotShape, &new.x, &new.y);
 
368
 
 
369
    if((new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
 
370
    {
 
371
        XineramaSetCursorPosition (new.x, new.y, generateEvents);
 
372
        if (!generateEvents)
 
373
            SyntheticMotion(new.x, new.y);
 
374
    }
 
375
 
 
376
    /* Tell DDX what the limits are */
 
377
    XineramaConstrainCursor();
 
378
}
 
379
 
 
380
 
 
381
static Bool
 
382
XineramaSetWindowPntrs(WindowPtr pWin)
 
383
{
 
384
    if(pWin == WindowTable[0]) {
 
385
            memcpy(sprite.windows, WindowTable, 
 
386
                                PanoramiXNumScreens*sizeof(WindowPtr));
 
387
    } else {
 
388
        PanoramiXRes *win;
 
389
        int i;
 
390
 
 
391
        win = (PanoramiXRes*)LookupIDByType(pWin->drawable.id, XRT_WINDOW);
 
392
 
 
393
        if(!win)
 
394
            return FALSE;
 
395
 
 
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 */
 
399
                return FALSE;
 
400
        }
 
401
    }
 
402
    return TRUE;
 
403
}
 
404
 
 
405
static void
 
406
XineramaCheckVirtualMotion(
 
407
   QdEventPtr qe,
 
408
   WindowPtr pWin
 
409
){
 
410
 
 
411
    if (qe)
 
412
    {
 
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 :
 
417
                                         NullWindow;
 
418
    }
 
419
    if (pWin)
 
420
    {
 
421
        int x, y, off_x, off_y, i;
 
422
        BoxRec lims;
 
423
 
 
424
        if(!XineramaSetWindowPntrs(pWin))
 
425
            return;
 
426
 
 
427
        i = PanoramiXNumScreens - 1;
 
428
        
 
429
        REGION_COPY(sprite.screen, &sprite.Reg2, 
 
430
                                        &sprite.windows[i]->borderSize); 
 
431
        off_x = panoramiXdataPtr[i].x;
 
432
        off_y = panoramiXdataPtr[i].y;
 
433
 
 
434
        while(i--) {
 
435
            x = off_x - panoramiXdataPtr[i].x;
 
436
            y = off_y - panoramiXdataPtr[i].y;
 
437
 
 
438
            if(x || y)
 
439
                REGION_TRANSLATE(sprite.screen, &sprite.Reg2, x, y);
 
440
                
 
441
            REGION_UNION(sprite.screen, &sprite.Reg2, &sprite.Reg2, 
 
442
                                        &sprite.windows[i]->borderSize);
 
443
 
 
444
            off_x = panoramiXdataPtr[i].x;
 
445
            off_y = panoramiXdataPtr[i].y;
 
446
        }
 
447
 
 
448
        lims = *REGION_EXTENTS(sprite.screen, &sprite.Reg2);
 
449
 
 
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;
 
458
 
 
459
        if (REGION_NUM_RECTS(&sprite.Reg2) > 1) 
 
460
            ConfineToShape(&sprite.Reg2, &sprite.hot.x, &sprite.hot.y);
 
461
 
 
462
        if (qe)
 
463
        {
 
464
            qe->pScreen = sprite.hot.pScreen;
 
465
            qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
 
466
            qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
 
467
        }
 
468
    }
 
469
}
 
470
 
 
471
 
 
472
static Bool
 
473
XineramaCheckMotion(xEvent *xE)
 
474
{
 
475
    WindowPtr prevSpriteWin = sprite.win;
 
476
 
 
477
    if (xE && !syncEvents.playingEvents)
 
478
    {
 
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;
 
486
 
 
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;
 
497
 
 
498
        if (sprite.hotShape) 
 
499
            ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
 
500
 
 
501
        sprite.hotPhys = sprite.hot;
 
502
        if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
 
503
            (sprite.hotPhys.y != XE_KBPTR.rootY))
 
504
        {
 
505
            XineramaSetCursorPosition(
 
506
                        sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
 
507
        }
 
508
        XE_KBPTR.rootX = sprite.hot.x;
 
509
        XE_KBPTR.rootY = sprite.hot.y;
 
510
    }
 
511
 
 
512
    sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
 
513
 
 
514
    if (sprite.win != prevSpriteWin)
 
515
    {
 
516
        if (prevSpriteWin != NullWindow) {
 
517
            if (!xE)
 
518
                UpdateCurrentTimeIf();
 
519
            DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
 
520
        }
 
521
        PostNewCursor();
 
522
        return FALSE;
 
523
    }
 
524
    return TRUE;
 
525
}
 
526
 
 
527
 
 
528
static void
 
529
XineramaConfineCursorToWindow(WindowPtr pWin, Bool generateEvents)
 
530
{
 
531
 
 
532
    if (syncEvents.playingEvents)
 
533
    {
 
534
        XineramaCheckVirtualMotion((QdEventPtr)NULL, pWin);
 
535
        SyntheticMotion(sprite.hot.x, sprite.hot.y);
 
536
    }
 
537
    else
 
538
    {
 
539
        int x, y, off_x, off_y, i;
 
540
 
 
541
        if(!XineramaSetWindowPntrs(pWin))
 
542
            return;
 
543
 
 
544
        i = PanoramiXNumScreens - 1;
 
545
        
 
546
        REGION_COPY(sprite.screen, &sprite.Reg1, 
 
547
                                        &sprite.windows[i]->borderSize); 
 
548
        off_x = panoramiXdataPtr[i].x;
 
549
        off_y = panoramiXdataPtr[i].y;
 
550
 
 
551
        while(i--) {
 
552
            x = off_x - panoramiXdataPtr[i].x;
 
553
            y = off_y - panoramiXdataPtr[i].y;
 
554
 
 
555
            if(x || y)
 
556
                REGION_TRANSLATE(sprite.screen, &sprite.Reg1, x, y);
 
557
                
 
558
            REGION_UNION(sprite.screen, &sprite.Reg1, &sprite.Reg1, 
 
559
                                        &sprite.windows[i]->borderSize);
 
560
 
 
561
            off_x = panoramiXdataPtr[i].x;
 
562
            off_y = panoramiXdataPtr[i].y;
 
563
        }
 
564
 
 
565
        sprite.hotLimits = *REGION_EXTENTS(sprite.screen, &sprite.Reg1);
 
566
 
 
567
        if(REGION_NUM_RECTS(&sprite.Reg1) > 1)
 
568
           sprite.hotShape = &sprite.Reg1;
 
569
        else
 
570
           sprite.hotShape = NullRegion;
 
571
        
 
572
        sprite.confined = FALSE;
 
573
        sprite.confineWin = (pWin == WindowTable[0]) ? NullWindow : pWin;
 
574
 
 
575
        XineramaCheckPhysLimits(sprite.current, generateEvents);
 
576
    }
 
577
}
 
578
 
 
579
 
 
580
static void
 
581
XineramaChangeToCursor(CursorPtr cursor)
 
582
{
 
583
    if (cursor != sprite.current)
 
584
    {
 
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;
 
590
    }
 
591
}
 
592
 
 
593
 
 
594
#endif  /* PANORAMIX */
 
595
 
 
596
void
 
597
SetMaskForEvent(mask, event)
 
598
    Mask mask;
 
599
    int event;
 
600
{
 
601
    if ((event < LASTEvent) || (event >= 128))
 
602
        FatalError("SetMaskForEvent: bogus event number");
 
603
    filters[event] = mask;
 
604
}
 
605
 
 
606
void
 
607
SetCriticalEvent(event)
 
608
    int event;
 
609
{
 
610
    if (event >= 128)
 
611
        FatalError("SetCriticalEvent: bogus event number");
 
612
    criticalEvents[event >> 3] |= 1 << (event & 7);
 
613
}
 
614
 
 
615
static void
 
616
#if NeedFunctionPrototypes
 
617
SyntheticMotion(int x, int y)
 
618
#else
 
619
SyntheticMotion(x, y)
 
620
    int x, y;
 
621
#endif
 
622
{
 
623
    xEvent xE;
 
624
 
 
625
#ifdef PANORAMIX
 
626
    /* Translate back to the sprite screen since processInputProc
 
627
       will translate from sprite screen to screen 0 upon reentry
 
628
       to the DIX layer */
 
629
    if(!noPanoramiXExtension) {
 
630
        x += panoramiXdataPtr[0].x - panoramiXdataPtr[sprite.screen->myNum].x;
 
631
        y += panoramiXdataPtr[0].y - panoramiXdataPtr[sprite.screen->myNum].y;
 
632
    }
 
633
#endif
 
634
    xE.u.keyButtonPointer.rootX = x;
 
635
    xE.u.keyButtonPointer.rootY = y;
 
636
    if (syncEvents.playingEvents)
 
637
        xE.u.keyButtonPointer.time = syncEvents.time.milliseconds;
 
638
    else
 
639
        xE.u.keyButtonPointer.time = currentTime.milliseconds;
 
640
    xE.u.u.type = MotionNotify;
 
641
    (*inputInfo.pointer->public.processInputProc)(&xE, inputInfo.pointer, 1);
 
642
}
 
643
 
 
644
#ifdef SHAPE
 
645
static void
 
646
#if NeedFunctionPrototypes
 
647
ConfineToShape(RegionPtr shape, int *px, int *py)
 
648
#else
 
649
ConfineToShape(shape, px, py)
 
650
    RegionPtr shape;
 
651
    int *px, *py;
 
652
#endif
 
653
{
 
654
    BoxRec box;
 
655
    int x = *px, y = *py;
 
656
    int incx = 1, incy = 1;
 
657
 
 
658
    if (POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box))
 
659
        return;
 
660
    box = *REGION_EXTENTS(sprite.hot.pScreen, shape);
 
661
    /* this is rather crude */
 
662
    do {
 
663
        x += incx;
 
664
        if (x >= box.x2)
 
665
        {
 
666
            incx = -1;
 
667
            x = *px - 1;
 
668
        }
 
669
        else if (x < box.x1)
 
670
        {
 
671
            incx = 1;
 
672
            x = *px;
 
673
            y += incy;
 
674
            if (y >= box.y2)
 
675
            {
 
676
                incy = -1;
 
677
                y = *py - 1;
 
678
            }
 
679
            else if (y < box.y1)
 
680
                return; /* should never get here! */
 
681
        }
 
682
    } while (!POINT_IN_REGION(sprite.hot.pScreen, shape, x, y, &box));
 
683
    *px = x;
 
684
    *py = y;
 
685
}
 
686
#endif
 
687
 
 
688
static void
 
689
#if NeedFunctionPrototypes
 
690
CheckPhysLimits(
 
691
    CursorPtr cursor,
 
692
    Bool generateEvents,
 
693
    Bool confineToScreen,
 
694
    ScreenPtr pScreen)
 
695
#else
 
696
CheckPhysLimits(cursor, generateEvents, confineToScreen, pScreen)
 
697
    CursorPtr cursor;
 
698
    Bool generateEvents;
 
699
    Bool confineToScreen;
 
700
    ScreenPtr pScreen;
 
701
#endif
 
702
{
 
703
    HotSpot new;
 
704
 
 
705
    if (!cursor)
 
706
        return;
 
707
    new = sprite.hotPhys;
 
708
    if (pScreen)
 
709
        new.pScreen = pScreen;
 
710
    else
 
711
        pScreen = new.pScreen;
 
712
    (*pScreen->CursorLimits) (pScreen, cursor, &sprite.hotLimits,
 
713
                              &sprite.physLimits);
 
714
    sprite.confined = confineToScreen;
 
715
    (* pScreen->ConstrainCursor)(pScreen, &sprite.physLimits);
 
716
    if (new.x < sprite.physLimits.x1)
 
717
        new.x = sprite.physLimits.x1;
 
718
    else
 
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;
 
723
    else
 
724
        if (new.y >= sprite.physLimits.y2)
 
725
            new.y = sprite.physLimits.y2 - 1;
 
726
#ifdef SHAPE
 
727
    if (sprite.hotShape)
 
728
        ConfineToShape(sprite.hotShape, &new.x, &new.y); 
 
729
#endif
 
730
    if ((pScreen != sprite.hotPhys.pScreen) ||
 
731
        (new.x != sprite.hotPhys.x) || (new.y != sprite.hotPhys.y))
 
732
    {
 
733
        if (pScreen != sprite.hotPhys.pScreen)
 
734
            sprite.hotPhys = new;
 
735
        (*pScreen->SetCursorPosition) (pScreen, new.x, new.y, generateEvents);
 
736
        if (!generateEvents)
 
737
            SyntheticMotion(new.x, new.y);
 
738
    }
 
739
}
 
740
 
 
741
static void
 
742
#if NeedFunctionPrototypes
 
743
CheckVirtualMotion(
 
744
    register QdEventPtr qe,
 
745
    register WindowPtr pWin)
 
746
#else
 
747
CheckVirtualMotion(qe, pWin)
 
748
    register QdEventPtr qe;
 
749
    register WindowPtr pWin;
 
750
#endif
 
751
{
 
752
#ifdef PANORAMIX
 
753
    if(!noPanoramiXExtension) {
 
754
        XineramaCheckVirtualMotion(qe, pWin);
 
755
        return;
 
756
    }
 
757
#endif
 
758
    if (qe)
 
759
    {
 
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 :
 
764
                                         NullWindow;
 
765
    }
 
766
    if (pWin)
 
767
    {
 
768
        BoxRec lims;
 
769
 
 
770
        if (sprite.hot.pScreen != pWin->drawable.pScreen)
 
771
        {
 
772
            sprite.hot.pScreen = pWin->drawable.pScreen;
 
773
            sprite.hot.x = sprite.hot.y = 0;
 
774
        }
 
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;
 
784
#ifdef SHAPE
 
785
        if (wBoundingShape(pWin))
 
786
            ConfineToShape(&pWin->borderSize, &sprite.hot.x, &sprite.hot.y);
 
787
#endif
 
788
        if (qe)
 
789
        {
 
790
            qe->pScreen = sprite.hot.pScreen;
 
791
            qe->event->u.keyButtonPointer.rootX = sprite.hot.x;
 
792
            qe->event->u.keyButtonPointer.rootY = sprite.hot.y;
 
793
        }
 
794
    }
 
795
    ROOT = WindowTable[sprite.hot.pScreen->myNum];
 
796
}
 
797
 
 
798
static void
 
799
ConfineCursorToWindow(WindowPtr pWin, Bool generateEvents, Bool confineToScreen)
 
800
{
 
801
    ScreenPtr pScreen = pWin->drawable.pScreen;
 
802
 
 
803
#ifdef PANORAMIX
 
804
    if(!noPanoramiXExtension) {
 
805
        XineramaConfineCursorToWindow(pWin, generateEvents);
 
806
        return;
 
807
    }   
 
808
#endif
 
809
 
 
810
    if (syncEvents.playingEvents)
 
811
    {
 
812
        CheckVirtualMotion((QdEventPtr)NULL, pWin);
 
813
        SyntheticMotion(sprite.hot.x, sprite.hot.y);
 
814
    }
 
815
    else
 
816
    {
 
817
        sprite.hotLimits = *REGION_EXTENTS( pScreen, &pWin->borderSize);
 
818
#ifdef SHAPE
 
819
        sprite.hotShape = wBoundingShape(pWin) ? &pWin->borderSize
 
820
                                               : NullRegion;
 
821
#endif
 
822
        CheckPhysLimits(sprite.current, generateEvents, confineToScreen,
 
823
                        pScreen);
 
824
    }
 
825
}
 
826
 
 
827
Bool
 
828
PointerConfinedToScreen()
 
829
{
 
830
    return sprite.confined;
 
831
}
 
832
 
 
833
static void
 
834
#if NeedFunctionPrototypes
 
835
ChangeToCursor(CursorPtr cursor)
 
836
#else
 
837
ChangeToCursor(cursor)
 
838
    CursorPtr cursor;
 
839
#endif
 
840
{
 
841
#ifdef PANORAMIX
 
842
    if(!noPanoramiXExtension) {
 
843
        XineramaChangeToCursor(cursor);
 
844
        return;
 
845
    }
 
846
#endif
 
847
 
 
848
    if (cursor != sprite.current)
 
849
    {
 
850
        if ((sprite.current->bits->xhot != cursor->bits->xhot) ||
 
851
                (sprite.current->bits->yhot != cursor->bits->yhot))
 
852
            CheckPhysLimits(cursor, FALSE, sprite.confined,
 
853
                            (ScreenPtr)NULL);
 
854
        (*sprite.hotPhys.pScreen->DisplayCursor) (sprite.hotPhys.pScreen,
 
855
                                                  cursor);
 
856
        sprite.current = cursor;
 
857
    }
 
858
}
 
859
 
 
860
/* returns true if b is a descendent of a */
 
861
Bool
 
862
IsParent(a, b)
 
863
    register WindowPtr a, b;
 
864
{
 
865
    for (b = b->parent; b; b = b->parent)
 
866
        if (b == a) return TRUE;
 
867
    return FALSE;
 
868
}
 
869
 
 
870
static void
 
871
#if NeedFunctionPrototypes
 
872
PostNewCursor(void)
 
873
#else
 
874
PostNewCursor()
 
875
#endif
 
876
{
 
877
    register    WindowPtr win;
 
878
    register    GrabPtr grab = inputInfo.pointer->grab;
 
879
 
 
880
    if (syncEvents.playingEvents)
 
881
        return;
 
882
    if (grab)
 
883
    {
 
884
        if (grab->cursor)
 
885
        {
 
886
            ChangeToCursor(grab->cursor);
 
887
            return;
 
888
        }
 
889
        if (IsParent(grab->window, sprite.win))
 
890
            win = sprite.win;
 
891
        else
 
892
            win = grab->window;
 
893
    }
 
894
    else
 
895
        win = sprite.win;
 
896
    for (; win; win = win->parent)
 
897
        if (win->optional && win->optional->cursor != NullCursor)
 
898
        {
 
899
            ChangeToCursor(win->optional->cursor);
 
900
            return;
 
901
        }
 
902
}
 
903
 
 
904
WindowPtr
 
905
GetCurrentRootWindow()
 
906
{
 
907
    return ROOT;
 
908
}
 
909
 
 
910
WindowPtr
 
911
GetSpriteWindow()
 
912
{
 
913
    return sprite.win;
 
914
}
 
915
 
 
916
CursorPtr
 
917
GetSpriteCursor()
 
918
{
 
919
    return sprite.current;
 
920
}
 
921
 
 
922
void
 
923
GetSpritePosition(px, py)
 
924
    int *px, *py;
 
925
{
 
926
    *px = sprite.hotPhys.x;
 
927
    *py = sprite.hotPhys.y;
 
928
}
 
929
 
 
930
#ifdef PANORAMIX
 
931
int
 
932
XineramaGetCursorScreen()
 
933
{
 
934
    if(!noPanoramiXExtension) {
 
935
        return sprite.screen->myNum;
 
936
    } else {
 
937
        return 0;
 
938
    }
 
939
}
 
940
#endif /* PANORAMIX */
 
941
 
 
942
#define TIMESLOP (5 * 60 * 1000) /* 5 minutes */
 
943
 
 
944
static void
 
945
#if NeedFunctionPrototypes
 
946
MonthChangedOrBadTime(register xEvent *xE)
 
947
#else
 
948
MonthChangedOrBadTime(xE)
 
949
    register xEvent *xE;
 
950
#endif
 
951
{
 
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.
 
955
     */
 
956
    if ((currentTime.milliseconds - XE_KBPTR.time) > TIMESLOP)
 
957
        currentTime.months++;
 
958
    else
 
959
        XE_KBPTR.time = currentTime.milliseconds;
 
960
}
 
961
 
 
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; }
 
967
 
 
968
void
 
969
NoticeEventTime(xE)
 
970
    register xEvent *xE;
 
971
{
 
972
    if (!syncEvents.playingEvents)
 
973
        NoticeTime(xE);
 
974
}
 
975
 
 
976
/**************************************************************************
 
977
 *            The following procedures deal with synchronous events       *
 
978
 **************************************************************************/
 
979
 
 
980
void
 
981
EnqueueEvent(xE, device, count)
 
982
    xEvent              *xE;
 
983
    DeviceIntPtr        device;
 
984
    int                 count;
 
985
{
 
986
    register QdEventPtr tail = *syncEvents.pendtail;
 
987
    register QdEventPtr qe;
 
988
    xEvent              *qxE;
 
989
 
 
990
    NoticeTime(xE);
 
991
    if (DeviceEventCallback)
 
992
    {
 
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
 
1001
         *  updated yet.
 
1002
         */
 
1003
        if (xE->u.u.type == MotionNotify)
 
1004
            XE_KBPTR.root =
 
1005
                WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
 
1006
        eventinfo.events = xE;
 
1007
        eventinfo.count = count;
 
1008
        CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
 
1009
    }
 
1010
    if (xE->u.u.type == MotionNotify)
 
1011
    {
 
1012
#ifdef PANORAMIX
 
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;
 
1018
        }
 
1019
#endif
 
1020
        sprite.hotPhys.x = XE_KBPTR.rootX;
 
1021
        sprite.hotPhys.y = XE_KBPTR.rootY;
 
1022
        /* do motion compression */
 
1023
        if (tail &&
 
1024
            (tail->event->u.u.type == MotionNotify) &&
 
1025
            (tail->pScreen == sprite.hotPhys.pScreen))
 
1026
        {
 
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;
 
1031
            return;
 
1032
        }
 
1033
    }
 
1034
    qe = (QdEventPtr)xalloc(sizeof(QdEventRec) + (count * sizeof(xEvent)));
 
1035
    if (!qe)
 
1036
        return;
 
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++)
 
1044
        *qxE = *xE;
 
1045
    if (tail)
 
1046
        syncEvents.pendtail = &tail->next;
 
1047
    *syncEvents.pendtail = qe;
 
1048
}
 
1049
 
 
1050
static void
 
1051
#if NeedFunctionPrototypes
 
1052
PlayReleasedEvents(void)
 
1053
#else
 
1054
PlayReleasedEvents()
 
1055
#endif
 
1056
{
 
1057
    register QdEventPtr *prev, qe;
 
1058
    register DeviceIntPtr dev;
 
1059
 
 
1060
    prev = &syncEvents.pending;
 
1061
    while ( (qe = *prev) )
 
1062
    {
 
1063
        if (!qe->device->sync.frozen)
 
1064
        {
 
1065
            *prev = qe->next;
 
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;
 
1072
#ifdef PANORAMIX
 
1073
           /* Translate back to the sprite screen since processInputProc
 
1074
              will translate from sprite screen to screen 0 upon reentry
 
1075
              to the DIX layer */
 
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;
 
1083
            }
 
1084
#endif
 
1085
            (*qe->device->public.processInputProc)(qe->event, qe->device,
 
1086
                                                   qe->evcount);
 
1087
            xfree(qe);
 
1088
            for (dev = inputInfo.devices; dev && dev->sync.frozen; dev = dev->next)
 
1089
                ;
 
1090
            if (!dev)
 
1091
                break;
 
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;
 
1095
        }
 
1096
        else
 
1097
            prev = &qe->next;
 
1098
    } 
 
1099
}
 
1100
 
 
1101
static void
 
1102
#if NeedFunctionPrototypes
 
1103
FreezeThaw(register DeviceIntPtr dev, Bool frozen)
 
1104
#else
 
1105
FreezeThaw(dev, frozen)
 
1106
    register DeviceIntPtr dev;
 
1107
    Bool frozen;
 
1108
#endif
 
1109
{
 
1110
    dev->sync.frozen = frozen;
 
1111
    if (frozen)
 
1112
        dev->public.processInputProc = dev->public.enqueueInputProc;
 
1113
    else
 
1114
        dev->public.processInputProc = dev->public.realInputProc;
 
1115
}
 
1116
 
 
1117
void
 
1118
ComputeFreezes()
 
1119
{
 
1120
    register DeviceIntPtr replayDev = syncEvents.replayDev;
 
1121
    register int i;
 
1122
    WindowPtr w;
 
1123
    register xEvent *xE;
 
1124
    int count;
 
1125
    GrabPtr grab;
 
1126
    register DeviceIntPtr dev;
 
1127
 
 
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))
 
1131
        return;
 
1132
    syncEvents.playingEvents = TRUE;
 
1133
    if (replayDev)
 
1134
    {
 
1135
        xE = replayDev->sync.event;
 
1136
        count = replayDev->sync.evcount;
 
1137
        syncEvents.replayDev = (DeviceIntPtr)NULL;
 
1138
 
 
1139
        w = XYToWindow( XE_KBPTR.rootX, XE_KBPTR.rootY);
 
1140
        for (i = 0; i < spriteTraceGood; i++)
 
1141
        {
 
1142
            if (syncEvents.replayWin == spriteTrace[i])
 
1143
            {
 
1144
                if (!CheckDeviceGrabs(replayDev, xE, i+1, count)) {
 
1145
                    if (replayDev->focus)
 
1146
                        DeliverFocusedEvent(replayDev, xE, w, count);
 
1147
                    else
 
1148
                        DeliverDeviceEvents(w, xE, NullGrab, NullWindow,
 
1149
                                                replayDev, count);
 
1150
                }
 
1151
                goto playmore;
 
1152
            }
 
1153
        }
 
1154
        /* must not still be in the same stack */
 
1155
        if (replayDev->focus)
 
1156
            DeliverFocusedEvent(replayDev, xE, w, count);
 
1157
        else
 
1158
            DeliverDeviceEvents(w, xE, NullGrab, NullWindow, replayDev, count);
 
1159
    }
 
1160
playmore:
 
1161
    for (dev = inputInfo.devices; dev; dev = dev->next)
 
1162
    {
 
1163
        if (!dev->sync.frozen)
 
1164
        {
 
1165
            PlayReleasedEvents();
 
1166
            break;
 
1167
        }
 
1168
    }
 
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)
 
1172
    {
 
1173
        if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
 
1174
            sprite.hotPhys.x = sprite.hotPhys.y = 0;
 
1175
        ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
 
1176
    }
 
1177
    else
 
1178
        ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
 
1179
                              TRUE, FALSE);
 
1180
    PostNewCursor();
 
1181
}
 
1182
 
 
1183
#ifdef RANDR
 
1184
void
 
1185
ScreenRestructured (ScreenPtr pScreen)
 
1186
{
 
1187
    GrabPtr grab;
 
1188
 
 
1189
    if ((grab = inputInfo.pointer->grab) && grab->confineTo)
 
1190
    {
 
1191
        if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
 
1192
            sprite.hotPhys.x = sprite.hotPhys.y = 0;
 
1193
        ConfineCursorToWindow(grab->confineTo, TRUE, TRUE);
 
1194
    }
 
1195
    else
 
1196
        ConfineCursorToWindow(WindowTable[sprite.hotPhys.pScreen->myNum],
 
1197
                              TRUE, FALSE);
 
1198
}
 
1199
#endif
 
1200
 
 
1201
void
 
1202
CheckGrabForSyncs(thisDev, thisMode, otherMode)
 
1203
    register DeviceIntPtr thisDev;
 
1204
    Bool thisMode, otherMode;
 
1205
{
 
1206
    register GrabPtr grab = thisDev->grab;
 
1207
    register DeviceIntPtr dev;
 
1208
 
 
1209
    if (thisMode == GrabModeSync)
 
1210
        thisDev->sync.state = FROZEN_NO_EVENT;
 
1211
    else
 
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;
 
1218
    }
 
1219
    for (dev = inputInfo.devices; dev; dev = dev->next)
 
1220
    {
 
1221
        if (dev != thisDev)
 
1222
        {
 
1223
            if (otherMode == GrabModeSync)
 
1224
                dev->sync.other = grab;
 
1225
            else
 
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;
 
1231
            }
 
1232
        }
 
1233
    }
 
1234
    ComputeFreezes();
 
1235
}
 
1236
 
 
1237
void
 
1238
ActivatePointerGrab(mouse, grab, time, autoGrab)
 
1239
    register GrabPtr grab;
 
1240
    register DeviceIntPtr mouse;
 
1241
    TimeStamp time;
 
1242
    Bool autoGrab;
 
1243
{
 
1244
    WindowPtr oldWin = (mouse->grab) ? mouse->grab->window
 
1245
                                     : sprite.win;
 
1246
 
 
1247
    if (grab->confineTo)
 
1248
    {
 
1249
        if (grab->confineTo->drawable.pScreen != sprite.hotPhys.pScreen)
 
1250
            sprite.hotPhys.x = sprite.hotPhys.y = 0;
 
1251
        ConfineCursorToWindow(grab->confineTo, FALSE, TRUE);
 
1252
    }
 
1253
    DoEnterLeaveEvents(oldWin, grab->window, NotifyGrab);
 
1254
    mouse->valuator->motionHintWindow = NullWindow;
 
1255
    if (syncEvents.playingEvents)
 
1256
        mouse->grabTime = syncEvents.time;
 
1257
    else
 
1258
        mouse->grabTime = time;
 
1259
    if (grab->cursor)
 
1260
        grab->cursor->refcnt++;
 
1261
    mouse->activeGrab = *grab;
 
1262
    mouse->grab = &mouse->activeGrab;
 
1263
    mouse->fromPassiveGrab = autoGrab;
 
1264
    PostNewCursor();
 
1265
    CheckGrabForSyncs(mouse,(Bool)grab->pointerMode, (Bool)grab->keyboardMode);
 
1266
}
 
1267
 
 
1268
void
 
1269
DeactivatePointerGrab(mouse)
 
1270
    register DeviceIntPtr mouse;
 
1271
{
 
1272
    register GrabPtr grab = mouse->grab;
 
1273
    register DeviceIntPtr dev;
 
1274
 
 
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)
 
1280
    {
 
1281
        if (dev->sync.other == grab)
 
1282
            dev->sync.other = NullGrab;
 
1283
    }
 
1284
    DoEnterLeaveEvents(grab->window, sprite.win, NotifyUngrab);
 
1285
    if (grab->confineTo)
 
1286
        ConfineCursorToWindow(ROOT, FALSE, FALSE);
 
1287
    PostNewCursor();
 
1288
    if (grab->cursor)
 
1289
        FreeCursor(grab->cursor, (Cursor)0);
 
1290
    ComputeFreezes();
 
1291
}
 
1292
 
 
1293
void
 
1294
ActivateKeyboardGrab(keybd, grab, time, passive)
 
1295
    register DeviceIntPtr keybd;
 
1296
    GrabPtr grab;
 
1297
    TimeStamp time;
 
1298
    Bool passive;
 
1299
{
 
1300
    WindowPtr oldWin;
 
1301
 
 
1302
    if (keybd->grab)
 
1303
        oldWin = keybd->grab->window;
 
1304
    else if (keybd->focus)
 
1305
        oldWin = keybd->focus->win;
 
1306
    else
 
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;
 
1315
    else
 
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);
 
1321
}
 
1322
 
 
1323
void
 
1324
DeactivateKeyboardGrab(keybd)
 
1325
    register DeviceIntPtr keybd;
 
1326
{
 
1327
    register GrabPtr grab = keybd->grab;
 
1328
    register DeviceIntPtr dev;
 
1329
    register WindowPtr focusWin = keybd->focus ? keybd->focus->win
 
1330
                                               : sprite.win;
 
1331
 
 
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)
 
1340
    {
 
1341
        if (dev->sync.other == grab)
 
1342
            dev->sync.other = NullGrab;
 
1343
    }
 
1344
    DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
 
1345
    ComputeFreezes();
 
1346
}
 
1347
 
 
1348
void
 
1349
AllowSome(client, time, thisDev, newState)
 
1350
    ClientPtr           client;
 
1351
    TimeStamp           time;
 
1352
    register DeviceIntPtr thisDev;
 
1353
    int                 newState;
 
1354
{
 
1355
    Bool thisGrabbed, otherGrabbed, othersFrozen, thisSynced;
 
1356
    TimeStamp grabTime;
 
1357
    register DeviceIntPtr dev;
 
1358
 
 
1359
    thisGrabbed = thisDev->grab && SameClient(thisDev->grab, client);
 
1360
    thisSynced = FALSE;
 
1361
    otherGrabbed = FALSE;
 
1362
    othersFrozen = TRUE;
 
1363
    grabTime = thisDev->grabTime;
 
1364
    for (dev = inputInfo.devices; dev; dev = dev->next)
 
1365
    {
 
1366
        if (dev == thisDev)
 
1367
            continue;
 
1368
        if (dev->grab && SameClient(dev->grab, client))
 
1369
        {
 
1370
            if (!(thisGrabbed || otherGrabbed) ||
 
1371
                (CompareTimeStamps(dev->grabTime, grabTime) == LATER))
 
1372
                grabTime = dev->grabTime;
 
1373
            otherGrabbed = TRUE;
 
1374
            if (thisDev->sync.other == dev->grab)
 
1375
                thisSynced = TRUE;
 
1376
            if (dev->sync.state < FROZEN)
 
1377
                othersFrozen = FALSE;
 
1378
        }
 
1379
        else if (!dev->sync.other || !SameClient(dev->sync.other, client))
 
1380
            othersFrozen = FALSE;
 
1381
    }
 
1382
    if (!((thisGrabbed && thisDev->sync.state >= FROZEN) || thisSynced))
 
1383
        return;
 
1384
    if ((CompareTimeStamps(time, currentTime) == LATER) ||
 
1385
        (CompareTimeStamps(time, grabTime) == EARLIER))
 
1386
        return;
 
1387
    switch (newState)
 
1388
    {
 
1389
        case THAWED:                   /* Async */
 
1390
            if (thisGrabbed)
 
1391
                thisDev->sync.state = THAWED;
 
1392
            if (thisSynced)
 
1393
                thisDev->sync.other = NullGrab;
 
1394
            ComputeFreezes();
 
1395
            break;
 
1396
        case FREEZE_NEXT_EVENT:         /* Sync */
 
1397
            if (thisGrabbed)
 
1398
            {
 
1399
                thisDev->sync.state = FREEZE_NEXT_EVENT;
 
1400
                if (thisSynced)
 
1401
                    thisDev->sync.other = NullGrab;
 
1402
                ComputeFreezes();
 
1403
            }
 
1404
            break;
 
1405
        case THAWED_BOTH:               /* AsyncBoth */
 
1406
            if (othersFrozen)
 
1407
            {
 
1408
                for (dev = inputInfo.devices; dev; dev = dev->next)
 
1409
                {
 
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;
 
1414
                }
 
1415
                ComputeFreezes();
 
1416
            }
 
1417
            break;
 
1418
        case FREEZE_BOTH_NEXT_EVENT:    /* SyncBoth */
 
1419
            if (othersFrozen)
 
1420
            {
 
1421
                for (dev = inputInfo.devices; dev; dev = dev->next)
 
1422
                {
 
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;
 
1427
                }
 
1428
                ComputeFreezes();
 
1429
            }
 
1430
            break;
 
1431
        case NOT_GRABBED:               /* Replay */
 
1432
            if (thisGrabbed && thisDev->sync.state == FROZEN_WITH_EVENT)
 
1433
            {
 
1434
                if (thisSynced)
 
1435
                    thisDev->sync.other = NullGrab;
 
1436
                syncEvents.replayDev = thisDev;
 
1437
                syncEvents.replayWin = thisDev->grab->window;
 
1438
                (*thisDev->DeactivateGrab)(thisDev);
 
1439
                syncEvents.replayDev = (DeviceIntPtr)NULL;
 
1440
            }
 
1441
            break;
 
1442
        case THAW_OTHERS:               /* AsyncOthers */
 
1443
            if (othersFrozen)
 
1444
            {
 
1445
                for (dev = inputInfo.devices; dev; dev = dev->next)
 
1446
                {
 
1447
                    if (dev == thisDev)
 
1448
                        continue;
 
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;
 
1453
                }
 
1454
                ComputeFreezes();
 
1455
            }
 
1456
            break;
 
1457
    }
 
1458
}
 
1459
 
 
1460
int
 
1461
ProcAllowEvents(client)
 
1462
    register ClientPtr client;
 
1463
{
 
1464
    TimeStamp           time;
 
1465
    DeviceIntPtr        mouse = inputInfo.pointer;
 
1466
    DeviceIntPtr        keybd = inputInfo.keyboard;
 
1467
    REQUEST(xAllowEventsReq);
 
1468
 
 
1469
    REQUEST_SIZE_MATCH(xAllowEventsReq);
 
1470
    time = ClientTimeToServerTime(stuff->time);
 
1471
    switch (stuff->mode)
 
1472
    {
 
1473
        case ReplayPointer:
 
1474
            AllowSome(client, time, mouse, NOT_GRABBED);
 
1475
            break;
 
1476
        case SyncPointer: 
 
1477
            AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
 
1478
            break;
 
1479
        case AsyncPointer: 
 
1480
            AllowSome(client, time, mouse, THAWED);
 
1481
            break;
 
1482
        case ReplayKeyboard: 
 
1483
            AllowSome(client, time, keybd, NOT_GRABBED);
 
1484
            break;
 
1485
        case SyncKeyboard: 
 
1486
            AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
 
1487
            break;
 
1488
        case AsyncKeyboard: 
 
1489
            AllowSome(client, time, keybd, THAWED);
 
1490
            break;
 
1491
        case SyncBoth:
 
1492
            AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
 
1493
            break;
 
1494
        case AsyncBoth:
 
1495
            AllowSome(client, time, keybd, THAWED_BOTH);
 
1496
            break;
 
1497
        default: 
 
1498
            client->errorValue = stuff->mode;
 
1499
            return BadValue;
 
1500
    }
 
1501
    return Success;
 
1502
}
 
1503
 
 
1504
void
 
1505
ReleaseActiveGrabs(client)
 
1506
    ClientPtr client;
 
1507
{
 
1508
    register DeviceIntPtr dev;
 
1509
    Bool    done;
 
1510
 
 
1511
    /* XXX CloseDownClient should remove passive grabs before
 
1512
     * releasing active grabs.
 
1513
     */
 
1514
    do {
 
1515
        done = TRUE;
 
1516
        for (dev = inputInfo.devices; dev; dev = dev->next)
 
1517
        {
 
1518
            if (dev->grab && SameClient(dev->grab, client))
 
1519
            {
 
1520
                (*dev->DeactivateGrab)(dev);
 
1521
                done = FALSE;
 
1522
            }
 
1523
        }
 
1524
    } while (!done);
 
1525
}
 
1526
 
 
1527
/**************************************************************************
 
1528
 *            The following procedures deal with delivering events        *
 
1529
 **************************************************************************/
 
1530
 
 
1531
int
 
1532
TryClientEvents (client, pEvents, count, mask, filter, grab)
 
1533
    ClientPtr client;
 
1534
    GrabPtr grab;
 
1535
    xEvent *pEvents;
 
1536
    int count;
 
1537
    Mask mask, filter;
 
1538
{
 
1539
    int i;
 
1540
    int type;
 
1541
 
 
1542
#ifdef DEBUG
 
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);
 
1546
#endif
 
1547
    if ((client) && (client != serverClient) && (!client->clientGone) &&
 
1548
        ((filter == CantBeFiltered) || (mask & filter)))
 
1549
    {
 
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)
 
1554
        {
 
1555
            if (mask & PointerMotionHintMask)
 
1556
            {
 
1557
                if (WID(inputInfo.pointer->valuator->motionHintWindow) ==
 
1558
                    pEvents->u.keyButtonPointer.event)
 
1559
                {
 
1560
#ifdef DEBUG
 
1561
                    if (debug_events) ErrorF("\n");
 
1562
            fprintf(stderr,"motionHintWindow == keyButtonPointer.event\n");
 
1563
#endif
 
1564
                    return 1; /* don't send, but pretend we did */
 
1565
                }
 
1566
                pEvents->u.u.detail = NotifyHint;
 
1567
            }
 
1568
            else
 
1569
            {
 
1570
                pEvents->u.u.detail = NotifyNormal;
 
1571
            }
 
1572
        }
 
1573
#ifdef XINPUT
 
1574
        else
 
1575
        {
 
1576
            if ((type == DeviceMotionNotify) &&
 
1577
                MaybeSendDeviceMotionNotifyHint
 
1578
                        ((deviceKeyButtonPointer*)pEvents, mask) != 0)
 
1579
                return 1;
 
1580
        }
 
1581
#endif
 
1582
        type &= 0177;
 
1583
        if (type != KeymapNotify)
 
1584
        {
 
1585
            /* all extension events must have a sequence number */
 
1586
            for (i = 0; i < count; i++)
 
1587
                pEvents[i].u.u.sequenceNumber = client->sequence;
 
1588
        }
 
1589
 
 
1590
        if (BitIsOn(criticalEvents, type))
 
1591
        {
 
1592
#ifdef SMART_SCHEDULE
 
1593
            if (client->smart_priority < SMART_MAX_PRIORITY)
 
1594
                client->smart_priority++;
 
1595
#endif
 
1596
            SetCriticalOutputPending();
 
1597
        }
 
1598
 
 
1599
        WriteEventsToClient(client, count, pEvents);
 
1600
#ifdef DEBUG
 
1601
        if (debug_events) ErrorF(  " delivered\n");
 
1602
#endif
 
1603
        return 1;
 
1604
    }
 
1605
    else
 
1606
    {
 
1607
#ifdef DEBUG
 
1608
        if (debug_events) ErrorF("\n");
 
1609
#endif
 
1610
        return 0;
 
1611
    }
 
1612
}
 
1613
 
 
1614
int
 
1615
DeliverEventsToWindow(pWin, pEvents, count, filter, grab, mskidx)
 
1616
    register WindowPtr pWin;
 
1617
    GrabPtr grab;
 
1618
    xEvent *pEvents;
 
1619
    int count;
 
1620
    Mask filter;
 
1621
    int mskidx;
 
1622
{
 
1623
    int deliveries = 0, nondeliveries = 0;
 
1624
    int attempt;
 
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;
 
1630
 
 
1631
    /* CantBeFiltered means only window owner gets the event */
 
1632
    if ((filter == CantBeFiltered) || !(type & EXTENSION_EVENT_BASE))
 
1633
    {
 
1634
        /* if nobody ever wants to see this event, skip some work */
 
1635
        if (filter != CantBeFiltered &&
 
1636
            !((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
 
1637
            return 0;
 
1638
        if ( (attempt = TryClientEvents(wClient(pWin), pEvents, count,
 
1639
                                      pWin->eventMask, filter, grab)) )
 
1640
        {
 
1641
            if (attempt > 0)
 
1642
            {
 
1643
                deliveries++;
 
1644
                client = wClient(pWin);
 
1645
                deliveryMask = pWin->eventMask;
 
1646
            } else
 
1647
                nondeliveries--;
 
1648
        }
 
1649
    }
 
1650
    if (filter != CantBeFiltered)
 
1651
    {
 
1652
        if (type & EXTENSION_EVENT_BASE)
 
1653
        {
 
1654
            OtherInputMasks *inputMasks;
 
1655
 
 
1656
            inputMasks = wOtherInputMasks(pWin);
 
1657
            if (!inputMasks ||
 
1658
                !(inputMasks->inputEvents[mskidx] & filter))
 
1659
                return 0;
 
1660
            other = inputMasks->inputClients;
 
1661
        }
 
1662
        else
 
1663
            other = (InputClients *)wOtherClients(pWin);
 
1664
        for (; other; other = other->next)
 
1665
        {
 
1666
            if ( (attempt = TryClientEvents(rClient(other), pEvents, count,
 
1667
                                          other->mask[mskidx], filter, grab)) )
 
1668
            {
 
1669
                if (attempt > 0)
 
1670
                {
 
1671
                    deliveries++;
 
1672
                    client = rClient(other);
 
1673
                    deliveryMask = other->mask[mskidx];
 
1674
                } else
 
1675
                    nondeliveries--;
 
1676
            }
 
1677
        }
 
1678
    }
 
1679
    if ((type == ButtonPress) && deliveries && (!grab))
 
1680
    {
 
1681
        GrabRec tempGrab;
 
1682
 
 
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,
 
1693
                                           currentTime, TRUE);
 
1694
    }
 
1695
    else if ((type == MotionNotify) && deliveries)
 
1696
        inputInfo.pointer->valuator->motionHintWindow = pWin;
 
1697
#ifdef XINPUT
 
1698
    else
 
1699
    {
 
1700
        if (((type == DeviceMotionNotify) || (type == DeviceButtonPress)) &&
 
1701
            deliveries)
 
1702
            CheckDeviceGrabAndHintWindow (pWin, type,
 
1703
                                          (deviceKeyButtonPointer*) pEvents,
 
1704
                                          grab, client, deliveryMask);
 
1705
    }
 
1706
#endif
 
1707
    if (deliveries)
 
1708
        return deliveries;
 
1709
    return nondeliveries;
 
1710
}
 
1711
 
 
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.
 
1715
*/
 
1716
 
 
1717
#ifdef PANORAMIX
 
1718
static int 
 
1719
XineramaTryClientEventsResult(
 
1720
    ClientPtr client,
 
1721
    GrabPtr grab,
 
1722
    Mask mask, 
 
1723
    Mask filter
 
1724
){
 
1725
    if ((client) && (client != serverClient) && (!client->clientGone) &&
 
1726
        ((filter == CantBeFiltered) || (mask & filter)))
 
1727
    {
 
1728
        if (grab && !SameClient(grab, client)) return -1;
 
1729
        else return 1;
 
1730
    }
 
1731
    return 0;
 
1732
}
 
1733
#endif
 
1734
 
 
1735
int
 
1736
MaybeDeliverEventsToClient(pWin, pEvents, count, filter, dontClient)
 
1737
    register WindowPtr pWin;
 
1738
    xEvent *pEvents;
 
1739
    int count;
 
1740
    Mask filter;
 
1741
    ClientPtr dontClient;
 
1742
{
 
1743
    register OtherClients *other;
 
1744
 
 
1745
 
 
1746
    if (pWin->eventMask & filter)
 
1747
    {
 
1748
        if (wClient(pWin) == dontClient)
 
1749
            return 0;
 
1750
#ifdef PANORAMIX
 
1751
        if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) 
 
1752
            return XineramaTryClientEventsResult(
 
1753
                        wClient(pWin), NullGrab, pWin->eventMask, filter);
 
1754
#endif
 
1755
        return TryClientEvents(wClient(pWin), pEvents, count,
 
1756
                               pWin->eventMask, filter, NullGrab);
 
1757
    }
 
1758
    for (other = wOtherClients(pWin); other; other = other->next)
 
1759
    {
 
1760
        if (other->mask & filter)
 
1761
        {
 
1762
            if (SameClient(other, dontClient))
 
1763
                return 0;
 
1764
#ifdef PANORAMIX
 
1765
            if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) 
 
1766
              return XineramaTryClientEventsResult(
 
1767
                        rClient(other), NullGrab, other->mask, filter);
 
1768
#endif
 
1769
            return TryClientEvents(rClient(other), pEvents, count,
 
1770
                                   other->mask, filter, NullGrab);
 
1771
        }
 
1772
    }
 
1773
    return 2;
 
1774
}
 
1775
 
 
1776
static void
 
1777
#if NeedFunctionPrototypes
 
1778
FixUpEventFromWindow(
 
1779
    xEvent *xE,
 
1780
    WindowPtr pWin,
 
1781
    Window child,
 
1782
    Bool calcChild)
 
1783
#else
 
1784
FixUpEventFromWindow(xE, pWin, child, calcChild)
 
1785
    xEvent *xE;
 
1786
    WindowPtr pWin;
 
1787
    Window child;
 
1788
    Bool calcChild;
 
1789
#endif
 
1790
{
 
1791
    if (calcChild)
 
1792
    {
 
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. */
 
1798
 
 
1799
        while (w) 
 
1800
        {
 
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. */
 
1803
 
 
1804
            if (w == pWin)
 
1805
            { 
 
1806
                child = None;
 
1807
                break;
 
1808
            }
 
1809
            
 
1810
            if (w->parent == pWin)
 
1811
            {
 
1812
                child = w->drawable.id;
 
1813
                break;
 
1814
            }
 
1815
            w = w->parent;
 
1816
        }           
 
1817
    }
 
1818
    XE_KBPTR.root = ROOT->drawable.id;
 
1819
    XE_KBPTR.event = pWin->drawable.id;
 
1820
    if (sprite.hot.pScreen == pWin->drawable.pScreen)
 
1821
    {
 
1822
        XE_KBPTR.sameScreen = xTrue;
 
1823
        XE_KBPTR.child = child;
 
1824
        XE_KBPTR.eventX =
 
1825
        XE_KBPTR.rootX - pWin->drawable.x;
 
1826
        XE_KBPTR.eventY =
 
1827
        XE_KBPTR.rootY - pWin->drawable.y;
 
1828
    }
 
1829
    else
 
1830
    {
 
1831
        XE_KBPTR.sameScreen = xFalse;
 
1832
        XE_KBPTR.child = None;
 
1833
        XE_KBPTR.eventX = 0;
 
1834
        XE_KBPTR.eventY = 0;
 
1835
    }
 
1836
}
 
1837
 
 
1838
int
 
1839
DeliverDeviceEvents(pWin, xE, grab, stopAt, dev, count)
 
1840
    register WindowPtr pWin, stopAt;
 
1841
    register xEvent *xE;
 
1842
    GrabPtr grab;
 
1843
    DeviceIntPtr dev;
 
1844
    int count;
 
1845
{
 
1846
    Window child = None;
 
1847
    int type = xE->u.u.type;
 
1848
    Mask filter = filters[type];
 
1849
    int deliveries = 0;
 
1850
 
 
1851
    if (type & EXTENSION_EVENT_BASE)
 
1852
    {
 
1853
        register OtherInputMasks *inputMasks;
 
1854
        int mskidx = dev->id;
 
1855
 
 
1856
        inputMasks = wOtherInputMasks(pWin);
 
1857
        if (inputMasks && !(filter & inputMasks->deliverableEvents[mskidx]))
 
1858
            return 0;
 
1859
        while (pWin)
 
1860
        {
 
1861
            if (inputMasks && (inputMasks->inputEvents[mskidx] & filter))
 
1862
            {
 
1863
                FixUpEventFromWindow(xE, pWin, child, FALSE);
 
1864
                deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
 
1865
                                                   grab, mskidx);
 
1866
                if (deliveries > 0)
 
1867
                    return deliveries;
 
1868
            }
 
1869
            if ((deliveries < 0) ||
 
1870
                (pWin == stopAt) ||
 
1871
                (inputMasks &&
 
1872
                 (filter & inputMasks->dontPropagateMask[mskidx])))
 
1873
                return 0;
 
1874
            child = pWin->drawable.id;
 
1875
            pWin = pWin->parent;
 
1876
            if (pWin)
 
1877
                inputMasks = wOtherInputMasks(pWin);
 
1878
        }
 
1879
    }
 
1880
    else
 
1881
    {
 
1882
        if (!(filter & pWin->deliverableEvents))
 
1883
            return 0;
 
1884
        while (pWin)
 
1885
        {
 
1886
            if ((wOtherEventMasks(pWin)|pWin->eventMask) & filter)
 
1887
            {
 
1888
                FixUpEventFromWindow(xE, pWin, child, FALSE);
 
1889
                deliveries = DeliverEventsToWindow(pWin, xE, count, filter,
 
1890
                                                   grab, 0);
 
1891
                if (deliveries > 0)
 
1892
                    return deliveries;
 
1893
            }
 
1894
            if ((deliveries < 0) ||
 
1895
                (pWin == stopAt) ||
 
1896
                (filter & wDontPropagateMask(pWin)))
 
1897
                return 0;
 
1898
            child = pWin->drawable.id;
 
1899
            pWin = pWin->parent;
 
1900
        }
 
1901
    }
 
1902
    return 0;
 
1903
}
 
1904
 
 
1905
/* not useful for events that propagate up the tree or extension events */
 
1906
int
 
1907
DeliverEvents(pWin, xE, count, otherParent)
 
1908
    register WindowPtr pWin, otherParent;
 
1909
    register xEvent *xE;
 
1910
    int count;
 
1911
{
 
1912
    Mask filter;
 
1913
    int     deliveries;
 
1914
 
 
1915
#ifdef PANORAMIX
 
1916
    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
 
1917
        return count;
 
1918
#endif
 
1919
 
 
1920
    if (!count)
 
1921
        return 0;
 
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,
 
1928
                                       NullGrab, 0);
 
1929
    if (pWin->parent)
 
1930
    {
 
1931
        xE->u.destroyNotify.event = pWin->parent->drawable.id;
 
1932
        deliveries += DeliverEventsToWindow(pWin->parent, xE, count,
 
1933
                                            SubstructureNotifyMask, NullGrab,
 
1934
                                            0);
 
1935
        if (xE->u.u.type == ReparentNotify)
 
1936
        {
 
1937
            xE->u.destroyNotify.event = otherParent->drawable.id;
 
1938
            deliveries += DeliverEventsToWindow(otherParent, xE, count,
 
1939
                                                SubstructureNotifyMask,
 
1940
                                                NullGrab, 0);
 
1941
        }
 
1942
    }
 
1943
    return deliveries;
 
1944
}
 
1945
 
 
1946
 
 
1947
static Bool 
 
1948
PointInBorderSize(WindowPtr pWin, int x, int y)
 
1949
{
 
1950
    BoxRec box;
 
1951
 
 
1952
    if(POINT_IN_REGION(pWin->drawable.pScreen, &pWin->borderSize, x, y, &box))
 
1953
        return TRUE;
 
1954
 
 
1955
#ifdef PANORAMIX
 
1956
    if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
 
1957
        int i;
 
1958
 
 
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, 
 
1964
                        &box))
 
1965
                return TRUE;
 
1966
        }
 
1967
    }
 
1968
#endif
 
1969
    return FALSE;
 
1970
}
 
1971
 
 
1972
static WindowPtr 
 
1973
#if NeedFunctionPrototypes
 
1974
XYToWindow(int x, int y)
 
1975
#else
 
1976
XYToWindow(x, y)
 
1977
        int x, y;
 
1978
#endif
 
1979
{
 
1980
    register WindowPtr  pWin;
 
1981
 
 
1982
    spriteTraceGood = 1;        /* root window still there */
 
1983
    pWin = ROOT->firstChild;
 
1984
    while (pWin)
 
1985
    {
 
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))
 
1993
#ifdef SHAPE
 
1994
                /* When a window is shaped, a further check
 
1995
                 * is made to see if the point is inside
 
1996
                 * borderSize
 
1997
                 */
 
1998
                && (!wBoundingShape(pWin) || PointInBorderSize(pWin, x, y))
 
1999
#endif
 
2000
                )
 
2001
        {
 
2002
            if (spriteTraceGood >= spriteTraceSize)
 
2003
            {
 
2004
                spriteTraceSize += 10;
 
2005
                Must_have_memory = TRUE; /* XXX */
 
2006
                spriteTrace = (WindowPtr *)xrealloc(
 
2007
                    spriteTrace, spriteTraceSize*sizeof(WindowPtr));
 
2008
                Must_have_memory = FALSE; /* XXX */
 
2009
            }
 
2010
            spriteTrace[spriteTraceGood++] = pWin;
 
2011
            pWin = pWin->firstChild;
 
2012
        }
 
2013
        else
 
2014
            pWin = pWin->nextSib;
 
2015
    }
 
2016
    return spriteTrace[spriteTraceGood-1];
 
2017
}
 
2018
 
 
2019
static Bool
 
2020
#if NeedFunctionPrototypes
 
2021
CheckMotion(xEvent *xE)
 
2022
#else
 
2023
CheckMotion(xE)
 
2024
    xEvent *xE;
 
2025
#endif
 
2026
{
 
2027
    WindowPtr prevSpriteWin = sprite.win;
 
2028
 
 
2029
#ifdef PANORAMIX
 
2030
    if(!noPanoramiXExtension)
 
2031
        return XineramaCheckMotion(xE);
 
2032
#endif
 
2033
 
 
2034
    if (xE && !syncEvents.playingEvents)
 
2035
    {
 
2036
        if (sprite.hot.pScreen != sprite.hotPhys.pScreen)
 
2037
        {
 
2038
            sprite.hot.pScreen = sprite.hotPhys.pScreen;
 
2039
            ROOT = WindowTable[sprite.hot.pScreen->myNum];
 
2040
        }
 
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;
 
2051
#ifdef SHAPE
 
2052
        if (sprite.hotShape)
 
2053
            ConfineToShape(sprite.hotShape, &sprite.hot.x, &sprite.hot.y);
 
2054
#endif
 
2055
        sprite.hotPhys = sprite.hot;
 
2056
        if ((sprite.hotPhys.x != XE_KBPTR.rootX) ||
 
2057
            (sprite.hotPhys.y != XE_KBPTR.rootY))
 
2058
        {
 
2059
            (*sprite.hotPhys.pScreen->SetCursorPosition)(
 
2060
                sprite.hotPhys.pScreen,
 
2061
                sprite.hotPhys.x, sprite.hotPhys.y, FALSE);
 
2062
        }
 
2063
        XE_KBPTR.rootX = sprite.hot.x;
 
2064
        XE_KBPTR.rootY = sprite.hot.y;
 
2065
    }
 
2066
 
 
2067
    sprite.win = XYToWindow(sprite.hot.x, sprite.hot.y);
 
2068
#ifdef notyet
 
2069
    if (!(sprite.win->deliverableEvents &
 
2070
          Motion_Filter(inputInfo.pointer->button))
 
2071
        !syncEvents.playingEvents)
 
2072
    {
 
2073
        /* XXX Do PointerNonInterestBox here */
 
2074
    }
 
2075
#endif
 
2076
    if (sprite.win != prevSpriteWin)
 
2077
    {
 
2078
        if (prevSpriteWin != NullWindow) {
 
2079
            if (!xE)
 
2080
                UpdateCurrentTimeIf();
 
2081
            DoEnterLeaveEvents(prevSpriteWin, sprite.win, NotifyNormal);
 
2082
        }
 
2083
        PostNewCursor();
 
2084
        return FALSE;
 
2085
    }
 
2086
    return TRUE;
 
2087
}
 
2088
 
 
2089
void
 
2090
WindowsRestructured()
 
2091
{
 
2092
    (void) CheckMotion((xEvent *)NULL);
 
2093
}
 
2094
 
 
2095
void
 
2096
DefineInitialRootWindow(win)
 
2097
    register WindowPtr win;
 
2098
{
 
2099
    register ScreenPtr pScreen = win->drawable.pScreen;
 
2100
 
 
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;
 
2107
    sprite.win = win;
 
2108
    sprite.current = wCursor (win);
 
2109
    spriteTraceGood = 1;
 
2110
    ROOT = win;
 
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);
 
2117
 
 
2118
#ifdef PANORAMIX
 
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);
 
2130
    }
 
2131
#endif
 
2132
}
 
2133
 
 
2134
/*
 
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.
 
2140
 */
 
2141
/*ARGSUSED*/
 
2142
void
 
2143
WindowHasNewCursor(pWin)
 
2144
    WindowPtr pWin;
 
2145
{
 
2146
    PostNewCursor();
 
2147
}
 
2148
 
 
2149
void
 
2150
NewCurrentScreen(newScreen, x, y)
 
2151
    ScreenPtr newScreen;
 
2152
    int x,y;
 
2153
{
 
2154
    sprite.hotPhys.x = x;
 
2155
    sprite.hotPhys.y = y;
 
2156
#ifdef PANORAMIX
 
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);
 
2167
            else
 
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);
 
2177
        }
 
2178
    } else 
 
2179
#endif
 
2180
    if (newScreen != sprite.hotPhys.pScreen)
 
2181
        ConfineCursorToWindow(WindowTable[newScreen->myNum], TRUE, FALSE);
 
2182
}
 
2183
 
 
2184
#ifdef PANORAMIX
 
2185
 
 
2186
static Bool
 
2187
XineramaPointInWindowIsVisible(
 
2188
    WindowPtr pWin,
 
2189
    int x,
 
2190
    int y
 
2191
)
 
2192
{
 
2193
    ScreenPtr pScreen = pWin->drawable.pScreen;
 
2194
    BoxRec box;
 
2195
    int i, xoff, yoff;
 
2196
 
 
2197
    if (!pWin->realized) return FALSE;
 
2198
 
 
2199
    if (POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
 
2200
        return TRUE;
 
2201
    
 
2202
    if(!XineramaSetWindowPntrs(pWin)) return FALSE;
 
2203
 
 
2204
    xoff = x + panoramiXdataPtr[0].x;  
 
2205
    yoff = y + panoramiXdataPtr[0].y;  
 
2206
 
 
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;
 
2212
 
 
2213
        if(POINT_IN_REGION(pScreen, &pWin->borderClip, x, y, &box))
 
2214
            return TRUE;
 
2215
 
 
2216
    }
 
2217
 
 
2218
    return FALSE;
 
2219
}
 
2220
 
 
2221
static int
 
2222
XineramaWarpPointer(ClientPtr client)
 
2223
{
 
2224
    WindowPtr   dest = NULL;
 
2225
    int         x, y;
 
2226
 
 
2227
    REQUEST(xWarpPointerReq);
 
2228
 
 
2229
 
 
2230
    if (stuff->dstWid != None)
 
2231
    {
 
2232
        dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
 
2233
        if (!dest)
 
2234
            return BadWindow;
 
2235
    }
 
2236
    x = sprite.hotPhys.x;
 
2237
    y = sprite.hotPhys.y;
 
2238
 
 
2239
    if (stuff->srcWid != None)
 
2240
    {
 
2241
        int     winX, winY;
 
2242
        XID     winID = stuff->srcWid;
 
2243
        WindowPtr source;
 
2244
        
 
2245
        source = SecurityLookupWindow(winID, client, SecurityReadAccess);
 
2246
        if (!source) return BadWindow;
 
2247
 
 
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;
 
2253
        }
 
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))
 
2261
            return Success;
 
2262
    }
 
2263
    if (dest) {
 
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;
 
2269
        }
 
2270
    } 
 
2271
 
 
2272
    x += stuff->dstX;
 
2273
    y += stuff->dstY;
 
2274
 
 
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);
 
2285
 
 
2286
    XineramaSetCursorPosition(x, y, TRUE);
 
2287
 
 
2288
    return Success;
 
2289
}
 
2290
 
 
2291
#endif
 
2292
 
 
2293
 
 
2294
int
 
2295
ProcWarpPointer(client)
 
2296
    ClientPtr client;
 
2297
{
 
2298
    WindowPtr   dest = NULL;
 
2299
    int         x, y;
 
2300
    ScreenPtr   newScreen;
 
2301
 
 
2302
    REQUEST(xWarpPointerReq);
 
2303
 
 
2304
    REQUEST_SIZE_MATCH(xWarpPointerReq);
 
2305
 
 
2306
#ifdef PANORAMIX
 
2307
    if(!noPanoramiXExtension)
 
2308
        return XineramaWarpPointer(client);
 
2309
#endif
 
2310
 
 
2311
    if (stuff->dstWid != None)
 
2312
    {
 
2313
        dest = SecurityLookupWindow(stuff->dstWid, client, SecurityReadAccess);
 
2314
        if (!dest)
 
2315
            return BadWindow;
 
2316
    }
 
2317
    x = sprite.hotPhys.x;
 
2318
    y = sprite.hotPhys.y;
 
2319
 
 
2320
    if (stuff->srcWid != None)
 
2321
    {
 
2322
        int     winX, winY;
 
2323
        XID     winID = stuff->srcWid;
 
2324
        WindowPtr source;
 
2325
        
 
2326
        source = SecurityLookupWindow(winID, client, SecurityReadAccess);
 
2327
        if (!source) return BadWindow;
 
2328
 
 
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))
 
2339
            return Success;
 
2340
    }
 
2341
    if (dest) 
 
2342
    {
 
2343
        x = dest->drawable.x;
 
2344
        y = dest->drawable.y;
 
2345
        newScreen = dest->drawable.pScreen;
 
2346
    } else 
 
2347
        newScreen = sprite.hotPhys.pScreen;
 
2348
 
 
2349
    x += stuff->dstX;
 
2350
    y += stuff->dstY;
 
2351
 
 
2352
    if (x < 0)
 
2353
        x = 0;
 
2354
    else if (x >= newScreen->width)
 
2355
        x = newScreen->width - 1;
 
2356
    if (y < 0)
 
2357
        y = 0;
 
2358
    else if (y >= newScreen->height)
 
2359
        y = newScreen->height - 1;
 
2360
 
 
2361
    if (newScreen == sprite.hotPhys.pScreen)
 
2362
    {
 
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;
 
2371
#if defined(SHAPE)
 
2372
        if (sprite.hotShape)
 
2373
            ConfineToShape(sprite.hotShape, &x, &y);
 
2374
#endif
 
2375
        (*newScreen->SetCursorPosition)(newScreen, x, y, TRUE);
 
2376
    }
 
2377
    else if (!PointerConfinedToScreen())
 
2378
    {
 
2379
        NewCurrentScreen(newScreen, x, y);
 
2380
    }
 
2381
    return Success;
 
2382
}
 
2383
 
 
2384
static Bool 
 
2385
BorderSizeNotEmpty(WindowPtr pWin)
 
2386
{
 
2387
     if(REGION_NOTEMPTY(sprite.hotPhys.pScreen, &pWin->borderSize))
 
2388
        return TRUE;
 
2389
 
 
2390
#ifdef PANORAMIX
 
2391
     if(!noPanoramiXExtension && XineramaSetWindowPntrs(pWin)) {
 
2392
        int i;
 
2393
 
 
2394
        for(i = 1; i < PanoramiXNumScreens; i++) {
 
2395
            if(REGION_NOTEMPTY(sprite.screen, &sprite.windows[i]->borderSize))
 
2396
                return TRUE;
 
2397
        }
 
2398
     }
 
2399
#endif
 
2400
     return FALSE;
 
2401
}
 
2402
 
 
2403
/* "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
 
2404
        passive grab set on the window to be activated. */
 
2405
 
 
2406
static Bool
 
2407
#if NeedFunctionPrototypes
 
2408
CheckPassiveGrabsOnWindow(
 
2409
    WindowPtr pWin,
 
2410
    register DeviceIntPtr device,
 
2411
    register xEvent *xE,
 
2412
    int count)
 
2413
#else
 
2414
CheckPassiveGrabsOnWindow(pWin, device, xE, count)
 
2415
    WindowPtr pWin;
 
2416
    register DeviceIntPtr device;
 
2417
    register xEvent *xE;
 
2418
    int count;
 
2419
#endif
 
2420
{
 
2421
    register GrabPtr grab = wPassiveGrabs(pWin);
 
2422
    GrabRec tempGrab;
 
2423
    register xEvent *dxE;
 
2424
 
 
2425
    if (!grab)
 
2426
        return FALSE;
 
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)
 
2434
    {
 
2435
#ifdef XKB
 
2436
        DeviceIntPtr    gdev;
 
2437
        XkbSrvInfoPtr   xkbi;
 
2438
 
 
2439
        gdev= grab->modifierDevice;
 
2440
        xkbi= gdev->key->xkbInfo;
 
2441
#endif
 
2442
        tempGrab.modifierDevice = grab->modifierDevice;
 
2443
        if (device == grab->modifierDevice &&
 
2444
            (xE->u.u.type == KeyPress
 
2445
#ifdef XINPUT
 
2446
             || xE->u.u.type == DeviceKeyPress
 
2447
#endif
 
2448
             ))
 
2449
            tempGrab.modifiersDetail.exact =
 
2450
#ifdef XKB
 
2451
                (noXkbExtension?gdev->key->prev_state:xkbi->state.grab_mods);
 
2452
#else
 
2453
                grab->modifierDevice->key->prev_state;
 
2454
#endif
 
2455
        else
 
2456
            tempGrab.modifiersDetail.exact =
 
2457
#ifdef XKB
 
2458
                (noXkbExtension ? gdev->key->state : xkbi->state.grab_mods);
 
2459
#else
 
2460
                grab->modifierDevice->key->state;
 
2461
#endif
 
2462
        if (GrabMatchesSecond(&tempGrab, grab) &&
 
2463
            (!grab->confineTo ||
 
2464
             (grab->confineTo->realized && 
 
2465
                                BorderSizeNotEmpty(grab->confineTo))))
 
2466
        {
 
2467
#ifdef XCSECURITY
 
2468
            if (!SecurityCheckDeviceAccess(wClient(pWin), device, FALSE))
 
2469
                return FALSE;
 
2470
#endif
 
2471
#ifdef XKB
 
2472
            if (!noXkbExtension) {
 
2473
                XE_KBPTR.state &= 0x1f00;
 
2474
                XE_KBPTR.state |=
 
2475
                                tempGrab.modifiersDetail.exact&(~0x1f00);
 
2476
            }
 
2477
#endif
 
2478
            (*device->ActivateGrab)(device, grab, currentTime, TRUE);
 
2479
 
 
2480
            FixUpEventFromWindow(xE, grab->window, None, TRUE);
 
2481
 
 
2482
            (void) TryClientEvents(rClient(grab), xE, count,
 
2483
                                   filters[xE->u.u.type],
 
2484
                                   filters[xE->u.u.type],  grab);
 
2485
 
 
2486
            if (device->sync.state == FROZEN_NO_EVENT)
 
2487
            {
 
2488
                if (device->sync.evcount < count)
 
2489
                {
 
2490
                    Must_have_memory = TRUE; /* XXX */
 
2491
                    device->sync.event = (xEvent *)xrealloc(device->sync.event,
 
2492
                                                            count*
 
2493
                                                            sizeof(xEvent));
 
2494
                    Must_have_memory = FALSE; /* XXX */
 
2495
                }
 
2496
                device->sync.evcount = count;
 
2497
                for (dxE = device->sync.event; --count >= 0; dxE++, xE++)
 
2498
                    *dxE = *xE;
 
2499
                device->sync.state = FROZEN_WITH_EVENT;
 
2500
            }   
 
2501
            return TRUE;
 
2502
        }
 
2503
    }
 
2504
    return FALSE;
 
2505
}
 
2506
 
 
2507
/*
 
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
 
2517
tried. PRH
 
2518
*/
 
2519
 
 
2520
Bool
 
2521
CheckDeviceGrabs(device, xE, checkFirst, count)
 
2522
    register DeviceIntPtr device;
 
2523
    register xEvent *xE;
 
2524
    int checkFirst;
 
2525
    int count;
 
2526
{
 
2527
    register int i;
 
2528
    register WindowPtr pWin = NULL;
 
2529
    register FocusClassPtr focus = device->focus;
 
2530
 
 
2531
    if ((xE->u.u.type == ButtonPress
 
2532
#ifdef XINPUT
 
2533
         || xE->u.u.type == DeviceButtonPress
 
2534
#endif
 
2535
         ) && device->button->buttonsDown != 1)
 
2536
        return FALSE;
 
2537
 
 
2538
    i = checkFirst;
 
2539
 
 
2540
    if (focus)
 
2541
    {
 
2542
        for (; i < focus->traceGood; i++)
 
2543
        {
 
2544
            pWin = focus->trace[i];
 
2545
            if (pWin->optional &&
 
2546
                CheckPassiveGrabsOnWindow(pWin, device, xE, count))
 
2547
                return TRUE;
 
2548
        }
 
2549
  
 
2550
        if ((focus->win == NoneWin) ||
 
2551
            (i >= spriteTraceGood) ||
 
2552
            ((i > checkFirst) && (pWin != spriteTrace[i-1])))
 
2553
            return FALSE;
 
2554
    }
 
2555
 
 
2556
    for (; i < spriteTraceGood; i++)
 
2557
    {
 
2558
        pWin = spriteTrace[i];
 
2559
        if (pWin->optional &&
 
2560
            CheckPassiveGrabsOnWindow(pWin, device, xE, count))
 
2561
            return TRUE;
 
2562
    }
 
2563
 
 
2564
    return FALSE;
 
2565
}
 
2566
 
 
2567
void
 
2568
DeliverFocusedEvent(keybd, xE, window, count)
 
2569
    xEvent *xE;
 
2570
    DeviceIntPtr keybd;
 
2571
    WindowPtr window;
 
2572
    int count;
 
2573
{
 
2574
    WindowPtr focus = keybd->focus->win;
 
2575
    int mskidx = 0;
 
2576
 
 
2577
    if (focus == FollowKeyboardWin)
 
2578
        focus = inputInfo.keyboard->focus->win;
 
2579
    if (!focus)
 
2580
        return;
 
2581
    if (focus == PointerRootWin)
 
2582
    {
 
2583
        DeliverDeviceEvents(window, xE, NullGrab, NullWindow, keybd, count);
 
2584
        return;
 
2585
    }
 
2586
    if ((focus == window) || IsParent(focus, window))
 
2587
    {
 
2588
        if (DeliverDeviceEvents(window, xE, NullGrab, focus, keybd, count))
 
2589
            return;
 
2590
    }
 
2591
    /* just deliver it to the focus window */
 
2592
    FixUpEventFromWindow(xE, focus, None, FALSE);
 
2593
    if (xE->u.u.type & EXTENSION_EVENT_BASE)
 
2594
        mskidx = keybd->id;
 
2595
    (void)DeliverEventsToWindow(focus, xE, count, filters[xE->u.u.type],
 
2596
                                NullGrab, mskidx);
 
2597
}
 
2598
 
 
2599
void
 
2600
DeliverGrabbedEvent(xE, thisDev, deactivateGrab, count)
 
2601
    register xEvent *xE;
 
2602
    register DeviceIntPtr thisDev;
 
2603
    Bool deactivateGrab;
 
2604
    int count;
 
2605
{
 
2606
    register GrabPtr grab = thisDev->grab;
 
2607
    int deliveries = 0;
 
2608
    register DeviceIntPtr dev;
 
2609
    register xEvent *dxE;
 
2610
 
 
2611
    if (grab->ownerEvents)
 
2612
    {
 
2613
        WindowPtr focus;
 
2614
 
 
2615
        if (thisDev->focus)
 
2616
        {
 
2617
            focus = thisDev->focus->win;
 
2618
            if (focus == FollowKeyboardWin)
 
2619
                focus = inputInfo.keyboard->focus->win;
 
2620
        }
 
2621
        else
 
2622
            focus = PointerRootWin;
 
2623
        if (focus == PointerRootWin)
 
2624
            deliveries = DeliverDeviceEvents(sprite.win, xE, grab, NullWindow,
 
2625
                                             thisDev, count);
 
2626
        else if (focus && (focus == sprite.win || IsParent(focus, sprite.win)))
 
2627
            deliveries = DeliverDeviceEvents(sprite.win, xE, grab, focus,
 
2628
                                             thisDev, count);
 
2629
        else if (focus)
 
2630
            deliveries = DeliverDeviceEvents(focus, xE, grab, focus,
 
2631
                                             thisDev, count);
 
2632
    }
 
2633
    if (!deliveries)
 
2634
    {
 
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
 
2640
#ifdef XINPUT
 
2641
                           || xE->u.u.type == DeviceMotionNotify
 
2642
#endif
 
2643
                           ))
 
2644
            thisDev->valuator->motionHintWindow = grab->window;
 
2645
    }
 
2646
    if (deliveries && !deactivateGrab && (xE->u.u.type != MotionNotify
 
2647
#ifdef XINPUT
 
2648
                                          && xE->u.u.type != DeviceMotionNotify
 
2649
#endif
 
2650
                                          ))
 
2651
        switch (thisDev->sync.state)
 
2652
        {
 
2653
        case FREEZE_BOTH_NEXT_EVENT:
 
2654
            for (dev = inputInfo.devices; dev; dev = dev->next)
 
2655
            {
 
2656
                if (dev == thisDev)
 
2657
                    continue;
 
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;
 
2663
                else
 
2664
                    dev->sync.other = thisDev->grab;
 
2665
            }
 
2666
            /* fall through */
 
2667
        case FREEZE_NEXT_EVENT:
 
2668
            thisDev->sync.state = FROZEN_WITH_EVENT;
 
2669
            FreezeThaw(thisDev, TRUE);
 
2670
            if (thisDev->sync.evcount < count)
 
2671
            {
 
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 */
 
2676
            }
 
2677
            thisDev->sync.evcount = count;
 
2678
            for (dxE = thisDev->sync.event; --count >= 0; dxE++, xE++)
 
2679
                *dxE = *xE;
 
2680
            break;
 
2681
        }
 
2682
}
 
2683
 
 
2684
void
 
2685
#ifdef XKB
 
2686
CoreProcessKeyboardEvent (xE, keybd, count)
 
2687
#else
 
2688
ProcessKeyboardEvent (xE, keybd, count)
 
2689
#endif
 
2690
    register xEvent *xE;
 
2691
    register DeviceIntPtr keybd;
 
2692
    int count;
 
2693
{
 
2694
    int             key, bit;
 
2695
    register BYTE   *kptr;
 
2696
    register int    i;
 
2697
    register CARD8  modifiers;
 
2698
    register CARD16 mask;
 
2699
    GrabPtr         grab = keybd->grab;
 
2700
    Bool            deactivateGrab = FALSE;
 
2701
    register KeyClassPtr keyc = keybd->key;
 
2702
 
 
2703
    if (!syncEvents.playingEvents)
 
2704
    {
 
2705
        NoticeTime(xE);
 
2706
        if (DeviceEventCallback)
 
2707
        {
 
2708
            DeviceEventInfoRec eventinfo;
 
2709
            eventinfo.events = xE;
 
2710
            eventinfo.count = count;
 
2711
            CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
 
2712
        }
 
2713
    }
 
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];
 
2721
#ifdef DEBUG
 
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"));
 
2726
    }
 
2727
#endif
 
2728
    switch (xE->u.u.type)
 
2729
    {
 
2730
        case KeyPress: 
 
2731
            if (*kptr & bit) /* allow ddx to generate multiple downs */
 
2732
            {   
 
2733
                if (!modifiers)
 
2734
                {
 
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);
 
2740
                }
 
2741
                return;
 
2742
            }
 
2743
            inputInfo.pointer->valuator->motionHintWindow = NullWindow;
 
2744
            *kptr |= bit;
 
2745
            keyc->prev_state = keyc->state;
 
2746
            for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
 
2747
            {
 
2748
                if (mask & modifiers)
 
2749
                {
 
2750
                    /* This key affects modifier "i" */
 
2751
                    keyc->modifierKeyCount[i]++;
 
2752
                    keyc->state |= mask;
 
2753
                    modifiers &= ~mask;
 
2754
                }
 
2755
            }
 
2756
            if (!grab && CheckDeviceGrabs(keybd, xE, 0, count))
 
2757
            {
 
2758
                keybd->activatingKey = key;
 
2759
                return;
 
2760
            }
 
2761
            break;
 
2762
        case KeyRelease: 
 
2763
            if (!(*kptr & bit)) /* guard against duplicates */
 
2764
                return;
 
2765
            inputInfo.pointer->valuator->motionHintWindow = NullWindow;
 
2766
            *kptr &= ~bit;
 
2767
            keyc->prev_state = keyc->state;
 
2768
            for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
 
2769
            {
 
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;
 
2775
                    }
 
2776
                    modifiers &= ~mask;
 
2777
                }
 
2778
            }
 
2779
            if (keybd->fromPassiveGrab && (key == keybd->activatingKey))
 
2780
                deactivateGrab = TRUE;
 
2781
            break;
 
2782
        default: 
 
2783
            FatalError("Impossible keyboard event");
 
2784
    }
 
2785
    if (grab)
 
2786
        DeliverGrabbedEvent(xE, keybd, deactivateGrab, count);
 
2787
    else
 
2788
        DeliverFocusedEvent(keybd, xE, sprite.win, count);
 
2789
    if (deactivateGrab)
 
2790
        (*keybd->DeactivateGrab)(keybd);
 
2791
}
 
2792
 
 
2793
#ifdef XKB
 
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.
 
2797
*/
 
2798
void
 
2799
FixKeyState (xE, keybd)
 
2800
    register xEvent *xE;
 
2801
    register DeviceIntPtr keybd;
 
2802
{
 
2803
    int             key, bit;
 
2804
    register BYTE   *kptr;
 
2805
    register KeyClassPtr keyc = keybd->key;
 
2806
 
 
2807
    key = xE->u.u.detail;
 
2808
    kptr = &keyc->down[key >> 3];
 
2809
    bit = 1 << (key & 7);
 
2810
#ifdef DEBUG
 
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"));
 
2815
    }
 
2816
#endif
 
2817
    switch (xE->u.u.type)
 
2818
    {
 
2819
        case KeyPress: 
 
2820
            *kptr |= bit;
 
2821
            break;
 
2822
        case KeyRelease: 
 
2823
            *kptr &= ~bit;
 
2824
            break;
 
2825
        default: 
 
2826
            FatalError("Impossible keyboard event");
 
2827
    }
 
2828
}
 
2829
#endif
 
2830
 
 
2831
void
 
2832
#ifdef XKB
 
2833
CoreProcessPointerEvent (xE, mouse, count)
 
2834
#else
 
2835
ProcessPointerEvent (xE, mouse, count)
 
2836
#endif
 
2837
    register xEvent             *xE;
 
2838
    register DeviceIntPtr       mouse;
 
2839
    int                         count;
 
2840
{
 
2841
    register GrabPtr    grab = mouse->grab;
 
2842
    Bool                deactivateGrab = FALSE;
 
2843
    register ButtonClassPtr butc = mouse->button;
 
2844
#ifdef XKB
 
2845
    XkbSrvInfoPtr xkbi= inputInfo.keyboard->key->xkbInfo;
 
2846
#endif
 
2847
 
 
2848
    if (!syncEvents.playingEvents)
 
2849
        NoticeTime(xE)
 
2850
    XE_KBPTR.state = (butc->state | (
 
2851
#ifdef XKB
 
2852
                        (noXkbExtension ?
 
2853
                                inputInfo.keyboard->key->state :
 
2854
                                xkbi->state.grab_mods)
 
2855
#else
 
2856
                        inputInfo.keyboard->key->state
 
2857
#endif
 
2858
                                    ));
 
2859
    {
 
2860
        NoticeTime(xE);
 
2861
        if (DeviceEventCallback)
 
2862
        {
 
2863
            DeviceEventInfoRec eventinfo;
 
2864
            /* see comment in EnqueueEvents regarding the next three lines */
 
2865
            if (xE->u.u.type == MotionNotify)
 
2866
                XE_KBPTR.root =
 
2867
                    WindowTable[sprite.hotPhys.pScreen->myNum]->drawable.id;
 
2868
            eventinfo.events = xE;
 
2869
            eventinfo.count = count;
 
2870
            CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
 
2871
        }
 
2872
    }
 
2873
    if (xE->u.u.type != MotionNotify)
 
2874
    {
 
2875
        register int  key;
 
2876
        register BYTE *kptr;
 
2877
        int           bit;
 
2878
 
 
2879
        XE_KBPTR.rootX = sprite.hot.x;
 
2880
        XE_KBPTR.rootY = sprite.hot.y;
 
2881
 
 
2882
        key = xE->u.u.detail;
 
2883
        kptr = &butc->down[key >> 3];
 
2884
        bit = 1 << (key & 7);
 
2885
        switch (xE->u.u.type)
 
2886
        {
 
2887
        case ButtonPress: 
 
2888
            mouse->valuator->motionHintWindow = NullWindow;
 
2889
            if (!(*kptr & bit))
 
2890
                butc->buttonsDown++;
 
2891
            butc->motionMask = ButtonMotionMask;
 
2892
            *kptr |= bit;
 
2893
#if !defined(XFree86Server) || !defined(XINPUT)
 
2894
            xE->u.u.detail = butc->map[key];
 
2895
#endif
 
2896
            if (xE->u.u.detail == 0)
 
2897
                return;
 
2898
            if (xE->u.u.detail <= 5)
 
2899
                butc->state |= (Button1Mask >> 1) << xE->u.u.detail;
 
2900
            filters[MotionNotify] = Motion_Filter(butc);
 
2901
            if (!grab)
 
2902
                if (CheckDeviceGrabs(mouse, xE, 0, count))
 
2903
                    return;
 
2904
            break;
 
2905
        case ButtonRelease: 
 
2906
            mouse->valuator->motionHintWindow = NullWindow;
 
2907
            if (*kptr & bit)
 
2908
                --butc->buttonsDown;
 
2909
            if (!butc->buttonsDown)
 
2910
                butc->motionMask = 0;
 
2911
            *kptr &= ~bit;
 
2912
#if !defined(XFree86Server) || !defined(XINPUT)
 
2913
            xE->u.u.detail = butc->map[key];
 
2914
#endif
 
2915
            if (xE->u.u.detail == 0)
 
2916
                return;
 
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;
 
2922
            break;
 
2923
        default: 
 
2924
            FatalError("bogus pointer event from ddx");
 
2925
        }
 
2926
    }
 
2927
    else if (!CheckMotion(xE))
 
2928
        return;
 
2929
    if (grab)
 
2930
        DeliverGrabbedEvent(xE, mouse, deactivateGrab, count);
 
2931
    else
 
2932
        DeliverDeviceEvents(sprite.win, xE, NullGrab, NullWindow,
 
2933
                            mouse, count);
 
2934
    if (deactivateGrab)
 
2935
        (*mouse->DeactivateGrab)(mouse);
 
2936
}
 
2937
 
 
2938
#define AtMostOneClient \
 
2939
        (SubstructureRedirectMask | ResizeRedirectMask | ButtonPressMask)
 
2940
 
 
2941
void
 
2942
RecalculateDeliverableEvents(pWin)
 
2943
    register WindowPtr pWin;
 
2944
{
 
2945
    register OtherClients *others;
 
2946
    register WindowPtr pChild;
 
2947
 
 
2948
    pChild = pWin;
 
2949
    while (1)
 
2950
    {
 
2951
        if (pChild->optional)
 
2952
        {
 
2953
            pChild->optional->otherEventMasks = 0;
 
2954
            for (others = wOtherClients(pChild); others; others = others->next)
 
2955
            {
 
2956
                pChild->optional->otherEventMasks |= others->mask;
 
2957
            }
 
2958
        }
 
2959
        pChild->deliverableEvents = pChild->eventMask|
 
2960
                                    wOtherEventMasks(pChild);
 
2961
        if (pChild->parent)
 
2962
            pChild->deliverableEvents |=
 
2963
                (pChild->parent->deliverableEvents &
 
2964
                 ~wDontPropagateMask(pChild) & PropagateMask);
 
2965
        if (pChild->firstChild)
 
2966
        {
 
2967
            pChild = pChild->firstChild;
 
2968
            continue;
 
2969
        }
 
2970
        while (!pChild->nextSib && (pChild != pWin))
 
2971
            pChild = pChild->parent;
 
2972
        if (pChild == pWin)
 
2973
            break;
 
2974
        pChild = pChild->nextSib;
 
2975
    }
 
2976
}
 
2977
 
 
2978
int
 
2979
OtherClientGone(value, id)
 
2980
    pointer value; /* must conform to DeleteType */
 
2981
    XID   id;
 
2982
{
 
2983
    register OtherClientsPtr other, prev;
 
2984
    register WindowPtr pWin = (WindowPtr)value;
 
2985
 
 
2986
    prev = 0;
 
2987
    for (other = wOtherClients(pWin); other; other = other->next)
 
2988
    {
 
2989
        if (other->resource == id)
 
2990
        {
 
2991
            if (prev)
 
2992
                prev->next = other->next;
 
2993
            else
 
2994
            {
 
2995
                if (!(pWin->optional->otherClients = other->next))
 
2996
                    CheckWindowOptionalNeed (pWin);
 
2997
            }
 
2998
            xfree(other);
 
2999
            RecalculateDeliverableEvents(pWin);
 
3000
            return(Success);
 
3001
        }
 
3002
        prev = other;
 
3003
    }
 
3004
    FatalError("client not on event list");
 
3005
    /*NOTREACHED*/
 
3006
    return -1; /* make compiler happy */
 
3007
}
 
3008
 
 
3009
int
 
3010
EventSelectForWindow(pWin, client, mask)
 
3011
    register WindowPtr pWin;
 
3012
    register ClientPtr client;
 
3013
    Mask mask;
 
3014
{
 
3015
    Mask check;
 
3016
    OtherClients * others;
 
3017
 
 
3018
    if (mask & ~AllEventMasks)
 
3019
    {
 
3020
        client->errorValue = mask;
 
3021
        return BadValue;
 
3022
    }
 
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
 
3030
                                          events.  */
 
3031
        if ((wClient(pWin) != client) && (check & pWin->eventMask))
 
3032
            return BadAccess;
 
3033
        for (others = wOtherClients (pWin); others; others = others->next)
 
3034
        {
 
3035
            if (!SameClient(others, client) && (check & others->mask))
 
3036
                return BadAccess;
 
3037
        }
 
3038
    }
 
3039
    if (wClient (pWin) == client)
 
3040
    {
 
3041
        check = pWin->eventMask;
 
3042
#ifdef SGIMISC
 
3043
        pWin->eventMask =
 
3044
            (mask & ~SGIMiscSpecialDestroyMask) | (pWin->eventMask & SGIMiscSpecialDestroyMask);
 
3045
#else
 
3046
        pWin->eventMask = mask;
 
3047
#endif
 
3048
    }
 
3049
    else
 
3050
    {
 
3051
        for (others = wOtherClients (pWin); others; others = others->next)
 
3052
        {
 
3053
            if (SameClient(others, client))
 
3054
            {
 
3055
                check = others->mask;
 
3056
#ifdef SGIMISC
 
3057
                mask = (mask & ~SGIMiscSpecialDestroyMask) | (others->mask & SGIMiscSpecialDestroyMask);
 
3058
#endif
 
3059
                if (mask == 0)
 
3060
                {
 
3061
                    FreeResource(others->resource, RT_NONE);
 
3062
                    return Success;
 
3063
                }
 
3064
                else
 
3065
                    others->mask = mask;
 
3066
                goto maskSet;
 
3067
            }
 
3068
        }
 
3069
        check = 0;
 
3070
        if (!pWin->optional && !MakeWindowOptional (pWin))
 
3071
            return BadAlloc;
 
3072
        others = (OtherClients *) xalloc(sizeof(OtherClients));
 
3073
        if (!others)
 
3074
            return BadAlloc;
 
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))
 
3080
            return BadAlloc;
 
3081
    }
 
3082
maskSet: 
 
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);
 
3089
    return Success;
 
3090
}
 
3091
 
 
3092
/*ARGSUSED*/
 
3093
int
 
3094
EventSuppressForWindow(pWin, client, mask, checkOptional)
 
3095
    register WindowPtr pWin;
 
3096
    register ClientPtr client;
 
3097
    Mask mask;
 
3098
    Bool *checkOptional;
 
3099
{
 
3100
    register int i, free;
 
3101
 
 
3102
    if ((mask & ~PropagateMask) && !permitOldBugs)
 
3103
    {
 
3104
        client->errorValue = mask;
 
3105
        return BadValue;
 
3106
    }
 
3107
    if (pWin->dontPropagate)
 
3108
        DontPropagateRefCnts[pWin->dontPropagate]--;
 
3109
    if (!mask)
 
3110
        i = 0;
 
3111
    else
 
3112
    {
 
3113
        for (i = DNPMCOUNT, free = 0; --i > 0; )
 
3114
        {
 
3115
            if (!DontPropagateRefCnts[i])
 
3116
                free = i;
 
3117
            else if (mask == DontPropagateMasks[i])
 
3118
                break;
 
3119
        }
 
3120
        if (!i && free)
 
3121
        {
 
3122
            i = free;
 
3123
            DontPropagateMasks[i] = mask;
 
3124
        }
 
3125
    }
 
3126
    if (i || !mask)
 
3127
    {
 
3128
        pWin->dontPropagate = i;
 
3129
        if (i)
 
3130
            DontPropagateRefCnts[i]++;
 
3131
        if (pWin->optional)
 
3132
        {
 
3133
            pWin->optional->dontPropagateMask = mask;
 
3134
            *checkOptional = TRUE;
 
3135
        }
 
3136
    }
 
3137
    else
 
3138
    {
 
3139
        if (!pWin->optional && !MakeWindowOptional (pWin))
 
3140
        {
 
3141
            if (pWin->dontPropagate)
 
3142
                DontPropagateRefCnts[pWin->dontPropagate]++;
 
3143
            return BadAlloc;
 
3144
        }
 
3145
        pWin->dontPropagate = 0;
 
3146
        pWin->optional->dontPropagateMask = mask;
 
3147
    }
 
3148
    RecalculateDeliverableEvents(pWin);
 
3149
    return Success;
 
3150
}
 
3151
 
 
3152
static WindowPtr 
 
3153
#if NeedFunctionPrototypes
 
3154
CommonAncestor(
 
3155
    register WindowPtr a,
 
3156
    register WindowPtr b)
 
3157
#else
 
3158
CommonAncestor(a, b)
 
3159
    register WindowPtr a, b;
 
3160
#endif
 
3161
{
 
3162
    for (b = b->parent; b; b = b->parent)
 
3163
        if (IsParent(b, a)) return b;
 
3164
    return NullWindow;
 
3165
}
 
3166
 
 
3167
static void
 
3168
#if NeedFunctionPrototypes
 
3169
EnterLeaveEvent(
 
3170
    int type,
 
3171
    int mode,
 
3172
    int detail,
 
3173
    register WindowPtr pWin,
 
3174
    Window child)
 
3175
#else
 
3176
EnterLeaveEvent(type, mode, detail, pWin, child)
 
3177
    int type, mode, detail;
 
3178
    register WindowPtr pWin;
 
3179
    Window child;
 
3180
#endif
 
3181
{
 
3182
    xEvent              event;
 
3183
    register DeviceIntPtr keybd = inputInfo.keyboard;
 
3184
    WindowPtr           focus;
 
3185
    register DeviceIntPtr mouse = inputInfo.pointer;
 
3186
    register GrabPtr    grab = mouse->grab;
 
3187
    Mask                mask;
 
3188
 
 
3189
    if ((pWin == mouse->valuator->motionHintWindow) &&
 
3190
        (detail != NotifyInferior))
 
3191
        mouse->valuator->motionHintWindow = NullWindow;
 
3192
    if (grab)
 
3193
    {
 
3194
        mask = (pWin == grab->window) ? grab->eventMask : 0;
 
3195
        if (grab->ownerEvents)
 
3196
            mask |= EventMaskForClient(pWin, rClient(grab));
 
3197
    }
 
3198
    else
 
3199
    {
 
3200
        mask = pWin->eventMask | wOtherEventMasks(pWin);
 
3201
    }
 
3202
    if (mask & filters[type])
 
3203
    {
 
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;
 
3215
#ifdef XKB
 
3216
        if (!noXkbExtension) {
 
3217
            event.u.enterLeave.state = mouse->button->state & 0x1f00;
 
3218
            event.u.enterLeave.state |= 
 
3219
                        XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
 
3220
        } else
 
3221
#endif
 
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;
 
3229
        if (grab)
 
3230
            (void)TryClientEvents(rClient(grab), &event, 1, mask,
 
3231
                                  filters[type], grab);
 
3232
        else
 
3233
            (void)DeliverEventsToWindow(pWin, &event, 1, filters[type],
 
3234
                                        NullGrab, 0);
 
3235
    }
 
3236
    if ((type == EnterNotify) && (mask & KeymapStateMask))
 
3237
    {
 
3238
        xKeymapEvent ke;
 
3239
 
 
3240
#ifdef XCSECURITY
 
3241
        ClientPtr client = grab ? rClient(grab)
 
3242
                                : clients[CLIENT_ID(pWin->drawable.id)];
 
3243
        if (!SecurityCheckDeviceAccess(client, keybd, FALSE))
 
3244
        {
 
3245
            bzero((char *)&ke.map[0], 31);
 
3246
        }
 
3247
        else
 
3248
#endif
 
3249
        memmove((char *)&ke.map[0], (char *)&keybd->key->down[1], 31);
 
3250
        ke.type = KeymapNotify;
 
3251
        if (grab)
 
3252
            (void)TryClientEvents(rClient(grab), (xEvent *)&ke, 1, mask,
 
3253
                                  KeymapStateMask, grab);
 
3254
        else
 
3255
            (void)DeliverEventsToWindow(pWin, (xEvent *)&ke, 1,
 
3256
                                        KeymapStateMask, NullGrab, 0);
 
3257
    }
 
3258
}
 
3259
 
 
3260
static void
 
3261
#if NeedFunctionPrototypes
 
3262
EnterNotifies(WindowPtr ancestor, WindowPtr child, int mode, int detail)
 
3263
#else
 
3264
EnterNotifies(ancestor, child, mode, detail)
 
3265
    WindowPtr ancestor, child;
 
3266
    int mode, detail;
 
3267
#endif
 
3268
{
 
3269
    WindowPtr   parent = child->parent;
 
3270
 
 
3271
    if (ancestor == parent)
 
3272
        return;
 
3273
    EnterNotifies(ancestor, parent, mode, detail);
 
3274
    EnterLeaveEvent(EnterNotify, mode, detail, parent, child->drawable.id);
 
3275
}
 
3276
 
 
3277
static void
 
3278
#if NeedFunctionPrototypes
 
3279
LeaveNotifies(WindowPtr child, WindowPtr ancestor, int mode, int detail)
 
3280
#else
 
3281
LeaveNotifies(child, ancestor, mode, detail)
 
3282
    WindowPtr child, ancestor;
 
3283
    int detail, mode;
 
3284
#endif
 
3285
{
 
3286
    register WindowPtr  pWin;
 
3287
 
 
3288
    if (ancestor == child)
 
3289
        return;
 
3290
    for (pWin = child->parent; pWin != ancestor; pWin = pWin->parent)
 
3291
    {
 
3292
        EnterLeaveEvent(LeaveNotify, mode, detail, pWin, child->drawable.id);
 
3293
        child = pWin;
 
3294
    }
 
3295
}
 
3296
 
 
3297
static void
 
3298
#if NeedFunctionPrototypes
 
3299
DoEnterLeaveEvents(WindowPtr fromWin, WindowPtr toWin, int mode)
 
3300
#else
 
3301
DoEnterLeaveEvents(fromWin, toWin, mode)
 
3302
    WindowPtr fromWin, toWin;
 
3303
    int mode;
 
3304
#endif
 
3305
{
 
3306
    if (fromWin == toWin)
 
3307
        return;
 
3308
    if (IsParent(fromWin, toWin))
 
3309
    {
 
3310
        EnterLeaveEvent(LeaveNotify, mode, NotifyInferior, fromWin, None);
 
3311
        EnterNotifies(fromWin, toWin, mode, NotifyVirtual);
 
3312
        EnterLeaveEvent(EnterNotify, mode, NotifyAncestor, toWin, None);
 
3313
    }
 
3314
    else if (IsParent(toWin, fromWin))
 
3315
    {
 
3316
        EnterLeaveEvent(LeaveNotify, mode, NotifyAncestor, fromWin, None);
 
3317
        LeaveNotifies(fromWin, toWin, mode, NotifyVirtual);
 
3318
        EnterLeaveEvent(EnterNotify, mode, NotifyInferior, toWin, None);
 
3319
    }
 
3320
    else
 
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);
 
3328
    }
 
3329
}
 
3330
 
 
3331
static void
 
3332
#if NeedFunctionPrototypes
 
3333
FocusEvent(DeviceIntPtr dev, int type, int mode, int detail, register WindowPtr pWin)
 
3334
#else
 
3335
FocusEvent(dev, type, mode, detail, pWin)
 
3336
    DeviceIntPtr dev;
 
3337
    int type, mode, detail;
 
3338
    register WindowPtr pWin;
 
3339
#endif
 
3340
{
 
3341
    xEvent event;
 
3342
 
 
3343
#ifdef XINPUT
 
3344
    if (dev != inputInfo.keyboard)
 
3345
    {
 
3346
        DeviceFocusEvent(dev, type, mode, detail, pWin);
 
3347
        return;
 
3348
    }
 
3349
#endif
 
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,
 
3355
                                0);
 
3356
    if ((type == FocusIn) &&
 
3357
        ((pWin->eventMask | wOtherEventMasks(pWin)) & KeymapStateMask))
 
3358
    {
 
3359
        xKeymapEvent ke;
 
3360
#ifdef XCSECURITY
 
3361
        ClientPtr client = clients[CLIENT_ID(pWin->drawable.id)];
 
3362
        if (!SecurityCheckDeviceAccess(client, dev, FALSE))
 
3363
        {
 
3364
            bzero((char *)&ke.map[0], 31);
 
3365
        }
 
3366
        else
 
3367
#endif
 
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);
 
3372
    }
 
3373
}
 
3374
 
 
3375
 /*
 
3376
  * recursive because it is easier
 
3377
  * no-op if child not descended from ancestor
 
3378
  */
 
3379
static Bool
 
3380
#if NeedFunctionPrototypes
 
3381
FocusInEvents(
 
3382
    DeviceIntPtr dev,
 
3383
    WindowPtr ancestor, WindowPtr child, WindowPtr skipChild,
 
3384
    int mode, int detail,
 
3385
    Bool doAncestor)
 
3386
#else
 
3387
FocusInEvents(dev, ancestor, child, skipChild, mode, detail, doAncestor)
 
3388
    DeviceIntPtr dev;
 
3389
    WindowPtr ancestor, child, skipChild;
 
3390
    int mode, detail;
 
3391
    Bool doAncestor;
 
3392
#endif
 
3393
{
 
3394
    if (child == NullWindow)
 
3395
        return ancestor == NullWindow;
 
3396
    if (ancestor == child)
 
3397
    {
 
3398
        if (doAncestor)
 
3399
            FocusEvent(dev, FocusIn, mode, detail, child);
 
3400
        return TRUE;
 
3401
    }
 
3402
    if (FocusInEvents(dev, ancestor, child->parent, skipChild, mode, detail,
 
3403
                      doAncestor))
 
3404
    {
 
3405
        if (child != skipChild)
 
3406
            FocusEvent(dev, FocusIn, mode, detail, child);
 
3407
        return TRUE;
 
3408
    }
 
3409
    return FALSE;
 
3410
}
 
3411
 
 
3412
/* dies horribly if ancestor is not an ancestor of child */
 
3413
static void
 
3414
#if NeedFunctionPrototypes
 
3415
FocusOutEvents(
 
3416
    DeviceIntPtr dev,
 
3417
    WindowPtr child, WindowPtr ancestor,
 
3418
    int mode, int detail,
 
3419
    Bool doAncestor)
 
3420
#else
 
3421
FocusOutEvents(dev, child, ancestor, mode, detail, doAncestor)
 
3422
    DeviceIntPtr dev;
 
3423
    WindowPtr child, ancestor;
 
3424
    int mode;
 
3425
    int detail;
 
3426
    Bool doAncestor;
 
3427
#endif
 
3428
{
 
3429
    register WindowPtr  pWin;
 
3430
 
 
3431
    for (pWin = child; pWin != ancestor; pWin = pWin->parent)
 
3432
        FocusEvent(dev, FocusOut, mode, detail, pWin);
 
3433
    if (doAncestor)
 
3434
        FocusEvent(dev, FocusOut, mode, detail, ancestor);
 
3435
}
 
3436
 
 
3437
void
 
3438
DoFocusEvents(dev, fromWin, toWin, mode)
 
3439
    DeviceIntPtr dev;
 
3440
    WindowPtr fromWin, toWin;
 
3441
    int mode;
 
3442
{
 
3443
    int     out, in;                   /* for holding details for to/from
 
3444
                                          PointerRoot/None */
 
3445
    int     i;
 
3446
 
 
3447
    if (fromWin == toWin)
 
3448
        return;
 
3449
    out = (fromWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
 
3450
    in = (toWin == NoneWin) ? NotifyDetailNone : NotifyPointerRoot;
 
3451
 /* wrong values if neither, but then not referenced */
 
3452
 
 
3453
    if ((toWin == NullWindow) || (toWin == PointerRootWin))
 
3454
    {
 
3455
        if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
 
3456
        {
 
3457
            if (fromWin == PointerRootWin)
 
3458
                FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
 
3459
                               TRUE);
 
3460
            /* Notify all the roots */
 
3461
#ifdef PANORAMIX
 
3462
            if ( !noPanoramiXExtension )
 
3463
                FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
 
3464
            else 
 
3465
#endif
 
3466
                for (i=0; i<screenInfo.numScreens; i++)
 
3467
                    FocusEvent(dev, FocusOut, mode, out, WindowTable[i]);
 
3468
        }
 
3469
        else
 
3470
        {
 
3471
            if (IsParent(fromWin, sprite.win))
 
3472
              FocusOutEvents(dev, sprite.win, fromWin, mode, NotifyPointer,
 
3473
                             FALSE);
 
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);
 
3478
        }
 
3479
        /* Notify all the roots */
 
3480
#ifdef PANORAMIX
 
3481
        if ( !noPanoramiXExtension )
 
3482
            FocusEvent(dev, FocusIn, mode, in, WindowTable[0]);
 
3483
        else 
 
3484
#endif
 
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);
 
3490
    }
 
3491
    else
 
3492
    {
 
3493
        if ((fromWin == NullWindow) || (fromWin == PointerRootWin))
 
3494
        {
 
3495
            if (fromWin == PointerRootWin)
 
3496
                FocusOutEvents(dev, sprite.win, ROOT, mode, NotifyPointer,
 
3497
                               TRUE);
 
3498
#ifdef PANORAMIX
 
3499
            if ( !noPanoramiXExtension )
 
3500
                FocusEvent(dev, FocusOut, mode, out, WindowTable[0]);
 
3501
            else 
 
3502
#endif
 
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);
 
3512
        }
 
3513
        else
 
3514
        {
 
3515
            if (IsParent(toWin, fromWin))
 
3516
            {
 
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);
 
3527
            }
 
3528
            else
 
3529
                if (IsParent(fromWin, toWin))
 
3530
                {
 
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);
 
3541
                }
 
3542
                else
 
3543
                {
 
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);
 
3561
                }
 
3562
        }
 
3563
    }
 
3564
}
 
3565
 
 
3566
int
 
3567
#if NeedFunctionPrototypes
 
3568
SetInputFocus(
 
3569
    ClientPtr client,
 
3570
    DeviceIntPtr dev,
 
3571
    Window focusID,
 
3572
    CARD8 revertTo,
 
3573
    Time ctime,
 
3574
    Bool followOK)
 
3575
#else
 
3576
SetInputFocus(client, dev, focusID, revertTo, ctime, followOK)
 
3577
    ClientPtr client;
 
3578
    DeviceIntPtr dev;
 
3579
    Window focusID;
 
3580
    CARD8 revertTo;
 
3581
    Time ctime;
 
3582
    Bool followOK;
 
3583
#endif
 
3584
{
 
3585
    register FocusClassPtr focus;
 
3586
    register WindowPtr focusWin;
 
3587
    int mode;
 
3588
    TimeStamp time;
 
3589
 
 
3590
    UpdateCurrentTime();
 
3591
    if ((revertTo != RevertToParent) &&
 
3592
        (revertTo != RevertToPointerRoot) &&
 
3593
        (revertTo != RevertToNone) &&
 
3594
        ((revertTo != RevertToFollowKeyboard) || !followOK))
 
3595
    {
 
3596
        client->errorValue = revertTo;
 
3597
        return BadValue;
 
3598
    }
 
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)))
 
3606
        return BadWindow;
 
3607
    else
 
3608
    {
 
3609
        /* It is a match error to try to set the input focus to an 
 
3610
        unviewable window. */
 
3611
 
 
3612
        if(!focusWin->realized)
 
3613
            return(BadMatch);
 
3614
    }
 
3615
    focus = dev->focus;
 
3616
    if ((CompareTimeStamps(time, currentTime) == LATER) ||
 
3617
        (CompareTimeStamps(time, focus->time) == EARLIER))
 
3618
        return Success;
 
3619
    mode = (dev->grab) ? NotifyWhileGrabbed : NotifyNormal;
 
3620
    if (focus->win == FollowKeyboardWin)
 
3621
        DoFocusEvents(dev, inputInfo.keyboard->focus->win, focusWin, mode);
 
3622
    else
 
3623
        DoFocusEvents(dev, focus->win, focusWin, mode);
 
3624
    focus->time = time;
 
3625
    focus->revert = revertTo;
 
3626
    if (focusID == FollowKeyboard)
 
3627
        focus->win = FollowKeyboardWin;
 
3628
    else
 
3629
        focus->win = focusWin;
 
3630
    if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
 
3631
        focus->traceGood = 0;
 
3632
    else
 
3633
    {
 
3634
        int depth = 0;
 
3635
        register WindowPtr pWin;
 
3636
 
 
3637
        for (pWin = focusWin; pWin; pWin = pWin->parent) depth++;
 
3638
        if (depth > focus->traceSize)
 
3639
        {
 
3640
            focus->traceSize = depth+1;
 
3641
            Must_have_memory = TRUE; /* XXX */
 
3642
            focus->trace = (WindowPtr *)xrealloc(focus->trace,
 
3643
                                                 focus->traceSize *
 
3644
                                                 sizeof(WindowPtr));
 
3645
            Must_have_memory = FALSE; /* XXX */
 
3646
        }
 
3647
        focus->traceGood = depth;
 
3648
        for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--) 
 
3649
            focus->trace[depth] = pWin;
 
3650
    }
 
3651
    return Success;
 
3652
}
 
3653
 
 
3654
int
 
3655
ProcSetInputFocus(client)
 
3656
    ClientPtr client;
 
3657
{
 
3658
    REQUEST(xSetInputFocusReq);
 
3659
 
 
3660
    REQUEST_SIZE_MATCH(xSetInputFocusReq);
 
3661
#ifdef XCSECURITY
 
3662
    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
 
3663
        return Success;
 
3664
#endif
 
3665
    return SetInputFocus(client, inputInfo.keyboard, stuff->focus,
 
3666
                         stuff->revertTo, stuff->time, FALSE);
 
3667
}
 
3668
 
 
3669
int
 
3670
ProcGetInputFocus(client)
 
3671
    ClientPtr client;
 
3672
{
 
3673
    xGetInputFocusReply rep;
 
3674
    /* REQUEST(xReq); */
 
3675
    FocusClassPtr focus = inputInfo.keyboard->focus;
 
3676
 
 
3677
    REQUEST_SIZE_MATCH(xReq);
 
3678
    rep.type = X_Reply;
 
3679
    rep.length = 0;
 
3680
    rep.sequenceNumber = client->sequence;
 
3681
    if (focus->win == NoneWin)
 
3682
        rep.focus = None;
 
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);
 
3688
    return Success;
 
3689
}
 
3690
 
 
3691
int
 
3692
ProcGrabPointer(client)
 
3693
    ClientPtr client;
 
3694
{
 
3695
    xGrabPointerReply rep;
 
3696
    DeviceIntPtr device = inputInfo.pointer;
 
3697
    GrabPtr grab;
 
3698
    WindowPtr pWin, confineTo;
 
3699
    CursorPtr cursor, oldCursor;
 
3700
    REQUEST(xGrabPointerReq);
 
3701
    TimeStamp time;
 
3702
 
 
3703
    REQUEST_SIZE_MATCH(xGrabPointerReq);
 
3704
    UpdateCurrentTime();
 
3705
    if ((stuff->pointerMode != GrabModeSync) &&
 
3706
        (stuff->pointerMode != GrabModeAsync))
 
3707
    {
 
3708
        client->errorValue = stuff->pointerMode;
 
3709
        return BadValue;
 
3710
    }
 
3711
    if ((stuff->keyboardMode != GrabModeSync) &&
 
3712
        (stuff->keyboardMode != GrabModeAsync))
 
3713
    {
 
3714
        client->errorValue = stuff->keyboardMode;
 
3715
        return BadValue;
 
3716
    }
 
3717
    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
 
3718
    {
 
3719
        client->errorValue = stuff->ownerEvents;
 
3720
        return BadValue;
 
3721
    }
 
3722
    if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
 
3723
    {
 
3724
        client->errorValue = stuff->eventMask;
 
3725
        return BadValue;
 
3726
    }
 
3727
    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
 
3728
    if (!pWin)
 
3729
        return BadWindow;
 
3730
    if (stuff->confineTo == None)
 
3731
        confineTo = NullWindow;
 
3732
    else 
 
3733
    {
 
3734
        confineTo = SecurityLookupWindow(stuff->confineTo, client,
 
3735
                                         SecurityReadAccess);
 
3736
        if (!confineTo)
 
3737
            return BadWindow;
 
3738
    }
 
3739
    if (stuff->cursor == None)
 
3740
        cursor = NullCursor;
 
3741
    else
 
3742
    {
 
3743
        cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
 
3744
                                                RT_CURSOR, SecurityReadAccess);
 
3745
        if (!cursor)
 
3746
        {
 
3747
            client->errorValue = stuff->cursor;
 
3748
            return BadCursor;
 
3749
        }
 
3750
    }
 
3751
        /* at this point, some sort of reply is guaranteed. */
 
3752
    time = ClientTimeToServerTime(stuff->time);
 
3753
    rep.type = X_Reply;
 
3754
    rep.sequenceNumber = client->sequence;
 
3755
    rep.length = 0;
 
3756
    grab = device->grab;
 
3757
    if ((grab) && !SameClient(grab, client))
 
3758
        rep.status = AlreadyGrabbed;
 
3759
    else if ((!pWin->realized) ||
 
3760
             (confineTo &&
 
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;
 
3769
    else
 
3770
    {
 
3771
        GrabRec tempGrab;
 
3772
 
 
3773
        oldCursor = NullCursor;
 
3774
        if (grab)
 
3775
        {
 
3776
            if (grab->confineTo && !confineTo)
 
3777
                ConfineCursorToWindow(ROOT, FALSE, FALSE);
 
3778
            oldCursor = grab->cursor;
 
3779
        }
 
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);
 
3790
        if (oldCursor)
 
3791
            FreeCursor (oldCursor, (Cursor)0);
 
3792
        rep.status = GrabSuccess;
 
3793
    }
 
3794
    WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
 
3795
    return Success;
 
3796
}
 
3797
 
 
3798
int
 
3799
ProcChangeActivePointerGrab(client)
 
3800
    ClientPtr client;
 
3801
{
 
3802
    DeviceIntPtr device = inputInfo.pointer;
 
3803
    register GrabPtr grab = device->grab;
 
3804
    CursorPtr newCursor, oldCursor;
 
3805
    REQUEST(xChangeActivePointerGrabReq);
 
3806
    TimeStamp time;
 
3807
 
 
3808
    REQUEST_SIZE_MATCH(xChangeActivePointerGrabReq);
 
3809
    if ((stuff->eventMask & ~PointerGrabMask) && !permitOldBugs)
 
3810
    {
 
3811
        client->errorValue = stuff->eventMask;
 
3812
        return BadValue;
 
3813
    }
 
3814
    if (stuff->cursor == None)
 
3815
        newCursor = NullCursor;
 
3816
    else
 
3817
    {
 
3818
        newCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
 
3819
                                                RT_CURSOR, SecurityReadAccess);
 
3820
        if (!newCursor)
 
3821
        {
 
3822
            client->errorValue = stuff->cursor;
 
3823
            return BadCursor;
 
3824
        }
 
3825
    }
 
3826
    if (!grab)
 
3827
        return Success;
 
3828
    if (!SameClient(grab, client))
 
3829
        return Success;
 
3830
    time = ClientTimeToServerTime(stuff->time);
 
3831
    if ((CompareTimeStamps(time, currentTime) == LATER) ||
 
3832
             (CompareTimeStamps(time, device->grabTime) == EARLIER))
 
3833
        return Success;
 
3834
    oldCursor = grab->cursor;
 
3835
    grab->cursor = newCursor;
 
3836
    if (newCursor)
 
3837
        newCursor->refcnt++;
 
3838
    PostNewCursor();
 
3839
    if (oldCursor)
 
3840
        FreeCursor(oldCursor, (Cursor)0);
 
3841
    grab->eventMask = stuff->eventMask;
 
3842
    return Success;
 
3843
}
 
3844
 
 
3845
int
 
3846
ProcUngrabPointer(client)
 
3847
    ClientPtr client;
 
3848
{
 
3849
    DeviceIntPtr device = inputInfo.pointer;
 
3850
    GrabPtr grab;
 
3851
    TimeStamp time;
 
3852
    REQUEST(xResourceReq);
 
3853
 
 
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);
 
3862
    return Success;
 
3863
}
 
3864
 
 
3865
int
 
3866
GrabDevice(client, dev, this_mode, other_mode, grabWindow, ownerEvents, ctime,
 
3867
           mask, status)
 
3868
    register ClientPtr client;
 
3869
    register DeviceIntPtr dev;
 
3870
    unsigned this_mode;
 
3871
    unsigned other_mode;
 
3872
    Window grabWindow;
 
3873
    unsigned ownerEvents;
 
3874
    Time ctime;
 
3875
    Mask mask;
 
3876
    CARD8 *status;
 
3877
{
 
3878
    register WindowPtr pWin;
 
3879
    register GrabPtr grab;
 
3880
    TimeStamp time;
 
3881
 
 
3882
    UpdateCurrentTime();
 
3883
    if ((this_mode != GrabModeSync) && (this_mode != GrabModeAsync))
 
3884
    {
 
3885
        client->errorValue = this_mode;
 
3886
        return BadValue;
 
3887
    }
 
3888
    if ((other_mode != GrabModeSync) && (other_mode != GrabModeAsync))
 
3889
    {
 
3890
        client->errorValue = other_mode;
 
3891
        return BadValue;
 
3892
    }
 
3893
    if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
 
3894
    {
 
3895
        client->errorValue = ownerEvents;
 
3896
        return BadValue;
 
3897
    }
 
3898
    pWin = SecurityLookupWindow(grabWindow, client, SecurityReadAccess);
 
3899
    if (!pWin)
 
3900
        return BadWindow;
 
3901
    time = ClientTimeToServerTime(ctime);
 
3902
    grab = dev->grab;
 
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;
 
3913
    else
 
3914
    {
 
3915
        GrabRec tempGrab;
 
3916
 
 
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;
 
3926
    }
 
3927
    return Success;
 
3928
}
 
3929
 
 
3930
int
 
3931
ProcGrabKeyboard(client)
 
3932
    ClientPtr client;
 
3933
{
 
3934
    xGrabKeyboardReply rep;
 
3935
    REQUEST(xGrabKeyboardReq);
 
3936
    int result;
 
3937
 
 
3938
    REQUEST_SIZE_MATCH(xGrabKeyboardReq);
 
3939
#ifdef XCSECURITY
 
3940
    if (!SecurityCheckDeviceAccess(client, inputInfo.keyboard, TRUE))
 
3941
    {
 
3942
        result = Success;
 
3943
        rep.status = AlreadyGrabbed;
 
3944
    }
 
3945
    else
 
3946
#endif
 
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)
 
3952
        return result;
 
3953
    rep.type = X_Reply;
 
3954
    rep.sequenceNumber = client->sequence;
 
3955
    rep.length = 0;
 
3956
    WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
 
3957
    return Success;
 
3958
}
 
3959
 
 
3960
int
 
3961
ProcUngrabKeyboard(client)
 
3962
    ClientPtr client;
 
3963
{
 
3964
    DeviceIntPtr device = inputInfo.keyboard;
 
3965
    GrabPtr grab;
 
3966
    TimeStamp time;
 
3967
    REQUEST(xResourceReq);
 
3968
 
 
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);
 
3977
    return Success;
 
3978
}
 
3979
 
 
3980
int
 
3981
ProcQueryPointer(client)
 
3982
    ClientPtr client;
 
3983
{
 
3984
    xQueryPointerReply rep;
 
3985
    WindowPtr pWin, t;
 
3986
    REQUEST(xResourceReq);
 
3987
    DeviceIntPtr mouse = inputInfo.pointer;
 
3988
 
 
3989
    REQUEST_SIZE_MATCH(xResourceReq);
 
3990
    pWin = SecurityLookupWindow(stuff->id, client, SecurityReadAccess);
 
3991
    if (!pWin)
 
3992
        return BadWindow;
 
3993
    if (mouse->valuator->motionHintWindow)
 
3994
        MaybeStopHint(mouse, client);
 
3995
    rep.type = X_Reply;
 
3996
    rep.sequenceNumber = client->sequence;
 
3997
    rep.mask = mouse->button->state | inputInfo.keyboard->key->state;
 
3998
    rep.length = 0;
 
3999
    rep.root = (ROOT)->drawable.id;
 
4000
    rep.rootX = sprite.hot.x;
 
4001
    rep.rootY = sprite.hot.y;
 
4002
    rep.child = None;
 
4003
    if (sprite.hot.pScreen == pWin->drawable.pScreen)
 
4004
    {
 
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)
 
4010
            {
 
4011
                rep.child = t->drawable.id;
 
4012
                break;
 
4013
            }
 
4014
    }
 
4015
    else
 
4016
    {
 
4017
        rep.sameScreen = xFalse;
 
4018
        rep.winX = 0;
 
4019
        rep.winY = 0;
 
4020
    }
 
4021
 
 
4022
#ifdef PANORAMIX
 
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;
 
4029
        }
 
4030
    }
 
4031
#endif
 
4032
 
 
4033
    WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);
 
4034
 
 
4035
    return(Success);    
 
4036
}
 
4037
 
 
4038
void
 
4039
InitEvents()
 
4040
{
 
4041
    int i;
 
4042
 
 
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)
 
4050
    {
 
4051
        spriteTraceSize = 32;
 
4052
        spriteTrace = (WindowPtr *)xalloc(32*sizeof(WindowPtr));
 
4053
        if (!spriteTrace)
 
4054
            FatalError("failed to allocate spriteTrace");
 
4055
    }
 
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)
 
4069
    {
 
4070
        QdEventPtr next = syncEvents.pending->next;
 
4071
        xfree(syncEvents.pending);
 
4072
        syncEvents.pending = next;
 
4073
    }
 
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++)
 
4082
    {
 
4083
        DontPropagateMasks[i] = 0;
 
4084
        DontPropagateRefCnts[i] = 0;
 
4085
    }
 
4086
}
 
4087
 
 
4088
void
 
4089
CloseDownEvents(void)
 
4090
{
 
4091
  xfree(spriteTrace);
 
4092
  spriteTrace = NULL;
 
4093
  spriteTraceSize = 0;
 
4094
}
 
4095
 
 
4096
int
 
4097
ProcSendEvent(client)
 
4098
    ClientPtr client;
 
4099
{
 
4100
    WindowPtr pWin;
 
4101
    WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
 
4102
    REQUEST(xSendEventReq);
 
4103
 
 
4104
    REQUEST_SIZE_MATCH(xSendEventReq);
 
4105
 
 
4106
    /* The client's event type must be a core event type or one defined by an
 
4107
        extension. */
 
4108
 
 
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)))
 
4113
    {
 
4114
        client->errorValue = stuff->event.u.u.type;
 
4115
        return BadValue;
 
4116
    }
 
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 &&
 
4121
        !permitOldBugs)
 
4122
    {
 
4123
        client->errorValue = stuff->event.u.u.detail;
 
4124
        return BadValue;
 
4125
    }
 
4126
    if ((stuff->eventMask & ~AllEventMasks) && !permitOldBugs)
 
4127
    {
 
4128
        client->errorValue = stuff->eventMask;
 
4129
        return BadValue;
 
4130
    }
 
4131
 
 
4132
    if (stuff->destination == PointerWindow)
 
4133
        pWin = sprite.win;
 
4134
    else if (stuff->destination == InputFocus)
 
4135
    {
 
4136
        WindowPtr inputFocus = inputInfo.keyboard->focus->win;
 
4137
 
 
4138
        if (inputFocus == NoneWin)
 
4139
            return Success;
 
4140
 
 
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)
 
4144
            inputFocus = ROOT;
 
4145
 
 
4146
        if (IsParent(inputFocus, sprite.win))
 
4147
        {
 
4148
            effectiveFocus = inputFocus;
 
4149
            pWin = sprite.win;
 
4150
        }
 
4151
        else
 
4152
            effectiveFocus = pWin = inputFocus;
 
4153
    }
 
4154
    else
 
4155
        pWin = SecurityLookupWindow(stuff->destination, client,
 
4156
                                    SecurityReadAccess);
 
4157
    if (!pWin)
 
4158
        return BadWindow;
 
4159
    if ((stuff->propagate != xFalse) && (stuff->propagate != xTrue))
 
4160
    {
 
4161
        client->errorValue = stuff->propagate;
 
4162
        return BadValue;
 
4163
    }
 
4164
    stuff->event.u.u.type |= 0x80;
 
4165
    if (stuff->propagate)
 
4166
    {
 
4167
        for (;pWin; pWin = pWin->parent)
 
4168
        {
 
4169
            if (DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
 
4170
                                      NullGrab, 0))
 
4171
                return Success;
 
4172
            if (pWin == effectiveFocus)
 
4173
                return Success;
 
4174
            stuff->eventMask &= ~wDontPropagateMask(pWin);
 
4175
            if (!stuff->eventMask)
 
4176
                break;
 
4177
        }
 
4178
    }
 
4179
    else
 
4180
        (void)DeliverEventsToWindow(pWin, &stuff->event, 1, stuff->eventMask,
 
4181
                                    NullGrab, 0);
 
4182
    return Success;
 
4183
}
 
4184
 
 
4185
int
 
4186
ProcUngrabKey(client)
 
4187
    ClientPtr client;
 
4188
{
 
4189
    REQUEST(xUngrabKeyReq);
 
4190
    WindowPtr pWin;
 
4191
    GrabRec tempGrab;
 
4192
    DeviceIntPtr keybd = inputInfo.keyboard;
 
4193
 
 
4194
    REQUEST_SIZE_MATCH(xUngrabKeyReq);
 
4195
    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
 
4196
    if (!pWin)
 
4197
        return BadWindow;
 
4198
 
 
4199
    if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
 
4200
         (stuff->key < keybd->key->curKeySyms.minKeyCode))
 
4201
        && (stuff->key != AnyKey))
 
4202
    {
 
4203
        client->errorValue = stuff->key;
 
4204
        return BadValue;
 
4205
    }
 
4206
    if ((stuff->modifiers != AnyModifier) &&
 
4207
        (stuff->modifiers & ~AllModifiersMask))
 
4208
    {
 
4209
        client->errorValue = stuff->modifiers;
 
4210
        return BadValue;
 
4211
    }
 
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;
 
4221
 
 
4222
    if (!DeletePassiveGrabFromList(&tempGrab))
 
4223
        return(BadAlloc);
 
4224
    return(Success);
 
4225
}
 
4226
 
 
4227
int
 
4228
ProcGrabKey(client)
 
4229
    ClientPtr client;
 
4230
{
 
4231
    WindowPtr pWin;
 
4232
    REQUEST(xGrabKeyReq);
 
4233
    GrabPtr grab;
 
4234
    DeviceIntPtr keybd = inputInfo.keyboard;
 
4235
 
 
4236
    REQUEST_SIZE_MATCH(xGrabKeyReq);
 
4237
    if ((stuff->ownerEvents != xTrue) && (stuff->ownerEvents != xFalse))
 
4238
    {
 
4239
        client->errorValue = stuff->ownerEvents;
 
4240
        return(BadValue);
 
4241
    }
 
4242
    if ((stuff->pointerMode != GrabModeSync) &&
 
4243
        (stuff->pointerMode != GrabModeAsync))
 
4244
    {
 
4245
        client->errorValue = stuff->pointerMode;
 
4246
        return BadValue;
 
4247
    }
 
4248
    if ((stuff->keyboardMode != GrabModeSync) &&
 
4249
        (stuff->keyboardMode != GrabModeAsync))
 
4250
    {
 
4251
        client->errorValue = stuff->keyboardMode;
 
4252
        return BadValue;
 
4253
    }
 
4254
    if (((stuff->key > keybd->key->curKeySyms.maxKeyCode) ||
 
4255
         (stuff->key < keybd->key->curKeySyms.minKeyCode))
 
4256
        && (stuff->key != AnyKey))
 
4257
    {
 
4258
        client->errorValue = stuff->key;
 
4259
        return BadValue;
 
4260
    }
 
4261
    if ((stuff->modifiers != AnyModifier) &&
 
4262
        (stuff->modifiers & ~AllModifiersMask))
 
4263
    {
 
4264
        client->errorValue = stuff->modifiers;
 
4265
        return BadValue;
 
4266
    }
 
4267
    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
 
4268
    if (!pWin)
 
4269
        return BadWindow;
 
4270
 
 
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);
 
4276
    if (!grab)
 
4277
        return BadAlloc;
 
4278
    return AddPassiveGrabToList(grab);
 
4279
}
 
4280
 
 
4281
 
 
4282
int
 
4283
ProcGrabButton(client)
 
4284
    ClientPtr client;
 
4285
{
 
4286
    WindowPtr pWin, confineTo;
 
4287
    REQUEST(xGrabButtonReq);
 
4288
    CursorPtr cursor;
 
4289
    GrabPtr grab;
 
4290
 
 
4291
    REQUEST_SIZE_MATCH(xGrabButtonReq);
 
4292
    if ((stuff->pointerMode != GrabModeSync) &&
 
4293
        (stuff->pointerMode != GrabModeAsync))
 
4294
    {
 
4295
        client->errorValue = stuff->pointerMode;
 
4296
        return BadValue;
 
4297
    }
 
4298
    if ((stuff->keyboardMode != GrabModeSync) &&
 
4299
        (stuff->keyboardMode != GrabModeAsync))
 
4300
    {
 
4301
        client->errorValue = stuff->keyboardMode;
 
4302
        return BadValue;
 
4303
    }
 
4304
    if ((stuff->modifiers != AnyModifier) &&
 
4305
        (stuff->modifiers & ~AllModifiersMask))
 
4306
    {
 
4307
        client->errorValue = stuff->modifiers;
 
4308
        return BadValue;
 
4309
    }
 
4310
    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue))
 
4311
    {
 
4312
        client->errorValue = stuff->ownerEvents;
 
4313
        return BadValue;
 
4314
    }
 
4315
    if (stuff->eventMask & ~PointerGrabMask)
 
4316
    {
 
4317
        client->errorValue = stuff->eventMask;
 
4318
        return BadValue;
 
4319
    }
 
4320
    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
 
4321
    if (!pWin)
 
4322
        return BadWindow;
 
4323
    if (stuff->confineTo == None)
 
4324
       confineTo = NullWindow;
 
4325
    else {
 
4326
        confineTo = SecurityLookupWindow(stuff->confineTo, client,
 
4327
                                         SecurityReadAccess);
 
4328
        if (!confineTo)
 
4329
            return BadWindow;
 
4330
    }
 
4331
    if (stuff->cursor == None)
 
4332
        cursor = NullCursor;
 
4333
    else
 
4334
    {
 
4335
        cursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
 
4336
                                                RT_CURSOR, SecurityReadAccess);
 
4337
        if (!cursor)
 
4338
        {
 
4339
            client->errorValue = stuff->cursor;
 
4340
            return BadCursor;
 
4341
        }
 
4342
    }
 
4343
 
 
4344
 
 
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);
 
4352
    if (!grab)
 
4353
        return BadAlloc;
 
4354
    return AddPassiveGrabToList(grab);
 
4355
}
 
4356
 
 
4357
int
 
4358
ProcUngrabButton(client)
 
4359
    ClientPtr client;
 
4360
{
 
4361
    REQUEST(xUngrabButtonReq);
 
4362
    WindowPtr pWin;
 
4363
    GrabRec tempGrab;
 
4364
 
 
4365
    REQUEST_SIZE_MATCH(xUngrabButtonReq);
 
4366
    if ((stuff->modifiers != AnyModifier) &&
 
4367
        (stuff->modifiers & ~AllModifiersMask))
 
4368
    {
 
4369
        client->errorValue = stuff->modifiers;
 
4370
        return BadValue;
 
4371
    }
 
4372
    pWin = SecurityLookupWindow(stuff->grabWindow, client, SecurityReadAccess);
 
4373
    if (!pWin)
 
4374
        return BadWindow;
 
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;
 
4384
 
 
4385
    if (!DeletePassiveGrabFromList(&tempGrab))
 
4386
        return(BadAlloc);
 
4387
    return(Success);
 
4388
}
 
4389
 
 
4390
void
 
4391
DeleteWindowFromAnyEvents(pWin, freeResources)
 
4392
    WindowPtr           pWin;
 
4393
    Bool                freeResources;
 
4394
{
 
4395
    WindowPtr           parent;
 
4396
    DeviceIntPtr        mouse = inputInfo.pointer;
 
4397
    DeviceIntPtr        keybd = inputInfo.keyboard;
 
4398
    FocusClassPtr       focus = keybd->focus;
 
4399
    OtherClientsPtr     oc;
 
4400
    GrabPtr             passive;
 
4401
 
 
4402
 
 
4403
    /* Deactivate any grabs performed on this window, before making any
 
4404
        input focus changes. */
 
4405
 
 
4406
    if (mouse->grab &&
 
4407
        ((mouse->grab->window == pWin) || (mouse->grab->confineTo == pWin)))
 
4408
        (*mouse->DeactivateGrab)(mouse);
 
4409
 
 
4410
    /* Deactivating a keyboard grab should cause focus events. */
 
4411
 
 
4412
    if (keybd->grab && (keybd->grab->window == pWin))
 
4413
        (*keybd->DeactivateGrab)(keybd);
 
4414
 
 
4415
    /* If the focus window is a root window (ie. has no parent) then don't 
 
4416
        delete the focus from it. */
 
4417
    
 
4418
    if ((pWin == focus->win) && (pWin->parent != NullWindow))
 
4419
    {
 
4420
        int focusEventMode = NotifyNormal;
 
4421
 
 
4422
        /* If a grab is in progress, then alter the mode of focus events. */
 
4423
 
 
4424
        if (keybd->grab)
 
4425
            focusEventMode = NotifyWhileGrabbed;
 
4426
 
 
4427
        switch (focus->revert)
 
4428
        {
 
4429
        case RevertToNone:
 
4430
            DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
 
4431
            focus->win = NoneWin;
 
4432
            focus->traceGood = 0;
 
4433
            break;
 
4434
        case RevertToParent:
 
4435
            parent = pWin;
 
4436
            do
 
4437
            {
 
4438
                parent = parent->parent;
 
4439
                focus->traceGood--;
 
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
 
4445
   to None
 
4446
 */
 
4447
#ifdef NOTDEF
 
4448
              || clients[CLIENT_ID(parent->drawable.id)]->clientGone
 
4449
#endif
 
4450
                );
 
4451
            DoFocusEvents(keybd, pWin, parent, focusEventMode);
 
4452
            focus->win = parent;
 
4453
            focus->revert = RevertToNone;
 
4454
            break;
 
4455
        case RevertToPointerRoot:
 
4456
            DoFocusEvents(keybd, pWin, PointerRootWin, focusEventMode);
 
4457
            focus->win = PointerRootWin;
 
4458
            focus->traceGood = 0;
 
4459
            break;
 
4460
        }
 
4461
    }
 
4462
 
 
4463
    if (mouse->valuator->motionHintWindow == pWin)
 
4464
        mouse->valuator->motionHintWindow = NullWindow;
 
4465
 
 
4466
    if (freeResources)
 
4467
    {
 
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);
 
4474
     }
 
4475
#ifdef XINPUT
 
4476
    DeleteWindowFromAnyExtEvents(pWin, freeResources);
 
4477
#endif
 
4478
}
 
4479
 
 
4480
/* Call this whenever some window at or below pWin has changed geometry */
 
4481
 
 
4482
/*ARGSUSED*/
 
4483
void
 
4484
CheckCursorConfinement(pWin)
 
4485
    WindowPtr pWin;
 
4486
{
 
4487
    GrabPtr grab = inputInfo.pointer->grab;
 
4488
    WindowPtr confineTo;
 
4489
 
 
4490
#ifdef PANORAMIX
 
4491
    if(!noPanoramiXExtension && pWin->drawable.pScreen->myNum) return;
 
4492
#endif
 
4493
 
 
4494
    if (grab && (confineTo = grab->confineTo))
 
4495
    {
 
4496
        if (!BorderSizeNotEmpty(confineTo))
 
4497
            (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer);
 
4498
        else if ((pWin == confineTo) || IsParent(pWin, confineTo))
 
4499
            ConfineCursorToWindow(confineTo, TRUE, TRUE);
 
4500
    }
 
4501
}
 
4502
 
 
4503
Mask
 
4504
EventMaskForClient(pWin, client)
 
4505
    WindowPtr           pWin;
 
4506
    ClientPtr           client;
 
4507
{
 
4508
    register OtherClientsPtr    other;
 
4509
 
 
4510
    if (wClient (pWin) == client)
 
4511
        return pWin->eventMask;
 
4512
    for (other = wOtherClients(pWin); other; other = other->next)
 
4513
    {
 
4514
        if (SameClient(other, client))
 
4515
            return other->mask;
 
4516
    }
 
4517
    return 0;
 
4518
}
 
4519
 
 
4520
int
 
4521
ProcRecolorCursor(client)
 
4522
    ClientPtr client;
 
4523
{
 
4524
    CursorPtr pCursor;
 
4525
    int         nscr;
 
4526
    ScreenPtr   pscr;
 
4527
    Bool        displayed;
 
4528
    REQUEST(xRecolorCursorReq);
 
4529
 
 
4530
    REQUEST_SIZE_MATCH(xRecolorCursorReq);
 
4531
    pCursor = (CursorPtr)SecurityLookupIDByType(client, stuff->cursor,
 
4532
                                        RT_CURSOR, SecurityWriteAccess);
 
4533
    if ( !pCursor) 
 
4534
    {
 
4535
        client->errorValue = stuff->cursor;
 
4536
        return (BadCursor);
 
4537
    }
 
4538
 
 
4539
    pCursor->foreRed = stuff->foreRed;
 
4540
    pCursor->foreGreen = stuff->foreGreen;
 
4541
    pCursor->foreBlue = stuff->foreBlue;
 
4542
 
 
4543
    pCursor->backRed = stuff->backRed;
 
4544
    pCursor->backGreen = stuff->backGreen;
 
4545
    pCursor->backBlue = stuff->backBlue;
 
4546
 
 
4547
    for (nscr = 0; nscr < screenInfo.numScreens; nscr++)
 
4548
    {
 
4549
        pscr = screenInfo.screens[nscr];
 
4550
#ifdef PANORAMIX
 
4551
        if(!noPanoramiXExtension)
 
4552
            displayed = (pscr == sprite.screen);
 
4553
        else
 
4554
#endif
 
4555
            displayed = (pscr == sprite.hotPhys.pScreen);
 
4556
        ( *pscr->RecolorCursor)(pscr, pCursor,
 
4557
                                (pCursor == sprite.current) && displayed);
 
4558
    }
 
4559
    return (Success);
 
4560
}
 
4561
 
 
4562
void
 
4563
WriteEventsToClient(pClient, count, events)
 
4564
    ClientPtr   pClient;
 
4565
    int         count;
 
4566
    xEvent      *events;
 
4567
{
 
4568
#ifdef PANORAMIX
 
4569
    xEvent    eventCopy;
 
4570
#endif
 
4571
    xEvent    eventTo, *eventFrom;
 
4572
    int       i;
 
4573
 
 
4574
#ifdef XKB
 
4575
    if ((!noXkbExtension)&&(!XkbFilterEvents(pClient, count, events)))
 
4576
        return;
 
4577
#endif
 
4578
 
 
4579
#ifdef PANORAMIX
 
4580
    if(!noPanoramiXExtension && 
 
4581
       (panoramiXdataPtr[0].x || panoramiXdataPtr[0].y)) 
 
4582
    {
 
4583
        switch(events->u.u.type) {
 
4584
        case MotionNotify:
 
4585
        case ButtonPress:
 
4586
        case ButtonRelease:
 
4587
        case KeyPress:
 
4588
        case KeyRelease:
 
4589
        case EnterNotify:
 
4590
        case LeaveNotify:
 
4591
        /* 
 
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 
 
4595
        */
 
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) 
 
4602
            {
 
4603
                eventCopy.u.keyButtonPointer.eventX += panoramiXdataPtr[0].x;
 
4604
                eventCopy.u.keyButtonPointer.eventY += panoramiXdataPtr[0].y;
 
4605
            }
 
4606
            events = &eventCopy;
 
4607
            break;
 
4608
        default: break;
 
4609
        }
 
4610
    }
 
4611
#endif
 
4612
 
 
4613
    if (EventCallback)
 
4614
    {
 
4615
        EventInfoRec eventinfo;
 
4616
        eventinfo.client = pClient;
 
4617
        eventinfo.events = events;
 
4618
        eventinfo.count = count;
 
4619
        CallCallbacks(&EventCallback, (pointer)&eventinfo);
 
4620
    }
 
4621
    if(pClient->swapped)
 
4622
    {
 
4623
        for(i = 0; i < count; i++)
 
4624
        {
 
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);
 
4631
        }
 
4632
    }
 
4633
    else
 
4634
    {
 
4635
        (void)WriteToClient(pClient, count * sizeof(xEvent), (char *) events);
 
4636
    }
 
4637
}