Commit message: dix: Disallow GenericEvent in SendEvent request.

The SendEvent request holds xEvent which is exactly 32 bytes long, no more,
no less. Both ProcSendEvent and SProcSendEvent verify that the received data
exactly match the request size. However nothing stops the client from passing
in event with xEvent::type = GenericEvent and any value of
xGenericEvent::length.

In the case of ProcSendEvent, the event will be eventually passed to
WriteEventsToClient which will see that it is Generic event and copy the
arbitrary length from the receive buffer (and possibly past it) and send it to
the other client. This allows clients to copy unitialized heap memory out of X
server or to crash it.

In case of SProcSendEvent, it will attempt to swap the incoming event by
calling a swapping function from the EventSwapVector array. The swapped event
is written to target buffer, which in this case is local xEvent variable. The
xEvent variable is 32 bytes long, but the swapping functions for GenericEvents
expect that the target buffer has size matching the size of the source
GenericEvent. This allows clients to cause stack buffer overflows.

Signed-off-by: Michal Srb <msrb@suse.com>
Reviewed-by: Peter Hutterer <peter.hutterer@who-t.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
CVE: CVE-2017-10971
CWE: CWE-119
Vulnerability description: In the X.Org X server before 2017-06-19, a user authenticated to an X Session could crash or execute code in the context of the X Server by exploiting a stack overflow in the endianness conversion of X Events.

Project: xserver
File: events.c

ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
{
    BOOL rc = FALSE;
    DeviceEvent event;

    if (dev->deviceGrab.grab) {
        if (!dev->deviceGrab.fromPassiveGrab ||
            dev->deviceGrab.grab->type != XI_Enter ||
            dev->deviceGrab.grab->window == win ||
            IsParent(dev->deviceGrab.grab->window, win))
            return FALSE;
        DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab);
        (*dev->deviceGrab.DeactivateGrab) (dev);
    }

    event = (DeviceEvent) {
        .header = ET_Internal,
        .type = ET_Enter,
        .length = sizeof(DeviceEvent),
        .time = GetTimeInMillis(),
        .deviceid = dev->id,
        .sourceid = dev->id,
        .detail.button = 0
    };
    rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE,
                                    TRUE) != NULL);
    if (rc)
        DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab);
    return rc;
}

Project: xserver
File: events.c

ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
{
    BOOL rc = FALSE;
    DeviceEvent event;

    if (dev->deviceGrab.grab) {
        if (!dev->deviceGrab.fromPassiveGrab ||
            dev->deviceGrab.grab->type != XI_FocusIn ||
            dev->deviceGrab.grab->window == win ||
            IsParent(dev->deviceGrab.grab->window, win))
            return FALSE;
        DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab);
        (*dev->deviceGrab.DeactivateGrab) (dev);
    }

    if (win == NoneWin || win == PointerRootWin)
        return FALSE;

    event = (DeviceEvent) {
        .header = ET_Internal,
        .type = ET_FocusIn,
        .length = sizeof(DeviceEvent),
        .time = GetTimeInMillis(),
        .deviceid = dev->id,
        .sourceid = dev->id,
        .detail.button = 0
    };
    rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE,
                                    TRUE) != NULL);
    if (rc)
        DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab);
    return rc;
}

Project: xserver
File: events.c

ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
                     xEvent *event, Mask deliveryMask)
{
    GrabPtr tempGrab;
    OtherInputMasks *inputMasks;
    CARD8 type = event->u.u.type;
    enum InputLevel grabtype;

    if (type == ButtonPress)
        grabtype = CORE;
    else if (type == DeviceButtonPress)
        grabtype = XI;
    else if ((type = xi2_get_type(event)) == XI_ButtonPress)
        grabtype = XI2;
    else
        return FALSE;

    tempGrab = AllocGrab(NULL);
    if (!tempGrab)
        return FALSE;
    tempGrab->next = NULL;
    tempGrab->device = dev;
    tempGrab->resource = client->clientAsMask;
    tempGrab->window = win;
    tempGrab->ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
    tempGrab->eventMask = deliveryMask;
    tempGrab->keyboardMode = GrabModeAsync;
    tempGrab->pointerMode = GrabModeAsync;
    tempGrab->confineTo = NullWindow;
    tempGrab->cursor = NullCursor;
    tempGrab->type = type;
    tempGrab->grabtype = grabtype;

    /* get the XI and XI2 device mask */
    inputMasks = wOtherInputMasks(win);
    tempGrab->deviceMask = (inputMasks) ? inputMasks->inputEvents[dev->id] : 0;

    if (inputMasks)
        xi2mask_merge(tempGrab->xi2mask, inputMasks->xi2mask);

    (*dev->deviceGrab.ActivateGrab) (dev, tempGrab,
                                     currentTime, TRUE | ImplicitGrabMask);
    FreeGrab(tempGrab);
    return TRUE;
}

Project: xserver
File: events.c

BorderSizeNotEmpty(DeviceIntPtr pDev, WindowPtr pWin)
{
    if (RegionNotEmpty(&pWin->borderSize))
        return TRUE;

#ifdef PANORAMIX
    if (!noPanoramiXExtension && XineramaSetWindowPntrs(pDev, pWin)) {
        int i;

        FOR_NSCREENS_FORWARD_SKIP(i) {
            if (RegionNotEmpty
                (&pDev->spriteInfo->sprite->windows[i]->borderSize))
                return TRUE;
        }
    }
#endif
    return FALSE;
}

Project: xserver
File: events.c

ChangeToCursor(DeviceIntPtr pDev, CursorPtr cursor)
{
    SpritePtr pSprite = pDev->spriteInfo->sprite;
    ScreenPtr pScreen;

    if (cursor != pSprite->current) {
        if ((pSprite->current->bits->xhot != cursor->bits->xhot) ||
            (pSprite->current->bits->yhot != cursor->bits->yhot))
            CheckPhysLimits(pDev, cursor, FALSE, pSprite->confined,
                            (ScreenPtr) NULL);
#ifdef PANORAMIX
        /* XXX: is this really necessary?? (whot) */
        if (!noPanoramiXExtension)
            pScreen = pSprite->screen;
        else
#endif
            pScreen = pSprite->hotPhys.pScreen;

        (*pScreen->DisplayCursor) (pDev, pScreen, cursor);
        FreeCursor(pSprite->current, (Cursor) 0);
        pSprite->current = RefCursor(cursor);
    }
}

Project: xserver
File: events.c

CheckCursorConfinement(WindowPtr pWin)
{
    GrabPtr grab;
    WindowPtr confineTo;
    DeviceIntPtr pDev;

#ifdef PANORAMIX
    if (!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
        return;
#endif

    for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
        if (DevHasCursor(pDev)) {
            grab = pDev->deviceGrab.grab;
            if (grab && (confineTo = grab->confineTo)) {
                if (!BorderSizeNotEmpty(pDev, confineTo))
                    (*pDev->deviceGrab.DeactivateGrab) (pDev);
                else if ((pWin == confineTo) || IsParent(pWin, confineTo))
                    ConfineCursorToWindow(pDev, confineTo, TRUE, TRUE);
            }
        }
    }
}

Project: xserver
File: events.c

CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor)
{
    int i;
    WindowPtr pWin = NULL;
    FocusClassPtr focus =
        IsPointerEvent((InternalEvent *) event) ? NULL : device->focus;
    BOOL sendCore = (IsMaster(device) && device->coreEvents);
    Bool ret = FALSE;

    if (event->type != ET_ButtonPress && event->type != ET_KeyPress)
        return FALSE;

    if (event->type == ET_ButtonPress && (device->button->buttonsDown != 1))
        return FALSE;

    if (device->deviceGrab.grab)
        return FALSE;

    i = 0;
    if (ancestor) {
        while (i < device->spriteInfo->sprite->spriteTraceGood)
            if (device->spriteInfo->sprite->spriteTrace[i++] == ancestor)
                break;
        if (i == device->spriteInfo->sprite->spriteTraceGood)
            goto out;
    }

    if (focus) {
        for (; i < focus->traceGood; i++) {
            pWin = focus->trace[i];
            if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event,
                                          sendCore, TRUE)) {
                ret = TRUE;
                goto out;
            }
        }

        if ((focus->win == NoneWin) ||
            (i >= device->spriteInfo->sprite->spriteTraceGood) ||
            (pWin && pWin != device->spriteInfo->sprite->spriteTrace[i - 1]))
            goto out;
    }

    for (; i < device->spriteInfo->sprite->spriteTraceGood; i++) {
        pWin = device->spriteInfo->sprite->spriteTrace[i];
        if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event,
                                      sendCore, TRUE)) {
            ret = TRUE;
            goto out;
        }
    }

 out:
    if (ret == TRUE && event->type == ET_KeyPress)
        device->deviceGrab.activatingKey = event->detail.key;
    return ret;
}

Project: xserver
File: events.c

CheckGrabForSyncs(DeviceIntPtr thisDev, Bool thisMode, Bool otherMode)
{
    GrabPtr grab = thisDev->deviceGrab.grab;
    DeviceIntPtr dev;

    if (thisMode == GrabModeSync)
        thisDev->deviceGrab.sync.state = FROZEN_NO_EVENT;
    else {                      /* free both if same client owns both */
        thisDev->deviceGrab.sync.state = THAWED;
        if (thisDev->deviceGrab.sync.other &&
            (CLIENT_BITS(thisDev->deviceGrab.sync.other->resource) ==
             CLIENT_BITS(grab->resource)))
            thisDev->deviceGrab.sync.other = NullGrab;
    }

    if (IsMaster(thisDev)) {
        dev = GetPairedDevice(thisDev);
        if (otherMode == GrabModeSync)
            dev->deviceGrab.sync.other = grab;
        else {                  /* free both if same client owns both */
            if (dev->deviceGrab.sync.other &&
                (CLIENT_BITS(dev->deviceGrab.sync.other->resource) ==
                 CLIENT_BITS(grab->resource)))
                dev->deviceGrab.sync.other = NullGrab;
        }
    }
    ComputeFreezes();
}

Project: xserver
File: events.c

CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
{
    WindowPtr prevSpriteWin, newSpriteWin;
    SpritePtr pSprite = pDev->spriteInfo->sprite;

    verify_internal_event((InternalEvent *) ev);

    prevSpriteWin = pSprite->win;

    if (ev && !syncEvents.playingEvents) {
        /* GetPointerEvents() guarantees that pointer events have the correct
           rootX/Y set already. */
        switch (ev->type) {
        case ET_ButtonPress:
        case ET_ButtonRelease:
        case ET_Motion:
        case ET_TouchBegin:
        case ET_TouchUpdate:
        case ET_TouchEnd:
            break;
        default:
            /* all other events return FALSE */
            return FALSE;
        }

#ifdef PANORAMIX
        if (!noPanoramiXExtension) {
            /* Motion events entering DIX get translated to Screen 0
               coordinates.  Replayed events have already been
               translated since they've entered DIX before */
            ev->root_x += pSprite->screen->x - screenInfo.screens[0]->x;
            ev->root_y += pSprite->screen->y - screenInfo.screens[0]->y;
        }
        else
#endif
        {
            if (pSprite->hot.pScreen != pSprite->hotPhys.pScreen) {
                pSprite->hot.pScreen = pSprite->hotPhys.pScreen;
                RootWindow(pDev->spriteInfo->sprite) =
                    pSprite->hot.pScreen->root;
            }
        }

        pSprite->hot.x = ev->root_x;
        pSprite->hot.y = ev->root_y;
        if (pSprite->hot.x < pSprite->physLimits.x1)
            pSprite->hot.x = pSprite->physLimits.x1;
        else if (pSprite->hot.x >= pSprite->physLimits.x2)
            pSprite->hot.x = pSprite->physLimits.x2 - 1;
        if (pSprite->hot.y < pSprite->physLimits.y1)
            pSprite->hot.y = pSprite->physLimits.y1;
        else if (pSprite->hot.y >= pSprite->physLimits.y2)
            pSprite->hot.y = pSprite->physLimits.y2 - 1;
        if (pSprite->hotShape)
            ConfineToShape(pDev, pSprite->hotShape, &pSprite->hot.x,
                           &pSprite->hot.y);
        pSprite->hotPhys = pSprite->hot;

        if ((pSprite->hotPhys.x != ev->root_x) ||
            (pSprite->hotPhys.y != ev->root_y)) {
#ifdef PANORAMIX
            if (!noPanoramiXExtension) {
                XineramaSetCursorPosition(pDev, pSprite->hotPhys.x,
                                          pSprite->hotPhys.y, FALSE);
            }
            else
#endif
            {
                (*pSprite->hotPhys.pScreen->SetCursorPosition) (pDev,
                                                                pSprite->
                                                                hotPhys.pScreen,
                                                                pSprite->
                                                                hotPhys.x,
                                                                pSprite->
                                                                hotPhys.y,
                                                                FALSE);
            }
        }

        ev->root_x = pSprite->hot.x;
        ev->root_y = pSprite->hot.y;
    }

    newSpriteWin = XYToWindow(pSprite, pSprite->hot.x, pSprite->hot.y);

    if (newSpriteWin != prevSpriteWin) {
        int sourceid;

        if (!ev) {
            UpdateCurrentTimeIf();
            sourceid = pDev->id;        /* when from WindowsRestructured */
        }
        else
            sourceid = ev->sourceid;

        if (prevSpriteWin != NullWindow) {
            if (!ActivateEnterGrab(pDev, prevSpriteWin, newSpriteWin))
                DoEnterLeaveEvents(pDev, sourceid, prevSpriteWin,
                                   newSpriteWin, NotifyNormal);
        }
        /* set pSprite->win after ActivateEnterGrab, otherwise
           sprite window == grab_window and no enter/leave events are
           sent. */
        pSprite->win = newSpriteWin;
        PostNewCursor(pDev);
        return FALSE;
    }
    return TRUE;
}

Project: xserver
File: events.c

CheckPassiveGrabsOnWindow(WindowPtr pWin,
                          DeviceIntPtr device,
                          InternalEvent *event, BOOL checkCore, BOOL activate)
{
    GrabPtr grab = wPassiveGrabs(pWin);
    GrabPtr tempGrab;

    if (!grab)
        return NULL;

    tempGrab = AllocGrab(NULL);
    if (tempGrab == NULL)
        return NULL;

    /* Fill out the grab details, but leave the type for later before
     * comparing */
    switch (event->any.type) {
    case ET_KeyPress:
    case ET_KeyRelease:
        tempGrab->detail.exact = event->device_event.detail.key;
        break;
    case ET_ButtonPress:
    case ET_ButtonRelease:
    case ET_TouchBegin:
    case ET_TouchEnd:
        tempGrab->detail.exact = event->device_event.detail.button;
        break;
    default:
        tempGrab->detail.exact = 0;
        break;
    }
    tempGrab->window = pWin;
    tempGrab->device = device;
    tempGrab->detail.pMask = NULL;
    tempGrab->modifiersDetail.pMask = NULL;
    tempGrab->next = NULL;

    for (; grab; grab = grab->next) {
        if (!CheckPassiveGrab(device, grab, event, checkCore, tempGrab))
            continue;

        if (activate && !ActivatePassiveGrab(device, grab, event, event))
            continue;

        break;
    }

    FreeGrab(tempGrab);
    return grab;
}

Project: xserver
File: events.c

CheckPhysLimits(DeviceIntPtr pDev, CursorPtr cursor, Bool generateEvents,
                Bool confineToScreen, /* unused if PanoramiX on */
                ScreenPtr pScreen)    /* unused if PanoramiX on */
{
    HotSpot new;
    SpritePtr pSprite = pDev->spriteInfo->sprite;

    if (!cursor)
        return;
    new = pSprite->hotPhys;
#ifdef PANORAMIX
    if (!noPanoramiXExtension)
        /* I don't care what the DDX has to say about it */
        pSprite->physLimits = pSprite->hotLimits;
    else
#endif
    {
        if (pScreen)
            new.pScreen = pScreen;
        else
            pScreen = new.pScreen;
        (*pScreen->CursorLimits) (pDev, pScreen, cursor, &pSprite->hotLimits,
                                  &pSprite->physLimits);
        pSprite->confined = confineToScreen;
        (*pScreen->ConstrainCursor) (pDev, pScreen, &pSprite->physLimits);
    }

    /* constrain the pointer to those limits */
    if (new.x < pSprite->physLimits.x1)
        new.x = pSprite->physLimits.x1;
    else if (new.x >= pSprite->physLimits.x2)
        new.x = pSprite->physLimits.x2 - 1;
    if (new.y < pSprite->physLimits.y1)
        new.y = pSprite->physLimits.y1;
    else if (new.y >= pSprite->physLimits.y2)
        new.y = pSprite->physLimits.y2 - 1;
    if (pSprite->hotShape)
        ConfineToShape(pDev, pSprite->hotShape, &new.x, &new.y);
    if ((
#ifdef PANORAMIX
            noPanoramiXExtension &&
#endif
            (pScreen != pSprite->hotPhys.pScreen)) ||
        (new.x != pSprite->hotPhys.x) || (new.y != pSprite->hotPhys.y)) {
#ifdef PANORAMIX
        if (!noPanoramiXExtension)
            XineramaSetCursorPosition(pDev, new.x, new.y, generateEvents);
        else
#endif
        {
            if (pScreen != pSprite->hotPhys.pScreen)
                pSprite->hotPhys = new;
            (*pScreen->SetCursorPosition)
                (pDev, pScreen, new.x, new.y, generateEvents);
        }
        if (!generateEvents)
            SyntheticMotion(pDev, new.x, new.y);
    }

#ifdef PANORAMIX
    /* Tell DDX what the limits are */
    if (!noPanoramiXExtension)
        XineramaConstrainCursor(pDev);
#endif
}

Project: xserver
File: events.c

