Extract HID events struct
An event contained several fields: - the accessory id - the HID event data - a field ack_to_wait specific to the AOA implementation. Extract the HID event part to prepare the factorization of HID event creation.
This commit is contained in:
parent
5583fd8394
commit
569b6e02d5
15
app/src/hid/hid_event.h
Normal file
15
app/src/hid/hid_event.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#ifndef SC_HID_EVENT_H
|
||||||
|
#define SC_HID_EVENT_H
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#define SC_HID_MAX_SIZE 8
|
||||||
|
|
||||||
|
struct sc_hid_event {
|
||||||
|
uint8_t data[SC_HID_MAX_SIZE];
|
||||||
|
uint8_t size;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -14,10 +14,10 @@
|
|||||||
|
|
||||||
#define DEFAULT_TIMEOUT 1000
|
#define DEFAULT_TIMEOUT 1000
|
||||||
|
|
||||||
#define SC_HID_EVENT_QUEUE_MAX 64
|
#define SC_AOA_EVENT_QUEUE_MAX 64
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sc_hid_event_log(const struct sc_hid_event *event) {
|
sc_hid_event_log(uint16_t accessory_id, const struct sc_hid_event *event) {
|
||||||
// HID Event: [00] FF FF FF FF...
|
// HID Event: [00] FF FF FF FF...
|
||||||
assert(event->size);
|
assert(event->size);
|
||||||
unsigned buffer_size = event->size * 3 + 1;
|
unsigned buffer_size = event->size * 3 + 1;
|
||||||
@ -29,7 +29,7 @@ sc_hid_event_log(const struct sc_hid_event *event) {
|
|||||||
for (unsigned i = 0; i < event->size; ++i) {
|
for (unsigned i = 0; i < event->size; ++i) {
|
||||||
snprintf(buffer + i * 3, 4, " %02x", event->data[i]);
|
snprintf(buffer + i * 3, 4, " %02x", event->data[i]);
|
||||||
}
|
}
|
||||||
LOGV("HID Event: [%d]%s", event->accessory_id, buffer);
|
LOGV("HID Event: [%d]%s", accessory_id, buffer);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -38,7 +38,7 @@ sc_aoa_init(struct sc_aoa *aoa, struct sc_usb *usb,
|
|||||||
struct sc_acksync *acksync) {
|
struct sc_acksync *acksync) {
|
||||||
sc_vecdeque_init(&aoa->queue);
|
sc_vecdeque_init(&aoa->queue);
|
||||||
|
|
||||||
if (!sc_vecdeque_reserve(&aoa->queue, SC_HID_EVENT_QUEUE_MAX)) {
|
if (!sc_vecdeque_reserve(&aoa->queue, SC_AOA_EVENT_QUEUE_MAX)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,13 +150,14 @@ sc_aoa_setup_hid(struct sc_aoa *aoa, uint16_t accessory_id,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
sc_aoa_send_hid_event(struct sc_aoa *aoa, const struct sc_hid_event *event) {
|
sc_aoa_send_hid_event(struct sc_aoa *aoa, uint16_t accessory_id,
|
||||||
|
const struct sc_hid_event *event) {
|
||||||
uint8_t request_type = LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR;
|
uint8_t request_type = LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR;
|
||||||
uint8_t request = ACCESSORY_SEND_HID_EVENT;
|
uint8_t request = ACCESSORY_SEND_HID_EVENT;
|
||||||
// <https://source.android.com/devices/accessories/aoa2.html#hid-support>
|
// <https://source.android.com/devices/accessories/aoa2.html#hid-support>
|
||||||
// value (arg0): accessory assigned ID for the HID device
|
// value (arg0): accessory assigned ID for the HID device
|
||||||
// index (arg1): 0 (unused)
|
// index (arg1): 0 (unused)
|
||||||
uint16_t value = event->accessory_id;
|
uint16_t value = accessory_id;
|
||||||
uint16_t index = 0;
|
uint16_t index = 0;
|
||||||
unsigned char *data = (uint8_t *) event->data; // discard const
|
unsigned char *data = (uint8_t *) event->data; // discard const
|
||||||
uint16_t length = event->size;
|
uint16_t length = event->size;
|
||||||
@ -173,7 +174,7 @@ sc_aoa_send_hid_event(struct sc_aoa *aoa, const struct sc_hid_event *event) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sc_aoa_unregister_hid(struct sc_aoa *aoa, const uint16_t accessory_id) {
|
sc_aoa_unregister_hid(struct sc_aoa *aoa, uint16_t accessory_id) {
|
||||||
uint8_t request_type = LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR;
|
uint8_t request_type = LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR;
|
||||||
uint8_t request = ACCESSORY_UNREGISTER_HID;
|
uint8_t request = ACCESSORY_UNREGISTER_HID;
|
||||||
// <https://source.android.com/devices/accessories/aoa2.html#hid-support>
|
// <https://source.android.com/devices/accessories/aoa2.html#hid-support>
|
||||||
@ -196,16 +197,25 @@ sc_aoa_unregister_hid(struct sc_aoa *aoa, const uint16_t accessory_id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sc_aoa_push_hid_event(struct sc_aoa *aoa, const struct sc_hid_event *event) {
|
sc_aoa_push_hid_event_with_ack_to_wait(struct sc_aoa *aoa,
|
||||||
|
uint16_t accessory_id,
|
||||||
|
const struct sc_hid_event *event,
|
||||||
|
uint64_t ack_to_wait) {
|
||||||
if (sc_get_log_level() <= SC_LOG_LEVEL_VERBOSE) {
|
if (sc_get_log_level() <= SC_LOG_LEVEL_VERBOSE) {
|
||||||
sc_hid_event_log(event);
|
sc_hid_event_log(accessory_id, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
sc_mutex_lock(&aoa->mutex);
|
sc_mutex_lock(&aoa->mutex);
|
||||||
bool full = sc_vecdeque_is_full(&aoa->queue);
|
bool full = sc_vecdeque_is_full(&aoa->queue);
|
||||||
if (!full) {
|
if (!full) {
|
||||||
bool was_empty = sc_vecdeque_is_empty(&aoa->queue);
|
bool was_empty = sc_vecdeque_is_empty(&aoa->queue);
|
||||||
sc_vecdeque_push_noresize(&aoa->queue, *event);
|
|
||||||
|
struct sc_aoa_event *aoa_event =
|
||||||
|
sc_vecdeque_push_hole_noresize(&aoa->queue);
|
||||||
|
aoa_event->hid = *event;
|
||||||
|
aoa_event->accessory_id = accessory_id;
|
||||||
|
aoa_event->ack_to_wait = ack_to_wait;
|
||||||
|
|
||||||
if (was_empty) {
|
if (was_empty) {
|
||||||
sc_cond_signal(&aoa->event_cond);
|
sc_cond_signal(&aoa->event_cond);
|
||||||
}
|
}
|
||||||
@ -233,7 +243,7 @@ run_aoa_thread(void *data) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert(!sc_vecdeque_is_empty(&aoa->queue));
|
assert(!sc_vecdeque_is_empty(&aoa->queue));
|
||||||
struct sc_hid_event event = sc_vecdeque_pop(&aoa->queue);
|
struct sc_aoa_event event = sc_vecdeque_pop(&aoa->queue);
|
||||||
uint64_t ack_to_wait = event.ack_to_wait;
|
uint64_t ack_to_wait = event.ack_to_wait;
|
||||||
sc_mutex_unlock(&aoa->mutex);
|
sc_mutex_unlock(&aoa->mutex);
|
||||||
|
|
||||||
@ -259,7 +269,7 @@ run_aoa_thread(void *data) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ok = sc_aoa_send_hid_event(aoa, &event);
|
bool ok = sc_aoa_send_hid_event(aoa, event.accessory_id, &event.hid);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
LOGW("Could not send HID event to USB device");
|
LOGW("Could not send HID event to USB device");
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <libusb-1.0/libusb.h>
|
#include <libusb-1.0/libusb.h>
|
||||||
|
|
||||||
|
#include "hid/hid_event.h"
|
||||||
#include "usb.h"
|
#include "usb.h"
|
||||||
#include "util/acksync.h"
|
#include "util/acksync.h"
|
||||||
#include "util/thread.h"
|
#include "util/thread.h"
|
||||||
@ -14,14 +15,13 @@
|
|||||||
|
|
||||||
#define SC_HID_MAX_SIZE 8
|
#define SC_HID_MAX_SIZE 8
|
||||||
|
|
||||||
struct sc_hid_event {
|
struct sc_aoa_event {
|
||||||
|
struct sc_hid_event hid;
|
||||||
uint16_t accessory_id;
|
uint16_t accessory_id;
|
||||||
uint8_t data[SC_HID_MAX_SIZE];
|
|
||||||
uint8_t size;
|
|
||||||
uint64_t ack_to_wait;
|
uint64_t ack_to_wait;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sc_hid_event_queue SC_VECDEQUE(struct sc_hid_event);
|
struct sc_aoa_event_queue SC_VECDEQUE(struct sc_aoa_event);
|
||||||
|
|
||||||
struct sc_aoa {
|
struct sc_aoa {
|
||||||
struct sc_usb *usb;
|
struct sc_usb *usb;
|
||||||
@ -29,7 +29,7 @@ struct sc_aoa {
|
|||||||
sc_mutex mutex;
|
sc_mutex mutex;
|
||||||
sc_cond event_cond;
|
sc_cond event_cond;
|
||||||
bool stopped;
|
bool stopped;
|
||||||
struct sc_hid_event_queue queue;
|
struct sc_aoa_event_queue queue;
|
||||||
|
|
||||||
struct sc_acksync *acksync;
|
struct sc_acksync *acksync;
|
||||||
};
|
};
|
||||||
@ -57,6 +57,16 @@ bool
|
|||||||
sc_aoa_unregister_hid(struct sc_aoa *aoa, uint16_t accessory_id);
|
sc_aoa_unregister_hid(struct sc_aoa *aoa, uint16_t accessory_id);
|
||||||
|
|
||||||
bool
|
bool
|
||||||
sc_aoa_push_hid_event(struct sc_aoa *aoa, const struct sc_hid_event *event);
|
sc_aoa_push_hid_event_with_ack_to_wait(struct sc_aoa *aoa,
|
||||||
|
uint16_t accessory_id,
|
||||||
|
const struct sc_hid_event *event,
|
||||||
|
uint64_t ack_to_wait);
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
sc_aoa_push_hid_event(struct sc_aoa *aoa, uint16_t accessory_id,
|
||||||
|
const struct sc_hid_event *event) {
|
||||||
|
return sc_aoa_push_hid_event_with_ack_to_wait(aoa, accessory_id, event,
|
||||||
|
SC_SEQUENCE_INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -233,9 +233,7 @@ sdl_keymod_to_hid_modifiers(uint16_t mod) {
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
sc_hid_keyboard_event_init(struct sc_hid_event *hid_event) {
|
sc_hid_keyboard_event_init(struct sc_hid_event *hid_event) {
|
||||||
hid_event->accessory_id = HID_KEYBOARD_ACCESSORY_ID;
|
|
||||||
hid_event->size = HID_KEYBOARD_EVENT_SIZE;
|
hid_event->size = HID_KEYBOARD_EVENT_SIZE;
|
||||||
hid_event->ack_to_wait = SC_SEQUENCE_INVALID;
|
|
||||||
|
|
||||||
uint8_t *data = hid_event->data;
|
uint8_t *data = hid_event->data;
|
||||||
|
|
||||||
@ -329,7 +327,8 @@ push_mod_lock_state(struct sc_hid_keyboard *kb, uint16_t mods_state) {
|
|||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sc_aoa_push_hid_event(kb->aoa, &hid_event)) {
|
if (!sc_aoa_push_hid_event(kb->aoa, HID_KEYBOARD_ACCESSORY_ID,
|
||||||
|
&hid_event)) {
|
||||||
LOGW("Could not request HID event (mod lock state)");
|
LOGW("Could not request HID event (mod lock state)");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -362,15 +361,15 @@ sc_key_processor_process_key(struct sc_key_processor *kp,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ack_to_wait) {
|
// If ack_to_wait is != SC_SEQUENCE_INVALID, then Ctrl+v is pressed, so
|
||||||
// Ctrl+v is pressed, so clipboard synchronization has been
|
// clipboard synchronization has been requested. Wait until clipboard
|
||||||
// requested. Wait until clipboard synchronization is acknowledged
|
// synchronization is acknowledged by the server, otherwise it could
|
||||||
// by the server, otherwise it could paste the old clipboard
|
// paste the old clipboard content.
|
||||||
// content.
|
|
||||||
hid_event.ack_to_wait = ack_to_wait;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!sc_aoa_push_hid_event(kb->aoa, &hid_event)) {
|
if (!sc_aoa_push_hid_event_with_ack_to_wait(kb->aoa,
|
||||||
|
HID_KEYBOARD_ACCESSORY_ID,
|
||||||
|
&hid_event,
|
||||||
|
ack_to_wait)) {
|
||||||
LOGW("Could not request HID event (key)");
|
LOGW("Could not request HID event (key)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,9 +133,7 @@ static const unsigned char mouse_report_desc[] = {
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
sc_hid_mouse_event_init(struct sc_hid_event *hid_event) {
|
sc_hid_mouse_event_init(struct sc_hid_event *hid_event) {
|
||||||
hid_event->accessory_id = HID_MOUSE_ACCESSORY_ID;
|
|
||||||
hid_event->size = HID_MOUSE_EVENT_SIZE;
|
hid_event->size = HID_MOUSE_EVENT_SIZE;
|
||||||
hid_event->ack_to_wait = SC_SEQUENCE_INVALID;
|
|
||||||
// Leave hid_event->data uninitialized, it will be fully initialized by
|
// Leave hid_event->data uninitialized, it will be fully initialized by
|
||||||
// callers
|
// callers
|
||||||
}
|
}
|
||||||
@ -175,7 +173,8 @@ sc_mouse_processor_process_mouse_motion(struct sc_mouse_processor *mp,
|
|||||||
data[2] = CLAMP(event->yrel, -127, 127);
|
data[2] = CLAMP(event->yrel, -127, 127);
|
||||||
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_MOUSE_ACCESSORY_ID,
|
||||||
|
&hid_event)) {
|
||||||
LOGW("Could not request HID event (mouse motion)");
|
LOGW("Could not request HID event (mouse motion)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -194,7 +193,8 @@ sc_mouse_processor_process_mouse_click(struct sc_mouse_processor *mp,
|
|||||||
data[2] = 0; // no y motion
|
data[2] = 0; // no y motion
|
||||||
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_MOUSE_ACCESSORY_ID,
|
||||||
|
&hid_event)) {
|
||||||
LOGW("Could not request HID event (mouse click)");
|
LOGW("Could not request HID event (mouse click)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -216,7 +216,8 @@ sc_mouse_processor_process_mouse_scroll(struct sc_mouse_processor *mp,
|
|||||||
data[3] = CLAMP(event->vscroll, -127, 127);
|
data[3] = CLAMP(event->vscroll, -127, 127);
|
||||||
// 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_MOUSE_ACCESSORY_ID,
|
||||||
|
&hid_event)) {
|
||||||
LOGW("Could not request HID event (mouse scroll)");
|
LOGW("Could not request HID event (mouse scroll)");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user