~ubuntu-branches/ubuntu/intrepid/xserver-xgl/intrepid

« back to all changes in this revision

Viewing changes to Xi/exevents.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthew Garrett
  • Date: 2006-02-13 14:21:43 UTC
  • Revision ID: james.westby@ubuntu.com-20060213142143-mad6z9xzem7hzxz9
Tags: upstream-7.0.0
ImportĀ upstreamĀ versionĀ 7.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* $Xorg: exevents.c,v 1.4 2001/02/09 02:04:33 xorgcvs Exp $ */
 
2
/************************************************************
 
3
 
 
4
Copyright 1989, 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
Copyright 1989 by Hewlett-Packard Company, Palo Alto, California.
 
27
 
 
28
                        All Rights Reserved
 
29
 
 
30
Permission to use, copy, modify, and distribute this software and its
 
31
documentation for any purpose and without fee is hereby granted,
 
32
provided that the above copyright notice appear in all copies and that
 
33
both that copyright notice and this permission notice appear in
 
34
supporting documentation, and that the name of Hewlett-Packard not be
 
35
used in advertising or publicity pertaining to distribution of the
 
36
software without specific, written prior permission.
 
37
 
 
38
HEWLETT-PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 
39
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
 
40
HEWLETT-PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
 
41
ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
 
42
WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
 
43
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 
44
SOFTWARE.
 
45
 
 
46
********************************************************/
 
47
/* $XFree86: xc/programs/Xserver/Xi/exevents.c,v 3.10 2001/12/14 19:58:55 dawes Exp $ */
 
48
 
 
49
/********************************************************************
 
50
 *
 
51
 *  Routines to register and initialize extension input devices.
 
52
 *  This also contains ProcessOtherEvent, the routine called from DDX
 
53
 *  to route extension events.
 
54
 *
 
55
 */
 
56
 
 
57
#define  NEED_EVENTS
 
58
#ifdef HAVE_DIX_CONFIG_H
 
59
#include <dix-config.h>
 
60
#endif
 
61
 
 
62
#include <X11/X.h>
 
63
#include <X11/Xproto.h>
 
64
#include <X11/extensions/XI.h>
 
65
#include <X11/extensions/XIproto.h>
 
66
#include "inputstr.h"
 
67
#include "windowstr.h"
 
68
#include "miscstruct.h"
 
69
#include "region.h"
 
70
#include "exevents.h"
 
71
#include "extnsionst.h"
 
72
#include "extinit.h"                    /* LookupDeviceIntRec */
 
73
#include "exglobals.h"
 
74
#include "dixevents.h"                  /* DeliverFocusedEvent */
 
75
#include "dixgrabs.h"                   /* CreateGrab() */
 
76
 
 
77
#include "chgptr.h"
 
78
 
 
79
#define WID(w) ((w) ? ((w)->drawable.id) : 0)
 
80
#define AllModifiersMask ( \
 
81
        ShiftMask | LockMask | ControlMask | Mod1Mask | Mod2Mask | \
 
82
        Mod3Mask | Mod4Mask | Mod5Mask )
 
83
#define AllButtonsMask ( \
 
84
        Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
 
85
#define Motion_Filter(class) (DevicePointerMotionMask | \
 
86
                              (class)->state | (class)->motionMask)
 
87
 
 
88
static Bool             ShouldFreeInputMasks(
 
89
                                WindowPtr /* pWin */,
 
90
                                Bool /* ignoreSelectedEvents */
 
91
                                );
 
92
static Bool             MakeInputMasks (
 
93
                                WindowPtr /* pWin */
 
94
                                );
 
95
 
 
96
/**************************************************************************
 
97
 *
 
98
 * Procedures for extension device event routing.
 
99
 *
 
100
 */
 
101
 
 
102
void
 
103
RegisterOtherDevice (device)
 
104
    DeviceIntPtr device;
 
105
    {
 
106
    device->public.processInputProc = ProcessOtherEvent;
 
107
    device->public.realInputProc = ProcessOtherEvent;
 
108
    (device)->ActivateGrab = ActivateKeyboardGrab;
 
109
    (device)->DeactivateGrab = DeactivateKeyboardGrab;
 
110
    }
 
111
 
 
112
/*ARGSUSED*/
 
113
void
 
114
ProcessOtherEvent (xE, other, count)
 
115
    xEventPtr xE;
 
116
    register DeviceIntPtr other;
 
117
    int count;
 
