src/hidapi/SDL_hidapi.c
author Ryan C. Gordon
Tue, 07 Apr 2020 14:03:13 -0400
changeset 13704 25edf3df6e51
parent 13586 2f5e3f0be62c
child 14352 97ac14655de3
permissions -rw-r--r--
emscripten: support KaiOS's Left Soft Key and Right Soft Key (thanks, pelya!).

Fixes Bugzilla #5027.
flibitijibibo@12974
     1
/*
flibitijibibo@12974
     2
  Simple DirectMedia Layer
slouken@13422
     3
  Copyright (C) 1997-2020 Sam Lantinga <slouken@libsdl.org>
flibitijibibo@12974
     4
flibitijibibo@12974
     5
  This software is provided 'as-is', without any express or implied
flibitijibibo@12974
     6
  warranty.  In no event will the authors be held liable for any damages
flibitijibibo@12974
     7
  arising from the use of this software.
flibitijibibo@12974
     8
flibitijibibo@12974
     9
  Permission is granted to anyone to use this software for any purpose,
flibitijibibo@12974
    10
  including commercial applications, and to alter it and redistribute it
flibitijibibo@12974
    11
  freely, subject to the following restrictions:
flibitijibibo@12974
    12
flibitijibibo@12974
    13
  1. The origin of this software must not be misrepresented; you must not
flibitijibibo@12974
    14
     claim that you wrote the original software. If you use this software
flibitijibibo@12974
    15
     in a product, an acknowledgment in the product documentation would be
flibitijibibo@12974
    16
     appreciated but is not required.
flibitijibibo@12974
    17
  2. Altered source versions must be plainly marked as such, and must not be
flibitijibibo@12974
    18
     misrepresented as being the original software.
flibitijibibo@12974
    19
  3. This notice may not be removed or altered from any source distribution.
flibitijibibo@12974
    20
*/
flibitijibibo@12974
    21
flibitijibibo@12974
    22
/* Original hybrid wrapper for Linux by Valve Software. Their original notes:
flibitijibibo@12974
    23
 *
flibitijibibo@12974
    24
 * The libusb version doesn't support Bluetooth, but not all Linux
flibitijibibo@12974
    25
 * distributions allow access to /dev/hidraw*
flibitijibibo@12974
    26
 *
flibitijibibo@12974
    27
 * This merges the two, at a small performance cost, until distributions
flibitijibibo@12974
    28
 * have granted access to /dev/hidraw*
flibitijibibo@12974
    29
 */
flibitijibibo@12974
    30
flibitijibibo@12974
    31
#include "../SDL_internal.h"
flibitijibibo@12974
    32
#include "SDL_loadso.h"
flibitijibibo@12974
    33
flibitijibibo@12974
    34
#ifdef SDL_JOYSTICK_HIDAPI
flibitijibibo@12974
    35
flibitijibibo@12974
    36
/* Platform HIDAPI Implementation */
flibitijibibo@12974
    37
flibitijibibo@12974
    38
#define hid_device_                     PLATFORM_hid_device_
flibitijibibo@12974
    39
#define hid_device                      PLATFORM_hid_device
flibitijibibo@12974
    40
#define hid_device_info                 PLATFORM_hid_device_info
flibitijibibo@12974
    41
#define hid_init                        PLATFORM_hid_init
flibitijibibo@12974
    42
#define hid_exit                        PLATFORM_hid_exit
flibitijibibo@12974
    43
#define hid_enumerate                   PLATFORM_hid_enumerate
flibitijibibo@12974
    44
#define hid_free_enumeration            PLATFORM_hid_free_enumeration
flibitijibibo@12974
    45
#define hid_open                        PLATFORM_hid_open
flibitijibibo@12974
    46
#define hid_open_path                   PLATFORM_hid_open_path
flibitijibibo@12974
    47
#define hid_write                       PLATFORM_hid_write
flibitijibibo@12974
    48
#define hid_read_timeout                PLATFORM_hid_read_timeout
flibitijibibo@12974
    49
#define hid_read                        PLATFORM_hid_read
flibitijibibo@12974
    50
#define hid_set_nonblocking             PLATFORM_hid_set_nonblocking
flibitijibibo@12974
    51
#define hid_send_feature_report         PLATFORM_hid_send_feature_report
flibitijibibo@12974
    52
#define hid_get_feature_report          PLATFORM_hid_get_feature_report
flibitijibibo@12974
    53
#define hid_close                       PLATFORM_hid_close
flibitijibibo@12974
    54
#define hid_get_manufacturer_string     PLATFORM_hid_get_manufacturer_string
flibitijibibo@12974
    55
#define hid_get_product_string          PLATFORM_hid_get_product_string
flibitijibibo@12974
    56
#define hid_get_serial_number_string    PLATFORM_hid_get_serial_number_string
flibitijibibo@12974
    57
#define hid_get_indexed_string          PLATFORM_hid_get_indexed_string
flibitijibibo@12974
    58
#define hid_error                       PLATFORM_hid_error
flibitijibibo@12974
    59
#define new_hid_device                  PLATFORM_new_hid_device
flibitijibibo@12974
    60
#define free_hid_device                 PLATFORM_free_hid_device
flibitijibibo@12974
    61
#define input_report                    PLATFORM_input_report
flibitijibibo@12974
    62
#define return_data                     PLATFORM_return_data
flibitijibibo@12974
    63
#define make_path                       PLATFORM_make_path
flibitijibibo@12974
    64
#define read_thread                     PLATFORM_read_thread
flibitijibibo@12974
    65
flibitijibibo@12974
    66
#if __LINUX__
flibitijibibo@12974
    67
flibitijibibo@12974
    68
#include "../../core/linux/SDL_udev.h"
flibitijibibo@12974
    69
#if SDL_USE_LIBUDEV
flibitijibibo@12974
    70
static const SDL_UDEV_Symbols *udev_ctx = NULL;
flibitijibibo@12974
    71
flibitijibibo@12974
    72
#define udev_device_get_sysattr_value                    udev_ctx->udev_device_get_sysattr_value
flibitijibibo@12974
    73
#define udev_new                                         udev_ctx->udev_new
flibitijibibo@12974
    74
#define udev_unref                                       udev_ctx->udev_unref
flibitijibibo@12974
    75
#define udev_device_new_from_devnum                      udev_ctx->udev_device_new_from_devnum
flibitijibibo@12974
    76
#define udev_device_get_parent_with_subsystem_devtype    udev_ctx->udev_device_get_parent_with_subsystem_devtype
flibitijibibo@12974
    77
#define udev_device_unref                                udev_ctx->udev_device_unref
flibitijibibo@12974
    78
#define udev_enumerate_new                               udev_ctx->udev_enumerate_new
flibitijibibo@12974
    79
#define udev_enumerate_add_match_subsystem               udev_ctx->udev_enumerate_add_match_subsystem
flibitijibibo@12974
    80
