~darkxst/ubuntu/raring/xorg-server/lp1073724

« back to all changes in this revision

Viewing changes to dix/events.c

  • Committer: Package Import Robot
  • Author(s): Cyril Brulebois
  • Date: 2011-12-20 11:39:51 UTC
  • mto: (0.10.23) (1.1.48)
  • mto: This revision was merged to the branch mainline in revision 244.
  • Revision ID: package-import@ubuntu.com-20111220113951-cx9svdcnqpcta5wk
Tags: upstream-1.11.99.2
ImportĀ upstreamĀ versionĀ 1.11.99.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
190
190
static inline int
191
191
xi2_get_type(const xEvent *event)
192
192
{
193
 
    xGenericEvent* e = (xGenericEvent*)event;
 
193
    const xGenericEvent* e = (const xGenericEvent*)event;
194
194
 
195
195
    return (e->type != GenericEvent || e->extension != IReqCode) ? 0 : e->evtype;
196
196
}
367
367
 * time a button is pressed, the filter is modified to also contain the
368
368
 * matching ButtonXMotion mask.
369
369
 */
370
 
static Mask filters[MAXDEVICES][128];
 
370
Mask event_filters[MAXDEVICES][MAXEVENTS];
371
371
 
372
 
static const Mask default_filter[128] =
 
372
static const Mask default_filter[MAXEVENTS] =
373
373
{
374
374
        NoSuchEvent,                   /* 0 */
375
375
        NoSuchEvent,                   /* 1 */
408
408
        CantBeFiltered                 /* MappingNotify */
409
409
};
410
410
 
411
 
static inline Mask
412
 
GetEventFilterMask(DeviceIntPtr dev, int evtype)
413
 
{
414
 
    return filters[dev ? dev->id : 0][evtype];
415
 
}
416
 
 
417
 
static inline Mask
418
 
GetXI2EventFilterMask(int evtype)
419
 
{
420
 
    return (1 << (evtype % 8));
421
 
}
422
 
 
423
 
static inline int
424
 
GetXI2EventFilterOffset(int evtype)
425
 
{
426
 
    return (evtype / 8);
427
 
}
428
 
 
429
411
/**
430
412
 * For the given event, return the matching event filter. This filter may then
431
413
 * be AND'ed with the selected event mask.
447
429
    int evtype = 0;
448
430
 
449
431
    if (event->u.u.type != GenericEvent)
450
 
        return GetEventFilterMask(dev, event->u.u.type);
 
432
        return event_get_filter_from_type(dev, event->u.u.type);
451
433
    else if ((evtype = xi2_get_type(event)))
452
 
        return GetXI2EventFilterMask(evtype);
 
434
        return event_get_filter_from_xi2type(evtype);
453
435
    ErrorF("[dix] Unknown event type %d. No filter\n", event->u.u.type);
454
436
    return 0;
455
437
}
458
440
 * Return the single byte of the device's XI2 mask that contains the mask
459
441
 * for the event_type.
460
442
 */
461
 
static int
462
 
GetXI2MaskByte(unsigned char xi2mask[][XI2MASKSIZE], DeviceIntPtr dev, int event_type)
 
443
int
 
444
GetXI2MaskByte(XI2Mask *mask, DeviceIntPtr dev, int event_type)
463
445
{
464
 
    int byte = GetXI2EventFilterOffset(event_type);
465
 
    return xi2mask[dev->id][byte] |
466
 
           xi2mask[XIAllDevices][byte] |
467
 
           (IsMaster(dev) ? xi2mask[XIAllMasterDevices][byte] : 0);
 
446
    /* we just return the matching filter because that's the only use
 
447
     * for this mask anyway.
 
448
     */
 
449
    if (xi2mask_isset(mask, dev, event_type))
 
450
        return event_get_filter_from_xi2type(event_type);
 
451
    else
 
452
        return 0;
468
453
}
469
454
 
470
455
 
471
456
/**
472
 
 * Return the windows complete XI2 mask for the given XI2 event type.
 
457
 * @return TRUE if the mask is set for this event from this device on the
 
458
 * window, or FALSE otherwise.
473
459
 */
474
 
Mask
475
 
GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
 
460
Bool
 