118
    {
 
119
    register BYTE       *kptr;
 
120
    register int        i;
 
121
    register CARD16     modifiers;
 
122
    register CARD16     mask;
 
123
    GrabPtr             grab = other->grab;
 
124
    Bool                deactivateDeviceGrab = FALSE;
 
125
    int                 key = 0, bit = 0, rootX, rootY;
 
126
    ButtonClassPtr      b = other->button;
 
127
    KeyClassPtr         k = other->key;
 
128
    ValuatorClassPtr    v = other->valuator;
 
129
    deviceValuator      *xV = (deviceValuator *) xE;
 
130
 
 
131
    if (xE->u.u.type != DeviceValuator) {
 
132
        GetSpritePosition(&rootX, &rootY);
 
133
        xE->u.keyButtonPointer.rootX = rootX;
 
134
        xE->u.keyButtonPointer.rootY = rootY;
 
135
        key = xE->u.u.detail;
 
136
        NoticeEventTime(xE);
 
137
        xE->u.keyButtonPointer.state = inputInfo.keyboard->key->state | 
 
138
                    inputInfo.pointer->button->state;
 
139
        bit = 1 << (key & 7);
 
140
    }
 
141
    if (DeviceEventCallback)
 
142
    {
 
143
        DeviceEventInfoRec eventinfo;
 
144
        eventinfo.events = (xEventPtr) xE;
 
145
        eventinfo.count = count;
 
146
        CallCallbacks(&DeviceEventCallback, (pointer)&eventinfo);
 
147
    }
 
148
    for (i=1; i<count; i++)
 
149
        if ((++xV)->type == DeviceValuator)
 
150
            {
 
151
            int first = xV->first_valuator;
 
152
            int *axisvals;
 
153
 
 
154
            if (xV->num_valuators && (!v || (xV->num_valuators && (first + xV->num_valuators > v->numAxes))))
 
155
                FatalError("Bad valuators reported for device %s\n",other->name);
 
156
            xV->device_state = 0;
 
157
            if (k)
 
158
                xV->device_state |= k->state;
 
159
            if (b)
 
160
                xV->device_state |= b->state;
 
161
            if (v && v->axisVal)
 
162
                {
 
163
                axisvals = v->axisVal;
 
164
                switch (xV->num_valuators) {
 
165
                    case 6:
 
166
                        *(axisvals+first+5) = xV->valuator5;
 
167
                    case 5:
 
168
                        *(axisvals+first+4) = xV->valuator4;
 
169
                    case 4:
 
170
                        *(axisvals+first+3) = xV->valuator3;
 
171
                    case 3:
 
172
                        *(axisvals+first+2) = xV->valuator2;
 
173
                    case 2:
 
174
                        *(axisvals+first+1) = xV->valuator1;
 
175
                    case 1:
 
176
                        *(axisvals+first) = xV->valuator0;
 
177
                    case 0:
 
178
                    default:
 
179
                        break;
 
180
                    }
 
181
                }
 
182
            }
 
183
    
 
184
    if (xE->u.u.type == DeviceKeyPress)
 
185
        {
 
186
        modifiers = k->modifierMap[key];
 
187
        kptr = &k->down[key >> 3];
 
188
        if (*kptr & bit) /* allow ddx to generate multiple downs */
 
189
            {   
 
190
            if (!modifiers)
 
191
                {
 
192
                xE->u.u.type = DeviceKeyRelease;
 
193
                ProcessOtherEvent(xE, other, count);
 
194
                xE->u.u.type = DeviceKeyPress;
 
195
                /* release can have side effects, don't fall through */
 
196
                ProcessOtherEvent(xE, other, count);
 
197
                }
 
198
            return;
 
199
            }
 
200
        if (other->valuator)
 
201
            other->valuator->motionHintWindow = NullWindow;
 
202
        *kptr |= bit;
 
203
        k->prev_state = k->state;
 
204
        for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
 
205
            {
 
206
            if (mask & modifiers) 
 
207
                {
 
208
                /* This key affects modifier "i" */
 
209
                k->modifierKeyCount[i]++;
 
210
                k->state |= mask;
 
211
                modifiers &= ~mask;
 
212
                }
 
213
            }
 
214
        if (!grab && CheckDeviceGrabs(other, xE, 0, count))
 
215
            {
 
216
            other->activatingKey = key;
 
217
            return;
 
218
            }
 
219
        }
 
220
    else if (xE->u.u.type == DeviceKeyRelease)
 
221
        {
 
222
        kptr = &k->down[key >> 3];
 
223
        if (!(*kptr & bit)) /* guard against duplicates */
 
224
            return;
 
225
        modifiers = k->modifierMap[key];
 
226
        if (other->valuator)
 
227
            other->valuator->motionHintWindow = NullWindow;
 
228
        *kptr &= ~bit;
 
229
        k->prev_state = k->state;
 
230
        for (i = 0, mask = 1; modifiers; i++, mask <<= 1)
 
231
            {
 
232
            if (mask & modifiers) 
 
233
                {
 
234
                /* This key affects modifier "i" */
 
235
                if (--k->modifierKeyCount[i] <= 0) 
 
236
                    {
 
237
                    k->modifierKeyCount[i] = 0;
 
238
                    k->state &= ~mask;
 
239
                    }
 
240
                modifiers &= ~mask;
 
241
                }
 
242
            }
 
243
 
 
244
        if (other->fromPassiveGrab && (key == other->activatingKey))
 
245
            deactivateDeviceGrab = TRUE;
 
246
        }
 
247
    else if (xE->u.u.type == DeviceButtonPress)
 
248
        {
 
249
        kptr = &b->down[key >> 3];
 
250
        *kptr |= bit;
 
251
        if (other->valuator)
 
252
            other->valuator->motionHintWindow = NullWindow;
 
253
        b->buttonsDown++;
 
254
        b->motionMask = DeviceButtonMotionMask;
 
255
        xE->u.u.detail = b->map[key];
 
256
        if (xE->u.u.detail == 0)
 
257
             return;
 
258
        if (xE->u.u.detail <= 5)
 
259
            b->state |= (Button1Mask >> 1) << xE->u.u.detail;
 
260
        SetMaskForEvent(Motion_Filter(b),DeviceMotionNotify);
 
261
        if (!grab)
 
262
            if (CheckDeviceGrabs(other, xE, 0, count))
 
263
                return;
 
264
 
 
265
        }
 
266
    else if (xE->u.u.type == DeviceButtonRelease)
 
267
        {
 
268
        kptr = &b->down[key >> 3];
 
269
        *kptr &= ~bit;
 
270
        if (other->valuator)
 
271
            other->valuator->motionHintWindow = NullWindow;
 
272
        if (!--b->buttonsDown)
 
273
                b->motionMask = 0;
 
274
        xE->u.u.detail = b->map[key];
 
275
        if (xE->u.u.detail == 0)
 
276
            return;
 
277
        if (xE->u.u.detail <= 5)
 
278
            b->state &= ~((Button1Mask >> 1) << xE->u.u.detail);
 
279
        SetMaskForEvent(Motion_Filter(b),DeviceMotionNotify);
 
280
        if (!b->state && other->fromPassiveGrab)
 
281
            deactivateDeviceGrab = TRUE;
 
282
        }
 
283
    else if (xE->u.u.type == ProximityIn)
 
284
        other->valuator->mode &= ~OutOfProximity;
 
285
    else if (xE->u.u.type == ProximityOut)
 
286
        other->valuator->mode |= OutOfProximity;
 
287
 
 
288
    if (grab)
 
289
        DeliverGrabbedEvent(xE, other, deactivateDeviceGrab, count);
 
290
    else if (other->focus)
 
291
        DeliverFocusedEvent(other, xE, GetSpriteWindow(), count);
 
292
    else
 
293
        DeliverDeviceEvents(GetSpriteWindow(), xE, NullGrab, NullWindow,
 
294
                            other, count);
 
295
 
 
296
    if (deactivateDeviceGrab == TRUE)
 
297
        (*other->DeactivateGrab)(other);
 
298
    }
 
299
 
 
300
int
 
301
InitProximityClassDeviceStruct( DeviceIntPtr dev)
 
302
{
 
303
    register ProximityClassPtr proxc;
 
304
 
 
305
    proxc = (ProximityClassPtr)xalloc(sizeof(ProximityClassRec));
 
306
    if (!proxc)
 
307
        return FALSE;
 
308
    dev->proximity = proxc;
 
309
    return TRUE;
 
310
}
 
311
 
 
312
void
 
313
InitValuatorAxisStruct( DeviceIntPtr dev,
 
314
                                                int axnum,
 
315
                                                int minval,
 
316
                                                int maxval,
 
317
                                                int resolution,
 
318
                                                int min_res,
 
319
                                                int max_res )
 
320
{
 
321
    register AxisInfoPtr ax = dev->valuator->axes + axnum;
 
322
 
 
323
    ax->min_value = minval;
 
324
    ax->max_value = maxval;
 
325
    ax->resolution = resolution;
 
326
    ax->min_resolution = min_res;
 
327
    ax->max_resolution = max_res;
 
328
}
 
329
 
 
330
static void
 
331
FixDeviceStateNotify (
 
332
    DeviceIntPtr dev,
 
333
    deviceStateNotify *ev,
 
334
    KeyClassPtr k,
 
335
    ButtonClassPtr b,
 
336
    ValuatorClassPtr v,
 
337
    int first)
 