#define udev_enumerate_scan_devices                      udev_ctx->udev_enumerate_scan_devices
flibitijibibo@12974
    81
#define udev_enumerate_get_list_entry                    udev_ctx->udev_enumerate_get_list_entry
flibitijibibo@12974
    82
#define udev_list_entry_get_name                         udev_ctx->udev_list_entry_get_name
flibitijibibo@12974
    83
#define udev_device_new_from_syspath                     udev_ctx->udev_device_new_from_syspath
flibitijibibo@12974
    84
#define udev_device_get_devnode                          udev_ctx->udev_device_get_devnode
flibitijibibo@12974
    85
#define udev_list_entry_get_next                         udev_ctx->udev_list_entry_get_next
flibitijibibo@12974
    86
#define udev_enumerate_unref                             udev_ctx->udev_enumerate_unref
flibitijibibo@12974
    87
flibitijibibo@12974
    88
#include "linux/hid.c"
flibitijibibo@12974
    89
#define HAVE_PLATFORM_BACKEND 1
flibitijibibo@12974
    90
#endif /* SDL_USE_LIBUDEV */
flibitijibibo@12974
    91
flibitijibibo@12974
    92
#elif __MACOSX__
flibitijibibo@12974
    93
#include "mac/hid.c"
flibitijibibo@12974
    94
#define HAVE_PLATFORM_BACKEND 1
flibitijibibo@12974
    95
#define udev_ctx 1
flibitijibibo@12974
    96
#elif __WINDOWS__
flibitijibibo@12974
    97
#include "windows/hid.c"
flibitijibibo@12974
    98
#define HAVE_PLATFORM_BACKEND 1
flibitijibibo@12974
    99
#define udev_ctx 1
flibitijibibo@12974
   100
#else
flibitijibibo@12974
   101
#error Need a hid.c for this platform!
flibitijibibo@12974
   102
#endif
flibitijibibo@12974
   103
flibitijibibo@12974
   104
#undef hid_device_
flibitijibibo@12974
   105
#undef hid_device
flibitijibibo@12974
   106
#undef hid_device_info
flibitijibibo@12974
   107
#undef hid_init
flibitijibibo@12974
   108
#undef hid_exit
flibitijibibo@12974
   109
#undef hid_enumerate
flibitijibibo@12974
   110
#undef hid_free_enumeration
flibitijibibo@12974
   111
#undef hid_open
flibitijibibo@12974
   112
#undef hid_open_path
flibitijibibo@12974
   113
#undef hid_write
flibitijibibo@12974
   114
#undef hid_read_timeout
flibitijibibo@12974
   115
#undef hid_read
flibitijibibo@12974
   116
#undef hid_set_nonblocking
flibitijibibo@12974
   117
#undef hid_send_feature_report
flibitijibibo@12974
   118
#undef hid_get_feature_report
flibitijibibo@12974
   119
#undef hid_close
flibitijibibo@12974
   120
#undef hid_get_manufacturer_string
flibitijibibo@12974
   121
#undef hid_get_product_string
flibitijibibo@12974
   122
#undef hid_get_serial_number_string
flibitijibibo@12974
   123
#undef hid_get_indexed_string
flibitijibibo@12974
   124
#undef hid_error
flibitijibibo@12974
   125
#undef new_hid_device
flibitijibibo@12974
   126
#undef free_hid_device
flibitijibibo@12974
   127
#undef input_report
flibitijibibo@12974
   128
#undef return_data
flibitijibibo@12974
   129
#undef make_path
flibitijibibo@12974
   130
#undef read_thread
flibitijibibo@12974
   131
flibitijibibo@12974
   132
#ifdef SDL_LIBUSB_DYNAMIC
flibitijibibo@12974
   133
/* libusb HIDAPI Implementation */
flibitijibibo@12974
   134
flibitijibibo@12974
   135
/* Include this now, for our dynamically-loaded libusb context */
flibitijibibo@12974
   136
#include <libusb.h>
flibitijibibo@12974
   137
flibitijibibo@12974
   138
static struct
flibitijibibo@12974
   139
{
flibitijibibo@12974
   140
    void* libhandle;
flibitijibibo@12974
   141
flibitijibibo@12974
   142
    int (*init)(libusb_context **ctx);
flibitijibibo@12974
   143
    void (*exit)(libusb_context *ctx);
flibitijibibo@12974
   144
    ssize_t (*get_device_list)(libusb_context *ctx, libusb_device ***list);
flibitijibibo@12974
   145
    void (*free_device_list)(libusb_device **list, int unref_devices);
flibitijibibo@12974
   146
    int (*get_device_descriptor)(libusb_device *dev, struct libusb_device_descriptor *desc);
flibitijibibo@12974
   147
    int (*get_active_config_descriptor)(libusb_device *dev,    struct libusb_config_descriptor **config);
flibitijibibo@12974
   148
    int (*get_config_descriptor)(
flibitijibibo@12974
   149
        libusb_device *dev,
flibitijibibo@12974
   150
        uint8_t config_index,
flibitijibibo@12974
   151
        struct libusb_config_descriptor **config
flibitijibibo@12974
   152
    );
flibitijibibo@12974
   153
    void (*free_config_descriptor)(struct libusb_config_descriptor *config);
flibitijibibo@12974
   154
    uint8_t (*get_bus_number)(libusb_device *dev);
flibitijibibo@12974
   155
    uint8_t (*get_device_address)(libusb_device *dev);
flibitijibibo@12974
   156
    int (*open)(libusb_device *dev, libusb_device_handle **dev_handle);
flibitijibibo@12974
   157
    void (*close)(libusb_device_handle *dev_handle);
flibitijibibo@12974
   158
    int (*claim_interface)(libusb_device_handle *dev_handle, int interface_number);
flibitijibibo@12974
   159
    int (*release_interface)(libusb_device_handle *dev_handle, int interface_number);
flibitijibibo@12974
   160
    int (*kernel_driver_active)(libusb_device_handle *dev_handle, int interface_number);
flibitijibibo@12974
   161
    int (*detach_kernel_driver)(libusb_device_handle *dev_handle, int interface_number);
slouken@13425
   162
    int (*attach_kernel_driver)(libusb_device_handle *dev_handle, int interface_number);
slouken@13419
   163
    int (*set_interface_alt_setting)(libusb_device_handle *dev, int interface_number, int alternate_setting);
flibitijibibo@12974
   164
    struct libusb_transfer * (*alloc_transfer)(int iso_packets);
flibitijibibo@12974
   165
    int (*submit_transfer)(struct libusb_transfer *transfer);
flibitijibibo@12974
   166
    int (*cancel_transfer)(struct libusb_transfer *transfer);
flibitijibibo@12974
   167
    void (*free_transfer)(struct libusb_transfer *transfer);
flibitijibibo@12974
   168
    int (*control_transfer)(
flibitijibibo@12974
   169
        libusb_device_handle *dev_handle,
flibitijibibo@12974
   170
        uint8_t request_type,
flibitijibibo@12974
   171
        uint8_t bRequest,
flibitijibibo@12974
   172
        uint16_t wValue,
flibitijibibo@12974
   173
        uint16_t wIndex,
flibitijibibo@12974
   174
        unsigned char *data,
flibitijibibo@12974
   175
        uint16_t wLength,
flibitijibibo@12974
   176
        unsigned int timeout
flibitijibibo@12974
   177
    );
flibitijibibo@12974
   178
    int (*interrupt_transfer)(
flibitijibibo@12974
   179
        libusb_device_handle *dev_handle,
flibitijibibo@12974
   180
        unsigned char endpoint,
flibitijibibo@12974
   181
        unsigned char *data,
flibitijibibo@12974
   182
        int length,
flibitijibibo@12974
   183
        int *actual_length,
flibitijibibo@12974
   184
        unsigned int timeout
flibitijibibo@12974
   185
    );
flibitijibibo@12974
   186
    int (*handle_events)(libusb_context *ctx);
flibitijibibo@12974
   187
    int (*handle_events_completed)(libusb_context *ctx, int *completed);
flibitijibibo@12974
   188
} libusb_ctx;
flibitijibibo@12974
   189