461
WindowXI2MaskIsset(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
476
462
{
477
463
    OtherInputMasks *inputMasks = wOtherInputMasks(win);
478
 
    int filter;
479
464
    int evtype;
480
465
 
481
466
    if (!inputMasks || xi2_get_type(ev) == 0)
482
467
        return 0;
483
468
 
484
469
    evtype = ((xGenericEvent*)ev)->evtype;
485
 
    filter = GetEventFilter(dev, ev);
486
470
 
487
 
    return (GetXI2MaskByte(inputMasks->xi2mask, dev, evtype) & filter);
 
471
    return xi2mask_isset(inputMasks->xi2mask, dev, evtype);
488
472
}
489
473
 
490
474
Mask
683
667
{
684
668
    if (deviceid < 0 || deviceid >= MAXDEVICES)
685
669
        FatalError("SetMaskForEvent: bogus device id");
686
 
    filters[deviceid][event] = mask;
 
670
    event_filters[deviceid][event] = mask;
687
671
}
688
672
 
689
673
void
690
674
SetCriticalEvent(int event)
691
675
{
692
 
    if (event >= 128)
 
676
    if (event >= MAXEVENTS)
693
677
        FatalError("SetCriticalEvent: bogus event number");
694
678
    criticalEvents[event >> 3] |= 1 << (event & 7);
695
679
}
1131
1115
void
1132
1116
EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
1133
1117
{
1134
 
    QdEventPtr  tail = *syncEvents.pendtail;
 
1118
    QdEventPtr  tail;
1135
1119
    QdEventPtr  qe;
1136
1120
    SpritePtr   pSprite = device->spriteInfo->sprite;
1137
1121
    int         eventlen;
1138
1122
    DeviceEvent *event = &ev->device_event;
1139
1123
 
 
1124
    tail = list_last_entry(&syncEvents.pending, QdEventRec, next);
 
1125
 
1140
1126
    NoticeTime((InternalEvent*)event);
1141
1127
 
1142
1128
    /* Fix for key repeating bug. */
1195
1181
    qe = malloc(sizeof(QdEventRec) + eventlen);
1196
1182
    if (!qe)
1197
1183
        return;
1198
 
    qe->next = (QdEventPtr)NULL;
 
1184
    list_init(&qe->next);
1199
1185
    qe->device = device;
1200
1186
    qe->pScreen = pSprite->hotPhys.pScreen;
1201
1187
    qe->months = currentTime.months;
1202
1188
    qe->event = (InternalEvent *)(qe + 1);
1203
1189
    memcpy(qe->event, event, eventlen);
1204
 
    if (tail)
1205
 
        syncEvents.pendtail = &tail->next;
1206
 
    *syncEvents.pendtail = qe;
 
1190
    list_append(&qe->next, &syncEvents.pending);
1207
1191
}
1208
1192
 
1209
1193
/**
1215
1199
 * If there is none, we're done. If there is at least one device that is not
1216
1200
 * frozen, then re-run from the beginning of the event queue.
1217
1201
 */
1218
 
static void
 
1202
void
1219
1203
PlayReleasedEvents(void)
1220
1204
{
1221
 
    QdEventPtr *prev, qe;
 
1205
    QdEventPtr tmp;
 
1206
    QdEventPtr qe;
1222
1207
    DeviceIntPtr dev;
1223
1208
    DeviceIntPtr pDev;
1224
1209
 
1225
 
    prev = &syncEvents.pending;
1226
 
    while ( (qe = *prev) )
1227
 
    {
 
1210
restart:
 
1211
    list_for_each_entry_safe(qe, tmp, &syncEvents.pending, next) {
1228
1212
        if (!qe->device->deviceGrab.sync.frozen)
1229
1213
        {
1230
 
            *prev = qe->next;
1231
 
            pDev = qe->device;
1232
 
            if (*syncEvents.pendtail == *prev)
1233
 
                syncEvents.pendtail = prev;
 
1214
            list_del(&qe->next);
 
1215
            pDev = qe->device;
1234
1216
            if (qe->event->any.type == ET_Motion)
1235
1217
                CheckVirtualMotion(pDev, qe, NullWindow);
1236
1218
            syncEvents.time.months = qe->months;
1267
1249
                ;
1268
1250
            if (!dev)
1269
1251
                break;
 
1252
 
1270
1253
            /* Playing the event may have unfrozen another device. */
1271
1254
            /* So to play it safe, restart at the head of the queue */
1272
 
            prev = &syncEvents.pending;
 
1255
            goto restart;
1273
1256
        }
1274
 
        else
1275
 
            prev = &qe->next;
1276
1257
    }
1277
1258
}
1278
1259
 
1313
1294
    for (dev = inputInfo.devices; dev; dev = dev->next)
1314
1295
        FreezeThaw(dev, dev->deviceGrab.sync.other ||
1315
1296
                (dev->deviceGrab.sync.state >= FROZEN));
1316
 
    if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
 
1297
    if (syncEvents.playingEvents ||
 
1298
        (!replayDev && list_is_empty(&syncEvents.pending)))
1317
1299
        return;
1318
1300
    syncEvents.playingEvents = TRUE;
1319
1301
    if (replayDev)
1490
1472
    Bool isPassive = autoGrab & ~ImplicitGrabMask;
1491
1473
 
1492
1474
    /* slave devices need to float for the duration of the grab. */
1493
 
    if (grab->grabtype == GRABTYPE_XI2 &&
 
1475
    if (grab->grabtype == XI2 &&
1494
1476
        !(autoGrab & ImplicitGrabMask) && !IsMaster(mouse))
1495
1477
        DetachFromMaster(mouse);
1496
1478
 
1510
1492
        grabinfo->grabTime = time;
1511
1493
    if (grab->cursor)
1512
1494
        grab->cursor->refcnt++;
1513
 
    grabinfo->activeGrab = *grab;
1514
 
    grabinfo->grab = &grabinfo->activeGrab;
 
1495
    CopyGrab(grabinfo->activeGrab, grab);
 
1496
    grabinfo->grab = grabinfo->activeGrab;
1515
1497
    grabinfo->fromPassiveGrab = isPassive;
1516
1498
    grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
1517
1499
    PostNewCursor(mouse);
1549
1531
    if (grab->cursor)
1550
1532
        FreeCursor(grab->cursor, (Cursor)0);
1551
1533
 
1552
 
    if (!wasImplicit && grab->grabtype == GRABTYPE_XI2)
 
1534
    if (!wasImplicit && grab->grabtype == XI2)
1553
1535
        ReattachToOldMaster(mouse);
1554
1536
 
1555
1537
    ComputeFreezes();
1567
1549
    WindowPtr oldWin;
1568
1550
 
1569
1551
    /* slave devices need to float for the duration of the grab. */
1570
 
    if (grab->grabtype == GRABTYPE_XI2 &&
 
1552
    if (grab->grabtype == XI2 &&
1571
1553
        !(passive & ImplicitGrabMask) &&
1572
1554
        !IsMaster(keybd))
1573
1555
        DetachFromMaster(keybd);
1587
1569
        grabinfo->grabTime = syncEvents.time;
1588
1570
    else
1589
1571
        grabinfo->grabTime = time;
1590
 
    grabinfo->activeGrab = *grab;
1591
 
    grabinfo->grab = &grabinfo->activeGrab;
 
1572
    CopyGrab(grabinfo->activeGrab, grab);
 
1573
    grabinfo->grab = grabinfo->activeGrab;
1592
1574
    grabinfo->fromPassiveGrab = passive;
1593
1575
    grabinfo->implicitGrab = passive & ImplicitGrabMask;
1594
1576
    CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
1622
1604
    }
1623
1605
    DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);
1624
1606
 
1625
 
    if (!wasImplicit && grab->grabtype == GRABTYPE_XI2)
 
1607
    if (!wasImplicit && grab->grabtype == XI2)
1626
1608
        ReattachToOldMaster(keybd);
1627
1609
 
1628
1610
    ComputeFreezes();
1977
1959
ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
1978
1960
                     xEvent *event, Mask deliveryMask)
1979
1961
{
1980
 
    GrabRec tempGrab;
 
1962
    GrabPtr tempGrab;
1981
1963
    OtherInputMasks *inputMasks;
1982
1964
    CARD8 type = event->u.u.type;
1983
 
    GrabType grabtype;
 
1965
    enum InputLevel grabtype;
1984
1966
 
1985
1967
    if (type == ButtonPress)
1986
 
        grabtype = GRABTYPE_CORE;
 
1968
        grabtype = CORE;
1987
1969
    else if (type == DeviceButtonPress)
1988
 
        grabtype = GRABTYPE_XI;
 
1970
        grabtype = XI;
1989
1971
    else if ((type = xi2_get_type(event)) == XI_ButtonPress)
1990
 
        grabtype = GRABTYPE_XI2;
 
1972
        grabtype = XI2;
1991
1973
    else
1992
1974
        return FALSE;
1993
1975
 
1994
 
    memset(&tempGrab, 0, sizeof(GrabRec));
1995
 
    tempGrab.next = NULL;
1996
 
    tempGrab.device = dev;
1997
 
    tempGrab.resource = client->clientAsMask;
1998
 
    tempGrab.window = win;
1999
 
    tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
2000
 
    tempGrab.eventMask = deliveryMask;
2001
 
    tempGrab.keyboardMode = GrabModeAsync;
2002
 
    tempGrab.pointerMode = GrabModeAsync;
2003
 
    tempGrab.confineTo = NullWindow;
2004
 
    tempGrab.cursor = NullCursor;
2005
 
    tempGrab.type = type;
2006
 
    tempGrab.grabtype = grabtype;
 
1976
    tempGrab = AllocGrab();
 
1977
    if (!tempGrab)
 
1978
        return FALSE;
 
1979
    tempGrab->next = NULL;
 
1980
    tempGrab->device = dev;
 
1981
    tempGrab->resource = client->clientAsMask;
 
1982
    tempGrab->window = win;
 
1983
    tempGrab->ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
 
1984
    tempGrab->eventMask = deliveryMask;
 
1985
    tempGrab->keyboardMode = GrabModeAsync;
 
1986
    tempGrab->pointerMode = GrabModeAsync;
 
1987
    tempGrab->confineTo = NullWindow;
 
1988
    tempGrab->cursor = NullCursor;
 
1989
    tempGrab->type = type;
 
1990
    tempGrab->grabtype = grabtype;
2007
1991
 
2008
1992
    /* get the XI and XI2 device mask */
2009
1993
    inputMasks = wOtherInputMasks(win);
2010
 
    tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[dev->id]: 0;
 
1994
    tempGrab->deviceMask = (inputMasks) ? inputMasks->inputEvents[dev->id]: 0;
2011
1995
 
2012
1996
    if (inputMasks)
2013
 
        memcpy(tempGrab.xi2mask, inputMasks->xi2mask,
2014
 
               sizeof(tempGrab.xi2mask));
 
1997
        xi2mask_merge(tempGrab->xi2mask, inputMasks->xi2mask);
2015
1998
 
2016
 
    (*dev->deviceGrab.ActivateGrab)(dev, &tempGrab,
 
1999
    (*dev->deviceGrab.ActivateGrab)(dev, tempGrab,
2017
2000
                                    currentTime, TRUE | ImplicitGrabMask);
 
2001
    FreeGrab(tempGrab);
2018
2002
    return TRUE;
2019
2003
}
2020
2004
 
2021
 
enum EventDeliveryState {
2022
 
    EVENT_DELIVERED,     /**< Event has been delivered to a client  */
2023
 
    EVENT_NOT_DELIVERED, /**< Event was not delivered to any client */
2024
 
    EVENT_SKIP,          /**< Event can be discarded by the caller  */
2025
 
    EVENT_REJECTED,      /**< Event was rejected for delivery to the client */
2026
 
};
2027
 
 
2028
2005
/**
2029
2006
 * Attempt event delivery to the client owning the window.
2030
2007
 */
2075
2052
    {
2076
2053
        OtherInputMasks *inputMasks = wOtherInputMasks(win);
2077
2054
        /* Has any client selected for the event? */
2078
 
        if (!GetWindowXI2Mask(dev, win, events))
 
2055
        if (!WindowXI2MaskIsset(dev, win, events))
2079
2056
            goto out;
2080
2057
        *clients = inputMasks->inputClients;
2081
2058
    } else {
2543
2520
 * client.
2544
2521
 *
2545
2522
 * @param[in] dev The device this event is being sent for.
2546
 
 * @param[in] event The event that is to be sent.
 
2523
 * @param[in] evtype The event type of the event that is to be sent.
2547
2524
 * @param[in] win The current event window.
2548
2525
 *
2549
2526
 * @return Bitmask of ::EVENT_XI2_MASK, ::EVENT_XI1_MASK, ::EVENT_CORE_MASK, and
2550
2527
 *         ::EVENT_DONT_PROPAGATE_MASK.
2551
2528
 */
2552
2529
int
2553
 
EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win)
 
2530
EventIsDeliverable(DeviceIntPtr dev, int evtype, WindowPtr win)
2554
2531
{
2555
2532
    int rc = 0;
2556
2533
    int filter = 0;
2557
2534
    int type;
2558
2535
    OtherInputMasks *inputMasks = wOtherInputMasks(win);
2559
2536
 
2560
 
    if ((type = GetXI2Type(event)) != 0)
 
2537
    if ((type = GetXI2Type(evtype)) != 0)
2561
2538
    {
2562
 
        filter = GetXI2EventFilterMask(type);
2563
 
 
2564
 
        if (inputMasks &&
2565
 
            (GetXI2MaskByte(inputMasks->xi2mask,  dev, type) & filter))
 
2539
        if (inputMasks && xi2mask_isset(inputMasks->xi2mask, dev, type))
2566
2540
            rc |= EVENT_XI2_MASK;
2567
2541
    }
2568
2542
 
2569
 
    if ((type = GetXIType(event)) != 0)
 
2543
    if ((type = GetXIType(evtype)) != 0)
2570
2544
    {
2571
 
        filter = GetEventFilterMask(dev, type);
 
2545
        filter = event_get_filter_from_type(dev, type);
2572
2546
 
2573
2547
        /* Check for XI mask */
2574
2548
        if (inputMasks &&
2582
2556
 
2583
2557
    }
2584
2558
 
2585
 
    if ((type = GetCoreType(event)) != 0)
 
2559
    if ((type = GetCoreType(evtype)) != 0)
2586
2560
    {
2587
 
        filter = GetEventFilterMask(dev, type);
 
2561
        filter = event_get_filter_from_type(dev, type);
2588
2562
 
2589
2563
        /* Check for core mask */
2590
2564
        if ((win->deliverableEvents & filter) &&
2599
2573
    return rc;
2600
2574
}
2601
2575
 
 
2576
static int
 
2577
DeliverEvent(DeviceIntPtr dev, xEvent *xE, int count,
 
2578
             WindowPtr win, Window child, GrabPtr grab)
 
2579
{
 
2580
    SpritePtr pSprite = dev->spriteInfo->sprite;
 
2581
    Mask filter;
 
2582
    int deliveries = 0;
 
2583
 
 
2584
    if (XaceHook(XACE_SEND_ACCESS, NULL, dev, win, xE, count) == Success) {
 
2585
        filter = GetEventFilter(dev, xE);
 
2586
        FixUpEventFromWindow(pSprite, xE, win, child, FALSE);
 
2587
        deliveries = DeliverEventsToWindow(dev, win, xE, count,
 
2588
                filter, grab);
 
2589
    }
 
2590
 
 
2591
    return deliveries;
 
2592
}
 
2593
 
 
2594
static int
 
2595
DeliverOneEvent(InternalEvent *event, DeviceIntPtr dev, enum InputLevel level,
 
2596
                WindowPtr win, Window child, GrabPtr grab)
 
2597
{
 
2598
    xEvent *xE = NULL;
 
2599
    int count = 0;
 
2600
    int deliveries = 0;
 
2601
    int rc;
 
2602
 
 
2603
    switch(level)
 
2604
    {
 
2605
        case XI2:
 
2606
            rc = EventToXI2(event, &xE);
 
2607
            count = 1;
 
2608
            break;
 
2609
        case XI:
 
2610
            rc = EventToXI(event, &xE, &count);
 
2611
            break;
 
2612
        case CORE:
 
2613
            rc = EventToCore(event, &xE, &count);
 
2614
            break;
 
2615
    }
 
2616
 
 
2617
    if (rc == Success)
 
2618
    {
 
2619
        deliveries = DeliverEvent(dev, xE, count, win, child, grab);
 
2620
        free(xE);
 
2621
    } else
 
2622
        BUG_WARN_MSG(rc != BadMatch, "%s: conversion to level %d failed with rc %d\n",
 
2623
                     dev->name, level, rc);
 
2624
    return deliveries;
 
2625
}
 
2626
 
2602
2627
/**
2603
2628
 * Deliver events caused by input devices.
2604
2629
 *
2622
2647
DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
2623
2648
                    WindowPtr stopAt, DeviceIntPtr dev)
2624
2649
{
2625
 
    SpritePtr pSprite = dev->spriteInfo->sprite;
2626
2650
    Window child = None;
2627
 
    Mask filter;
2628
2651
    int deliveries = 0;
2629
 
    xEvent *xE = NULL, *core = NULL;
2630
 
    int rc, mask, count = 0;
 
2652
    int mask;
2631
2653
 
2632
2654
    verify_internal_event(event);
2633
2655
 
2634
2656
    while (pWin)
2635
2657
    {
2636
 
        if ((mask = EventIsDeliverable(dev, event, pWin)))
 
2658
        if ((mask = EventIsDeliverable(dev, event->any.type, pWin)))
2637
2659
        {
2638
2660
            /* XI2 events first */
2639
2661
            if (mask & EVENT_XI2_MASK)
2640
2662
            {
2641
 
                xEvent *xi2 = NULL;
2642
 
                rc = EventToXI2(event, &xi2);
2643
 
                if (rc == Success)
2644
 
                {
2645
 
                    /* XXX: XACE */
2646
 
                    filter = GetEventFilter(dev, xi2);
2647
 
                    FixUpEventFromWindow(pSprite, xi2, pWin, child, FALSE);
2648
 
                    deliveries = DeliverEventsToWindow(dev, pWin, xi2, 1,
2649
 
                                                       filter, grab);
2650
 
                    free(xi2);
2651
 
                    if (deliveries > 0)
2652
 
                        goto unwind;
2653
 
                } else if (rc != BadMatch)
2654
 
                    ErrorF("[dix] %s: XI2 conversion failed in DDE (%d).\n",
2655
 
                            dev->name, rc);
 
2663
                deliveries = DeliverOneEvent(event, dev, XI2, pWin, child, grab);
 
2664
                if (deliveries > 0)
 
2665
                    break;
2656
2666
            }
2657
2667
 
2658
2668
            /* XI events */
2659
2669
            if (mask & EVENT_XI1_MASK)
2660
2670
            {
2661
 
                rc = EventToXI(event, &xE, &count);
2662
 
                if (rc == Success) {
2663
 
                    if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, xE, count) == Success) {
2664
 
                        filter = GetEventFilter(dev, xE);
2665
 
                        FixUpEventFromWindow(pSprite, xE, pWin, child, FALSE);
2666
 
                        deliveries = DeliverEventsToWindow(dev, pWin, xE, count,
2667
 
                                                           filter, grab);
2668
 
                        if (deliveries > 0)
2669
 
                            goto unwind;
2670
 
                    }
2671
 
                } else if (rc != BadMatch)
2672
 
                    ErrorF("[dix] %s: XI conversion failed in DDE (%d, %d). Skipping delivery.\n",
2673
 
                            dev->name, event->any.type, rc);
 
2671
                deliveries = DeliverOneEvent(event, dev, XI, pWin, child, grab);
 
2672
                if (deliveries > 0)
 
2673
                    break;
2674
2674
            }
2675
2675
 
2676
2676
            /* Core event */
2677
2677
            if ((mask & EVENT_CORE_MASK) && IsMaster(dev) && dev->coreEvents)
2678
2678
            {
2679
 
                rc = EventToCore(event, &core, &count);
2680
 
                if (rc == Success) {
2681
 
                    if (XaceHook(XACE_SEND_ACCESS, NULL, dev, pWin, core, count) == Success) {
2682
 
                        filter = GetEventFilter(dev, core);
2683
 
                        FixUpEventFromWindow(pSprite, core, pWin, child, FALSE);
2684
 
                        deliveries = DeliverEventsToWindow(dev, pWin, core,
2685
 
                                                           count, filter, grab);
2686
 
                        if (deliveries > 0)
2687
 
                            goto unwind;
2688
 
                    }
2689
 
                } else if (rc != BadMatch)
2690
 
                        ErrorF("[dix] %s: Core conversion failed in DDE (%d, %d).\n",
2691
 
                                dev->name, event->any.type, rc);
2692
 
            }
2693
 
 
2694
 
            if ((deliveries < 0) || (pWin == stopAt) ||
2695
 
                (mask & EVENT_DONT_PROPAGATE_MASK))
2696
 
            {
2697
 
                deliveries = 0;
2698
 
                goto unwind;
2699
 
            }
 
2679
                deliveries = DeliverOneEvent(event, dev, CORE, pWin, child, grab);
 
2680
                if (deliveries > 0)
 
2681
                    break;
 
2682
            }
 
2683
 
 
2684
        }
 
2685
 
 
2686
        if ((deliveries < 0) || (pWin == stopAt) ||
 
2687
            (mask & EVENT_DONT_PROPAGATE_MASK))
 
2688
        {
 
2689
            deliveries = 0;
 
2690
            break;
2700
2691
        }
2701
2692
 
2702
2693
        child = pWin->drawable.id;
2703
2694
        pWin = pWin->parent;
2704
2695
    }