338
{
 
339
    ev->type = DeviceStateNotify;
 
340
    ev->deviceid = dev->id;
 
341
    ev->time = currentTime.milliseconds;
 
342
    ev->classes_reported = 0;
 
343
    ev->num_keys = 0;
 
344
    ev->num_buttons = 0;
 
345
    ev->num_valuators = 0;
 
346
 
 
347
    if (b) {
 
348
        ev->classes_reported |= (1 << ButtonClass);
 
349
        ev->num_buttons = b->numButtons;
 
350
        memmove((char *) &ev->buttons[0], (char *) b->down, 4);
 
351
        }
 
352
    else if (k) {
 
353
        ev->classes_reported |= (1 << KeyClass);
 
354
        ev->num_keys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode;
 
355
        memmove((char *) &ev->keys[0], (char *) k->down, 4);
 
356
        }
 
357
    if (v) {
 
358
        int nval = v->numAxes - first;
 
359
        ev->classes_reported |= (1 << ValuatorClass);
 
360
        ev->classes_reported |= (dev->valuator->mode << ModeBitsShift);
 
361
        ev->num_valuators = nval < 3 ? nval : 3;
 
362
        switch (ev->num_valuators) 
 
363
            {
 
364
            case 3:
 
365
                ev->valuator2 = v->axisVal[first+2];
 
366
            case 2:
 
367
                ev->valuator1 = v->axisVal[first+1];
 
368
            case 1:
 
369
                ev->valuator0 = v->axisVal[first];
 
370
            break;
 
371
            }
 
372
        }
 
373
    }
 
374
 
 
375
static void
 
376
FixDeviceValuator (
 
377
    DeviceIntPtr dev,
 
378
    deviceValuator *ev,
 
379
    ValuatorClassPtr v,
 
380
    int first)
 
381
{
 
382
    int nval = v->numAxes - first;
 
383
 
 
384
    ev->type = DeviceValuator;
 
385
    ev->deviceid = dev->id;
 
386
    ev->num_valuators = nval < 3 ? nval : 3;
 
387
    ev->first_valuator = first;
 
388
    switch (ev->num_valuators) {
 
389
        case 3:
 
390
            ev->valuator2 = v->axisVal[first+2];
 
391
        case 2:
 
392
            ev->valuator1 = v->axisVal[first+1];
 
393
        case 1:
 
394
            ev->valuator0 = v->axisVal[first];
 
395
        break;
 
396
        }
 
397
    first += ev->num_valuators;
 
398
    }
 
399
 
 
400
void
 
401
DeviceFocusEvent(dev, type, mode, detail, pWin)
 
402
    DeviceIntPtr dev;
 
403
    int type, mode, detail;
 
404
    register WindowPtr pWin;
 
405
    {
 
406
    deviceFocus event;
 
407
 
 
408
    if (type == FocusIn)
 
409
        type = DeviceFocusIn;
 
410
    else
 
411
        type = DeviceFocusOut;
 
412
 
 
413
    event.deviceid = dev->id;
 
414
    event.mode = mode;
 
415
    event.type = type;
 
416
    event.detail = detail;
 
417
    event.window = pWin->drawable.id;
 
418
    event.time = currentTime.milliseconds;
 
419
 
 
420
    (void) DeliverEventsToWindow(pWin, (xEvent *)&event, 1,
 
421
        DeviceFocusChangeMask, NullGrab, dev->id);
 
422
 
 
423
    if ((type == DeviceFocusIn) && 
 
424
        (wOtherInputMasks(pWin)) &&
 
425
        (wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask))
 
426
        {
 
427
        int                     evcount = 1;
 
428
        deviceStateNotify       *ev, *sev;
 
429
        deviceKeyStateNotify    *kev;
 
430
        deviceButtonStateNotify *bev;
 
431
 
 
432
        KeyClassPtr k;
 
433
        ButtonClassPtr b;
 
434
        ValuatorClassPtr v;
 
435
        int nval=0, nkeys=0, nbuttons=0, first=0;
 
436
 
 
437
        if ((b=dev->button) != NULL) {
 
438
            nbuttons = b->numButtons;
 
439
            if (nbuttons > 32)
 
440
                evcount++;
 
441
        }
 
442
        if ((k=dev->key) != NULL) {
 
443
            nkeys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode;
 
444
            if (nkeys > 32)
 
445
                evcount++;
 
446
            if (nbuttons > 0) {
 
447
                evcount++;
 
448
            }
 
449
        }
 
450
        if ((v=dev->valuator) != NULL) {
 
451
            nval = v->numAxes;
 
452
 
 
453
            if (nval > 3)
 
454
                evcount++;
 
455
            if (nval > 6) {
 
456
                if (!(k && b))
 
457
                    evcount++;
 
458
                if (nval > 9)
 
459
                    evcount += ((nval - 7) / 3);
 
460
            }
 
461
        }
 
462
 
 
463
        sev = ev = (deviceStateNotify *) xalloc(evcount * sizeof(xEvent));
 
464
        FixDeviceStateNotify (dev, ev, NULL, NULL, NULL, first);
 
465
 
 
466
        if (b != NULL) {
 
467
            FixDeviceStateNotify (dev, ev++, NULL, b, v, first);
 
468
            first += 3;
 
469
            nval -= 3;
 
470
            if (nbuttons > 32) {
 
471
                (ev-1)->deviceid |= MORE_EVENTS;
 
472
                bev = (deviceButtonStateNotify *) ev++; 
 
473
                bev->type = DeviceButtonStateNotify;
 
474
                bev->deviceid = dev->id;
 
475
                memmove((char *) &bev->buttons[0], (char *) &b->down[4], 28);
 
476
            }
 
477
            if (nval > 0) {
 
478
                (ev-1)->deviceid |= MORE_EVENTS;
 
479
                FixDeviceValuator (dev, (deviceValuator *) ev++, v, first);
 
480
                first += 3;
 
481
                nval -= 3;
 
482
            }
 
483
        }
 
484
 
 
485
        if (k != NULL) {
 
486
            FixDeviceStateNotify (dev, ev++, k, NULL, v, first);
 
487
            first += 3;
 
488
            nval -= 3;
 
489
            if (nkeys > 32) {
 
490
                (ev-1)->deviceid |= MORE_EVENTS;
 
491
                kev = (deviceKeyStateNotify *) ev++; 
 
492
                kev->type = DeviceKeyStateNotify;
 
493
                kev->deviceid = dev->id;
 
494
                memmove((char *) &kev->keys[0], (char *) &k->down[4], 28);
 
495
            }
 
496
            if (nval > 0) {
 
497
                (ev-1)->deviceid |= MORE_EVENTS;
 
498
                FixDeviceValuator (dev, (deviceValuator *) ev++, v, first);
 
499
                first += 3;
 
500
                nval -= 3;
 
501
            }
 
502
        }
 
503
 
 
504
        while (nval > 0) {
 
505
            FixDeviceStateNotify (dev, ev++, NULL, NULL, v, first);
 
506
            first += 3;
 
507
            nval -= 3;
 
508
            if (nval > 0) {
 
509
                (ev-1)->deviceid |= MORE_EVENTS;
 
510
                FixDeviceValuator (dev, (deviceValuator *) ev++, v, first);
 
511
                first += 3;
 
512
                nval -= 3;
 
513
            }
 
514
        }
 
515
 
 
516
        (void) DeliverEventsToWindow(pWin, (xEvent *)sev, evcount,
 
517
            DeviceStateNotifyMask, NullGrab, dev->id);
 
518
        xfree (sev);
 
519
        }
 
520
    }
 