flibitijibibo@12974
   190
#define libusb_init                            libusb_ctx.init
flibitijibibo@12974
   191
#define libusb_exit                            libusb_ctx.exit
flibitijibibo@12974
   192
#define libusb_get_device_list                 libusb_ctx.get_device_list
flibitijibibo@12974
   193
#define libusb_free_device_list                libusb_ctx.free_device_list
flibitijibibo@12974
   194
#define libusb_get_device_descriptor           libusb_ctx.get_device_descriptor
flibitijibibo@12974
   195
#define libusb_get_active_config_descriptor    libusb_ctx.get_active_config_descriptor
flibitijibibo@12974
   196
#define libusb_get_config_descriptor           libusb_ctx.get_config_descriptor
flibitijibibo@12974
   197
#define libusb_free_config_descriptor          libusb_ctx.free_config_descriptor
flibitijibibo@12974
   198
#define libusb_get_bus_number                  libusb_ctx.get_bus_number
flibitijibibo@12974
   199
#define libusb_get_device_address              libusb_ctx.get_device_address
flibitijibibo@12974
   200
#define libusb_open                            libusb_ctx.open
flibitijibibo@12974
   201
#define libusb_close                           libusb_ctx.close
flibitijibibo@12974
   202
#define libusb_claim_interface                 libusb_ctx.claim_interface
flibitijibibo@12974
   203
#define libusb_release_interface               libusb_ctx.release_interface
flibitijibibo@12974
   204
#define libusb_kernel_driver_active            libusb_ctx.kernel_driver_active
flibitijibibo@12974
   205
#define libusb_detach_kernel_driver            libusb_ctx.detach_kernel_driver
slouken@13425
   206
#define libusb_attach_kernel_driver            libusb_ctx.attach_kernel_driver
slouken@13419
   207
#define libusb_set_interface_alt_setting       libusb_ctx.set_interface_alt_setting
flibitijibibo@12974
   208
#define libusb_alloc_transfer                  libusb_ctx.alloc_transfer
flibitijibibo@12974
   209
#define libusb_submit_transfer                 libusb_ctx.submit_transfer
flibitijibibo@12974
   210
#define libusb_cancel_transfer                 libusb_ctx.cancel_transfer
flibitijibibo@12974
   211
#define libusb_free_transfer                   libusb_ctx.free_transfer
flibitijibibo@12974
   212
#define libusb_control_transfer                libusb_ctx.control_transfer
flibitijibibo@12974
   213
#define libusb_interrupt_transfer              libusb_ctx.interrupt_transfer
flibitijibibo@12974
   214
#define libusb_handle_events                   libusb_ctx.handle_events
flibitijibibo@12974
   215
#define libusb_handle_events_completed         libusb_ctx.handle_events_completed
flibitijibibo@12974
   216
flibitijibibo@12974
   217
#define hid_device_                     LIBUSB_hid_device_
flibitijibibo@12974
   218
#define hid_device                      LIBUSB_hid_device
flibitijibibo@12974
   219
#define hid_device_info                 LIBUSB_hid_device_info
flibitijibibo@12974
   220
#define hid_init                        LIBUSB_hid_init
flibitijibibo@12974
   221
#define hid_exit                        LIBUSB_hid_exit
flibitijibibo@12974
   222
#define hid_enumerate                   LIBUSB_hid_enumerate
flibitijibibo@12974
   223
#define hid_free_enumeration            LIBUSB_hid_free_enumeration
flibitijibibo@12974
   224
#define hid_open                        LIBUSB_hid_open
flibitijibibo@12974
   225
#define hid_open_path                   LIBUSB_hid_open_path
flibitijibibo@12974
   226
#define hid_write                       LIBUSB_hid_write
flibitijibibo@12974
   227
#define hid_read_timeout                LIBUSB_hid_read_timeout
flibitijibibo@12974
   228
#define hid_read                        LIBUSB_hid_read
flibitijibibo@12974
   229
#define hid_set_nonblocking             LIBUSB_hid_set_nonblocking
flibitijibibo@12974
   230
#define hid_send_feature_report         LIBUSB_hid_send_feature_report
flibitijibibo@12974
   231
#define hid_get_feature_report          LIBUSB_hid_get_feature_report
flibitijibibo@12974
   232
#define hid_close                       LIBUSB_hid_close
flibitijibibo@12974
   233
#define hid_get_manufacturer_string     LIBUSB_hid_get_manufacturer_string
flibitijibibo@12974
   234
#define hid_get_product_string          LIBUSB_hid_get_product_string
flibitijibibo@12974
   235
#define hid_get_serial_number_string    LIBUSB_hid_get_serial_number_string
flibitijibibo@12974
   236
#define hid_get_indexed_string          LIBUSB_hid_get_indexed_string
flibitijibibo@12974
   237
#define hid_error                       LIBUSB_hid_error
flibitijibibo@12974
   238
#define new_hid_device                  LIBUSB_new_hid_device
flibitijibibo@12974
   239
#define free_hid_device                 LIBUSB_free_hid_device
flibitijibibo@12974
   240
#define input_report                    LIBUSB_input_report
flibitijibibo@12974
   241
#define return_data                     LIBUSB_return_data
flibitijibibo@12974
   242
#define make_path                       LIBUSB_make_path
flibitijibibo@12974
   243
#define read_thread                     LIBUSB_read_thread
flibitijibibo@12974
   244
flibitijibibo@12974
   245