CheckVirtualMotion(DeviceIntPtr pDev, QdEventPtr qe, WindowPtr pWin)
{
    SpritePtr pSprite = pDev->spriteInfo->sprite;
    RegionPtr reg = NULL;
    DeviceEvent *ev = NULL;

    if (qe) {
        ev = &qe->event->device_event;
        switch (ev->type) {
        case ET_Motion:
        case ET_ButtonPress:
        case ET_ButtonRelease:
        case ET_KeyPress:
        case ET_KeyRelease:
        case ET_ProximityIn:
        case ET_ProximityOut:
            pSprite->hot.pScreen = qe->pScreen;
            pSprite->hot.x = ev->root_x;
            pSprite->hot.y = ev->root_y;
            pWin =
                pDev->deviceGrab.grab ? pDev->deviceGrab.grab->
                confineTo : NullWindow;
            break;
        default:
            break;
        }
    }
    if (pWin) {
        BoxRec lims;

#ifdef PANORAMIX
        if (!noPanoramiXExtension) {
            int x, y, off_x, off_y, i;

            if (!XineramaSetWindowPntrs(pDev, pWin))
                return;

            i = PanoramiXNumScreens - 1;

            RegionCopy(&pSprite->Reg2, &pSprite->windows[i]->borderSize);
            off_x = screenInfo.screens[i]->x;
            off_y = screenInfo.screens[i]->y;

            while (i--) {
                x = off_x - screenInfo.screens[i]->x;
                y = off_y - screenInfo.screens[i]->y;

                if (x || y)
                    RegionTranslate(&pSprite->Reg2, x, y);

                RegionUnion(&pSprite->Reg2, &pSprite->Reg2,
                            &pSprite->windows[i]->borderSize);

                off_x = screenInfo.screens[i]->x;
                off_y = screenInfo.screens[i]->y;
            }
        }
        else
#endif
        {
            if (pSprite->hot.pScreen != pWin->drawable.pScreen) {
                pSprite->hot.pScreen = pWin->drawable.pScreen;
                pSprite->hot.x = pSprite->hot.y = 0;
            }
        }

        lims = *RegionExtents(&pWin->borderSize);
        if (pSprite->hot.x < lims.x1)
            pSprite->hot.x = lims.x1;
        else if (pSprite->hot.x >= lims.x2)
            pSprite->hot.x = lims.x2 - 1;
        if (pSprite->hot.y < lims.y1)
            pSprite->hot.y = lims.y1;
        else if (pSprite->hot.y >= lims.y2)
            pSprite->hot.y = lims.y2 - 1;

#ifdef PANORAMIX
        if (!noPanoramiXExtension) {
            if (RegionNumRects(&pSprite->Reg2) > 1)
                reg = &pSprite->Reg2;

        }
        else
#endif
        {
            if (wBoundingShape(pWin))
                reg = &pWin->borderSize;
        }

        if (reg)
            ConfineToShape(pDev, reg, &pSprite->hot.x, &pSprite->hot.y);

        if (qe && ev) {
            qe->pScreen = pSprite->hot.pScreen;
            ev->root_x = pSprite->hot.x;
            ev->root_y = pSprite->hot.y;
        }
    }
#ifdef PANORAMIX
    if (noPanoramiXExtension)   /* No typo. Only set the root win if disabled */
#endif
        RootWindow(pDev->spriteInfo->sprite) = pSprite->hot.pScreen->root;
}

Project: xserver
File: events.c

ComputeFreezes(void)
{
    DeviceIntPtr replayDev = syncEvents.replayDev;
    WindowPtr w;
    GrabPtr grab;
    DeviceIntPtr dev;

    for (dev = inputInfo.devices; dev; dev = dev->next)
        FreezeThaw(dev, dev->deviceGrab.sync.other ||
                   (dev->deviceGrab.sync.state >= FROZEN));
    if (syncEvents.playingEvents ||
        (!replayDev && xorg_list_is_empty(&syncEvents.pending)))
        return;
    syncEvents.playingEvents = TRUE;
    if (replayDev) {
        DeviceEvent *event = replayDev->deviceGrab.sync.event;

        syncEvents.replayDev = (DeviceIntPtr) NULL;

        w = XYToWindow(replayDev->spriteInfo->sprite,
                       event->root_x, event->root_y);
        if (!CheckDeviceGrabs(replayDev, event, syncEvents.replayWin)) {
            if (IsTouchEvent((InternalEvent *) event)) {
                TouchPointInfoPtr ti =
                    TouchFindByClientID(replayDev, event->touchid);
                BUG_WARN(!ti);

                TouchListenerAcceptReject(replayDev, ti, 0, XIRejectTouch);
            }
            else if (replayDev->focus &&
                     !IsPointerEvent((InternalEvent *) event))
                DeliverFocusedEvent(replayDev, (InternalEvent *) event, w);
            else
                DeliverDeviceEvents(w, (InternalEvent *) event, NullGrab,
                                    NullWindow, replayDev);
        }
    }
    for (dev = inputInfo.devices; dev; dev = dev->next) {
        if (!dev->deviceGrab.sync.frozen) {
            PlayReleasedEvents();
            break;
        }
    }
    syncEvents.playingEvents = FALSE;
    for (dev = inputInfo.devices; dev; dev = dev->next) {
        if (DevHasCursor(dev)) {
            /* the following may have been skipped during replay,
               so do it now */
            if ((grab = dev->deviceGrab.grab) && grab->confineTo) {
                if (grab->confineTo->drawable.pScreen !=
                    dev->spriteInfo->sprite->hotPhys.pScreen)
                    dev->spriteInfo->sprite->hotPhys.x =
                        dev->spriteInfo->sprite->hotPhys.y = 0;
                ConfineCursorToWindow(dev, grab->confineTo, TRUE, TRUE);
            }
            else
                ConfineCursorToWindow(dev,
                                      dev->spriteInfo->sprite->hotPhys.pScreen->
                                      root, TRUE, FALSE);
            PostNewCursor(dev);
        }
    }
}

Project: xserver
File: events.c

ConfineCursorToWindow(DeviceIntPtr pDev, WindowPtr pWin, Bool generateEvents,
                      Bool confineToScreen)
{
    SpritePtr pSprite = pDev->spriteInfo->sprite;

    if (syncEvents.playingEvents) {
        CheckVirtualMotion(pDev, (QdEventPtr) NULL, pWin);
        SyntheticMotion(pDev, pSprite->hot.x, pSprite->hot.y);
    }
    else {
        ScreenPtr pScreen = pWin->drawable.pScreen;

#ifdef PANORAMIX
        if (!noPanoramiXExtension) {
            XineramaConfineCursorToWindow(pDev, pWin, generateEvents);
            return;
        }
#endif
        pSprite->hotLimits = *RegionExtents(&pWin->borderSize);
        pSprite->hotShape = wBoundingShape(pWin) ? &pWin->borderSize
            : NullRegion;
        CheckPhysLimits(pDev, pSprite->current, generateEvents,
                        confineToScreen, pWin->drawable.pScreen);

        if (*pScreen->CursorConfinedTo)
            (*pScreen->CursorConfinedTo) (pDev, pScreen, pWin);
    }
}

Project: xserver
File: events.c

CoreEnterLeaveEvent(DeviceIntPtr mouse,
                    int type,
                    int mode, int detail, WindowPtr pWin, Window child)
{
    xEvent event = {
        .u.u.type = type,
        .u.u.detail = detail
    };
    WindowPtr focus;
    DeviceIntPtr keybd;
    GrabPtr grab = mouse->deviceGrab.grab;
    Mask mask;

    keybd = GetMaster(mouse, KEYBOARD_OR_FLOAT);

    if ((pWin == mouse->valuator->motionHintWindow) &&
        (detail != NotifyInferior))
        mouse->valuator->motionHintWindow = NullWindow;
    if (grab) {
        mask = (pWin == grab->window) ? grab->eventMask : 0;
        if (grab->ownerEvents)
            mask |= EventMaskForClient(pWin, rClient(grab));
    }
    else {
        mask = pWin->eventMask | wOtherEventMasks(pWin);
    }

    event.u.enterLeave.time = currentTime.milliseconds;
    event.u.enterLeave.rootX = mouse->spriteInfo->sprite->hot.x;
    event.u.enterLeave.rootY = mouse->spriteInfo->sprite->hot.y;
    /* Counts on the same initial structure of crossing & button events! */
    FixUpEventFromWindow(mouse->spriteInfo->sprite, &event, pWin, None, FALSE);
    /* Enter/Leave events always set child */
    event.u.enterLeave.child = child;
    event.u.enterLeave.flags = event.u.keyButtonPointer.sameScreen ?
        ELFlagSameScreen : 0;
    event.u.enterLeave.state =
        mouse->button ? (mouse->button->state & 0x1f00) : 0;
    if (keybd)
        event.u.enterLeave.state |=
            XkbGrabStateFromRec(&keybd->key->xkbInfo->state);
    event.u.enterLeave.mode = mode;
    focus = (keybd) ? keybd->focus->win : None;
    if ((focus != NoneWin) &&
        ((pWin == focus) || (focus == PointerRootWin) || IsParent(focus, pWin)))
        event.u.enterLeave.flags |= ELFlagFocus;

    if ((mask & GetEventFilter(mouse, &event))) {
        if (grab)
            TryClientEvents(rClient(grab), mouse, &event, 1, mask,
                            GetEventFilter(mouse, &event), grab);
        else
            DeliverEventsToWindow(mouse, pWin, &event, 1,
                                  GetEventFilter(mouse, &event), NullGrab);
    }

    if ((type == EnterNotify) && (mask & KeymapStateMask)) {
        xKeymapEvent ke = {
            .type = KeymapNotify
        };
        ClientPtr client = grab ? rClient(grab) : wClient(pWin);
        int rc;

        rc = XaceHook(XACE_DEVICE_ACCESS, client, keybd, DixReadAccess);
        if (rc == Success)
            memcpy((char *) &ke.map[0], (char *) &keybd->key->down[1], 31);

        if (grab)
            TryClientEvents(rClient(grab), keybd, (xEvent *) &ke, 1,
                            mask, KeymapStateMask, grab);
        else
            DeliverEventsToWindow(mouse, pWin, (xEvent *) &ke, 1,
                                  KeymapStateMask, NullGrab);
    }
}

Project: xserver
File: events.c

CoreGrabInterferes(DeviceIntPtr device, GrabPtr grab)
{
    DeviceIntPtr other;
    BOOL interfering = FALSE;

    for (other = inputInfo.devices; other; other = other->next) {
        GrabPtr othergrab = other->deviceGrab.grab;

        if (othergrab && othergrab->grabtype == CORE &&
            SameClient(grab, rClient(othergrab)) &&
            ((IsPointerDevice(grab->device) &&
              IsPointerDevice(othergrab->device)) ||
             (IsKeyboardDevice(grab->device) &&
              IsKeyboardDevice(othergrab->device)))) {
            interfering = TRUE;
            break;
        }
    }

    return interfering;
}

Project: xserver
File: events.c

DeactivateKeyboardGrab(DeviceIntPtr keybd)
{
    GrabPtr grab = keybd->deviceGrab.grab;
    DeviceIntPtr dev;
    WindowPtr focusWin;
    Bool wasImplicit = (keybd->deviceGrab.fromPassiveGrab &&
                        keybd->deviceGrab.implicitGrab);

    if (keybd->valuator)
        keybd->valuator->motionHintWindow = NullWindow;
    keybd->deviceGrab.grab = NullGrab;
    keybd->deviceGrab.sync.state = NOT_GRABBED;
    keybd->deviceGrab.fromPassiveGrab = FALSE;

    for (dev = inputInfo.devices; dev; dev = dev->next) {
        if (dev->deviceGrab.sync.other == grab)
            dev->deviceGrab.sync.other = NullGrab;
    }

    if (keybd->focus)
        focusWin = keybd->focus->win;
    else if (keybd->spriteInfo->sprite)
        focusWin = keybd->spriteInfo->sprite->win;
    else
        focusWin = NullWindow;

    if (focusWin == FollowKeyboardWin)
        focusWin = inputInfo.keyboard->focus->win;

    DoFocusEvents(keybd, grab->window, focusWin, NotifyUngrab);

    if (!wasImplicit && grab->grabtype == XI2)
        ReattachToOldMaster(keybd);

    ComputeFreezes();

    FreeGrab(grab);
}

Project: xserver
File: events.c

DeactivatePointerGrab(DeviceIntPtr mouse)
{
    GrabPtr grab = mouse->deviceGrab.grab;
    DeviceIntPtr dev;
    Bool wasPassive = mouse->deviceGrab.fromPassiveGrab;
    Bool wasImplicit = (mouse->deviceGrab.fromPassiveGrab &&
                        mouse->deviceGrab.implicitGrab);
    XID grab_resource = grab->resource;
    int i;

    /* If an explicit grab was deactivated, we must remove it from the head of
     * all the touches' listener lists. */
    for (i = 0; !wasPassive && mouse->touch && i < mouse->touch->num_touches; i++) {
        TouchPointInfoPtr ti = mouse->touch->touches + i;
        if (ti->active && TouchResourceIsOwner(ti, grab_resource)) {
            int mode = XIRejectTouch;
            /* Rejecting will generate a TouchEnd, but we must not
               emulate a ButtonRelease here. So pretend the listener
               already has the end event */
            if (grab->grabtype == CORE || grab->grabtype == XI ||
                    !xi2mask_isset(mouse->deviceGrab.grab->xi2mask, mouse, XI_TouchBegin)) {
                mode = XIAcceptTouch;
                /* NOTE: we set the state here, but
                 * ProcessTouchOwnershipEvent() will still call
                 * TouchEmitTouchEnd for this listener. The other half of
                 * this hack is in DeliverTouchEndEvent */
                ti->listeners[0].state = LISTENER_HAS_END;
            }
            TouchListenerAcceptReject(mouse, ti, 0, mode);
        }
    }

    TouchRemovePointerGrab(mouse);

    mouse->valuator->motionHintWindow = NullWindow;
    mouse->deviceGrab.grab = NullGrab;
    mouse->deviceGrab.sync.state = NOT_GRABBED;
    mouse->deviceGrab.fromPassiveGrab = FALSE;

    for (dev = inputInfo.devices; dev; dev = dev->next) {
        if (dev->deviceGrab.sync.other == grab)
            dev->deviceGrab.sync.other = NullGrab;
    }
    DoEnterLeaveEvents(mouse, mouse->id, grab->window,
                       mouse->spriteInfo->sprite->win, NotifyUngrab);
    if (grab->confineTo)
        ConfineCursorToWindow(mouse, GetCurrentRootWindow(mouse), FALSE, FALSE);
    PostNewCursor(mouse);

    if (!wasImplicit && grab->grabtype == XI2)
        ReattachToOldMaster(mouse);

    ComputeFreezes();

    FreeGrab(grab);
}

Project: xserver
File: events.c

DeleteWindowFromAnyEvents(WindowPtr pWin, Bool freeResources)
{
    WindowPtr parent;
    DeviceIntPtr mouse = inputInfo.pointer;
    DeviceIntPtr keybd = inputInfo.keyboard;
    FocusClassPtr focus;
    OtherClientsPtr oc;
    GrabPtr passive;
    GrabPtr grab;

    /* Deactivate any grabs performed on this window, before making any
       input focus changes. */
    grab = mouse->deviceGrab.grab;
    if (grab && ((grab->window == pWin) || (grab->confineTo == pWin)))
        (*mouse->deviceGrab.DeactivateGrab) (mouse);

    /* Deactivating a keyboard grab should cause focus events. */
    grab = keybd->deviceGrab.grab;
    if (grab && (grab->window == pWin))
        (*keybd->deviceGrab.DeactivateGrab) (keybd);

    /* And now the real devices */
    for (mouse = inputInfo.devices; mouse; mouse = mouse->next) {
        grab = mouse->deviceGrab.grab;
        if (grab && ((grab->window == pWin) || (grab->confineTo == pWin)))
            (*mouse->deviceGrab.DeactivateGrab) (mouse);
    }

    for (keybd = inputInfo.devices; keybd; keybd = keybd->next) {
        if (IsKeyboardDevice(keybd)) {
            focus = keybd->focus;

            /* If the focus window is a root window (ie. has no parent)
               then don't delete the focus from it. */

            if ((pWin == focus->win) && (pWin->parent != NullWindow)) {
                int focusEventMode = NotifyNormal;

                /* If a grab is in progress, then alter the mode of focus events. */

                if (keybd->deviceGrab.grab)
                    focusEventMode = NotifyWhileGrabbed;

                switch (focus->revert) {
                case RevertToNone:
                    DoFocusEvents(keybd, pWin, NoneWin, focusEventMode);
                    focus->win = NoneWin;
                    focus->traceGood = 0;
                    break;
                case RevertToParent:
                    parent = pWin;
                    do {
                        parent = parent->parent;
                        focus->traceGood--;
                    } while (!parent->realized
                    /* This would be a good protocol change -- windows being
                       reparented during SaveSet processing would cause the
                       focus to revert to the nearest enclosing window which
                       will survive the death of the exiting client, instead
                       of ending up reverting to a dying window and thence
                       to None */
#ifdef NOTDEF
                             || wClient(parent)->clientGone
#endif
                        );
                    if (!ActivateFocusInGrab(keybd, pWin, parent))
                        DoFocusEvents(keybd, pWin, parent, focusEventMode);
                    focus->win = parent;
                    focus->revert = RevertToNone;
                    break;
                case RevertToPointerRoot:
                    if (!ActivateFocusInGrab(keybd, pWin, PointerRootWin))
                        DoFocusEvents(keybd, pWin, PointerRootWin,
                                      focusEventMode);
                    focus->win = PointerRootWin;
                    focus->traceGood = 0;
                    break;
                }
            }
        }

        if (IsPointerDevice(keybd)) {
            if (keybd->valuator->motionHintWindow == pWin)
                keybd->valuator->motionHintWindow = NullWindow;
        }
    }

    if (freeResources) {
        if (pWin->dontPropagate)
            DontPropagateRefCnts[pWin->dontPropagate]--;
        while ((oc = wOtherClients(pWin)))
            FreeResource(oc->resource, RT_NONE);
        while ((passive = wPassiveGrabs(pWin)))
            FreeResource(passive->resource, RT_NONE);
    }

    DeleteWindowFromAnyExtEvents(pWin, freeResources);
}