521
 
 
522
int
 
523
GrabButton(
 
524
    ClientPtr client,
 
525
    DeviceIntPtr dev,
 
526
    BYTE this_device_mode,
 
527
    BYTE other_devices_mode,
 
528
    CARD16 modifiers,
 
529
    DeviceIntPtr modifier_device,
 
530
    CARD8 button,
 
531
    Window grabWindow,
 
532
    BOOL ownerEvents,
 
533
    Cursor rcursor,
 
534
    Window rconfineTo,
 
535
    Mask eventMask)
 
536
{
 
537
    WindowPtr pWin, confineTo;
 
538
    CursorPtr cursor;
 
539
    GrabPtr grab;
 
540
 
 
541
    if ((this_device_mode != GrabModeSync) &&
 
542
        (this_device_mode != GrabModeAsync))
 
543
    {
 
544
        client->errorValue = this_device_mode;
 
545
        return BadValue;
 
546
    }
 
547
    if ((other_devices_mode != GrabModeSync) &&
 
548
        (other_devices_mode != GrabModeAsync))
 
549
    {
 
550
        client->errorValue = other_devices_mode;
 
551
        return BadValue;
 
552
    }
 
553
    if ((modifiers != AnyModifier) &&
 
554
        (modifiers & ~AllModifiersMask))
 
555
    {
 
556
        client->errorValue = modifiers;
 
557
        return BadValue;
 
558
    }
 
559
    if ((ownerEvents != xFalse) && (ownerEvents != xTrue))
 
560
    {
 
561
        client->errorValue = ownerEvents;
 
562
        return BadValue;
 
563
    }
 
564
    pWin = LookupWindow(grabWindow, client);
 
565
    if (!pWin)
 
566
        return BadWindow;
 
567
    if (rconfineTo == None)
 
568
        confineTo = NullWindow;
 
569
    else
 
570
    {
 
571
        confineTo = LookupWindow(rconfineTo, client);
 
572
        if (!confineTo)
 
573
            return BadWindow;
 
574
    }
 
575
    if (rcursor == None)
 
576
        cursor = NullCursor;
 
577
    else
 
578
    {
 
579
        cursor = (CursorPtr)LookupIDByType(rcursor, RT_CURSOR);
 
580
        if (!cursor)
 
581
        {
 
582
            client->errorValue = rcursor;
 
583
            return BadCursor;
 
584
        }
 
585
    }
 
586
 
 
587
    grab = CreateGrab(client->index, dev, pWin, eventMask,
 
588
        (Bool)ownerEvents, (Bool) this_device_mode, (Bool)other_devices_mode,
 
589
        modifier_device, modifiers, DeviceButtonPress, button, confineTo, 
 
590
        cursor);
 
591
    if (!grab)
 
592
        return BadAlloc;
 
593
    return AddPassiveGrabToList(grab);
 
594
    }
 
595
 
 
596
int
 
597
GrabKey(
 
598
    ClientPtr client,
 
599
    DeviceIntPtr dev,
 
600
    BYTE this_device_mode,
 
601
    BYTE other_devices_mode,
 
602
    CARD16 modifiers,
 
603
    DeviceIntPtr modifier_device,
 
604
    CARD8 key,
 
605
    Window grabWindow,
 
606
    BOOL ownerEvents,
 
607
    Mask mask)
 
608
{
 
609
    WindowPtr pWin;
 
610
    GrabPtr grab;
 
611
    KeyClassPtr k = dev->key;
 
612
 
 
613
    if (k==NULL)
 
614
        return BadMatch;
 
615
    if ((other_devices_mode != GrabModeSync) &&
 
616
        (other_devices_mode != GrabModeAsync))
 
617
    {
 
618
        client->errorValue = other_devices_mode;
 
619
        return BadValue;
 
620
    }
 
621
    if ((this_device_mode != GrabModeSync) &&
 
622
        (this_device_mode != GrabModeAsync))
 
623
    {
 
624
        client->errorValue = this_device_mode;
 
625
        return BadValue;
 
626
    }
 
627
    if (((key > k->curKeySyms.maxKeyCode) || 
 
628
         (key < k->curKeySyms.minKeyCode))
 
629
        && (key != AnyKey))
 
630
    {
 
631
        client->errorValue = key;
 
632
        return BadValue;
 
633
    }
 
634
    if ((modifiers != AnyModifier) &&
 
635
        (modifiers & ~AllModifiersMask))
 
636
    {
 
637
        client->errorValue = modifiers;
 
638
        return BadValue;
 
639
    }
 
640
    if ((ownerEvents != xTrue) && (ownerEvents != xFalse))
 
641
    {
 
642
        client->errorValue = ownerEvents;
 
643
        return BadValue;
 
644
    }
 
645
    pWin = LookupWindow(grabWindow, client);
 
646
    if (!pWin)
 
647
        return BadWindow;
 
648
 
 
649
    grab = CreateGrab(client->index, dev, pWin, 
 
650
        mask, ownerEvents, this_device_mode, other_devices_mode, 
 
651
        modifier_device, modifiers, DeviceKeyPress, key, NullWindow, 
 
652
        NullCursor);
 
653
    if (!grab)
 
654
        return BadAlloc;
 
655
    return AddPassiveGrabToList(grab);
 
656
    }
 
657
 
 
658
int
 
659
SelectForWindow(dev, pWin, client, mask, exclusivemasks, validmasks)
 
660
        DeviceIntPtr dev;
 
661
        WindowPtr pWin;
 
662
        ClientPtr client;
 
663
        Mask mask;
 
664
        Mask exclusivemasks;
 
665
        Mask validmasks;
 