2705
2696
 
2706
 
unwind:
2707
 
    free(core);
2708
 
    free(xE);
2709
2697
    return deliveries;
2710
2698
}
2711
2699
 
3636
3624
}
3637
3625
 
3638
3626
/**
 
3627
 * Activate the given passive grab. If the grab is activated successfully, the
 
3628
 * event has been delivered to the client.
 
3629
 *
 
3630
 * @param device The device of the event to check.
 
3631
 * @param grab The grab to check.
 
3632
 * @param event The current device event.
 
3633
 *
 
3634
 * @return Whether the grab has been activated.
 
3635
 */
 
3636
Bool
 
3637
ActivatePassiveGrab(DeviceIntPtr device, GrabPtr grab, InternalEvent *event)
 
3638
{
 
3639
    SpritePtr pSprite = device->spriteInfo->sprite;
 
3640
    GrabInfoPtr grabinfo = &device->deviceGrab;
 
3641
    xEvent *xE = NULL;
 
3642
    int count;
 
3643
    int rc;
 
3644
 
 
3645
    /* The only consumers of corestate are Xi 1.x and core events, which
 
3646
     * are guaranteed to come from DeviceEvents. */
 
3647
    if (grab->grabtype == XI || grab->grabtype == CORE)
 
3648
    {
 
3649
        DeviceIntPtr gdev;
 
3650
 
 
3651
        event->device_event.corestate &= 0x1f00;
 
3652
 
 
3653
        if (grab->grabtype == CORE)
 
3654
            gdev = GetMaster(device, KEYBOARD_OR_FLOAT);
 
3655
        else
 
3656
            gdev = grab->modifierDevice;
 
3657
 
 
3658
        if (gdev && gdev->key && gdev->key->xkbInfo)
 
3659
            event->device_event.corestate |=
 
3660
                gdev->key->xkbInfo->state.grab_mods & (~0x1f00);
 
3661
    }
 
3662
 
 
3663
    if (grab->grabtype == CORE)
 
3664
    {
 
3665
        rc = EventToCore(event, &xE, &count);
 
3666
        if (rc != Success)
 
3667
        {
 
3668
            BUG_WARN_MSG(rc != BadMatch,"[dix] %s: core conversion failed"
 
3669
                         "(%d, %d).\n", device->name, event->any.type, rc);
 
3670
            return FALSE;
 
3671
        }
 
3672
    } else if (grab->grabtype == XI2)
 
3673
    {
 
3674
        rc = EventToXI2(event, &xE);
 
3675
        if (rc != Success)
 
3676
        {
 
3677
            if (rc != BadMatch)
 
3678
                BUG_WARN_MSG(rc != BadMatch,"[dix] %s: XI2 conversion failed"
 
3679
                             "(%d, %d).\n", device->name, event->any.type, rc);
 
3680
            return FALSE;
 
3681
        }
 
3682
        count = 1;
 
3683
    } else
 
3684
    {
 
3685
        rc = EventToXI(event, &xE, &count);
 
3686
        if (rc != Success)
 
3687
        {
 
3688
            if (rc != BadMatch)
 
3689
                BUG_WARN_MSG(rc != BadMatch,"[dix] %s: XI conversion failed"
 
3690
                             "(%d, %d).\n", device->name, event->any.type, rc);
 
3691
            return FALSE;
 
3692
        }
 
3693
    }
 
3694
 
 
3695
    (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
 
3696
 
 
3697
    if (xE)
 
3698
    {
 
3699
        FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
 
3700
 
 
3701
        /* XXX: XACE? */
 
3702
        TryClientEvents(rClient(grab), device, xE, count,
 
3703
                        GetEventFilter(device, xE),
 
3704
                        GetEventFilter(device, xE), grab);
 
3705
    }
 
3706
 
 
3707
    if (grabinfo->sync.state == FROZEN_NO_EVENT)
 
3708
        grabinfo->sync.state = FROZEN_WITH_EVENT;
 
3709
    *grabinfo->sync.event = event->device_event;
 
3710
 
 
3711
    free(xE);
 
3712
    return TRUE;
 
3713
}
 
3714
 
 
3715
static BOOL
 
3716
CoreGrabInterferes(DeviceIntPtr device, GrabPtr grab)
 
3717
{
 
3718
    DeviceIntPtr other;
 
3719
    BOOL interfering = FALSE;
 
3720
 
 
3721
    for (other = inputInfo.devices; other; other = other->next)
 
3722
    {
 
3723
        GrabPtr othergrab = other->deviceGrab.grab;
 
3724
        if (othergrab && othergrab->grabtype == CORE &&
 
3725
                SameClient(grab, rClient(othergrab)) &&
 
3726
                ((IsPointerDevice(grab->device) &&
 
3727
                  IsPointerDevice(othergrab->device)) ||
 
3728
                 (IsKeyboardDevice(grab->device) &&
 
3729
                  IsKeyboardDevice(othergrab->device))))
 
3730
        {
 
3731
            interfering = TRUE;
 
3732
            break;
 
3733
        }
 
3734
    }
 
3735
 
 
3736
    return interfering;
 
3737
}
 
3738
 
 
3739
enum MatchFlags {
 
3740
    NO_MATCH    = 0x0,
 
3741
    CORE_MATCH  = 0x1,
 
3742
    XI_MATCH    = 0x2,
 
3743
    XI2_MATCH   = 0x4,
 
3744
};
 
3745
 
 
3746
/**
 
3747
 * Match the grab against the temporary grab on the given input level.
 
3748
 * Modifies the temporary grab pointer.
 
3749
 *
 
3750
 * @param grab The grab to match against
 
3751
 * @param tmp The temporary grab to use for matching
 
3752
 * @param level The input level we want to match on
 
3753
 * @param event_type Wire protocol event type
 
3754
 *
 
3755
 * @return The respective matched flag or 0 for no match
 
3756
 */
 
3757
static enum MatchFlags
 
3758
MatchForType(const GrabPtr grab, GrabPtr tmp, enum InputLevel level, int event_type)
 
3759
{
 
3760
    enum MatchFlags match;
 
3761
    BOOL ignore_device = FALSE;
 
3762
    int grabtype;
 
3763
    int evtype;
 
3764
 
 
3765
    switch(level)
 
3766
    {
 
3767
        case XI2:
 
3768
            grabtype = XI2;
 
3769
            evtype = GetXI2Type(event_type);
 
3770
            BUG_WARN(!evtype);
 
3771
            match = XI2_MATCH;
 
3772
            break;
 
3773
        case XI:
 
3774
            grabtype = XI;
 
3775
            evtype = GetXIType(event_type);
 
3776
            match = XI_MATCH;
 
3777
            break;
 
3778
        case CORE:
 
3779
            grabtype = CORE;
 
3780
            evtype = GetCoreType(event_type);
 
3781
            match = CORE_MATCH;
 
3782
            ignore_device = TRUE;
 
3783
            break;
 
3784
    }
 
3785
 
 
3786
    tmp->grabtype = grabtype;
 
3787
    tmp->type = evtype;
 
3788
 
 
3789
    if (tmp->type && GrabMatchesSecond(tmp, grab, ignore_device))
 
3790
        return match;
 
3791
 
 
3792
    return NO_MATCH;
 
3793
}
 
3794
 
 
3795
/**
 
3796
 * Check an individual grab against an event to determine if a passive grab
 
3797
 * should be activated.
 
3798
 *
 
3799
 * @param device The device of the event to check.
 
3800
 * @param grab The grab to check.
 
3801
 * @param event The current device event.
 
3802
 * @param checkCore Check for core grabs too.
 
3803
 * @param tempGrab A pre-allocated temporary grab record for matching. This
 
3804
 *        must have the window and device values filled in.
 
3805
 *
 
3806
 * @return Whether the grab matches the event.
 
3807
 */
 
3808
static Bool
 
3809
CheckPassiveGrab(DeviceIntPtr device, GrabPtr grab, InternalEvent *event,
 
3810
                 Bool checkCore, GrabPtr tempGrab)
 
3811
{
 
3812
    DeviceIntPtr gdev;
 
3813
    XkbSrvInfoPtr xkbi = NULL;
 
3814
    enum MatchFlags match = 0;
 
3815
 
 
3816
    gdev = grab->modifierDevice;
 
3817
    if (grab->grabtype == CORE)
 
3818
    {
 
3819
        gdev = GetMaster(device, KEYBOARD_OR_FLOAT);
 
3820
    } else if (grab->grabtype == XI2)
 
3821
    {
 
3822
        /* if the device is an attached slave device, gdev must be the
 
3823
         * attached master keyboard. Since the slave may have been
 
3824
         * reattached after the grab, the modifier device may not be the
 
3825
         * same. */
 
3826
        if (!IsMaster(grab->device) && !IsFloating(device))
 
3827
            gdev = GetMaster(device, MASTER_KEYBOARD);
 
3828
    }
 
3829
 
 
3830
    if (gdev && gdev->key)
 
3831
        xkbi= gdev->key->xkbInfo;
 
3832
    tempGrab->modifierDevice = grab->modifierDevice;
 
3833
    tempGrab->modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
 
3834
 
 
3835
    /* Check for XI2 and XI grabs first */
 
3836
    match = MatchForType(grab, tempGrab, XI2, GetXI2Type(event->any.type));
 
3837
 
 
3838
    if (!match)
 
3839
        match = MatchForType(grab, tempGrab, XI, GetXIType(event->any.type));
 
3840
 
 
3841
    if (!match && checkCore)
 
3842
        match = MatchForType(grab, tempGrab, CORE, GetCoreType(event->any.type));
 
3843
 
 
3844
    if (!match || (grab->confineTo &&
 
3845
                   (!grab->confineTo->realized ||
 
3846
                    !BorderSizeNotEmpty(device, grab->confineTo))))
 
3847
        return FALSE;
 
3848
 
 
3849
    /* In some cases a passive core grab may exist, but the client
 
3850
     * already has a core grab on some other device. In this case we
 
3851
     * must not get the grab, otherwise we may never ungrab the
 
3852
     * device.
 
3853
     */
 
3854
 
 
3855
    if (grab->grabtype == CORE)
 
3856
    {
 
3857
        /* A passive grab may have been created for a different device
 
3858
           than it is assigned to at this point in time.
 
3859
           Update the grab's device and modifier device to reflect the
 
3860
           current state.
 
3861
           Since XGrabDeviceButton requires to specify the
 
3862
           modifierDevice explicitly, we don't override this choice.
 
3863
         */
 
3864
        if (grab->type < GenericEvent)
 
3865
        {
 
3866
            grab->device = device;
 
3867
            grab->modifierDevice = GetMaster(device, MASTER_KEYBOARD);
 
3868
        }
 
3869
 
 
3870
        if (CoreGrabInterferes(device, grab))
 
3871
            return FALSE;
 
3872
    }
 
3873
 
 
3874
    return TRUE;
 
3875
}
 
3876
 
 
3877
/**
3639
3878
 * "CheckPassiveGrabsOnWindow" checks to see if the event passed in causes a
3640
3879
 * passive grab set on the window to be activated.
3641
3880
 * If activate is true and a passive grab is found, it will be activated,
3656
3895
    BOOL checkCore,
3657
3896
    BOOL activate)
3658
3897
{
3659
 
    SpritePtr pSprite = device->spriteInfo->sprite;
3660
3898
    GrabPtr grab = wPassiveGrabs(pWin);
3661
 
    GrabRec tempGrab;
3662
 
    GrabInfoPtr grabinfo;
3663
 
#define CORE_MATCH      0x1
3664
 
#define XI_MATCH        0x2
3665
 
#define XI2_MATCH        0x4
3666
 
    int match = 0;
 
3899
    GrabPtr tempGrab;
3667
3900
 
3668
3901
    if (!grab)
3669
3902
        return NULL;
 
3903
 
 
3904
    tempGrab = AllocGrab();
 
3905
 
3670
3906
    /* Fill out the grab details, but leave the type for later before
3671
3907
     * comparing */
3672
3908
    switch (event->any.type)
3673
3909
    {
3674
3910
        case ET_KeyPress:
3675
3911
        case ET_KeyRelease:
3676
 
            tempGrab.detail.exact = event->device_event.detail.key;
 
3912
            tempGrab->detail.exact = event->device_event.detail.key;
3677
3913
            break;
3678
3914
        case ET_ButtonPress:
3679
3915
        case ET_ButtonRelease:
3680
 
            tempGrab.detail.exact = event->device_event.detail.button;
 
3916
            tempGrab->detail.exact = event->device_event.detail.button;
3681
3917
            break;
3682
3918
        default:
3683
 
            tempGrab.detail.exact = 0;
 
3919
            tempGrab->detail.exact = 0;
3684
3920
            break;
3685
3921
    }
3686
 
    tempGrab.window = pWin;
3687
 
    tempGrab.device = device;
3688
 
    tempGrab.detail.pMask = NULL;
3689
 
    tempGrab.modifiersDetail.pMask = NULL;
3690
 
    tempGrab.next = NULL;
 
3922
    tempGrab->window = pWin;
 
3923
    tempGrab->device = device;
 
3924
    tempGrab->detail.pMask = NULL;
 
3925
    tempGrab->modifiersDetail.pMask = NULL;
 
3926
    tempGrab->next = NULL;
 
3927
 
3691
3928
    for (; grab; grab = grab->next)
3692
3929
    {
3693
 
        DeviceIntPtr    gdev;
3694
 
        XkbSrvInfoPtr   xkbi = NULL;
3695
 
        xEvent *xE = NULL;
3696
 
        int count, rc;
3697
 
 
3698
 
        gdev= grab->modifierDevice;
3699
 
        if (grab->grabtype == GRABTYPE_CORE)
3700
 
        {
3701
 
            gdev = GetMaster(device, KEYBOARD_OR_FLOAT);
3702
 
        } else if (grab->grabtype == GRABTYPE_XI2)
3703
 
        {
3704
 
            /* if the device is an attached slave device, gdev must be the
3705
 
             * attached master keyboard. Since the slave may have been
3706
 
             * reattached after the grab, the modifier device may not be the
3707
 
             * same. */
3708
 
            if (!IsMaster(grab->device) && !IsFloating(device))
3709
 
                gdev = GetMaster(device, MASTER_KEYBOARD);
3710
 
        }
3711
 
 
3712
 
 
3713
 
        if (gdev && gdev->key)
3714
 
            xkbi= gdev->key->xkbInfo;
3715
 
        tempGrab.modifierDevice = grab->modifierDevice;
3716
 
        tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
3717
 
 
3718
 
        /* Check for XI2 and XI grabs first */
3719
 
        tempGrab.type = GetXI2Type(event);
3720
 
        tempGrab.grabtype = GRABTYPE_XI2;
3721
 
        if (GrabMatchesSecond(&tempGrab, grab, FALSE))
3722
 
            match = XI2_MATCH;
3723
 
 
3724
 
        if (!match)
3725
 
        {
3726
 
            tempGrab.grabtype = GRABTYPE_XI;
3727
 
            if ((tempGrab.type = GetXIType(event)) &&
3728
 
                (GrabMatchesSecond(&tempGrab, grab, FALSE)))
3729
 
                match = XI_MATCH;
3730
 
        }
3731
 
 
3732
 
        /* Check for a core grab (ignore the device when comparing) */
3733
 
        if (!match && checkCore)
3734
 
        {
3735
 
            tempGrab.grabtype = GRABTYPE_CORE;
3736
 
            if ((tempGrab.type = GetCoreType(event)) &&
3737
 
                (GrabMatchesSecond(&tempGrab, grab, TRUE)))
3738
 
                match = CORE_MATCH;
3739
 
        }
3740
 
 
3741
 
        if (!match || (grab->confineTo &&
3742
 
                       (!grab->confineTo->realized ||
3743
 
                        !BorderSizeNotEmpty(device, grab->confineTo))))
3744
 
            continue;
3745
 
 
3746
 
        grabinfo = &device->deviceGrab;
3747
 
        /* In some cases a passive core grab may exist, but the client
3748
 
         * already has a core grab on some other device. In this case we
3749
 
         * must not get the grab, otherwise we may never ungrab the
3750
 
         * device.
3751
 
         */
3752
 
 
3753
 
        if (grab->grabtype == GRABTYPE_CORE)
3754
 
        {
3755
 
            DeviceIntPtr other;
3756
 
            BOOL interfering = FALSE;
3757
 
 
3758
 
            /* A passive grab may have been created for a different device
3759
 
               than it is assigned to at this point in time.
3760
 
               Update the grab's device and modifier device to reflect the
3761
 
               current state.
3762
 
               Since XGrabDeviceButton requires to specify the
3763
 
               modifierDevice explicitly, we don't override this choice.
3764
 
               */
3765
 
            if (tempGrab.type < GenericEvent)
3766
 
            {
3767
 
                grab->device = device;
3768
 
                grab->modifierDevice = GetMaster(device, MASTER_KEYBOARD);
3769
 
            }
3770
 
 
3771
 
            for (other = inputInfo.devices; other; other = other->next)
3772
 
            {
3773
 
                GrabPtr othergrab = other->deviceGrab.grab;
3774
 
                if (othergrab && othergrab->grabtype == GRABTYPE_CORE &&
3775
 
                    SameClient(grab, rClient(othergrab)) &&
3776
 
                    ((IsPointerDevice(grab->device) &&
3777
 
                     IsPointerDevice(othergrab->device)) ||
3778
 
                     (IsKeyboardDevice(grab->device) &&
3779
 
                      IsKeyboardDevice(othergrab->device))))
3780
 
                {
3781
 
                    interfering = TRUE;
3782
 
                    break;
3783
 
                }
3784
 
            }
3785
 
            if (interfering)
3786
 
                continue;
3787
 
        }
3788
 
 
3789
 
        if (!activate)
3790
 
        {
3791
 
            return grab;
3792
 
        }
3793
 
        else if (!GetXIType(event) && !GetCoreType(event))
3794
 
        {
3795
 
            ErrorF("Event type %d in CheckPassiveGrabsOnWindow is neither"
3796
 
                   " XI 1.x nor core\n", event->any.type);
3797
 
            return NULL;
3798
 
        }
3799
 
 
3800
 
        /* The only consumers of corestate are Xi 1.x and core events, which
3801
 
         * are guaranteed to come from DeviceEvents. */
3802
 
        if (match & (XI_MATCH | CORE_MATCH))
3803
 
        {
3804
 
            event->device_event.corestate &= 0x1f00;
3805
 
            event->device_event.corestate |= tempGrab.modifiersDetail.exact &
3806
 
                                              (~0x1f00);
3807
 
        }
3808
 
 
3809
 
        if (match & CORE_MATCH)
3810
 
        {
3811
 
            rc = EventToCore(event, &xE, &count);
3812
 
            if (rc != Success)
3813
 
            {
3814
 
                if (rc != BadMatch)
3815
 
                    ErrorF("[dix] %s: core conversion failed in CPGFW "
3816
 
                            "(%d, %d).\n", device->name, event->any.type, rc);
3817
 
                continue;
3818
 
            }
3819
 
        } else if (match & XI2_MATCH)
3820
 
        {
3821
 
            rc = EventToXI2(event, &xE);
3822
 
            if (rc != Success)
3823
 
            {
3824
 
                if (rc != BadMatch)
3825
 
                    ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
3826
 
                            "(%d, %d).\n", device->name, event->any.type, rc);
3827
 
                continue;
3828
 
            }
3829
 
            count = 1;
3830
 
        } else
3831
 
        {
3832
 
            rc = EventToXI(event, &xE, &count);
3833
 
            if (rc != Success)
3834
 
            {
3835
 
                if (rc != BadMatch)
3836
 
                    ErrorF("[dix] %s: XI conversion failed in CPGFW "
3837
 
                            "(%d, %d).\n", device->name, event->any.type, rc);
3838
 
                continue;
3839
 
            }
3840
 
        }
3841
 
 
3842
 
        (*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
3843
 
 
3844
 
        if (xE)
3845
 
        {
3846
 
            FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
3847
 
 
3848
 
            /* XXX: XACE? */
3849
 
            TryClientEvents(rClient(grab), device, xE, count,
3850
 
                            GetEventFilter(device, xE),
3851
 
                            GetEventFilter(device, xE), grab);
3852
 
        }
3853
 
 
3854
 
        if (grabinfo->sync.state == FROZEN_NO_EVENT)
3855
 
        {
3856
 
            if (!grabinfo->sync.event)
3857
 
                grabinfo->sync.event = calloc(1, sizeof(DeviceEvent));
3858
 
            *grabinfo->sync.event = event->device_event;
3859
 
            grabinfo->sync.state = FROZEN_WITH_EVENT;
3860
 
        }
3861
 
 
3862
 
        free(xE);
3863
 
        return grab;
 
3930
        if (!CheckPassiveGrab(device, grab, event, checkCore, tempGrab))
 
3931
            continue;
 
3932
 
 
3933
        if (activate && !ActivatePassiveGrab(device, grab, event))
 
3934
            continue;
 
3935
 
 
3936
        break;
3864
3937
    }
3865
 
    return NULL;
3866
 
#undef CORE_MATCH
3867
 
#undef XI_MATCH
3868
 
#undef XI2_MATCH
 
3938
 
 
3939
    FreeGrab(tempGrab);
 
3940
    return grab;
3869
3941
}
3870
3942
 
