From 97a2cea918dbbdc76834e84cb234f3344e8ed2f0 Mon Sep 17 00:00:00 2001 From: Hrvoje Cavrak Date: Sat, 24 Aug 2024 00:12:49 +0200 Subject: [PATCH] DeskHop v0.64 (Bugfixes) - Caps lock / Num lock didn't correctly remember output B state - Windows relative mouse was jumping from secondary to primary - Fixed NKRO keyboards without report ID - IMPORTANT: moved config shortcut to LEFT CTRL + RIGHT SHIFT + C + O because users had issues with keyboards unable to send both shifts. Sorry for changing this. --- CMakeLists.txt | 2 +- src/handlers.c | 8 ++++-- src/hid_report.c | 5 +--- src/include/main.h | 5 +++- src/include/usb_descriptors.h | 53 +++++++++++++++++++++++++++++++++-- src/keyboard.c | 4 +-- src/mouse.c | 6 +--- src/usb.c | 19 +++++++------ 8 files changed, 77 insertions(+), 25 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 56f74f1..97f1ef3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.6) set(VERSION_MAJOR 00) -set(VERSION_MINOR 156) +set(VERSION_MINOR 157) set(PICO_SDK_FETCH_FROM_GIT off) set(PICO_BOARD=pico) diff --git a/src/handlers.c b/src/handlers.c index c15924d..fef3723 100644 --- a/src/handlers.c +++ b/src/handlers.c @@ -172,8 +172,12 @@ void handle_mouse_zoom_msg(uart_packet_t *packet, device_t *state) { /* Process request to update keyboard LEDs */ void handle_set_report_msg(uart_packet_t *packet, device_t *state) { - state->keyboard_leds[BOARD_ROLE] = packet->data[0]; - restore_leds(state); + /* We got this via serial, so it's stored to the opposite of our board role */ + state->keyboard_leds[OTHER_ROLE] = packet->data[0]; + + /* If we have a keyboard we can control leds on, restore state if active */ + if (global_state.keyboard_connected && !CURRENT_BOARD_IS_ACTIVE_OUTPUT) + restore_leds(state); } /* Process request to block mouse from switching, update internal state */ diff --git a/src/hid_report.c b/src/hid_report.c index 045d5e1..abd1bc9 100644 --- a/src/hid_report.c +++ b/src/hid_report.c @@ -275,7 +275,6 @@ int32_t _extract_kbd_nkro(uint8_t *raw_report, int len, hid_interface_t *iface, int32_t extract_kbd_data( uint8_t *raw_report, int len, uint8_t itf, hid_interface_t *iface, hid_keyboard_report_t *report) { - int report_id = raw_report[0]; /* Clear the report to start fresh */ memset(report, 0, KBD_REPORT_LENGTH); @@ -285,9 +284,7 @@ int32_t extract_kbd_data( return _extract_kbd_boot(raw_report, len, report); /* NKRO is a special case */ - if (report_id > 0 - && report_id == iface->keyboard.nkro.report_id - && iface->keyboard.is_nkro) + if (iface->keyboard.is_nkro) return _extract_kbd_nkro(raw_report, len, iface, report); /* If we're getting 8 bytes of report, it's safe to assume standard modifier + reserved + keys */ diff --git a/src/include/main.h b/src/include/main.h index 545ce37..20946e6 100644 --- a/src/include/main.h +++ b/src/include/main.h @@ -49,6 +49,7 @@ #define ABSOLUTE 0 #define RELATIVE 1 +#define TOUCH 2 #define MOUSE_BOOT_REPORT_LEN 4 #define MOUSE_ZOOM_SCALING_FACTOR 2 @@ -76,6 +77,7 @@ #define SERIAL_RX_PIN (global_state.board_role == OUTPUT_A ? BOARD_A_RX : BOARD_B_RX) #define BOARD_ROLE (global_state.board_role) +#define OTHER_ROLE (BOARD_ROLE == OUTPUT_A ? OUTPUT_B : OUTPUT_A) /********* Serial port definitions **********/ #define SERIAL_UART uart0 @@ -351,7 +353,7 @@ typedef struct TU_ATTR_PACKED { multiple desktops (Windows/MacOS) */ typedef struct { uint8_t tip_pressure; - uint8_t buttons; // Buttons + uint8_t buttons; // Digitizer buttons uint16_t x; // X coordinate (0-32767) uint16_t y; // Y coordinate (0-32767) } touch_report_t; @@ -423,6 +425,7 @@ typedef struct { bool onboard_led_state; // True when LED is ON bool relative_mouse; // True when relative mouse mode is used bool config_mode_active; // True when config mode is active + bool digitizer_active; // True when digitizer Win/Mac workaround is active /* Onboard LED blinky (provide feedback when e.g. mouse connected) */ int32_t blinks_left; // How many blink transitions are left diff --git a/src/include/usb_descriptors.h b/src/include/usb_descriptors.h index 0ddc871..e32a45e 100644 --- a/src/include/usb_descriptors.h +++ b/src/include/usb_descriptors.h @@ -32,7 +32,8 @@ #define REPORT_ID_SYSTEM 4 // Interface 1 -#define REPORT_ID_RELMOUSE 5 +#define REPORT_ID_RELMOUSE 5 +#define REPORT_ID_DIGITIZER 7 // Interface 2 #define REPORT_ID_VENDOR 6 @@ -173,7 +174,7 @@ HID_COLLECTION_END \ HID_REPORT_SIZE ( 3 ) ,\ HID_INPUT ( HID_CONSTANT ) ,\ HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ - /* X, Y position [-127, 127] */ \ + /* X, Y position [-32767, 32767] */ \ HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\ HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\ HID_LOGICAL_MIN_N ( 0x8000, 2 ) ,\ @@ -195,4 +196,52 @@ HID_COLLECTION_END \ HID_COLLECTION_END , \ HID_COLLECTION_END \ +#define HID_USAGE_DIGITIZER 0x01 + +#define TUD_HID_REPORT_DESC_DIGITIZER_PEN(...) \ +HID_USAGE_PAGE ( HID_USAGE_PAGE_DIGITIZER ) ,\ +HID_USAGE ( HID_USAGE_DIGITIZER ) ,\ +HID_COLLECTION ( HID_COLLECTION_APPLICATION ) ,\ + /* Report ID if any */\ + __VA_ARGS__ \ + HID_USAGE ( HID_USAGE_DIGITIZER ) ,\ + HID_COLLECTION ( HID_COLLECTION_PHYSICAL ) ,\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DIGITIZER ) ,\ + /* Tip Pressure */\ + HID_USAGE ( 0x30 ) ,\ + HID_LOGICAL_MIN ( 0x00 ) ,\ + HID_LOGICAL_MAX ( 0xff ) ,\ + HID_REPORT_COUNT( 1 ) ,\ + HID_REPORT_SIZE ( 8 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + \ + HID_REPORT_COUNT( 5 ) ,\ + HID_REPORT_SIZE ( 1 ) ,\ + /* In range */\ + HID_USAGE ( 0x32 ) ,\ + /* Tip switch */\ + HID_USAGE ( 0x42 ) ,\ + /* Eraser */\ + HID_USAGE ( 0x45 ) ,\ + /* Barrel switch */\ + HID_USAGE ( 0x44 ) ,\ + /* Invert */\ + HID_USAGE ( 0x3c ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE ) ,\ + \ + HID_REPORT_COUNT( 3 ) ,\ + HID_REPORT_SIZE ( 1 ) ,\ + HID_INPUT ( HID_CONSTANT ) ,\ + /* X and Y coordinates */\ + HID_USAGE_PAGE ( HID_USAGE_PAGE_DESKTOP ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_X ) ,\ + HID_USAGE ( HID_USAGE_DESKTOP_Y ) ,\ + HID_LOGICAL_MIN ( 0 ) ,\ + HID_LOGICAL_MAX_N ( 32767, 2 ) ,\ + HID_REPORT_SIZE ( 16 ) ,\ + HID_REPORT_COUNT ( 2 ) ,\ + HID_INPUT ( HID_DATA | HID_VARIABLE | HID_ABSOLUTE) ,\ + HID_COLLECTION_END ,\ +HID_COLLECTION_END + #endif /* USB_DESCRIPTORS_H_ */ diff --git a/src/keyboard.c b/src/keyboard.c index d25fe34..8f96f04 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -52,7 +52,7 @@ hotkey_combo_t hotkeys[] = { .action_handler = &screenlock_hotkey_handler}, /* Toggle gaming mode */ - {.modifier = KEYBOARD_MODIFIER_LEFTSHIFT | KEYBOARD_MODIFIER_RIGHTSHIFT, + {.modifier = KEYBOARD_MODIFIER_LEFTCTRL | KEYBOARD_MODIFIER_RIGHTSHIFT, .keys = {HID_KEY_G}, .key_count = 1, .acknowledge = true, @@ -73,7 +73,7 @@ hotkey_combo_t hotkeys[] = { .action_handler = &screen_border_hotkey_handler}, /* Switch to configuration mode */ - {.modifier = KEYBOARD_MODIFIER_RIGHTSHIFT | KEYBOARD_MODIFIER_LEFTSHIFT, + {.modifier = KEYBOARD_MODIFIER_LEFTCTRL | KEYBOARD_MODIFIER_RIGHTSHIFT, .keys = {HID_KEY_C, HID_KEY_O}, .key_count = 2, .acknowledge = true, diff --git a/src/mouse.c b/src/mouse.c index 72170a3..e640b12 100644 --- a/src/mouse.c +++ b/src/mouse.c @@ -64,10 +64,6 @@ void update_mouse_position(device_t *state, mouse_values_t *values) { output_t *current = &state->config.output[state->active_output]; uint8_t reduce_speed = 0; - /* If relative mouse mode is active, just pass mouse movements and update nothing */ - if (state->relative_mouse) - return; - /* Check if we are configured to move slowly */ if (state->mouse_zoom) reduce_speed = MOUSE_ZOOM_SCALING_FACTOR; @@ -299,7 +295,7 @@ void process_mouse_queue_task(device_t *state) { if (!tud_hid_n_ready(ITF_NUM_HID)) return; - /* ... try sending it to the host, if it's successful */ + /* Try sending it to the host, if it's successful */ bool succeeded = tud_mouse_report(report.mode, report.buttons, report.x, report.y, report.wheel); /* ... then we can remove it from the queue */ diff --git a/src/usb.c b/src/usb.c index f9e409f..cef34e1 100644 --- a/src/usb.c +++ b/src/usb.c @@ -79,14 +79,14 @@ void tud_hid_set_report_cb(uint8_t instance, leds |= KEYBOARD_LED_CAPSLOCK; } - global_state.keyboard_leds[global_state.active_output] = leds; + global_state.keyboard_leds[BOARD_ROLE] = leds; - /* If the board doesn't have the keyboard hooked up directly, we need to relay this information - to the other one that has (and LEDs you can turn on). */ - if (global_state.keyboard_connected) + /* If the board has a keyboard connected directly, restore those leds. */ + if (global_state.keyboard_connected && CURRENT_BOARD_IS_ACTIVE_OUTPUT) restore_leds(&global_state); - else - send_value(leds, KBD_SET_REPORT_MSG); + + /* Always send to the other one, so it is aware of the change */ + send_value(leds, KBD_SET_REPORT_MSG); } /* Invoked when device is mounted */ @@ -194,8 +194,11 @@ void tuh_hid_report_received_cb(uint8_t dev_addr, uint8_t instance, uint8_t cons if (instance >= MAX_INTERFACES) return; - if (iface->uses_report_id) { - uint8_t report_id = report[0]; + if (itf_protocol == HID_ITF_PROTOCOL_NONE) { + uint8_t report_id = 0; + + if (iface->uses_report_id) + report_id = report[0]; if (report_id < MAX_REPORTS) { process_report_f receiver = iface->report_handler[report_id];