666
{
 
667
    int mskidx = dev->id;
 
668
    int i, ret;
 
669
    Mask check;
 
670
    InputClientsPtr others;
 
671
 
 
672
    if (mask & ~validmasks)
 
673
    {
 
674
        client->errorValue = mask;
 
675
        return BadValue;
 
676
    }
 
677
    check = (mask & exclusivemasks);
 
678
    if (wOtherInputMasks(pWin))
 
679
        {
 
680
        if (check & wOtherInputMasks(pWin)->inputEvents[mskidx])
 
681
            {                          /* It is illegal for two different
 
682
                                          clients to select on any of the
 
683
                                          events for maskcheck. However,
 
684
                                          it is OK, for some client to
 
685
                                          continue selecting on one of those
 
686
                                          events.  */
 
687
            for (others = wOtherInputMasks(pWin)->inputClients; others; 
 
688
                others = others->next)
 
689
                {
 
690
                if (!SameClient(others, client) && (check & 
 
691
                    others->mask[mskidx]))
 
692
                    return BadAccess;
 
693
                }
 
694
            }
 
695
        for (others = wOtherInputMasks(pWin)->inputClients; others; 
 
696
                others = others->next)
 
697
            {
 
698
            if (SameClient(others, client))
 
699
                {
 
700
                check = others->mask[mskidx];
 
701
                others->mask[mskidx] = mask;
 
702
                if (mask == 0)
 
703
                    {
 
704
                    for (i=0; i<EMASKSIZE; i++)
 
705
                        if (i != mskidx && others->mask[i] != 0)
 
706
                            break;
 
707
                    if (i == EMASKSIZE)
 
708
                        {
 
709
                        RecalculateDeviceDeliverableEvents(pWin);
 
710
                        if (ShouldFreeInputMasks(pWin, FALSE))
 
711
                            FreeResource(others->resource, RT_NONE);
 
712
                        return Success;
 
713
                        }
 
714
                    }
 
715
                goto maskSet;
 
716
                }
 
717
            }
 
718
        }
 
719
    check = 0;
 
720
    if ((ret = AddExtensionClient (pWin, client, mask, mskidx)) != Success)
 
721
        return ret;
 
722
maskSet: 
 
723
    if (dev->valuator)
 
724
        if ((dev->valuator->motionHintWindow == pWin) &&
 
725
            (mask & DevicePointerMotionHintMask) &&
 
726
            !(check & DevicePointerMotionHintMask) &&
 
727
            !dev->grab)
 
728
            dev->valuator->motionHintWindow = NullWindow;
 
729
    RecalculateDeviceDeliverableEvents(pWin);
 
730
    return Success;
 
731
}
 
732
 
 
733
int 
 
734
AddExtensionClient (pWin, client, mask, mskidx)
 
735
    WindowPtr pWin;
 
736
    ClientPtr client;
 
737
    Mask mask;
 
738
    int mskidx;
 
739
    {
 
740
    InputClientsPtr others;
 
741
 
 
742
    if (!pWin->optional && !MakeWindowOptional (pWin))
 
743
        return BadAlloc;
 
744
    others = (InputClients *) xalloc(sizeof(InputClients));
 
745
    if (!others)
 
746
        return BadAlloc;
 
747
    if (!pWin->optional->inputMasks && !MakeInputMasks (pWin))
 
748
        return BadAlloc;
 
749
    bzero((char *) &others->mask[0], sizeof(Mask)*EMASKSIZE);
 
750
    others->mask[mskidx] = mask;
 
751
    others->resource = FakeClientID(client->index);
 
752
    others->next = pWin->optional->inputMasks->inputClients;
 
753
    pWin->optional->inputMasks->inputClients = others;
 
754
    if (!AddResource(others->resource, RT_INPUTCLIENT, (pointer)pWin))
 
755
        return BadAlloc;
 
756
    return Success;
 
757
    }
 
758
 
 
759
static Bool
 
760
MakeInputMasks (pWin)
 
761
    WindowPtr   pWin;
 
762
    {
 
763
    struct _OtherInputMasks *imasks;
 
764
 
 
765
    imasks = (struct _OtherInputMasks *) 
 
766
        xalloc (sizeof (struct _OtherInputMasks));
 
767
    if (!imasks)
 
768
        return FALSE;
 
769
    bzero((char *) imasks, sizeof (struct _OtherInputMasks));
 
770
    pWin->optional->inputMasks = imasks;
 
771
    return TRUE;
 
772
    }
 
773
 
 
774
void
 
775
RecalculateDeviceDeliverableEvents(pWin)
 
776
    WindowPtr pWin;
 
777
    {
 
778
    register InputClientsPtr others;
 
779
    struct _OtherInputMasks *inputMasks;   /* default: NULL */
 
780
    register WindowPtr pChild, tmp;
 
781
    int i;
 
782
 
 
783
    pChild = pWin;
 
784
    while (1)
 
785
        {
 
786
        if ((inputMasks = wOtherInputMasks(pChild)) != 0)
 
787
            {
 
788
            for (others = inputMasks->inputClients; others; 
 
789
                others = others->next)
 
790
                {
 
791
                for (i=0; i<EMASKSIZE; i++)
 
792
                    inputMasks->inputEvents[i] |= others->mask[i];
 
793
                }
 
794
            for (i=0; i<EMASKSIZE; i++)
 
795
                inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i];
 
796
            for (tmp = pChild->parent; tmp; tmp=tmp->parent)
 
797
                if (wOtherInputMasks(tmp))
 
798
                    for (i=0; i<EMASKSIZE; i++)
 
799
                        inputMasks->deliverableEvents[i] |=
 
800
                        (wOtherInputMasks(tmp)->deliverableEvents[i] 
 
801
                        & ~inputMasks->dontPropagateMask[i] & PropagateMask[i]);
 
802
            }
 
803
        if (pChild->firstChild)
 
804
            {
 
805
            pChild = pChild->firstChild;
 
806
            continue;
 
807
            }
 
808
        while (!pChild->nextSib && (pChild != pWin))
 
809
            pChild = pChild->parent;
 
810
        if (pChild == pWin)
 
811
            break;
 
812
        pChild = pChild->nextSib;
 
813
        }
 
814
    }
 
815
 
 
816
int
 
817
InputClientGone(pWin, id)
 
818
    register WindowPtr pWin;
 
819
    XID   id;
 
820
    {
 
821
    register InputClientsPtr other, prev;
 
822
    if (!wOtherInputMasks(pWin))
 
823
        return(Success);
 
824
    prev = 0;
 
825
    for (other = wOtherInputMasks(pWin)->inputClients; other; 
 
826
        other = other->next)
 
827
        {
 
828
        if (other->resource == id)
 
829
            {
 
830
            if (prev)
 
831
                {
 
832
                prev->next = other->next;
 
833
                xfree(other);
 
834
                }
 
835
            else if (!(other->next))
 
836
                {
 
837
                if (ShouldFreeInputMasks(pWin, TRUE))
 
838
                    {
 
839
                    wOtherInputMasks(pWin)->inputClients = other->next;
 
840
                    xfree(wOtherInputMasks(pWin));
 
841
                    pWin->optional->inputMasks = (OtherInputMasks *) NULL;
 
842
                    CheckWindowOptionalNeed (pWin);
 
843
                    xfree(other);
 
844
                    }
 
845
                else
 
846
                    {
 
847
                    other->resource = FakeClientID(0);
 
848
                    if (!AddResource(other->resource, RT_INPUTCLIENT, 
 
849
                        (pointer)pWin))
 
850
                        return BadAlloc;
 
851
                    }
 
852
                }
 
853
            else
 
854
                {
 
855
                wOtherInputMasks(pWin)->inputClients = other->next;
 
856
                xfree(other);
 
857
                }
 
858
            RecalculateDeviceDeliverableEvents(pWin);
 
859
            return(Success);
 
860
            }
 
861
        prev = other;
 
862
        }
 
863
    FatalError("client not on device event list");
 
864
    /*NOTREACHED*/
 
865
    }
 
866
 
 
867
int
 
868
SendEvent (client, d, dest, propagate, ev, mask, count)
 
869
    ClientPtr           client;
 
870
    DeviceIntPtr        d;
 
871
    Window              dest;
 
872
    Bool                propagate;
 
873
    xEvent              *ev;
 
874
    Mask                mask;
 
