void ProcessPointerEvent( register xEvent * xE, register DeviceIntPtr mouse, int count) { DeviceIntPtr dev = (DeviceIntPtr)LookupKeyboardDevice(); XkbSrvInfoPtr xkbi = dev->key->xkbInfo; unsigned changed = 0; xkbi->shiftKeyCount = 0; xkbi->lastPtrEventTime= xE->u.keyButtonPointer.time; if (xE->u.u.type==ButtonPress) { changed |= XkbPointerButtonMask; } else if (xE->u.u.type==ButtonRelease) { xkbi->lockedPtrButtons&= ~(1<<(xE->u.u.detail&0x7)); changed |= XkbPointerButtonMask; } CoreProcessPointerEvent(xE,mouse,count); xkbi->state.ptr_buttons = mouse->button->state; /* clear any latched modifiers */ if ( xkbi->state.latched_mods && (xE->u.u.type==ButtonRelease) ) { unsigned changed_leds; XkbStateRec oldState; XkbSrvLedInfoPtr sli; sli= XkbFindSrvLedInfo(dev,XkbDfltXIClass,XkbDfltXIId,0); oldState= xkbi->state; XkbLatchModifiers(dev,0xFF,0x00); XkbComputeDerivedState(xkbi); changed |= XkbStateChangedFlags(&oldState,&xkbi->state); if (changed&sli->usedComponents) { changed_leds= XkbIndicatorsToUpdate(dev,changed,False); if (changed_leds) { XkbEventCauseRec cause; XkbSetCauseKey(&cause,(xE->u.u.detail&0x7),xE->u.u.type); XkbUpdateIndicators(dev,changed_leds,True,NULL,&cause); } } dev->key->state= XkbStateFieldFromRec(&xkbi->state); } if (((xkbi->flags&_XkbStateNotifyInProgress)==0)&&(changed!=0)) { xkbStateNotify sn; sn.keycode= xE->u.u.detail; sn.eventType= xE->u.u.type; sn.requestMajor = sn.requestMinor = 0; sn.changed= changed; XkbSendStateNotify(dev,&sn); } } /* ProcessPointerEvent */
static PyObject * virtkey_unlatch_mod(PyObject * self,PyObject *args) { int mask = 0; virtkey * cvirt = (virtkey *)self; if ((PyArg_ParseTuple(args, "i", &mask))){//find mask arg in args tuple. XkbLatchModifiers(cvirt->display, XkbUseCoreKbd, mask, 0); XSync(cvirt->display, False); } Py_INCREF(Py_None); return Py_None; }
static void global_filter_fn (XEvent *xevent, void *data) { SpiDEController *controller; DEControllerPrivateData *priv; Display *display = spi_get_display (); controller = SPI_DEVICE_EVENT_CONTROLLER (data); priv = controller->priv; if (xevent->type == MappingNotify) xmkeymap = NULL; if (xevent->type == KeyPress || xevent->type == KeyRelease) { if (priv->xevie_display == NULL) { gboolean is_consumed; is_consumed = spi_device_event_controller_forward_key_event (controller, xevent); if (is_consumed) { int n_events; int i; XEvent next_event; n_events = XPending (display); #ifdef SPI_KEYEVENT_DEBUG g_print ("Number of events pending: %d\n", n_events); #endif for (i = 0; i < n_events; i++) { XNextEvent (display, &next_event); if (next_event.type != KeyPress && next_event.type != KeyRelease) g_warning ("Unexpected event type %d in queue", next_event.type); } XAllowEvents (display, AsyncKeyboard, CurrentTime); if (n_events) XUngrabKeyboard (display, CurrentTime); } else { if (xevent->type == KeyPress) wait_for_release_event (xevent, controller); XAllowEvents (display, ReplayKeyboard, CurrentTime); } } return; } if (xevent->type == ButtonPress || xevent->type == ButtonRelease) { spi_device_event_controller_forward_mouse_event (controller, xevent); } if (xevent->type == priv->xkb_base_event_code) { XkbAnyEvent * xkb_ev = (XkbAnyEvent *) xevent; /* ugly but probably necessary...*/ XSynchronize (display, TRUE); if (xkb_ev->xkb_type == XkbStateNotify) { XkbStateNotifyEvent *xkb_snev = (XkbStateNotifyEvent *) xkb_ev; /* check the mouse, to catch mouse events grabbed by * another client; in case we should revert this XKB delatch */ if (!priv->pending_xkb_mod_relatch_mask) { int x, y; gboolean moved; spi_dec_x11_mouse_check (controller, &x, &y, &moved); } /* we check again, since the previous call may have changed this flag */ if (priv->pending_xkb_mod_relatch_mask) { unsigned int feedback_mask; #ifdef SPI_XKB_DEBUG fprintf (stderr, "relatching %x\n", priv->pending_xkb_mod_relatch_mask); #endif /* temporarily turn off the latch bell, if it's on */ XkbGetControls (display, XkbAccessXFeedbackMask, priv->xkb_desc); feedback_mask = priv->xkb_desc->ctrls->ax_options; if (feedback_mask & XkbAX_StickyKeysFBMask) { XkbControlsChangesRec changes = {XkbAccessXFeedbackMask, 0, False}; priv->xkb_desc->ctrls->ax_options &= ~(XkbAX_StickyKeysFBMask); XkbChangeControls (display, priv->xkb_desc, &changes); } /* TODO: account for lock as well as latch */ XkbLatchModifiers (display, XkbUseCoreKbd, priv->pending_xkb_mod_relatch_mask, priv->pending_xkb_mod_relatch_mask); if (feedback_mask & XkbAX_StickyKeysFBMask) { XkbControlsChangesRec changes = {XkbAccessXFeedbackMask, 0, False}; priv->xkb_desc->ctrls->ax_options = feedback_mask; XkbChangeControls (display, priv->xkb_desc, &changes); } #ifdef SPI_XKB_DEBUG fprintf (stderr, "relatched %x\n", priv->pending_xkb_mod_relatch_mask); #endif priv->pending_xkb_mod_relatch_mask = 0; } else { priv->xkb_latch_mask = xkb_snev->latched_mods; } } XSynchronize (display, FALSE); } return; }