#ifndef __FreeBSD__
flibitijibibo@12974
   246
/* this is awkwardly inlined, so we need to re-implement it here
flibitijibibo@12974
   247
 * so we can override the libusb_control_transfer call */
flibitijibibo@12974
   248
static int
flibitijibibo@12974
   249
SDL_libusb_get_string_descriptor(libusb_device_handle *dev,
flibitijibibo@12974
   250
                                 uint8_t descriptor_index, uint16_t lang_id,
flibitijibibo@12974
   251
                                 unsigned char *data, int length)
flibitijibibo@12974
   252
{
flibitijibibo@12974
   253
    return libusb_control_transfer(dev,
flibitijibibo@12974
   254
                                   LIBUSB_ENDPOINT_IN | 0x0, /* Endpoint 0 IN */
flibitijibibo@12974
   255
                                   LIBUSB_REQUEST_GET_DESCRIPTOR,
flibitijibibo@12974
   256
                                   (LIBUSB_DT_STRING << 8) | descriptor_index,
flibitijibibo@12974
   257
                                   lang_id,
flibitijibibo@12974
   258
                                   data,
flibitijibibo@12974
   259
                                   (uint16_t) length,
flibitijibibo@12974
   260
                                   1000);
flibitijibibo@12974
   261
}
flibitijibibo@12974
   262
#define libusb_get_string_descriptor SDL_libusb_get_string_descriptor
flibitijibibo@12974
   263
#endif /* __FreeBSD__ */
flibitijibibo@12974
   264
flibitijibibo@12974
   265
#undef HIDAPI_H__
flibitijibibo@12974
   266
#include "libusb/hid.c"
flibitijibibo@12974
   267
flibitijibibo@12974
   268
#undef hid_device_
flibitijibibo@12974
   269
#undef hid_device
flibitijibibo@12974
   270
#undef hid_device_info
flibitijibibo@12974
   271
#undef hid_init
flibitijibibo@12974
   272
#undef hid_exit
flibitijibibo@12974
   273
#undef hid_enumerate
flibitijibibo@12974
   274
#undef hid_free_enumeration
flibitijibibo@12974
   275
#undef hid_open
flibitijibibo@12974
   276
#undef hid_open_path
flibitijibibo@12974
   277
#undef hid_write
flibitijibibo@12974
   278
#undef hid_read_timeout
flibitijibibo@12974
   279
#undef hid_read
flibitijibibo@12974
   280
#undef hid_set_nonblocking
flibitijibibo@12974
   281
#undef hid_send_feature_report
flibitijibibo@12974
   282
#undef hid_get_feature_report
flibitijibibo@12974
   283
#undef hid_close
flibitijibibo@12974
   284
#undef hid_get_manufacturer_string
flibitijibibo@12974
   285
#undef hid_get_product_string
flibitijibibo@12974
   286
#undef hid_get_serial_number_string
flibitijibibo@12974
   287
#undef hid_get_indexed_string
flibitijibibo@12974
   288
#undef hid_error
flibitijibibo@12974
   289
#undef new_hid_device
flibitijibibo@12974
   290
#undef free_hid_device
flibitijibibo@12974
   291
#undef input_report
flibitijibibo@12974
   292
#undef return_data
flibitijibibo@12974
   293
#undef make_path
flibitijibibo@12974
   294
#undef read_thread
flibitijibibo@12974
   295
flibitijibibo@12974
   296
#endif /* SDL_LIBUSB_DYNAMIC */
flibitijibibo@12974
   297
flibitijibibo@12974
   298
/* Shared HIDAPI Implementation */
flibitijibibo@12974
   299
flibitijibibo@12974
   300
#undef HIDAPI_H__
flibitijibibo@12974
   301
#include "hidapi.h"
flibitijibibo@12974
   302
flibitijibibo@12974
   303
struct hidapi_backend {
flibitijibibo@12974
   304
#define F(x) typeof(x) *x
flibitijibibo@12974
   305
    F(hid_write);
flibitijibibo@12974
   306
    F(hid_read_timeout);
flibitijibibo@12974
   307
    F(hid_read);
flibitijibibo@12974
   308
    F(hid_set_nonblocking);
flibitijibibo@12974
   309
    F(hid_send_feature_report);
flibitijibibo@12974
   310
    F(hid_get_feature_report);
flibitijibibo@12974
   311
    F(hid_close);
flibitijibibo@12974
   312
    F(hid_get_manufacturer_string);
flibitijibibo@12974
   313
    F(hid_get_product_string);
flibitijibibo@12974
   314
    F(hid_get_serial_number_string);
flibitijibibo@12974
   315
    F(hid_get_indexed_string);
flibitijibibo@12974
   316
    F(hid_error);
flibitijibibo@12974
   317
#undef F
flibitijibibo@12974
   318
};
flibitijibibo@12974
   319
flibitijibibo@12974
   320
#if HAVE_PLATFORM_BACKEND
flibitijibibo@12974
   321
static const struct hidapi_backend PLATFORM_Backend = {
flibitijibibo@12974
   322
    (void*)PLATFORM_hid_write,
flibitijibibo@12974
   323
    (void*)PLATFORM_hid_read_timeout,
flibitijibibo@12974
   324
    (void*)PLATFORM_hid_read,
flibitijibibo@12974
   325
    (void*)PLATFORM_hid_set_nonblocking,
flibitijibibo@12974
   326
    (void*)PLATFORM_hid_send_feature_report,
flibitijibibo@12974
   327
    (void*)PLATFORM_hid_get_feature_report,
flibitijibibo@12974
   328
    (void*)PLATFORM_hid_close,
flibitijibibo@12974
   329
    (void*)PLATFORM_hid_get_manufacturer_string,
flibitijibibo@12974
   330
    (void*)PLATFORM_hid_get_product_string,
flibitijibibo@12974
   331
    (void*)PLATFORM_hid_get_serial_number_string,
flibitijibibo@12974
   332
    (void*)PLATFORM_hid_get_indexed_string,
flibitijibibo@12974
   333
    (void*)PLATFORM_hid_error
flibitijibibo@12974
   334
};
flibitijibibo@12974
   335
#endif /* HAVE_PLATFORM_BACKEND */
flibitijibibo@12974
   336
flibitijibibo@12974
   337
#ifdef SDL_LIBUSB_DYNAMIC
flibitijibibo@12974
   338