875
    int                 count;
 
876
    {
 
877
    WindowPtr pWin;
 
878
    WindowPtr effectiveFocus = NullWindow; /* only set if dest==InputFocus */
 
879
    WindowPtr spriteWin=GetSpriteWindow();
 
880
 
 
881
    if (dest == PointerWindow)
 
882
        pWin = spriteWin;
 
883
    else if (dest == InputFocus)
 
884
    {
 
885
        WindowPtr inputFocus;
 
886
        
 
887
        if (!d->focus)
 
888
            inputFocus = spriteWin;
 
889
        else
 
890
            inputFocus = d->focus->win;
 
891
 
 
892
        if (inputFocus == FollowKeyboardWin)
 
893
            inputFocus = inputInfo.keyboard->focus->win;
 
894
 
 
895
        if (inputFocus == NoneWin)
 
896
            return Success;
 
897
 
 
898
        /* If the input focus is PointerRootWin, send the event to where
 
899
        the pointer is if possible, then perhaps propogate up to root. */
 
900
        if (inputFocus == PointerRootWin)
 
901
            inputFocus = GetCurrentRootWindow();
 
902
 
 
903
        if (IsParent(inputFocus, spriteWin))
 
904
        {
 
905
            effectiveFocus = inputFocus;
 
906
            pWin = spriteWin;
 
907
        }
 
908
        else
 
909
            effectiveFocus = pWin = inputFocus;
 
910
    }
 
911
    else
 
912
        pWin = LookupWindow(dest, client);
 
913
    if (!pWin)
 
914
        return BadWindow;
 
915
    if ((propagate != xFalse) && (propagate != xTrue))
 
916
    {
 
917
        client->errorValue = propagate;
 
918
        return BadValue;
 
919
    }
 
920
    ev->u.u.type |= 0x80;
 
921
    if (propagate)
 
922
    {
 
923
        for (;pWin; pWin = pWin->parent)
 
924
        {
 
925
            if (DeliverEventsToWindow( pWin, ev, count, mask, NullGrab, d->id))
 
926
                return Success;
 
927
            if (pWin == effectiveFocus)
 
928
                return Success;
 
929
            if (wOtherInputMasks(pWin))
 
930
                mask &= ~wOtherInputMasks(pWin)->dontPropagateMask[d->id];
 
931
            if (!mask)
 
932
                break;
 
933
        }
 
934
    }
 
935
    else
 
936
        (void)(DeliverEventsToWindow( pWin, ev, count, mask, NullGrab, d->id));
 
937
    return Success;
 
938
    }
 
939
 
 
940
int
 
941
SetButtonMapping (client, dev, nElts, map)
 
942
    ClientPtr client;
 
943
    DeviceIntPtr dev;
 
944
    int nElts;
 
945
    BYTE *map;
 
946
    {
 
947
    register int i;
 
948
    ButtonClassPtr b = dev->button;
 
949
 
 
950
    if (b == NULL)
 
951
        return BadMatch;
 
952
 
 
953
    if (nElts != b->numButtons)
 
954
    {
 
955
        client->errorValue = nElts;
 
956
        return BadValue;
 
957
    }
 
958
    if (BadDeviceMap(&map[0], nElts, 1, 255, &client->errorValue))
 
959
        return BadValue;
 
960
    for (i=0; i < nElts; i++)
 
961
        if ((b->map[i + 1] != map[i]) &&
 
962
                BitIsOn(b->down, i + 1))
 
963
            return MappingBusy;
 
964
    for (i = 0; i < nElts; i++)
 
965
        b->map[i + 1] = map[i];
 
966
    return Success;
 
967
    }
 
968
 
 
969
int 
 
970
SetModifierMapping(client, dev, len, rlen, numKeyPerModifier, inputMap, k)
 
971
    ClientPtr client;
 
972
    DeviceIntPtr dev;
 
973
    int len;
 
974
    int rlen;
 
975
    int numKeyPerModifier;
 
976
    KeyCode *inputMap;
 
977
    KeyClassPtr *k;
 
978
{
 
979
    KeyCode *map = NULL;
 
980
    int inputMapLen;
 
981
    register int i;
 
982
    
 
983
    *k = dev->key;
 
984
    if (*k == NULL)
 
985
        return BadMatch;
 
986
    if (len != ((numKeyPerModifier<<1) + rlen))
 
987
        return BadLength;
 
988
 
 
989
    inputMapLen = 8*numKeyPerModifier;
 
990
 
 
991
    /*
 
992
     *  Now enforce the restriction that "all of the non-zero keycodes must be
 
993
     *  in the range specified by min-keycode and max-keycode in the
 
994
     *  connection setup (else a Value error)"
 
995
     */
 
996
    i = inputMapLen;
 
997
    while (i--) {
 
998
        if (inputMap[i]
 
999
            && (inputMap[i] < (*k)->curKeySyms.minKeyCode
 
1000
                || inputMap[i] > (*k)->curKeySyms.maxKeyCode)) {
 
1001
                client->errorValue = inputMap[i];
 
1002
                return -1; /* BadValue collides with MappingFailed */
 
1003
                }
 
1004
    }
 
1005
 
 
1006
    /*
 
1007
     *  Now enforce the restriction that none of the old or new
 
1008
     *  modifier keys may be down while we change the mapping,  and
 
1009
     *  that the DDX layer likes the choice.
 
1010
     */
 
1011
    if (!AllModifierKeysAreUp (dev, (*k)->modifierKeyMap, 
 
1012
        (int)(*k)->maxKeysPerModifier, inputMap, (int)numKeyPerModifier)
 
1013
            ||
 
1014
        !AllModifierKeysAreUp(dev, inputMap, (int)numKeyPerModifier,
 
1015
              (*k)->modifierKeyMap, (int)(*k)->maxKeysPerModifier)) {
 
1016
        return MappingBusy;
 
1017
    } else {
 
1018
        for (i = 0; i < inputMapLen; i++) {
 
1019
            if (inputMap[i] && !LegalModifier(inputMap[i], (DevicePtr)dev)) {
 
1020
                return MappingFailed;
 
1021
            }
 
1022
        }
 
1023
    }
 
1024
 
 
1025
    /*
 
1026
     *  Now build the keyboard's modifier bitmap from the
 
1027
     *  list of keycodes.
 
1028
     */
 
1029
    if (inputMapLen) {
 
1030
        map = (KeyCode *)xalloc(inputMapLen);
 
1031
        if (!map)
 
1032
            return BadAlloc;
 
1033
    }
 
1034
    if ((*k)->modifierKeyMap)
 
1035
        xfree((*k)->modifierKeyMap);
 
1036
    if (inputMapLen) {
 
1037
        (*k)->modifierKeyMap = map;
 
1038
        memmove((char *)(*k)->modifierKeyMap, (char *)inputMap, inputMapLen);
 
1039
    } else
 
1040
        (*k)->modifierKeyMap = NULL;
 
1041
 
 
1042
    (*k)->maxKeysPerModifier = numKeyPerModifier;
 
1043
    for (i = 0; i < MAP_LENGTH; i++)
 
1044
        (*k)->modifierMap[i] = 0;
 
1045
    for (i = 0; i < inputMapLen; i++) if (inputMap[i]) {
 
1046
        (*k)->modifierMap[inputMap[i]]
 
1047
          |= (1<<(i/ (*k)->maxKeysPerModifier));
 
1048
    }
 
1049
 
 
1050
    return(MappingSuccess);
 
1051
    }
 
