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; }
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++; } } } }
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; }