void DarwinInputReleaseButtonsAndKeys(DeviceIntPtr pDev) { darwinEvents_lock(); { int i; if (pDev->button) { for (i = 0; i < pDev->button->numButtons; i++) { if (BitIsOn(pDev->button->down, i)) { QueuePointerEvents(pDev, ButtonRelease, i, POINTER_ABSOLUTE, NULL); } } } if (pDev->key) { for (i = 0; i < NUM_KEYCODES; i++) { if (BitIsOn(pDev->key->down, i + MIN_KEYCODE)) { QueueKeyboardEvents(pDev, KeyRelease, i + MIN_KEYCODE); } } } DarwinPokeEQ(); } darwinEvents_unlock(); }
/** * Write button information into info. * @return Number of bytes written into info. */ int ListButtonInfo(DeviceIntPtr dev, xXIButtonInfo * info, Bool reportState) { unsigned char *bits; int mask_len; int i; if (!dev || !dev->button) return 0; mask_len = bytes_to_int32(bits_to_bytes(dev->button->numButtons)); info->type = ButtonClass; info->num_buttons = dev->button->numButtons; info->length = bytes_to_int32(sizeof(xXIButtonInfo)) + info->num_buttons + mask_len; info->sourceid = dev->button->sourceid; bits = (unsigned char *) &info[1]; memset(bits, 0, mask_len * 4); if (reportState) for (i = 0; i < dev->button->numButtons; i++) if (BitIsOn(dev->button->down, i)) SetBit(bits, i); bits += mask_len * 4; memcpy(bits, dev->button->labels, dev->button->numButtons * sizeof(Atom)); return info->length * 4; }
int CountBits(const uint8_t *mask, int len) { int i; int ret = 0; for (i = 0; i < len; i++) if (BitIsOn(mask, i)) ret++; return ret; }
static void SDeviceEvent(xXIDeviceEvent *from, xXIDeviceEvent *to) { int i; char n; char *ptr; char *vmask; memcpy(to, from, sizeof(xEvent) + from->length * 4); swaps(&to->sequenceNumber, n); swapl(&to->length, n); swaps(&to->evtype, n); swaps(&to->deviceid, n); swapl(&to->time, n); swapl(&to->detail, n); swapl(&to->root, n); swapl(&to->event, n); swapl(&to->child, n); swapl(&to->root_x, n); swapl(&to->root_y, n); swapl(&to->event_x, n); swapl(&to->event_y, n); swaps(&to->buttons_len, n); swaps(&to->valuators_len, n); swaps(&to->sourceid, n); swapl(&to->mods.base_mods, n); swapl(&to->mods.latched_mods, n); swapl(&to->mods.locked_mods, n); swapl(&to->mods.effective_mods, n); swapl(&to->flags, n); ptr = (char*)(&to[1]); ptr += from->buttons_len * 4; vmask = ptr; /* valuator mask */ ptr += from->valuators_len * 4; for (i = 0; i < from->valuators_len * 32; i++) { if (BitIsOn(vmask, i)) { swapl(((uint32_t*)ptr), n); ptr += 4; swapl(((uint32_t*)ptr), n); ptr += 4; } } }
static int eventToRawEvent(RawDeviceEvent *ev, xEvent **xi) { xXIRawEvent* raw; int vallen, nvals; int i, len = sizeof(xXIRawEvent); char *ptr; FP3232 *axisval, *axisval_raw; nvals = count_bits(ev->valuators.mask, sizeof(ev->valuators.mask)); len += nvals * sizeof(FP3232) * 2; /* 8 byte per valuator, once raw, once processed */ vallen = bytes_to_int32(bits_to_bytes(MAX_VALUATORS)); len += vallen * 4; /* valuators mask */ *xi = calloc(1, len); raw = (xXIRawEvent*)*xi; raw->type = GenericEvent; raw->extension = IReqCode; raw->evtype = GetXI2Type(ev->type); raw->time = ev->time; raw->length = bytes_to_int32(len - sizeof(xEvent)); raw->detail = ev->detail.button; raw->deviceid = ev->deviceid; raw->sourceid = ev->sourceid; raw->valuators_len = vallen; raw->flags = ev->flags; ptr = (char*)&raw[1]; axisval = (FP3232*)(ptr + raw->valuators_len * 4); axisval_raw = axisval + nvals; 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_raw = double_to_fp3232(ev->valuators.data_raw[i]); axisval++; axisval_raw++; } } return Success; }
static CARD32 AccessXSlowKeyExpire(OsTimerPtr timer,CARD32 now,pointer arg) { DeviceIntPtr keybd; XkbSrvInfoPtr xkbi; XkbDescPtr xkb; XkbControlsPtr ctrls; keybd= (DeviceIntPtr)arg; xkbi= keybd->key->xkbInfo; xkb= xkbi->desc; ctrls= xkb->ctrls; if (xkbi->slowKey!=0) { xkbAccessXNotify ev; KeySym *sym= XkbKeySymsPtr(xkb,xkbi->slowKey); ev.detail= XkbAXN_SKAccept; ev.keycode= xkbi->slowKey; ev.slowKeysDelay= ctrls->slow_keys_delay; ev.debounceDelay= ctrls->debounce_delay; XkbSendAccessXNotify(keybd,&ev); if (XkbAX_NeedFeedback(ctrls,XkbAX_SKAcceptFBMask)) XkbDDXAccessXBeep(keybd,_BEEP_SLOW_ACCEPT,XkbSlowKeysMask); AccessXKeyboardEvent(keybd,KeyPress,xkbi->slowKey,False); /* check for magic sequences */ if ((ctrls->enabled_ctrls&XkbAccessXKeysMask) && ((sym[0]==XK_Shift_R)||(sym[0]==XK_Shift_L))) xkbi->shiftKeyCount++; /* Start repeating if necessary. Stop autorepeating if the user * presses a non-modifier key that doesn't autorepeat. */ if (keybd->kbdfeed->ctrl.autoRepeat && ((xkbi->slowKey != xkbi->mouseKey) || (!xkbi->mouseKeysAccel)) && (ctrls->enabled_ctrls&XkbRepeatKeysMask)) { if (BitIsOn(keybd->kbdfeed->ctrl.autoRepeats,xkbi->slowKey)) { xkbi->repeatKey = xkbi->slowKey; xkbi->repeatKeyTimer= TimerSet(xkbi->repeatKeyTimer, 0, ctrls->repeat_delay, AccessXRepeatKeyExpire, (pointer)keybd); } } } return 0; }
/** * Set first to the first valuator in the event ev and return the number of * valuators from first to the last set valuator. */ static int countValuators(DeviceEvent *ev, int *first) { int first_valuator = -1, last_valuator = -1, num_valuators = 0; int i; for (i = 0; i < sizeof(ev->valuators.mask) * 8; i++) { if (BitIsOn(ev->valuators.mask, i)) { if (first_valuator == -1) first_valuator = i; last_valuator = i; } } if (first_valuator != -1) { num_valuators = last_valuator - first_valuator + 1; *first = first_valuator; } return num_valuators; }
static void SRawEvent(xXIRawEvent *from, xXIRawEvent *to) { char n; int i; FP3232 *values; unsigned char *mask; memcpy(to, from, sizeof(xEvent) + from->length * 4); swaps(&to->sequenceNumber, n); swapl(&to->length, n); swaps(&to->evtype, n); swaps(&to->deviceid, n); swapl(&to->time, n); swapl(&to->detail, n); mask = (unsigned char*)&to[1]; values = (FP3232*)(mask + from->valuators_len * 4); for (i = 0; i < from->valuators_len * 4 * 8; i++) { if (BitIsOn(mask, i)) { /* for each bit set there are two FP3232 values on the wire, in * the order abcABC for data and data_raw. Here we swap as if * they were in aAbBcC order because it's easier and really * doesn't matter. */ swapl(&values->integral, n); swapl(&values->frac, n); values++; swapl(&values->integral, n); swapl(&values->frac, n); values++; } } swaps(&to->valuators_len, n); }
/** * Return true if the valuator is set in the mask, or false otherwise. */ int valuator_mask_isset(const ValuatorMask *mask, int valuator) { return mask->last_bit >= valuator && BitIsOn(mask->mask, valuator); }
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 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; }
/** * Convert the given event to the respective core event. * * Return values: * Success ... core contains the matching core event. * BadValue .. One or more values in the internal event are invalid. * BadMatch .. The event has no core equivalent. * * @param[in] event The event to convert into a core event. * @param[in] core The memory location to store the core event at. * @return Success or the matching error code. */ int EventToCore(InternalEvent *event, xEvent **core_out, int *count_out) { xEvent *core = NULL; int count = 0; int ret = BadImplementation; switch(event->any.type) { case ET_Motion: { DeviceEvent *e = &event->device_event; /* Don't create core motion event if neither x nor y are * present */ if (!BitIsOn(e->valuators.mask, 0) && !BitIsOn(e->valuators.mask, 1)) { ret = BadMatch; goto out; } } /* fallthrough */ case ET_ButtonPress: case ET_ButtonRelease: case ET_KeyPress: case ET_KeyRelease: { DeviceEvent *e = &event->device_event; if (e->detail.key > 0xFF) { ret = BadMatch; goto out; } core = calloc(1, sizeof(*core)); if (!core) return BadAlloc; count = 1; core->u.u.type = e->type - ET_KeyPress + KeyPress; core->u.u.detail = e->detail.key & 0xFF; core->u.keyButtonPointer.time = e->time; core->u.keyButtonPointer.rootX = e->root_x; core->u.keyButtonPointer.rootY = e->root_y; core->u.keyButtonPointer.state = e->corestate; core->u.keyButtonPointer.root = e->root; EventSetKeyRepeatFlag(core, (e->type == ET_KeyPress && e->key_repeat)); ret = Success; } break; case ET_ProximityIn: case ET_ProximityOut: case ET_RawKeyPress: case ET_RawKeyRelease: case ET_RawButtonPress: case ET_RawButtonRelease: case ET_RawMotion: case ET_RawTouchBegin: case ET_RawTouchUpdate: case ET_RawTouchEnd: case ET_TouchBegin: case ET_TouchUpdate: case ET_TouchEnd: case ET_TouchOwnership: ret = BadMatch; break; default: /* XXX: */ ErrorF("[dix] EventToCore: Not implemented yet \n"); ret = BadImplementation; } out: *core_out = core; *count_out = count; return ret; }
Bool AccessXFilterReleaseEvent( register xEvent * xE, register DeviceIntPtr keybd, int count) { XkbSrvInfoPtr xkbi = keybd->key->xkbInfo; XkbControlsPtr ctrls = xkbi->desc->ctrls; KeyCode key = xE->u.u.detail; Bool ignoreKeyEvent = FALSE; /* Don't transmit the KeyRelease if BounceKeys is on and * this is the release of a key that was ignored due to * BounceKeys. */ if (ctrls->enabled_ctrls & XkbBounceKeysMask) { if ((key!=xkbi->mouseKey)&&(!BitIsOn(keybd->key->down,key))) ignoreKeyEvent = TRUE; xkbi->inactiveKey= key; xkbi->bounceKeysTimer= TimerSet(xkbi->bounceKeysTimer, 0, ctrls->debounce_delay, AccessXBounceKeyExpire, (pointer)keybd); } /* Don't transmit the KeyRelease if SlowKeys is turned on and * the user didn't hold the key long enough. We know we passed * the key if the down bit was set by CoreProcessKeyboadEvent. */ if (ctrls->enabled_ctrls & XkbSlowKeysMask) { xkbAccessXNotify ev; unsigned beep_type; ev.keycode= key; ev.slowKeysDelay= ctrls->slow_keys_delay; ev.debounceDelay= ctrls->debounce_delay; if (BitIsOn(keybd->key->down,key) | (xkbi->mouseKey == key)) { ev.detail= XkbAXN_SKRelease; beep_type= _BEEP_SLOW_RELEASE; } else { ev.detail= XkbAXN_SKReject; beep_type= _BEEP_SLOW_REJECT; ignoreKeyEvent = TRUE; } XkbSendAccessXNotify(keybd,&ev); if (XkbAX_NeedFeedback(ctrls,XkbAX_SKRejectFBMask)) { XkbDDXAccessXBeep(keybd,beep_type,XkbSlowKeysMask); } if (xkbi->slowKey==key) xkbi->slowKey= 0; } /* Stop Repeating if the user releases the key that is currently * repeating. */ if (xkbi->repeatKey==key) { xkbi->repeatKey= 0; } if ((ctrls->enabled_ctrls&XkbAccessXTimeoutMask)&&(ctrls->ax_timeout>0)) { xkbi->lastPtrEventTime= 0; xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, ctrls->ax_timeout*1000, AccessXTimeoutExpire, (pointer)keybd); xkbi->krgTimerActive= _ALL_TIMEOUT_TIMER; } else if (xkbi->krgTimerActive!=_OFF_TIMER) { xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, 0, NULL, NULL); xkbi->krgTimerActive= _OFF_TIMER; } /* Keep track of how many times the Shift key has been pressed. * If it has been pressed and released 5 times in a row, toggle * the state of StickyKeys. */ if ((!ignoreKeyEvent)&&(xkbi->shiftKeyCount)) { KeySym *pSym= XkbKeySymsPtr(xkbi->desc,key); if ((pSym[0]!=XK_Shift_L)&&(pSym[0]!=XK_Shift_R)) { xkbi->shiftKeyCount= 0; } else if (xkbi->shiftKeyCount>=5) { xkbControlsNotify cn; cn.keycode = key; cn.eventType = KeyPress; cn.requestMajor = 0; cn.requestMinor = 0; if (ctrls->enabled_ctrls & XkbStickyKeysMask) AccessXStickyKeysTurnOff(keybd,&cn); else AccessXStickyKeysTurnOn(keybd,&cn); xkbi->shiftKeyCount= 0; } } if (!ignoreKeyEvent) XkbProcessKeyboardEvent(xE,keybd,count); return ignoreKeyEvent; } /* AccessXFilterReleaseEvent */
Bool AccessXFilterPressEvent( register xEvent * xE, register DeviceIntPtr keybd, int count) { XkbSrvInfoPtr xkbi = keybd->key->xkbInfo; XkbControlsPtr ctrls = xkbi->desc->ctrls; Bool ignoreKeyEvent = FALSE; KeyCode key = xE->u.u.detail; KeySym * sym = XkbKeySymsPtr(xkbi->desc,key); if (ctrls->enabled_ctrls&XkbAccessXKeysMask) { /* check for magic sequences */ if ((sym[0]==XK_Shift_R)||(sym[0]==XK_Shift_L)) { if (XkbAX_NeedFeedback(ctrls,XkbAX_SlowWarnFBMask)) { xkbi->krgTimerActive = _KRG_WARN_TIMER; xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, 4000, AccessXKRGExpire, (pointer)keybd); } else { xkbi->krgTimerActive = _KRG_TIMER; xkbi->krgTimer= TimerSet(xkbi->krgTimer, 0, 8000, AccessXKRGExpire, (pointer)keybd); } if (!(ctrls->enabled_ctrls & XkbSlowKeysMask)) { CARD32 now= GetTimeInMillis(); if ((now-xkbi->lastShiftEventTime)>15000) xkbi->shiftKeyCount= 1; else xkbi->shiftKeyCount++; xkbi->lastShiftEventTime= now; } } else { if (xkbi->krgTimerActive) { xkbi->krgTimer= TimerSet(xkbi->krgTimer,0, 0, NULL, NULL); xkbi->krgTimerActive= _OFF_TIMER; } } } /* Don't transmit the KeyPress if SlowKeys is turned on; * The wakeup handler will synthesize one for us if the user * has held the key long enough. */ if (ctrls->enabled_ctrls & XkbSlowKeysMask) { xkbAccessXNotify ev; /* If key was already pressed, ignore subsequent press events * from the server's autorepeat */ if(xkbi->slowKey == key) return TRUE; ev.detail= XkbAXN_SKPress; ev.keycode= key; ev.slowKeysDelay= ctrls->slow_keys_delay; ev.debounceDelay= ctrls->debounce_delay; XkbSendAccessXNotify(keybd,&ev); if (XkbAX_NeedFeedback(ctrls,XkbAX_SKPressFBMask)) XkbDDXAccessXBeep(keybd,_BEEP_SLOW_PRESS,XkbSlowKeysMask); xkbi->slowKey= key; xkbi->slowKeysTimer = TimerSet(xkbi->slowKeysTimer, 0, ctrls->slow_keys_delay, AccessXSlowKeyExpire, (pointer)keybd); ignoreKeyEvent = TRUE; } /* Don't transmit the KeyPress if BounceKeys is turned on * and the user pressed the same key within a given time period * from the last release. */ else if ((ctrls->enabled_ctrls & XkbBounceKeysMask) && (key == xkbi->inactiveKey)) { if (XkbAX_NeedFeedback(ctrls,XkbAX_BKRejectFBMask)) XkbDDXAccessXBeep(keybd,_BEEP_BOUNCE_REJECT,XkbBounceKeysMask); ignoreKeyEvent = TRUE; } /* Start repeating if necessary. Stop autorepeating if the user * presses a non-modifier key that doesn't autorepeat. */ if (XkbDDXUsesSoftRepeat(keybd)) { if ((keybd->kbdfeed->ctrl.autoRepeat) && ((ctrls->enabled_ctrls&(XkbSlowKeysMask|XkbRepeatKeysMask))== XkbRepeatKeysMask)) { if (BitIsOn(keybd->kbdfeed->ctrl.autoRepeats,key) && !keybd->key->modifierMap[key]) { #ifdef DEBUG if (xkbDebugFlags&0x10) ErrorF("Starting software autorepeat...\n"); #endif xkbi->repeatKey = key; xkbi->repeatKeyTimer= TimerSet(xkbi->repeatKeyTimer, 0, ctrls->repeat_delay, AccessXRepeatKeyExpire, (pointer)keybd); } } } /* Check for two keys being pressed at the same time. This section * essentially says the following: * * If StickyKeys is on, and a modifier is currently being held down, * and one of the following is true: the current key is not a modifier * or the currentKey is a modifier, but not the only modifier being * held down, turn StickyKeys off if the TwoKeys off ctrl is set. */ if ((ctrls->enabled_ctrls & XkbStickyKeysMask) && (xkbi->state.base_mods!=0) && (XkbAX_NeedOption(ctrls,XkbAX_TwoKeysMask))) { xkbControlsNotify cn; cn.keycode = key; cn.eventType = KeyPress; cn.requestMajor = 0; cn.requestMinor = 0; AccessXStickyKeysTurnOff(keybd,&cn); } if (!ignoreKeyEvent) XkbProcessKeyboardEvent(xE,keybd,count); return ignoreKeyEvent; } /* AccessXFilterPressEvent */
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 */ XIClientPtr xi_client; Bool have_xi22 = FALSE; REQUEST(xXIQueryPointerReq); REQUEST_SIZE_MATCH(xXIQueryPointerReq); /* Check if client is compliant with XInput 2.2 or later. Earlier clients * do not know about touches, so we must report emulated button presses. 2.2 * and later clients are aware of touches, so we don't include emulated * button presses in the reply. */ xi_client = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey); if (version_compare(xi_client->major_version, xi_client->minor_version, 2, 2) >= 0) have_xi22 = TRUE; rc = dixLookupDevice(&pDev, stuff->deviceid, client, DixReadAccess); if (rc != Success) { client->errorValue = stuff->deviceid; return rc; } if (pDev->valuator == NULL || IsKeyboardDevice(pDev) || (!IsMaster(pDev) && !IsFloating(pDev))) { /* no attached devices */ client->errorValue = stuff->deviceid; return BadDevice; } rc = dixLookupWindow(&pWin, stuff->win, client, DixGetAttrAccess); if (rc != Success) { client->errorValue = stuff->win; return rc; } if (pDev->valuator->motionHintWindow) MaybeStopHint(pDev, client); if (IsMaster(pDev)) kbd = GetMaster(pDev, MASTER_KEYBOARD); else kbd = (pDev->key) ? pDev : NULL; pSprite = pDev->spriteInfo->sprite; rep = (xXIQueryPointerReply) { .repType = X_Reply, .RepType = X_XIQueryPointer, .sequenceNumber = client->sequence, .length = 6, .root = (GetCurrentRootWindow(pDev))->drawable.id, .root_x = double_to_fp1616(pSprite->hot.x), .root_y = double_to_fp1616(pSprite->hot.y), .child = None }; if (kbd) { state = &kbd->key->xkbInfo->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; rep.buttons_len = bytes_to_int32(bits_to_bytes(pDev->button->numButtons)); rep.length += rep.buttons_len; buttons = calloc(rep.buttons_len, 4); if (!buttons) return BadAlloc; buttons_size = rep.buttons_len * 4; for (i = 1; i < pDev->button->numButtons; i++) if (BitIsOn(pDev->button->down, i)) SetBit(buttons, pDev->button->map[i]); if (!have_xi22 && pDev->touch && pDev->touch->buttonsDown > 0) SetBit(buttons, pDev->button->map[1]); } else rep.buttons_len = 0; if (pSprite->hot.pScreen == pWin->drawable.pScreen) { rep.same_screen = xTrue; rep.win_x = double_to_fp1616(pSprite->hot.x - pWin->drawable.x); rep.win_y = double_to_fp1616(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.same_screen = xFalse; rep.win_x = 0; rep.win_y = 0; } #ifdef PANORAMIX if (!noPanoramiXExtension) { rep.root_x += double_to_fp1616(screenInfo.screens[0]->x); rep.root_y += double_to_fp1616(screenInfo.screens[0]->y); if (stuff->win == rep.root) { rep.win_x += double_to_fp1616(screenInfo.screens[0]->x); rep.win_y += double_to_fp1616(screenInfo.screens[0]->y); } } #endif WriteReplyToClient(client, sizeof(xXIQueryPointerReply), &rep); if (buttons) WriteToClient(client, buttons_size, buttons); free(buttons); return Success; } /*********************************************************************** * * This procedure writes the reply for the XIQueryPointer function, * if the client and server have a different byte ordering. * */ void SRepXIQueryPointer(ClientPtr client, int size, xXIQueryPointerReply * rep) { swaps(&rep->sequenceNumber); swapl(&rep->length); swapl(&rep->root); swapl(&rep->child); swapl(&rep->root_x); swapl(&rep->root_y); swapl(&rep->win_x); swapl(&rep->win_y); swaps(&rep->buttons_len); WriteToClient(client, size, rep); }