3871
3943
/**
4051
4123
    return;
4052
4124
}
4053
4125
 
 
4126
 
 
4127
int
 
4128
DeliverOneGrabbedEvent(InternalEvent *event, DeviceIntPtr dev, enum InputLevel level)
 
4129
{
 
4130
    SpritePtr pSprite = dev->spriteInfo->sprite;
 
4131
    int rc;
 
4132
    xEvent *xE = NULL;
 
4133
    int count = 0;
 
4134
    int deliveries = 0;
 
4135
    Mask mask;
 
4136
    GrabInfoPtr grabinfo = &dev->deviceGrab;
 
4137
    GrabPtr grab = grabinfo->grab;
 
4138
    Mask filter;
 
4139
 
 
4140
    switch(level)
 
4141
    {
 
4142
        case XI2:
 
4143
            rc = EventToXI2(event, &xE);
 
4144
            count = 1;
 
4145
            if (rc == Success)
 
4146
            {
 
4147
                int evtype = xi2_get_type(xE);
 
4148
                mask = xi2mask_isset(grab->xi2mask, dev, evtype);
 
4149
                filter = 1;
 
4150
            }
 
4151
            break;
 
4152
        case XI:
 
4153
            if (grabinfo->fromPassiveGrab && grabinfo->implicitGrab)
 
4154
                mask = grab->deviceMask;
 
4155
            else
 
4156
                mask = grab->eventMask;
 
4157
            rc = EventToXI(event, &xE, &count);
 
4158
            if (rc == Success)
 
4159
                filter = GetEventFilter(dev, xE);
 
4160
            break;
 
4161
        case CORE:
 
4162
            rc = EventToCore(event, &xE, &count);
 
4163
            mask = grab->eventMask;
 
4164
            if (rc == Success)
 
4165
                filter = GetEventFilter(dev, xE);
 
4166
            break;
 
4167
        default:
 
4168
            BUG_WARN_MSG(1, "Invalid input level %d\n", level);
 
4169
            return 0;
 
4170
    }
 
4171
 
 
4172
    if (rc == Success)
 
4173
    {
 
4174
        FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
 
4175
        if (XaceHook(XACE_SEND_ACCESS, 0, dev,
 
4176
                    grab->window, xE, count) ||
 
4177
                XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
 
4178
                    grab->window, xE, count))
 
4179
            deliveries = 1; /* don't send, but pretend we did */
 
