mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-06-05 22:30:29 +00:00
WebHID fixes
This commit is contained in:
parent
138683e645
commit
6577fc722e
4 changed files with 49 additions and 31 deletions
|
|
@ -27,6 +27,10 @@
|
|||
|
||||
EM_JS_DEPS(hidapi, "$dynCall");
|
||||
|
||||
#if 0
|
||||
#define HIDAPI_WEBHID_DEBUG
|
||||
#endif
|
||||
|
||||
struct hid_device_ {
|
||||
int device_id;
|
||||
unsigned char *last_report;
|
||||
|
|
@ -66,26 +70,8 @@ HID_API_EXPORT const char* HID_API_CALL hid_version_str(void)
|
|||
return HID_API_VERSION_STR;
|
||||
}
|
||||
|
||||
// static void test(hid_device *dev, unsigned char *data, size_t length)
|
||||
// static void test(unsigned char *data)
|
||||
// {
|
||||
// // printf("Test function, device_id=%d\n", dev->device_id);
|
||||
// printf("Test function\n");
|
||||
// for (int i = 0; i < 3; i++) {
|
||||
// printf("Test function, data[%d]=%d\n", i, data[i]);
|
||||
// }
|
||||
// free(data);
|
||||
// }
|
||||
|
||||
int HID_API_EXPORT hid_init(void)
|
||||
{
|
||||
// MAIN_THREAD_EM_ASM({
|
||||
// const typedArray = Uint8Array.from([1,2,3]);
|
||||
// const heapPointer = _malloc(typedArray.length * typedArray.BYTES_PER_ELEMENT);
|
||||
// HEAPU8.set(typedArray, heapPointer);
|
||||
// dynCall('vi', $0, [heapPointer]);
|
||||
// }, &test);
|
||||
|
||||
return MAIN_THREAD_EM_ASM_INT({
|
||||
return "hid" in navigator ? 0 : -1;
|
||||
});
|
||||
|
|
@ -167,12 +153,14 @@ static struct hid_device_info * create_device_info_for_device(int device_id)
|
|||
|
||||
cur_dev->next = NULL;
|
||||
|
||||
#ifdef HIDAPI_WEBHID_DEBUG
|
||||
printf("HIDAPI: New device found: %d %d\n", cur_dev->vendor_id, cur_dev->product_id);
|
||||
#endif
|
||||
end:
|
||||
return root;
|
||||
}
|
||||
|
||||
// TODO: remove all EM_ASYNC_JS
|
||||
// TODO: remove all EM_ASYNC_JS for non-blocking operations
|
||||
EM_ASYNC_JS(int, hid_js_get_device_count, (), {
|
||||
window._hidDeviceList = await navigator.hid.getDevices();
|
||||
return window._hidDeviceList.length;
|
||||
|
|
@ -188,7 +176,9 @@ struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, u
|
|||
|
||||
device_count = hid_js_get_device_count();
|
||||
|
||||
#ifdef HIDAPI_WEBHID_DEBUG
|
||||
printf("hid_enumerate, device_count=%d\n", device_count);
|
||||
#endif
|
||||
|
||||
int device_id;
|
||||
for (device_id = 0; device_id < device_count; device_id++) {
|
||||
|
|
@ -277,7 +267,9 @@ static void set_byte(unsigned char *data, size_t length, int byte, size_t offset
|
|||
if (offset >= length)
|
||||
return;
|
||||
data[offset] = (unsigned char)byte;
|
||||
#ifdef HIDAPI_WEBHID_DEBUG
|
||||
// printf("set_byte: offset=%d byte=%d\n", (int)offset, byte);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void set_report(hid_device *dev, unsigned char *data, size_t length)
|
||||
|
|
@ -292,16 +284,14 @@ static void set_report(hid_device *dev, unsigned char *data, size_t length)
|
|||
|
||||
EM_ASYNC_JS(void, hid_js_open, (int device_id, hid_device *dev, SetByteCallback callback, SetReportCallback set_report_callback), {
|
||||
let device = window._hidDeviceList[device_id];
|
||||
console.log("Opening device1 " + device_id);
|
||||
if (device) {
|
||||
console.log("Opening device2 " + device_id);
|
||||
await device.open();
|
||||
device.addEventListener("inputreport", function (event) {
|
||||
const { data, device, reportId } = event;
|
||||
|
||||
|
||||
let dataLength = data['byteLength']+1;
|
||||
let pointer = _malloc(dataLength);
|
||||
dynCall("viiii", callback, [pointer, dataLength, report_id, 0]);
|
||||
dynCall("viiii", callback, [pointer, dataLength, reportId, 0]);
|
||||
for (let i = 0; i < data['byteLength']; i++) {
|
||||
dynCall("viiii", callback, [pointer, dataLength, data['getUint8'](i), i+1]);
|
||||
}
|
||||
|
|
@ -318,16 +308,22 @@ hid_device * HID_API_EXPORT hid_open_path(const char *path)
|
|||
hid_init();
|
||||
/* register_global_error: global error is reset by hid_init */
|
||||
|
||||
#ifdef HIDAPI_WEBHID_DEBUG
|
||||
printf("hid_open_path: %s\n", path);
|
||||
#endif
|
||||
dev = new_hid_device();
|
||||
if (!dev) {
|
||||
#ifdef HIDAPI_WEBHID_DEBUG
|
||||
printf("hid_open_path: no memory\n");
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (sscanf(path, "hid%d", &device_id) != 1) {
|
||||
free(dev);
|
||||
#ifdef HIDAPI_WEBHID_DEBUG
|
||||
printf("hid_open_path: invalid path\n");
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -342,7 +338,6 @@ EM_ASYNC_JS(int, hid_js_write, (int device_id, int report_id, const unsigned cha
|
|||
if (device) {
|
||||
let dataArray = new Uint8Array(length);
|
||||
for (let i = 0; i < length; i++) {
|
||||
// console.log("hid_write: offset=" + i + " byte=" + HEAPU8[data+i]);
|
||||
dataArray[i] = HEAPU8[data+i];
|
||||
}
|
||||
await device.sendReport(report_id, dataArray);
|
||||
|
|
@ -362,8 +357,8 @@ EM_ASYNC_JS(int, hid_js_read_timeout, (int device_id, unsigned char *data, size_
|
|||
if (device) {
|
||||
let [report_id, dataView] = await new Promise(function(resolve, reject) {
|
||||
device.addEventListener("inputreport", function (event) {
|
||||
const { data, device, reportId } = event;
|
||||
resolve([reportId, data]); // done
|
||||
const { data, device, report_id } = event;
|
||||
resolve([report_id, data]); // done
|
||||
}, {once: true});
|
||||
});
|
||||
dynCall("viiii", callback, [data, length, report_id, 0]);
|
||||
|
|
|
|||
|
|
@ -1034,7 +1034,6 @@ static void HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_d
|
|||
SDL_SendJoystickTouchpad(timestamp, joystick, 0, 1, touchpad_down, touchpad_x * TOUCHPAD_SCALEX, touchpad_y * TOUCHPAD_SCALEY, touchpad_down ? 1.0f : 0.0f);
|
||||
}
|
||||
|
||||
printf("PS4 Packet usb1 %d\n", packet->rgucButtonsHatAndCounter[0]);
|
||||
if (ctx->last_state.rgucButtonsHatAndCounter[0] != packet->rgucButtonsHatAndCounter[0]) {
|
||||
{
|
||||
Uint8 data = (packet->rgucButtonsHatAndCounter[0] >> 4);
|
||||
|
|
@ -1296,9 +1295,7 @@ static bool HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
|
|||
#ifdef DEBUG_PS4_PROTOCOL
|
||||
HIDAPI_DumpPacket("PS4 packet: size = %d", data, size);
|
||||
#endif
|
||||
printf("PS4 Packet start\n");
|
||||
if (!HIDAPI_DriverPS4_IsPacketValid(ctx, data, size)) {
|
||||
printf("PS4 Packet invalid\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
@ -1306,13 +1303,11 @@ static bool HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
|
|||
ctx->last_packet = now;
|
||||
|
||||
if (!joystick) {
|
||||
printf("PS4 Packet no joystick\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (data[0]) {
|
||||
case k_EPS4ReportIdUsbState:
|
||||
printf("PS4 Packet usb, packet[1]=%d\n", +data[1]);
|
||||
HIDAPI_DriverPS4_HandleStatePacket(joystick, device->dev, ctx, (PS4StatePacket_t *)&data[1], size - 1);
|
||||
break;
|
||||
case k_EPS4ReportIdBluetoothState1:
|
||||
|
|
|
|||
|
|
@ -49,12 +49,15 @@ typedef struct SDL_HIDAPI_RumbleContext
|
|||
SDL_HIDAPI_RumbleRequest *requests_tail;
|
||||
} SDL_HIDAPI_RumbleContext;
|
||||
|
||||
#ifndef SDL_PLATFORM_EMSCRIPTEN
|
||||
#ifndef SDL_THREAD_SAFETY_ANALYSIS
|
||||
static
|
||||
#endif
|
||||
SDL_Mutex *SDL_HIDAPI_rumble_lock;
|
||||
#endif
|
||||
static SDL_HIDAPI_RumbleContext rumble_context SDL_GUARDED_BY(SDL_HIDAPI_rumble_lock);
|
||||
|
||||
#ifndef SDL_PLATFORM_EMSCRIPTEN // Threads are not used for the web
|
||||
static int SDLCALL SDL_HIDAPI_RumbleThread(void *data)
|
||||
{
|
||||
SDL_HIDAPI_RumbleContext *ctx = (SDL_HIDAPI_RumbleContext *)data;
|
||||
|
|
@ -161,9 +164,11 @@ static bool SDL_HIDAPI_StartRumbleThread(SDL_HIDAPI_RumbleContext *ctx)
|
|||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool SDL_HIDAPI_LockRumble(void)
|
||||
{
|
||||
#ifndef SDL_PLATFORM_EMSCRIPTEN
|
||||
SDL_HIDAPI_RumbleContext *ctx = &rumble_context;
|
||||
|
||||
if (SDL_CompareAndSwapAtomicInt(&ctx->initialized, false, true)) {
|
||||
|
|
@ -173,11 +178,13 @@ bool SDL_HIDAPI_LockRumble(void)
|
|||
}
|
||||
|
||||
SDL_LockMutex(SDL_HIDAPI_rumble_lock);
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SDL_HIDAPI_GetPendingRumbleLocked(SDL_HIDAPI_Device *device, Uint8 **data, int **size, int *maximum_size)
|
||||
{
|
||||
#ifndef SDL_PLATFORM_EMSCRIPTEN
|
||||
SDL_HIDAPI_RumbleContext *ctx = &rumble_context;
|
||||
SDL_HIDAPI_RumbleRequest *request, *found;
|
||||
|
||||
|
|
@ -193,6 +200,7 @@ bool SDL_HIDAPI_GetPendingRumbleLocked(SDL_HIDAPI_Device *device, Uint8 **data,
|
|||
*maximum_size = sizeof(found->data);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -212,6 +220,7 @@ int SDL_HIDAPI_SendRumbleWithCallbackAndUnlock(SDL_HIDAPI_Device *device, const
|
|||
return -1;
|
||||
}
|
||||
|
||||
#ifndef SDL_PLATFORM_EMSCRIPTEN
|
||||
request = (SDL_HIDAPI_RumbleRequest *)SDL_calloc(1, sizeof(*request));
|
||||
if (!request) {
|
||||
SDL_HIDAPI_UnlockRumble();
|
||||
|
|
@ -234,6 +243,9 @@ int SDL_HIDAPI_SendRumbleWithCallbackAndUnlock(SDL_HIDAPI_Device *device, const
|
|||
|
||||
// Make sure we unlock before posting the semaphore so the rumble thread can run immediately
|
||||
SDL_HIDAPI_UnlockRumble();
|
||||
#else
|
||||
SDL_hid_write(device->dev, data, size);
|
||||
#endif
|
||||
|
||||
SDL_SignalSemaphore(ctx->request_sem);
|
||||
|
||||
|
|
@ -242,7 +254,9 @@ int SDL_HIDAPI_SendRumbleWithCallbackAndUnlock(SDL_HIDAPI_Device *device, const
|
|||
|
||||
void SDL_HIDAPI_UnlockRumble(void)
|
||||
{
|
||||
#ifndef SDL_PLATFORM_EMSCRIPTEN
|
||||
SDL_UnlockMutex(SDL_HIDAPI_rumble_lock);
|
||||
#endif
|
||||
}
|
||||
|
||||
int SDL_HIDAPI_SendRumble(SDL_HIDAPI_Device *device, const Uint8 *data, int size)
|
||||
|
|
@ -273,11 +287,13 @@ int SDL_HIDAPI_SendRumble(SDL_HIDAPI_Device *device, const Uint8 *data, int size
|
|||
|
||||
void SDL_HIDAPI_QuitRumble(void)
|
||||
{
|
||||
#ifndef SDL_PLATFORM_EMSCRIPTEN
|
||||
SDL_HIDAPI_RumbleContext *ctx = &rumble_context;
|
||||
|
||||
if (SDL_GetAtomicInt(&ctx->running)) {
|
||||
SDL_HIDAPI_StopRumbleThread(ctx);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif // SDL_JOYSTICK_HIDAPI
|
||||
|
|
|
|||
|
|
@ -642,6 +642,7 @@ void HIDAPI_SetDeviceProduct(SDL_HIDAPI_Device *device, Uint16 vendor_id, Uint16
|
|||
device->guid = SDL_CreateJoystickGUID(device->guid.data[0], vendor_id, product_id, device->version, device->manufacturer_string, device->product_string, 'h', 0);
|
||||
}
|
||||
|
||||
#ifndef SDL_PLATFORM_EMSCRIPTEN
|
||||
static void HIDAPI_UpdateJoystickSerial(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
int i;
|
||||
|
|
@ -656,6 +657,7 @@ static void HIDAPI_UpdateJoystickSerial(SDL_HIDAPI_Device *device)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool HIDAPI_SerialIsEmpty(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
|
|
@ -675,13 +677,18 @@ static bool HIDAPI_SerialIsEmpty(SDL_HIDAPI_Device *device)
|
|||
|
||||
void HIDAPI_SetDeviceSerial(SDL_HIDAPI_Device *device, const char *serial)
|
||||
{
|
||||
#ifdef SDL_PLATFORM_EMSCRIPTEN
|
||||
// Don't include the serial number for the web to decrease the fingerprinting surface
|
||||
#else
|
||||
if (serial && *serial && (!device->serial || SDL_strcmp(serial, device->serial) != 0)) {
|
||||
SDL_free(device->serial);
|
||||
device->serial = SDL_strdup(serial);
|
||||
HIDAPI_UpdateJoystickSerial(device);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef SDL_PLATFORM_EMSCRIPTEN
|
||||
static int wcstrcmp(const wchar_t *str1, const char *str2)
|
||||
{
|
||||
int result;
|
||||
|
|
@ -696,14 +703,19 @@ static int wcstrcmp(const wchar_t *str1, const char *str2)
|
|||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void HIDAPI_SetDeviceSerialW(SDL_HIDAPI_Device *device, const wchar_t *serial)
|
||||
{
|
||||
#ifdef SDL_PLATFORM_EMSCRIPTEN
|
||||
// Don't include the serial number for the web to decrease the fingerprinting surface
|
||||
#else
|
||||
if (serial && *serial && (!device->serial || wcstrcmp(serial, device->serial) != 0)) {
|
||||
SDL_free(device->serial);
|
||||
device->serial = HIDAPI_ConvertString(serial);
|
||||
HIDAPI_UpdateJoystickSerial(device);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool HIDAPI_HasConnectedUSBDevice(const char *serial)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue