From faf02f0a1c1aad8482b3c049ccb956eca6e84840 Mon Sep 17 00:00:00 2001 From: Sophie Winter Date: Sat, 21 Jun 2025 13:08:12 -0400 Subject: [PATCH 1/2] Fix the EventReceiver API (on Linux) Split EVENT_DEVICE_ADDED into EVENT_ZCM1_ADDED and EVENT_ZCM2_ADDED so the proper product ID can be used, this removes two FIXMEs and makes it work on Linux (NOT tested on OSX/windows, no code changes were needed on windows, and the OSX code changes were relatively simple) --- src/daemon/moved.cpp | 7 ++----- src/daemon/moved_monitor.h | 3 ++- src/daemon/moved_monitor_linux.c | 2 +- src/daemon/moved_monitor_osx.mm | 2 +- src/psmoveapi.cpp | 11 +++++------ src/utils/psmovepair.c | 2 +- 6 files changed, 12 insertions(+), 15 deletions(-) diff --git a/src/daemon/moved.cpp b/src/daemon/moved.cpp index 746f30f6..fc35b9b4 100644 --- a/src/daemon/moved.cpp +++ b/src/daemon/moved.cpp @@ -98,12 +98,9 @@ on_monitor_update_moved(enum MonitorEvent event, { move_daemon *moved = static_cast(user_data); - if (event == EVENT_DEVICE_ADDED) { + if (event == EVENT_ZCM1_ADDED || event == EVENT_ZCM2_ADDED) { if (device_type == EVENT_DEVICE_TYPE_USB) { - // TODO: FIXME: This should use the device's actual USB product ID. - // HACK: We rely on this invalid PID being translated to a - // valid controller model (the old ZCM1, by default). - unsigned short pid = 0; + unsigned short pid = event == EVENT_ZCM1_ADDED ? PSMOVE_PID : PSMOVE_PS4_PID; PSMove *move = psmove_connect_internal(serial, path, -1, pid); if (psmove_pair(move)) { // Indicate to the user that pairing was successful diff --git a/src/daemon/moved_monitor.h b/src/daemon/moved_monitor.h index d06e11d9..76d9934f 100644 --- a/src/daemon/moved_monitor.h +++ b/src/daemon/moved_monitor.h @@ -37,7 +37,8 @@ extern "C" { #include enum MonitorEvent { - EVENT_DEVICE_ADDED, + EVENT_ZCM1_ADDED, + EVENT_ZCM2_ADDED, EVENT_DEVICE_REMOVED, }; diff --git a/src/daemon/moved_monitor_linux.c b/src/daemon/moved_monitor_linux.c index 8f6e699f..a2e38fc8 100644 --- a/src/daemon/moved_monitor_linux.c +++ b/src/daemon/moved_monitor_linux.c @@ -158,7 +158,7 @@ _moved_monitor_handle_device(moved_monitor *monitor, struct udev_device *dev) device_type = EVENT_DEVICE_TYPE_USB; } - monitor->event_callback(EVENT_DEVICE_ADDED, device_type, path, + monitor->event_callback(product_id == PSMOVE_PID ? EVENT_ZCM1_ADDED : EVENT_ZCM2_ADDED, device_type, path, serial_number, monitor->event_callback_user_data); } diff --git a/src/daemon/moved_monitor_osx.mm b/src/daemon/moved_monitor_osx.mm index 76379e00..88571edb 100644 --- a/src/daemon/moved_monitor_osx.mm +++ b/src/daemon/moved_monitor_osx.mm @@ -119,7 +119,7 @@ void pump_loop() static void on_device_matching(void *context, IOReturn result, void *sender, IOHIDDeviceRef device) { _moved_monitor *monitor = (_moved_monitor *)(context); - monitor->make_event(EVENT_DEVICE_ADDED, device); + monitor->make_event(get_product_id(device) == PSMOVE_PID ? EVENT_ZCM1_ADDED : EVENT_ZCM2_ADDED, device); } static void on_device_removal(void *context, IOReturn result, void *sender, IOHIDDeviceRef device) diff --git a/src/psmoveapi.cpp b/src/psmoveapi.cpp index 62032014..43da1bd0 100644 --- a/src/psmoveapi.cpp +++ b/src/psmoveapi.cpp @@ -295,9 +295,11 @@ PSMoveAPI::on_monitor_event(enum MonitorEvent event, enum MonitorEventDeviceType auto self = static_cast(user_data); switch (event) { - case EVENT_DEVICE_ADDED: + case EVENT_ZCM1_ADDED: + case EVENT_ZCM2_ADDED: { - PSMOVE_DEBUG("on_monitor_event(event=EVENT_DEVICE_ADDED, device_type=0x%08x, path=\"%s\", serial=%p)", + PSMOVE_DEBUG("on_monitor_event(event=%s, device_type=0x%08x, path=\"%s\", serial=%p)", + event == EVENT_ZCM1_ADDED ? "EVENT_ZCM1_ADDED" : "EVENT_ZCM2_ADDED", device_type, path, serial); for (auto &c: self->controllers) { @@ -308,10 +310,7 @@ PSMoveAPI::on_monitor_event(enum MonitorEvent event, enum MonitorEventDeviceType } } - // TODO: FIXME: This should use the device's actual USB product ID. - // HACK: We rely on this invalid PID being translated to a - // valid controller model (the old ZCM1, by default). - unsigned short pid = 0; + unsigned short pid = event == EVENT_ZCM1_ADDED ? PSMOVE_PID : PSMOVE_PS4_PID; PSMove *move = psmove_connect_internal(serial, path, -1, pid); if (move == nullptr) { PSMOVE_ERROR("Cannot open move for retrieving serial!"); diff --git a/src/utils/psmovepair.c b/src/utils/psmovepair.c index b4fe6726..06cb6f4f 100644 --- a/src/utils/psmovepair.c +++ b/src/utils/psmovepair.c @@ -97,7 +97,7 @@ on_monitor_update_pair(enum MonitorEvent event, const char *path, const wchar_t *serial, void *user_data) { - if (event == EVENT_DEVICE_ADDED) { + if (event == EVENT_ZCM1_ADDED || event == EVENT_ZCM2_ADDED) { if (device_type == EVENT_DEVICE_TYPE_USB) { pair(NULL); } From 8c418e439cf78c8ac58e58c1e33e675eb524782e Mon Sep 17 00:00:00 2001 From: Sophie Winter Date: Mon, 14 Jul 2025 08:59:10 -0700 Subject: [PATCH 2/2] Add pid parameter instead of EVENT_ZCM1_ADDED/EVENT_ZCM2_ADDED --- src/daemon/moved.cpp | 5 ++--- src/daemon/moved_monitor.h | 6 +++--- src/daemon/moved_monitor_linux.c | 6 +++--- src/daemon/moved_monitor_osx.mm | 9 ++++++--- src/psmoveapi.cpp | 11 ++++------- src/utils/psmovepair.c | 4 ++-- 6 files changed, 20 insertions(+), 21 deletions(-) diff --git a/src/daemon/moved.cpp b/src/daemon/moved.cpp index fc35b9b4..6912cb9f 100644 --- a/src/daemon/moved.cpp +++ b/src/daemon/moved.cpp @@ -94,13 +94,12 @@ static void on_monitor_update_moved(enum MonitorEvent event, enum MonitorEventDeviceType device_type, const char *path, const wchar_t *serial, - void *user_data) + unsigned short pid, void *user_data) { move_daemon *moved = static_cast(user_data); - if (event == EVENT_ZCM1_ADDED || event == EVENT_ZCM2_ADDED) { + if (event == EVENT_DEVICE_ADDED) { if (device_type == EVENT_DEVICE_TYPE_USB) { - unsigned short pid = event == EVENT_ZCM1_ADDED ? PSMOVE_PID : PSMOVE_PS4_PID; PSMove *move = psmove_connect_internal(serial, path, -1, pid); if (psmove_pair(move)) { // Indicate to the user that pairing was successful diff --git a/src/daemon/moved_monitor.h b/src/daemon/moved_monitor.h index 76d9934f..0f27485f 100644 --- a/src/daemon/moved_monitor.h +++ b/src/daemon/moved_monitor.h @@ -37,8 +37,7 @@ extern "C" { #include enum MonitorEvent { - EVENT_ZCM1_ADDED, - EVENT_ZCM2_ADDED, + EVENT_DEVICE_ADDED, EVENT_DEVICE_REMOVED, }; @@ -48,9 +47,10 @@ enum MonitorEventDeviceType { EVENT_DEVICE_TYPE_UNKNOWN, }; +// pid is the product ID on connect, it may be 0 on disconnect typedef void (*moved_event_callback)(enum MonitorEvent event, enum MonitorEventDeviceType device_type, const char *path, - const wchar_t *serial, void *user_data); + const wchar_t *serial, unsigned short pid, void *user_data); typedef struct _moved_monitor moved_monitor; diff --git a/src/daemon/moved_monitor_linux.c b/src/daemon/moved_monitor_linux.c index a2e38fc8..ed5bfa02 100644 --- a/src/daemon/moved_monitor_linux.c +++ b/src/daemon/moved_monitor_linux.c @@ -158,8 +158,8 @@ _moved_monitor_handle_device(moved_monitor *monitor, struct udev_device *dev) device_type = EVENT_DEVICE_TYPE_USB; } - monitor->event_callback(product_id == PSMOVE_PID ? EVENT_ZCM1_ADDED : EVENT_ZCM2_ADDED, device_type, path, - serial_number, monitor->event_callback_user_data); + monitor->event_callback(EVENT_DEVICE_ADDED, device_type, path, + serial_number, product_id, monitor->event_callback_user_data); } free(serial_number); @@ -170,7 +170,7 @@ _moved_monitor_handle_device(moved_monitor *monitor, struct udev_device *dev) free(uevent); } else if (strcmp(action, "remove") == 0) { monitor->event_callback(EVENT_DEVICE_REMOVED, device_type, path, - NULL, monitor->event_callback_user_data); + NULL, 0, monitor->event_callback_user_data); } } diff --git a/src/daemon/moved_monitor_osx.mm b/src/daemon/moved_monitor_osx.mm index 88571edb..3bd13fd4 100644 --- a/src/daemon/moved_monitor_osx.mm +++ b/src/daemon/moved_monitor_osx.mm @@ -49,6 +49,7 @@ enum MonitorEventDeviceType device_type; char path[256]; wchar_t serial_number[256]; + unsigned short pid; }; struct _moved_monitor { @@ -85,7 +86,7 @@ void pump_loop() auto event = events.front(); event_callback(event.event, event.device_type, event.path, event.serial_number, - event_callback_user_data); + event.pid, event_callback_user_data); events.pop(); } } @@ -94,10 +95,12 @@ void pump_loop() void make_event(enum MonitorEvent event, IOHIDDeviceRef device) { - if (get_vendor_id(device) == PSMOVE_VID && (get_product_id(device) == PSMOVE_PID || get_product_id(device) == PSMOVE_PS4_PID)) { + unsigned short pid = get_product_id(device); + if (get_vendor_id(device) == PSMOVE_VID && (pid == PSMOVE_PID || pid == PSMOVE_PS4_PID)) { ASyncDeviceEvent ade; ade.event = event; ade.device_type = EVENT_DEVICE_TYPE_UNKNOWN; + ade.pid = pid; // Example paths: // e.g. "USB_054c_03d5_14100000" @@ -119,7 +122,7 @@ void pump_loop() static void on_device_matching(void *context, IOReturn result, void *sender, IOHIDDeviceRef device) { _moved_monitor *monitor = (_moved_monitor *)(context); - monitor->make_event(get_product_id(device) == PSMOVE_PID ? EVENT_ZCM1_ADDED : EVENT_ZCM2_ADDED, device); + monitor->make_event(EVENT_DEVICE_ADDED, device); } static void on_device_removal(void *context, IOReturn result, void *sender, IOHIDDeviceRef device) diff --git a/src/psmoveapi.cpp b/src/psmoveapi.cpp index 43da1bd0..7cbfd6d2 100644 --- a/src/psmoveapi.cpp +++ b/src/psmoveapi.cpp @@ -70,7 +70,7 @@ struct PSMoveAPI { void update(); - static void on_monitor_event(enum MonitorEvent event, enum MonitorEventDeviceType device_type, const char *path, const wchar_t *serial, void *user_data); + static void on_monitor_event(enum MonitorEvent event, enum MonitorEventDeviceType device_type, const char *path, const wchar_t *serial, unsigned short pid, void *user_data); EventReceiver *receiver; void *user_data; @@ -290,16 +290,14 @@ PSMoveAPI::update() } void -PSMoveAPI::on_monitor_event(enum MonitorEvent event, enum MonitorEventDeviceType device_type, const char *path, const wchar_t *serial, void *user_data) +PSMoveAPI::on_monitor_event(enum MonitorEvent event, enum MonitorEventDeviceType device_type, const char *path, const wchar_t *serial, unsigned short pid, void *user_data) { auto self = static_cast(user_data); switch (event) { - case EVENT_ZCM1_ADDED: - case EVENT_ZCM2_ADDED: + case EVENT_DEVICE_ADDED: { - PSMOVE_DEBUG("on_monitor_event(event=%s, device_type=0x%08x, path=\"%s\", serial=%p)", - event == EVENT_ZCM1_ADDED ? "EVENT_ZCM1_ADDED" : "EVENT_ZCM2_ADDED", + PSMOVE_DEBUG("on_monitor_event(event=EVENT_DEVICE_ADDED, device_type=0x%08x, path=\"%s\", serial=%p)", device_type, path, serial); for (auto &c: self->controllers) { @@ -310,7 +308,6 @@ PSMoveAPI::on_monitor_event(enum MonitorEvent event, enum MonitorEventDeviceType } } - unsigned short pid = event == EVENT_ZCM1_ADDED ? PSMOVE_PID : PSMOVE_PS4_PID; PSMove *move = psmove_connect_internal(serial, path, -1, pid); if (move == nullptr) { PSMOVE_ERROR("Cannot open move for retrieving serial!"); diff --git a/src/utils/psmovepair.c b/src/utils/psmovepair.c index 06cb6f4f..5be709d3 100644 --- a/src/utils/psmovepair.c +++ b/src/utils/psmovepair.c @@ -95,9 +95,9 @@ static void on_monitor_update_pair(enum MonitorEvent event, enum MonitorEventDeviceType device_type, const char *path, const wchar_t *serial, - void *user_data) + unsigned short pid, void *user_data) { - if (event == EVENT_ZCM1_ADDED || event == EVENT_ZCM2_ADDED) { + if (event == EVENT_DEVICE_ADDED) { if (device_type == EVENT_DEVICE_TYPE_USB) { pair(NULL); }