4180
        else if (level != CORE || !IsInterferingGrab(rClient(grab), dev, xE))
 
4181
        {
 
4182
            deliveries = TryClientEvents(rClient(grab), dev,
 
4183
                    xE, count, mask, filter,
 
4184
                    grab);
 
4185
        }
 
4186
    } else
 
4187
        BUG_WARN_MSG(rc != BadMatch, "%s: conversion to mode %d failed on %d with %d\n",
 
4188
                dev->name, level, event->any.type, rc);
 
4189
 
 
4190
    free(xE);
 
4191
    return deliveries;
 
4192
}
 
4193
 
 
4194
 
4054
4195
/**
4055
4196
 * Deliver an event from a device that is currently grabbed. Uses
4056
4197
 * DeliverDeviceEvents() for further delivery if a ownerEvents is set on the
4070
4211
    DeviceIntPtr dev;
4071
4212
    SpritePtr pSprite = thisDev->spriteInfo->sprite;
4072
4213
    BOOL sendCore = FALSE;
4073
 
    int rc, count = 0;
4074
 
    xEvent *xi = NULL;
4075
 
    xEvent *xi2 = NULL;
4076
 
    xEvent *core = NULL;
4077
4214
 
4078
4215
    grabinfo = &thisDev->deviceGrab;
4079
4216
    grab = grabinfo->grab;
4081
4218
    if (grab->ownerEvents)
4082
4219
    {
4083
4220
        WindowPtr focus;
 
4221
        WindowPtr win;
4084
4222
 
4085
4223
        /* Hack: Some pointer device have a focus class. So we need to check
4086
4224
         * for the type of event, to see if we really want to deliver it to
4097
4235
        else
4098
4236
            focus = PointerRootWin;
4099
4237
        if (focus == PointerRootWin)
4100
 
            deliveries = DeliverDeviceEvents(pSprite->win, event, grab,
4101
 
                                             NullWindow, thisDev);
4102
 
        else if (focus && (focus == pSprite->win ||
4103
 
                    IsParent(focus, pSprite->win)))
4104
 
            deliveries = DeliverDeviceEvents(pSprite->win, event, grab, focus,
4105
 
                                             thisDev);
 
4238
        {
 
4239
            win = pSprite->win;
 
4240
            focus = NullWindow;
 
4241
        } else if (focus && (focus == pSprite->win ||
 
4242
                    IsParent(focus, pSprite->win)))
 
4243
            win = pSprite->win;
4106
4244
        else if (focus)
4107
 
            deliveries = DeliverDeviceEvents(focus, event, grab, focus,
4108
 
                                             thisDev);
 
4245
            win = focus;
 
4246
 
 
4247
        deliveries = DeliverDeviceEvents(win, event, grab, focus, thisDev);
4109
4248
    }
4110
4249
    if (!deliveries)
4111
4250
    {
4112
 
        Mask mask;
4113
 
 
4114
4251
        /* XXX: In theory, we could pass the internal events through to
4115
4252
         * everything and only convert just before hitting the wire. We can't
4116
4253
         * do that yet, so DGE is the last stop for internal events. From here
4117
4254
         * onwards, we deal with core/XI events.
4118
4255
         */
4119
4256
 
4120
 
        mask = grab->eventMask;
4121
 
 
4122
4257
        sendCore = (IsMaster(thisDev) && thisDev->coreEvents);
4123
4258
        /* try core event */
4124
 
        if (sendCore && grab->grabtype == GRABTYPE_CORE)
4125
 
        {
4126
 
            rc = EventToCore(event, &core, &count);
4127
 
            if (rc == Success)
4128
 
            {
4129
 
                FixUpEventFromWindow(pSprite, core, grab->window, None, TRUE);
4130
 
                if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
4131
 
                            grab->window, core, count) ||
4132
 
                        XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
4133
 
                            grab->window, core, count))
4134
 
                    deliveries = 1; /* don't send, but pretend we did */
4135
 
                else if (!IsInterferingGrab(rClient(grab), thisDev, core))
4136
 
                {
4137
 
                    deliveries = TryClientEvents(rClient(grab), thisDev,
4138
 
                            core, count, mask,
4139
 
                            GetEventFilter(thisDev, core),
4140
 
                            grab);
4141
 
                }
4142
 
            } else if (rc != BadMatch)
4143
 
                ErrorF("[dix] DeliverGrabbedEvent. Core conversion failed.\n");
4144
 
        }
4145
 
 
4146
 
        if (!deliveries)
