2019-09-15 22:27:37 +08:00
|
|
|
#include "event_converter.h"
|
2017-12-14 18:38:44 +08:00
|
|
|
|
2019-09-30 04:36:56 +08:00
|
|
|
#include "config.h"
|
|
|
|
|
2019-03-03 06:52:22 +08:00
|
|
|
#define MAP(FROM, TO) case FROM: *to = TO; return true
|
|
|
|
#define FAIL default: return false
|
2017-12-14 18:38:44 +08:00
|
|
|
|
2019-03-03 06:52:22 +08:00
|
|
|
static bool
|
2019-03-03 03:09:56 +08:00
|
|
|
convert_keycode_action(SDL_EventType from, enum android_keyevent_action *to) {
|
2017-12-14 18:38:44 +08:00
|
|
|
switch (from) {
|
|
|
|
MAP(SDL_KEYDOWN, AKEY_EVENT_ACTION_DOWN);
|
|
|
|
MAP(SDL_KEYUP, AKEY_EVENT_ACTION_UP);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-03 03:09:56 +08:00
|
|
|
static enum android_metastate
|
|
|
|
autocomplete_metastate(enum android_metastate metastate) {
|
2017-12-14 18:38:44 +08:00
|
|
|
// fill dependant flags
|
|
|
|
if (metastate & (AMETA_SHIFT_LEFT_ON | AMETA_SHIFT_RIGHT_ON)) {
|
|
|
|
metastate |= AMETA_SHIFT_ON;
|
|
|
|
}
|
|
|
|
if (metastate & (AMETA_CTRL_LEFT_ON | AMETA_CTRL_RIGHT_ON)) {
|
|
|
|
metastate |= AMETA_CTRL_ON;
|
|
|
|
}
|
|
|
|
if (metastate & (AMETA_ALT_LEFT_ON | AMETA_ALT_RIGHT_ON)) {
|
|
|
|
metastate |= AMETA_ALT_ON;
|
|
|
|
}
|
|
|
|
if (metastate & (AMETA_META_LEFT_ON | AMETA_META_RIGHT_ON)) {
|
|
|
|
metastate |= AMETA_META_ON;
|
|
|
|
}
|
|
|
|
|
|
|
|
return metastate;
|
|
|
|
}
|
|
|
|
|
2019-03-03 03:09:56 +08:00
|
|
|
static enum android_metastate
|
|
|
|
convert_meta_state(SDL_Keymod mod) {
|
2017-12-14 18:38:44 +08:00
|
|
|
enum android_metastate metastate = 0;
|
|
|
|
if (mod & KMOD_LSHIFT) {
|
|
|
|
metastate |= AMETA_SHIFT_LEFT_ON;
|
|
|
|
}
|
|
|
|
if (mod & KMOD_RSHIFT) {
|
|
|
|
metastate |= AMETA_SHIFT_RIGHT_ON;
|
|
|
|
}
|
|
|
|
if (mod & KMOD_LCTRL) {
|
|
|
|
metastate |= AMETA_CTRL_LEFT_ON;
|
|
|
|
}
|
|
|
|
if (mod & KMOD_RCTRL) {
|
|
|
|
metastate |= AMETA_CTRL_RIGHT_ON;
|
|
|
|
}
|
|
|
|
if (mod & KMOD_LALT) {
|
|
|
|
metastate |= AMETA_ALT_LEFT_ON;
|
|
|
|
}
|
|
|
|
if (mod & KMOD_RALT) {
|
|
|
|
metastate |= AMETA_ALT_RIGHT_ON;
|
|
|
|
}
|
|
|
|
if (mod & KMOD_LGUI) { // Windows key
|
|
|
|
metastate |= AMETA_META_LEFT_ON;
|
|
|
|
}
|
|
|
|
if (mod & KMOD_RGUI) { // Windows key
|
|
|
|
metastate |= AMETA_META_RIGHT_ON;
|
|
|
|
}
|
|
|
|
if (mod & KMOD_NUM) {
|
|
|
|
metastate |= AMETA_NUM_LOCK_ON;
|
|
|
|
}
|
|
|
|
if (mod & KMOD_CAPS) {
|
|
|
|
metastate |= AMETA_CAPS_LOCK_ON;
|
|
|
|
}
|
|
|
|
if (mod & KMOD_MODE) { // Alt Gr
|
|
|
|
// no mapping?
|
|
|
|
}
|
|
|
|
|
|
|
|
// fill the dependent fields
|
|
|
|
return autocomplete_metastate(metastate);
|
|
|
|
}
|
|
|
|
|
2019-03-03 06:52:22 +08:00
|
|
|
static bool
|
|
|
|
convert_keycode(SDL_Keycode from, enum android_keycode *to, uint16_t mod) {
|
2017-12-14 18:38:44 +08:00
|
|
|
switch (from) {
|
|
|
|
MAP(SDLK_RETURN, AKEYCODE_ENTER);
|
2018-04-08 18:38:06 +08:00
|
|
|
MAP(SDLK_KP_ENTER, AKEYCODE_NUMPAD_ENTER);
|
2017-12-14 18:38:44 +08:00
|
|
|
MAP(SDLK_ESCAPE, AKEYCODE_ESCAPE);
|
|
|
|
MAP(SDLK_BACKSPACE, AKEYCODE_DEL);
|
|
|
|
MAP(SDLK_TAB, AKEYCODE_TAB);
|
|
|
|
MAP(SDLK_PAGEUP, AKEYCODE_PAGE_UP);
|
|
|
|
MAP(SDLK_DELETE, AKEYCODE_FORWARD_DEL);
|
2019-05-27 16:19:03 +08:00
|
|
|
MAP(SDLK_HOME, AKEYCODE_MOVE_HOME);
|
2017-12-14 18:38:44 +08:00
|
|
|
MAP(SDLK_END, AKEYCODE_MOVE_END);
|
|
|
|
MAP(SDLK_PAGEDOWN, AKEYCODE_PAGE_DOWN);
|
|
|
|
MAP(SDLK_RIGHT, AKEYCODE_DPAD_RIGHT);
|
|
|
|
MAP(SDLK_LEFT, AKEYCODE_DPAD_LEFT);
|
|
|
|
MAP(SDLK_DOWN, AKEYCODE_DPAD_DOWN);
|
|
|
|
MAP(SDLK_UP, AKEYCODE_DPAD_UP);
|
2018-09-09 22:31:41 +08:00
|
|
|
}
|
|
|
|
if (mod & (KMOD_LALT | KMOD_RALT | KMOD_LGUI | KMOD_RGUI)) {
|
2019-03-03 06:52:22 +08:00
|
|
|
return false;
|
2018-09-09 22:31:41 +08:00
|
|
|
}
|
|
|
|
// if ALT and META are not pressed, also handle letters and space
|
|
|
|
switch (from) {
|
|
|
|
MAP(SDLK_a, AKEYCODE_A);
|
|
|
|
MAP(SDLK_b, AKEYCODE_B);
|
|
|
|
MAP(SDLK_c, AKEYCODE_C);
|
|
|
|
MAP(SDLK_d, AKEYCODE_D);
|
|
|
|
MAP(SDLK_e, AKEYCODE_E);
|
|
|
|
MAP(SDLK_f, AKEYCODE_F);
|
|
|
|
MAP(SDLK_g, AKEYCODE_G);
|
|
|
|
MAP(SDLK_h, AKEYCODE_H);
|
|
|
|
MAP(SDLK_i, AKEYCODE_I);
|
|
|
|
MAP(SDLK_j, AKEYCODE_J);
|
|
|
|
MAP(SDLK_k, AKEYCODE_K);
|
|
|
|
MAP(SDLK_l, AKEYCODE_L);
|
|
|
|
MAP(SDLK_m, AKEYCODE_M);
|
|
|
|
MAP(SDLK_n, AKEYCODE_N);
|
|
|
|
MAP(SDLK_o, AKEYCODE_O);
|
|
|
|
MAP(SDLK_p, AKEYCODE_P);
|
|
|
|
MAP(SDLK_q, AKEYCODE_Q);
|
|
|
|
MAP(SDLK_r, AKEYCODE_R);
|
|
|
|
MAP(SDLK_s, AKEYCODE_S);
|
|
|
|
MAP(SDLK_t, AKEYCODE_T);
|
|
|
|
MAP(SDLK_u, AKEYCODE_U);
|
|
|
|
MAP(SDLK_v, AKEYCODE_V);
|
|
|
|
MAP(SDLK_w, AKEYCODE_W);
|
|
|
|
MAP(SDLK_x, AKEYCODE_X);
|
|
|
|
MAP(SDLK_y, AKEYCODE_Y);
|
|
|
|
MAP(SDLK_z, AKEYCODE_Z);
|
|
|
|
MAP(SDLK_SPACE, AKEYCODE_SPACE);
|
2017-12-14 18:38:44 +08:00
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-03 03:09:56 +08:00
|
|
|
static enum android_motionevent_buttons
|
2019-03-03 06:52:22 +08:00
|
|
|
convert_mouse_buttons(uint32_t state) {
|
2017-12-14 18:38:44 +08:00
|
|
|
enum android_motionevent_buttons buttons = 0;
|
|
|
|
if (state & SDL_BUTTON_LMASK) {
|
|
|
|
buttons |= AMOTION_EVENT_BUTTON_PRIMARY;
|
|
|
|
}
|
|
|
|
if (state & SDL_BUTTON_RMASK) {
|
|
|
|
buttons |= AMOTION_EVENT_BUTTON_SECONDARY;
|
|
|
|
}
|
|
|
|
if (state & SDL_BUTTON_MMASK) {
|
|
|
|
buttons |= AMOTION_EVENT_BUTTON_TERTIARY;
|
|
|
|
}
|
|
|
|
if (state & SDL_BUTTON_X1) {
|
|
|
|
buttons |= AMOTION_EVENT_BUTTON_BACK;
|
|
|
|
}
|
|
|
|
if (state & SDL_BUTTON_X2) {
|
|
|
|
buttons |= AMOTION_EVENT_BUTTON_FORWARD;
|
|
|
|
}
|
|
|
|
return buttons;
|
|
|
|
}
|
|
|
|
|
2019-03-03 06:52:22 +08:00
|
|
|
bool
|
2019-09-15 22:32:46 +08:00
|
|
|
convert_input_key(const SDL_KeyboardEvent *from, struct control_msg *to) {
|
2019-05-31 20:55:11 +08:00
|
|
|
to->type = CONTROL_MSG_TYPE_INJECT_KEYCODE;
|
2017-12-14 18:38:44 +08:00
|
|
|
|
2019-05-31 20:55:11 +08:00
|
|
|
if (!convert_keycode_action(from->type, &to->inject_keycode.action)) {
|
2019-03-03 06:52:22 +08:00
|
|
|
return false;
|
2017-12-14 18:38:44 +08:00
|
|
|
}
|
|
|
|
|
2019-03-03 06:52:22 +08:00
|
|
|
uint16_t mod = from->keysym.mod;
|
2019-05-31 20:55:11 +08:00
|
|
|
if (!convert_keycode(from->keysym.sym, &to->inject_keycode.keycode, mod)) {
|
2019-03-03 06:52:22 +08:00
|
|
|
return false;
|
2017-12-14 18:38:44 +08:00
|
|
|
}
|
|
|
|
|
2019-05-31 20:55:11 +08:00
|
|
|
to->inject_keycode.metastate = convert_meta_state(mod);
|
2017-12-14 18:38:44 +08:00
|
|
|
|
2019-03-03 06:52:22 +08:00
|
|
|
return true;
|
2017-12-14 18:38:44 +08:00
|
|
|
}
|
|
|
|
|
2019-10-04 02:14:12 +08:00
|
|
|
static bool
|
|
|
|
convert_mouse_action(SDL_EventType from, enum android_motionevent_action *to) {
|
|
|
|
switch (from) {
|
|
|
|
MAP(SDL_MOUSEBUTTONDOWN, AMOTION_EVENT_ACTION_DOWN);
|
|
|
|
MAP(SDL_MOUSEBUTTONUP, AMOTION_EVENT_ACTION_UP);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-03 06:52:22 +08:00
|
|
|
bool
|
2019-09-15 22:32:46 +08:00
|
|
|
convert_mouse_button(const SDL_MouseButtonEvent *from, struct size screen_size,
|
|
|
|
struct control_msg *to) {
|
2019-10-04 02:14:12 +08:00
|
|
|
to->type = CONTROL_MSG_TYPE_INJECT_TOUCH_EVENT;
|
2017-12-14 18:38:44 +08:00
|
|
|
|
2019-10-04 02:14:12 +08:00
|
|
|
if (!convert_mouse_action(from->type, &to->inject_touch_event.action)) {
|
2019-03-03 06:52:22 +08:00
|
|
|
return false;
|
2017-12-14 18:38:44 +08:00
|
|
|
}
|
|
|
|
|
2019-10-04 02:14:12 +08:00
|
|
|
to->inject_touch_event.pointer_id = POINTER_ID_MOUSE;
|
|
|
|
to->inject_touch_event.position.screen_size = screen_size;
|
|
|
|
to->inject_touch_event.position.point.x = from->x;
|
|
|
|
to->inject_touch_event.position.point.y = from->y;
|
|
|
|
to->inject_touch_event.pressure = 1.f;
|
|
|
|
to->inject_touch_event.buttons =
|
2019-05-31 20:55:11 +08:00
|
|
|
convert_mouse_buttons(SDL_BUTTON(from->button));
|
2017-12-14 18:38:44 +08:00
|
|
|
|
2019-03-03 06:52:22 +08:00
|
|
|
return true;
|
2017-12-14 18:38:44 +08:00
|
|
|
}
|
|
|
|
|
2019-03-03 06:52:22 +08:00
|
|
|
bool
|
2019-09-15 22:32:46 +08:00
|
|
|
convert_mouse_motion(const SDL_MouseMotionEvent *from, struct size screen_size,
|
|
|
|
struct control_msg *to) {
|
2019-10-04 02:14:12 +08:00
|
|
|
to->type = CONTROL_MSG_TYPE_INJECT_TOUCH_EVENT;
|
|
|
|
to->inject_touch_event.action = AMOTION_EVENT_ACTION_MOVE;
|
|
|
|
to->inject_touch_event.pointer_id = POINTER_ID_MOUSE;
|
|
|
|
to->inject_touch_event.position.screen_size = screen_size;
|
|
|
|
to->inject_touch_event.position.point.x = from->x;
|
|
|
|
to->inject_touch_event.position.point.y = from->y;
|
|
|
|
to->inject_touch_event.pressure = 1.f;
|
|
|
|
to->inject_touch_event.buttons = convert_mouse_buttons(from->state);
|
2017-12-14 18:38:44 +08:00
|
|
|
|
2019-03-03 06:52:22 +08:00
|
|
|
return true;
|
2017-12-14 18:38:44 +08:00
|
|
|
}
|
|
|
|
|
2019-09-23 03:30:05 +08:00
|
|
|
static bool
|
|
|
|
convert_touch_action(SDL_EventType from, enum android_motionevent_action *to) {
|
|
|
|
switch (from) {
|
|
|
|
MAP(SDL_FINGERMOTION, AMOTION_EVENT_ACTION_MOVE);
|
|
|
|
MAP(SDL_FINGERDOWN, AMOTION_EVENT_ACTION_DOWN);
|
|
|
|
MAP(SDL_FINGERUP, AMOTION_EVENT_ACTION_UP);
|
|
|
|
FAIL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
convert_touch(const SDL_TouchFingerEvent *from, struct size screen_size,
|
|
|
|
struct control_msg *to) {
|
|
|
|
to->type = CONTROL_MSG_TYPE_INJECT_TOUCH_EVENT;
|
|
|
|
|
|
|
|
if (!convert_touch_action(from->type, &to->inject_touch_event.action)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
to->inject_touch_event.pointer_id = from->fingerId;
|
|
|
|
to->inject_touch_event.position.screen_size = screen_size;
|
|
|
|
// SDL touch event coordinates are normalized in the range [0; 1]
|
|
|
|
to->inject_touch_event.position.point.x = from->x * screen_size.width;
|
|
|
|
to->inject_touch_event.position.point.y = from->y * screen_size.height;
|
|
|
|
to->inject_touch_event.pressure = from->pressure;
|
2019-10-04 02:14:12 +08:00
|
|
|
to->inject_touch_event.buttons = 0;
|
2019-09-23 03:30:05 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-03-03 06:52:22 +08:00
|
|
|
bool
|
2019-09-15 22:32:46 +08:00
|
|
|
convert_mouse_wheel(const SDL_MouseWheelEvent *from, struct position position,
|
|
|
|
struct control_msg *to) {
|
2019-05-31 20:55:11 +08:00
|
|
|
to->type = CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT;
|
2017-12-14 18:38:44 +08:00
|
|
|
|
2019-05-31 20:55:11 +08:00
|
|
|
to->inject_scroll_event.position = position;
|
2017-12-14 18:38:44 +08:00
|
|
|
|
2018-01-22 23:50:08 +08:00
|
|
|
int mul = from->direction == SDL_MOUSEWHEEL_NORMAL ? 1 : -1;
|
2018-03-12 16:37:46 +08:00
|
|
|
// SDL behavior seems inconsistent between horizontal and vertical scrolling
|
|
|
|
// so reverse the horizontal
|
|
|
|
// <https://wiki.libsdl.org/SDL_MouseWheelEvent#Remarks>
|
2019-05-31 20:55:11 +08:00
|
|
|
to->inject_scroll_event.hscroll = -mul * from->x;
|
|
|
|
to->inject_scroll_event.vscroll = mul * from->y;
|
2017-12-14 18:38:44 +08:00
|
|
|
|
2019-03-03 06:52:22 +08:00
|
|
|
return true;
|
2017-12-14 18:38:44 +08:00
|
|
|
}
|