static const struct hidapi_backend LIBUSB_Backend = {
flibitijibibo@12974
   339
    (void*)LIBUSB_hid_write,
flibitijibibo@12974
   340
    (void*)LIBUSB_hid_read_timeout,
flibitijibibo@12974
   341
    (void*)LIBUSB_hid_read,
flibitijibibo@12974
   342
    (void*)LIBUSB_hid_set_nonblocking,
flibitijibibo@12974
   343
    (void*)LIBUSB_hid_send_feature_report,
flibitijibibo@12974
   344
    (void*)LIBUSB_hid_get_feature_report,
flibitijibibo@12974
   345
    (void*)LIBUSB_hid_close,
flibitijibibo@12974
   346
    (void*)LIBUSB_hid_get_manufacturer_string,
flibitijibibo@12974
   347
    (void*)LIBUSB_hid_get_product_string,
flibitijibibo@12974
   348
    (void*)LIBUSB_hid_get_serial_number_string,
flibitijibibo@12974
   349
    (void*)LIBUSB_hid_get_indexed_string,
flibitijibibo@12974
   350
    (void*)LIBUSB_hid_error
flibitijibibo@12974
   351
};
flibitijibibo@12974
   352
#endif /* SDL_LIBUSB_DYNAMIC */
flibitijibibo@12974
   353
flibitijibibo@12974
   354
typedef struct _HIDDeviceWrapper HIDDeviceWrapper;
flibitijibibo@12974
   355
struct _HIDDeviceWrapper
flibitijibibo@12974
   356
{
flibitijibibo@12974
   357
    hid_device *device; /* must be first field */
flibitijibibo@12974
   358
    const struct hidapi_backend *backend;
flibitijibibo@12974
   359
};
flibitijibibo@12974
   360
flibitijibibo@12974
   361
static HIDDeviceWrapper *
flibitijibibo@12974
   362
CreateHIDDeviceWrapper(hid_device *device, const struct hidapi_backend *backend)
flibitijibibo@12974
   363
{
flibitijibibo@12974
   364
    HIDDeviceWrapper *ret = SDL_malloc(sizeof(*ret));
flibitijibibo@12974
   365
    ret->device = device;
flibitijibibo@12974
   366
    ret->backend = backend;
flibitijibibo@12974
   367
    return ret;
flibitijibibo@12974
   368
}
flibitijibibo@12974
   369
flibitijibibo@12974
   370
static hid_device *
flibitijibibo@12974
   371
WrapHIDDevice(HIDDeviceWrapper *wrapper)
flibitijibibo@12974
   372
{
flibitijibibo@12974
   373
    return (hid_device *)wrapper;
flibitijibibo@12974
   374
}
flibitijibibo@12974
   375
flibitijibibo@12974
   376
static HIDDeviceWrapper *
flibitijibibo@12974
   377
UnwrapHIDDevice(hid_device *device)
flibitijibibo@12974
   378
{
flibitijibibo@12974
   379
    return (HIDDeviceWrapper *)device;
flibitijibibo@12974
   380
}
flibitijibibo@12974
   381
flibitijibibo@12974
   382
static void
flibitijibibo@12974
   383
DeleteHIDDeviceWrapper(HIDDeviceWrapper *device)
flibitijibibo@12974
   384
{
flibitijibibo@12974
   385
    SDL_free(device);
flibitijibibo@12974
   386
}
flibitijibibo@12974
   387
flibitijibibo@12974
   388
#define COPY_IF_EXISTS(var) \
flibitijibibo@12974
   389
    if (pSrc->var != NULL) { \
flibitijibibo@12974
   390
        pDst->var = SDL_strdup(pSrc->var); \
flibitijibibo@12974
   391
    } else { \
flibitijibibo@12974
   392
        pDst->var = NULL; \
flibitijibibo@12974
   393
    }
flibitijibibo@12974
   394
#define WCOPY_IF_EXISTS(var) \
flibitijibibo@12974
   395
    if (pSrc->var != NULL) { \
flibitijibibo@12974
   396
        pDst->var = SDL_wcsdup(pSrc->var); \
flibitijibibo@12974
   397
    } else { \
flibitijibibo@12974
   398
        pDst->var = NULL; \
flibitijibibo@12974
   399
    }
flibitijibibo@12974
   400
flibitijibibo@12974
   401
#ifdef SDL_LIBUSB_DYNAMIC
flibitijibibo@12974
   402
static void
flibitijibibo@12974
   403
LIBUSB_CopyHIDDeviceInfo(struct LIBUSB_hid_device_info *pSrc,
flibitijibibo@12974
   404
                         struct hid_device_info *pDst)
flibitijibibo@12974
   405
{
flibitijibibo@12974
   406
    COPY_IF_EXISTS(path)
flibitijibibo@12974
   407
    pDst->vendor_id = pSrc->vendor_id;
flibitijibibo@12974
   408
    pDst->product_id = pSrc->product_id;
flibitijibibo@12974
   409
    WCOPY_IF_EXISTS(serial_number)
flibitijibibo@12974
   410
    pDst->release_number = pSrc->release_number;
flibitijibibo@12974
   411
    WCOPY_IF_EXISTS(manufacturer_string)
flibitijibibo@12974
   412
    WCOPY_IF_EXISTS(product_string)
flibitijibibo@12974
   413
    pDst->usage_page = pSrc->usage_page;
flibitijibibo@12974
   414
    pDst->usage = pSrc->usage;
flibitijibibo@12974
   415
    pDst->interface_number = pSrc->interface_number;
slouken@13429
   416
    pDst->interface_class = pSrc->interface_class;
slouken@13429
   417
    pDst->interface_subclass = pSrc->interface_subclass;
slouken@13429
   418
    pDst->interface_protocol = pSrc->interface_protocol;
flibitijibibo@12974
   419
    pDst->next = NULL;
flibitijibibo@12974
   420
}
flibitijibibo@12974
   421
#endif /* SDL_LIBUSB_DYNAMIC */
flibitijibibo@12974
   422
flibitijibibo@12974
   423
#if HAVE_PLATFORM_BACKEND
flibitijibibo@12974
   424
static void
flibitijibibo@12974
   425
PLATFORM_CopyHIDDeviceInfo(struct PLATFORM_hid_device_info *pSrc,
flibitijibibo@12974
   426
                           struct hid_device_info *pDst)
flibitijibibo@12974
   427
{
flibitijibibo@12974
   428
    COPY_IF_EXISTS(path)
flibitijibibo@12974
   429
    pDst->vendor_id = pSrc->vendor_id;
flibitijibibo@12974
   430
    pDst->product_id = pSrc->product_id;
flibitijibibo@12974
   431
    WCOPY_IF_EXISTS(serial_number)
flibitijibibo@12974
   432
    pDst->release_number = pSrc->release_number;
flibitijibibo@12974
   433
    WCOPY_IF_EXISTS(manufacturer_string)
flibitijibibo@12974
   434
    WCOPY_IF_EXISTS(product_string)
flibitijibibo@12974
   435
    pDst->usage_page = pSrc->usage_page;
flibitijibibo@12974
   436
    pDst->usage = pSrc->usage;
flibitijibibo@12974
   437
    pDst->interface_number = pSrc->interface_number;
slouken@13429
   438
    pDst->interface_class = pSrc->interface_class;
slouken@13429
   439
    pDst->interface_subclass = pSrc->interface_subclass;
slouken@13429
   440
    pDst->interface_protocol = pSrc->interface_protocol;
flibitijibibo@12974
   441
    pDst->next = NULL;
flibitijibibo@12974
   442
}
flibitijibibo@12974
   443