Project: xserver
File: events.c

DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
                    WindowPtr stopAt, DeviceIntPtr dev)
{
    Window child = None;
    int deliveries = 0;
    int mask;

    verify_internal_event(event);

    while (pWin) {
        if ((mask = EventIsDeliverable(dev, event->any.type, pWin))) {
            /* XI2 events first */
            if (mask & EVENT_XI2_MASK) {
                deliveries =
                    DeliverOneEvent(event, dev, XI2, pWin, child, grab);
                if (deliveries > 0)
                    break;
            }

            /* XI events */
            if (mask & EVENT_XI1_MASK) {
                deliveries = DeliverOneEvent(event, dev, XI, pWin, child, grab);
                if (deliveries > 0)
                    break;
            }

            /* Core event */
            if ((mask & EVENT_CORE_MASK) && IsMaster(dev) && dev->coreEvents) {
                deliveries =
                    DeliverOneEvent(event, dev, CORE, pWin, child, grab);
                if (deliveries > 0)
                    break;
            }

        }

        if ((deliveries < 0) || (pWin == stopAt) ||
            (mask & EVENT_DONT_PROPAGATE_MASK)) {
            deliveries = 0;
            break;
        }

        child = pWin->drawable.id;
        pWin = pWin->parent;
    }

    return deliveries;
}

Project: xserver
File: events.c

DeliverEvent(DeviceIntPtr dev, xEvent *xE, int count,
             WindowPtr win, Window child, GrabPtr grab)
{
    SpritePtr pSprite = dev->spriteInfo->sprite;
    Mask filter;
    int deliveries = 0;

    if (XaceHook(XACE_SEND_ACCESS, NULL, dev, win, xE, count) == Success) {
        filter = GetEventFilter(dev, xE);
        FixUpEventFromWindow(pSprite, xE, win, child, FALSE);
        deliveries = DeliverEventsToWindow(dev, win, xE, count, filter, grab);
    }

    return deliveries;
}

Project: xserver
File: events.c

DeliverEventToInputClients(DeviceIntPtr dev, InputClients * inputclients,
                           WindowPtr win, xEvent *events,
                           int count, Mask filter, GrabPtr grab,
                           ClientPtr *client_return, Mask *mask_return)
{
    int attempt;
    enum EventDeliveryState rc = EVENT_NOT_DELIVERED;
    Bool have_device_button_grab_class_client = FALSE;

    for (; inputclients; inputclients = inputclients->next) {
        Mask mask;
        ClientPtr client = rClient(inputclients);

        if (IsInterferingGrab(client, dev, events))
            continue;

        if (IsWrongPointerBarrierClient(client, dev, events))
            continue;

        mask = GetEventMask(dev, events, inputclients);

        if (XaceHook(XACE_RECEIVE_ACCESS, client, win, events, count))
            /* do nothing */ ;
        else if ((attempt = TryClientEvents(client, dev,
                                            events, count,
                                            mask, filter, grab))) {
            if (attempt > 0) {
                /*
                 * The order of clients is arbitrary therefore if one
                 * client belongs to DeviceButtonGrabClass make sure to
                 * catch it.
                 */
                if (!have_device_button_grab_class_client) {
                    rc = EVENT_DELIVERED;
                    *client_return = client;
                    *mask_return = mask;
                    /* Success overrides non-success, so if we've been
                     * successful on one client, return that */
                    if (mask & DeviceButtonGrabMask)
                        have_device_button_grab_class_client = TRUE;
                }
            } else if (rc == EVENT_NOT_DELIVERED)
                rc = EVENT_REJECTED;
        }
    }

    return rc;
}

Project: xserver
File: events.c

DeliverEventToWindowMask(DeviceIntPtr dev, WindowPtr win, xEvent *events,
                         int count, Mask filter, GrabPtr grab,
                         ClientPtr *client_return, Mask *mask_return)
{
    InputClients *iclients;

    if (!GetClientsForDelivery(dev, win, events, filter, &iclients))
        return EVENT_SKIP;

    return DeliverEventToInputClients(dev, iclients, win, events, count, filter,
                                      grab, client_return, mask_return);

}

Project: xserver
File: events.c

DeliverEvents(WindowPtr pWin, xEvent *xE, int count, WindowPtr otherParent)
{
    DeviceIntRec dummy;
    int deliveries;

#ifdef PANORAMIX
    if (!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
        return count;
#endif

    if (!count)
        return 0;

    dummy.id = XIAllDevices;

    switch (xE->u.u.type) {
    case DestroyNotify:
    case UnmapNotify:
    case MapNotify:
    case MapRequest:
    case ReparentNotify:
    case ConfigureNotify:
    case ConfigureRequest:
    case GravityNotify:
    case CirculateNotify:
    case CirculateRequest:
        xE->u.destroyNotify.event = pWin->drawable.id;
        break;
    }

    switch (xE->u.u.type) {
    case DestroyNotify:
    case UnmapNotify:
    case MapNotify:
    case ReparentNotify:
    case ConfigureNotify:
    case GravityNotify:
    case CirculateNotify:
        break;
    default:
    {
        Mask filter;

        filter = GetEventFilter(&dummy, xE);
        return DeliverEventsToWindow(&dummy, pWin, xE, count, filter, NullGrab);
    }
    }

    deliveries = DeliverEventsToWindow(&dummy, pWin, xE, count,
                                       StructureNotifyMask, NullGrab);
    if (pWin->parent) {
        xE->u.destroyNotify.event = pWin->parent->drawable.id;
        deliveries += DeliverEventsToWindow(&dummy, pWin->parent, xE, count,
                                            SubstructureNotifyMask, NullGrab);
        if (xE->u.u.type == ReparentNotify) {
            xE->u.destroyNotify.event = otherParent->drawable.id;
            deliveries += DeliverEventsToWindow(&dummy,
                                                otherParent, xE, count,
                                                SubstructureNotifyMask,
                                                NullGrab);
        }
    }
    return deliveries;
}

Project: xserver
File: events.c

DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
                      *pEvents, int count, Mask filter, GrabPtr grab)
{
    int deliveries = 0, nondeliveries = 0;
    ClientPtr client = NullClient;
    Mask deliveryMask = 0;      /* If a grab occurs due to a button press, then
                                   this mask is the mask of the grab. */
    int type = pEvents->u.u.type;

    /* Deliver to window owner */
    if ((filter == CantBeFiltered) || core_get_type(pEvents) != 0) {
        enum EventDeliveryState rc;

        rc = DeliverToWindowOwner(pDev, pWin, pEvents, count, filter, grab);

        switch (rc) {
        case EVENT_SKIP:
            return 0;
        case EVENT_REJECTED:
            nondeliveries--;
            break;
        case EVENT_DELIVERED:
            /* We delivered to the owner, with our event mask */
            deliveries++;
            client = wClient(pWin);
            deliveryMask = pWin->eventMask;
            break;
        case EVENT_NOT_DELIVERED:
            break;
        }
    }

    /* CantBeFiltered means only window owner gets the event */
    if (filter != CantBeFiltered) {
        enum EventDeliveryState rc;

        rc = DeliverEventToWindowMask(pDev, pWin, pEvents, count, filter,
                                      grab, &client, &deliveryMask);

        switch (rc) {
        case EVENT_SKIP:
            return 0;
        case EVENT_REJECTED:
            nondeliveries--;
            break;
        case EVENT_DELIVERED:
            deliveries++;
            break;
        case EVENT_NOT_DELIVERED:
            break;
        }
    }

    if (deliveries) {
        /*
         * Note that since core events are delivered first, an implicit grab may
         * be activated on a core grab, stopping the XI events.
         */
        if (!grab &&
            ActivateImplicitGrab(pDev, client, pWin, pEvents, deliveryMask))
            /* grab activated */ ;
        else if (type == MotionNotify)
            pDev->valuator->motionHintWindow = pWin;
        else if (type == DeviceMotionNotify || type == DeviceButtonPress)
            CheckDeviceGrabAndHintWindow(pWin, type,
                                         (deviceKeyButtonPointer *) pEvents,
                                         grab, client, deliveryMask);
        return deliveries;
    }
    return nondeliveries;
}

Project: xserver
File: events.c

DeliverFocusedEvent(DeviceIntPtr keybd, InternalEvent *event, WindowPtr window)
{
    DeviceIntPtr ptr;
    WindowPtr focus = keybd->focus->win;
    BOOL sendCore = (IsMaster(keybd) && keybd->coreEvents);
    xEvent *core = NULL, *xE = NULL, *xi2 = NULL;
    int count, rc;
    int deliveries = 0;

    if (focus == FollowKeyboardWin)
        focus = inputInfo.keyboard->focus->win;
    if (!focus)
        return;
    if (focus == PointerRootWin) {
        DeliverDeviceEvents(window, event, NullGrab, NullWindow, keybd);
        return;
    }
    if ((focus == window) || IsParent(focus, window)) {
        if (DeliverDeviceEvents(window, event, NullGrab, focus, keybd))
            return;
    }

    /* just deliver it to the focus window */
    ptr = GetMaster(keybd, POINTER_OR_FLOAT);

    rc = EventToXI2(event, &xi2);
    if (rc == Success) {
        /* XXX: XACE */
        int filter = GetEventFilter(keybd, xi2);

        FixUpEventFromWindow(ptr->spriteInfo->sprite, xi2, focus, None, FALSE);
        deliveries = DeliverEventsToWindow(keybd, focus, xi2, 1,
                                           filter, NullGrab);
        if (deliveries > 0)
            goto unwind;
    }
    else if (rc != BadMatch)
        ErrorF
            ("[dix] %s: XI2 conversion failed in DFE (%d, %d). Skipping delivery.\n",
             keybd->name, event->any.type, rc);

    rc = EventToXI(event, &xE, &count);
    if (rc == Success &&
        XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, xE, count) == Success) {
        FixUpEventFromWindow(ptr->spriteInfo->sprite, xE, focus, None, FALSE);
        deliveries = DeliverEventsToWindow(keybd, focus, xE, count,
                                           GetEventFilter(keybd, xE), NullGrab);

        if (deliveries > 0)
            goto unwind;
    }
    else if (rc != BadMatch)
        ErrorF
            ("[dix] %s: XI conversion failed in DFE (%d, %d). Skipping delivery.\n",
             keybd->name, event->any.type, rc);

    if (sendCore) {
        rc = EventToCore(event, &core, &count);
        if (rc == Success) {
            if (XaceHook(XACE_SEND_ACCESS, NULL, keybd, focus, core, count) ==
                Success) {
                FixUpEventFromWindow(keybd->spriteInfo->sprite, core, focus,
                                     None, FALSE);
                deliveries =
                    DeliverEventsToWindow(keybd, focus, core, count,
                                          GetEventFilter(keybd, core),
                                          NullGrab);
            }
        }
        else if (rc != BadMatch)
            ErrorF
                ("[dix] %s: core conversion failed DFE (%d, %d). Skipping delivery.\n",
                 keybd->name, event->any.type, rc);
    }

 unwind:
    free(core);
    free(xE);
    free(xi2);
    return;
}

Project: xserver
File: events.c

DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
                    Bool deactivateGrab)
{
    GrabPtr grab;
    GrabInfoPtr grabinfo;
    int deliveries = 0;
    DeviceIntPtr dev;
    SpritePtr pSprite = thisDev->spriteInfo->sprite;
    BOOL sendCore = FALSE;

    grabinfo = &thisDev->deviceGrab;
    grab = grabinfo->grab;

    if (grab->ownerEvents) {
        WindowPtr focus;

        /* Hack: Some pointer device have a focus class. So we need to check
         * for the type of event, to see if we really want to deliver it to
         * the focus window. For pointer events, the answer is no.
         */
        if (IsPointerEvent(event))
            focus = PointerRootWin;
        else if (thisDev->focus) {
            focus = thisDev->focus->win;
            if (focus == FollowKeyboardWin)
                focus = inputInfo.keyboard->focus->win;
        }
        else
            focus = PointerRootWin;
        if (focus == PointerRootWin)
            deliveries = DeliverDeviceEvents(pSprite->win, event, grab,
                                             NullWindow, thisDev);
        else if (focus && (focus == pSprite->win ||
                           IsParent(focus, pSprite->win)))
            deliveries = DeliverDeviceEvents(pSprite->win, event, grab, focus,
                                             thisDev);
        else if (focus)
            deliveries = DeliverDeviceEvents(focus, event, grab, focus,
                                             thisDev);
    }
    if (!deliveries) {
        sendCore = (IsMaster(thisDev) && thisDev->coreEvents);
        /* try core event */
        if ((sendCore && grab->grabtype == CORE) || grab->grabtype != CORE)
            deliveries = DeliverOneGrabbedEvent(event, thisDev, grab->grabtype);

        if (deliveries && (event->any.type == ET_Motion))
            thisDev->valuator->motionHintWindow = grab->window;
    }
    if (deliveries && !deactivateGrab &&
        (event->any.type == ET_KeyPress ||
         event->any.type == ET_KeyRelease ||
         event->any.type == ET_ButtonPress ||
         event->any.type == ET_ButtonRelease)) {
        switch (grabinfo->sync.state) {
        case FREEZE_BOTH_NEXT_EVENT:
            dev = GetPairedDevice(thisDev);
            if (dev) {
                FreezeThaw(dev, TRUE);
                if ((dev->deviceGrab.sync.state == FREEZE_BOTH_NEXT_EVENT) &&
                    (CLIENT_BITS(grab->resource) ==
                     CLIENT_BITS(dev->deviceGrab.grab->resource)))
                    dev->deviceGrab.sync.state = FROZEN_NO_EVENT;
                else
                    dev->deviceGrab.sync.other = grab;
            }
            /* fall through */
        case FREEZE_NEXT_EVENT:
            grabinfo->sync.state = FROZEN_WITH_EVENT;
            FreezeThaw(thisDev, TRUE);
            *grabinfo->sync.event = event->device_event;
            break;
        }
    }

    return deliveries;
}

Project: xserver
File: events.c

DeliverOneEvent(InternalEvent *event, DeviceIntPtr dev, enum InputLevel level,
                WindowPtr win, Window child, GrabPtr grab)
{
    xEvent *xE = NULL;
    int count = 0;
    int deliveries = 0;
    int rc;

    switch (level) {
    case XI2:
        rc = EventToXI2(event, &xE);
        count = 1;
        break;
    case XI:
        rc = EventToXI(event, &xE, &count);
        break;
    case CORE:
        rc = EventToCore(event, &xE, &count);
        break;
    default:
        rc = BadImplementation;
        break;
    }

    if (rc == Success) {
        deliveries = DeliverEvent(dev, xE, count, win, child, grab);
        free(xE);
    }
    else
        BUG_WARN_MSG(rc != BadMatch,
                     "%s: conversion to level %d failed with rc %d\n",
                     dev->name, level, rc);
    return deliveries;
}

Project: xserver
File: events.c

DeliverOneGrabbedEvent(InternalEvent *event, DeviceIntPtr dev,
                       enum InputLevel level)
{
    SpritePtr pSprite = dev->spriteInfo->sprite;
    int rc;
    xEvent *xE = NULL;
    int count = 0;
    int deliveries = 0;
    Mask mask;
    GrabInfoPtr grabinfo = &dev->deviceGrab;
    GrabPtr grab = grabinfo->grab;
    Mask filter;

    if (grab->grabtype != level)
        return 0;

    switch (level) {
    case XI2:
        rc = EventToXI2(event, &xE);
        count = 1;
        if (rc == Success) {
            int evtype = xi2_get_type(xE);

            mask = GetXI2MaskByte(grab->xi2mask, dev, evtype);
            filter = GetEventFilter(dev, xE);
        }
        break;
    case XI:
        if (grabinfo->fromPassiveGrab && grabinfo->implicitGrab)
            mask = grab->deviceMask;
        else
            mask = grab->eventMask;
        rc = EventToXI(event, &xE, &count);
        if (rc == Success)
            filter = GetEventFilter(dev, xE);
        break;
    case CORE:
        rc = EventToCore(event, &xE, &count);
        mask = grab->eventMask;
        if (rc == Success)
            filter = GetEventFilter(dev, xE);
        break;
    default:
        BUG_WARN_MSG(1, "Invalid input level %d\n", level);
        return 0;
    }

    if (rc == Success) {
        FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
        if (XaceHook(XACE_SEND_ACCESS, 0, dev,
                     grab->window, xE, count) ||
            XaceHook(XACE_RECEIVE_ACCESS, rClient(grab),
                     grab->window, xE, count))
            deliveries = 1;     /* don't send, but pretend we did */
        else if (level != CORE || !IsInterferingGrab(rClient(grab), dev, xE)) {
            deliveries = TryClientEvents(rClient(grab), dev,
                                         xE, count, mask, filter, grab);
        }
    }
    else
        BUG_WARN_MSG(rc != BadMatch,
                     "%s: conversion to mode %d failed on %d with %d\n",
                     dev->name, level, event->any.type, rc);

    free(xE);
    return deliveries;
}

Project: xserver
File: events.c

DeliverRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
{
    GrabPtr grab = device->deviceGrab.grab;
    xEvent *xi;
    int i, rc;
    int filter;

    rc = EventToXI2((InternalEvent *) ev, (xEvent **) &xi);
    if (rc != Success) {
        ErrorF("[Xi] %s: XI2 conversion failed in %s (%d)\n",
               __func__, device->name, rc);
        return;
    }

    if (grab)
        DeliverGrabbedEvent((InternalEvent *) ev, device, FALSE);

    filter = GetEventFilter(device, xi);

    for (i = 0; i < screenInfo.numScreens; i++) {
        WindowPtr root;
        InputClients *inputclients;

        root = screenInfo.screens[i]->root;
        if (!GetClientsForDelivery(device, root, xi, filter, &inputclients))
            continue;

        for (; inputclients; inputclients = inputclients->next) {
            ClientPtr c;        /* unused */
            Mask m;             /* unused */
            InputClients ic = *inputclients;

            /* Because we run through the list manually, copy the actual
             * list, shorten the copy to only have one client and then pass
             * that down to DeliverEventToInputClients. This way we avoid
             * double events on XI 2.1 clients that have a grab on the
             * device.
             */
            ic.next = NULL;

            if (!FilterRawEvents(rClient(&ic), grab, root))
                DeliverEventToInputClients(device, &ic, root, xi, 1,
                                           filter, NULL, &c, &m);
        }
    }

    free(xi);
}

Project: xserver
File: events.c

DeliverToWindowOwner(DeviceIntPtr dev, WindowPtr win,
                     xEvent *events, int count, Mask filter, GrabPtr grab)
{
    /* if nobody ever wants to see this event, skip some work */
    if (filter != CantBeFiltered &&
        !((wOtherEventMasks(win) | win->eventMask) & filter))
        return EVENT_SKIP;

    if (IsInterferingGrab(wClient(win), dev, events))
        return EVENT_SKIP;

    if (!XaceHook(XACE_RECEIVE_ACCESS, wClient(win), win, events, count)) {
        int attempt = TryClientEvents(wClient(win), dev, events,
                                      count, win->eventMask,
                                      filter, grab);

        if (attempt > 0)
            return EVENT_DELIVERED;
        if (attempt < 0)
            return EVENT_REJECTED;
    }

    return EVENT_NOT_DELIVERED;
}

Project: xserver
File: events.c

DetachFromMaster(DeviceIntPtr dev)
{
    if (IsFloating(dev))
        return;

    dev->saved_master_id = GetMaster(dev, MASTER_ATTACHED)->id;

    AttachDevice(NULL, dev, NULL);
}

Project: xserver
File: events.c

DevHasCursor(DeviceIntPtr pDev)
{
    return pDev->spriteInfo->spriteOwner;
}

Project: xserver
File: events.c

DeviceEnterLeaveEvent(DeviceIntPtr mouse,
                      int sourceid,
                      int type,
                      int mode, int detail, WindowPtr pWin, Window child)
{
    GrabPtr grab = mouse->deviceGrab.grab;
    xXIEnterEvent *event;
    WindowPtr focus;
    int filter;
    int btlen, len, i;
    DeviceIntPtr kbd;

    if ((mode == XINotifyPassiveGrab && type == XI_Leave) ||
        (mode == XINotifyPassiveUngrab && type == XI_Enter))
        return;

    btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0;
    btlen = bytes_to_int32(btlen);
    len = sizeof(xXIEnterEvent) + btlen * 4;

    event = calloc(1, len);
    event->type = GenericEvent;
    event->extension = IReqCode;
    event->evtype = type;
    event->length = (len - sizeof(xEvent)) / 4;
    event->buttons_len = btlen;
    event->detail = detail;
    event->time = currentTime.milliseconds;
    event->deviceid = mouse->id;
    event->sourceid = sourceid;
    event->mode = mode;
    event->root_x = double_to_fp1616(mouse->spriteInfo->sprite->hot.x);
    event->root_y = double_to_fp1616(mouse->spriteInfo->sprite->hot.y);

    for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
        if (BitIsOn(mouse->button->down, i))
            SetBit(&event[1], i);

    kbd = GetMaster(mouse, MASTER_KEYBOARD);
    if (kbd && kbd->key) {
        event->mods.base_mods = kbd->key->xkbInfo->state.base_mods;
        event->mods.latched_mods = kbd->key->xkbInfo->state.latched_mods;
        event->mods.locked_mods = kbd->key->xkbInfo->state.locked_mods;

        event->group.base_group = kbd->key->xkbInfo->state.base_group;
        event->group.latched_group = kbd->key->xkbInfo->state.latched_group;
        event->group.locked_group = kbd->key->xkbInfo->state.locked_group;
    }

    focus = (kbd) ? kbd->focus->win : None;
    if ((focus != NoneWin) &&
        ((pWin == focus) || (focus == PointerRootWin) || IsParent(focus, pWin)))
        event->focus = TRUE;

    FixUpEventFromWindow(mouse->spriteInfo->sprite, (xEvent *) event, pWin,
                         None, FALSE);

    filter = GetEventFilter(mouse, (xEvent *) event);

    if (grab && grab->grabtype == XI2) {
        Mask mask;

        mask = xi2mask_isset(grab->xi2mask, mouse, type);
        TryClientEvents(rClient(grab), mouse, (xEvent *) event, 1, mask, 1,
                        grab);
    }
    else {
        if (!WindowXI2MaskIsset(mouse, pWin, (xEvent *) event))
            goto out;
        DeliverEventsToWindow(mouse, pWin, (xEvent *) event, 1, filter,
                              NullGrab);
    }

 out:
    free(event);
}

Project: xserver
File: events.c

EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
{
    QdEventPtr tail = NULL;
    QdEventPtr qe;
    SpritePtr pSprite = device->spriteInfo->sprite;
    int eventlen;
    DeviceEvent *event = &ev->device_event;

    if (!xorg_list_is_empty(&syncEvents.pending))
        tail = xorg_list_last_entry(&syncEvents.pending, QdEventRec, next);

    NoticeTimeMillis(device, &ev->any.time);

    /* Fix for key repeating bug. */
    if (device->key != NULL && device->key->xkbInfo != NULL &&
        event->type == ET_KeyRelease)
        AccessXCancelRepeatKey(device->key->xkbInfo, event->detail.key);

    if (DeviceEventCallback) {
        DeviceEventInfoRec eventinfo;

        /*  The RECORD spec says that the root window field of motion events
         *  must be valid.  At this point, it hasn't been filled in yet, so
         *  we do it here.  The long expression below is necessary to get
         *  the current root window; the apparently reasonable alternative
         *  GetCurrentRootWindow()->drawable.id doesn't give you the right
         *  answer on the first motion event after a screen change because
         *  the data that GetCurrentRootWindow relies on hasn't been
         *  updated yet.
         */
        if (ev->any.type == ET_Motion)
            ev->device_event.root = pSprite->hotPhys.pScreen->root->drawable.id;

        eventinfo.event = ev;
        eventinfo.device = device;
        CallCallbacks(&DeviceEventCallback, (void *) &eventinfo);
    }

    if (event->type == ET_Motion) {
#ifdef PANORAMIX
        if (!noPanoramiXExtension) {
            event->root_x += pSprite->screen->x - screenInfo.screens[0]->x;
            event->root_y += pSprite->screen->y - screenInfo.screens[0]->y;
        }
#endif
        pSprite->hotPhys.x = event->root_x;
        pSprite->hotPhys.y = event->root_y;
        /* do motion compression, but not if from different devices */
        if (tail &&
            (tail->event->any.type == ET_Motion) &&
            (tail->device == device) &&
            (tail->pScreen == pSprite->hotPhys.pScreen)) {
            DeviceEvent *tailev = &tail->event->device_event;

            tailev->root_x = pSprite->hotPhys.x;
            tailev->root_y = pSprite->hotPhys.y;
            tailev->time = event->time;
            tail->months = currentTime.months;
            return;
        }
    }

    eventlen = event->length;

    qe = malloc(sizeof(QdEventRec) + eventlen);
    if (!qe)
        return;
    xorg_list_init(&qe->next);
    qe->device = device;
    qe->pScreen = pSprite->hotPhys.pScreen;
    qe->months = currentTime.months;
    qe->event = (InternalEvent *) (qe + 1);
    memcpy(qe->event, event, eventlen);
    xorg_list_append(&qe->next, &syncEvents.pending);
}

Project: xserver
File: events.c

EventIsDeliverable(DeviceIntPtr dev, int evtype, WindowPtr win)
{
    int rc = 0;
    int filter = 0;
    int type;
    OtherInputMasks *inputMasks = wOtherInputMasks(win);

    if ((type = GetXI2Type(evtype)) != 0) {
        if (inputMasks && xi2mask_isset(inputMasks->xi2mask, dev, type))
            rc |= EVENT_XI2_MASK;
    }

    if ((type = GetXIType(evtype)) != 0) {
        filter = event_get_filter_from_type(dev, type);

        /* Check for XI mask */
        if (inputMasks &&
            (inputMasks->deliverableEvents[dev->id] & filter) &&
            (inputMasks->inputEvents[dev->id] & filter))
            rc |= EVENT_XI1_MASK;

        /* Check for XI DontPropagate mask */
        if (inputMasks && (inputMasks->dontPropagateMask[dev->id] & filter))
            rc |= EVENT_DONT_PROPAGATE_MASK;

    }

    if ((type = GetCoreType(evtype)) != 0) {
        filter = event_get_filter_from_type(dev, type);

        /* Check for core mask */
        if ((win->deliverableEvents & filter) &&
            ((wOtherEventMasks(win) | win->eventMask) & filter))
            rc |= EVENT_CORE_MASK;

        /* Check for core DontPropagate mask */
        if (filter & wDontPropagateMask(win))
            rc |= EVENT_DONT_PROPAGATE_MASK;
    }

    return rc;
}

Project: xserver
File: events.c

EventMaskForClient(WindowPtr pWin, ClientPtr client)
{
    OtherClientsPtr other;

    if (wClient(pWin) == client)
        return pWin->eventMask;
    for (other = wOtherClients(pWin); other; other = other->next) {
        if (SameClient(other, client))
            return other->mask;
    }
    return 0;
}

Project: xserver
File: events.c

EventSelectForWindow(WindowPtr pWin, ClientPtr client, Mask mask)
{
    Mask check;
    OtherClients *others;
    DeviceIntPtr dev;
    int rc;

    if (mask & ~AllEventMasks) {
        client->errorValue = mask;
        return BadValue;
    }
    check = (mask & ManagerMask);
    if (check) {
        rc = XaceHook(XACE_RESOURCE_ACCESS, client, pWin->drawable.id,
                      RT_WINDOW, pWin, RT_NONE, NULL, DixManageAccess);
        if (rc != Success)
            return rc;
    }
    check = (mask & AtMostOneClient);
    if (check & (pWin->eventMask | wOtherEventMasks(pWin))) {
        /* It is illegal for two different clients to select on any of the
           events for AtMostOneClient. However, it is OK, for some client to
           continue selecting on one of those events.  */
        if ((wClient(pWin) != client) && (check & pWin->eventMask))
            return BadAccess;
        for (others = wOtherClients(pWin); others; others = others->next) {
            if (!SameClient(others, client) && (check & others->mask))
                return BadAccess;
        }
    }
    if (wClient(pWin) == client) {
        check = pWin->eventMask;
        pWin->eventMask = mask;
    }
    else {
        for (others = wOtherClients(pWin); others; others = others->next) {
            if (SameClient(others, client)) {
                check = others->mask;
                if (mask == 0) {
                    FreeResource(others->resource, RT_NONE);
                    return Success;
                }
                else
                    others->mask = mask;
                goto maskSet;
            }
        }
        check = 0;
        if (!pWin->optional && !MakeWindowOptional(pWin))
            return BadAlloc;
        others = malloc(sizeof(OtherClients));
        if (!others)
            return BadAlloc;
        others->mask = mask;
        others->resource = FakeClientID(client->index);
        others->next = pWin->optional->otherClients;
        pWin->optional->otherClients = others;
        if (!AddResource(others->resource, RT_OTHERCLIENT, (void *) pWin))
            return BadAlloc;
    }
 maskSet:
    if ((mask & PointerMotionHintMask) && !(check & PointerMotionHintMask)) {
        for (dev = inputInfo.devices; dev; dev = dev->next) {
            if (dev->valuator && dev->valuator->motionHintWindow == pWin)
                dev->valuator->motionHintWindow = NullWindow;
        }
    }
    RecalculateDeliverableEvents(pWin);
    return Success;
}

Project: xserver
File: events.c

EventSuppressForWindow(WindowPtr pWin, ClientPtr client,
                       Mask mask, Bool *checkOptional)
{
    int i, freed;

    if (mask & ~PropagateMask) {
        client->errorValue = mask;
        return BadValue;
    }
    if (pWin->dontPropagate)
        DontPropagateRefCnts[pWin->dontPropagate]--;
    if (!mask)
        i = 0;
    else {
        for (i = DNPMCOUNT, freed = 0; --i > 0;) {
            if (!DontPropagateRefCnts[i])
                freed = i;
            else if (mask == DontPropagateMasks[i])
                break;
        }
        if (!i && freed) {
            i = freed;
            DontPropagateMasks[i] = mask;
        }
    }
    if (i || !mask) {
        pWin->dontPropagate = i;
        if (i)
            DontPropagateRefCnts[i]++;
        if (pWin->optional) {
            pWin->optional->dontPropagateMask = mask;
            *checkOptional = TRUE;
        }
    }
    else {
        if (!pWin->optional && !MakeWindowOptional(pWin)) {
            if (pWin->dontPropagate)
                DontPropagateRefCnts[pWin->dontPropagate]++;
            return BadAlloc;
        }
        pWin->dontPropagate = 0;
        pWin->optional->dontPropagateMask = mask;
    }
    RecalculateDeliverableEvents(pWin);
    return Success;
}

Project: xserver
File: events.c

FilterRawEvents(const ClientPtr client, const GrabPtr grab, WindowPtr root)
{
    XIClientPtr client_xi_version;
    int cmp;

    /* device not grabbed -> don't filter */
    if (!grab)
        return FALSE;

    client_xi_version =
        dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);

    cmp = version_compare(client_xi_version->major_version,
                          client_xi_version->minor_version, 2, 0);
    /* XI 2.0: if device is grabbed, skip
       XI 2.1: if device is grabbed by us, skip, we've already delivered */
    if (cmp == 0)
        return TRUE;

    return (grab->window != root) ? FALSE : SameClient(grab, client);
}

Project: xserver
File: events.c

FindChildForEvent(SpritePtr pSprite, WindowPtr event)
{
    WindowPtr w = DeepestSpriteWin(pSprite);
    Window child = None;

    /* If the search ends up past the root should the child field be
       set to none or should the value in the argument be passed
       through. It probably doesn't matter since everyone calls
       this function with child == None anyway. */
    while (w) {
        /* If the source window is same as event window, child should be
           none.  Don't bother going all all the way back to the root. */

        if (w == event) {
            child = None;
            break;
        }

        if (w->parent == event) {
            child = w->drawable.id;
            break;
        }
        w = w->parent;
    }
    return child;
}

Project: xserver
File: events.c

FixUpEventFromWindow(SpritePtr pSprite,
                     xEvent *xE, WindowPtr pWin, Window child, Bool calcChild)
{
    int evtype;

    if (calcChild)
        child = FindChildForEvent(pSprite, pWin);

    if ((evtype = xi2_get_type(xE))) {
        xXIDeviceEvent *event = (xXIDeviceEvent *) xE;

        switch (evtype) {
        case XI_RawKeyPress:
        case XI_RawKeyRelease:
        case XI_RawButtonPress:
        case XI_RawButtonRelease:
        case XI_RawMotion:
        case XI_RawTouchBegin:
        case XI_RawTouchUpdate:
        case XI_RawTouchEnd:
        case XI_DeviceChanged:
        case XI_HierarchyChanged:
        case XI_PropertyEvent:
        case XI_BarrierHit:
        case XI_BarrierLeave:
            return;
        default:
            break;
        }

        event->root = RootWindow(pSprite)->drawable.id;
        event->event = pWin->drawable.id;

        if (evtype == XI_TouchOwnership) {
            event->child = child;
            return;
        }

        if (pSprite->hot.pScreen == pWin->drawable.pScreen) {
            event->event_x = event->root_x - double_to_fp1616(pWin->drawable.x);
            event->event_y = event->root_y - double_to_fp1616(pWin->drawable.y);
            event->child = child;
        }
        else {
            event->event_x = 0;
            event->event_y = 0;
            event->child = None;
        }

        if (event->evtype == XI_Enter || event->evtype == XI_Leave ||
            event->evtype == XI_FocusIn || event->evtype == XI_FocusOut)
            ((xXIEnterEvent *) event)->same_screen =
                (pSprite->hot.pScreen == pWin->drawable.pScreen);

    }
    else {
        XE_KBPTR.root = RootWindow(pSprite)->drawable.id;
        XE_KBPTR.event = pWin->drawable.id;
        if (pSprite->hot.pScreen == pWin->drawable.pScreen) {
            XE_KBPTR.sameScreen = xTrue;
            XE_KBPTR.child = child;
            XE_KBPTR.eventX = XE_KBPTR.rootX - pWin->drawable.x;
            XE_KBPTR.eventY = XE_KBPTR.rootY - pWin->drawable.y;
        }
        else {
            XE_KBPTR.sameScreen = xFalse;
            XE_KBPTR.child = None;
            XE_KBPTR.eventX = 0;
            XE_KBPTR.eventY = 0;
        }
    }
}

Project: xserver
File: events.c

void FreeSprite(DeviceIntPtr dev)
{
    if (DevHasCursor(dev) && dev->spriteInfo->sprite) {
        if (dev->spriteInfo->sprite->current)
            FreeCursor(dev->spriteInfo->sprite->current, None);
        free(dev->spriteInfo->sprite->spriteTrace);
        free(dev->spriteInfo->sprite);
    }
    dev->spriteInfo->sprite = NULL;
}

Project: xserver
File: events.c

FreezeThaw(DeviceIntPtr dev, Bool frozen)
{
    dev->deviceGrab.sync.frozen = frozen;
    if (frozen)
        dev->public.processInputProc = dev->public.enqueueInputProc;
    else
        dev->public.processInputProc = dev->public.realInputProc;
}

Project: xserver
File: events.c

GetClientsForDelivery(DeviceIntPtr dev, WindowPtr win,
                      xEvent *events, Mask filter, InputClients ** iclients)
{
    int rc = 0;

    if (core_get_type(events) != 0)
        *iclients = (InputClients *) wOtherClients(win);
    else if (xi2_get_type(events) != 0) {
        OtherInputMasks *inputMasks = wOtherInputMasks(win);

        /* Has any client selected for the event? */
        if (!WindowXI2MaskIsset(dev, win, events))
            goto out;
        *iclients = inputMasks->inputClients;
    }
    else {
        OtherInputMasks *inputMasks = wOtherInputMasks(win);

        /* Has any client selected for the event? */
        if (!inputMasks || !(inputMasks->inputEvents[dev->id] & filter))
            goto out;

        *iclients = inputMasks->inputClients;
    }

    rc = 1;
 out:
    return rc;
}

Project: xserver
File: events.c

GetCurrentRootWindow(DeviceIntPtr dev)
{
    return RootWindow(dev->spriteInfo->sprite);
}

Project: xserver
File: events.c

GetEventFilter(DeviceIntPtr dev, xEvent *event)
{
    int evtype = 0;

    if (event->u.u.type != GenericEvent)
        return event_get_filter_from_type(dev, event->u.u.type);
    else if ((evtype = xi2_get_type(event)))
        return event_get_filter_from_xi2type(evtype);
    ErrorF("[dix] Unknown event type %d. No filter\n", event->u.u.type);
    return 0;
}

Project: xserver
File: events.c

GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients * other)
{
    int evtype;

    /* XI2 filters are only ever 8 bit, so let's return a 8 bit mask */
    if ((evtype = xi2_get_type(event))) {
        return GetXI2MaskByte(other->xi2mask, dev, evtype);
    }
    else if (core_get_type(event) != 0)
        return other->mask[XIAllDevices];
    else
        return other->mask[dev->id];
}

Project: xserver
File: events.c

GetSpriteCursor(DeviceIntPtr pDev)
{
    return pDev->spriteInfo->sprite->current;
}

Project: xserver
File: events.c

GetSpriteWindow(DeviceIntPtr pDev)
{
    return pDev->spriteInfo->sprite->win;
}

Project: xserver
File: events.c

GetXI2MaskByte(XI2Mask *mask, DeviceIntPtr dev, int event_type)
{
    /* we just return the matching filter because that's the only use
     * for this mask anyway.
     */
    if (xi2mask_isset(mask, dev, event_type))
        return event_get_filter_from_xi2type(event_type);
    else
        return 0;
}

Project: xserver
File: events.c

GrabDevice(ClientPtr client, DeviceIntPtr dev,
           unsigned pointer_mode, unsigned keyboard_mode, Window grabWindow,
           unsigned ownerEvents, Time ctime, GrabMask *mask,
           int grabtype, Cursor curs, Window confineToWin, CARD8 *status)
{
    WindowPtr pWin, confineTo;
    GrabPtr grab;
    TimeStamp time;
    Mask access_mode = DixGrabAccess;
    int rc;
    GrabInfoPtr grabInfo = &dev->deviceGrab;
    CursorPtr cursor;

    UpdateCurrentTime();
    if ((keyboard_mode != GrabModeSync) && (keyboard_mode != GrabModeAsync)) {
        client->errorValue = keyboard_mode;
        return BadValue;
    }
    if ((pointer_mode != GrabModeSync) && (pointer_mode != GrabModeAsync)) {
        client->errorValue = pointer_mode;
        return BadValue;
    }
    if ((ownerEvents != xFalse) && (ownerEvents != xTrue)) {
        client->errorValue = ownerEvents;
        return BadValue;
    }

    rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess);
    if (rc != Success)
        return rc;

    if (confineToWin == None)
        confineTo = NullWindow;
    else {
        rc = dixLookupWindow(&confineTo, confineToWin, client,
                             DixSetAttrAccess);
        if (rc != Success)
            return rc;
    }

    if (curs == None)
        cursor = NullCursor;
    else {
        rc = dixLookupResourceByType((void **) &cursor, curs, RT_CURSOR,
                                     client, DixUseAccess);
        if (rc != Success) {
            client->errorValue = curs;
            return rc;
        }
        access_mode |= DixForceAccess;
    }

    if (keyboard_mode == GrabModeSync || pointer_mode == GrabModeSync)
        access_mode |= DixFreezeAccess;
    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
    if (rc != Success)
        return rc;

    time = ClientTimeToServerTime(ctime);
    grab = grabInfo->grab;
    if (grab && grab->grabtype != grabtype)
        *status = AlreadyGrabbed;
    else if (grab && !SameClient(grab, client))
        *status = AlreadyGrabbed;
    else if ((!pWin->realized) ||
             (confineTo &&
              !(confineTo->realized && BorderSizeNotEmpty(dev, confineTo))))
        *status = GrabNotViewable;
    else if ((CompareTimeStamps(time, currentTime) == LATER) ||
             (CompareTimeStamps(time, grabInfo->grabTime) == EARLIER))
        *status = GrabInvalidTime;
    else if (grabInfo->sync.frozen &&
             grabInfo->sync.other && !SameClient(grabInfo->sync.other, client))
        *status = GrabFrozen;
    else {
        GrabPtr tempGrab;

        tempGrab = AllocGrab(NULL);
        if (tempGrab == NULL)
            return BadAlloc;

        tempGrab->next = NULL;
        tempGrab->window = pWin;
        tempGrab->resource = client->clientAsMask;
        tempGrab->ownerEvents = ownerEvents;
        tempGrab->keyboardMode = keyboard_mode;
        tempGrab->pointerMode = pointer_mode;
        if (grabtype == CORE)
            tempGrab->eventMask = mask->core;
        else if (grabtype == XI)
            tempGrab->eventMask = mask->xi;
        else
            xi2mask_merge(tempGrab->xi2mask, mask->xi2mask);
        tempGrab->device = dev;
        tempGrab->cursor = RefCursor(cursor);
        tempGrab->confineTo = confineTo;
        tempGrab->grabtype = grabtype;
        (*grabInfo->ActivateGrab) (dev, tempGrab, time, FALSE);
        *status = GrabSuccess;

        FreeGrab(tempGrab);
    }
    return Success;
}

Project: xserver
File: events.c

InitEvents(void)
{
    int i;
    QdEventPtr qe, tmp;

    inputInfo.numDevices = 0;
    inputInfo.devices = (DeviceIntPtr) NULL;
    inputInfo.off_devices = (DeviceIntPtr) NULL;
    inputInfo.keyboard = (DeviceIntPtr) NULL;
    inputInfo.pointer = (DeviceIntPtr) NULL;

    for (i = 0; i < MAXDEVICES; i++) {
        DeviceIntRec dummy;
        memcpy(&event_filters[i], default_filter, sizeof(default_filter));

        dummy.id = i;
        NoticeTime(&dummy, currentTime);
        LastEventTimeToggleResetFlag(i, FALSE);
    }

    syncEvents.replayDev = (DeviceIntPtr) NULL;
    syncEvents.replayWin = NullWindow;
    if (syncEvents.pending.next)
        xorg_list_for_each_entry_safe(qe, tmp, &syncEvents.pending, next)
            free(qe);
    xorg_list_init(&syncEvents.pending);
    syncEvents.playingEvents = FALSE;
    syncEvents.time.months = 0;
    syncEvents.time.milliseconds = 0;   /* hardly matters */
    currentTime.months = 0;
    currentTime.milliseconds = GetTimeInMillis();
    for (i = 0; i < DNPMCOUNT; i++) {
        DontPropagateMasks[i] = 0;
        DontPropagateRefCnts[i] = 0;
    }

    InputEventList = InitEventList(GetMaximumEventsNum());
    if (!InputEventList)
        FatalError("[dix] Failed to allocate input event list.\n");
}

Project: xserver
File: events.c

InitializeSprite(DeviceIntPtr pDev, WindowPtr pWin)
{
    SpritePtr pSprite;
    ScreenPtr pScreen;
    CursorPtr pCursor;

    if (!pDev->spriteInfo->sprite) {
        DeviceIntPtr it;

        pDev->spriteInfo->sprite = (SpritePtr) calloc(1, sizeof(SpriteRec));
        if (!pDev->spriteInfo->sprite)
            FatalError("InitializeSprite: failed to allocate sprite struct");

        /* We may have paired another device with this device before our
         * device had a actual sprite. We need to check for this and reset the
         * sprite field for all paired devices.
         *
         * The VCK is always paired with the VCP before the VCP has a sprite.
         */
        for (it = inputInfo.devices; it; it = it->next) {
            if (it->spriteInfo->paired == pDev)
                it->spriteInfo->sprite = pDev->spriteInfo->sprite;
        }
        if (inputInfo.keyboard->spriteInfo->paired == pDev)
            inputInfo.keyboard->spriteInfo->sprite = pDev->spriteInfo->sprite;
    }

    pSprite = pDev->spriteInfo->sprite;
    pDev->spriteInfo->spriteOwner = TRUE;

    pScreen = (pWin) ? pWin->drawable.pScreen : (ScreenPtr) NULL;
    pSprite->hot.pScreen = pScreen;
    pSprite->hotPhys.pScreen = pScreen;
    if (pScreen) {
        pSprite->hotPhys.x = pScreen->width / 2;
        pSprite->hotPhys.y = pScreen->height / 2;
        pSprite->hotLimits.x2 = pScreen->width;
        pSprite->hotLimits.y2 = pScreen->height;
    }

    pSprite->hot = pSprite->hotPhys;
    pSprite->win = pWin;

    if (pWin) {
        pCursor = wCursor(pWin);
        pSprite->spriteTrace = (WindowPtr *) calloc(1, 32 * sizeof(WindowPtr));
        if (!pSprite->spriteTrace)
            FatalError("Failed to allocate spriteTrace");
        pSprite->spriteTraceSize = 32;

        RootWindow(pDev->spriteInfo->sprite) = pWin;
        pSprite->spriteTraceGood = 1;

        pSprite->pEnqueueScreen = pScreen;
        pSprite->pDequeueScreen = pSprite->pEnqueueScreen;

    }
    else {
        pCursor = NullCursor;
        pSprite->spriteTrace = NULL;
        pSprite->spriteTraceSize = 0;
        pSprite->spriteTraceGood = 0;
        pSprite->pEnqueueScreen = screenInfo.screens[0];
        pSprite->pDequeueScreen = pSprite->pEnqueueScreen;
    }
    pCursor = RefCursor(pCursor);
    if (pSprite->current)
        FreeCursor(pSprite->current, None);
    pSprite->current = pCursor;

    if (pScreen) {
        (*pScreen->RealizeCursor) (pDev, pScreen, pSprite->current);
        (*pScreen->CursorLimits) (pDev, pScreen, pSprite->current,
                                  &pSprite->hotLimits, &pSprite->physLimits);
        pSprite->confined = FALSE;

        (*pScreen->ConstrainCursor) (pDev, pScreen, &pSprite->physLimits);
        (*pScreen->SetCursorPosition) (pDev, pScreen, pSprite->hot.x,
                                       pSprite->hot.y, FALSE);
        (*pScreen->DisplayCursor) (pDev, pScreen, pSprite->current);
    }
#ifdef PANORAMIX
    if (!noPanoramiXExtension) {
        pSprite->hotLimits.x1 = -screenInfo.screens[0]->x;
        pSprite->hotLimits.y1 = -screenInfo.screens[0]->y;
        pSprite->hotLimits.x2 = PanoramiXPixWidth - screenInfo.screens[0]->x;
        pSprite->hotLimits.y2 = PanoramiXPixHeight - screenInfo.screens[0]->y;
        pSprite->physLimits = pSprite->hotLimits;
        pSprite->confineWin = NullWindow;
        pSprite->hotShape = NullRegion;
        pSprite->screen = pScreen;
        /* gotta UNINIT these someplace */
        RegionNull(&pSprite->Reg1);
        RegionNull(&pSprite->Reg2);
    }
#endif
}

Project: xserver
File: events.c

IsFloating(DeviceIntPtr dev)
{
    return !IsMaster(dev) && GetMaster(dev, MASTER_KEYBOARD) == NULL;
}

Project: xserver
File: events.c

IsInterferingGrab(ClientPtr client, DeviceIntPtr dev, xEvent *event)
{
    DeviceIntPtr it = inputInfo.devices;

    switch (event->u.u.type) {
    case KeyPress:
    case KeyRelease:
    case ButtonPress:
    case ButtonRelease:
    case MotionNotify:
    case EnterNotify:
    case LeaveNotify:
        break;
    default:
        return FALSE;
    }

    if (dev->deviceGrab.grab && SameClient(dev->deviceGrab.grab, client))
        return FALSE;

    while (it) {
        if (it != dev) {
            if (it->deviceGrab.grab && SameClient(it->deviceGrab.grab, client)
                && !it->deviceGrab.fromPassiveGrab) {
                if ((IsPointerDevice(it) && IsPointerDevice(dev)) ||
                    (IsKeyboardDevice(it) && IsKeyboardDevice(dev)))
                    return TRUE;
            }
        }
        it = it->next;
    }

    return FALSE;
}

Project: xserver
File: events.c

IsMaster(DeviceIntPtr dev)
{
    return dev->type == MASTER_POINTER || dev->type == MASTER_KEYBOARD;
}

Project: xserver
File: events.c

IsParent(WindowPtr a, WindowPtr b)
{
    for (b = b->parent; b; b = b->parent)
        if (b == a)
            return TRUE;
    return FALSE;
}

Project: xserver
File: events.c

IsPointerDevice(DeviceIntPtr dev)
{
    return (dev->type == MASTER_POINTER) ||
        (dev->valuator && dev->button) || (dev->valuator && !dev->key);
}

Project: xserver
File: events.c

IsWrongPointerBarrierClient(ClientPtr client, DeviceIntPtr dev, xEvent *event)
{
    xXIBarrierEvent *ev = (xXIBarrierEvent*)event;

    if (ev->type != GenericEvent || ev->extension != IReqCode)
        return FALSE;

    if (ev->evtype != XI_BarrierHit && ev->evtype != XI_BarrierLeave)
        return FALSE;

    return client->index != CLIENT_ID(ev->barrier);
}

Project: xserver
File: events.c

LastEventTime(int deviceid)
{
    return lastDeviceEventTime[deviceid].time;
}

Project: xserver
File: events.c

LastEventTimeToggleResetFlag(int deviceid, Bool state)
{
    lastDeviceEventTime[deviceid].reset = state;
}

Project: xserver
File: events.c

MatchForType(const GrabPtr grab, GrabPtr tmp, enum InputLevel level,
             int event_type)
{
    enum MatchFlags match;
    BOOL ignore_device = FALSE;
    int grabtype;
    int evtype;

    switch (level) {
    case XI2:
        grabtype = XI2;
        evtype = GetXI2Type(event_type);
        BUG_WARN(!evtype);
        match = XI2_MATCH;
        break;
    case XI:
        grabtype = XI;
        evtype = GetXIType(event_type);
        match = XI_MATCH;
        break;
    case CORE:
        grabtype = CORE;
        evtype = GetCoreType(event_type);
        match = CORE_MATCH;
        ignore_device = TRUE;
        break;
    default:
        return NO_MATCH;
    }

    tmp->grabtype = grabtype;
    tmp->type = evtype;

    if (tmp->type && GrabMatchesSecond(tmp, grab, ignore_device))
        return match;

    return NO_MATCH;
}

Project: xserver
File: events.c

MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents,
                           int count, Mask filter, ClientPtr dontClient)
{
    OtherClients *other;

    if (pWin->eventMask & filter) {
        if (wClient(pWin) == dontClient)
            return 0;
#ifdef PANORAMIX
        if (!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
            return XineramaTryClientEventsResult(wClient(pWin), NullGrab,
                                                 pWin->eventMask, filter);
#endif
        if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count))
            return 1;           /* don't send, but pretend we did */
        return TryClientEvents(wClient(pWin), NULL, pEvents, count,
                               pWin->eventMask, filter, NullGrab);
    }
    for (other = wOtherClients(pWin); other; other = other->next) {
        if (other->mask & filter) {
            if (SameClient(other, dontClient))
                return 0;
#ifdef PANORAMIX
            if (!noPanoramiXExtension && pWin->drawable.pScreen->myNum)
                return XineramaTryClientEventsResult(rClient(other), NullGrab,
                                                     other->mask, filter);
#endif
            if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin, pEvents,
                         count))
                return 1;       /* don't send, but pretend we did */
            return TryClientEvents(rClient(other), NULL, pEvents, count,
                                   other->mask, filter, NullGrab);
        }
    }
    return 2;
}

Project: xserver
File: events.c

MonthChangedOrBadTime(CARD32 *ms)
{
    /* If the ddx/OS is careless about not processing timestamped events from
     * different sources in sorted order, then it's possible for time to go
     * backwards when it should not.  Here we ensure a decent time.
     */
    if ((currentTime.milliseconds - *ms) > TIMESLOP)
        currentTime.months++;
    else
        *ms = currentTime.milliseconds;
}

Project: xserver
File: events.c

NewCurrentScreen(DeviceIntPtr pDev, ScreenPtr newScreen, int x, int y)
{
    DeviceIntPtr ptr;
    SpritePtr pSprite;

    ptr =
        IsFloating(pDev) ? pDev :
        GetXTestDevice(GetMaster(pDev, MASTER_POINTER));
    pSprite = ptr->spriteInfo->sprite;

    pSprite->hotPhys.x = x;
    pSprite->hotPhys.y = y;
#ifdef PANORAMIX
    if (!noPanoramiXExtension) {
        pSprite->hotPhys.x += newScreen->x - screenInfo.screens[0]->x;
        pSprite->hotPhys.y += newScreen->y - screenInfo.screens[0]->y;
        if (newScreen != pSprite->screen) {
            pSprite->screen = newScreen;
            /* Make sure we tell the DDX to update its copy of the screen */
            if (pSprite->confineWin)
                XineramaConfineCursorToWindow(ptr, pSprite->confineWin, TRUE);
            else
                XineramaConfineCursorToWindow(ptr, screenInfo.screens[0]->root,
                                              TRUE);
            /* if the pointer wasn't confined, the DDX won't get
               told of the pointer warp so we reposition it here */
            if (!syncEvents.playingEvents)
                (*pSprite->screen->SetCursorPosition) (ptr,
                                                       pSprite->screen,
                                                       pSprite->hotPhys.x +
                                                       screenInfo.screens[0]->
                                                       x - pSprite->screen->x,
                                                       pSprite->hotPhys.y +
                                                       screenInfo.screens[0]->
                                                       y - pSprite->screen->y,
                                                       FALSE);
        }
    }
    else
#endif
    if (newScreen != pSprite->hotPhys.pScreen)
        ConfineCursorToWindow(ptr, newScreen->root, TRUE, FALSE);
}

Project: xserver
File: events.c

NoticeEventTime(InternalEvent *ev, DeviceIntPtr dev)
{
    if (!syncEvents.playingEvents)
        NoticeTimeMillis(dev, &ev->any.time);
}

Project: xserver
File: events.c

NoticeTimeMillis(const DeviceIntPtr dev, CARD32 *ms)
{
    TimeStamp time;
    if (*ms < currentTime.milliseconds)
        MonthChangedOrBadTime(ms);
    time.months = currentTime.months;
    time.milliseconds = *ms;
    NoticeTime(dev, time);
}

Project: xserver
File: events.c

OtherClientGone(void *value, XID id)
{
    OtherClientsPtr other, prev;
    WindowPtr pWin = (WindowPtr) value;

    prev = 0;
    for (other = wOtherClients(pWin); other; other = other->next) {
        if (other->resource == id) {
            if (prev)
                prev->next = other->next;
            else {
                if (!(pWin->optional->otherClients = other->next))
                    CheckWindowOptionalNeed(pWin);
            }
            free(other);
            RecalculateDeliverableEvents(pWin);
            return Success;
        }
        prev = other;
    }
    FatalError("client not on event list");
}

Project: xserver
File: events.c

PickKeyboard(ClientPtr client)
{
    DeviceIntPtr ptr = PickPointer(client);
    DeviceIntPtr kbd = GetMaster(ptr, MASTER_KEYBOARD);

    if (!kbd) {
        ErrorF("[dix] ClientPointer not paired with a keyboard. This "
               "is a bug.\n");
    }

    return kbd;
}

Project: xserver
File: events.c

PickPointer(ClientPtr client)
{
    DeviceIntPtr it = inputInfo.devices;

    /* First, check if the client currently has a grab on a device. Even
     * keyboards count. */
    for (it = inputInfo.devices; it; it = it->next) {
        GrabPtr grab = it->deviceGrab.grab;

        if (grab && grab->grabtype == CORE && SameClient(grab, client)) {
            it = GetMaster(it, MASTER_POINTER);
            return it;          /* Always return a core grabbed device */
        }
    }

    if (!client->clientPtr) {
        it = inputInfo.devices;
        while (it) {
            if (IsMaster(it) && it->spriteInfo->spriteOwner) {
                client->clientPtr = it;
                break;
            }
            it = it->next;
        }
    }
    return client->clientPtr;
}

Project: xserver
File: events.c

PlayReleasedEvents(void)
{
    QdEventPtr tmp;
    QdEventPtr qe;
    DeviceIntPtr dev;
    DeviceIntPtr pDev;

 restart:
    xorg_list_for_each_entry_safe(qe, tmp, &syncEvents.pending, next) {
        if (!qe->device->deviceGrab.sync.frozen) {
            xorg_list_del(&qe->next);
            pDev = qe->device;
            if (qe->event->any.type == ET_Motion)
                CheckVirtualMotion(pDev, qe, NullWindow);
            syncEvents.time.months = qe->months;
            syncEvents.time.milliseconds = qe->event->any.time;
#ifdef PANORAMIX
            /* Translate back to the sprite screen since processInputProc
               will translate from sprite screen to screen 0 upon reentry
               to the DIX layer */
            if (!noPanoramiXExtension) {
                DeviceEvent *ev = &qe->event->device_event;

                switch (ev->type) {
                case ET_Motion:
                case ET_ButtonPress:
                case ET_ButtonRelease:
                case ET_KeyPress:
                case ET_KeyRelease:
                case ET_ProximityIn:
                case ET_ProximityOut:
                case ET_TouchBegin:
                case ET_TouchUpdate:
                case ET_TouchEnd:
                    ev->root_x += screenInfo.screens[0]->x -
                        pDev->spriteInfo->sprite->screen->x;
                    ev->root_y += screenInfo.screens[0]->y -
                        pDev->spriteInfo->sprite->screen->y;
                    break;
                default:
                    break;
                }

            }
#endif
            (*qe->device->public.processInputProc) (qe->event, qe->device);
            free(qe);
            for (dev = inputInfo.devices; dev && dev->deviceGrab.sync.frozen;
                 dev = dev->next);
            if (!dev)
                break;

            /* Playing the event may have unfrozen another device. */
            /* So to play it safe, restart at the head of the queue */
            goto restart;
        }
    }
}

Project: xserver
File: events.c

PointInBorderSize(WindowPtr pWin, int x, int y)
{
    BoxRec box;

    if (RegionContainsPoint(&pWin->borderSize, x, y, &box))
        return TRUE;

#ifdef PANORAMIX
    if (!noPanoramiXExtension &&
        XineramaSetWindowPntrs(inputInfo.pointer, pWin)) {
        SpritePtr pSprite = inputInfo.pointer->spriteInfo->sprite;
        int i;

        FOR_NSCREENS_FORWARD_SKIP(i) {
            if (RegionContainsPoint(&pSprite->windows[i]->borderSize,
                                    x + screenInfo.screens[0]->x -
                                    screenInfo.screens[i]->x,
                                    y + screenInfo.screens[0]->y -
                                    screenInfo.screens[i]->y, &box))
                return TRUE;
        }
    }
#endif
    return FALSE;
}

Project: xserver
File: events.c

PointerConfinedToScreen(DeviceIntPtr pDev)
{
    return pDev->spriteInfo->sprite->confined;
}

Project: xserver
File: events.c

PostNewCursor(DeviceIntPtr pDev)
{
    WindowPtr win;
    GrabPtr grab = pDev->deviceGrab.grab;
    SpritePtr pSprite = pDev->spriteInfo->sprite;
    CursorPtr pCursor;

    if (syncEvents.playingEvents)
        return;
    if (grab) {
        if (grab->cursor) {
            ChangeToCursor(pDev, grab->cursor);
            return;
        }
        if (IsParent(grab->window, pSprite->win))
            win = pSprite->win;
        else
            win = grab->window;
    }
    else
        win = pSprite->win;
    for (; win; win = win->parent) {
        if (win->optional) {
            pCursor = WindowGetDeviceCursor(win, pDev);
            if (!pCursor && win->optional->cursor != NullCursor)
                pCursor = win->optional->cursor;
            if (pCursor) {
                ChangeToCursor(pDev, pCursor);
                return;
            }
        }
    }
}

Project: xserver
File: events.c

ProcAllowEvents(ClientPtr client)
{
    TimeStamp time;
    DeviceIntPtr mouse = NULL;
    DeviceIntPtr keybd = NULL;

    REQUEST(xAllowEventsReq);

    REQUEST_SIZE_MATCH(xAllowEventsReq);
    UpdateCurrentTime();
    time = ClientTimeToServerTime(stuff->time);

    mouse = PickPointer(client);
    keybd = PickKeyboard(client);

    switch (stuff->mode) {
    case ReplayPointer:
        AllowSome(client, time, mouse, NOT_GRABBED);
        break;
    case SyncPointer:
        AllowSome(client, time, mouse, FREEZE_NEXT_EVENT);
        break;
    case AsyncPointer:
        AllowSome(client, time, mouse, THAWED);
        break;
    case ReplayKeyboard:
        AllowSome(client, time, keybd, NOT_GRABBED);
        break;
    case SyncKeyboard:
        AllowSome(client, time, keybd, FREEZE_NEXT_EVENT);
        break;
    case AsyncKeyboard:
        AllowSome(client, time, keybd, THAWED);
        break;
    case SyncBoth:
        AllowSome(client, time, keybd, FREEZE_BOTH_NEXT_EVENT);
        break;
    case AsyncBoth:
        AllowSome(client, time, keybd, THAWED_BOTH);
        break;
    default:
        client->errorValue = stuff->mode;
        return BadValue;
    }
    return Success;
}

Project: xserver
File: events.c

ProcGetInputFocus(ClientPtr client)
{
    DeviceIntPtr kbd = PickKeyboard(client);
    xGetInputFocusReply rep;
    FocusClassPtr focus = kbd->focus;
    int rc;

    /* REQUEST(xReq); */
    REQUEST_SIZE_MATCH(xReq);

    rc = XaceHook(XACE_DEVICE_ACCESS, client, kbd, DixGetFocusAccess);
    if (rc != Success)
        return rc;

    rep = (xGetInputFocusReply) {
        .type = X_Reply,
        .length = 0,
        .sequenceNumber = client->sequence,
        .revertTo = focus->revert
    };

    if (focus->win == NoneWin)
        rep.focus = None;
    else if (focus->win == PointerRootWin)
        rep.focus = PointerRoot;
    else
        rep.focus = focus->win->drawable.id;

    WriteReplyToClient(client, sizeof(xGetInputFocusReply), &rep);
    return Success;
}

Project: xserver
File: events.c

ProcGrabButton(ClientPtr client)
{
    WindowPtr pWin, confineTo;

    REQUEST(xGrabButtonReq);
    CursorPtr cursor;
    GrabPtr grab;
    DeviceIntPtr ptr, modifierDevice;
    Mask access_mode = DixGrabAccess;
    GrabMask mask;
    GrabParameters param;
    int rc;

    REQUEST_SIZE_MATCH(xGrabButtonReq);
    UpdateCurrentTime();
    if ((stuff->pointerMode != GrabModeSync) &&
        (stuff->pointerMode != GrabModeAsync)) {
        client->errorValue = stuff->pointerMode;
        return BadValue;
    }
    if ((stuff->keyboardMode != GrabModeSync) &&
        (stuff->keyboardMode != GrabModeAsync)) {
        client->errorValue = stuff->keyboardMode;
        return BadValue;
    }
    if ((stuff->modifiers != AnyModifier) &&
        (stuff->modifiers & ~AllModifiersMask)) {
        client->errorValue = stuff->modifiers;
        return BadValue;
    }
    if ((stuff->ownerEvents != xFalse) && (stuff->ownerEvents != xTrue)) {
        client->errorValue = stuff->ownerEvents;
        return BadValue;
    }
    if (stuff->eventMask & ~PointerGrabMask) {
        client->errorValue = stuff->eventMask;
        return BadValue;
    }
    rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixSetAttrAccess);
    if (rc != Success)
        return rc;
    if (stuff->confineTo == None)
        confineTo = NullWindow;
    else {
        rc = dixLookupWindow(&confineTo, stuff->confineTo, client,
                             DixSetAttrAccess);
        if (rc != Success)
            return rc;
    }
    if (stuff->cursor == None)
        cursor = NullCursor;
    else {
        rc = dixLookupResourceByType((void **) &cursor, stuff->cursor,
                                     RT_CURSOR, client, DixUseAccess);
        if (rc != Success) {
            client->errorValue = stuff->cursor;
            return rc;
        }
        access_mode |= DixForceAccess;
    }

    ptr = PickPointer(client);
    modifierDevice = GetMaster(ptr, MASTER_KEYBOARD);
    if (stuff->pointerMode == GrabModeSync ||
        stuff->keyboardMode == GrabModeSync)
        access_mode |= DixFreezeAccess;
    rc = XaceHook(XACE_DEVICE_ACCESS, client, ptr, access_mode);
    if (rc != Success)
        return rc;

    param = (GrabParameters) {
        .grabtype = CORE,
        .ownerEvents = stuff->ownerEvents,
        .this_device_mode = stuff->keyboardMode,
        .other_devices_mode = stuff->pointerMode,
        .modifiers = stuff->modifiers
    };

    mask.core = stuff->eventMask;

    grab = CreateGrab(client->index, ptr, modifierDevice, pWin,
                      CORE, &mask, &param, ButtonPress,
                      stuff->button, confineTo, cursor);
    if (!grab)
        return BadAlloc;
    return AddPassiveGrabToList(client, grab);
}

Project: xserver
File: events.c

ProcGrabKey(ClientPtr client)
{
    WindowPtr pWin;

    REQUEST(xGrabKeyReq);
    GrabPtr grab;
    DeviceIntPtr keybd = PickKeyboard(client);
    int rc;
    GrabParameters param;
    GrabMask mask;

    REQUEST_SIZE_MATCH(xGrabKeyReq);

    param = (GrabParameters) {
        .grabtype = CORE,
        .ownerEvents = stuff->ownerEvents,
        .this_device_mode = stuff->keyboardMode,
        .other_devices_mode = stuff->pointerMode,
        .modifiers = stuff->modifiers
    };

    rc = CheckGrabValues(client, &param);
    if (rc != Success)
        return rc;

    if (((stuff->key > keybd->key->xkbInfo->desc->max_key_code) ||
         (stuff->key < keybd->key->xkbInfo->desc->min_key_code))
        && (stuff->key != AnyKey)) {
        client->errorValue = stuff->key;
        return BadValue;
    }
    rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixSetAttrAccess);
    if (rc != Success)
        return rc;

    mask.core = (KeyPressMask | KeyReleaseMask);

    grab = CreateGrab(client->index, keybd, keybd, pWin, CORE, &mask,
                      &param, KeyPress, stuff->key, NullWindow, NullCursor);
    if (!grab)
        return BadAlloc;
    return AddPassiveGrabToList(client, grab);
}

Project: xserver
File: events.c

ProcGrabKeyboard(ClientPtr client)
{
    xGrabKeyboardReply rep;
    BYTE status;

    REQUEST(xGrabKeyboardReq);
    int result;
    DeviceIntPtr keyboard = PickKeyboard(client);
    GrabMask mask;

    REQUEST_SIZE_MATCH(xGrabKeyboardReq);
    UpdateCurrentTime();

    mask.core = KeyPressMask | KeyReleaseMask;

    result = GrabDevice(client, keyboard, stuff->pointerMode,
                        stuff->keyboardMode, stuff->grabWindow,
                        stuff->ownerEvents, stuff->time, &mask, CORE, None,
                        None, &status);

    if (result != Success)
        return result;

    rep = (xGrabKeyboardReply) {
        .type = X_Reply,
        .status = status,
        .sequenceNumber = client->sequence,
        .length = 0
    };
    WriteReplyToClient(client, sizeof(xGrabKeyboardReply), &rep);
    return Success;
}

Project: xserver
File: events.c

ProcGrabPointer(ClientPtr client)
{
    xGrabPointerReply rep;
    DeviceIntPtr device = PickPointer(client);
    GrabPtr grab;
    GrabMask mask;
    WindowPtr confineTo;
    BYTE status;

    REQUEST(xGrabPointerReq);
    int rc;

    REQUEST_SIZE_MATCH(xGrabPointerReq);
    UpdateCurrentTime();

    if (stuff->eventMask & ~PointerGrabMask) {
        client->errorValue = stuff->eventMask;
        return BadValue;
    }

    if (stuff->confineTo == None)
        confineTo = NullWindow;
    else {
        rc = dixLookupWindow(&confineTo, stuff->confineTo, client,
                             DixSetAttrAccess);
        if (rc != Success)
            return rc;
    }

    grab = device->deviceGrab.grab;

    if (grab && grab->confineTo && !confineTo)
        ConfineCursorToWindow(device, GetCurrentRootWindow(device), FALSE, FALSE);

    mask.core = stuff->eventMask;

    rc = GrabDevice(client, device, stuff->pointerMode, stuff->keyboardMode,
                    stuff->grabWindow, stuff->ownerEvents, stuff->time,
                    &mask, CORE, stuff->cursor, stuff->confineTo, &status);
    if (rc != Success)
        return rc;

    rep = (xGrabPointerReply) {
        .type = X_Reply,
        .status = status,
        .sequenceNumber = client->sequence,
        .length = 0
    };
    WriteReplyToClient(client, sizeof(xGrabPointerReply), &rep);
    return Success;
}

Project: xserver
File: events.c

ProcQueryPointer(ClientPtr client)
{
    xQueryPointerReply rep;
    WindowPtr pWin, t;
    DeviceIntPtr mouse = PickPointer(client);
    DeviceIntPtr keyboard;
    SpritePtr pSprite;
    int rc;

    REQUEST(xResourceReq);
    REQUEST_SIZE_MATCH(xResourceReq);

    rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
    if (rc != Success)
        return rc;
    rc = XaceHook(XACE_DEVICE_ACCESS, client, mouse, DixReadAccess);
    if (rc != Success && rc != BadAccess)
        return rc;

    keyboard = GetMaster(mouse, MASTER_KEYBOARD);

    pSprite = mouse->spriteInfo->sprite;
    if (mouse->valuator->motionHintWindow)
        MaybeStopHint(mouse, client);
    rep = (xQueryPointerReply) {
        .type = X_Reply,
        .sequenceNumber = client->sequence,
        .length = 0,
        .mask = event_get_corestate(mouse, keyboard),
        .root = (GetCurrentRootWindow(mouse))->drawable.id,
        .rootX = pSprite->hot.x,
        .rootY = pSprite->hot.y,
        .child = None
    };
    if (pSprite->hot.pScreen == pWin->drawable.pScreen) {
        rep.sameScreen = xTrue;
        rep.winX = pSprite->hot.x - pWin->drawable.x;
        rep.winY = pSprite->hot.y - pWin->drawable.y;
        for (t = pSprite->win; t; t = t->parent)
            if (t->parent == pWin) {
                rep.child = t->drawable.id;
                break;
            }
    }
    else {
        rep.sameScreen = xFalse;
        rep.winX = 0;
        rep.winY = 0;
    }

#ifdef PANORAMIX
    if (!noPanoramiXExtension) {
        rep.rootX += screenInfo.screens[0]->x;
        rep.rootY += screenInfo.screens[0]->y;
        if (stuff->id == rep.root) {
            rep.winX += screenInfo.screens[0]->x;
            rep.winY += screenInfo.screens[0]->y;
        }
    }
#endif

    if (rc == BadAccess) {
        rep.mask = 0;
        rep.child = None;
        rep.rootX = 0;
        rep.rootY = 0;
        rep.winX = 0;
        rep.winY = 0;
    }

    WriteReplyToClient(client, sizeof(xQueryPointerReply), &rep);

    return Success;
}

Project: xserver
File: events.c

ProcSetInputFocus(ClientPtr client)
{
    DeviceIntPtr kbd = PickKeyboard(client);

    REQUEST(xSetInputFocusReq);

    REQUEST_SIZE_MATCH(xSetInputFocusReq);

    return SetInputFocus(client, kbd, stuff->focus,
                         stuff->revertTo, stuff->time, FALSE);
}

Project: xserver
File: events.c

ProcUngrabButton(ClientPtr client)
{
    REQUEST(xUngrabButtonReq);
    WindowPtr pWin;
    GrabPtr tempGrab;
    int rc;
    DeviceIntPtr ptr;

    REQUEST_SIZE_MATCH(xUngrabButtonReq);
    UpdateCurrentTime();
    if ((stuff->modifiers != AnyModifier) &&
        (stuff->modifiers & ~AllModifiersMask)) {
        client->errorValue = stuff->modifiers;
        return BadValue;
    }
    rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixReadAccess);
    if (rc != Success)
        return rc;

    ptr = PickPointer(client);

    tempGrab = AllocGrab(NULL);
    if (!tempGrab)
        return BadAlloc;
    tempGrab->resource = client->clientAsMask;
    tempGrab->device = ptr;
    tempGrab->window = pWin;
    tempGrab->modifiersDetail.exact = stuff->modifiers;
    tempGrab->modifiersDetail.pMask = NULL;
    tempGrab->modifierDevice = GetMaster(ptr, MASTER_KEYBOARD);
    tempGrab->type = ButtonPress;
    tempGrab->detail.exact = stuff->button;
    tempGrab->grabtype = CORE;
    tempGrab->detail.pMask = NULL;
    tempGrab->next = NULL;

    if (!DeletePassiveGrabFromList(tempGrab))
        rc = BadAlloc;

    FreeGrab(tempGrab);
    return rc;
}

Project: xserver
File: events.c

ProcUngrabKey(ClientPtr client)
{
    REQUEST(xUngrabKeyReq);
    WindowPtr pWin;
    GrabPtr tempGrab;
    DeviceIntPtr keybd = PickKeyboard(client);
    int rc;

    REQUEST_SIZE_MATCH(xUngrabKeyReq);
    rc = dixLookupWindow(&pWin, stuff->grabWindow, client, DixGetAttrAccess);
    if (rc != Success)
        return rc;

    if (((stuff->key > keybd->key->xkbInfo->desc->max_key_code) ||
         (stuff->key < keybd->key->xkbInfo->desc->min_key_code))
        && (stuff->key != AnyKey)) {
        client->errorValue = stuff->key;
        return BadValue;
    }
    if ((stuff->modifiers != AnyModifier) &&
        (stuff->modifiers & ~AllModifiersMask)) {
        client->errorValue = stuff->modifiers;
        return BadValue;
    }
    tempGrab = AllocGrab(NULL);
    if (!tempGrab)
        return BadAlloc;
    tempGrab->resource = client->clientAsMask;
    tempGrab->device = keybd;
    tempGrab->window = pWin;
    tempGrab->modifiersDetail.exact = stuff->modifiers;
    tempGrab->modifiersDetail.pMask = NULL;
    tempGrab->modifierDevice = keybd;
    tempGrab->type = KeyPress;
    tempGrab->grabtype = CORE;
    tempGrab->detail.exact = stuff->key;
    tempGrab->detail.pMask = NULL;
    tempGrab->next = NULL;

    if (!DeletePassiveGrabFromList(tempGrab))
        rc = BadAlloc;

    FreeGrab(tempGrab);

    return rc;
}

Project: xserver
File: events.c

ProcUngrabKeyboard(ClientPtr client)
{
    DeviceIntPtr device = PickKeyboard(client);
    GrabPtr grab;
    TimeStamp time;

    REQUEST(xResourceReq);

    REQUEST_SIZE_MATCH(xResourceReq);
    UpdateCurrentTime();

    grab = device->deviceGrab.grab;

    time = ClientTimeToServerTime(stuff->id);
    if ((CompareTimeStamps(time, currentTime) != LATER) &&
        (CompareTimeStamps(time, device->deviceGrab.grabTime) != EARLIER) &&
        (grab) && SameClient(grab, client) && grab->grabtype == CORE)
        (*device->deviceGrab.DeactivateGrab) (device);
    return Success;
}

Project: xserver
File: events.c

ProcUngrabPointer(ClientPtr client)
{
    DeviceIntPtr device = PickPointer(client);
    GrabPtr grab;
    TimeStamp time;

    REQUEST(xResourceReq);

    REQUEST_SIZE_MATCH(xResourceReq);
    UpdateCurrentTime();
    grab = device->deviceGrab.grab;

    time = ClientTimeToServerTime(stuff->id);
    if ((CompareTimeStamps(time, currentTime) != LATER) &&
        (CompareTimeStamps(time, device->deviceGrab.grabTime) != EARLIER) &&
        (grab) && SameClient(grab, client))
        (*device->deviceGrab.DeactivateGrab) (device);
    return Success;
}

Project: xserver
File: events.c

ProcWarpPointer(ClientPtr client)
{
    WindowPtr dest = NULL;
    int x, y, rc;
    ScreenPtr newScreen;
    DeviceIntPtr dev, tmp;
    SpritePtr pSprite;

    REQUEST(xWarpPointerReq);
    REQUEST_SIZE_MATCH(xWarpPointerReq);

    dev = PickPointer(client);

    for (tmp = inputInfo.devices; tmp; tmp = tmp->next) {
        if (GetMaster(tmp, MASTER_ATTACHED) == dev) {
            rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixWriteAccess);
            if (rc != Success)
                return rc;
        }
    }

    if (dev->lastSlave)
        dev = dev->lastSlave;
    pSprite = dev->spriteInfo->sprite;

#ifdef PANORAMIX
    if (!noPanoramiXExtension)
        return XineramaWarpPointer(client);
#endif

    if (stuff->dstWid != None) {
        rc = dixLookupWindow(&dest, stuff->dstWid, client, DixGetAttrAccess);
        if (rc != Success)
            return rc;
    }
    x = pSprite->hotPhys.x;
    y = pSprite->hotPhys.y;

    if (stuff->srcWid != None) {
        int winX, winY;
        XID winID = stuff->srcWid;
        WindowPtr source;

        rc = dixLookupWindow(&source, winID, client, DixGetAttrAccess);
        if (rc != Success)
            return rc;

        winX = source->drawable.x;
        winY = source->drawable.y;
        if (source->drawable.pScreen != pSprite->hotPhys.pScreen ||
            x < winX + stuff->srcX ||
            y < winY + stuff->srcY ||
            (stuff->srcWidth != 0 &&
             winX + stuff->srcX + (int) stuff->srcWidth < x) ||
            (stuff->srcHeight != 0 &&
             winY + stuff->srcY + (int) stuff->srcHeight < y) ||
            (source->parent && !PointInWindowIsVisible(source, x, y)))
            return Success;
    }
    if (dest) {
        x = dest->drawable.x;
        y = dest->drawable.y;
        newScreen = dest->drawable.pScreen;
    }
    else
        newScreen = pSprite->hotPhys.pScreen;

    x += stuff->dstX;
    y += stuff->dstY;

    if (x < 0)
        x = 0;
    else if (x >= newScreen->width)
        x = newScreen->width - 1;
    if (y < 0)
        y = 0;
    else if (y >= newScreen->height)
        y = newScreen->height - 1;

    if (newScreen == pSprite->hotPhys.pScreen) {
        if (x < pSprite->physLimits.x1)
            x = pSprite->physLimits.x1;
        else if (x >= pSprite->physLimits.x2)
            x = pSprite->physLimits.x2 - 1;
        if (y < pSprite->physLimits.y1)
            y = pSprite->physLimits.y1;
        else if (y >= pSprite->physLimits.y2)
            y = pSprite->physLimits.y2 - 1;
        if (pSprite->hotShape)
            ConfineToShape(dev, pSprite->hotShape, &x, &y);
        (*newScreen->SetCursorPosition) (dev, newScreen, x, y, TRUE);
    }
    else if (!PointerConfinedToScreen(dev)) {
        NewCurrentScreen(dev, newScreen, x, y);
    }
    if (*newScreen->CursorWarpedTo)
        (*newScreen->CursorWarpedTo) (dev, newScreen, client,
                                      dest, pSprite, x, y);
    return Success;
}

Project: xserver
File: events.c

ReattachToOldMaster(DeviceIntPtr dev)
{
    DeviceIntPtr master = NULL;

    if (IsMaster(dev))
        return;

    dixLookupDevice(&master, dev->saved_master_id, serverClient, DixUseAccess);

    if (master) {
        AttachDevice(serverClient, dev, master);
        dev->saved_master_id = 0;
    }
}

Project: xserver
File: events.c

RecalculateDeliverableEvents(WindowPtr pWin)
{
    OtherClients *others;
    WindowPtr pChild;

    pChild = pWin;
    while (1) {
        if (pChild->optional) {
            pChild->optional->otherEventMasks = 0;
            for (others = wOtherClients(pChild); others; others = others->next) {
                pChild->optional->otherEventMasks |= others->mask;
            }
        }
        pChild->deliverableEvents = pChild->eventMask |
            wOtherEventMasks(pChild);
        if (pChild->parent)
            pChild->deliverableEvents |=
                (pChild->parent->deliverableEvents &
                 ~wDontPropagateMask(pChild) & PropagateMask);
        if (pChild->firstChild) {
            pChild = pChild->firstChild;
            continue;
        }
        while (!pChild->nextSib && (pChild != pWin))
            pChild = pChild->parent;
        if (pChild == pWin)
            break;
        pChild = pChild->nextSib;
    }
}

Project: xserver
File: events.c

ReinitializeRootWindow(WindowPtr win, int xoff, int yoff)
{
    GrabPtr grab;
    DeviceIntPtr pDev;
    SpritePtr pSprite;

    if (noPanoramiXExtension)
        return;

    pDev = inputInfo.devices;
    while (pDev) {
        if (DevHasCursor(pDev)) {
            pSprite = pDev->spriteInfo->sprite;
            pSprite->hot.x -= xoff;
            pSprite->hot.y -= yoff;

            pSprite->hotPhys.x -= xoff;
            pSprite->hotPhys.y -= yoff;

            pSprite->hotLimits.x1 -= xoff;
            pSprite->hotLimits.y1 -= yoff;
            pSprite->hotLimits.x2 -= xoff;
            pSprite->hotLimits.y2 -= yoff;

            if (RegionNotEmpty(&pSprite->Reg1))
                RegionTranslate(&pSprite->Reg1, xoff, yoff);
            if (RegionNotEmpty(&pSprite->Reg2))
                RegionTranslate(&pSprite->Reg2, xoff, yoff);

            /* FIXME: if we call ConfineCursorToWindow, must we do anything else? */
            if ((grab = pDev->deviceGrab.grab) && grab->confineTo) {
                if (grab->confineTo->drawable.pScreen
                    != pSprite->hotPhys.pScreen)
                    pSprite->hotPhys.x = pSprite->hotPhys.y = 0;
                ConfineCursorToWindow(pDev, grab->confineTo, TRUE, TRUE);
            }
            else
                ConfineCursorToWindow(pDev,
                                      pSprite->hotPhys.pScreen->root,
                                      TRUE, FALSE);

        }
        pDev = pDev->next;
    }
}

Project: xserver
File: events.c

ReleaseActiveGrabs(ClientPtr client)
{
    DeviceIntPtr dev;
    Bool done;

    /* XXX CloseDownClient should remove passive grabs before
     * releasing active grabs.
     */
    do {
        done = TRUE;
        for (dev = inputInfo.devices; dev; dev = dev->next) {
            if (dev->deviceGrab.grab &&
                SameClient(dev->deviceGrab.grab, client)) {
                (*dev->deviceGrab.DeactivateGrab) (dev);
                done = FALSE;
            }
        }
    } while (!done);
}

Project: xserver
File: events.c

ScreenRestructured(ScreenPtr pScreen)
{
    GrabPtr grab;
    DeviceIntPtr pDev;

    for (pDev = inputInfo.devices; pDev; pDev = pDev->next) {
        if (!IsFloating(pDev) && !DevHasCursor(pDev))
            continue;

        /* GrabDevice doesn't have a confineTo field, so we don't need to
         * worry about it. */
        if ((grab = pDev->deviceGrab.grab) && grab->confineTo) {
            if (grab->confineTo->drawable.pScreen
                != pDev->spriteInfo->sprite->hotPhys.pScreen)
                pDev->spriteInfo->sprite->hotPhys.x =
                    pDev->spriteInfo->sprite->hotPhys.y = 0;
            ConfineCursorToWindow(pDev, grab->confineTo, TRUE, TRUE);
        }
        else
            ConfineCursorToWindow(pDev,
                                  pDev->spriteInfo->sprite->hotPhys.pScreen->
                                  root, TRUE, FALSE);
    }
}

Project: xserver
File: events.c

SetClientPointer(ClientPtr client, DeviceIntPtr device)
{
    int rc = XaceHook(XACE_DEVICE_ACCESS, client, device, DixUseAccess);

    if (rc != Success)
        return rc;

    if (!IsMaster(device)) {
        ErrorF("[dix] Need master device for ClientPointer. This is a bug.\n");
        return BadDevice;
    }
    else if (!device->spriteInfo->spriteOwner) {
        ErrorF("[dix] Device %d does not have a sprite. "
               "Cannot be ClientPointer\n", device->id);
        return BadDevice;
    }
    client->clientPtr = device;
    return Success;
}

Project: xserver
File: events.c

SetCriticalEvent(int event)
{
    if (event >= MAXEVENTS)
        FatalError("SetCriticalEvent: bogus event number");
    criticalEvents[event >> 3] |= 1 << (event & 7);
}

Project: xserver
File: events.c

SetInputFocus(ClientPtr client,
              DeviceIntPtr dev,
              Window focusID, CARD8 revertTo, Time ctime, Bool followOK)
{
    FocusClassPtr focus;
    WindowPtr focusWin;
    int mode, rc;
    TimeStamp time;
    DeviceIntPtr keybd;         /* used for FollowKeyboard or FollowKeyboardWin */

    UpdateCurrentTime();
    if ((revertTo != RevertToParent) &&
        (revertTo != RevertToPointerRoot) &&
        (revertTo != RevertToNone) &&
        ((revertTo != RevertToFollowKeyboard) || !followOK)) {
        client->errorValue = revertTo;
        return BadValue;
    }
    time = ClientTimeToServerTime(ctime);

    keybd = GetMaster(dev, KEYBOARD_OR_FLOAT);

    if ((focusID == None) || (focusID == PointerRoot))
        focusWin = (WindowPtr) (long) focusID;
    else if ((focusID == FollowKeyboard) && followOK) {
        focusWin = keybd->focus->win;
    }
    else {
        rc = dixLookupWindow(&focusWin, focusID, client, DixSetAttrAccess);
        if (rc != Success)
            return rc;
        /* It is a match error to try to set the input focus to an
           unviewable window. */
        if (!focusWin->realized)
            return BadMatch;
    }
    rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixSetFocusAccess);
    if (rc != Success)
        return Success;

    focus = dev->focus;
    if ((CompareTimeStamps(time, currentTime) == LATER) ||
        (CompareTimeStamps(time, focus->time) == EARLIER))
        return Success;
    mode = (dev->deviceGrab.grab) ? NotifyWhileGrabbed : NotifyNormal;
    if (focus->win == FollowKeyboardWin) {
        if (!ActivateFocusInGrab(dev, keybd->focus->win, focusWin))
            DoFocusEvents(dev, keybd->focus->win, focusWin, mode);
    }
    else {
        if (!ActivateFocusInGrab(dev, focus->win, focusWin))
            DoFocusEvents(dev, focus->win, focusWin, mode);
    }
    focus->time = time;
    focus->revert = revertTo;
    if (focusID == FollowKeyboard)
        focus->win = FollowKeyboardWin;
    else
        focus->win = focusWin;
    if ((focusWin == NoneWin) || (focusWin == PointerRootWin))
        focus->traceGood = 0;
    else {
        int depth = 0;
        WindowPtr pWin;

        for (pWin = focusWin; pWin; pWin = pWin->parent)
            depth++;
        if (depth > focus->traceSize) {
            focus->traceSize = depth + 1;
            focus->trace = reallocarray(focus->trace, focus->traceSize,
                                        sizeof(WindowPtr));
        }
        focus->traceGood = depth;
        for (pWin = focusWin, depth--; pWin; pWin = pWin->parent, depth--)
            focus->trace[depth] = pWin;
    }
    return Success;
}

