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