#endif /* HAVE_PLATFORM_BACKEND */
flibitijibibo@12974
   444
flibitijibibo@12974
   445
#undef COPY_IF_EXISTS
flibitijibibo@12974
   446
#undef WCOPY_IF_EXISTS
flibitijibibo@12974
   447
flibitijibibo@12974
   448
static SDL_bool SDL_hidapi_wasinit = SDL_FALSE;
flibitijibibo@12974
   449
flibitijibibo@12974
   450
int HID_API_EXPORT HID_API_CALL hid_init(void)
flibitijibibo@12974
   451
{
flibitijibibo@12974
   452
    int err;
flibitijibibo@12974
   453
flibitijibibo@12974
   454
    if (SDL_hidapi_wasinit == SDL_TRUE) {
flibitijibibo@12974
   455
        return 0;
flibitijibibo@12974
   456
    }
flibitijibibo@12974
   457
flibitijibibo@12974
   458
#ifdef SDL_LIBUSB_DYNAMIC
flibitijibibo@12974
   459
    libusb_ctx.libhandle = SDL_LoadObject(SDL_LIBUSB_DYNAMIC);
flibitijibibo@12974
   460
    if (libusb_ctx.libhandle != NULL) {
flibitijibibo@12974
   461
        #define LOAD_LIBUSB_SYMBOL(func) \
flibitijibibo@12974
   462
            libusb_ctx.func = SDL_LoadFunction(libusb_ctx.libhandle, "libusb_" #func);
flibitijibibo@12974
   463
        LOAD_LIBUSB_SYMBOL(init)
flibitijibibo@12974
   464
        LOAD_LIBUSB_SYMBOL(exit)
flibitijibibo@12974
   465
        LOAD_LIBUSB_SYMBOL(get_device_list)
flibitijibibo@12974
   466
        LOAD_LIBUSB_SYMBOL(free_device_list)
flibitijibibo@12974
   467
        LOAD_LIBUSB_SYMBOL(get_device_descriptor)
flibitijibibo@12974
   468
        LOAD_LIBUSB_SYMBOL(get_active_config_descriptor)
flibitijibibo@12974
   469
        LOAD_LIBUSB_SYMBOL(get_config_descriptor)
flibitijibibo@12974
   470
        LOAD_LIBUSB_SYMBOL(free_config_descriptor)
flibitijibibo@12974
   471
        LOAD_LIBUSB_SYMBOL(get_bus_number)
flibitijibibo@12974
   472
        LOAD_LIBUSB_SYMBOL(get_device_address)
flibitijibibo@12974
   473
        LOAD_LIBUSB_SYMBOL(open)
flibitijibibo@12974
   474
        LOAD_LIBUSB_SYMBOL(close)
flibitijibibo@12974
   475
        LOAD_LIBUSB_SYMBOL(claim_interface)
flibitijibibo@12974
   476
        LOAD_LIBUSB_SYMBOL(release_interface)
flibitijibibo@12974
   477
        LOAD_LIBUSB_SYMBOL(kernel_driver_active)
flibitijibibo@12974
   478
        LOAD_LIBUSB_SYMBOL(detach_kernel_driver)
slouken@13425
   479
        LOAD_LIBUSB_SYMBOL(attach_kernel_driver)
slouken@13419
   480
        LOAD_LIBUSB_SYMBOL(set_interface_alt_setting)
flibitijibibo@12974
   481
        LOAD_LIBUSB_SYMBOL(alloc_transfer)
flibitijibibo@12974
   482
        LOAD_LIBUSB_SYMBOL(submit_transfer)
flibitijibibo@12974
   483
        LOAD_LIBUSB_SYMBOL(cancel_transfer)
flibitijibibo@12974
   484
        LOAD_LIBUSB_SYMBOL(free_transfer)
flibitijibibo@12974
   485
        LOAD_LIBUSB_SYMBOL(control_transfer)
flibitijibibo@12974
   486
        LOAD_LIBUSB_SYMBOL(interrupt_transfer)
flibitijibibo@12974
   487
        LOAD_LIBUSB_SYMBOL(handle_events)
flibitijibibo@12974
   488
        LOAD_LIBUSB_SYMBOL(handle_events_completed)
flibitijibibo@12974
   489
        #undef LOAD_LIBUSB_SYMBOL
flibitijibibo@12974
   490
flibitijibibo@12974
   491
        if ((err = LIBUSB_hid_init()) < 0) {
flibitijibibo@12974
   492
            SDL_UnloadObject(libusb_ctx.libhandle);
flibitijibibo@12974
   493
            return err;
flibitijibibo@12974
   494
        }
flibitijibibo@12974
   495
    }
flibitijibibo@12974
   496
#endif /* SDL_LIBUSB_DYNAMIC */
flibitijibibo@12974
   497
flibitijibibo@12974
   498
#if HAVE_PLATFORM_BACKEND
flibitijibibo@12974
   499
#if __LINUX__
flibitijibibo@12974
   500
    udev_ctx = SDL_UDEV_GetUdevSyms();
flibitijibibo@12974
   501
#endif /* __LINUX __ */
flibitijibibo@12974
   502
    if (udev_ctx && (err = PLATFORM_hid_init()) < 0) {
flibitijibibo@12974
   503
#ifdef SDL_LIBUSB_DYNAMIC
flibitijibibo@12974
   504
        if (libusb_ctx.libhandle) {
flibitijibibo@12974
   505
            SDL_UnloadObject(libusb_ctx.libhandle);
flibitijibibo@12974
   506
        }
flibitijibibo@12974
   507
#endif /* SDL_LIBUSB_DYNAMIC */
flibitijibibo@12974
   508
        return err;
flibitijibibo@12974
   509
    }
flibitijibibo@12974
   510
#endif /* HAVE_PLATFORM_BACKEND */
flibitijibibo@12974
   511
flibitijibibo@12974
   512
    return 0;
flibitijibibo@12974
   513
}
flibitijibibo@12974
   514
flibitijibibo@12974
   515
int HID_API_EXPORT HID_API_CALL hid_exit(void)
flibitijibibo@12974
   516
{
flibitijibibo@12974
   517
    int err = 0;
flibitijibibo@12974
   518
flibitijibibo@12974
   519
    if (SDL_hidapi_wasinit == SDL_FALSE) {
flibitijibibo@12974
   520
        return 0;
flibitijibibo@12974
   521
    }
flibitijibibo@12974
   522
flibitijibibo@12974
   523
#if HAVE_PLATFORM_BACKEND
flibitijibibo@12974
   524
    if (udev_ctx) {
flibitijibibo@12974
   525
        err = PLATFORM_hid_exit();
flibitijibibo@12974
   526
    }
flibitijibibo@12974
   527
#endif /* HAVE_PLATFORM_BACKEND */
flibitijibibo@12974
   528
#ifdef SDL_LIBUSB_DYNAMIC
flibitijibibo@12974
   529
    if (libusb_ctx.libhandle) {
flibitijibibo@12974
   530
        err |= LIBUSB_hid_exit(); /* Ehhhhh */
flibitijibibo@12974
   531
        SDL_UnloadObject(libusb_ctx.libhandle);
flibitijibibo@12974
   532
    }
flibitijibibo@12974
   533
#endif /* SDL_LIBUSB_DYNAMIC */
flibitijibibo@12974
   534
    return err;
flibitijibibo@12974
   535
}
flibitijibibo@12974
   536
flibitijibibo@12974
   537
struct hid_device_info HID_API_EXPORT * HID_API_CALL hid_enumerate(unsigned short vendor_id, unsigned short product_id)
flibitijibibo@12974
   538
{
slouken@13586
   539
#ifdef SDL_LIBUSB_DYNAMIC
slouken@13586
   540
    struct LIBUSB_hid_device_info *usb_devs = NULL;
slouken@13586
   541
    struct LIBUSB_hid_device_info *usb_dev;
slouken@13586
   542
#endif
flibitijibibo@12974
   543
#if HAVE_PLATFORM_BACKEND
flibitijibibo@12974
   544
    struct PLATFORM_hid_device_info *raw_devs = NULL;
flibitijibibo@12974
   545
    struct PLATFORM_hid_device_info *raw_dev;
slouken@13586
   546
#endif
flibitijibibo@12974
   547
    struct hid_device_info *devs = NULL, *last = NULL, *new_dev;
flibitijibibo@12974
   548
flibitijibibo@12974
   549
    if (SDL_hidapi_wasinit == SDL_FALSE) {
flibitijibibo@12974
   550
        hid_init();
flibitijibibo@12974
   551
    }
flibitijibibo@12974
   552
slouken@13586
   553
#ifdef SDL_LIBUSB_DYNAMIC
slouken@13586
   554
    if (libusb_ctx.libhandle) {
slouken@13586
   555
        usb_devs = LIBUSB_hid_enumerate(vendor_id, product_id);
slouken@13586
   556
        for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) {
slouken@13586
   557
            new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info));
slouken@13586
   558
            LIBUSB_CopyHIDDeviceInfo(usb_dev, new_dev);
slouken@13586
   559
slouken@13586
   560
            if (last != NULL) {
slouken@13586
   561
                last->next = new_dev;
slouken@13586
   562
            } else {
slouken@13586
   563
                devs = new_dev;
slouken@13586
   564
            }
slouken@13586
   565
            last = new_dev;
slouken@13586
   566
        }
