static void process_mouse_input(LPRAWINPUT raw_input) { LPRAWMOUSE raw_mouse = &(raw_input->data.mouse); //fs_log("flags: %d %d %d\n", raw_mouse->usFlags, MOUSE_MOVE_RELATIVE, MOUSE_MOVE_ABSOLUTE); if (raw_mouse->usFlags & MOUSE_MOVE_ABSOLUTE) { } else { if (raw_mouse->lLastX != 0 || raw_mouse->lLastY != 0) { fs_ml_input_event *event = fs_ml_input_event_alloc(); event->type = FS_ML_INPUT_EVENT_MOUSE_MOTION; event->mouse.dx = raw_mouse->lLastX; event->mouse.dy = raw_mouse->lLastY; fs_ml_input_event_post(event); } } int flags = raw_mouse->usButtonFlags; if (flags) { if (flags & RI_MOUSE_LEFT_BUTTON_DOWN) { post_mouse_button_event(1, 1); } if (flags & RI_MOUSE_LEFT_BUTTON_UP) { post_mouse_button_event(1, 0); } if (flags & RI_MOUSE_MIDDLE_BUTTON_DOWN) { post_mouse_button_event(2, 1); } if (flags & RI_MOUSE_MIDDLE_BUTTON_UP) { post_mouse_button_event(2, 0); } if (flags & RI_MOUSE_RIGHT_BUTTON_DOWN) { post_mouse_button_event(3, 1); } if (flags & RI_MOUSE_RIGHT_BUTTON_UP) { post_mouse_button_event(3, 0); } } }
UIOHOOK_API void hook_post_event(uiohook_event * const event) { XLockDisplay(properties_disp); #ifdef USE_XTEST // XTest does not have modifier support, so we fake it by depressing the // appropriate modifier keys. for (unsigned int i = 0; i < sizeof(keymask_lookup) / sizeof(KeySym); i++) { if (event->mask & 1 << i) { XTestFakeKeyEvent(properties_disp, XKeysymToKeycode(properties_disp, keymask_lookup[i]), True, 0); } } for (unsigned int i = 0; i < sizeof(btnmask_lookup) / sizeof(unsigned int); i++) { if (event->mask & btnmask_lookup[i]) { XTestFakeButtonEvent(properties_disp, i + 1, True, 0); } } #endif switch (event->type) { case EVENT_KEY_PRESSED: case EVENT_KEY_RELEASED: case EVENT_KEY_TYPED: post_key_event(event); break; case EVENT_MOUSE_PRESSED: case EVENT_MOUSE_RELEASED: case EVENT_MOUSE_WHEEL: case EVENT_MOUSE_CLICKED: post_mouse_button_event(event); break; case EVENT_MOUSE_DRAGGED: case EVENT_MOUSE_MOVED: post_mouse_motion_event(event); break; case EVENT_HOOK_ENABLED: case EVENT_HOOK_DISABLED: // Ignore hook enabled / disabled events. default: // Ignore any other garbage. logger(LOG_LEVEL_WARN, "%s [%u]: Ignoring post event type %#X\n", __FUNCTION__, __LINE__, event->type); break; } #ifdef USE_XTEST // Release the previously held modifier keys used to fake the event mask. for (unsigned int i = 0; i < sizeof(keymask_lookup) / sizeof(KeySym); i++) { if (event->mask & 1 << i) { XTestFakeKeyEvent(properties_disp, XKeysymToKeycode(properties_disp, keymask_lookup[i]), False, 0); } } for (unsigned int i = 0; i < sizeof(btnmask_lookup) / sizeof(unsigned int); i++) { if (event->mask & btnmask_lookup[i]) { XTestFakeButtonEvent(properties_disp, i + 1, False, 0); } } #endif // Don't forget to flush! XSync(properties_disp, True); XUnlockDisplay(properties_disp); }