4147
 
        {
4148
 
            rc = EventToXI2(event, &xi2);
4149
 
            if (rc == Success)
4150
 
            {
4151
 
                int evtype = xi2_get_type(xi2);
4152
 
                mask = GetXI2MaskByte(grab->xi2mask, thisDev, evtype);
4153
 
                /* try XI2 event */
4154
 
                FixUpEventFromWindow(pSprite, xi2, grab->window, None, TRUE);
4155
 
                /* XXX: XACE */
4156
 
                deliveries = TryClientEvents(rClient(grab), thisDev, xi2, 1, mask,
4157
 
                        GetEventFilter(thisDev, xi2), grab);
4158
 
            } else if (rc != BadMatch)
4159
 
                ErrorF("[dix] %s: XI2 conversion failed in DGE (%d, %d). Skipping delivery.\n",
4160
 
                        thisDev->name, event->any.type, rc);
4161
 
        }
4162
 
 
4163
 
        if (!deliveries)
4164
 
        {
4165
 
            rc = EventToXI(event, &xi, &count);
4166
 
            if (rc == Success)
4167
 
            {
4168
 
                /* try XI event */
4169
 
                if (grabinfo->fromPassiveGrab  &&
4170
 
                        grabinfo->implicitGrab)
4171
 
                    mask = grab->deviceMask;
4172
 
                else
4173
 
                    mask = grab->eventMask;
4174
 
 
4175
 
                FixUpEventFromWindow(pSprite, xi, grab->window, None, TRUE);
4176
 
 
4177
 
                if (XaceHook(XACE_SEND_ACCESS, 0, thisDev,
4178
 
                            grab->window, xi, count) ||
4179
 
                        XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
4180
 
                            grab->window, xi, count))
4181
 
                    deliveries = 1; /* don't send, but pretend we did */
4182
 
                else
4183
 
                {
4184
 
                    deliveries =
4185
 
                        TryClientEvents(rClient(grab), thisDev,
4186
 
                                xi, count,
4187
 
                                mask,
4188
 
                                GetEventFilter(thisDev, xi),
4189
 
                                grab);
4190
 
                }
4191
 
            } else if (rc != BadMatch)
4192
 
                ErrorF("[dix] %s: XI conversion failed in DGE (%d, %d). Skipping delivery.\n",
4193
 
                        thisDev->name, event->any.type, rc);
 
4259
        if (sendCore && grab->grabtype == CORE)
 
4260
        {
 
4261
            deliveries = DeliverOneGrabbedEvent(event, thisDev, CORE);
 
4262
        }
 
4263
 
 
4264
        if (!deliveries)
 
4265
        {
 
4266
            deliveries = DeliverOneGrabbedEvent(event, thisDev, XI2);
 
4267
        }
 
4268
 
 
4269
        if (!deliveries)
 
4270
        {
 
4271
            deliveries = DeliverOneGrabbedEvent(event, thisDev, XI);
4194
4272
        }
4195
4273
 
4196
4274
        if (deliveries && (event->any.type == ET_Motion))
4216
4294
        case FREEZE_NEXT_EVENT:
4217
4295
            grabinfo->sync.state = FROZEN_WITH_EVENT;
4218
4296
            FreezeThaw(thisDev, TRUE);
4219
 
            if (!grabinfo->sync.event)
4220
 
                grabinfo->sync.event = calloc(1, sizeof(InternalEvent));
4221
4297
            *grabinfo->sync.event = event->device_event;
4222
4298
            break;
4223
4299
        }
4224
4300
    }
4225
4301
 
4226
 
    free(core);
4227
 
    free(xi);
4228
 
    free(xi2);
4229
 
 
4230
4302
    return deliveries;
4231
4303
}
4232
4304
 
4628
4700
    if (grab)
4629
4701
    {
4630
4702
        Mask mask;
4631
 
        mask = GetXI2MaskByte(grab->xi2mask, mouse, type);
4632
 
        TryClientEvents(rClient(grab), mouse, (xEvent*)event, 1, mask,
4633
 
                        filter, grab);
 
4703
        mask = xi2mask_isset(grab->xi2mask, mouse, type);
 
4704
        TryClientEvents(rClient(grab), mouse, (xEvent*)event, 1, mask, 1, grab);
4634
4705
    } else {
4635
 
        if (!GetWindowXI2Mask(mouse, pWin, (xEvent*)event))
 
4706
        if (!WindowXI2MaskIsset(mouse, pWin, (xEvent*)event))
4636
4707
            goto out;
4637
4708
        DeliverEventsToWindow(mouse, pWin, (xEvent*)event, 1, filter,
4638
4709
                              NullGrab);
4881
4952
 
4882
4953
    rc = GrabDevice(client, device, stuff->pointerMode, stuff->keyboardMode,
4883
4954
                    stuff->grabWindow, stuff->ownerEvents, stuff->time,
4884
 
                    &mask, GRABTYPE_CORE, stuff->cursor,
 
4955
                    &mask, CORE, stuff->cursor,
4885
4956
                    stuff->confineTo, &rep.status);
4886
4957
    if (rc != Success)
4887
4958
        return rc;
5079
5150
        *status = GrabFrozen;
5080
5151
    else
5081
5152
    {
5082
 
        GrabRec tempGrab;
5083
 
 
5084
 
        /* Otherwise segfaults happen on grabbed MPX devices */
5085
 
        memset(&tempGrab, 0, sizeof(GrabRec));
5086
 
 
5087
 
        tempGrab.next = NULL;
5088
 
        tempGrab.window = pWin;
5089
 
        tempGrab.resource = client->clientAsMask;
5090
 
        tempGrab.ownerEvents = ownerEvents;
5091
 
        tempGrab.keyboardMode = keyboard_mode;
5092
 
        tempGrab.pointerMode = pointer_mode;
5093
 
        if (grabtype == GRABTYPE_CORE)
5094
 
            tempGrab.eventMask = mask->core;
5095
 
        else if (grabtype == GRABTYPE_XI)
5096
 
            tempGrab.eventMask = mask->xi;
 
5153
        GrabPtr tempGrab;
 
5154
 
 
5155
        tempGrab = AllocGrab();
 
5156
 
 
5157
        tempGrab->next = NULL;
 
5158
        tempGrab->window = pWin;
 
5159
        tempGrab->resource = client->clientAsMask;
 
5160
        tempGrab->ownerEvents = ownerEvents;
 
5161
        tempGrab->keyboardMode = keyboard_mode;
 
5162
        tempGrab->pointerMode = pointer_mode;
 
5163
        if (grabtype == CORE)
 
5164
            tempGrab->eventMask = mask->core;
 
5165
        else if (grabtype == XI)
 
5166
            tempGrab->eventMask = mask->xi;
5097
5167
        else
5098
 
            memcpy(tempGrab.xi2mask, mask->xi2mask, sizeof(tempGrab.xi2mask));
5099
 
        tempGrab.device = dev;
5100
 
        tempGrab.cursor = cursor;
5101
 
        tempGrab.confineTo = confineTo;
5102
 
        tempGrab.grabtype = grabtype;
5103
 
        (*grabInfo->ActivateGrab)(dev, &tempGrab, time, FALSE);
 
5168
            xi2mask_merge(tempGrab->xi2mask, mask->xi2mask);
 
5169
        tempGrab->device = dev;
 
5170
        tempGrab->cursor = cursor;
 
5171
        tempGrab->confineTo = confineTo;
 
5172
        tempGrab->grabtype = grabtype;
 
5173
        (*grabInfo->ActivateGrab)(dev, tempGrab, time, FALSE);
5104
5174
        *status = GrabSuccess;
 
5175
 
 
5176
        FreeGrab(tempGrab);
5105
5177
    }
5106
5178
    return Success;
5107
5179
}
5127
5199
 
5128
5200
    result = GrabDevice(client, keyboard, stuff->pointerMode,
5129
5201
            stuff->keyboardMode, stuff->grabWindow, stuff->ownerEvents,
5130
 
            stuff->time, &mask, GRABTYPE_CORE, None, None,
 
5202
            stuff->time, &mask, CORE, None, None,
5131
5203
            &rep.status);
5132
5204
 
5133
5205
    if (result != Success)
5160
5232
    time = ClientTimeToServerTime(stuff->id);
5161
5233
    if ((CompareTimeStamps(time, currentTime) != LATER) &&
5162
5234
        (CompareTimeStamps(time, device->deviceGrab.grabTime) != EARLIER) &&
5163
 
        (grab) && SameClient(grab, client) && grab->grabtype == GRABTYPE_CORE)
 