1052
 
 
1053
void
 
1054
SendDeviceMappingNotify(
 
1055
    CARD8 request,
 
1056
    KeyCode firstKeyCode,
 
1057
    CARD8 count,
 
1058
    DeviceIntPtr dev)
 
1059
{
 
1060
    xEvent event;
 
1061
    deviceMappingNotify         *ev = (deviceMappingNotify *) &event;
 
1062
 
 
1063
    ev->type = DeviceMappingNotify;
 
1064
    ev->request = request;
 
1065
    ev->deviceid = dev->id;
 
1066
    ev->time = currentTime.milliseconds;
 
1067
    if (request == MappingKeyboard)
 
1068
        {
 
1069
        ev->firstKeyCode = firstKeyCode;
 
1070
        ev->count = count;
 
1071
        }
 
1072
 
 
1073
    SendEventToAllWindows (dev, DeviceMappingNotifyMask, (xEvent *)ev, 1);
 
1074
    }
 
1075
 
 
1076
int
 
1077
ChangeKeyMapping(
 
1078
    ClientPtr   client,
 
1079
    DeviceIntPtr dev,
 
1080
    unsigned    len,
 
1081
    int         type,
 
1082
    KeyCode     firstKeyCode,
 
1083
    CARD8       keyCodes,
 
1084
    CARD8       keySymsPerKeyCode,
 
1085
    KeySym      *map)
 
1086
{
 
1087
    KeySymsRec keysyms;
 
1088
    KeyClassPtr k = dev->key;
 
1089
 
 
1090
    if (k == NULL)
 
1091
        return (BadMatch);
 
1092
 
 
1093
    if (len != (keyCodes * keySymsPerKeyCode))
 
1094
            return BadLength;
 
1095
 
 
1096
    if ((firstKeyCode < k->curKeySyms.minKeyCode) ||
 
1097
        (firstKeyCode + keyCodes - 1 > k->curKeySyms.maxKeyCode))
 
1098
    {
 
1099
            client->errorValue = firstKeyCode;
 
1100
            return BadValue;
 
1101
    }
 
1102
    if (keySymsPerKeyCode == 0)
 
1103
    {
 
1104
            client->errorValue = 0;
 
1105
            return BadValue;
 
1106
    }
 
1107
    keysyms.minKeyCode = firstKeyCode;
 
1108
    keysyms.maxKeyCode = firstKeyCode + keyCodes - 1;
 
1109
    keysyms.mapWidth = keySymsPerKeyCode;
 
1110
    keysyms.map = map;
 
1111
    if (!SetKeySymsMap(&k->curKeySyms, &keysyms))
 
1112
        return BadAlloc;
 
1113
    SendDeviceMappingNotify(MappingKeyboard, firstKeyCode, keyCodes,
 
1114
        dev);
 
1115
    return client->noClientException;
 
1116
    }
 
1117
 
 
1118
void
 
1119
DeleteWindowFromAnyExtEvents(pWin, freeResources)
 
1120
    WindowPtr           pWin;
 
1121
    Bool                freeResources;
 
1122
    {
 
1123
    int                 i;
 
1124
    DeviceIntPtr        dev;
 
1125
    InputClientsPtr     ic;
 
1126
    struct _OtherInputMasks *inputMasks;
 
1127
 
 
1128
    for (dev=inputInfo.devices; dev; dev=dev->next)
 
1129
        {
 
1130
        if (dev == inputInfo.pointer ||
 
1131
            dev == inputInfo.keyboard)
 
1132
            continue;
 
1133
        DeleteDeviceFromAnyExtEvents(pWin, dev);
 
1134
        }
 
1135
 
 
1136
    for (dev=inputInfo.off_devices; dev; dev=dev->next)
 
1137
        DeleteDeviceFromAnyExtEvents(pWin, dev);
 
1138
 
 
1139
    if (freeResources)
 
1140
        while ((inputMasks = wOtherInputMasks(pWin)) != 0)
 
1141
            {
 
1142
            ic = inputMasks->inputClients;
 
1143
            for (i=0; i<EMASKSIZE; i++)
 
1144
                inputMasks->dontPropagateMask[i] = 0;
 
1145
            FreeResource(ic->resource, RT_NONE);
 
1146
            }
 
1147
    }
 
1148
 
 
1149
void
 
1150
DeleteDeviceFromAnyExtEvents(pWin, dev)
 
1151
    WindowPtr           pWin;
 
1152
    DeviceIntPtr        dev;
 
1153
    {
 
1154
    WindowPtr           parent;
 
1155
 
 
1156
    /* Deactivate any grabs performed on this window, before making
 
1157
        any input focus changes.
 
1158
        Deactivating a device grab should cause focus events. */
 
1159
 
 
1160
    if (dev->grab && (dev->grab->window == pWin))
 
1161
        (*dev->DeactivateGrab)(dev);
 
1162
 
 
1163
    /* If the focus window is a root window (ie. has no parent) 
 
1164
        then don't delete the focus from it. */
 
1165
    
 
1166
    if (dev->focus && (pWin==dev->focus->win) && (pWin->parent != NullWindow))
 
1167
        {
 
1168
        int focusEventMode = NotifyNormal;
 
1169
 
 
1170
        /* If a grab is in progress, then alter the mode of focus events. */
 
1171
 
 
1172
        if (dev->grab)
 
1173
            focusEventMode = NotifyWhileGrabbed;
 
1174
 
 
1175
        switch (dev->focus->revert)
 
1176
            {
 
1177
            case RevertToNone:
 
1178
                DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
 
1179
                dev->focus->win = NoneWin;
 
1180
                dev->focus->traceGood = 0;
 
1181
                break;
 
1182
            case RevertToParent:
 
1183
                parent = pWin;
 
1184
                do
 
1185
                    {
 
1186
                    parent = parent->parent;
 
1187
                    dev->focus->traceGood--;
 
1188
                    } while (!parent->realized);
 
1189
                DoFocusEvents(dev, pWin, parent, focusEventMode);
 
1190
                dev->focus->win = parent;
 
1191
                dev->focus->revert = RevertToNone;
 
1192
                break;
 
1193
            case RevertToPointerRoot:
 
1194
                DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode);
 
1195
                dev->focus->win = PointerRootWin;
 
1196
                dev->focus->traceGood = 0;
 
1197
                break;
 
1198
            case RevertToFollowKeyboard:
 
1199
                if (inputInfo.keyboard->focus->win) {
 
1200
                    DoFocusEvents(dev, pWin, inputInfo.keyboard->focus->win,
 
1201
                                  focusEventMode);
 
1202
                    dev->focus->win = FollowKeyboardWin;
 
1203
                    dev->focus->traceGood = 0;
 
1204
                } else {
 
1205
                    DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
 
1206
                    dev->focus->win = NoneWin;
 
1207
                    dev->focus->traceGood = 0;
 
1208
                }
 
1209
                break;
 
1210
            }
 
1211
        }
 