slouken@13586
   567
    }
slouken@13586
   568
#endif /* SDL_LIBUSB_DYNAMIC */
slouken@13586
   569
flibitijibibo@12974
   570
#if HAVE_PLATFORM_BACKEND
flibitijibibo@12974
   571
    if (udev_ctx) {
flibitijibibo@12974
   572
        raw_devs = PLATFORM_hid_enumerate(vendor_id, product_id);
slouken@13586
   573
        for (raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next) {
slouken@13586
   574
            SDL_bool bFound = SDL_FALSE;
flibitijibibo@12974
   575
#ifdef SDL_LIBUSB_DYNAMIC
slouken@13586
   576
            for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) {
slouken@13586
   577
                if (raw_dev->vendor_id == usb_dev->vendor_id &&
slouken@13586
   578
                    raw_dev->product_id == usb_dev->product_id &&
slouken@13586
   579
                    (raw_dev->interface_number < 0 || raw_dev->interface_number == usb_dev->interface_number)) {
flibitijibibo@12974
   580
                    bFound = SDL_TRUE;
flibitijibibo@12974
   581
                    break;
flibitijibibo@12974
   582
                }
flibitijibibo@12974
   583
            }
flibitijibibo@12974
   584
#endif
slouken@13384
   585
            if (!bFound) {
slouken@13384
   586
                new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info));
slouken@13384
   587
                PLATFORM_CopyHIDDeviceInfo(raw_dev, new_dev);
slouken@13384
   588
                new_dev->next = NULL;
slouken@13384
   589
slouken@13384
   590
                if (last != NULL) {
slouken@13384
   591
                    last->next = new_dev;
slouken@13384
   592
                } else {
slouken@13384
   593
                    devs = new_dev;
slouken@13384
   594
                }
slouken@13384
   595
                last = new_dev;
flibitijibibo@12974
   596
            }
flibitijibibo@12974
   597
        }
flibitijibibo@12974
   598
        PLATFORM_hid_free_enumeration(raw_devs);
flibitijibibo@12974
   599
    }
flibitijibibo@12974
   600
#endif /* HAVE_PLATFORM_BACKEND */
flibitijibibo@12974
   601
slouken@13586
   602
#ifdef SDL_LIBUSB_DYNAMIC
slouken@13586
   603
    if (libusb_ctx.libhandle) {
slouken@13586
   604
        LIBUSB_hid_free_enumeration(usb_devs);
slouken@13586
   605
    }
slouken@13586
   606
#endif
flibitijibibo@12974
   607
    return devs;
flibitijibibo@12974
   608
}
flibitijibibo@12974
   609
flibitijibibo@12974
   610
void  HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
flibitijibibo@12974
   611
{
flibitijibibo@12974
   612
    while (devs) {
flibitijibibo@12974
   613
        struct hid_device_info *next = devs->next;
flibitijibibo@12974
   614
        SDL_free(devs->path);
flibitijibibo@12974
   615
        SDL_free(devs->serial_number);
flibitijibibo@12974
   616
        SDL_free(devs->manufacturer_string);
flibitijibibo@12974
   617
        SDL_free(devs->product_string);
flibitijibibo@12974
   618
        SDL_free(devs);
flibitijibibo@12974
   619
        devs = next;
flibitijibibo@12974
   620
    }
flibitijibibo@12974
   621
}
flibitijibibo@12974
   622
flibitijibibo@12974
   623
HID_API_EXPORT hid_device * HID_API_CALL hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
flibitijibibo@12974
   624
{
flibitijibibo@12974
   625
    hid_device *pDevice = NULL;
flibitijibibo@12974
   626
flibitijibibo@12974
   627
    if (SDL_hidapi_wasinit == SDL_FALSE) {
flibitijibibo@12974
   628
        hid_init();
flibitijibibo@12974
   629
    }
flibitijibibo@12974
   630
flibitijibibo@12974
   631
#if HAVE_PLATFORM_BACKEND
flibitijibibo@12974
   632
    if (udev_ctx &&
flibitijibibo@12974
   633
        (pDevice = (hid_device*) PLATFORM_hid_open(vendor_id, product_id, serial_number)) != NULL) {
flibitijibibo@12974
   634
flibitijibibo@12974
   635
        HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend);
flibitijibibo@12974
   636
        return WrapHIDDevice(wrapper);
flibitijibibo@12974
   637
    }
