Exemplo n.º 1
0
int GetDeviceUse(DeviceIntPtr dev, uint16_t *attachment)
{
    DeviceIntPtr master = dev->u.master;
    int use;

    if (IsMaster(dev))
    {
        DeviceIntPtr paired = GetPairedDevice(dev);
        use = IsPointerDevice(dev) ? XIMasterPointer : XIMasterKeyboard;
        *attachment = (paired ? paired->id : 0);
    } else if (master)
    {
        use = IsPointerDevice(master) ? XISlavePointer : XISlaveKeyboard;
        *attachment = master->id;
    } else
        use = XIFloatingSlave;

    return use;
}
int
ProcXIQueryPointer(ClientPtr client)
{
    int rc;
    xXIQueryPointerReply rep;
    DeviceIntPtr pDev, kbd;
    WindowPtr pWin, t;
    SpritePtr pSprite;
    XkbStatePtr state;
    char *buttons = NULL;
    int buttons_size = 0; /* size of buttons array */

    REQUEST(xXIQueryPointerReq);
    REQUEST_SIZE_MATCH(xXIQueryPointerReq);

    rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess);
    if (rc != Success)
    {
        client->errorValue = stuff->deviceid;
        return rc;
    }

    if (pDev->valuator == NULL || IsKeyboardDevice(pDev) ||
        (!IsMaster(pDev) && pDev->u.master)) /* no attached devices */
    {
        client->errorValue = stuff->deviceid;
        return BadDevice;
    }

    rc = dixLookupWindow(&pWin, stuff->win, client, DixGetAttrAccess);
    if (rc != Success)
    {
        SendErrorToClient(client, IReqCode, X_XIQueryPointer,
                stuff->win, rc);
        return Success;
    }

    if (pDev->valuator->motionHintWindow)
        MaybeStopHint(pDev, client);

    if (IsMaster(pDev))
        kbd = GetPairedDevice(pDev);
    else
        kbd = (pDev->key) ? pDev : NULL;

    pSprite = pDev->spriteInfo->sprite;

    memset(&rep, 0, sizeof(rep));
    rep.repType = X_Reply;
    rep.RepType = X_XIQueryPointer;
    rep.length = 6;
    rep.sequenceNumber = client->sequence;
    rep.root = (GetCurrentRootWindow(pDev))->drawable.id;
    rep.root_x = FP1616(pSprite->hot.x, 0);
    rep.root_y = FP1616(pSprite->hot.y, 0);
    rep.child = None;

    if (kbd)
    {
        state = &kbd->key->xkbInfo->prev_state;
        rep.mods.base_mods = state->base_mods;
        rep.mods.latched_mods = state->latched_mods;
        rep.mods.locked_mods = state->locked_mods;

        rep.group.base_group = state->base_group;
        rep.group.latched_group = state->latched_group;
        rep.group.locked_group = state->locked_group;
    }

    if (pDev->button)
    {
        int i, down;
        rep.buttons_len = bytes_to_int32(bits_to_bytes(pDev->button->numButtons));
        rep.length += rep.buttons_len;
        buttons_size = rep.buttons_len * 4;
        buttons = xcalloc(1, buttons_size);
        if (!buttons)
            return BadAlloc;

        down = pDev->button->buttonsDown;

        for (i = 0; i < pDev->button->numButtons && down; i++)
        {
            if (BitIsOn(pDev->button->down, i))
            {
                SetBit(buttons, i);
                down--;
            }
        }
    } else
        rep.buttons_len = 0;

    if (pSprite->hot.pScreen == pWin->drawable.pScreen)
    {
        rep.same_screen = xTrue;
        rep.win_x = FP1616(pSprite->hot.x - pWin->drawable.x, 0);
        rep.win_y = FP1616(pSprite->hot.y - pWin->drawable.y, 0);
        for (t = pSprite->win; t; t = t->parent)
            if (t->parent == pWin)
            {
                rep.child = t->drawable.id;
                break;
            }
    } else
    {
        rep.same_screen = xFalse;
        rep.win_x = 0;
        rep.win_y = 0;
    }

#ifdef PANORAMIX
    if(!noPanoramiXExtension) {
        rep.root_x += FP1616(panoramiXdataPtr[0].x, 0);
        rep.root_y += FP1616(panoramiXdataPtr[0].y, 0);
        if (stuff->win == rep.root)
        {
            rep.win_x += FP1616(panoramiXdataPtr[0].x, 0);
            rep.win_y += FP1616(panoramiXdataPtr[0].y, 0);
        }
    }
#endif

    WriteReplyToClient(client, sizeof(xXIQueryPointerReply), &rep);
    if (buttons)
        WriteToClient(client, buttons_size, buttons);

    xfree(buttons);

    return Success;
}