Project: xserver
File: events.c

SetMaskForEvent(int deviceid, Mask mask, int event)
{
    if (deviceid < 0 || deviceid >= MAXDEVICES)
        FatalError("SetMaskForEvent: bogus device id");
    event_filters[deviceid][event] = mask;
}

Project: xserver
File: events.c

SyntheticMotion(DeviceIntPtr dev, int x, int y)
{
    int screenno = 0;

#ifdef PANORAMIX
    if (!noPanoramiXExtension)
        screenno = dev->spriteInfo->sprite->screen->myNum;
#endif
    PostSyntheticMotion(dev, x, y, screenno,
                        (syncEvents.playingEvents) ? syncEvents.time.
                        milliseconds : currentTime.milliseconds);

}

Project: xserver
File: events.c

UpdateSpriteForScreen(DeviceIntPtr pDev, ScreenPtr pScreen)
{
    SpritePtr pSprite = NULL;
    WindowPtr win = NULL;
    CursorPtr pCursor;

    if (!pScreen)
        return;

    if (!pDev->spriteInfo->sprite)
        return;

    pSprite = pDev->spriteInfo->sprite;

    win = pScreen->root;

    pSprite->hotPhys.pScreen = pScreen;
    pSprite->hot = pSprite->hotPhys;
    pSprite->hotLimits.x2 = pScreen->width;
    pSprite->hotLimits.y2 = pScreen->height;
    pSprite->win = win;
    pCursor = RefCursor(wCursor(win));
    if (pSprite->current)
        FreeCursor(pSprite->current, 0);
    pSprite->current = pCursor;
    pSprite->spriteTraceGood = 1;
    pSprite->spriteTrace[0] = win;
    (*pScreen->CursorLimits) (pDev,
                              pScreen,
                              pSprite->current,
                              &pSprite->hotLimits, &pSprite->physLimits);
    pSprite->confined = FALSE;
    (*pScreen->ConstrainCursor) (pDev, pScreen, &pSprite->physLimits);
    (*pScreen->DisplayCursor) (pDev, pScreen, pSprite->current);

#ifdef PANORAMIX
    if (!noPanoramiXExtension) {
        pSprite->hotLimits.x1 = -screenInfo.screens[0]->x;
        pSprite->hotLimits.y1 = -screenInfo.screens[0]->y;
        pSprite->hotLimits.x2 = PanoramiXPixWidth - screenInfo.screens[0]->x;
        pSprite->hotLimits.y2 = PanoramiXPixHeight - screenInfo.screens[0]->y;
        pSprite->physLimits = pSprite->hotLimits;
        pSprite->screen = pScreen;
    }
#endif
}

Project: xserver
File: events.c

UpdateTouchesForGrab(DeviceIntPtr mouse)
{
    int i;

    if (!mouse->touch || mouse->deviceGrab.fromPassiveGrab)
        return;

    for (i = 0; i < mouse->touch->num_touches; i++) {
        TouchPointInfoPtr ti = mouse->touch->touches + i;
        TouchListener *listener = &ti->listeners[0];
        GrabPtr grab = mouse->deviceGrab.grab;

        if (ti->active &&
            CLIENT_BITS(listener->listener) == grab->resource) {
            listener->listener = grab->resource;
            listener->level = grab->grabtype;
            listener->state = LISTENER_IS_OWNER;
            listener->window = grab->window;

            if (grab->grabtype == CORE || grab->grabtype == XI ||
                !xi2mask_isset(grab->xi2mask, mouse, XI_TouchBegin))
                listener->type = LISTENER_POINTER_GRAB;
            else
                listener->type = LISTENER_GRAB;
            if (listener->grab)
                FreeGrab(listener->grab);
            listener->grab = AllocGrab(grab);
        }
    }
}

Project: xserver
File: events.c

WindowXI2MaskIsset(DeviceIntPtr dev, WindowPtr win, xEvent *ev)
{
    OtherInputMasks *inputMasks = wOtherInputMasks(win);
    int evtype;

    if (!inputMasks || xi2_get_type(ev) == 0)
        return 0;

    evtype = ((xGenericEvent *) ev)->evtype;

    return xi2mask_isset(inputMasks->xi2mask, dev, evtype);
}

Project: xserver
File: events.c

WindowsRestructured(void)
{
    DeviceIntPtr pDev = inputInfo.devices;

    while (pDev) {
        if (IsMaster(pDev) || IsFloating(pDev))
            CheckMotion(NULL, pDev);
        pDev = pDev->next;
    }
}

Project: xserver
File: events.c

XItoCoreType(int xitype)
{
    int coretype = 0;

    if (xitype == DeviceMotionNotify)
        coretype = MotionNotify;
    else if (xitype == DeviceButtonPress)
        coretype = ButtonPress;
    else if (xitype == DeviceButtonRelease)
        coretype = ButtonRelease;
    else if (xitype == DeviceKeyPress)
        coretype = KeyPress;
    else if (xitype == DeviceKeyRelease)
        coretype = KeyRelease;

    return coretype;
}

Project: xserver
File: events.c

XYToWindow(SpritePtr pSprite, int x, int y)
{
    ScreenPtr pScreen = RootWindow(pSprite)->drawable.pScreen;

    return (*pScreen->XYToWindow)(pScreen, pSprite, x, y);
}

Project: xserver
File: events.c

XineramaConfineCursorToWindow(DeviceIntPtr pDev,
                              WindowPtr pWin, Bool generateEvents)
{
    SpritePtr pSprite = pDev->spriteInfo->sprite;

    int x, y, off_x, off_y, i;

    if (!XineramaSetWindowPntrs(pDev, pWin))
        return;

    i = PanoramiXNumScreens - 1;

    RegionCopy(&pSprite->Reg1, &pSprite->windows[i]->borderSize);
    off_x = screenInfo.screens[i]->x;
    off_y = screenInfo.screens[i]->y;

    while (i--) {
        x = off_x - screenInfo.screens[i]->x;
        y = off_y - screenInfo.screens[i]->y;

        if (x || y)
            RegionTranslate(&pSprite->Reg1, x, y);

        RegionUnion(&pSprite->Reg1, &pSprite->Reg1,
                    &pSprite->windows[i]->borderSize);

        off_x = screenInfo.screens[i]->x;
        off_y = screenInfo.screens[i]->y;
    }

    pSprite->hotLimits = *RegionExtents(&pSprite->Reg1);

    if (RegionNumRects(&pSprite->Reg1) > 1)
        pSprite->hotShape = &pSprite->Reg1;
    else
        pSprite->hotShape = NullRegion;

    pSprite->confined = FALSE;
    pSprite->confineWin =
        (pWin == screenInfo.screens[0]->root) ? NullWindow : pWin;

    CheckPhysLimits(pDev, pSprite->current, generateEvents, FALSE, NULL);
}

Project: xserver
File: events.c

XineramaConstrainCursor(DeviceIntPtr pDev)
{
    SpritePtr pSprite = pDev->spriteInfo->sprite;
    ScreenPtr pScreen;
    BoxRec newBox;

    pScreen = pSprite->screen;
    newBox = pSprite->physLimits;

    /* Translate the constraining box to the screen
       the sprite is actually on */
    newBox.x1 += screenInfo.screens[0]->x - pScreen->x;
    newBox.x2 += screenInfo.screens[0]->x - pScreen->x;
    newBox.y1 += screenInfo.screens[0]->y - pScreen->y;
    newBox.y2 += screenInfo.screens[0]->y - pScreen->y;

    (*pScreen->ConstrainCursor) (pDev, pScreen, &newBox);
}

Project: xserver
File: events.c

XineramaGetCursorScreen(DeviceIntPtr pDev)
{
    if (!noPanoramiXExtension) {
        return pDev->spriteInfo->sprite->screen->myNum;
    }
    else {
        return 0;
    }
}

Project: xserver
File: events.c

XineramaPointInWindowIsVisible(WindowPtr pWin, int x, int y)
{
    BoxRec box;
    int i, xoff, yoff;

    if (!pWin->realized)
        return FALSE;

    if (RegionContainsPoint(&pWin->borderClip, x, y, &box))
        return TRUE;

    if (!XineramaSetWindowPntrs(inputInfo.pointer, pWin))
         return FALSE;

    xoff = x + screenInfo.screens[0]->x;
    yoff = y + screenInfo.screens[0]->y;

    FOR_NSCREENS_FORWARD_SKIP(i) {
        pWin = inputInfo.pointer->spriteInfo->sprite->windows[i];

        x = xoff - screenInfo.screens[i]->x;
        y = yoff - screenInfo.screens[i]->y;

        if (RegionContainsPoint(&pWin->borderClip, x, y, &box)
            && (!wInputShape(pWin) ||
                RegionContainsPoint(wInputShape(pWin),
                                    x - pWin->drawable.x,
                                    y - pWin->drawable.y, &box)))
            return TRUE;

    }

    return FALSE;
}

Project: xserver
File: events.c

XineramaSetCursorPosition(DeviceIntPtr pDev, int x, int y, Bool generateEvent)
{
    ScreenPtr pScreen;
    int i;
    SpritePtr pSprite = pDev->spriteInfo->sprite;

    /* x,y are in Screen 0 coordinates.  We need to decide what Screen
       to send the message too and what the coordinates relative to
       that screen are. */

    pScreen = pSprite->screen;
    x += screenInfo.screens[0]->x;
    y += screenInfo.screens[0]->y;

    if (!point_on_screen(pScreen, x, y)) {
        FOR_NSCREENS(i) {
            if (i == pScreen->myNum)
                continue;
            if (point_on_screen(screenInfo.screens[i], x, y)) {
                pScreen = screenInfo.screens[i];
                break;
            }
        }
    }

    pSprite->screen = pScreen;
    pSprite->hotPhys.x = x - screenInfo.screens[0]->x;
    pSprite->hotPhys.y = y - screenInfo.screens[0]->y;
    x -= pScreen->x;
    y -= pScreen->y;

    return (*pScreen->SetCursorPosition) (pDev, pScreen, x, y, generateEvent);
}

Project: xserver
File: events.c

XineramaSetWindowPntrs(DeviceIntPtr pDev, WindowPtr pWin)
{
    SpritePtr pSprite = pDev->spriteInfo->sprite;

    if (pWin == screenInfo.screens[0]->root) {
        int i;

        FOR_NSCREENS(i)
            pSprite->windows[i] = screenInfo.screens[i]->root;
    }
    else {
        PanoramiXRes *win;
        int rc, i;

        rc = dixLookupResourceByType((void **) &win, pWin->drawable.id,
                                     XRT_WINDOW, serverClient, DixReadAccess);
        if (rc != Success)
            return FALSE;

        FOR_NSCREENS(i) {
            rc = dixLookupWindow(pSprite->windows + i, win->info[i].id,
                                 serverClient, DixReadAccess);
            if (rc != Success)  /* window is being unmapped */
                return FALSE;
        }
    }
    return TRUE;
}

Project: xserver
File: events.c

XineramaTryClientEventsResult(ClientPtr client,
                              GrabPtr grab, Mask mask, Mask filter)
{
    if ((client) && (client != serverClient) && (!client->clientGone) &&
        ((filter == CantBeFiltered) || (mask & filter))) {
        if (grab && !SameClient(grab, client))
            return -1;
        else
            return 1;
    }
    return 0;
}

Project: xserver
File: events.c

XineramaWarpPointer(ClientPtr client)
{
    WindowPtr dest = NULL;
    int x, y, rc;
    SpritePtr pSprite = PickPointer(client)->spriteInfo->sprite;

    REQUEST(xWarpPointerReq);

    if (stuff->dstWid != None) {
        rc = dixLookupWindow(&dest, stuff->dstWid, client, DixReadAccess);
        if (rc != Success)
            return rc;
    }
    x = pSprite->hotPhys.x;
    y = pSprite->hotPhys.y;

    if (stuff->srcWid != None) {
        int winX, winY;
        XID winID = stuff->srcWid;
        WindowPtr source;

        rc = dixLookupWindow(&source, winID, client, DixReadAccess);
        if (rc != Success)
            return rc;

        winX = source->drawable.x;
        winY = source->drawable.y;
        if (source == screenInfo.screens[0]->root) {
            winX -= screenInfo.screens[0]->x;
            winY -= screenInfo.screens[0]->y;
        }
        if (x < winX + stuff->srcX ||
            y < winY + stuff->srcY ||
            (stuff->srcWidth != 0 &&
             winX + stuff->srcX + (int) stuff->srcWidth < x) ||
            (stuff->srcHeight != 0 &&
             winY + stuff->srcY + (int) stuff->srcHeight < y) ||
            !XineramaPointInWindowIsVisible(source, x, y))
            return Success;
    }
    if (dest) {
        x = dest->drawable.x;
        y = dest->drawable.y;
        if (dest == screenInfo.screens[0]->root) {
            x -= screenInfo.screens[0]->x;
            y -= screenInfo.screens[0]->y;
        }
    }

    x += stuff->dstX;
    y += stuff->dstY;

    if (x < pSprite->physLimits.x1)
        x = pSprite->physLimits.x1;
    else if (x >= pSprite->physLimits.x2)
        x = pSprite->physLimits.x2 - 1;
    if (y < pSprite->physLimits.y1)
        y = pSprite->physLimits.y1;
    else if (y >= pSprite->physLimits.y2)
        y = pSprite->physLimits.y2 - 1;
    if (pSprite->hotShape)
        ConfineToShape(PickPointer(client), pSprite->hotShape, &x, &y);

    XineramaSetCursorPosition(PickPointer(client), x, y, TRUE);

    return Success;
}

Project: xserver
File: events.c

core_get_type(const xEvent *event)
{
    int type = event->u.u.type;

    return ((type & EXTENSION_EVENT_BASE) || type == GenericEvent) ? 0 : type;
}

Project: xserver
File: swapreq.c

SProcChangeProperty(ClientPtr client)
{
    REQUEST(xChangePropertyReq);
    swaps(&stuff->length);
    REQUEST_AT_LEAST_SIZE(xChangePropertyReq);
    swapl(&stuff->window);
    swapl(&stuff->property);
    swapl(&stuff->type);
    swapl(&stuff->nUnits);
    switch (stuff->format) {
    case 8:
        break;
    case 16:
        SwapRestS(stuff);
        break;
    case 32:
        SwapRestL(stuff);
        break;
    }
    return ((*ProcVector[X_ChangeProperty]) (client));
}

Project: xserver
File: swapreq.c

SProcChangeWindowAttributes(ClientPtr client)
{
    REQUEST(xChangeWindowAttributesReq);
    swaps(&stuff->length);
    REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
    swapl(&stuff->window);
    swapl(&stuff->valueMask);
    SwapRestL(stuff);
    return ((*ProcVector[X_ChangeWindowAttributes]) (client));
}

Project: xserver
File: swapreq.c

SProcConfigureWindow(ClientPtr client)
{
    REQUEST(xConfigureWindowReq);
    swaps(&stuff->length);
    REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
    swapl(&stuff->window);
    swaps(&stuff->mask);
    SwapRestL(stuff);
    return ((*ProcVector[X_ConfigureWindow]) (client));

}

Project: xserver
File: swapreq.c

SProcConvertSelection(ClientPtr client)
{
    REQUEST(xConvertSelectionReq);
    swaps(&stuff->length);
    REQUEST_SIZE_MATCH(xConvertSelectionReq);
    swapl(&stuff->requestor);
    swapl(&stuff->selection);
    swapl(&stuff->target);
    swapl(&stuff->property);
    swapl(&stuff->time);
    return ((*ProcVector[X_ConvertSelection]) (client));
}

Project: xserver
File: swapreq.c

SProcCreateWindow(ClientPtr client)
{
    REQUEST(xCreateWindowReq);
    swaps(&stuff->length);
    REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
    swapl(&stuff->wid);
    swapl(&stuff->parent);
    swaps(&stuff->x);
    swaps(&stuff->y);
    swaps(&stuff->width);
    swaps(&stuff->height);
    swaps(&stuff->borderWidth);
    swaps(&stuff->class);
    swapl(&stuff->visual);
    swapl(&stuff->mask);
    SwapRestL(stuff);
    return ((*ProcVector[X_CreateWindow]) (client));
}

Project: xserver
File: swapreq.c

SProcDeleteProperty(ClientPtr client)
{
    REQUEST(xDeletePropertyReq);
    swaps(&stuff->length);
    REQUEST_SIZE_MATCH(xDeletePropertyReq);
    swapl(&stuff->window);
    swapl(&stuff->property);
    return ((*ProcVector[X_DeleteProperty]) (client));

}

Project: xserver
File: swapreq.c

SProcInternAtom(ClientPtr client)
{
    REQUEST(xInternAtomReq);
    swaps(&stuff->length);
    REQUEST_AT_LEAST_SIZE(xInternAtomReq);
    swaps(&stuff->nbytes);
    return ((*ProcVector[X_InternAtom]) (client));
}

Project: xserver
File: swapreq.c

SProcResourceReq(ClientPtr client)
{
    REQUEST(xResourceReq);
    swaps(&stuff->length);
    REQUEST_AT_LEAST_SIZE(xResourceReq);        /* not EXACT */
    swapl(&stuff->id);
    return (*ProcVector[stuff->reqType]) (client);
}