1212
 
 
1213
    if (dev->valuator)
 
1214
        if (dev->valuator->motionHintWindow == pWin)
 
1215
            dev->valuator->motionHintWindow = NullWindow;
 
1216
    }
 
1217
 
 
1218
int
 
1219
MaybeSendDeviceMotionNotifyHint (pEvents, mask)
 
1220
    deviceKeyButtonPointer *pEvents;
 
1221
    Mask mask;
 
1222
    {
 
1223
    DeviceIntPtr dev;
 
1224
 
 
1225
    dev = LookupDeviceIntRec (pEvents->deviceid & DEVICE_BITS);
 
1226
    if (pEvents->type == DeviceMotionNotify)
 
1227
        {
 
1228
        if (mask & DevicePointerMotionHintMask)
 
1229
            {
 
1230
            if (WID(dev->valuator->motionHintWindow) == pEvents->event)
 
1231
                {
 
1232
                return 1; /* don't send, but pretend we did */
 
1233
                }
 
1234
            pEvents->detail = NotifyHint;
 
1235
            }
 
1236
         else
 
1237
            {
 
1238
            pEvents->detail = NotifyNormal;
 
1239
            }
 
1240
        }
 
1241
    return (0);
 
1242
    }
 
1243
 
 
1244
void
 
1245
CheckDeviceGrabAndHintWindow (pWin, type, xE, grab, client, deliveryMask)
 
1246
    WindowPtr pWin;
 
1247
    int type;
 
1248
    deviceKeyButtonPointer *xE;
 
1249
    GrabPtr grab;
 
1250
    ClientPtr client;
 
1251
    Mask deliveryMask;
 
1252
    {
 
1253
    DeviceIntPtr dev;
 
1254
 
 
1255
    dev = LookupDeviceIntRec (xE->deviceid & DEVICE_BITS);
 
1256
    if (type == DeviceMotionNotify)
 
1257
        dev->valuator->motionHintWindow = pWin;
 
1258
    else if ((type == DeviceButtonPress) && (!grab) && 
 
1259
        (deliveryMask & DeviceButtonGrabMask))
 
1260
        {
 
1261
        GrabRec tempGrab;
 
1262
 
 
1263
        tempGrab.device = dev;
 
1264
        tempGrab.resource = client->clientAsMask;
 
1265
        tempGrab.window = pWin;
 
1266
        tempGrab.ownerEvents = (deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE;
 
1267
        tempGrab.eventMask = deliveryMask;
 
1268
        tempGrab.keyboardMode = GrabModeAsync;
 
1269
        tempGrab.pointerMode = GrabModeAsync;
 
1270
        tempGrab.confineTo = NullWindow;
 
1271
        tempGrab.cursor = NullCursor;
 
1272
        (*dev->ActivateGrab)(dev, &tempGrab, currentTime, TRUE);
 
1273
        }
 
1274
    }
 
1275
 
 
1276
Mask
 
1277
DeviceEventMaskForClient(dev, pWin, client)
 
1278
    DeviceIntPtr        dev;
 
1279
    WindowPtr           pWin;
 
1280
    ClientPtr           client;
 
1281
    {
 
1282
    register InputClientsPtr other;
 
1283
 
 
1284
    if (!wOtherInputMasks(pWin))
 
1285
        return 0;
 
1286
    for (other = wOtherInputMasks(pWin)->inputClients; other; 
 
1287
        other = other->next)
 
1288
        {
 
1289
        if (SameClient(other, client))
 
1290
            return other->mask[dev->id];
 
1291
        }
 
1292
    return 0;
 
1293
    }
 
1294
 
 
1295
void
 
1296
MaybeStopDeviceHint(dev, client)
 
1297
    register DeviceIntPtr dev;
 
1298
    ClientPtr client;
 
1299
{
 
1300
    WindowPtr pWin;
 
1301
    GrabPtr grab = dev->grab;
 
1302
    pWin = dev->valuator->motionHintWindow;
 
1303
 
 
1304
    if ((grab && SameClient(grab, client) &&
 
1305
         ((grab->eventMask & DevicePointerMotionHintMask) ||
 
1306
          (grab->ownerEvents &&
 
1307
           (DeviceEventMaskForClient(dev, pWin, client) &
 
1308
            DevicePointerMotionHintMask)))) ||
 
1309
        (!grab &&
 
1310
         (DeviceEventMaskForClient(dev, pWin, client) &
 
1311
          DevicePointerMotionHintMask)))
 
1312
        dev->valuator->motionHintWindow = NullWindow;
 
1313
}
 
1314
 
 
1315
int
 
1316
DeviceEventSuppressForWindow(pWin, client, mask, maskndx)
 
1317
        WindowPtr pWin;
 
1318
        ClientPtr client;
 
1319
        Mask mask;
 
1320
        int maskndx;
 
1321
    {
 
1322
    struct _OtherInputMasks *inputMasks = wOtherInputMasks (pWin);
 
1323
 
 
1324
    if (mask & ~PropagateMask[maskndx])
 
1325
        {
 
1326
        client->errorValue = mask;
 
1327
        return BadValue;
 
1328
        }
 
1329
 
 
1330
    if (mask == 0) 
 
1331
        {
 
1332
        if (inputMasks)
 
1333
            inputMasks->dontPropagateMask[maskndx] = mask;
 
1334
        } 
 
1335
    else 
 
1336
        {
 
1337
        if (!inputMasks)
 
1338
            AddExtensionClient (pWin, client, 0, 0);
 
1339
        inputMasks = wOtherInputMasks(pWin);
 
1340
        inputMasks->dontPropagateMask[maskndx] = mask;
 
1341
        }
 
1342
    RecalculateDeviceDeliverableEvents(pWin);
 
1343
    if (ShouldFreeInputMasks(pWin, FALSE))
 
1344
        FreeResource(inputMasks->inputClients->resource, RT_NONE);
 
1345
    return Success;
 
1346
    }
 
1347
 
 
1348
static Bool
 
1349
ShouldFreeInputMasks (pWin, ignoreSelectedEvents)
 
1350
    WindowPtr pWin;
 
1351
    Bool ignoreSelectedEvents;
 
1352
    {
 
1353
    int i;
 
1354
    Mask allInputEventMasks = 0;
 
1355
    struct _OtherInputMasks *inputMasks = wOtherInputMasks (pWin);
 
1356
 
 
1357
    for (i=0; i<EMASKSIZE; i++)
 
1358
        allInputEventMasks |= inputMasks->dontPropagateMask[i];
 
1359
    if (!ignoreSelectedEvents)
 
1360
        for (i=0; i<EMASKSIZE; i++)
 
1361
            allInputEventMasks |= inputMasks->inputEvents[i];
 
1362
    if (allInputEventMasks == 0)
 
1363
        return TRUE;
 
1364
    else
 
1365
        return FALSE;
 
1366
    }