mirror of
https://github.com/Genymobile/scrcpy
synced 2024-11-17 03:25:38 +00:00
Embed HID event data
In the implementation, an HID event is at most 8 bytes. Embed the data in the HID event structure to avoid allocations and simplify the code.
This commit is contained in:
parent
f0c39c8565
commit
a1e12f1dc3
@ -33,20 +33,6 @@ sc_hid_event_log(const struct sc_hid_event *event) {
|
|||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
sc_hid_event_init(struct sc_hid_event *hid_event, uint16_t accessory_id,
|
|
||||||
unsigned char *data, uint16_t size) {
|
|
||||||
hid_event->accessory_id = accessory_id;
|
|
||||||
hid_event->data = data;
|
|
||||||
hid_event->size = size;
|
|
||||||
hid_event->ack_to_wait = SC_SEQUENCE_INVALID;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
sc_hid_event_destroy(struct sc_hid_event *hid_event) {
|
|
||||||
free(hid_event->data);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sc_aoa_init(struct sc_aoa *aoa, struct sc_usb *usb,
|
sc_aoa_init(struct sc_aoa *aoa, struct sc_usb *usb,
|
||||||
struct sc_acksync *acksync) {
|
struct sc_acksync *acksync) {
|
||||||
@ -76,12 +62,7 @@ sc_aoa_init(struct sc_aoa *aoa, struct sc_usb *usb,
|
|||||||
|
|
||||||
void
|
void
|
||||||
sc_aoa_destroy(struct sc_aoa *aoa) {
|
sc_aoa_destroy(struct sc_aoa *aoa) {
|
||||||
// Destroy remaining events
|
sc_vecdeque_destroy(&aoa->queue);
|
||||||
while (!sc_vecdeque_is_empty(&aoa->queue)) {
|
|
||||||
struct sc_hid_event *event = sc_vecdeque_popref(&aoa->queue);
|
|
||||||
assert(event);
|
|
||||||
sc_hid_event_destroy(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
sc_cond_destroy(&aoa->event_cond);
|
sc_cond_destroy(&aoa->event_cond);
|
||||||
sc_mutex_destroy(&aoa->mutex);
|
sc_mutex_destroy(&aoa->mutex);
|
||||||
@ -177,7 +158,7 @@ sc_aoa_send_hid_event(struct sc_aoa *aoa, const struct sc_hid_event *event) {
|
|||||||
// index (arg1): 0 (unused)
|
// index (arg1): 0 (unused)
|
||||||
uint16_t value = event->accessory_id;
|
uint16_t value = event->accessory_id;
|
||||||
uint16_t index = 0;
|
uint16_t index = 0;
|
||||||
unsigned char *data = event->data;
|
unsigned char *data = (uint8_t *) event->data; // discard const
|
||||||
uint16_t length = event->size;
|
uint16_t length = event->size;
|
||||||
int result = libusb_control_transfer(aoa->usb->handle, request_type,
|
int result = libusb_control_transfer(aoa->usb->handle, request_type,
|
||||||
request, value, index, data, length,
|
request, value, index, data, length,
|
||||||
@ -271,17 +252,14 @@ run_aoa_thread(void *data) {
|
|||||||
|
|
||||||
if (result == SC_ACKSYNC_WAIT_TIMEOUT) {
|
if (result == SC_ACKSYNC_WAIT_TIMEOUT) {
|
||||||
LOGW("Ack not received after 500ms, discarding HID event");
|
LOGW("Ack not received after 500ms, discarding HID event");
|
||||||
sc_hid_event_destroy(&event);
|
|
||||||
continue;
|
continue;
|
||||||
} else if (result == SC_ACKSYNC_WAIT_INTR) {
|
} else if (result == SC_ACKSYNC_WAIT_INTR) {
|
||||||
// stopped
|
// stopped
|
||||||
sc_hid_event_destroy(&event);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ok = sc_aoa_send_hid_event(aoa, &event);
|
bool ok = sc_aoa_send_hid_event(aoa, &event);
|
||||||
sc_hid_event_destroy(&event);
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
LOGW("Could not send HID event to USB device");
|
LOGW("Could not send HID event to USB device");
|
||||||
}
|
}
|
||||||
|
@ -12,21 +12,15 @@
|
|||||||
#include "util/tick.h"
|
#include "util/tick.h"
|
||||||
#include "util/vecdeque.h"
|
#include "util/vecdeque.h"
|
||||||
|
|
||||||
|
#define SC_HID_MAX_SIZE 8
|
||||||
|
|
||||||
struct sc_hid_event {
|
struct sc_hid_event {
|
||||||
uint16_t accessory_id;
|
uint16_t accessory_id;
|
||||||
unsigned char *data;
|
uint8_t data[SC_HID_MAX_SIZE];
|
||||||
uint16_t size;
|
uint8_t size;
|
||||||
uint64_t ack_to_wait;
|
uint64_t ack_to_wait;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Takes ownership of buffer
|
|
||||||
void
|
|
||||||
sc_hid_event_init(struct sc_hid_event *hid_event, uint16_t accessory_id,
|
|
||||||
unsigned char *data, uint16_t size);
|
|
||||||
|
|
||||||
void
|
|
||||||
sc_hid_event_destroy(struct sc_hid_event *hid_event);
|
|
||||||
|
|
||||||
struct sc_hid_event_queue SC_VECDEQUE(struct sc_hid_event);
|
struct sc_hid_event_queue SC_VECDEQUE(struct sc_hid_event);
|
||||||
|
|
||||||
struct sc_aoa {
|
struct sc_aoa {
|
||||||
|
@ -231,21 +231,17 @@ sdl_keymod_to_hid_modifiers(uint16_t mod) {
|
|||||||
return modifiers;
|
return modifiers;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static void
|
||||||
sc_hid_keyboard_event_init(struct sc_hid_event *hid_event) {
|
sc_hid_keyboard_event_init(struct sc_hid_event *hid_event) {
|
||||||
unsigned char *data = malloc(HID_KEYBOARD_EVENT_SIZE);
|
hid_event->accessory_id = HID_KEYBOARD_ACCESSORY_ID;
|
||||||
if (!data) {
|
hid_event->size = HID_KEYBOARD_EVENT_SIZE;
|
||||||
LOG_OOM();
|
hid_event->ack_to_wait = SC_SEQUENCE_INVALID;
|
||||||
return false;
|
|
||||||
}
|
uint8_t *data = hid_event->data;
|
||||||
|
|
||||||
data[HID_KEYBOARD_INDEX_MODIFIER] = HID_MODIFIER_NONE;
|
data[HID_KEYBOARD_INDEX_MODIFIER] = HID_MODIFIER_NONE;
|
||||||
data[1] = HID_RESERVED;
|
data[1] = HID_RESERVED;
|
||||||
memset(&data[HID_KEYBOARD_INDEX_KEYS], 0, HID_KEYBOARD_MAX_KEYS);
|
memset(&data[HID_KEYBOARD_INDEX_KEYS], 0, HID_KEYBOARD_MAX_KEYS);
|
||||||
|
|
||||||
sc_hid_event_init(hid_event, HID_KEYBOARD_ACCESSORY_ID, data,
|
|
||||||
HID_KEYBOARD_EVENT_SIZE);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
@ -268,10 +264,7 @@ convert_hid_keyboard_event(struct sc_hid_keyboard *kb,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sc_hid_keyboard_event_init(hid_event)) {
|
sc_hid_keyboard_event_init(hid_event);
|
||||||
LOGW("Could not initialize HID keyboard event");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char modifiers = sdl_keymod_to_hid_modifiers(event->mods_state);
|
unsigned char modifiers = sdl_keymod_to_hid_modifiers(event->mods_state);
|
||||||
|
|
||||||
@ -324,10 +317,7 @@ push_mod_lock_state(struct sc_hid_keyboard *kb, uint16_t mods_state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
struct sc_hid_event hid_event;
|
struct sc_hid_event hid_event;
|
||||||
if (!sc_hid_keyboard_event_init(&hid_event)) {
|
sc_hid_keyboard_event_init(&hid_event);
|
||||||
LOGW("Could not initialize HID keyboard event");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned i = 0;
|
unsigned i = 0;
|
||||||
if (capslock) {
|
if (capslock) {
|
||||||
@ -340,7 +330,6 @@ push_mod_lock_state(struct sc_hid_keyboard *kb, uint16_t mods_state) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!sc_aoa_push_hid_event(kb->aoa, &hid_event)) {
|
if (!sc_aoa_push_hid_event(kb->aoa, &hid_event)) {
|
||||||
sc_hid_event_destroy(&hid_event);
|
|
||||||
LOGW("Could not request HID event (mod lock state)");
|
LOGW("Could not request HID event (mod lock state)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -382,7 +371,6 @@ sc_key_processor_process_key(struct sc_key_processor *kp,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!sc_aoa_push_hid_event(kb->aoa, &hid_event)) {
|
if (!sc_aoa_push_hid_event(kb->aoa, &hid_event)) {
|
||||||
sc_hid_event_destroy(&hid_event);
|
|
||||||
LOGW("Could not request HID event (key)");
|
LOGW("Could not request HID event (key)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -131,17 +131,13 @@ static const unsigned char mouse_report_desc[] = {
|
|||||||
* +---------------+
|
* +---------------+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static bool
|
static void
|
||||||
sc_hid_mouse_event_init(struct sc_hid_event *hid_event) {
|
sc_hid_mouse_event_init(struct sc_hid_event *hid_event) {
|
||||||
unsigned char *data = calloc(1, HID_MOUSE_EVENT_SIZE);
|
hid_event->accessory_id = HID_MOUSE_ACCESSORY_ID;
|
||||||
if (!data) {
|
hid_event->size = HID_MOUSE_EVENT_SIZE;
|
||||||
LOG_OOM();
|
hid_event->ack_to_wait = SC_SEQUENCE_INVALID;
|
||||||
return false;
|
// Leave hid_event->data uninitialized, it will be fully initialized by
|
||||||
}
|
// callers
|
||||||
|
|
||||||
sc_hid_event_init(hid_event, HID_MOUSE_ACCESSORY_ID, data,
|
|
||||||
HID_MOUSE_EVENT_SIZE);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned char
|
static unsigned char
|
||||||
@ -171,9 +167,7 @@ sc_mouse_processor_process_mouse_motion(struct sc_mouse_processor *mp,
|
|||||||
struct sc_hid_mouse *mouse = DOWNCAST(mp);
|
struct sc_hid_mouse *mouse = DOWNCAST(mp);
|
||||||
|
|
||||||
struct sc_hid_event hid_event;
|
struct sc_hid_event hid_event;
|
||||||
if (!sc_hid_mouse_event_init(&hid_event)) {
|
sc_hid_mouse_event_init(&hid_event);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char *data = hid_event.data;
|
unsigned char *data = hid_event.data;
|
||||||
data[0] = buttons_state_to_hid_buttons(event->buttons_state);
|
data[0] = buttons_state_to_hid_buttons(event->buttons_state);
|
||||||
@ -182,7 +176,6 @@ sc_mouse_processor_process_mouse_motion(struct sc_mouse_processor *mp,
|
|||||||
data[3] = 0; // wheel coordinates only used for scrolling
|
data[3] = 0; // wheel coordinates only used for scrolling
|
||||||
|
|
||||||
if (!sc_aoa_push_hid_event(mouse->aoa, &hid_event)) {
|
if (!sc_aoa_push_hid_event(mouse->aoa, &hid_event)) {
|
||||||
sc_hid_event_destroy(&hid_event);
|
|
||||||
LOGW("Could not request HID event (mouse motion)");
|
LOGW("Could not request HID event (mouse motion)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,9 +186,7 @@ sc_mouse_processor_process_mouse_click(struct sc_mouse_processor *mp,
|
|||||||
struct sc_hid_mouse *mouse = DOWNCAST(mp);
|
struct sc_hid_mouse *mouse = DOWNCAST(mp);
|
||||||
|
|
||||||
struct sc_hid_event hid_event;
|
struct sc_hid_event hid_event;
|
||||||
if (!sc_hid_mouse_event_init(&hid_event)) {
|
sc_hid_mouse_event_init(&hid_event);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char *data = hid_event.data;
|
unsigned char *data = hid_event.data;
|
||||||
data[0] = buttons_state_to_hid_buttons(event->buttons_state);
|
data[0] = buttons_state_to_hid_buttons(event->buttons_state);
|
||||||
@ -204,7 +195,6 @@ sc_mouse_processor_process_mouse_click(struct sc_mouse_processor *mp,
|
|||||||
data[3] = 0; // wheel coordinates only used for scrolling
|
data[3] = 0; // wheel coordinates only used for scrolling
|
||||||
|
|
||||||
if (!sc_aoa_push_hid_event(mouse->aoa, &hid_event)) {
|
if (!sc_aoa_push_hid_event(mouse->aoa, &hid_event)) {
|
||||||
sc_hid_event_destroy(&hid_event);
|
|
||||||
LOGW("Could not request HID event (mouse click)");
|
LOGW("Could not request HID event (mouse click)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -215,9 +205,7 @@ sc_mouse_processor_process_mouse_scroll(struct sc_mouse_processor *mp,
|
|||||||
struct sc_hid_mouse *mouse = DOWNCAST(mp);
|
struct sc_hid_mouse *mouse = DOWNCAST(mp);
|
||||||
|
|
||||||
struct sc_hid_event hid_event;
|
struct sc_hid_event hid_event;
|
||||||
if (!sc_hid_mouse_event_init(&hid_event)) {
|
sc_hid_mouse_event_init(&hid_event);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned char *data = hid_event.data;
|
unsigned char *data = hid_event.data;
|
||||||
data[0] = 0; // buttons state irrelevant (and unknown)
|
data[0] = 0; // buttons state irrelevant (and unknown)
|
||||||
@ -229,7 +217,6 @@ sc_mouse_processor_process_mouse_scroll(struct sc_mouse_processor *mp,
|
|||||||
// Horizontal scrolling ignored
|
// Horizontal scrolling ignored
|
||||||
|
|
||||||
if (!sc_aoa_push_hid_event(mouse->aoa, &hid_event)) {
|
if (!sc_aoa_push_hid_event(mouse->aoa, &hid_event)) {
|
||||||
sc_hid_event_destroy(&hid_event);
|
|
||||||
LOGW("Could not request HID event (mouse scroll)");
|
LOGW("Could not request HID event (mouse scroll)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user