flibitijibibo@12974
   638
#endif /* HAVE_PLATFORM_BACKEND */
flibitijibibo@12974
   639
#ifdef SDL_LIBUSB_DYNAMIC
flibitijibibo@12974
   640
    if (libusb_ctx.libhandle &&
flibitijibibo@12974
   641
        (pDevice = (hid_device*) LIBUSB_hid_open(vendor_id, product_id, serial_number)) != NULL) {
flibitijibibo@12974
   642
flibitijibibo@12974
   643
        HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend);
flibitijibibo@12974
   644
        return WrapHIDDevice(wrapper);
flibitijibibo@12974
   645
    }
flibitijibibo@12974
   646
#endif /* SDL_LIBUSB_DYNAMIC */
flibitijibibo@12974
   647
    return NULL;
flibitijibibo@12974
   648
}
flibitijibibo@12974
   649
flibitijibibo@12974
   650
HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bExclusive /* = false */)
flibitijibibo@12974
   651
{
flibitijibibo@12974
   652
    hid_device *pDevice = NULL;
flibitijibibo@12974
   653
flibitijibibo@12974
   654
    if (SDL_hidapi_wasinit == SDL_FALSE) {
flibitijibibo@12974
   655
        hid_init();
flibitijibibo@12974
   656
    }
flibitijibibo@12974
   657
flibitijibibo@12974
   658
#if HAVE_PLATFORM_BACKEND
flibitijibibo@12974
   659
    if (udev_ctx &&
flibitijibibo@12974
   660
        (pDevice = (hid_device*) PLATFORM_hid_open_path(path, bExclusive)) != NULL) {
flibitijibibo@12974
   661
flibitijibibo@12974
   662
        HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend);
flibitijibibo@12974
   663
        return WrapHIDDevice(wrapper);
flibitijibibo@12974
   664
    }
flibitijibibo@12974
   665
#endif /* HAVE_PLATFORM_BACKEND */
flibitijibibo@12974
   666
#ifdef SDL_LIBUSB_DYNAMIC
flibitijibibo@12974
   667
    if (libusb_ctx.libhandle &&
flibitijibibo@12974
   668
        (pDevice = (hid_device*) LIBUSB_hid_open_path(path, bExclusive)) != NULL) {
flibitijibibo@12974
   669
flibitijibibo@12974
   670
        HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend);
flibitijibibo@12974
   671
        return WrapHIDDevice(wrapper);
flibitijibibo@12974
   672
    }
flibitijibibo@12974
   673
#endif /* SDL_LIBUSB_DYNAMIC */
flibitijibibo@12974
   674
    return NULL;
flibitijibibo@12974
   675
}
flibitijibibo@12974
   676
flibitijibibo@12974
   677
int  HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length)
flibitijibibo@12974
   678
{
flibitijibibo@12974
   679
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   680
    return wrapper->backend->hid_write(wrapper->device, data, length);
flibitijibibo@12974
   681
}
flibitijibibo@12974
   682
flibitijibibo@12974
   683
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds)
flibitijibibo@12974
   684
{
flibitijibibo@12974
   685
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   686
    return wrapper->backend->hid_read_timeout(wrapper->device, data, length, milliseconds);
flibitijibibo@12974
   687
}
flibitijibibo@12974
   688
flibitijibibo@12974
   689
int  HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length)
flibitijibibo@12974
   690
{
flibitijibibo@12974
   691
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   692
    return wrapper->backend->hid_read(wrapper->device, data, length);
flibitijibibo@12974
   693
}
flibitijibibo@12974
   694
flibitijibibo@12974
   695
int  HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock)
flibitijibibo@12974
   696
{
flibitijibibo@12974
   697
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   698
    return wrapper->backend->hid_set_nonblocking(wrapper->device, nonblock);
flibitijibibo@12974
   699
}
flibitijibibo@12974
   700
flibitijibibo@12974
   701
int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length)
flibitijibibo@12974
   702
{
flibitijibibo@12974
   703
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   704
    return wrapper->backend->hid_send_feature_report(wrapper->device, data, length);
flibitijibibo@12974
   705
}
flibitijibibo@12974
   706
flibitijibibo@12974
   707
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length)
flibitijibibo@12974
   708
{
flibitijibibo@12974
   709
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   710
    return wrapper->backend->hid_get_feature_report(wrapper->device, data, length);
flibitijibibo@12974
   711
}
flibitijibibo@12974
   712
flibitijibibo@12974
   713
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device)
flibitijibibo@12974
   714
{
flibitijibibo@12974
   715
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   716
    wrapper->backend->hid_close(wrapper->device);
flibitijibibo@12974
   717
    DeleteHIDDeviceWrapper(wrapper);
flibitijibibo@12974
   718
}
flibitijibibo@12974
   719
flibitijibibo@12974
   720
int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen)
flibitijibibo@12974
   721
{
flibitijibibo@12974
   722
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   723
    return wrapper->backend->hid_get_manufacturer_string(wrapper->device, string, maxlen);
flibitijibibo@12974
   724
}
flibitijibibo@12974
   725
flibitijibibo@12974
   726
int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen)
flibitijibibo@12974
   727
{
flibitijibibo@12974
   728
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   729
    return wrapper->backend->hid_get_product_string(wrapper->device, string, maxlen);
flibitijibibo@12974
   730
}
flibitijibibo@12974
   731
flibitijibibo@12974
   732
int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen)
flibitijibibo@12974
   733
{
flibitijibibo@12974
   734
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   735
    return wrapper->backend->hid_get_serial_number_string(wrapper->device, string, maxlen);
flibitijibibo@12974
   736
}
flibitijibibo@12974
   737
flibitijibibo@12974
   738
int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen)
flibitijibibo@12974
   739
{
flibitijibibo@12974
   740
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   741
    return wrapper->backend->hid_get_indexed_string(wrapper->device, string_index, string, maxlen);
flibitijibibo@12974
   742
}
flibitijibibo@12974
   743
flibitijibibo@12974
   744
HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device)
flibitijibibo@12974
   745
{
flibitijibibo@12974
   746
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   747
    return wrapper->backend->hid_error(wrapper->device);
flibitijibibo@12974
   748
}
flibitijibibo@12974
   749
flibitijibibo@12974
   750
#endif /* SDL_JOYSTICK_HIDAPI */
slouken@13586
   751
slouken@13586
   752
/* vi: set sts=4 ts=4 sw=4 expandtab: */