5235
        (grab) && SameClient(grab, client) && grab->grabtype == CORE)
5164
5236
        (*device->deviceGrab.DeactivateGrab)(device);
5165
5237
    return Success;
5166
5238
}
5257
5329
InitEvents(void)
5258
5330
{
5259
5331
    int i;
 
5332
    QdEventPtr qe, tmp;
5260
5333
 
5261
5334
    inputInfo.numDevices = 0;
5262
5335
    inputInfo.devices = (DeviceIntPtr)NULL;
5265
5338
    inputInfo.pointer = (DeviceIntPtr)NULL;
5266
5339
    for (i = 0; i < MAXDEVICES; i++)
5267
5340
    {
5268
 
        memcpy(&filters[i], default_filter, sizeof(default_filter));
 
5341
        memcpy(&event_filters[i], default_filter, sizeof(default_filter));
5269
5342
    }
5270
5343
 
5271
5344
    syncEvents.replayDev = (DeviceIntPtr)NULL;
5272
5345
    syncEvents.replayWin = NullWindow;
5273
 
    while (syncEvents.pending)
5274
 
    {
5275
 
        QdEventPtr next = syncEvents.pending->next;
5276
 
        free(syncEvents.pending);
5277
 
        syncEvents.pending = next;
5278
 
    }
5279
 
    syncEvents.pendtail = &syncEvents.pending;
 
5346
    if (syncEvents.pending.next)
 
5347
        list_for_each_entry_safe(qe, tmp, &syncEvents.pending, next)
 
5348
            free(qe);
 
5349
    list_init(&syncEvents.pending);
5280
5350
    syncEvents.playingEvents = FALSE;
5281
5351
    syncEvents.time.months = 0;
5282
5352
    syncEvents.time.milliseconds = 0;   /* hardly matters */
5422
5492
{
5423
5493
    REQUEST(xUngrabKeyReq);
5424
5494
    WindowPtr pWin;
5425
 
    GrabRec tempGrab;
 
5495
    GrabPtr tempGrab;
5426
5496
    DeviceIntPtr keybd = PickKeyboard(client);
5427
5497
    int rc;
5428
5498
 
5444
5514
        client->errorValue = stuff->modifiers;
5445
5515
        return BadValue;
5446
5516
    }
5447
 
    tempGrab.resource = client->clientAsMask;
5448
 
    tempGrab.device = keybd;
5449
 
    tempGrab.window = pWin;
5450
 
    tempGrab.modifiersDetail.exact = stuff->modifiers;
5451
 
    tempGrab.modifiersDetail.pMask = NULL;
5452
 
    tempGrab.modifierDevice = keybd;
5453
 
    tempGrab.type = KeyPress;
5454
 
    tempGrab.grabtype = GRABTYPE_CORE;
5455
 
    tempGrab.detail.exact = stuff->key;
5456
 
    tempGrab.detail.pMask = NULL;
5457
 
    tempGrab.next = NULL;
5458
 
 
5459
 
    if (!DeletePassiveGrabFromList(&tempGrab))
5460
 
        return BadAlloc;
5461
 
    return Success;
 
5517
    tempGrab = AllocGrab();
 
5518
    if (!tempGrab)
 
5519
        return BadAlloc;
 
5520
    tempGrab->resource = client->clientAsMask;
 
5521
    tempGrab->device = keybd;
 
5522
    tempGrab->window = pWin;
 
5523
    tempGrab->modifiersDetail.exact = stuff->modifiers;
 
5524
    tempGrab->modifiersDetail.pMask = NULL;
 
5525
    tempGrab->modifierDevice = keybd;
 
5526
    tempGrab->type = KeyPress;
 
5527
    tempGrab->grabtype = CORE;
 
5528
    tempGrab->detail.exact = stuff->key;
 
5529
    tempGrab->detail.pMask = NULL;
 
5530
    tempGrab->next = NULL;
 
5531
 
 
5532
    if (!DeletePassiveGrabFromList(tempGrab))
 
5533
        rc = BadAlloc;
 
5534
 
 
5535
    FreeGrab(tempGrab);
 
5536
 
 
5537
    return rc;
5462
5538
}
5463
5539
 
5464
5540
/**
5481
5557
    REQUEST_SIZE_MATCH(xGrabKeyReq);
5482
5558
 
5483
5559
    memset(&param, 0, sizeof(param));
5484
 
    param.grabtype = GRABTYPE_CORE;
 
5560
    param.grabtype = CORE;
5485
5561
    param.ownerEvents = stuff->ownerEvents;
5486
5562
    param.this_device_mode = stuff->keyboardMode;
5487
5563
    param.other_devices_mode = stuff->pointerMode;
5505
5581
 
5506
5582
    mask.core = (KeyPressMask | KeyReleaseMask);
5507
5583
 
5508
 
    grab = CreateGrab(client->index, keybd, keybd, pWin, GRABTYPE_CORE, &mask,
 
5584
    grab = CreateGrab(client->index, keybd, keybd, pWin, CORE, &mask,
5509
5585
                      &param, KeyPress, stuff->key, NullWindow, NullCursor);
5510
5586
    if (!grab)
5511
5587
        return BadAlloc;
5596
5672
        return rc;
5597
5673
 
5598
5674
    memset(&param, 0, sizeof(param));
5599
 
    param.grabtype = GRABTYPE_CORE;
 
5675
    param.grabtype = CORE;
5600
5676
    param.ownerEvents = stuff->ownerEvents;
5601
5677
    param.this_device_mode = stuff->keyboardMode;
5602
5678
    param.other_devices_mode = stuff->pointerMode;
5605
5681
    mask.core = stuff->eventMask;
5606
5682
 
5607
5683
    grab = CreateGrab(client->index, ptr, modifierDevice, pWin,
5608
 
                      GRABTYPE_CORE, &mask, &param, ButtonPress,
 
5684
                      CORE, &mask, &param, ButtonPress,
5609
5685
                      stuff->button, confineTo, cursor);
5610
5686
    if (!grab)
5611
5687
        return BadAlloc;
5622
5698
{
5623
5699
    REQUEST(xUngrabButtonReq);
5624
5700
    WindowPtr pWin;
5625
 
    GrabRec tempGrab;
 
5701
    GrabPtr tempGrab;
5626
5702
    int rc;
5627
5703
    DeviceIntPtr ptr;
5628
5704
 
5639
5715
 
5640
5716
    ptr = PickPointer(client);
5641
5717
 
5642
 
    tempGrab.resource = client->clientAsMask;
5643
 
    tempGrab.device = ptr;
5644
 
    tempGrab.window = pWin;
5645
 
    tempGrab.modifiersDetail.exact = stuff->modifiers;
5646
 
    tempGrab.modifiersDetail.pMask = NULL;
5647
 
    tempGrab.modifierDevice = GetMaster(ptr, MASTER_KEYBOARD);
5648
 
    tempGrab.type = ButtonPress;
5649
 
    tempGrab.detail.exact = stuff->button;
5650
 
    tempGrab.grabtype = GRABTYPE_CORE;
5651
 
    tempGrab.detail.pMask = NULL;
5652
 
    tempGrab.next = NULL;
5653
 
 
5654
 
    if (!DeletePassiveGrabFromList(&tempGrab))
5655
 
        return BadAlloc;
5656
 
    return Success;
 
5718
    tempGrab = AllocGrab();
 
5719
    if (!tempGrab)
 
5720
        return BadAlloc;
 
5721
    tempGrab->resource = client->clientAsMask;
 
5722
    tempGrab->device = ptr;
 
5723
    tempGrab->window = pWin;
 
5724
    tempGrab->modifiersDetail.exact = stuff->modifiers;
 
5725
    tempGrab->modifiersDetail.pMask = NULL;
 
5726
    tempGrab->modifierDevice = GetMaster(ptr, MASTER_KEYBOARD);
 
5727
    tempGrab->type = ButtonPress;
 
5728
    tempGrab->detail.exact = stuff->button;
 
5729
    tempGrab->grabtype = CORE;
 
5730
    tempGrab->detail.pMask = NULL;
 
5731
    tempGrab->next = NULL;
 
5732
 
 
5733
    if (!DeletePassiveGrabFromList(tempGrab))
 
5734
        rc = BadAlloc;
 
5735
 
 
5736
    FreeGrab(tempGrab);
 
5737
    return rc;
5657
5738
}
5658
5739
 
5659
5740
/**
6052
6133
    for(it = inputInfo.devices; it; it = it->next)
6053
6134
    {
6054
6135
        GrabPtr grab = it->deviceGrab.grab;
6055
 
        if (grab && grab->grabtype == GRABTYPE_CORE && SameClient(grab, client))
 
6136
        if (grab && grab->grabtype == CORE && SameClient(grab, client))
6056
6137
        {
6057
6138
            it = GetMaster(it, MASTER_POINTER);
6058
6139
            return it; /* Always return a core grabbed device */