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;
}
Example #2
0
static void test_values_XIDeviceEvent(DeviceEvent *in, xXIDeviceEvent *out,
                                      BOOL swap)
{
    int buttons, valuators;
    int i;
    unsigned char *ptr;
    uint32_t flagmask = 0;
    FP3232 *values;

    if (swap) {
        swaps(&out->sequenceNumber);
        swapl(&out->length);
        swaps(&out->evtype);
        swaps(&out->deviceid);
        swaps(&out->sourceid);
        swapl(&out->time);
        swapl(&out->detail);
        swapl(&out->root);
        swapl(&out->event);
        swapl(&out->child);
        swapl(&out->root_x);
        swapl(&out->root_y);
        swapl(&out->event_x);
        swapl(&out->event_y);
        swaps(&out->buttons_len);
        swaps(&out->valuators_len);
        swapl(&out->mods.base_mods);
        swapl(&out->mods.latched_mods);
        swapl(&out->mods.locked_mods);
        swapl(&out->mods.effective_mods);
        swapl(&out->flags);
    }

    assert(out->extension == 0); /* IReqCode defaults to 0 */
    assert(out->evtype == GetXI2Type((InternalEvent*)in));
    assert(out->time == in->time);
    assert(out->detail == in->detail.button);
    assert(out->length >= 12);

    assert(out->deviceid == in->deviceid);
    assert(out->sourceid == in->sourceid);

    switch (in->type) {
        case ET_ButtonPress:
        case ET_Motion:
        case ET_ButtonRelease:
            flagmask = XIPointerEmulated;
            break;
        case ET_KeyPress:
            flagmask = XIKeyRepeat;
            break;
        default:
            flagmask = 0;
            break;
    }
    assert((out->flags & ~flagmask) == 0);

    assert(out->root == in->root);
    assert(out->event == None); /* set in FixUpEventFromWindow */
    assert(out->child == None); /* set in FixUpEventFromWindow */

    assert(out->mods.base_mods == in->mods.base);
    assert(out->mods.latched_mods == in->mods.latched);
    assert(out->mods.locked_mods == in->mods.locked);
    assert(out->mods.effective_mods == in->mods.effective);

    assert(out->group.base_group == in->group.base);
    assert(out->group.latched_group == in->group.latched);
    assert(out->group.locked_group == in->group.locked);
    assert(out->group.effective_group == in->group.effective);

    assert(out->event_x == 0); /* set in FixUpEventFromWindow */
    assert(out->event_y == 0); /* set in FixUpEventFromWindow */

    assert(out->root_x == FP1616(in->root_x, in->root_x_frac));
    assert(out->root_y == FP1616(in->root_y, in->root_y_frac));

    buttons = 0;
    for (i = 0; i < bits_to_bytes(sizeof(in->buttons)); i++)
    {
        if (XIMaskIsSet(in->buttons, i))
        {
            assert(out->buttons_len >= bytes_to_int32(bits_to_bytes(i)));
            buttons++;
        }
    }

    ptr = (unsigned char*)&out[1];
    for (i = 0; i < sizeof(in->buttons) * 8; i++)
        assert(XIMaskIsSet(in->buttons, i) == XIMaskIsSet(ptr, i));


    valuators = 0;
    for (i = 0; i < MAX_VALUATORS; i++)
        if (XIMaskIsSet(in->valuators.mask, i))
            valuators++;

    assert(out->valuators_len >= bytes_to_int32(bits_to_bytes(valuators)));

    ptr += out->buttons_len * 4;
    values = (FP3232*)(ptr + out->valuators_len * 4);
    for (i = 0; i < sizeof(in->valuators.mask) * 8 ||
                i < (out->valuators_len * 4) * 8; i++)
    {
        if (i >= MAX_VALUATORS)
            assert(!XIMaskIsSet(in->valuators.mask, i) && !XIMaskIsSet(ptr, i));
        else if (i > sizeof(in->valuators.mask) * 8)
            assert(!XIMaskIsSet(ptr, i));
        else if (i > out->valuators_len * 4 * 8)
            assert(!XIMaskIsSet(in->valuators.mask, i));
        else {
            assert(XIMaskIsSet(in->valuators.mask, i) ==
                     XIMaskIsSet(ptr, i));

            if (XIMaskIsSet(ptr, i))
            {
                FP3232 vi, vo;

                vi = double_to_fp3232(in->valuators.data[i]);
                vo = *values;

                if (swap)
                {
                    swapl(&vo.integral);
                    swapl(&vo.frac);
                }


                assert(vi.integral == vo.integral);
                assert(vi.frac == vo.frac);
                values++;
            }
        }
    }
}
Example #3
0
static int
eventToDeviceEvent(DeviceEvent *ev, xEvent **xi)
{
    int len = sizeof(xXIDeviceEvent);
    xXIDeviceEvent *xde;
    int i, btlen, vallen;
    char *ptr;
    FP3232 *axisval;

    /* FIXME: this should just send the buttons we have, not MAX_BUTTONs. Same
     * with MAX_VALUATORS below */
    /* btlen is in 4 byte units */
    btlen = bytes_to_int32(bits_to_bytes(MAX_BUTTONS));
    len += btlen * 4; /* buttonmask len */


    vallen = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)/sizeof(ev->valuators.mask[0]));
    len += vallen * 2 * sizeof(uint32_t); /* axisvalues */
    vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS));
    len += vallen * 4; /* valuators mask */

    *xi = calloc(1, len);
    xde = (xXIDeviceEvent*)*xi;
    xde->type           = GenericEvent;
    xde->extension      = IReqCode;
    xde->evtype         = GetXI2Type(ev->type);
    xde->time           = ev->time;
    xde->length         = bytes_to_int32(len - sizeof(xEvent));
    if (IsTouchEvent((InternalEvent*)ev))
        xde->detail     = ev->touchid;
    else
        xde->detail     = ev->detail.button;

    xde->root           = ev->root;
    xde->buttons_len    = btlen;
    xde->valuators_len  = vallen;
    xde->deviceid       = ev->deviceid;
    xde->sourceid       = ev->sourceid;
    xde->root_x         = FP1616(ev->root_x, ev->root_x_frac);
    xde->root_y         = FP1616(ev->root_y, ev->root_y_frac);

    if (ev->type == ET_TouchUpdate)
        xde->flags |= (ev->flags & TOUCH_PENDING_END) ? XITouchPendingEnd : 0;
    else
        xde->flags = ev->flags;

    if (IsTouchEvent((InternalEvent*)ev) &&
        ev->flags & TOUCH_POINTER_EMULATED)
        xde->flags |= XITouchEmulatingPointer;

    if (ev->key_repeat)
        xde->flags      |= XIKeyRepeat;

    xde->mods.base_mods         = ev->mods.base;
    xde->mods.latched_mods      = ev->mods.latched;
    xde->mods.locked_mods       = ev->mods.locked;
    xde->mods.effective_mods    = ev->mods.effective;

    xde->group.base_group       = ev->group.base;
    xde->group.latched_group    = ev->group.latched;
    xde->group.locked_group     = ev->group.locked;
    xde->group.effective_group  = ev->group.effective;

    ptr = (char*)&xde[1];
    for (i = 0; i < sizeof(ev->buttons) * 8; i++)
    {
        if (BitIsOn(ev->buttons, i))
            SetBit(ptr, i);
    }

    ptr += xde->buttons_len * 4;
    axisval = (FP3232*)(ptr + xde->valuators_len * 4);
    for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++)
    {
        if (BitIsOn(ev->valuators.mask, i))
        {
            SetBit(ptr, i);
            *axisval = double_to_fp3232(ev->valuators.data[i]);
            axisval++;
        }
    }

    return Success;
}