From b8c81bb5fdec77cfb1a0cc04fd9e1afa9e5b3f84 Mon Sep 17 00:00:00 2001 From: Simon Chan <1330321+yume-chan@users.noreply.github.com> Date: Tue, 7 Feb 2023 14:54:27 +0800 Subject: [PATCH] Add --no-game-controller option --- app/src/cli.c | 9 +++ app/src/input_manager.c | 168 ++++++++++++++++++++++++---------------- app/src/input_manager.h | 1 + app/src/options.c | 1 + app/src/options.h | 1 + 5 files changed, 113 insertions(+), 67 deletions(-) diff --git a/app/src/cli.c b/app/src/cli.c index 27b0ddef..a4eaf89b 100644 --- a/app/src/cli.c +++ b/app/src/cli.c @@ -58,6 +58,7 @@ #define OPT_PRINT_FPS 1038 #define OPT_NO_POWER_ON 1039 #define OPT_CODEC 1040 +#define OPT_NO_GAME_CONTROLLER 1041 struct sc_option { char shortopt; @@ -298,6 +299,11 @@ static const struct sc_option options[] = { .text = "Do not display device (only when screen recording or V4L2 " "sink is enabled).", }, + { + .longopt_id = OPT_NO_GAME_CONTROLLER, + .longopt = "no-game-controller", + .text = "Disable game controller support.", + }, { .longopt_id = OPT_NO_KEY_REPEAT, .longopt = "no-key-repeat", @@ -1582,6 +1588,9 @@ parse_args_with_getopt(struct scrcpy_cli_args *args, int argc, char *argv[], case OPT_NO_MIPMAPS: opts->mipmaps = false; break; + case OPT_NO_GAME_CONTROLLER: + opts->forward_game_controllers = false; + break; case OPT_NO_KEY_REPEAT: opts->forward_key_repeat = false; break; diff --git a/app/src/input_manager.c b/app/src/input_manager.c index e99c4de0..5cdce72e 100644 --- a/app/src/input_manager.c +++ b/app/src/input_manager.c @@ -62,6 +62,7 @@ sc_input_manager_init(struct sc_input_manager *im, im->kp = params->kp; im->mp = params->mp; + im->forward_game_controllers = options->forward_game_controllers; im->forward_all_clicks = params->forward_all_clicks; im->legacy_paste = params->legacy_paste; im->clipboard_autosync = params->clipboard_autosync; @@ -798,75 +799,36 @@ sc_input_manager_process_file(struct sc_input_manager *im, } void -sc_input_manager_handle_event(struct sc_input_manager *im, SDL_Event *event) { - bool control = im->controller; - switch (event->type) { - case SDL_TEXTINPUT: - if (!control) { - break; - } - sc_input_manager_process_text_input(im, &event->text); - break; - case SDL_KEYDOWN: - case SDL_KEYUP: - // some key events do not interact with the device, so process the - // event even if control is disabled - sc_input_manager_process_key(im, &event->key); - break; - case SDL_MOUSEMOTION: - if (!control) { - break; - } - sc_input_manager_process_mouse_motion(im, &event->motion); - break; - case SDL_MOUSEWHEEL: - if (!control) { - break; - } - sc_input_manager_process_mouse_wheel(im, &event->wheel); - break; - case SDL_MOUSEBUTTONDOWN: - case SDL_MOUSEBUTTONUP: - // some mouse events do not interact with the device, so process - // the event even if control is disabled - sc_input_manager_process_mouse_button(im, &event->button); - break; - case SDL_FINGERMOTION: - case SDL_FINGERDOWN: - case SDL_FINGERUP: - if (!control) { - break; - } - sc_input_manager_process_touch(im, &event->tfinger); - break; - case SDL_DROPFILE: { - if (!control) { - break; - } - sc_input_manager_process_file(im, &event->drop); +input_manager_process_controller_axis(struct input_manager *im, + const SDL_ControllerAxisEvent *event) { + struct control_msg msg; + msg.type = CONTROL_MSG_TYPE_INJECT_GAME_CONTROLLER_AXIS; + msg.inject_game_controller_axis.id = event->which; + msg.inject_game_controller_axis.axis = event->axis; + msg.inject_game_controller_axis.value = event->value; + controller_push_msg(im->controller, &msg); +} + +void +input_manager_process_controller_button(struct input_manager *im, + const SDL_ControllerButtonEvent *event) { + struct control_msg msg; + msg.type = CONTROL_MSG_TYPE_INJECT_GAME_CONTROLLER_BUTTON; + msg.inject_game_controller_button.id = event->which; + msg.inject_game_controller_button.button = event->button; + msg.inject_game_controller_button.state = event->state; + controller_push_msg(im->controller, &msg); +} + +static SDL_GameController ** +find_free_game_controller_slot(struct input_manager *im) { + for (unsigned i = 0; i < MAX_GAME_CONTROLLERS; ++i) { + if (!im->game_controllers[i]) { + return &im->game_controllers[i]; } - case SDL_CONTROLLERAXISMOTION: - if (!control) { - break; - } - input_manager_process_controller_axis(&input_manager, &event->caxis); - break; - case SDL_CONTROLLERBUTTONDOWN: - case SDL_CONTROLLERBUTTONUP: - if (!control) { - break; - } - input_manager_process_controller_button(&input_manager, &event->cbutton); - break; - case SDL_CONTROLLERDEVICEADDED: - // case SDL_CONTROLLERDEVICEREMAPPED: - case SDL_CONTROLLERDEVICEREMOVED: - if (!control) { - break; - } - input_manager_process_controller_device(&input_manager, &event->cdevice); - break; } + + return NULL; } void @@ -927,3 +889,75 @@ input_manager_process_controller_device(struct input_manager *im, msg.inject_game_controller_device.event -= SDL_CONTROLLERDEVICEADDED; controller_push_msg(im->controller, &msg); } + +void +sc_input_manager_handle_event(struct sc_input_manager *im, SDL_Event *event) { + bool control = im->controller; + switch (event->type) { + case SDL_TEXTINPUT: + if (!control) { + break; + } + sc_input_manager_process_text_input(im, &event->text); + break; + case SDL_KEYDOWN: + case SDL_KEYUP: + // some key events do not interact with the device, so process the + // event even if control is disabled + sc_input_manager_process_key(im, &event->key); + break; + case SDL_MOUSEMOTION: + if (!control) { + break; + } + sc_input_manager_process_mouse_motion(im, &event->motion); + break; + case SDL_MOUSEWHEEL: + if (!control) { + break; + } + sc_input_manager_process_mouse_wheel(im, &event->wheel); + break; + case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONUP: + // some mouse events do not interact with the device, so process + // the event even if control is disabled + sc_input_manager_process_mouse_button(im, &event->button); + break; + case SDL_FINGERMOTION: + case SDL_FINGERDOWN: + case SDL_FINGERUP: + if (!control) { + break; + } + sc_input_manager_process_touch(im, &event->tfinger); + break; + case SDL_DROPFILE: { + if (!control) { + break; + } + sc_input_manager_process_file(im, &event->drop); + } + case SDL_CONTROLLERAXISMOTION: + if (!control || !im->forward_game_controllers) { + break; + } + input_manager_process_controller_axis(im, &event->caxis); + break; + case SDL_CONTROLLERBUTTONDOWN: + case SDL_CONTROLLERBUTTONUP: + if (!control || !im->forward_game_controllers) { + break; + } + input_manager_process_controller_button(im, &event->cbutton); + break; + case SDL_CONTROLLERDEVICEADDED: + // case SDL_CONTROLLERDEVICEREMAPPED: + case SDL_CONTROLLERDEVICEREMOVED: + if (!control || !im->forward_game_controllers) { + break; + } + input_manager_process_controller_device(im, &event->cdevice); + break; + } +} diff --git a/app/src/input_manager.h b/app/src/input_manager.h index 9233292b..9e836f03 100644 --- a/app/src/input_manager.h +++ b/app/src/input_manager.h @@ -25,6 +25,7 @@ struct sc_input_manager { struct sc_key_processor *kp; struct sc_mouse_processor *mp; + bool forward_game_controllers; bool forward_all_clicks; bool legacy_paste; bool clipboard_autosync; diff --git a/app/src/options.c b/app/src/options.c index 525795ae..37a4109d 100644 --- a/app/src/options.c +++ b/app/src/options.c @@ -53,6 +53,7 @@ const struct scrcpy_options scrcpy_options_default = { .stay_awake = false, .force_adb_forward = false, .disable_screensaver = false, + .forward_game_controllers = true, .forward_key_repeat = true, .forward_all_clicks = false, .legacy_paste = false, diff --git a/app/src/options.h b/app/src/options.h index b9d237e0..b9e51eaa 100644 --- a/app/src/options.h +++ b/app/src/options.h @@ -134,6 +134,7 @@ struct scrcpy_options { bool stay_awake; bool force_adb_forward; bool disable_screensaver; + bool forward_game_controllers; bool forward_key_repeat; bool forward_all_clicks; bool legacy_paste;