Compare commits

...

9 Commits

Author SHA1 Message Date
3b6774174d wip 2021-12-29 01:42:28 +01:00
4640b088ef wip 2021-12-29 01:42:27 +01:00
bbe8a99a3e wip 2021-12-29 01:40:10 +01:00
43416b6654 wip 2021-12-29 01:40:07 +01:00
7f781f1085 wip 2021-12-29 01:40:04 +01:00
c4648f1078 wip 2021-12-29 01:40:01 +01:00
eec2d1d160 input_events 2021-12-29 01:39:58 +01:00
ccfb4d3cfd Rename SC_MOD_* to SC_SHORTCUT_MOD_*
This will avoid conflicts with new SC_MOD_* constants.
2021-12-29 01:39:55 +01:00
49a788841d Remove actions bitset
The input manager exposed functions taking an "actions" parameter,
containing a bitmask-OR of ACTION_UP and ACTION_DOWN.

But they are never called with both actions simultaneously anymore, so
simplify.

Refs 964b6d2243
Refs d0739911a3
2021-12-29 01:34:54 +01:00
11 changed files with 855 additions and 237 deletions

View File

@ -14,6 +14,7 @@ src = [
'src/file_handler.c', 'src/file_handler.c',
'src/fps_counter.c', 'src/fps_counter.c',
'src/frame_buffer.c', 'src/frame_buffer.c',
'src/input_events.c',
'src/input_manager.c', 'src/input_manager.c',
'src/keyboard_inject.c', 'src/keyboard_inject.c',
'src/mouse_inject.c', 'src/mouse_inject.c',

View File

@ -1121,7 +1121,7 @@ parse_log_level(const char *s, enum sc_log_level *log_level) {
} }
// item is a list of mod keys separated by '+' (e.g. "lctrl+lalt") // item is a list of mod keys separated by '+' (e.g. "lctrl+lalt")
// returns a bitwise-or of SC_MOD_* constants (or 0 on error) // returns a bitwise-or of SC_SHORTCUT_MOD_* constants (or 0 on error)
static unsigned static unsigned
parse_shortcut_mods_item(const char *item, size_t len) { parse_shortcut_mods_item(const char *item, size_t len) {
unsigned mod = 0; unsigned mod = 0;
@ -1139,17 +1139,17 @@ parse_shortcut_mods_item(const char *item, size_t len) {
((sizeof(literal)-1 == len) && !memcmp(literal, s, len)) ((sizeof(literal)-1 == len) && !memcmp(literal, s, len))
if (STREQ("lctrl", item, key_len)) { if (STREQ("lctrl", item, key_len)) {
mod |= SC_MOD_LCTRL; mod |= SC_SHORTCUT_MOD_LCTRL;
} else if (STREQ("rctrl", item, key_len)) { } else if (STREQ("rctrl", item, key_len)) {
mod |= SC_MOD_RCTRL; mod |= SC_SHORTCUT_MOD_RCTRL;
} else if (STREQ("lalt", item, key_len)) { } else if (STREQ("lalt", item, key_len)) {
mod |= SC_MOD_LALT; mod |= SC_SHORTCUT_MOD_LALT;
} else if (STREQ("ralt", item, key_len)) { } else if (STREQ("ralt", item, key_len)) {
mod |= SC_MOD_RALT; mod |= SC_SHORTCUT_MOD_RALT;
} else if (STREQ("lsuper", item, key_len)) { } else if (STREQ("lsuper", item, key_len)) {
mod |= SC_MOD_LSUPER; mod |= SC_SHORTCUT_MOD_LSUPER;
} else if (STREQ("rsuper", item, key_len)) { } else if (STREQ("rsuper", item, key_len)) {
mod |= SC_MOD_RSUPER; mod |= SC_SHORTCUT_MOD_RSUPER;
} else { } else {
LOGE("Unknown modifier key: %.*s " LOGE("Unknown modifier key: %.*s "
"(must be one of: lctrl, rctrl, lalt, ralt, lsuper, rsuper)", "(must be one of: lctrl, rctrl, lalt, ralt, lsuper, rsuper)",

View File

@ -1,8 +1,8 @@
#include "hid_keyboard.h" #include "hid_keyboard.h"
#include <assert.h> #include <assert.h>
#include <SDL2/SDL_events.h>
#include "input_events.h"
#include "util/log.h" #include "util/log.h"
/** Downcast key processor to hid_keyboard */ /** Downcast key processor to hid_keyboard */
@ -201,30 +201,30 @@ static const unsigned char keyboard_report_desc[] = {
*/ */
static unsigned char static unsigned char
sdl_keymod_to_hid_modifiers(SDL_Keymod mod) { sdl_keymod_to_hid_modifiers(uint16_t mod) {
unsigned char modifiers = HID_MODIFIER_NONE; unsigned char modifiers = HID_MODIFIER_NONE;
if (mod & KMOD_LCTRL) { if (mod & SC_MOD_LCTRL) {
modifiers |= HID_MODIFIER_LEFT_CONTROL; modifiers |= HID_MODIFIER_LEFT_CONTROL;
} }
if (mod & KMOD_LSHIFT) { if (mod & SC_MOD_LSHIFT) {
modifiers |= HID_MODIFIER_LEFT_SHIFT; modifiers |= HID_MODIFIER_LEFT_SHIFT;
} }
if (mod & KMOD_LALT) { if (mod & SC_MOD_LALT) {
modifiers |= HID_MODIFIER_LEFT_ALT; modifiers |= HID_MODIFIER_LEFT_ALT;
} }
if (mod & KMOD_LGUI) { if (mod & SC_MOD_LGUI) {
modifiers |= HID_MODIFIER_LEFT_GUI; modifiers |= HID_MODIFIER_LEFT_GUI;
} }
if (mod & KMOD_RCTRL) { if (mod & SC_MOD_RCTRL) {
modifiers |= HID_MODIFIER_RIGHT_CONTROL; modifiers |= HID_MODIFIER_RIGHT_CONTROL;
} }
if (mod & KMOD_RSHIFT) { if (mod & SC_MOD_RSHIFT) {
modifiers |= HID_MODIFIER_RIGHT_SHIFT; modifiers |= HID_MODIFIER_RIGHT_SHIFT;
} }
if (mod & KMOD_RALT) { if (mod & SC_MOD_RALT) {
modifiers |= HID_MODIFIER_RIGHT_ALT; modifiers |= HID_MODIFIER_RIGHT_ALT;
} }
if (mod & KMOD_RGUI) { if (mod & SC_MOD_RGUI) {
modifiers |= HID_MODIFIER_RIGHT_GUI; modifiers |= HID_MODIFIER_RIGHT_GUI;
} }
return modifiers; return modifiers;
@ -248,15 +248,15 @@ sc_hid_keyboard_event_init(struct sc_hid_event *hid_event) {
} }
static inline bool static inline bool
scancode_is_modifier(SDL_Scancode scancode) { scancode_is_modifier(enum sc_scancode scancode) {
return scancode >= SDL_SCANCODE_LCTRL && scancode <= SDL_SCANCODE_RGUI; return scancode >= SC_SCANCODE_LCTRL && scancode <= SC_SCANCODE_RGUI;
} }
static bool static bool
convert_hid_keyboard_event(struct sc_hid_keyboard *kb, convert_hid_keyboard_event(struct sc_hid_keyboard *kb,
struct sc_hid_event *hid_event, struct sc_hid_event *hid_event,
const SDL_KeyboardEvent *event) { const struct sc_key_event *event) {
SDL_Scancode scancode = event->keysym.scancode; enum sc_scancode scancode = event->scancode;
assert(scancode >= 0); assert(scancode >= 0);
// SDL also generates events when only modifiers are pressed, we cannot // SDL also generates events when only modifiers are pressed, we cannot
@ -272,11 +272,11 @@ convert_hid_keyboard_event(struct sc_hid_keyboard *kb,
return false; return false;
} }
unsigned char modifiers = sdl_keymod_to_hid_modifiers(event->keysym.mod); unsigned char modifiers = sdl_keymod_to_hid_modifiers(event->mods_state);
if (scancode < SC_HID_KEYBOARD_KEYS) { if (scancode < SC_HID_KEYBOARD_KEYS) {
// Pressed is true and released is false // Pressed is true and released is false
kb->keys[scancode] = (event->type == SDL_KEYDOWN); kb->keys[scancode] = (event->action == SC_ACTION_DOWN);
LOGV("keys[%02x] = %s", scancode, LOGV("keys[%02x] = %s", scancode,
kb->keys[scancode] ? "true" : "false"); kb->keys[scancode] ? "true" : "false");
} }
@ -306,17 +306,17 @@ convert_hid_keyboard_event(struct sc_hid_keyboard *kb,
end: end:
LOGV("hid keyboard: key %-4s scancode=%02x (%u) mod=%02x", LOGV("hid keyboard: key %-4s scancode=%02x (%u) mod=%02x",
event->type == SDL_KEYDOWN ? "down" : "up", event->keysym.scancode, event->action == SC_ACTION_DOWN ? "down" : "up", event->scancode,
event->keysym.scancode, modifiers); event->scancode, modifiers);
return true; return true;
} }
static bool static bool
push_mod_lock_state(struct sc_hid_keyboard *kb, uint16_t sdl_mod) { push_mod_lock_state(struct sc_hid_keyboard *kb, uint16_t mods_state) {
bool capslock = sdl_mod & KMOD_CAPS; bool capslock = mods_state & SC_MOD_CAPS;
bool numlock = sdl_mod & KMOD_NUM; bool numlock = mods_state & SC_MOD_NUM;
if (!capslock && !numlock) { if (!capslock && !numlock) {
// Nothing to do // Nothing to do
return true; return true;
@ -328,8 +328,6 @@ push_mod_lock_state(struct sc_hid_keyboard *kb, uint16_t sdl_mod) {
return false; return false;
} }
#define SC_SCANCODE_CAPSLOCK SDL_SCANCODE_CAPSLOCK
#define SC_SCANCODE_NUMLOCK SDL_SCANCODE_NUMLOCKCLEAR
unsigned i = 0; unsigned i = 0;
if (capslock) { if (capslock) {
hid_event.buffer[HID_KEYBOARD_INDEX_KEYS + i] = SC_SCANCODE_CAPSLOCK; hid_event.buffer[HID_KEYBOARD_INDEX_KEYS + i] = SC_SCANCODE_CAPSLOCK;
@ -353,7 +351,7 @@ push_mod_lock_state(struct sc_hid_keyboard *kb, uint16_t sdl_mod) {
static void static void
sc_key_processor_process_key(struct sc_key_processor *kp, sc_key_processor_process_key(struct sc_key_processor *kp,
const SDL_KeyboardEvent *event, const struct sc_key_event *event,
uint64_t ack_to_wait) { uint64_t ack_to_wait) {
if (event->repeat) { if (event->repeat) {
// In USB HID protocol, key repeat is handled by the host (Android), so // In USB HID protocol, key repeat is handled by the host (Android), so
@ -369,7 +367,7 @@ sc_key_processor_process_key(struct sc_key_processor *kp,
if (!kb->mod_lock_synchronized) { if (!kb->mod_lock_synchronized) {
// Inject CAPSLOCK and/or NUMLOCK if necessary to synchronize // Inject CAPSLOCK and/or NUMLOCK if necessary to synchronize
// keyboard state // keyboard state
if (push_mod_lock_state(kb, event->keysym.mod)) { if (push_mod_lock_state(kb, event->mods_state)) {
kb->mod_lock_synchronized = true; kb->mod_lock_synchronized = true;
} }
} }
@ -391,7 +389,7 @@ sc_key_processor_process_key(struct sc_key_processor *kp,
static void static void
sc_key_processor_process_text(struct sc_key_processor *kp, sc_key_processor_process_text(struct sc_key_processor *kp,
const SDL_TextInputEvent *event) { const struct sc_text_event *event) {
(void) kp; (void) kp;
(void) event; (void) event;

76
app/src/input_events.c Normal file
View File

@ -0,0 +1,76 @@
#include <input_events.h>
static inline uint16_t
sc_mods_state_from_sdl(uint16_t mods_state) {
return mods_state;
}
static inline enum sc_keycode
sc_keycode_from_sdl(SDL_Keycode keycode) {
return (enum sc_keycode) keycode;
}
static inline enum sc_scancode
sc_scancode_from_sdl(SDL_Scancode scancode) {
return (enum sc_scancode) scancode;
}
static inline enum sc_action
sc_action_from_sdl_keyboard_type(uint32_t type) {
assert(type == SDL_KEYDOWN || type == SDL_KEYUP);
if (type == SDL_KEYDOWN) {
return SC_ACTION_DOWN;
}
return SC_ACTION_UP;
}
static inline enum sc_action
sc_action_from_sdl_mousebutton_type(uint32_t type) {
assert(type == SDL_MOUSEBUTTONDOWN || type == SDL_MOUSEBUTTONUP);
if (type == SDL_MOUSEBUTTONDOWN) {
return SC_ACTION_DOWN;
}
return SC_ACTION_UP;
}
static inline enum sc_mouse_button
sc_mouse_button_from_sdl(uint8_t button) {
if (button >= SDL_BUTTON_LEFT && button <= SDL_BUTTON_X2) {
// SC_MOUSE_BUTTON_* constants are initialized from SDL_BUTTON(index)
return SDL_BUTTON(button);
}
return SC_MOUSE_BUTTON_UNKNOWN;
}
static inline uint8_t
sc_mouse_buttons_state_from_sdl(uint32_t buttons_state) {
assert(buttons_state < 0x100); // fits in uint8_t
return buttons_state;
}
void
sc_key_event_from_sdl(struct sc_key_event *event,
const SDL_KeyboardEvent *sdl) {
event->action = sc_action_from_sdl_keyboard_type(sdl->type);
event->keycode = sc_keycode_from_sdl(sdl->keysym.sym);
event->scancode = sc_scancode_from_sdl(sdl->keysym.scancode);
event->repeat = sdl->repeat;
event->mods_state = sc_mods_state_from_sdl(sdl->keysym.mod);
}
void
sc_text_event_from_sdl(struct sc_text_event *event,
const SDL_TextInputEvent *sdl) {
event->text = sdl->text;
}
void
sc_mouse_click_event_from_sdl(struct sc_mouse_click_event *event,
const SDL_MouseButtonEvent *sdl,
const SDL_Window *window,
struct sc_size screen_size) {
event->action = sc_action_from_sdl_mousebutton_type(sdl->type);
event->button = sc_mouse_button_from_sdl(sdl->button);
event->position.screen_size = screen_size;
}

404
app/src/input_events.h Normal file
View File

@ -0,0 +1,404 @@
#ifndef SC_INPUT_EVENTS_H
#define SC_INPUT_EVENTS_H
#include "common.h"
#include <assert.h>
#include <stdbool.h>
#include <stdint.h>
#include <SDL2/SDL_events.h>
#include "coords.h"
/* The values are purposely the same as the SDL constants, so that the
* implementation to convert from the SDL version to the scrcpy version is
* straightforward */
enum sc_mod {
SC_MOD_LSHIFT = KMOD_LSHIFT,
SC_MOD_RSHIFT = KMOD_RSHIFT,
SC_MOD_LCTRL = KMOD_LCTRL,
SC_MOD_RCTRL = KMOD_RCTRL,
SC_MOD_LALT = KMOD_LALT,
SC_MOD_RALT = KMOD_RALT,
SC_MOD_LGUI = KMOD_LGUI,
SC_MOD_RGUI = KMOD_RGUI,
SC_MOD_NUM = KMOD_NUM,
SC_MOD_CAPS = KMOD_CAPS,
SC_MOD_SCROLL = KMOD_SCROLL,
};
enum sc_action {
SC_ACTION_DOWN, // key or button pressed
SC_ACTION_UP, // key or button released
};
enum sc_keycode {
SC_KEYCODE_UNKNOWN = SDLK_UNKNOWN,
SC_KEYCODE_RETURN = SDLK_RETURN,
SC_KEYCODE_ESCAPE = SDLK_ESCAPE,
SC_KEYCODE_BACKSPACE = SDLK_BACKSPACE,
SC_KEYCODE_TAB = SDLK_TAB,
SC_KEYCODE_SPACE = SDLK_SPACE,
SC_KEYCODE_EXCLAIM = SDLK_EXCLAIM,
SC_KEYCODE_QUOTEDBL = SDLK_QUOTEDBL,
SC_KEYCODE_HASH = SDLK_HASH,
SC_KEYCODE_PERCENT = SDLK_PERCENT,
SC_KEYCODE_DOLLAR = SDLK_DOLLAR,
SC_KEYCODE_AMPERSAND = SDLK_AMPERSAND,
SC_KEYCODE_QUOTE = SDLK_QUOTE,
SC_KEYCODE_LEFTPAREN = SDLK_LEFTPAREN,
SC_KEYCODE_RIGHTPAREN = SDLK_RIGHTPAREN,
SC_KEYCODE_ASTERISK = SDLK_ASTERISK,
SC_KEYCODE_PLUS = SDLK_PLUS,
SC_KEYCODE_COMMA = SDLK_COMMA,
SC_KEYCODE_MINUS = SDLK_MINUS,
SC_KEYCODE_PERIOD = SDLK_PERIOD,
SC_KEYCODE_SLASH = SDLK_SLASH,
SC_KEYCODE_0 = SDLK_0,
SC_KEYCODE_1 = SDLK_1,
SC_KEYCODE_2 = SDLK_2,
SC_KEYCODE_3 = SDLK_3,
SC_KEYCODE_4 = SDLK_4,
SC_KEYCODE_5 = SDLK_5,
SC_KEYCODE_6 = SDLK_6,
SC_KEYCODE_7 = SDLK_7,
SC_KEYCODE_8 = SDLK_8,
SC_KEYCODE_9 = SDLK_9,
SC_KEYCODE_COLON = SDLK_COLON,
SC_KEYCODE_SEMICOLON = SDLK_SEMICOLON,
SC_KEYCODE_LESS = SDLK_LESS,
SC_KEYCODE_EQUALS = SDLK_EQUALS,
SC_KEYCODE_GREATER = SDLK_GREATER,
SC_KEYCODE_QUESTION = SDLK_QUESTION,
SC_KEYCODE_AT = SDLK_AT,
SC_KEYCODE_LEFTBRACKET = SDLK_LEFTBRACKET,
SC_KEYCODE_BACKSLASH = SDLK_BACKSLASH,
SC_KEYCODE_RIGHTBRACKET = SDLK_RIGHTBRACKET,
SC_KEYCODE_CARET = SDLK_CARET,
SC_KEYCODE_UNDERSCORE = SDLK_UNDERSCORE,
SC_KEYCODE_BACKQUOTE = SDLK_BACKQUOTE,
SC_KEYCODE_a = SDLK_a,
SC_KEYCODE_b = SDLK_b,
SC_KEYCODE_c = SDLK_c,
SC_KEYCODE_d = SDLK_d,
SC_KEYCODE_e = SDLK_e,
SC_KEYCODE_f = SDLK_f,
SC_KEYCODE_g = SDLK_g,
SC_KEYCODE_h = SDLK_h,
SC_KEYCODE_i = SDLK_i,
SC_KEYCODE_j = SDLK_j,
SC_KEYCODE_k = SDLK_k,
SC_KEYCODE_l = SDLK_l,
SC_KEYCODE_m = SDLK_m,
SC_KEYCODE_n = SDLK_n,
SC_KEYCODE_o = SDLK_o,
SC_KEYCODE_p = SDLK_p,
SC_KEYCODE_q = SDLK_q,
SC_KEYCODE_r = SDLK_r,
SC_KEYCODE_s = SDLK_s,
SC_KEYCODE_t = SDLK_t,
SC_KEYCODE_u = SDLK_u,
SC_KEYCODE_v = SDLK_v,
SC_KEYCODE_w = SDLK_w,
SC_KEYCODE_x = SDLK_x,
SC_KEYCODE_y = SDLK_y,
SC_KEYCODE_z = SDLK_z,
SC_KEYCODE_CAPSLOCK = SDLK_CAPSLOCK,
SC_KEYCODE_F1 = SDLK_F1,
SC_KEYCODE_F2 = SDLK_F2,
SC_KEYCODE_F3 = SDLK_F3,
SC_KEYCODE_F4 = SDLK_F4,
SC_KEYCODE_F5 = SDLK_F5,
SC_KEYCODE_F6 = SDLK_F6,
SC_KEYCODE_F7 = SDLK_F7,
SC_KEYCODE_F8 = SDLK_F8,
SC_KEYCODE_F9 = SDLK_F9,
SC_KEYCODE_F10 = SDLK_F10,
SC_KEYCODE_F11 = SDLK_F11,
SC_KEYCODE_F12 = SDLK_F12,
SC_KEYCODE_PRINTSCREEN = SDLK_PRINTSCREEN,
SC_KEYCODE_SCROLLLOCK = SDLK_SCROLLLOCK,
SC_KEYCODE_PAUSE = SDLK_PAUSE,
SC_KEYCODE_INSERT = SDLK_INSERT,
SC_KEYCODE_HOME = SDLK_HOME,
SC_KEYCODE_PAGEUP = SDLK_PAGEUP,
SC_KEYCODE_DELETE = SDLK_DELETE,
SC_KEYCODE_END = SDLK_END,
SC_KEYCODE_PAGEDOWN = SDLK_PAGEDOWN,
SC_KEYCODE_RIGHT = SDLK_RIGHT,
SC_KEYCODE_LEFT = SDLK_LEFT,
SC_KEYCODE_DOWN = SDLK_DOWN,
SC_KEYCODE_UP = SDLK_UP,
SC_KEYCODE_KP_DIVIDE = SDLK_KP_DIVIDE,
SC_KEYCODE_KP_MULTIPLY = SDLK_KP_MULTIPLY,
SC_KEYCODE_KP_MINUS = SDLK_KP_MINUS,
SC_KEYCODE_KP_PLUS = SDLK_KP_PLUS,
SC_KEYCODE_KP_ENTER = SDLK_KP_ENTER,
SC_KEYCODE_KP_1 = SDLK_KP_1,
SC_KEYCODE_KP_2 = SDLK_KP_2,
SC_KEYCODE_KP_3 = SDLK_KP_3,
SC_KEYCODE_KP_4 = SDLK_KP_4,
SC_KEYCODE_KP_5 = SDLK_KP_5,
SC_KEYCODE_KP_6 = SDLK_KP_6,
SC_KEYCODE_KP_7 = SDLK_KP_7,
SC_KEYCODE_KP_8 = SDLK_KP_8,
SC_KEYCODE_KP_9 = SDLK_KP_9,
SC_KEYCODE_KP_0 = SDLK_KP_0,
SC_KEYCODE_KP_PERIOD = SDLK_KP_PERIOD,
SC_KEYCODE_KP_EQUALS = SDLK_KP_EQUALS,
SC_KEYCODE_KP_LEFTPAREN = SDLK_KP_LEFTPAREN,
SC_KEYCODE_KP_RIGHTPAREN = SDLK_KP_RIGHTPAREN,
SC_KEYCODE_LCTRL = SDLK_LCTRL,
SC_KEYCODE_LSHIFT = SDLK_LSHIFT,
SC_KEYCODE_LALT = SDLK_LALT,
SC_KEYCODE_LGUI = SDLK_LGUI,
SC_KEYCODE_RCTRL = SDLK_RCTRL,
SC_KEYCODE_RSHIFT = SDLK_RSHIFT,
SC_KEYCODE_RALT = SDLK_RALT,
SC_KEYCODE_RGUI = SDLK_RGUI,
};
enum sc_scancode {
SC_SCANCODE_UNKNOWN = SDL_SCANCODE_UNKNOWN,
SC_SCANCODE_A = SDL_SCANCODE_A,
SC_SCANCODE_B = SDL_SCANCODE_B,
SC_SCANCODE_C = SDL_SCANCODE_C,
SC_SCANCODE_D = SDL_SCANCODE_D,
SC_SCANCODE_E = SDL_SCANCODE_E,
SC_SCANCODE_F = SDL_SCANCODE_F,
SC_SCANCODE_G = SDL_SCANCODE_G,
SC_SCANCODE_H = SDL_SCANCODE_H,
SC_SCANCODE_I = SDL_SCANCODE_I,
SC_SCANCODE_J = SDL_SCANCODE_J,
SC_SCANCODE_K = SDL_SCANCODE_K,
SC_SCANCODE_L = SDL_SCANCODE_L,
SC_SCANCODE_M = SDL_SCANCODE_M,
SC_SCANCODE_N = SDL_SCANCODE_N,
SC_SCANCODE_O = SDL_SCANCODE_O,
SC_SCANCODE_P = SDL_SCANCODE_P,
SC_SCANCODE_Q = SDL_SCANCODE_Q,
SC_SCANCODE_R = SDL_SCANCODE_R,
SC_SCANCODE_S = SDL_SCANCODE_S,
SC_SCANCODE_T = SDL_SCANCODE_T,
SC_SCANCODE_U = SDL_SCANCODE_U,
SC_SCANCODE_V = SDL_SCANCODE_V,
SC_SCANCODE_W = SDL_SCANCODE_W,
SC_SCANCODE_X = SDL_SCANCODE_X,
SC_SCANCODE_Y = SDL_SCANCODE_Y,
SC_SCANCODE_Z = SDL_SCANCODE_Z,
SC_SCANCODE_1 = SDL_SCANCODE_1,
SC_SCANCODE_2 = SDL_SCANCODE_2,
SC_SCANCODE_3 = SDL_SCANCODE_3,
SC_SCANCODE_4 = SDL_SCANCODE_4,
SC_SCANCODE_5 = SDL_SCANCODE_5,
SC_SCANCODE_6 = SDL_SCANCODE_6,
SC_SCANCODE_7 = SDL_SCANCODE_7,
SC_SCANCODE_8 = SDL_SCANCODE_8,
SC_SCANCODE_9 = SDL_SCANCODE_9,
SC_SCANCODE_0 = SDL_SCANCODE_0,
SC_SCANCODE_RETURN = SDL_SCANCODE_RETURN,
SC_SCANCODE_ESCAPE = SDL_SCANCODE_ESCAPE,
SC_SCANCODE_BACKSPACE = SDL_SCANCODE_BACKSPACE,
SC_SCANCODE_TAB = SDL_SCANCODE_TAB,
SC_SCANCODE_SPACE = SDL_SCANCODE_SPACE,
SC_SCANCODE_MINUS = SDL_SCANCODE_MINUS,
SC_SCANCODE_EQUALS = SDL_SCANCODE_EQUALS,
SC_SCANCODE_LEFTBRACKET = SDL_SCANCODE_LEFTBRACKET,
SC_SCANCODE_RIGHTBRACKET = SDL_SCANCODE_RIGHTBRACKET,
SC_SCANCODE_BACKSLASH = SDL_SCANCODE_BACKSLASH,
SC_SCANCODE_NONUSHASH = SDL_SCANCODE_NONUSHASH,
SC_SCANCODE_SEMICOLON = SDL_SCANCODE_SEMICOLON,
SC_SCANCODE_APOSTROPHE = SDL_SCANCODE_APOSTROPHE,
SC_SCANCODE_GRAVE = SDL_SCANCODE_GRAVE,
SC_SCANCODE_COMMA = SDL_SCANCODE_COMMA,
SC_SCANCODE_PERIOD = SDL_SCANCODE_PERIOD,
SC_SCANCODE_SLASH = SDL_SCANCODE_SLASH,
SC_SCANCODE_CAPSLOCK = SDL_SCANCODE_CAPSLOCK,
SC_SCANCODE_F1 = SDL_SCANCODE_F1,
SC_SCANCODE_F2 = SDL_SCANCODE_F2,
SC_SCANCODE_F3 = SDL_SCANCODE_F3,
SC_SCANCODE_F4 = SDL_SCANCODE_F4,
SC_SCANCODE_F5 = SDL_SCANCODE_F5,
SC_SCANCODE_F6 = SDL_SCANCODE_F6,
SC_SCANCODE_F7 = SDL_SCANCODE_F7,
SC_SCANCODE_F8 = SDL_SCANCODE_F8,
SC_SCANCODE_F9 = SDL_SCANCODE_F9,
SC_SCANCODE_F10 = SDL_SCANCODE_F10,
SC_SCANCODE_F11 = SDL_SCANCODE_F11,
SC_SCANCODE_F12 = SDL_SCANCODE_F12,
SC_SCANCODE_PRINTSCREEN = SDL_SCANCODE_PRINTSCREEN,
SC_SCANCODE_SCROLLLOCK = SDL_SCANCODE_SCROLLLOCK,
SC_SCANCODE_PAUSE = SDL_SCANCODE_PAUSE,
SC_SCANCODE_INSERT = SDL_SCANCODE_INSERT,
SC_SCANCODE_HOME = SDL_SCANCODE_HOME,
SC_SCANCODE_PAGEUP = SDL_SCANCODE_PAGEUP,
SC_SCANCODE_DELETE = SDL_SCANCODE_DELETE,
SC_SCANCODE_END = SDL_SCANCODE_END,
SC_SCANCODE_PAGEDOWN = SDL_SCANCODE_PAGEDOWN,
SC_SCANCODE_RIGHT = SDL_SCANCODE_RIGHT,
SC_SCANCODE_LEFT = SDL_SCANCODE_LEFT,
SC_SCANCODE_DOWN = SDL_SCANCODE_DOWN,
SC_SCANCODE_UP = SDL_SCANCODE_UP,
SC_SCANCODE_NUMLOCK = SDL_SCANCODE_NUMLOCKCLEAR,
SC_SCANCODE_KP_DIVIDE = SDL_SCANCODE_KP_DIVIDE,
SC_SCANCODE_KP_MULTIPLY = SDL_SCANCODE_KP_MULTIPLY,
SC_SCANCODE_KP_MINUS = SDL_SCANCODE_KP_MINUS,
SC_SCANCODE_KP_PLUS = SDL_SCANCODE_KP_PLUS,
SC_SCANCODE_KP_ENTER = SDL_SCANCODE_KP_ENTER,
SC_SCANCODE_KP_1 = SDL_SCANCODE_KP_1,
SC_SCANCODE_KP_2 = SDL_SCANCODE_KP_2,
SC_SCANCODE_KP_3 = SDL_SCANCODE_KP_3,
SC_SCANCODE_KP_4 = SDL_SCANCODE_KP_4,
SC_SCANCODE_KP_5 = SDL_SCANCODE_KP_5,
SC_SCANCODE_KP_6 = SDL_SCANCODE_KP_6,
SC_SCANCODE_KP_7 = SDL_SCANCODE_KP_7,
SC_SCANCODE_KP_8 = SDL_SCANCODE_KP_8,
SC_SCANCODE_KP_9 = SDL_SCANCODE_KP_9,
SC_SCANCODE_KP_0 = SDL_SCANCODE_KP_0,
SC_SCANCODE_KP_PERIOD = SDL_SCANCODE_KP_PERIOD,
SC_SCANCODE_LCTRL = SDL_SCANCODE_LCTRL,
SC_SCANCODE_LSHIFT = SDL_SCANCODE_LSHIFT,
SC_SCANCODE_LALT = SDL_SCANCODE_LALT,
SC_SCANCODE_LGUI = SDL_SCANCODE_LGUI,
SC_SCANCODE_RCTRL = SDL_SCANCODE_RCTRL,
SC_SCANCODE_RSHIFT = SDL_SCANCODE_RSHIFT,
SC_SCANCODE_RALT = SDL_SCANCODE_RALT,
SC_SCANCODE_RGUI = SDL_SCANCODE_RGUI,
};
// On purpose, only use the "mask" values (1, 2, 4, 8, 16) for a single button,
// to avoid unnecessary conversions (and confusion).
enum sc_mouse_button {
SC_MOUSE_BUTTON_UNKNOWN = 0,
SC_MOUSE_BUTTON_LEFT = SDL_BUTTON(SDL_BUTTON_LEFT),
SC_MOUSE_BUTTON_RIGHT = SDL_BUTTON(SDL_BUTTON_RIGHT),
SC_MOUSE_BUTTON_MIDDLE = SDL_BUTTON(SDL_BUTTON_MIDDLE),
SC_MOUSE_BUTTON_X1 = SDL_BUTTON(SDL_BUTTON_X1),
SC_MOUSE_BUTTON_X2 = SDL_BUTTON(SDL_BUTTON_X2),
};
static_assert(sizeof(enum sc_mod) >= sizeof(SDL_Keymod),
"SDL_Keymod must be convertible to sc_mod");
static_assert(sizeof(enum sc_keycode) >= sizeof(SDL_Keycode),
"SDL_Keycode must be convertible to sc_keycode");
static_assert(sizeof(enum sc_scancode) >= sizeof(SDL_Scancode),
"SDL_Scancode must be convertible to sc_scancode");
enum sc_touch_action {
SC_TOUCH_ACTION_MOVE,
SC_TOUCH_ACTION_DOWN,
SC_TOUCH_ACTION_UP,
};
struct sc_key_event {
enum sc_action action;
enum sc_keycode keycode;
enum sc_scancode scancode;
uint16_t mods_state; // bitwise-OR of sc_mod values
bool repeat;
};
struct sc_text_event {
const char *text; // not owned
};
struct sc_mouse_click_event {
struct sc_position position;
enum sc_action action;
enum sc_mouse_button button;
uint8_t buttons_state; // bitwise-OR of sc_mouse_button values
};
struct sc_mouse_scroll_event {
struct sc_position position;
int32_t hscroll;
int32_t vscroll;
};
struct sc_mouse_motion_event {
struct sc_position position;
int32_t xrel;
int32_t yrel;
uint8_t buttons_state; // bitwise-OR of sc_mouse_button values
};
//enum sc_mouse_event_type {
// SC_MOUSE_EVENT_TYPE_CLICK,
// SC_MOUSE_EVENT_TYPE_MOVE,
// SC_MOUSE_EVENT_TYPE_SCROLL,
//};
//
//struct sc_mouse_event {
// enum sc_mouse_event_type type;
// struct sc_position position;
// uint8_t buttons_state; // bitwise-OR of sc_mouse_button values
// union {
// struct {
// enum sc_action action;
// enum sc_mouse_button button;
// } click;
// struct {
// int32_t xrel;
// int32_t yrel;
// } move;
// struct {
// int32_t h;
// int32_t v;
// } scroll;
// };
//};
struct sc_touch_event {
struct sc_position position;
enum sc_touch_action action;
uint64_t pointer_id;
float pressure;
};
//void
//sc_key_event_from_sdl(struct sc_key_event *event, const SDL_KeyboardEvent *sdl);
//
//void
//sc_text_event_from_sdl(struct sc_text_event *event,
// const SDL_TextInputEvent *sdl);
//
//void
//sc_mouse_click_event_from_sdl(struct sc_mouse_click_event *event,
// const SDL_MouseButtonEvent *sdl,
// const SDL_Window *window,
// struct sc_size screen_size);
//
//void
//sc_mouse_wheel_event_from_sdl(struct sc_mouse_wheel_event *event,
// const SDL_MouseWheelEvent *sdl);
//
//void
//sc_mouse_motion_event_from_sdl(struct sc_mouse_motion_event *event,
// const SDL_MouseMotionEvent *sdl);
//
//void
//sc_touch_event_from_sdl(struct sc_touch_event *event,
// const SDL_TouchFingerEvent *sdl);
#endif

View File

@ -3,32 +3,117 @@
#include <assert.h> #include <assert.h>
#include <SDL2/SDL_keycode.h> #include <SDL2/SDL_keycode.h>
#include "input_events.h"
#include "util/log.h" #include "util/log.h"
static const int ACTION_DOWN = 1; static inline uint16_t
static const int ACTION_UP = 1 << 1; sc_mods_state_from_sdl(uint16_t mods_state) {
return mods_state;
}
static inline enum sc_keycode
sc_keycode_from_sdl(SDL_Keycode keycode) {
return (enum sc_keycode) keycode;
}
static inline enum sc_scancode
sc_scancode_from_sdl(SDL_Scancode scancode) {
return (enum sc_scancode) scancode;
}
static inline enum sc_action
sc_action_from_sdl_keyboard_type(uint32_t type) {
assert(type == SDL_KEYDOWN || type == SDL_KEYUP);
if (type == SDL_KEYDOWN) {
return SC_ACTION_DOWN;
}
return SC_ACTION_UP;
}
static inline enum sc_action
sc_action_from_sdl_mousebutton_type(uint32_t type) {
assert(type == SDL_MOUSEBUTTONDOWN || type == SDL_MOUSEBUTTONUP);
if (type == SDL_MOUSEBUTTONDOWN) {
return SC_ACTION_DOWN;
}
return SC_ACTION_UP;
}
static inline enum sc_touch_action
sc_touch_action_from_sdl(uint32_t type) {
assert(type == SDL_FINGERMOTION || type == SDL_FINGERDOWN ||
type == SDL_FINGERUP);
if (type == SDL_FINGERMOTION) {
return SC_TOUCH_ACTION_MOVE;
}
if (type == SDL_FINGERDOWN) {
return SC_TOUCH_ACTION_DOWN;
}
return SC_TOUCH_ACTION_UP;
}
static inline enum sc_mouse_button
sc_mouse_button_from_sdl(uint8_t button) {
if (button >= SDL_BUTTON_LEFT && button <= SDL_BUTTON_X2) {
// SC_MOUSE_BUTTON_* constants are initialized from SDL_BUTTON(index)
return SDL_BUTTON(button);
}
return SC_MOUSE_BUTTON_UNKNOWN;
}
static inline uint8_t
sc_mouse_buttons_state_from_sdl(uint32_t buttons_state) {
assert(buttons_state < 0x100); // fits in uint8_t
return buttons_state;
}
//void
//sc_key_event_from_sdl(struct sc_key_event *event,
// const SDL_KeyboardEvent *sdl) {
// event->action = sc_action_from_sdl_keyboard_type(sdl->type);
// event->keycode = sc_keycode_from_sdl(sdl->keysym.sym);
// event->scancode = sc_scancode_from_sdl(sdl->keysym.scancode);
// event->repeat = sdl->repeat;
// event->mods_state = sc_mods_state_from_sdl(sdl->keysym.mod);
//}
//
//void
//sc_text_event_from_sdl(struct sc_text_event *event,
// const SDL_TextInputEvent *sdl) {
// event->text = sdl->text;
//}
//
//void
//sc_mouse_click_event_from_sdl(struct sc_mouse_click_event *event,
// const SDL_MouseButtonEvent *sdl,
// struct sc_size screen_size) {
// event->action = sc_action_from_sdl_mousebutton_type(sdl->type);
// event->button = sc_mouse_button_from_sdl(sdl->button);
// event->position.screen_size = screen_size;
//}
#define SC_SDL_SHORTCUT_MODS_MASK (KMOD_CTRL | KMOD_ALT | KMOD_GUI) #define SC_SDL_SHORTCUT_MODS_MASK (KMOD_CTRL | KMOD_ALT | KMOD_GUI)
static inline uint16_t static inline uint16_t
to_sdl_mod(unsigned mod) { to_sdl_mod(unsigned shortcut_mod) {
uint16_t sdl_mod = 0; uint16_t sdl_mod = 0;
if (mod & SC_MOD_LCTRL) { if (shortcut_mod & SC_SHORTCUT_MOD_LCTRL) {
sdl_mod |= KMOD_LCTRL; sdl_mod |= KMOD_LCTRL;
} }
if (mod & SC_MOD_RCTRL) { if (shortcut_mod & SC_SHORTCUT_MOD_RCTRL) {
sdl_mod |= KMOD_RCTRL; sdl_mod |= KMOD_RCTRL;
} }
if (mod & SC_MOD_LALT) { if (shortcut_mod & SC_SHORTCUT_MOD_LALT) {
sdl_mod |= KMOD_LALT; sdl_mod |= KMOD_LALT;
} }
if (mod & SC_MOD_RALT) { if (shortcut_mod & SC_SHORTCUT_MOD_RALT) {
sdl_mod |= KMOD_RALT; sdl_mod |= KMOD_RALT;
} }
if (mod & SC_MOD_LSUPER) { if (shortcut_mod & SC_SHORTCUT_MOD_LSUPER) {
sdl_mod |= KMOD_LGUI; sdl_mod |= KMOD_LGUI;
} }
if (mod & SC_MOD_RSUPER) { if (shortcut_mod & SC_SHORTCUT_MOD_RSUPER) {
sdl_mod |= KMOD_RGUI; sdl_mod |= KMOD_RGUI;
} }
return sdl_mod; return sdl_mod;
@ -89,85 +174,72 @@ input_manager_init(struct input_manager *im, struct controller *controller,
static void static void
send_keycode(struct controller *controller, enum android_keycode keycode, send_keycode(struct controller *controller, enum android_keycode keycode,
int actions, const char *name) { enum sc_action action, const char *name) {
// send DOWN event // send DOWN event
struct control_msg msg; struct control_msg msg;
msg.type = CONTROL_MSG_TYPE_INJECT_KEYCODE; msg.type = CONTROL_MSG_TYPE_INJECT_KEYCODE;
msg.inject_keycode.action = action == SC_ACTION_DOWN
? AKEY_EVENT_ACTION_DOWN
: AKEY_EVENT_ACTION_UP;
msg.inject_keycode.keycode = keycode; msg.inject_keycode.keycode = keycode;
msg.inject_keycode.metastate = 0; msg.inject_keycode.metastate = 0;
msg.inject_keycode.repeat = 0; msg.inject_keycode.repeat = 0;
if (actions & ACTION_DOWN) { if (!controller_push_msg(controller, &msg)) {
msg.inject_keycode.action = AKEY_EVENT_ACTION_DOWN; LOGW("Could not request 'inject %s'", name);
if (!controller_push_msg(controller, &msg)) { return;
LOGW("Could not request 'inject %s (DOWN)'", name);
return;
}
}
if (actions & ACTION_UP) {
msg.inject_keycode.action = AKEY_EVENT_ACTION_UP;
if (!controller_push_msg(controller, &msg)) {
LOGW("Could not request 'inject %s (UP)'", name);
}
} }
} }
static inline void static inline void
action_home(struct controller *controller, int actions) { action_home(struct controller *controller, enum sc_action action) {
send_keycode(controller, AKEYCODE_HOME, actions, "HOME"); send_keycode(controller, AKEYCODE_HOME, action, "HOME");
} }
static inline void static inline void
action_back(struct controller *controller, int actions) { action_back(struct controller *controller, enum sc_action action) {
send_keycode(controller, AKEYCODE_BACK, actions, "BACK"); send_keycode(controller, AKEYCODE_BACK, action, "BACK");
} }
static inline void static inline void
action_app_switch(struct controller *controller, int actions) { action_app_switch(struct controller *controller, enum sc_action action) {
send_keycode(controller, AKEYCODE_APP_SWITCH, actions, "APP_SWITCH"); send_keycode(controller, AKEYCODE_APP_SWITCH, action, "APP_SWITCH");
} }
static inline void static inline void
action_power(struct controller *controller, int actions) { action_power(struct controller *controller, enum sc_action action) {
send_keycode(controller, AKEYCODE_POWER, actions, "POWER"); send_keycode(controller, AKEYCODE_POWER, action, "POWER");
} }
static inline void static inline void
action_volume_up(struct controller *controller, int actions) { action_volume_up(struct controller *controller, enum sc_action action) {
send_keycode(controller, AKEYCODE_VOLUME_UP, actions, "VOLUME_UP"); send_keycode(controller, AKEYCODE_VOLUME_UP, action, "VOLUME_UP");
} }
static inline void static inline void
action_volume_down(struct controller *controller, int actions) { action_volume_down(struct controller *controller, enum sc_action action) {
send_keycode(controller, AKEYCODE_VOLUME_DOWN, actions, "VOLUME_DOWN"); send_keycode(controller, AKEYCODE_VOLUME_DOWN, action, "VOLUME_DOWN");
} }
static inline void static inline void
action_menu(struct controller *controller, int actions) { action_menu(struct controller *controller, enum sc_action action) {
send_keycode(controller, AKEYCODE_MENU, actions, "MENU"); send_keycode(controller, AKEYCODE_MENU, action, "MENU");
} }
// turn the screen on if it was off, press BACK otherwise // turn the screen on if it was off, press BACK otherwise
// If the screen is off, it is turned on only on ACTION_DOWN // If the screen is off, it is turned on only on ACTION_DOWN
static void static void
press_back_or_turn_screen_on(struct controller *controller, int actions) { press_back_or_turn_screen_on(struct controller *controller,
enum sc_action action) {
struct control_msg msg; struct control_msg msg;
msg.type = CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON; msg.type = CONTROL_MSG_TYPE_BACK_OR_SCREEN_ON;
msg.back_or_screen_on.action = action == SC_ACTION_DOWN
? AKEY_EVENT_ACTION_DOWN
: AKEY_EVENT_ACTION_UP;
if (actions & ACTION_DOWN) { if (!controller_push_msg(controller, &msg)) {
msg.back_or_screen_on.action = AKEY_EVENT_ACTION_DOWN; LOGW("Could not request 'press back or turn screen on'");
if (!controller_push_msg(controller, &msg)) { return;
LOGW("Could not request 'press back or turn screen on'");
return;
}
}
if (actions & ACTION_UP) {
msg.back_or_screen_on.action = AKEY_EVENT_ACTION_UP;
if (!controller_push_msg(controller, &msg)) {
LOGW("Could not request 'press back or turn screen on'");
}
} }
} }
@ -334,7 +406,11 @@ input_manager_process_text_input(struct input_manager *im,
return; return;
} }
im->kp->ops->process_text(im->kp, event); struct sc_text_event evt = {
.text = event->text,
};
im->kp->ops->process_text(im->kp, &evt);
} }
static bool static bool
@ -396,7 +472,7 @@ input_manager_process_key(struct input_manager *im,
// The shortcut modifier is pressed // The shortcut modifier is pressed
if (smod) { if (smod) {
int action = down ? ACTION_DOWN : ACTION_UP; enum sc_action action = down ? SC_ACTION_DOWN : SC_ACTION_UP;
switch (keycode) { switch (keycode) {
case SDLK_h: case SDLK_h:
if (control && !shift && !repeat) { if (control && !shift && !repeat) {
@ -553,7 +629,15 @@ input_manager_process_key(struct input_manager *im,
} }
} }
im->kp->ops->process_key(im->kp, event, ack_to_wait); struct sc_key_event evt = {
.action = sc_action_from_sdl_keyboard_type(event->type),
.keycode = sc_keycode_from_sdl(event->keysym.sym),
.scancode = sc_scancode_from_sdl(event->keysym.scancode),
.repeat = event->repeat,
.mods_state = sc_mods_state_from_sdl(event->keysym.mod),
};
im->kp->ops->process_key(im->kp, &evt, ack_to_wait);
} }
static void static void
@ -572,6 +656,17 @@ input_manager_process_mouse_motion(struct input_manager *im,
return; return;
} }
struct sc_mouse_motion_event evt = {
.position = {
.screen_size = im->screen->frame_size,
.point = screen_convert_window_to_frame_coords(im->screen,
event->x, event->y),
},
.xrel = event->xrel,
.yrel = event->yrel,
.buttons_state = sc_mouse_buttons_state_from_sdl(event->state),
};
im->mp->ops->process_mouse_motion(im->mp, event); im->mp->ops->process_mouse_motion(im->mp, event);
if (im->vfinger_down) { if (im->vfinger_down) {
@ -586,6 +681,24 @@ input_manager_process_mouse_motion(struct input_manager *im,
static void static void
input_manager_process_touch(struct input_manager *im, input_manager_process_touch(struct input_manager *im,
const SDL_TouchFingerEvent *event) { const SDL_TouchFingerEvent *event) {
int dw;
int dh;
SDL_GL_GetDrawableSize(im->screen->window, &dw, &dh);
// SDL touch event coordinates are normalized in the range [0; 1]
int32_t x = event->x * dw;
int32_t y = event->y * dh;
struct sc_touch_event evt = {
.position = {
.screen_size = im->screen->frame_size,
.point = screen_convert_drawable_to_frame_coords(im->screen, x, y),
},
.action = sc_touch_action_from_sdl(event->type),
.pointer_id = event->fingerId,
.pressure = event->pressure,
};
im->mp->ops->process_touch(im->mp, event); im->mp->ops->process_touch(im->mp, event);
} }
@ -601,7 +714,7 @@ input_manager_process_mouse_button(struct input_manager *im,
bool down = event->type == SDL_MOUSEBUTTONDOWN; bool down = event->type == SDL_MOUSEBUTTONDOWN;
if (!im->forward_all_clicks) { if (!im->forward_all_clicks) {
int action = down ? ACTION_DOWN : ACTION_UP; enum sc_action action = down ? SC_ACTION_DOWN : SC_ACTION_UP;
if (control && event->button == SDL_BUTTON_X1) { if (control && event->button == SDL_BUTTON_X1) {
action_app_switch(im->controller, action); action_app_switch(im->controller, action);
@ -646,6 +759,19 @@ input_manager_process_mouse_button(struct input_manager *im,
return; return;
} }
uint32_t sdl_buttons_state = SDL_GetMouseState(NULL, NULL);
struct sc_mouse_click_event evt = {
.position = {
.screen_size = im->screen->frame_size,
.point = screen_convert_window_to_frame_coords(im->screen, event->x,
event->y),
},
.action = sc_action_from_sdl_mousebutton_type(event->type),
.button = sc_mouse_button_from_sdl(event->button),
.buttons_state = sc_mouse_buttons_state_from_sdl(sdl_buttons_state),
};
im->mp->ops->process_mouse_button(im->mp, event); im->mp->ops->process_mouse_button(im->mp, event);
// Pinch-to-zoom simulation. // Pinch-to-zoom simulation.
@ -677,6 +803,21 @@ input_manager_process_mouse_button(struct input_manager *im,
static void static void
input_manager_process_mouse_wheel(struct input_manager *im, input_manager_process_mouse_wheel(struct input_manager *im,
const SDL_MouseWheelEvent *event) { const SDL_MouseWheelEvent *event) {
// mouse_x and mouse_y are expressed in pixels relative to the window
int mouse_x;
int mouse_y;
SDL_GetMouseState(&mouse_x, &mouse_y);
struct sc_mouse_scroll_event evt = {
.position = {
.screen_size = im->screen->frame_size,
.point = screen_convert_window_to_frame_coords(im->screen,
mouse_x, mouse_y),
},
.hscroll = event->x,
.vscroll = event->y,
};
im->mp->ops->process_mouse_wheel(im->mp, event); im->mp->ops->process_mouse_wheel(im->mp, event);
} }

View File

@ -1,11 +1,11 @@
#include "keyboard_inject.h" #include "keyboard_inject.h"
#include <assert.h> #include <assert.h>
#include <SDL2/SDL_events.h>
#include "android/input.h" #include "android/input.h"
#include "control_msg.h" #include "control_msg.h"
#include "controller.h" #include "controller.h"
#include "input_events.h"
#include "util/intmap.h" #include "util/intmap.h"
#include "util/log.h" #include "util/log.h"
@ -13,10 +13,10 @@
#define DOWNCAST(KP) container_of(KP, struct sc_keyboard_inject, key_processor) #define DOWNCAST(KP) container_of(KP, struct sc_keyboard_inject, key_processor)
static bool static bool
convert_keycode_action(SDL_EventType from, enum android_keyevent_action *to) { convert_keycode_action(enum sc_action from, enum android_keyevent_action *to) {
static const struct sc_intmap_entry actions[] = { static const struct sc_intmap_entry actions[] = {
{SDL_KEYDOWN, AKEY_EVENT_ACTION_DOWN}, {SC_ACTION_DOWN, AKEY_EVENT_ACTION_DOWN},
{SDL_KEYUP, AKEY_EVENT_ACTION_UP}, {SC_ACTION_UP, AKEY_EVENT_ACTION_UP},
}; };
const struct sc_intmap_entry *entry = SC_INTMAP_FIND_ENTRY(actions, from); const struct sc_intmap_entry *entry = SC_INTMAP_FIND_ENTRY(actions, from);
@ -29,125 +29,125 @@ convert_keycode_action(SDL_EventType from, enum android_keyevent_action *to) {
} }
static bool static bool
convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod, convert_keycode(enum sc_keycode from, enum android_keycode *to, uint16_t mod,
enum sc_key_inject_mode key_inject_mode) { enum sc_key_inject_mode key_inject_mode) {
// Navigation keys and ENTER. // Navigation keys and ENTER.
// Used in all modes. // Used in all modes.
static const struct sc_intmap_entry special_keys[] = { static const struct sc_intmap_entry special_keys[] = {
{SDLK_RETURN, AKEYCODE_ENTER}, {SC_KEYCODE_RETURN, AKEYCODE_ENTER},
{SDLK_KP_ENTER, AKEYCODE_NUMPAD_ENTER}, {SC_KEYCODE_KP_ENTER, AKEYCODE_NUMPAD_ENTER},
{SDLK_ESCAPE, AKEYCODE_ESCAPE}, {SC_KEYCODE_ESCAPE, AKEYCODE_ESCAPE},
{SDLK_BACKSPACE, AKEYCODE_DEL}, {SC_KEYCODE_BACKSPACE, AKEYCODE_DEL},
{SDLK_TAB, AKEYCODE_TAB}, {SC_KEYCODE_TAB, AKEYCODE_TAB},
{SDLK_PAGEUP, AKEYCODE_PAGE_UP}, {SC_KEYCODE_PAGEUP, AKEYCODE_PAGE_UP},
{SDLK_DELETE, AKEYCODE_FORWARD_DEL}, {SC_KEYCODE_DELETE, AKEYCODE_FORWARD_DEL},
{SDLK_HOME, AKEYCODE_MOVE_HOME}, {SC_KEYCODE_HOME, AKEYCODE_MOVE_HOME},
{SDLK_END, AKEYCODE_MOVE_END}, {SC_KEYCODE_END, AKEYCODE_MOVE_END},
{SDLK_PAGEDOWN, AKEYCODE_PAGE_DOWN}, {SC_KEYCODE_PAGEDOWN, AKEYCODE_PAGE_DOWN},
{SDLK_RIGHT, AKEYCODE_DPAD_RIGHT}, {SC_KEYCODE_RIGHT, AKEYCODE_DPAD_RIGHT},
{SDLK_LEFT, AKEYCODE_DPAD_LEFT}, {SC_KEYCODE_LEFT, AKEYCODE_DPAD_LEFT},
{SDLK_DOWN, AKEYCODE_DPAD_DOWN}, {SC_KEYCODE_DOWN, AKEYCODE_DPAD_DOWN},
{SDLK_UP, AKEYCODE_DPAD_UP}, {SC_KEYCODE_UP, AKEYCODE_DPAD_UP},
{SDLK_LCTRL, AKEYCODE_CTRL_LEFT}, {SC_KEYCODE_LCTRL, AKEYCODE_CTRL_LEFT},
{SDLK_RCTRL, AKEYCODE_CTRL_RIGHT}, {SC_KEYCODE_RCTRL, AKEYCODE_CTRL_RIGHT},
{SDLK_LSHIFT, AKEYCODE_SHIFT_LEFT}, {SC_KEYCODE_LSHIFT, AKEYCODE_SHIFT_LEFT},
{SDLK_RSHIFT, AKEYCODE_SHIFT_RIGHT}, {SC_KEYCODE_RSHIFT, AKEYCODE_SHIFT_RIGHT},
}; };
// Numpad navigation keys. // Numpad navigation keys.
// Used in all modes, when NumLock and Shift are disabled. // Used in all modes, when NumLock and Shift are disabled.
static const struct sc_intmap_entry kp_nav_keys[] = { static const struct sc_intmap_entry kp_nav_keys[] = {
{SDLK_KP_0, AKEYCODE_INSERT}, {SC_KEYCODE_KP_0, AKEYCODE_INSERT},
{SDLK_KP_1, AKEYCODE_MOVE_END}, {SC_KEYCODE_KP_1, AKEYCODE_MOVE_END},
{SDLK_KP_2, AKEYCODE_DPAD_DOWN}, {SC_KEYCODE_KP_2, AKEYCODE_DPAD_DOWN},
{SDLK_KP_3, AKEYCODE_PAGE_DOWN}, {SC_KEYCODE_KP_3, AKEYCODE_PAGE_DOWN},
{SDLK_KP_4, AKEYCODE_DPAD_LEFT}, {SC_KEYCODE_KP_4, AKEYCODE_DPAD_LEFT},
{SDLK_KP_6, AKEYCODE_DPAD_RIGHT}, {SC_KEYCODE_KP_6, AKEYCODE_DPAD_RIGHT},
{SDLK_KP_7, AKEYCODE_MOVE_HOME}, {SC_KEYCODE_KP_7, AKEYCODE_MOVE_HOME},
{SDLK_KP_8, AKEYCODE_DPAD_UP}, {SC_KEYCODE_KP_8, AKEYCODE_DPAD_UP},
{SDLK_KP_9, AKEYCODE_PAGE_UP}, {SC_KEYCODE_KP_9, AKEYCODE_PAGE_UP},
{SDLK_KP_PERIOD, AKEYCODE_FORWARD_DEL}, {SC_KEYCODE_KP_PERIOD, AKEYCODE_FORWARD_DEL},
}; };
// Letters and space. // Letters and space.
// Used in non-text mode. // Used in non-text mode.
static const struct sc_intmap_entry alphaspace_keys[] = { static const struct sc_intmap_entry alphaspace_keys[] = {
{SDLK_a, AKEYCODE_A}, {SC_KEYCODE_a, AKEYCODE_A},
{SDLK_b, AKEYCODE_B}, {SC_KEYCODE_b, AKEYCODE_B},
{SDLK_c, AKEYCODE_C}, {SC_KEYCODE_c, AKEYCODE_C},
{SDLK_d, AKEYCODE_D}, {SC_KEYCODE_d, AKEYCODE_D},
{SDLK_e, AKEYCODE_E}, {SC_KEYCODE_e, AKEYCODE_E},
{SDLK_f, AKEYCODE_F}, {SC_KEYCODE_f, AKEYCODE_F},
{SDLK_g, AKEYCODE_G}, {SC_KEYCODE_g, AKEYCODE_G},
{SDLK_h, AKEYCODE_H}, {SC_KEYCODE_h, AKEYCODE_H},
{SDLK_i, AKEYCODE_I}, {SC_KEYCODE_i, AKEYCODE_I},
{SDLK_j, AKEYCODE_J}, {SC_KEYCODE_j, AKEYCODE_J},
{SDLK_k, AKEYCODE_K}, {SC_KEYCODE_k, AKEYCODE_K},
{SDLK_l, AKEYCODE_L}, {SC_KEYCODE_l, AKEYCODE_L},
{SDLK_m, AKEYCODE_M}, {SC_KEYCODE_m, AKEYCODE_M},
{SDLK_n, AKEYCODE_N}, {SC_KEYCODE_n, AKEYCODE_N},
{SDLK_o, AKEYCODE_O}, {SC_KEYCODE_o, AKEYCODE_O},
{SDLK_p, AKEYCODE_P}, {SC_KEYCODE_p, AKEYCODE_P},
{SDLK_q, AKEYCODE_Q}, {SC_KEYCODE_q, AKEYCODE_Q},
{SDLK_r, AKEYCODE_R}, {SC_KEYCODE_r, AKEYCODE_R},
{SDLK_s, AKEYCODE_S}, {SC_KEYCODE_s, AKEYCODE_S},
{SDLK_t, AKEYCODE_T}, {SC_KEYCODE_t, AKEYCODE_T},
{SDLK_u, AKEYCODE_U}, {SC_KEYCODE_u, AKEYCODE_U},
{SDLK_v, AKEYCODE_V}, {SC_KEYCODE_v, AKEYCODE_V},
{SDLK_w, AKEYCODE_W}, {SC_KEYCODE_w, AKEYCODE_W},
{SDLK_x, AKEYCODE_X}, {SC_KEYCODE_x, AKEYCODE_X},
{SDLK_y, AKEYCODE_Y}, {SC_KEYCODE_y, AKEYCODE_Y},
{SDLK_z, AKEYCODE_Z}, {SC_KEYCODE_z, AKEYCODE_Z},
{SDLK_SPACE, AKEYCODE_SPACE}, {SC_KEYCODE_SPACE, AKEYCODE_SPACE},
}; };
// Numbers and punctuation keys. // Numbers and punctuation keys.
// Used in raw mode only. // Used in raw mode only.
static const struct sc_intmap_entry numbers_punct_keys[] = { static const struct sc_intmap_entry numbers_punct_keys[] = {
{SDLK_HASH, AKEYCODE_POUND}, {SC_KEYCODE_HASH, AKEYCODE_POUND},
{SDLK_PERCENT, AKEYCODE_PERIOD}, {SC_KEYCODE_PERCENT, AKEYCODE_PERIOD},
{SDLK_QUOTE, AKEYCODE_APOSTROPHE}, {SC_KEYCODE_QUOTE, AKEYCODE_APOSTROPHE},
{SDLK_ASTERISK, AKEYCODE_STAR}, {SC_KEYCODE_ASTERISK, AKEYCODE_STAR},
{SDLK_PLUS, AKEYCODE_PLUS}, {SC_KEYCODE_PLUS, AKEYCODE_PLUS},
{SDLK_COMMA, AKEYCODE_COMMA}, {SC_KEYCODE_COMMA, AKEYCODE_COMMA},
{SDLK_MINUS, AKEYCODE_MINUS}, {SC_KEYCODE_MINUS, AKEYCODE_MINUS},
{SDLK_PERIOD, AKEYCODE_PERIOD}, {SC_KEYCODE_PERIOD, AKEYCODE_PERIOD},
{SDLK_SLASH, AKEYCODE_SLASH}, {SC_KEYCODE_SLASH, AKEYCODE_SLASH},
{SDLK_0, AKEYCODE_0}, {SC_KEYCODE_0, AKEYCODE_0},
{SDLK_1, AKEYCODE_1}, {SC_KEYCODE_1, AKEYCODE_1},
{SDLK_2, AKEYCODE_2}, {SC_KEYCODE_2, AKEYCODE_2},
{SDLK_3, AKEYCODE_3}, {SC_KEYCODE_3, AKEYCODE_3},
{SDLK_4, AKEYCODE_4}, {SC_KEYCODE_4, AKEYCODE_4},
{SDLK_5, AKEYCODE_5}, {SC_KEYCODE_5, AKEYCODE_5},
{SDLK_6, AKEYCODE_6}, {SC_KEYCODE_6, AKEYCODE_6},
{SDLK_7, AKEYCODE_7}, {SC_KEYCODE_7, AKEYCODE_7},
{SDLK_8, AKEYCODE_8}, {SC_KEYCODE_8, AKEYCODE_8},
{SDLK_9, AKEYCODE_9}, {SC_KEYCODE_9, AKEYCODE_9},
{SDLK_SEMICOLON, AKEYCODE_SEMICOLON}, {SC_KEYCODE_SEMICOLON, AKEYCODE_SEMICOLON},
{SDLK_EQUALS, AKEYCODE_EQUALS}, {SC_KEYCODE_EQUALS, AKEYCODE_EQUALS},
{SDLK_AT, AKEYCODE_AT}, {SC_KEYCODE_AT, AKEYCODE_AT},
{SDLK_LEFTBRACKET, AKEYCODE_LEFT_BRACKET}, {SC_KEYCODE_LEFTBRACKET, AKEYCODE_LEFT_BRACKET},
{SDLK_BACKSLASH, AKEYCODE_BACKSLASH}, {SC_KEYCODE_BACKSLASH, AKEYCODE_BACKSLASH},
{SDLK_RIGHTBRACKET, AKEYCODE_RIGHT_BRACKET}, {SC_KEYCODE_RIGHTBRACKET, AKEYCODE_RIGHT_BRACKET},
{SDLK_BACKQUOTE, AKEYCODE_GRAVE}, {SC_KEYCODE_BACKQUOTE, AKEYCODE_GRAVE},
{SDLK_KP_1, AKEYCODE_NUMPAD_1}, {SC_KEYCODE_KP_1, AKEYCODE_NUMPAD_1},
{SDLK_KP_2, AKEYCODE_NUMPAD_2}, {SC_KEYCODE_KP_2, AKEYCODE_NUMPAD_2},
{SDLK_KP_3, AKEYCODE_NUMPAD_3}, {SC_KEYCODE_KP_3, AKEYCODE_NUMPAD_3},
{SDLK_KP_4, AKEYCODE_NUMPAD_4}, {SC_KEYCODE_KP_4, AKEYCODE_NUMPAD_4},
{SDLK_KP_5, AKEYCODE_NUMPAD_5}, {SC_KEYCODE_KP_5, AKEYCODE_NUMPAD_5},
{SDLK_KP_6, AKEYCODE_NUMPAD_6}, {SC_KEYCODE_KP_6, AKEYCODE_NUMPAD_6},
{SDLK_KP_7, AKEYCODE_NUMPAD_7}, {SC_KEYCODE_KP_7, AKEYCODE_NUMPAD_7},
{SDLK_KP_8, AKEYCODE_NUMPAD_8}, {SC_KEYCODE_KP_8, AKEYCODE_NUMPAD_8},
{SDLK_KP_9, AKEYCODE_NUMPAD_9}, {SC_KEYCODE_KP_9, AKEYCODE_NUMPAD_9},
{SDLK_KP_0, AKEYCODE_NUMPAD_0}, {SC_KEYCODE_KP_0, AKEYCODE_NUMPAD_0},
{SDLK_KP_DIVIDE, AKEYCODE_NUMPAD_DIVIDE}, {SC_KEYCODE_KP_DIVIDE, AKEYCODE_NUMPAD_DIVIDE},
{SDLK_KP_MULTIPLY, AKEYCODE_NUMPAD_MULTIPLY}, {SC_KEYCODE_KP_MULTIPLY, AKEYCODE_NUMPAD_MULTIPLY},
{SDLK_KP_MINUS, AKEYCODE_NUMPAD_SUBTRACT}, {SC_KEYCODE_KP_MINUS, AKEYCODE_NUMPAD_SUBTRACT},
{SDLK_KP_PLUS, AKEYCODE_NUMPAD_ADD}, {SC_KEYCODE_KP_PLUS, AKEYCODE_NUMPAD_ADD},
{SDLK_KP_PERIOD, AKEYCODE_NUMPAD_DOT}, {SC_KEYCODE_KP_PERIOD, AKEYCODE_NUMPAD_DOT},
{SDLK_KP_EQUALS, AKEYCODE_NUMPAD_EQUALS}, {SC_KEYCODE_KP_EQUALS, AKEYCODE_NUMPAD_EQUALS},
{SDLK_KP_LEFTPAREN, AKEYCODE_NUMPAD_LEFT_PAREN}, {SC_KEYCODE_KP_LEFTPAREN, AKEYCODE_NUMPAD_LEFT_PAREN},
{SDLK_KP_RIGHTPAREN, AKEYCODE_NUMPAD_RIGHT_PAREN}, {SC_KEYCODE_KP_RIGHTPAREN, AKEYCODE_NUMPAD_RIGHT_PAREN},
}; };
const struct sc_intmap_entry *entry = const struct sc_intmap_entry *entry =
@ -157,7 +157,7 @@ convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod,
return true; return true;
} }
if (!(mod & (KMOD_NUM | KMOD_SHIFT))) { if (!(mod & (SC_MOD_NUM | SC_MOD_LSHIFT | SC_MOD_RSHIFT))) {
// Handle Numpad events when Num Lock is disabled // Handle Numpad events when Num Lock is disabled
// If SHIFT is pressed, a text event will be sent instead // If SHIFT is pressed, a text event will be sent instead
entry = SC_INTMAP_FIND_ENTRY(kp_nav_keys, from); entry = SC_INTMAP_FIND_ENTRY(kp_nav_keys, from);
@ -167,12 +167,13 @@ convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod,
} }
} }
if (key_inject_mode == SC_KEY_INJECT_MODE_TEXT && !(mod & KMOD_CTRL)) { if (key_inject_mode == SC_KEY_INJECT_MODE_TEXT &&
!(mod & (SC_MOD_LCTRL | SC_MOD_RCTRL))) {
// do not forward alpha and space key events (unless Ctrl is pressed) // do not forward alpha and space key events (unless Ctrl is pressed)
return false; return false;
} }
if (mod & (KMOD_LALT | KMOD_RALT | KMOD_LGUI | KMOD_RGUI)) { if (mod & (SC_MOD_LALT | SC_MOD_RALT | SC_MOD_LGUI | SC_MOD_RGUI)) {
return false; return false;
} }
@ -214,70 +215,66 @@ autocomplete_metastate(enum android_metastate metastate) {
} }
static enum android_metastate static enum android_metastate
convert_meta_state(SDL_Keymod mod) { convert_meta_state(uint16_t mod) {
enum android_metastate metastate = 0; enum android_metastate metastate = 0;
if (mod & KMOD_LSHIFT) { if (mod & SC_MOD_LSHIFT) {
metastate |= AMETA_SHIFT_LEFT_ON; metastate |= AMETA_SHIFT_LEFT_ON;
} }
if (mod & KMOD_RSHIFT) { if (mod & SC_MOD_RSHIFT) {
metastate |= AMETA_SHIFT_RIGHT_ON; metastate |= AMETA_SHIFT_RIGHT_ON;
} }
if (mod & KMOD_LCTRL) { if (mod & SC_MOD_LCTRL) {
metastate |= AMETA_CTRL_LEFT_ON; metastate |= AMETA_CTRL_LEFT_ON;
} }
if (mod & KMOD_RCTRL) { if (mod & SC_MOD_RCTRL) {
metastate |= AMETA_CTRL_RIGHT_ON; metastate |= AMETA_CTRL_RIGHT_ON;
} }
if (mod & KMOD_LALT) { if (mod & SC_MOD_LALT) {
metastate |= AMETA_ALT_LEFT_ON; metastate |= AMETA_ALT_LEFT_ON;
} }
if (mod & KMOD_RALT) { if (mod & SC_MOD_RALT) {
metastate |= AMETA_ALT_RIGHT_ON; metastate |= AMETA_ALT_RIGHT_ON;
} }
if (mod & KMOD_LGUI) { // Windows key if (mod & SC_MOD_LGUI) { // Windows key
metastate |= AMETA_META_LEFT_ON; metastate |= AMETA_META_LEFT_ON;
} }
if (mod & KMOD_RGUI) { // Windows key if (mod & SC_MOD_RGUI) { // Windows key
metastate |= AMETA_META_RIGHT_ON; metastate |= AMETA_META_RIGHT_ON;
} }
if (mod & KMOD_NUM) { if (mod & SC_MOD_NUM) {
metastate |= AMETA_NUM_LOCK_ON; metastate |= AMETA_NUM_LOCK_ON;
} }
if (mod & KMOD_CAPS) { if (mod & SC_MOD_CAPS) {
metastate |= AMETA_CAPS_LOCK_ON; metastate |= AMETA_CAPS_LOCK_ON;
} }
if (mod & KMOD_MODE) { // Alt Gr
// no mapping?
}
// fill the dependent fields // fill the dependent fields
return autocomplete_metastate(metastate); return autocomplete_metastate(metastate);
} }
static bool static bool
convert_input_key(const SDL_KeyboardEvent *from, struct control_msg *to, convert_input_key(const struct sc_key_event *event, struct control_msg *msg,
enum sc_key_inject_mode key_inject_mode, uint32_t repeat) { enum sc_key_inject_mode key_inject_mode, uint32_t repeat) {
to->type = CONTROL_MSG_TYPE_INJECT_KEYCODE; msg->type = CONTROL_MSG_TYPE_INJECT_KEYCODE;
if (!convert_keycode_action(from->type, &to->inject_keycode.action)) { if (!convert_keycode_action(event->action, &msg->inject_keycode.action)) {
return false; return false;
} }
uint16_t mod = from->keysym.mod; if (!convert_keycode(event->keycode, &msg->inject_keycode.keycode,
if (!convert_keycode(from->keysym.sym, &to->inject_keycode.keycode, mod, event->mods_state, key_inject_mode)) {
key_inject_mode)) {
return false; return false;
} }
to->inject_keycode.repeat = repeat; msg->inject_keycode.repeat = repeat;
to->inject_keycode.metastate = convert_meta_state(mod); msg->inject_keycode.metastate = convert_meta_state(event->mods_state);
return true; return true;
} }
static void static void
sc_key_processor_process_key(struct sc_key_processor *kp, sc_key_processor_process_key(struct sc_key_processor *kp,
const SDL_KeyboardEvent *event, const struct sc_key_event *event,
uint64_t ack_to_wait) { uint64_t ack_to_wait) {
// The device clipboard synchronization and the key event messages are // The device clipboard synchronization and the key event messages are
// serialized, there is nothing special to do to ensure that the clipboard // serialized, there is nothing special to do to ensure that the clipboard
@ -305,7 +302,7 @@ sc_key_processor_process_key(struct sc_key_processor *kp,
static void static void
sc_key_processor_process_text(struct sc_key_processor *kp, sc_key_processor_process_text(struct sc_key_processor *kp,
const SDL_TextInputEvent *event) { const struct sc_text_event *event) {
struct sc_keyboard_inject *ki = DOWNCAST(kp); struct sc_keyboard_inject *ki = DOWNCAST(kp);
if (ki->key_inject_mode == SC_KEY_INJECT_MODE_RAW) { if (ki->key_inject_mode == SC_KEY_INJECT_MODE_RAW) {

View File

@ -22,7 +22,7 @@ const struct scrcpy_options scrcpy_options_default = {
.tunnel_host = 0, .tunnel_host = 0,
.tunnel_port = 0, .tunnel_port = 0,
.shortcut_mods = { .shortcut_mods = {
.data = {SC_MOD_LALT, SC_MOD_LSUPER}, .data = {SC_SHORTCUT_MOD_LALT, SC_SHORTCUT_MOD_LSUPER},
.count = 2, .count = 2,
}, },
.max_size = 0, .max_size = 0,

View File

@ -55,12 +55,12 @@ enum sc_key_inject_mode {
#define SC_MAX_SHORTCUT_MODS 8 #define SC_MAX_SHORTCUT_MODS 8
enum sc_shortcut_mod { enum sc_shortcut_mod {
SC_MOD_LCTRL = 1 << 0, SC_SHORTCUT_MOD_LCTRL = 1 << 0,
SC_MOD_RCTRL = 1 << 1, SC_SHORTCUT_MOD_RCTRL = 1 << 1,
SC_MOD_LALT = 1 << 2, SC_SHORTCUT_MOD_LALT = 1 << 2,
SC_MOD_RALT = 1 << 3, SC_SHORTCUT_MOD_RALT = 1 << 3,
SC_MOD_LSUPER = 1 << 4, SC_SHORTCUT_MOD_LSUPER = 1 << 4,
SC_MOD_RSUPER = 1 << 5, SC_SHORTCUT_MOD_RSUPER = 1 << 5,
}; };
struct sc_shortcut_mods { struct sc_shortcut_mods {

View File

@ -6,7 +6,7 @@
#include <assert.h> #include <assert.h>
#include <stdbool.h> #include <stdbool.h>
#include <SDL2/SDL_events.h> #include "input_events.h"
/** /**
* Key processor trait. * Key processor trait.
@ -37,12 +37,12 @@ struct sc_key_processor_ops {
* Ctrl+v on the device. * Ctrl+v on the device.
*/ */
void void
(*process_key)(struct sc_key_processor *kp, const SDL_KeyboardEvent *event, (*process_key)(struct sc_key_processor *kp,
uint64_t ack_to_wait); const struct sc_key_event *event, uint64_t ack_to_wait);
void void
(*process_text)(struct sc_key_processor *kp, (*process_text)(struct sc_key_processor *kp,
const SDL_TextInputEvent *event); const struct sc_text_event *event);
}; };
#endif #endif

View File

@ -129,25 +129,26 @@ static void test_parse_shortcut_mods(void) {
ok = sc_parse_shortcut_mods("lctrl", &mods); ok = sc_parse_shortcut_mods("lctrl", &mods);
assert(ok); assert(ok);
assert(mods.count == 1); assert(mods.count == 1);
assert(mods.data[0] == SC_MOD_LCTRL); assert(mods.data[0] == SC_SHORTCUT_MOD_LCTRL);
ok = sc_parse_shortcut_mods("lctrl+lalt", &mods); ok = sc_parse_shortcut_mods("lctrl+lalt", &mods);
assert(ok); assert(ok);
assert(mods.count == 1); assert(mods.count == 1);
assert(mods.data[0] == (SC_MOD_LCTRL | SC_MOD_LALT)); assert(mods.data[0] == (SC_SHORTCUT_MOD_LCTRL | SC_SHORTCUT_MOD_LALT));
ok = sc_parse_shortcut_mods("rctrl,lalt", &mods); ok = sc_parse_shortcut_mods("rctrl,lalt", &mods);
assert(ok); assert(ok);
assert(mods.count == 2); assert(mods.count == 2);
assert(mods.data[0] == SC_MOD_RCTRL); assert(mods.data[0] == SC_SHORTCUT_MOD_RCTRL);
assert(mods.data[1] == SC_MOD_LALT); assert(mods.data[1] == SC_SHORTCUT_MOD_LALT);
ok = sc_parse_shortcut_mods("lsuper,rsuper+lalt,lctrl+rctrl+ralt", &mods); ok = sc_parse_shortcut_mods("lsuper,rsuper+lalt,lctrl+rctrl+ralt", &mods);
assert(ok); assert(ok);
assert(mods.count == 3); assert(mods.count == 3);
assert(mods.data[0] == SC_MOD_LSUPER); assert(mods.data[0] == SC_SHORTCUT_MOD_LSUPER);
assert(mods.data[1] == (SC_MOD_RSUPER | SC_MOD_LALT)); assert(mods.data[1] == (SC_SHORTCUT_MOD_RSUPER | SC_SHORTCUT_MOD_LALT));
assert(mods.data[2] == (SC_MOD_LCTRL | SC_MOD_RCTRL | SC_MOD_RALT)); assert(mods.data[2] == (SC_SHORTCUT_MOD_LCTRL | SC_SHORTCUT_MOD_RCTRL |
SC_SHORTCUT_MOD_RALT));
ok = sc_parse_shortcut_mods("", &mods); ok = sc_parse_shortcut_mods("", &mods);
assert(!ok); assert(!ok);