void xnestUpdateModifierState(unsigned int state) { DeviceIntPtr pDev = xnestKeyboardDevice; KeyClassPtr keyc = pDev->key; int i; CARD8 mask; int xkb_state; if (!pDev) return; xkb_state = XkbStateFieldFromRec(&pDev->key->xkbInfo->state); state = state & 0xff; if (xkb_state == state) return; for (i = 0, mask = 1; i < 8; i++, mask <<= 1) { int key; /* Modifier is down, but shouldn't be */ if ((xkb_state & mask) && !(state & mask)) { int count = keyc->modifierKeyCount[i]; for (key = 0; key < MAP_LENGTH; key++) if (keyc->xkbInfo->desc->map->modmap[key] & mask) { if (mask == LockMask) { xnestQueueKeyEvent(KeyPress, key); xnestQueueKeyEvent(KeyRelease, key); } else if (key_is_down(pDev, key, KEY_PROCESSED)) xnestQueueKeyEvent(KeyRelease, key); if (--count == 0) break; } } /* Modifier shoud be down, but isn't */ if (!(xkb_state & mask) && (state & mask)) for (key = 0; key < MAP_LENGTH; key++) if (keyc->xkbInfo->desc->map->modmap[key] & mask) { xnestQueueKeyEvent(KeyPress, key); if (mask == LockMask) xnestQueueKeyEvent(KeyRelease, key); break; } } }
void xnestCollectEvents(void) { XEvent X; int valuators[2]; ValuatorMask mask; ScreenPtr pScreen; while (XCheckIfEvent(xnestDisplay, &X, xnestNotExposurePredicate, NULL)) { switch (X.type) { case KeyPress: xnestUpdateModifierState(X.xkey.state); xnestQueueKeyEvent(KeyPress, X.xkey.keycode); break; case KeyRelease: xnestUpdateModifierState(X.xkey.state); xnestQueueKeyEvent(KeyRelease, X.xkey.keycode); break; case ButtonPress: valuator_mask_set_range(&mask, 0, 0, NULL); xnestUpdateModifierState(X.xkey.state); lastEventTime = GetTimeInMillis(); QueuePointerEvents(xnestPointerDevice, ButtonPress, X.xbutton.button, POINTER_RELATIVE, &mask); break; case ButtonRelease: valuator_mask_set_range(&mask, 0, 0, NULL); xnestUpdateModifierState(X.xkey.state); lastEventTime = GetTimeInMillis(); QueuePointerEvents(xnestPointerDevice, ButtonRelease, X.xbutton.button, POINTER_RELATIVE, &mask); break; case MotionNotify: valuators[0] = X.xmotion.x; valuators[1] = X.xmotion.y; valuator_mask_set_range(&mask, 0, 2, valuators); lastEventTime = GetTimeInMillis(); QueuePointerEvents(xnestPointerDevice, MotionNotify, 0, POINTER_ABSOLUTE, &mask); break; case FocusIn: if (X.xfocus.detail != NotifyInferior) { pScreen = xnestScreen(X.xfocus.window); if (pScreen) xnestDirectInstallColormaps(pScreen); } break; case FocusOut: if (X.xfocus.detail != NotifyInferior) { pScreen = xnestScreen(X.xfocus.window); if (pScreen) xnestDirectUninstallColormaps(pScreen); } break; case KeymapNotify: break; case EnterNotify: if (X.xcrossing.detail != NotifyInferior) { pScreen = xnestScreen(X.xcrossing.window); if (pScreen) { NewCurrentScreen(inputInfo.pointer, pScreen, X.xcrossing.x, X.xcrossing.y); valuators[0] = X.xcrossing.x; valuators[1] = X.xcrossing.y; valuator_mask_set_range(&mask, 0, 2, valuators); lastEventTime = GetTimeInMillis(); QueuePointerEvents(xnestPointerDevice, MotionNotify, 0, POINTER_ABSOLUTE, &mask); xnestDirectInstallColormaps(pScreen); } } break; case LeaveNotify: if (X.xcrossing.detail != NotifyInferior) { pScreen = xnestScreen(X.xcrossing.window); if (pScreen) { xnestDirectUninstallColormaps(pScreen); } } break; case DestroyNotify: if (xnestParentWindow != (Window) 0 && X.xdestroywindow.window == xnestParentWindow) exit(0); break; case CirculateNotify: case ConfigureNotify: case GravityNotify: case MapNotify: case ReparentNotify: case UnmapNotify: break; default: ErrorF("xnest warning: unhandled event\n"); break; } } }