Split gamepad device added/removed events

Use two separate callbacks for gamepad device added and gamepad device
removed.

It looks cleaner.

PR #5623 <https://github.com/Genymobile/scrcpy/pull/5623>
This commit is contained in:
Romain Vimont 2024-12-07 14:12:53 +01:00
parent c59a3c3169
commit 4bd1c5981d
6 changed files with 80 additions and 82 deletions

View File

@ -412,18 +412,12 @@ struct sc_touch_event {
float pressure; float pressure;
}; };
enum sc_gamepad_device_event_type {
SC_GAMEPAD_DEVICE_ADDED,
SC_GAMEPAD_DEVICE_REMOVED,
};
// As documented in <https://wiki.libsdl.org/SDL2/SDL_JoystickID>: // As documented in <https://wiki.libsdl.org/SDL2/SDL_JoystickID>:
// The ID value starts at 0 and increments from there. The value -1 is an // The ID value starts at 0 and increments from there. The value -1 is an
// invalid ID. // invalid ID.
#define SC_GAMEPAD_ID_INVALID UINT32_C(-1) #define SC_GAMEPAD_ID_INVALID UINT32_C(-1)
struct sc_gamepad_device_event { struct sc_gamepad_device_event {
enum sc_gamepad_device_event_type type;
uint32_t gamepad_id; uint32_t gamepad_id;
}; };
@ -503,16 +497,6 @@ sc_mouse_buttons_state_from_sdl(uint32_t buttons_state) {
return buttons_state; return buttons_state;
} }
static inline enum sc_gamepad_device_event_type
sc_gamepad_device_event_type_from_sdl_type(uint32_t type) {
assert(type == SDL_CONTROLLERDEVICEADDED
|| type == SDL_CONTROLLERDEVICEREMOVED);
if (type == SDL_CONTROLLERDEVICEADDED) {
return SC_GAMEPAD_DEVICE_ADDED;
}
return SC_GAMEPAD_DEVICE_REMOVED;
}
static inline enum sc_gamepad_axis static inline enum sc_gamepad_axis
sc_gamepad_axis_from_sdl(uint8_t axis) { sc_gamepad_axis_from_sdl(uint8_t axis) {
if (axis <= SDL_CONTROLLER_AXIS_TRIGGERRIGHT) { if (axis <= SDL_CONTROLLER_AXIS_TRIGGERRIGHT) {

View File

@ -908,7 +908,6 @@ sc_input_manager_process_mouse_wheel(struct sc_input_manager *im,
static void static void
sc_input_manager_process_gamepad_device(struct sc_input_manager *im, sc_input_manager_process_gamepad_device(struct sc_input_manager *im,
const SDL_ControllerDeviceEvent *event) { const SDL_ControllerDeviceEvent *event) {
SDL_JoystickID id;
if (event->type == SDL_CONTROLLERDEVICEADDED) { if (event->type == SDL_CONTROLLERDEVICEADDED) {
SDL_GameController *gc = SDL_GameControllerOpen(event->which); SDL_GameController *gc = SDL_GameControllerOpen(event->which);
if (!gc) { if (!gc) {
@ -923,9 +922,12 @@ sc_input_manager_process_gamepad_device(struct sc_input_manager *im,
return; return;
} }
id = SDL_JoystickInstanceID(joystick); struct sc_gamepad_device_event evt = {
.gamepad_id = SDL_JoystickInstanceID(joystick),
};
im->gp->ops->process_gamepad_added(im->gp, &evt);
} else if (event->type == SDL_CONTROLLERDEVICEREMOVED) { } else if (event->type == SDL_CONTROLLERDEVICEREMOVED) {
id = event->which; SDL_JoystickID id = event->which;
SDL_GameController *gc = SDL_GameControllerFromInstanceID(id); SDL_GameController *gc = SDL_GameControllerFromInstanceID(id);
if (gc) { if (gc) {
@ -933,16 +935,15 @@ sc_input_manager_process_gamepad_device(struct sc_input_manager *im,
} else { } else {
LOGW("Unknown gamepad device removed"); LOGW("Unknown gamepad device removed");
} }
struct sc_gamepad_device_event evt = {
.gamepad_id = id,
};
im->gp->ops->process_gamepad_removed(im->gp, &evt);
} else { } else {
// Nothing to do // Nothing to do
return; return;
} }
struct sc_gamepad_device_event evt = {
.type = sc_gamepad_device_event_type_from_sdl_type(event->type),
.gamepad_id = id,
};
im->gp->ops->process_gamepad_device(im->gp, &evt);
} }
static void static void

View File

@ -20,12 +20,21 @@ struct sc_gamepad_processor {
struct sc_gamepad_processor_ops { struct sc_gamepad_processor_ops {
/** /**
* Process a gamepad device added or removed * Process a gamepad device added event
* *
* This function is mandatory. * This function is mandatory.
*/ */
void void
(*process_gamepad_device)(struct sc_gamepad_processor *gp, (*process_gamepad_added)(struct sc_gamepad_processor *gp,
const struct sc_gamepad_device_event *event);
/**
* Process a gamepad device removed event
*
* This function is mandatory.
*/
void
(*process_gamepad_removed)(struct sc_gamepad_processor *gp,
const struct sc_gamepad_device_event *event); const struct sc_gamepad_device_event *event);
/** /**

View File

@ -52,11 +52,10 @@ sc_gamepad_uhid_send_close(struct sc_gamepad_uhid *gamepad,
} }
static void static void
sc_gamepad_processor_process_gamepad_device(struct sc_gamepad_processor *gp, sc_gamepad_processor_process_gamepad_added(struct sc_gamepad_processor *gp,
const struct sc_gamepad_device_event *event) { const struct sc_gamepad_device_event *event) {
struct sc_gamepad_uhid *gamepad = DOWNCAST(gp); struct sc_gamepad_uhid *gamepad = DOWNCAST(gp);
if (event->type == SC_GAMEPAD_DEVICE_ADDED) {
struct sc_hid_open hid_open; struct sc_hid_open hid_open;
if (!sc_hid_gamepad_generate_open(&gamepad->hid, &hid_open, if (!sc_hid_gamepad_generate_open(&gamepad->hid, &hid_open,
event->gamepad_id)) { event->gamepad_id)) {
@ -64,8 +63,12 @@ sc_gamepad_processor_process_gamepad_device(struct sc_gamepad_processor *gp,
} }
sc_gamepad_uhid_send_open(gamepad, &hid_open); sc_gamepad_uhid_send_open(gamepad, &hid_open);
} else { }
assert(event->type == SC_GAMEPAD_DEVICE_REMOVED);
static void
sc_gamepad_processor_process_gamepad_removed(struct sc_gamepad_processor *gp,
const struct sc_gamepad_device_event *event) {
struct sc_gamepad_uhid *gamepad = DOWNCAST(gp);
struct sc_hid_close hid_close; struct sc_hid_close hid_close;
if (!sc_hid_gamepad_generate_close(&gamepad->hid, &hid_close, if (!sc_hid_gamepad_generate_close(&gamepad->hid, &hid_close,
@ -75,7 +78,6 @@ sc_gamepad_processor_process_gamepad_device(struct sc_gamepad_processor *gp,
sc_gamepad_uhid_send_close(gamepad, &hid_close); sc_gamepad_uhid_send_close(gamepad, &hid_close);
} }
}
static void static void
sc_gamepad_processor_process_gamepad_axis(struct sc_gamepad_processor *gp, sc_gamepad_processor_process_gamepad_axis(struct sc_gamepad_processor *gp,
@ -114,7 +116,8 @@ sc_gamepad_uhid_init(struct sc_gamepad_uhid *gamepad,
gamepad->controller = controller; gamepad->controller = controller;
static const struct sc_gamepad_processor_ops ops = { static const struct sc_gamepad_processor_ops ops = {
.process_gamepad_device = sc_gamepad_processor_process_gamepad_device, .process_gamepad_added = sc_gamepad_processor_process_gamepad_added,
.process_gamepad_removed = sc_gamepad_processor_process_gamepad_removed,
.process_gamepad_axis = sc_gamepad_processor_process_gamepad_axis, .process_gamepad_axis = sc_gamepad_processor_process_gamepad_axis,
.process_gamepad_button = sc_gamepad_processor_process_gamepad_button, .process_gamepad_button = sc_gamepad_processor_process_gamepad_button,
}; };

View File

@ -7,11 +7,10 @@
#define DOWNCAST(GP) container_of(GP, struct sc_gamepad_aoa, gamepad_processor) #define DOWNCAST(GP) container_of(GP, struct sc_gamepad_aoa, gamepad_processor)
static void static void
sc_gamepad_processor_process_gamepad_device(struct sc_gamepad_processor *gp, sc_gamepad_processor_process_gamepad_added(struct sc_gamepad_processor *gp,
const struct sc_gamepad_device_event *event) { const struct sc_gamepad_device_event *event) {
struct sc_gamepad_aoa *gamepad = DOWNCAST(gp); struct sc_gamepad_aoa *gamepad = DOWNCAST(gp);
if (event->type == SC_GAMEPAD_DEVICE_ADDED) {
struct sc_hid_open hid_open; struct sc_hid_open hid_open;
if (!sc_hid_gamepad_generate_open(&gamepad->hid, &hid_open, if (!sc_hid_gamepad_generate_open(&gamepad->hid, &hid_open,
event->gamepad_id)) { event->gamepad_id)) {
@ -22,8 +21,12 @@ sc_gamepad_processor_process_gamepad_device(struct sc_gamepad_processor *gp,
if (!sc_aoa_push_open(gamepad->aoa, &hid_open, false)) { if (!sc_aoa_push_open(gamepad->aoa, &hid_open, false)) {
LOGW("Could not push AOA HID open (gamepad)"); LOGW("Could not push AOA HID open (gamepad)");
} }
} else { }
assert(event->type == SC_GAMEPAD_DEVICE_REMOVED);
static void
sc_gamepad_processor_process_gamepad_removed(struct sc_gamepad_processor *gp,
const struct sc_gamepad_device_event *event) {
struct sc_gamepad_aoa *gamepad = DOWNCAST(gp);
struct sc_hid_close hid_close; struct sc_hid_close hid_close;
if (!sc_hid_gamepad_generate_close(&gamepad->hid, &hid_close, if (!sc_hid_gamepad_generate_close(&gamepad->hid, &hid_close,
@ -35,7 +38,6 @@ sc_gamepad_processor_process_gamepad_device(struct sc_gamepad_processor *gp,
LOGW("Could not push AOA HID close (gamepad)"); LOGW("Could not push AOA HID close (gamepad)");
} }
} }
}
static void static void
sc_gamepad_processor_process_gamepad_axis(struct sc_gamepad_processor *gp, sc_gamepad_processor_process_gamepad_axis(struct sc_gamepad_processor *gp,
@ -76,7 +78,8 @@ sc_gamepad_aoa_init(struct sc_gamepad_aoa *gamepad, struct sc_aoa *aoa) {
sc_hid_gamepad_init(&gamepad->hid); sc_hid_gamepad_init(&gamepad->hid);
static const struct sc_gamepad_processor_ops ops = { static const struct sc_gamepad_processor_ops ops = {
.process_gamepad_device = sc_gamepad_processor_process_gamepad_device, .process_gamepad_added = sc_gamepad_processor_process_gamepad_added,
.process_gamepad_removed = sc_gamepad_processor_process_gamepad_removed,
.process_gamepad_axis = sc_gamepad_processor_process_gamepad_axis, .process_gamepad_axis = sc_gamepad_processor_process_gamepad_axis,
.process_gamepad_button = sc_gamepad_processor_process_gamepad_button, .process_gamepad_button = sc_gamepad_processor_process_gamepad_button,
}; };

View File

@ -175,7 +175,6 @@ sc_screen_otg_process_gamepad_device(struct sc_screen_otg *screen,
assert(screen->gamepad); assert(screen->gamepad);
struct sc_gamepad_processor *gp = &screen->gamepad->gamepad_processor; struct sc_gamepad_processor *gp = &screen->gamepad->gamepad_processor;
SDL_JoystickID id;
if (event->type == SDL_CONTROLLERDEVICEADDED) { if (event->type == SDL_CONTROLLERDEVICEADDED) {
SDL_GameController *gc = SDL_GameControllerOpen(event->which); SDL_GameController *gc = SDL_GameControllerOpen(event->which);
if (!gc) { if (!gc) {
@ -190,9 +189,12 @@ sc_screen_otg_process_gamepad_device(struct sc_screen_otg *screen,
return; return;
} }
id = SDL_JoystickInstanceID(joystick); struct sc_gamepad_device_event evt = {
.gamepad_id = SDL_JoystickInstanceID(joystick),
};
gp->ops->process_gamepad_added(gp, &evt);
} else if (event->type == SDL_CONTROLLERDEVICEREMOVED) { } else if (event->type == SDL_CONTROLLERDEVICEREMOVED) {
id = event->which; SDL_JoystickID id = event->which;
SDL_GameController *gc = SDL_GameControllerFromInstanceID(id); SDL_GameController *gc = SDL_GameControllerFromInstanceID(id);
if (gc) { if (gc) {
@ -200,16 +202,12 @@ sc_screen_otg_process_gamepad_device(struct sc_screen_otg *screen,
} else { } else {
LOGW("Unknown gamepad device removed"); LOGW("Unknown gamepad device removed");
} }
} else {
// Nothing to do
return;
}
struct sc_gamepad_device_event evt = { struct sc_gamepad_device_event evt = {
.type = sc_gamepad_device_event_type_from_sdl_type(event->type),
.gamepad_id = id, .gamepad_id = id,
}; };
gp->ops->process_gamepad_device(gp, &evt); gp->ops->process_gamepad_removed(gp, &evt);
}
} }
static void static void