Compare commits

..

8 Commits

Author SHA1 Message Date
Romain Vimont
b26ad41da7 wip 2021-12-29 01:21:40 +01:00
Romain Vimont
bc84a130a4 wip 2021-12-29 00:37:49 +01:00
Romain Vimont
3c663e1c0f wip 2021-12-28 23:46:24 +01:00
Romain Vimont
05ef36545c wip 2021-12-28 23:46:24 +01:00
Romain Vimont
ac32280a43 wip 2021-12-28 23:46:24 +01:00
Romain Vimont
93c49ae446 wip 2021-12-28 23:46:24 +01:00
Romain Vimont
15d40b6d16 input_events 2021-12-28 23:46:24 +01:00
Romain Vimont
c520d9f0e7 Rename SC_MOD_* to SC_SHORTCUT_MOD_*
This will avoid conflicts with new SC_MOD_* constants.
2021-12-28 23:46:24 +01:00
9 changed files with 386 additions and 160 deletions

View File

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

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;
}

View File

@@ -10,37 +10,9 @@
#include "coords.h"
/* The representation of input events in scrcpy is very close to the SDL API,
* for simplicity.
*
* This scrcpy input events API is designed to be consumed by input event
* processors (sc_key_processor and sc_mouse_processor, see app/src/trait/).
*
* One major semantic difference between SDL input events and scrcpy input
* events is their frame of reference (for mouse and touch events): SDL events
* coordinates are expressed in SDL window coordinates (the visible UI), while
* scrcpy events are expressed in device frame coordinates.
*
* In particular, the window may be visually scaled or rotated (with --rotation
* or MOD+Left/Right), but this does not impact scrcpy input events (contrary
* to SDL input events). This allows to abstract these display details from the
* input event processors (and to make them independent from the "screen").
*
* For many enums below, the values are purposely the same as the SDL
* constants (though not all SDL values are represented), so that the
/* 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.
*
* In practice, there are 3 levels of input events:
* 1. SDL input events (as received from SDL)
* 2. scrcpy input events (this API)
* 3. the key/mouse processors input events (Android API or HID events)
*
* An input event is first received (1), then (if accepted) converted to an
* scrcpy input event (2), then submitted to the relevant key/mouse processor,
* which (if accepted) is converted to an Android event (to be sent to the
* server) or to an HID event (to be sent over USB/AOA directly).
*/
* straightforward */
enum sc_mod {
SC_MOD_LSHIFT = KMOD_LSHIFT,
@@ -58,8 +30,8 @@ enum sc_mod {
};
enum sc_action {
SC_ACTION_DOWN, // key or button pressed
SC_ACTION_UP, // key or button released
SC_ACTION_DOWN = 1, // key or button pressed
SC_ACTION_UP = 2, // key or button released
};
enum sc_keycode {
@@ -365,9 +337,37 @@ struct sc_mouse_scroll_event {
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;
@@ -375,4 +375,30 @@ struct sc_touch_event {
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

@@ -68,6 +68,31 @@ sc_mouse_buttons_state_from_sdl(uint32_t buttons_state) {
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)
static inline uint16_t
@@ -149,72 +174,85 @@ input_manager_init(struct input_manager *im, struct controller *controller,
static void
send_keycode(struct controller *controller, enum android_keycode keycode,
enum sc_action action, const char *name) {
int actions, const char *name) {
// send DOWN event
struct control_msg msg;
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.metastate = 0;
msg.inject_keycode.repeat = 0;
if (!controller_push_msg(controller, &msg)) {
LOGW("Could not request 'inject %s'", name);
return;
if (actions & SC_ACTION_DOWN) {
msg.inject_keycode.action = AKEY_EVENT_ACTION_DOWN;
if (!controller_push_msg(controller, &msg)) {
LOGW("Could not request 'inject %s (DOWN)'", name);
return;
}
}
if (actions & SC_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
action_home(struct controller *controller, enum sc_action action) {
send_keycode(controller, AKEYCODE_HOME, action, "HOME");
action_home(struct controller *controller, int actions) {
send_keycode(controller, AKEYCODE_HOME, actions, "HOME");
}
static inline void
action_back(struct controller *controller, enum sc_action action) {
send_keycode(controller, AKEYCODE_BACK, action, "BACK");
action_back(struct controller *controller, int actions) {
send_keycode(controller, AKEYCODE_BACK, actions, "BACK");
}
static inline void
action_app_switch(struct controller *controller, enum sc_action action) {
send_keycode(controller, AKEYCODE_APP_SWITCH, action, "APP_SWITCH");
action_app_switch(struct controller *controller, int actions) {
send_keycode(controller, AKEYCODE_APP_SWITCH, actions, "APP_SWITCH");
}
static inline void
action_power(struct controller *controller, enum sc_action action) {
send_keycode(controller, AKEYCODE_POWER, action, "POWER");
action_power(struct controller *controller, int actions) {
send_keycode(controller, AKEYCODE_POWER, actions, "POWER");
}
static inline void
action_volume_up(struct controller *controller, enum sc_action action) {
send_keycode(controller, AKEYCODE_VOLUME_UP, action, "VOLUME_UP");
action_volume_up(struct controller *controller, int actions) {
send_keycode(controller, AKEYCODE_VOLUME_UP, actions, "VOLUME_UP");
}
static inline void
action_volume_down(struct controller *controller, enum sc_action action) {
send_keycode(controller, AKEYCODE_VOLUME_DOWN, action, "VOLUME_DOWN");
action_volume_down(struct controller *controller, int actions) {
send_keycode(controller, AKEYCODE_VOLUME_DOWN, actions, "VOLUME_DOWN");
}
static inline void
action_menu(struct controller *controller, enum sc_action action) {
send_keycode(controller, AKEYCODE_MENU, action, "MENU");
action_menu(struct controller *controller, int actions) {
send_keycode(controller, AKEYCODE_MENU, actions, "MENU");
}
// turn the screen on if it was off, press BACK otherwise
// If the screen is off, it is turned on only on ACTION_DOWN
static void
press_back_or_turn_screen_on(struct controller *controller,
enum sc_action action) {
press_back_or_turn_screen_on(struct controller *controller, int actions) {
struct control_msg msg;
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 (!controller_push_msg(controller, &msg)) {
LOGW("Could not request 'press back or turn screen on'");
return;
if (actions & SC_ACTION_DOWN) {
msg.back_or_screen_on.action = AKEY_EVENT_ACTION_DOWN;
if (!controller_push_msg(controller, &msg)) {
LOGW("Could not request 'press back or turn screen on'");
return;
}
}
if (actions & SC_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'");
}
}
}
@@ -637,10 +675,12 @@ input_manager_process_mouse_motion(struct input_manager *im,
.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, &evt);
im->mp->ops->process_mouse_motion(im->mp, event);
if (im->vfinger_down) {
struct sc_point mouse =
@@ -672,7 +712,7 @@ input_manager_process_touch(struct input_manager *im,
.pressure = event->pressure,
};
im->mp->ops->process_touch(im->mp, &evt);
im->mp->ops->process_touch(im->mp, event);
}
static void
@@ -745,7 +785,7 @@ input_manager_process_mouse_button(struct input_manager *im,
.buttons_state = sc_mouse_buttons_state_from_sdl(sdl_buttons_state),
};
im->mp->ops->process_mouse_click(im->mp, &evt);
im->mp->ops->process_mouse_button(im->mp, event);
// Pinch-to-zoom simulation.
//
@@ -791,7 +831,7 @@ input_manager_process_mouse_wheel(struct input_manager *im,
.vscroll = event->y,
};
im->mp->ops->process_mouse_scroll(im->mp, &evt);
im->mp->ops->process_mouse_wheel(im->mp, event);
}
bool

View File

@@ -12,13 +12,20 @@
/** Downcast key processor to sc_keyboard_inject */
#define DOWNCAST(KP) container_of(KP, struct sc_keyboard_inject, key_processor)
static enum android_keyevent_action
convert_keycode_action(enum sc_action action) {
if (action == SC_ACTION_DOWN) {
return AKEY_EVENT_ACTION_DOWN;
static bool
convert_keycode_action(enum sc_action from, enum android_keyevent_action *to) {
static const struct sc_intmap_entry actions[] = {
{SC_ACTION_DOWN, AKEY_EVENT_ACTION_DOWN},
{SC_ACTION_UP, AKEY_EVENT_ACTION_UP},
};
const struct sc_intmap_entry *entry = SC_INTMAP_FIND_ENTRY(actions, from);
if (entry) {
*to = entry->value;
return true;
}
assert(action == SC_ACTION_UP);
return AKEY_EVENT_ACTION_UP;
return false;
}
static bool
@@ -250,12 +257,15 @@ convert_input_key(const struct sc_key_event *event, struct control_msg *msg,
enum sc_key_inject_mode key_inject_mode, uint32_t repeat) {
msg->type = CONTROL_MSG_TYPE_INJECT_KEYCODE;
if (!convert_keycode_action(event->action, &msg->inject_keycode.action)) {
return false;
}
if (!convert_keycode(event->keycode, &msg->inject_keycode.keycode,
event->mods_state, key_inject_mode)) {
return false;
}
msg->inject_keycode.action = convert_keycode_action(event->action);
msg->inject_keycode.repeat = repeat;
msg->inject_keycode.metastate = convert_meta_state(event->mods_state);

View File

@@ -1,11 +1,11 @@
#include "mouse_inject.h"
#include <assert.h>
#include <SDL2/SDL_events.h>
#include "android/input.h"
#include "control_msg.h"
#include "controller.h"
#include "input_events.h"
#include "util/intmap.h"
#include "util/log.h"
@@ -15,61 +15,153 @@
static enum android_motionevent_buttons
convert_mouse_buttons(uint32_t state) {
enum android_motionevent_buttons buttons = 0;
if (state & SC_MOUSE_BUTTON_LEFT) {
if (state & SDL_BUTTON_LMASK) {
buttons |= AMOTION_EVENT_BUTTON_PRIMARY;
}
if (state & SC_MOUSE_BUTTON_RIGHT) {
if (state & SDL_BUTTON_RMASK) {
buttons |= AMOTION_EVENT_BUTTON_SECONDARY;
}
if (state & SC_MOUSE_BUTTON_MIDDLE) {
if (state & SDL_BUTTON_MMASK) {
buttons |= AMOTION_EVENT_BUTTON_TERTIARY;
}
if (state & SC_MOUSE_BUTTON_X1) {
if (state & SDL_BUTTON_X1MASK) {
buttons |= AMOTION_EVENT_BUTTON_BACK;
}
if (state & SC_MOUSE_BUTTON_X2) {
if (state & SDL_BUTTON_X2MASK) {
buttons |= AMOTION_EVENT_BUTTON_FORWARD;
}
return buttons;
}
static enum android_motionevent_action
convert_mouse_action(enum sc_action action) {
if (action == SC_ACTION_DOWN) {
return AMOTION_EVENT_ACTION_DOWN;
static bool
convert_mouse_action(SDL_EventType from, enum android_motionevent_action *to) {
static const struct sc_intmap_entry actions[] = {
{SDL_MOUSEBUTTONDOWN, AMOTION_EVENT_ACTION_DOWN},
{SDL_MOUSEBUTTONUP, AMOTION_EVENT_ACTION_UP},
};
const struct sc_intmap_entry *entry = SC_INTMAP_FIND_ENTRY(actions, from);
if (entry) {
*to = entry->value;
return true;
}
assert(action == SC_ACTION_UP);
return AMOTION_EVENT_ACTION_UP;
return false;
}
static enum android_motionevent_action
convert_touch_action(enum sc_touch_action action) {
switch (action) {
case SC_TOUCH_ACTION_MOVE:
return AMOTION_EVENT_ACTION_MOVE;
case SC_TOUCH_ACTION_DOWN:
return AMOTION_EVENT_ACTION_DOWN;
default:
assert(action == SC_TOUCH_ACTION_UP);
return AMOTION_EVENT_ACTION_UP;
static bool
convert_touch_action(SDL_EventType from, enum android_motionevent_action *to) {
static const struct sc_intmap_entry actions[] = {
{SDL_FINGERMOTION, AMOTION_EVENT_ACTION_MOVE},
{SDL_FINGERDOWN, AMOTION_EVENT_ACTION_DOWN},
{SDL_FINGERUP, AMOTION_EVENT_ACTION_UP},
};
const struct sc_intmap_entry *entry = SC_INTMAP_FIND_ENTRY(actions, from);
if (entry) {
*to = entry->value;
return true;
}
return false;
}
static bool
convert_mouse_motion(const SDL_MouseMotionEvent *from, struct screen *screen,
struct control_msg *to) {
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->frame_size;
to->inject_touch_event.position.point =
screen_convert_window_to_frame_coords(screen, from->x, from->y);
to->inject_touch_event.pressure = 1.f;
to->inject_touch_event.buttons = convert_mouse_buttons(from->state);
return true;
}
static bool
convert_touch(const SDL_TouchFingerEvent *from, struct screen *screen,
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->frame_size;
int dw;
int dh;
SDL_GL_GetDrawableSize(screen->window, &dw, &dh);
// SDL touch event coordinates are normalized in the range [0; 1]
int32_t x = from->x * dw;
int32_t y = from->y * dh;
to->inject_touch_event.position.point =
screen_convert_drawable_to_frame_coords(screen, x, y);
to->inject_touch_event.pressure = from->pressure;
to->inject_touch_event.buttons = 0;
return true;
}
static bool
convert_mouse_button(const SDL_MouseButtonEvent *from, struct screen *screen,
struct control_msg *to) {
to->type = CONTROL_MSG_TYPE_INJECT_TOUCH_EVENT;
if (!convert_mouse_action(from->type, &to->inject_touch_event.action)) {
return false;
}
to->inject_touch_event.pointer_id = POINTER_ID_MOUSE;
to->inject_touch_event.position.screen_size = screen->frame_size;
to->inject_touch_event.position.point =
screen_convert_window_to_frame_coords(screen, from->x, from->y);
to->inject_touch_event.pressure =
from->type == SDL_MOUSEBUTTONDOWN ? 1.f : 0.f;
to->inject_touch_event.buttons =
convert_mouse_buttons(SDL_BUTTON(from->button));
return true;
}
static bool
convert_mouse_wheel(const SDL_MouseWheelEvent *from, struct screen *screen,
struct control_msg *to) {
// 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_position position = {
.screen_size = screen->frame_size,
.point = screen_convert_window_to_frame_coords(screen,
mouse_x, mouse_y),
};
to->type = CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT;
to->inject_scroll_event.position = position;
to->inject_scroll_event.hscroll = from->x;
to->inject_scroll_event.vscroll = from->y;
return true;
}
static void
sc_mouse_processor_process_mouse_motion(struct sc_mouse_processor *mp,
const struct sc_mouse_motion_event *event) {
const SDL_MouseMotionEvent *event) {
struct sc_mouse_inject *mi = DOWNCAST(mp);
struct control_msg msg = {
.type = CONTROL_MSG_TYPE_INJECT_TOUCH_EVENT,
.inject_touch_event = {
.action = AMOTION_EVENT_ACTION_MOVE,
.pointer_id = POINTER_ID_MOUSE,
.position = event->position,
.pressure = 1.f,
.buttons = convert_mouse_buttons(event->buttons_state),
},
};
struct control_msg msg;
if (!convert_mouse_motion(event, mi->screen, &msg)) {
return;
}
if (!controller_push_msg(mi->controller, &msg)) {
LOGW("Could not request 'inject mouse motion event'");
@@ -78,75 +170,54 @@ sc_mouse_processor_process_mouse_motion(struct sc_mouse_processor *mp,
static void
sc_mouse_processor_process_touch(struct sc_mouse_processor *mp,
const struct sc_touch_event *event) {
const SDL_TouchFingerEvent *event) {
struct sc_mouse_inject *mi = DOWNCAST(mp);
struct control_msg msg = {
.type = CONTROL_MSG_TYPE_INJECT_TOUCH_EVENT,
.inject_touch_event = {
.action = convert_touch_action(event->action),
.pointer_id = event->pointer_id,
.position = event->position,
.pressure = event->pressure,
.buttons = 0,
},
};
if (!controller_push_msg(mi->controller, &msg)) {
LOGW("Could not request 'inject touch event'");
struct control_msg msg;
if (convert_touch(event, mi->screen, &msg)) {
if (!controller_push_msg(mi->controller, &msg)) {
LOGW("Could not request 'inject touch event'");
}
}
}
static void
sc_mouse_processor_process_mouse_click(struct sc_mouse_processor *mp,
const struct sc_mouse_click_event *event) {
sc_mouse_processor_process_mouse_button(struct sc_mouse_processor *mp,
const SDL_MouseButtonEvent *event) {
struct sc_mouse_inject *mi = DOWNCAST(mp);
struct control_msg msg = {
.type = CONTROL_MSG_TYPE_INJECT_TOUCH_EVENT,
.inject_touch_event = {
.action = convert_mouse_action(event->action),
.pointer_id = POINTER_ID_MOUSE,
.position = event->position,
.pressure = event->action == SC_ACTION_DOWN ? 1.f : 0.f,
.buttons = convert_mouse_buttons(event->buttons_state),
},
};
if (!controller_push_msg(mi->controller, &msg)) {
LOGW("Could not request 'inject mouse click event'");
struct control_msg msg;
if (convert_mouse_button(event, mi->screen, &msg)) {
if (!controller_push_msg(mi->controller, &msg)) {
LOGW("Could not request 'inject mouse button event'");
}
}
}
static void
sc_mouse_processor_process_mouse_scroll(struct sc_mouse_processor *mp,
const struct sc_mouse_scroll_event *event) {
sc_mouse_processor_process_mouse_wheel(struct sc_mouse_processor *mp,
const SDL_MouseWheelEvent *event) {
struct sc_mouse_inject *mi = DOWNCAST(mp);
struct control_msg msg = {
.type = CONTROL_MSG_TYPE_INJECT_SCROLL_EVENT,
.inject_scroll_event = {
.position = event->position,
.hscroll = event->hscroll,
.vscroll = event->vscroll,
},
};
if (!controller_push_msg(mi->controller, &msg)) {
LOGW("Could not request 'inject mouse scroll event'");
struct control_msg msg;
if (convert_mouse_wheel(event, mi->screen, &msg)) {
if (!controller_push_msg(mi->controller, &msg)) {
LOGW("Could not request 'inject mouse wheel event'");
}
}
}
void
sc_mouse_inject_init(struct sc_mouse_inject *mi,
struct controller *controller) {
sc_mouse_inject_init(struct sc_mouse_inject *mi, struct controller *controller,
struct screen *screen) {
mi->controller = controller;
mi->screen = screen;
static const struct sc_mouse_processor_ops ops = {
.process_mouse_motion = sc_mouse_processor_process_mouse_motion,
.process_touch = sc_mouse_processor_process_touch,
.process_mouse_click = sc_mouse_processor_process_mouse_click,
.process_mouse_scroll = sc_mouse_processor_process_mouse_scroll,
.process_mouse_button = sc_mouse_processor_process_mouse_button,
.process_mouse_wheel = sc_mouse_processor_process_mouse_wheel,
};
mi->mouse_processor.ops = &ops;

View File

@@ -13,9 +13,11 @@ struct sc_mouse_inject {
struct sc_mouse_processor mouse_processor; // mouse processor trait
struct controller *controller;
struct screen *screen;
};
void
sc_mouse_inject_init(struct sc_mouse_inject *mi, struct controller *controller);
sc_mouse_inject_init(struct sc_mouse_inject *mi, struct controller *controller,
struct screen *screen);
#endif

View File

@@ -581,7 +581,7 @@ aoa_hid_end:
kp = &s->keyboard_inject.key_processor;
}
sc_mouse_inject_init(&s->mouse_inject, &s->controller);
sc_mouse_inject_init(&s->mouse_inject, &s->controller, &s->screen);
mp = &s->mouse_inject.mouse_processor;
}

View File

@@ -6,7 +6,7 @@
#include <assert.h>
#include <stdbool.h>
#include "input_events.h"
#include <SDL2/SDL_events.h>
/**
* Mouse processor trait.
@@ -21,19 +21,19 @@ struct sc_mouse_processor {
struct sc_mouse_processor_ops {
void
(*process_mouse_motion)(struct sc_mouse_processor *mp,
const struct sc_mouse_motion_event *event);
const SDL_MouseMotionEvent *event);
void
(*process_touch)(struct sc_mouse_processor *mp,
const struct sc_touch_event *event);
const SDL_TouchFingerEvent *event);
void
(*process_mouse_click)(struct sc_mouse_processor *mp,
const struct sc_mouse_click_event *event);
(*process_mouse_button)(struct sc_mouse_processor *mp,
const SDL_MouseButtonEvent *event);
void
(*process_mouse_scroll)(struct sc_mouse_processor *mp,
const struct sc_mouse_scroll_event *event);
(*process_mouse_wheel)(struct sc_mouse_processor *mp,
const SDL_MouseWheelEvent *event);
};
#endif