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
This commit is contained in:
parent
2b34e1224e
commit
6102a0b5bb
5 changed files with 87 additions and 73 deletions
|
@ -4,6 +4,7 @@
|
||||||
#include <SDL2/SDL_keycode.h>
|
#include <SDL2/SDL_keycode.h>
|
||||||
|
|
||||||
#include "input_events.h"
|
#include "input_events.h"
|
||||||
|
#include "screen.h"
|
||||||
#include "util/log.h"
|
#include "util/log.h"
|
||||||
|
|
||||||
static inline uint16_t
|
static inline uint16_t
|
||||||
|
|
|
@ -10,7 +10,6 @@
|
||||||
#include "controller.h"
|
#include "controller.h"
|
||||||
#include "fps_counter.h"
|
#include "fps_counter.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "screen.h"
|
|
||||||
#include "trait/key_processor.h"
|
#include "trait/key_processor.h"
|
||||||
#include "trait/mouse_processor.h"
|
#include "trait/mouse_processor.h"
|
||||||
|
|
||||||
|
|
127
app/src/scrcpy.c
127
app/src/scrcpy.c
|
@ -17,7 +17,6 @@
|
||||||
#include "decoder.h"
|
#include "decoder.h"
|
||||||
#include "events.h"
|
#include "events.h"
|
||||||
#include "file_handler.h"
|
#include "file_handler.h"
|
||||||
#include "input_manager.h"
|
|
||||||
#ifdef HAVE_AOA_HID
|
#ifdef HAVE_AOA_HID
|
||||||
# include "hid_keyboard.h"
|
# include "hid_keyboard.h"
|
||||||
#endif
|
#endif
|
||||||
|
@ -57,7 +56,6 @@ struct scrcpy {
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
struct sc_mouse_inject mouse_inject;
|
struct sc_mouse_inject mouse_inject;
|
||||||
struct input_manager input_manager;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline void
|
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);
|
bool consumed = screen_handle_event(&s->screen, event);
|
||||||
if (consumed) {
|
|
||||||
goto end;
|
|
||||||
}
|
|
||||||
|
|
||||||
consumed = input_manager_handle_event(&s->input_manager, event);
|
|
||||||
(void) consumed;
|
(void) consumed;
|
||||||
|
|
||||||
end:
|
end:
|
||||||
|
@ -450,6 +443,9 @@ scrcpy(struct scrcpy_options *options) {
|
||||||
stream_add_sink(&s->stream, &rec->packet_sink);
|
stream_add_sink(&s->stream, &rec->packet_sink);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct sc_key_processor *kp = NULL;
|
||||||
|
struct sc_mouse_processor *mp = NULL;
|
||||||
|
|
||||||
if (options->control) {
|
if (options->control) {
|
||||||
#ifdef HAVE_AOA_HID
|
#ifdef HAVE_AOA_HID
|
||||||
if (options->keyboard_input_mode == SC_KEYBOARD_INPUT_MODE_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'");
|
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
|
#ifdef HAVE_AOA_HID
|
||||||
if (options->keyboard_input_mode == SC_KEYBOARD_INPUT_MODE_HID) {
|
if (options->keyboard_input_mode == SC_KEYBOARD_INPUT_MODE_HID) {
|
||||||
bool aoa_hid_ok = false;
|
bool aoa_hid_ok = false;
|
||||||
|
@ -582,19 +526,60 @@ aoa_hid_end:
|
||||||
mp = &s->mouse_inject.mouse_processor;
|
mp = &s->mouse_inject.mouse_processor;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct input_manager_params im_params = {
|
if (options->display) {
|
||||||
.controller = &s->controller,
|
const char *window_title =
|
||||||
.screen = &s->screen,
|
options->window_title ? options->window_title : info->device_name;
|
||||||
.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,
|
|
||||||
};
|
|
||||||
|
|
||||||
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);
|
ret = event_loop(s, options);
|
||||||
LOGD("quit...");
|
LOGD("quit...");
|
||||||
|
|
|
@ -470,6 +470,20 @@ screen_init(struct screen *screen, const struct screen_params *params) {
|
||||||
goto error_destroy_texture;
|
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
|
// Reset the window size to trigger a SIZE_CHANGED event, to workaround
|
||||||
// HiDPI issues with some SDL renderers when several displays having
|
// HiDPI issues with some SDL renderers when several displays having
|
||||||
// different HiDPI scaling are connected
|
// different HiDPI scaling are connected
|
||||||
|
@ -773,7 +787,7 @@ screen_handle_event(struct screen *screen, SDL_Event *event) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return input_manager_handle_event(&screen->im, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct sc_point
|
struct sc_point
|
||||||
|
|
|
@ -7,10 +7,14 @@
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
|
|
||||||
|
#include "controller.h"
|
||||||
#include "coords.h"
|
#include "coords.h"
|
||||||
#include "fps_counter.h"
|
#include "fps_counter.h"
|
||||||
|
#include "input_manager.h"
|
||||||
#include "opengl.h"
|
#include "opengl.h"
|
||||||
|
#include "trait/key_processor.h"
|
||||||
#include "trait/frame_sink.h"
|
#include "trait/frame_sink.h"
|
||||||
|
#include "trait/mouse_processor.h"
|
||||||
#include "video_buffer.h"
|
#include "video_buffer.h"
|
||||||
|
|
||||||
struct screen {
|
struct screen {
|
||||||
|
@ -20,6 +24,7 @@ struct screen {
|
||||||
bool open; // track the open/close state to assert correct behavior
|
bool open; // track the open/close state to assert correct behavior
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct input_manager im;
|
||||||
struct sc_video_buffer vb;
|
struct sc_video_buffer vb;
|
||||||
struct fps_counter fps_counter;
|
struct fps_counter fps_counter;
|
||||||
|
|
||||||
|
@ -50,6 +55,16 @@ struct screen {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct screen_params {
|
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;
|
const char *window_title;
|
||||||
struct sc_size frame_size;
|
struct sc_size frame_size;
|
||||||
bool always_on_top;
|
bool always_on_top;
|
||||||
|
|
Loading…
Reference in a new issue