From 6102a0b5bb5b7c8473c407592707539be48da19e Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Fri, 31 Dec 2021 16:32:07 +0100 Subject: [PATCH] Move input_manager into screen The input_manager is strongly tied to the screen, it could not work independently of the specific screen implementation. To implement a user-friendly HID mouse behavior, some SDL events will need to be handled both by the screen and by the input manager. For example, a click must typically be handled by the input_manager so that it is forwarded to the device, but in HID mouse mode, the first click should be handled by the screen to capture the mouse (enable relative mouse mode). Make the input_manager a descendant of the screen, so that the screen decides what to do on SDL events. Concretely, replace this structure hierarchy: +- struct scrcpy +- struct input_manager +- struct screen by this one: +- struct scrcpy +- struct screen +- struct input_manager --- app/src/input_manager.c | 1 + app/src/input_manager.h | 1 - app/src/scrcpy.c | 127 ++++++++++++++++++---------------------- app/src/screen.c | 16 ++++- app/src/screen.h | 15 +++++ 5 files changed, 87 insertions(+), 73 deletions(-) diff --git a/app/src/input_manager.c b/app/src/input_manager.c index ce138012..ec91787a 100644 --- a/app/src/input_manager.c +++ b/app/src/input_manager.c @@ -4,6 +4,7 @@ #include #include "input_events.h" +#include "screen.h" #include "util/log.h" static inline uint16_t diff --git a/app/src/input_manager.h b/app/src/input_manager.h index 38d0d703..088406f6 100644 --- a/app/src/input_manager.h +++ b/app/src/input_manager.h @@ -10,7 +10,6 @@ #include "controller.h" #include "fps_counter.h" #include "options.h" -#include "screen.h" #include "trait/key_processor.h" #include "trait/mouse_processor.h" diff --git a/app/src/scrcpy.c b/app/src/scrcpy.c index 972e2d99..5370f448 100644 --- a/app/src/scrcpy.c +++ b/app/src/scrcpy.c @@ -17,7 +17,6 @@ #include "decoder.h" #include "events.h" #include "file_handler.h" -#include "input_manager.h" #ifdef HAVE_AOA_HID # include "hid_keyboard.h" #endif @@ -57,7 +56,6 @@ struct scrcpy { #endif }; struct sc_mouse_inject mouse_inject; - struct input_manager input_manager; }; static inline void @@ -189,11 +187,6 @@ handle_event(struct scrcpy *s, const struct scrcpy_options *options, } bool consumed = screen_handle_event(&s->screen, event); - if (consumed) { - goto end; - } - - consumed = input_manager_handle_event(&s->input_manager, event); (void) consumed; end: @@ -450,6 +443,9 @@ scrcpy(struct scrcpy_options *options) { stream_add_sink(&s->stream, &rec->packet_sink); } + struct sc_key_processor *kp = NULL; + struct sc_mouse_processor *mp = NULL; + if (options->control) { #ifdef HAVE_AOA_HID if (options->keyboard_input_mode == SC_KEYBOARD_INPUT_MODE_HID) { @@ -481,59 +477,7 @@ scrcpy(struct scrcpy_options *options) { LOGW("Could not request 'set screen power mode'"); } } - } - if (options->display) { - const char *window_title = - options->window_title ? options->window_title : info->device_name; - - struct screen_params screen_params = { - .window_title = window_title, - .frame_size = info->frame_size, - .always_on_top = options->always_on_top, - .window_x = options->window_x, - .window_y = options->window_y, - .window_width = options->window_width, - .window_height = options->window_height, - .window_borderless = options->window_borderless, - .rotation = options->rotation, - .mipmaps = options->mipmaps, - .fullscreen = options->fullscreen, - .buffering_time = options->display_buffer, - }; - - if (!screen_init(&s->screen, &screen_params)) { - goto end; - } - screen_initialized = true; - - decoder_add_sink(&s->decoder, &s->screen.frame_sink); - } - -#ifdef HAVE_V4L2 - if (options->v4l2_device) { - if (!sc_v4l2_sink_init(&s->v4l2_sink, options->v4l2_device, - info->frame_size, options->v4l2_buffer)) { - goto end; - } - - decoder_add_sink(&s->decoder, &s->v4l2_sink.frame_sink); - - v4l2_sink_initialized = true; - } -#endif - - // now we consumed the header values, the socket receives the video stream - // start the stream - if (!stream_start(&s->stream)) { - goto end; - } - stream_started = true; - - struct sc_key_processor *kp = NULL; - struct sc_mouse_processor *mp = NULL; - - if (options->control) { #ifdef HAVE_AOA_HID if (options->keyboard_input_mode == SC_KEYBOARD_INPUT_MODE_HID) { bool aoa_hid_ok = false; @@ -582,19 +526,60 @@ aoa_hid_end: mp = &s->mouse_inject.mouse_processor; } - struct input_manager_params im_params = { - .controller = &s->controller, - .screen = &s->screen, - .kp = kp, - .mp = mp, - .control = options->control, - .forward_all_clicks = options->forward_all_clicks, - .legacy_paste = options->legacy_paste, - .clipboard_autosync = options->clipboard_autosync, - .shortcut_mods = &options->shortcut_mods, - }; + if (options->display) { + const char *window_title = + options->window_title ? options->window_title : info->device_name; - input_manager_init(&s->input_manager, &im_params); + struct screen_params screen_params = { + .controller = &s->controller, + .kp = kp, + .mp = mp, + .control = options->control, + .forward_all_clicks = options->forward_all_clicks, + .legacy_paste = options->legacy_paste, + .clipboard_autosync = options->clipboard_autosync, + .shortcut_mods = &options->shortcut_mods, + .window_title = window_title, + .frame_size = info->frame_size, + .always_on_top = options->always_on_top, + .window_x = options->window_x, + .window_y = options->window_y, + .window_width = options->window_width, + .window_height = options->window_height, + .window_borderless = options->window_borderless, + .rotation = options->rotation, + .mipmaps = options->mipmaps, + .fullscreen = options->fullscreen, + .buffering_time = options->display_buffer, + }; + + if (!screen_init(&s->screen, &screen_params)) { + goto end; + } + screen_initialized = true; + + decoder_add_sink(&s->decoder, &s->screen.frame_sink); + } + +#ifdef HAVE_V4L2 + if (options->v4l2_device) { + if (!sc_v4l2_sink_init(&s->v4l2_sink, options->v4l2_device, + info->frame_size, options->v4l2_buffer)) { + goto end; + } + + decoder_add_sink(&s->decoder, &s->v4l2_sink.frame_sink); + + v4l2_sink_initialized = true; + } +#endif + + // now we consumed the header values, the socket receives the video stream + // start the stream + if (!stream_start(&s->stream)) { + goto end; + } + stream_started = true; ret = event_loop(s, options); LOGD("quit..."); diff --git a/app/src/screen.c b/app/src/screen.c index 0cb09a4b..9ad81cb8 100644 --- a/app/src/screen.c +++ b/app/src/screen.c @@ -470,6 +470,20 @@ screen_init(struct screen *screen, const struct screen_params *params) { goto error_destroy_texture; } + struct input_manager_params im_params = { + .controller = params->controller, + .screen = screen, + .kp = params->kp, + .mp = params->mp, + .control = params->control, + .forward_all_clicks = params->forward_all_clicks, + .legacy_paste = params->legacy_paste, + .clipboard_autosync = params->clipboard_autosync, + .shortcut_mods = params->shortcut_mods, + }; + + input_manager_init(&screen->im, &im_params); + // Reset the window size to trigger a SIZE_CHANGED event, to workaround // HiDPI issues with some SDL renderers when several displays having // different HiDPI scaling are connected @@ -773,7 +787,7 @@ screen_handle_event(struct screen *screen, SDL_Event *event) { return true; } - return false; + return input_manager_handle_event(&screen->im, event); } struct sc_point diff --git a/app/src/screen.h b/app/src/screen.h index b82bf631..bc7696f1 100644 --- a/app/src/screen.h +++ b/app/src/screen.h @@ -7,10 +7,14 @@ #include #include +#include "controller.h" #include "coords.h" #include "fps_counter.h" +#include "input_manager.h" #include "opengl.h" +#include "trait/key_processor.h" #include "trait/frame_sink.h" +#include "trait/mouse_processor.h" #include "video_buffer.h" struct screen { @@ -20,6 +24,7 @@ struct screen { bool open; // track the open/close state to assert correct behavior #endif + struct input_manager im; struct sc_video_buffer vb; struct fps_counter fps_counter; @@ -50,6 +55,16 @@ struct screen { }; struct screen_params { + struct controller *controller; + struct sc_key_processor *kp; + struct sc_mouse_processor *mp; + + bool control; + bool forward_all_clicks; + bool legacy_paste; + bool clipboard_autosync; + const struct sc_shortcut_mods *shortcut_mods; + const char *window_title; struct sc_size frame_size; bool always_on_top;