src/hidapi/SDL_hidapi.c
author Sam Lantinga
Sun, 01 Mar 2020 17:53:30 -0800
changeset 13565 7f96440b8e3d
parent 13429 1fa9a405fab3
child 13586 2f5e3f0be62c
permissions -rw-r--r--
We already have a hidapi implementation for Windows, we don't need libusb
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
{
flibitijibibo@12974
   539
#if HAVE_PLATFORM_BACKEND
flibitijibibo@12974
   540
    struct PLATFORM_hid_device_info *raw_devs = NULL;
flibitijibibo@12974
   541
    struct PLATFORM_hid_device_info *raw_dev;
flibitijibibo@12974
   542
#endif /* HAVE_PLATFORM_BACKEND */
flibitijibibo@12974
   543
    struct hid_device_info *devs = NULL, *last = NULL, *new_dev;
flibitijibibo@12974
   544
    SDL_bool bFound;
flibitijibibo@12974
   545
flibitijibibo@12974
   546
    if (SDL_hidapi_wasinit == SDL_FALSE) {
flibitijibibo@12974
   547
        hid_init();
flibitijibibo@12974
   548
    }
flibitijibibo@12974
   549
flibitijibibo@12974
   550
#if HAVE_PLATFORM_BACKEND
flibitijibibo@12974
   551
    if (udev_ctx) {
flibitijibibo@12974
   552
        raw_devs = PLATFORM_hid_enumerate(vendor_id, product_id);
flibitijibibo@12974
   553
    }
flibitijibibo@12974
   554
#endif /* HAVE_PLATFORM_BACKEND */
flibitijibibo@12974
   555
flibitijibibo@12974
   556
#ifdef SDL_LIBUSB_DYNAMIC
flibitijibibo@12974
   557
    if (libusb_ctx.libhandle) {
flibitijibibo@12974
   558
        struct LIBUSB_hid_device_info *usb_devs = LIBUSB_hid_enumerate(vendor_id, product_id);
flibitijibibo@12974
   559
        struct LIBUSB_hid_device_info *usb_dev;
flibitijibibo@12974
   560
        for (usb_dev = usb_devs; usb_dev; usb_dev = usb_dev->next) {
flibitijibibo@12974
   561
            bFound = SDL_FALSE;
flibitijibibo@12974
   562
#if HAVE_PLATFORM_BACKEND
flibitijibibo@12974
   563
            for (raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next) {
slouken@13384
   564
                if (raw_dev->vendor_id == 0x057e && raw_dev->product_id == 0x0337) {
slouken@13384
   565
                    /* The GameCube adapter is handled by the USB HIDAPI driver */
slouken@13384
   566
                    continue;
slouken@13384
   567
                }
flibitijibibo@12974
   568
                if (usb_dev->vendor_id == raw_dev->vendor_id &&
slouken@13350
   569
                    usb_dev->product_id == raw_dev->product_id &&
slouken@13370
   570
                    (raw_dev->interface_number < 0 || usb_dev->interface_number == raw_dev->interface_number)) {
flibitijibibo@12974
   571
                    bFound = SDL_TRUE;
flibitijibibo@12974
   572
                    break;
flibitijibibo@12974
   573
                }
flibitijibibo@12974
   574
            }
flibitijibibo@12974
   575
#endif
flibitijibibo@12974
   576
flibitijibibo@12974
   577
            if (!bFound) {
flibitijibibo@12974
   578
                new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info));
flibitijibibo@12974
   579
                LIBUSB_CopyHIDDeviceInfo(usb_dev, new_dev);
flibitijibibo@12974
   580
flibitijibibo@12974
   581
                if (last != NULL) {
flibitijibibo@12974
   582
                    last->next = new_dev;
flibitijibibo@12974
   583
                } else {
flibitijibibo@12974
   584
                    devs = new_dev;
flibitijibibo@12974
   585
                }
flibitijibibo@12974
   586
                last = new_dev;
flibitijibibo@12974
   587
            }
flibitijibibo@12974
   588
        }
flibitijibibo@12974
   589
        LIBUSB_hid_free_enumeration(usb_devs);
flibitijibibo@12974
   590
    }
flibitijibibo@12974
   591
#endif /* SDL_LIBUSB_DYNAMIC */
flibitijibibo@12974
   592
flibitijibibo@12974
   593
#if HAVE_PLATFORM_BACKEND
flibitijibibo@12974
   594
    if (udev_ctx) {
flibitijibibo@12974
   595
        for (raw_dev = raw_devs; raw_dev; raw_dev = raw_dev->next) {
slouken@13384
   596
            bFound = SDL_FALSE;
slouken@13384
   597
            for (new_dev = devs; new_dev; new_dev = new_dev->next) {
slouken@13384
   598
                if (raw_dev->vendor_id == new_dev->vendor_id &&
slouken@13384
   599
                    raw_dev->product_id == new_dev->product_id &&
slouken@13384
   600
                    raw_dev->interface_number == new_dev->interface_number) {
slouken@13384
   601
                    bFound = SDL_TRUE;
slouken@13384
   602
                    break;
slouken@13384
   603
                }
slouken@13384
   604
            }
flibitijibibo@12974
   605
slouken@13384
   606
            if (!bFound) {
slouken@13384
   607
                new_dev = (struct hid_device_info*) SDL_malloc(sizeof(struct hid_device_info));
slouken@13384
   608
                PLATFORM_CopyHIDDeviceInfo(raw_dev, new_dev);
slouken@13384
   609
                new_dev->next = NULL;
slouken@13384
   610
slouken@13384
   611
                if (last != NULL) {
slouken@13384
   612
                    last->next = new_dev;
slouken@13384
   613
                } else {
slouken@13384
   614
                    devs = new_dev;
slouken@13384
   615
                }
slouken@13384
   616
                last = new_dev;
flibitijibibo@12974
   617
            }
flibitijibibo@12974
   618
        }
flibitijibibo@12974
   619
        PLATFORM_hid_free_enumeration(raw_devs);
flibitijibibo@12974
   620
    }
flibitijibibo@12974
   621
#endif /* HAVE_PLATFORM_BACKEND */
flibitijibibo@12974
   622
flibitijibibo@12974
   623
    return devs;
flibitijibibo@12974
   624
}
flibitijibibo@12974
   625
flibitijibibo@12974
   626
void  HID_API_EXPORT HID_API_CALL hid_free_enumeration(struct hid_device_info *devs)
flibitijibibo@12974
   627
{
flibitijibibo@12974
   628
    while (devs) {
flibitijibibo@12974
   629
        struct hid_device_info *next = devs->next;
flibitijibibo@12974
   630
        SDL_free(devs->path);
flibitijibibo@12974
   631
        SDL_free(devs->serial_number);
flibitijibibo@12974
   632
        SDL_free(devs->manufacturer_string);
flibitijibibo@12974
   633
        SDL_free(devs->product_string);
flibitijibibo@12974
   634
        SDL_free(devs);
flibitijibibo@12974
   635
        devs = next;
flibitijibibo@12974
   636
    }
flibitijibibo@12974
   637
}
flibitijibibo@12974
   638
flibitijibibo@12974
   639
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
   640
{
flibitijibibo@12974
   641
    hid_device *pDevice = NULL;
flibitijibibo@12974
   642
flibitijibibo@12974
   643
    if (SDL_hidapi_wasinit == SDL_FALSE) {
flibitijibibo@12974
   644
        hid_init();
flibitijibibo@12974
   645
    }
flibitijibibo@12974
   646
flibitijibibo@12974
   647
#if HAVE_PLATFORM_BACKEND
flibitijibibo@12974
   648
    if (udev_ctx &&
flibitijibibo@12974
   649
        (pDevice = (hid_device*) PLATFORM_hid_open(vendor_id, product_id, serial_number)) != NULL) {
flibitijibibo@12974
   650
flibitijibibo@12974
   651
        HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend);
flibitijibibo@12974
   652
        return WrapHIDDevice(wrapper);
flibitijibibo@12974
   653
    }
flibitijibibo@12974
   654
#endif /* HAVE_PLATFORM_BACKEND */
flibitijibibo@12974
   655
#ifdef SDL_LIBUSB_DYNAMIC
flibitijibibo@12974
   656
    if (libusb_ctx.libhandle &&
flibitijibibo@12974
   657
        (pDevice = (hid_device*) LIBUSB_hid_open(vendor_id, product_id, serial_number)) != NULL) {
flibitijibibo@12974
   658
flibitijibibo@12974
   659
        HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend);
flibitijibibo@12974
   660
        return WrapHIDDevice(wrapper);
flibitijibibo@12974
   661
    }
flibitijibibo@12974
   662
#endif /* SDL_LIBUSB_DYNAMIC */
flibitijibibo@12974
   663
    return NULL;
flibitijibibo@12974
   664
}
flibitijibibo@12974
   665
flibitijibibo@12974
   666
HID_API_EXPORT hid_device * HID_API_CALL hid_open_path(const char *path, int bExclusive /* = false */)
flibitijibibo@12974
   667
{
flibitijibibo@12974
   668
    hid_device *pDevice = NULL;
flibitijibibo@12974
   669
flibitijibibo@12974
   670
    if (SDL_hidapi_wasinit == SDL_FALSE) {
flibitijibibo@12974
   671
        hid_init();
flibitijibibo@12974
   672
    }
flibitijibibo@12974
   673
flibitijibibo@12974
   674
#if HAVE_PLATFORM_BACKEND
flibitijibibo@12974
   675
    if (udev_ctx &&
flibitijibibo@12974
   676
        (pDevice = (hid_device*) PLATFORM_hid_open_path(path, bExclusive)) != NULL) {
flibitijibibo@12974
   677
flibitijibibo@12974
   678
        HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &PLATFORM_Backend);
flibitijibibo@12974
   679
        return WrapHIDDevice(wrapper);
flibitijibibo@12974
   680
    }
flibitijibibo@12974
   681
#endif /* HAVE_PLATFORM_BACKEND */
flibitijibibo@12974
   682
#ifdef SDL_LIBUSB_DYNAMIC
flibitijibibo@12974
   683
    if (libusb_ctx.libhandle &&
flibitijibibo@12974
   684
        (pDevice = (hid_device*) LIBUSB_hid_open_path(path, bExclusive)) != NULL) {
flibitijibibo@12974
   685
flibitijibibo@12974
   686
        HIDDeviceWrapper *wrapper = CreateHIDDeviceWrapper(pDevice, &LIBUSB_Backend);
flibitijibibo@12974
   687
        return WrapHIDDevice(wrapper);
flibitijibibo@12974
   688
    }
flibitijibibo@12974
   689
#endif /* SDL_LIBUSB_DYNAMIC */
flibitijibibo@12974
   690
    return NULL;
flibitijibibo@12974
   691
}
flibitijibibo@12974
   692
flibitijibibo@12974
   693
int  HID_API_EXPORT HID_API_CALL hid_write(hid_device *device, const unsigned char *data, size_t length)
flibitijibibo@12974
   694
{
flibitijibibo@12974
   695
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   696
    return wrapper->backend->hid_write(wrapper->device, data, length);
flibitijibibo@12974
   697
}
flibitijibibo@12974
   698
flibitijibibo@12974
   699
int HID_API_EXPORT HID_API_CALL hid_read_timeout(hid_device *device, unsigned char *data, size_t length, int milliseconds)
flibitijibibo@12974
   700
{
flibitijibibo@12974
   701
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   702
    return wrapper->backend->hid_read_timeout(wrapper->device, data, length, milliseconds);
flibitijibibo@12974
   703
}
flibitijibibo@12974
   704
flibitijibibo@12974
   705
int  HID_API_EXPORT HID_API_CALL hid_read(hid_device *device, unsigned char *data, size_t length)
flibitijibibo@12974
   706
{
flibitijibibo@12974
   707
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   708
    return wrapper->backend->hid_read(wrapper->device, data, length);
flibitijibibo@12974
   709
}
flibitijibibo@12974
   710
flibitijibibo@12974
   711
int  HID_API_EXPORT HID_API_CALL hid_set_nonblocking(hid_device *device, int nonblock)
flibitijibibo@12974
   712
{
flibitijibibo@12974
   713
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   714
    return wrapper->backend->hid_set_nonblocking(wrapper->device, nonblock);
flibitijibibo@12974
   715
}
flibitijibibo@12974
   716
flibitijibibo@12974
   717
int HID_API_EXPORT HID_API_CALL hid_send_feature_report(hid_device *device, const unsigned char *data, size_t length)
flibitijibibo@12974
   718
{
flibitijibibo@12974
   719
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   720
    return wrapper->backend->hid_send_feature_report(wrapper->device, data, length);
flibitijibibo@12974
   721
}
flibitijibibo@12974
   722
flibitijibibo@12974
   723
int HID_API_EXPORT HID_API_CALL hid_get_feature_report(hid_device *device, unsigned char *data, size_t length)
flibitijibibo@12974
   724
{
flibitijibibo@12974
   725
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   726
    return wrapper->backend->hid_get_feature_report(wrapper->device, data, length);
flibitijibibo@12974
   727
}
flibitijibibo@12974
   728
flibitijibibo@12974
   729
void HID_API_EXPORT HID_API_CALL hid_close(hid_device *device)
flibitijibibo@12974
   730
{
flibitijibibo@12974
   731
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   732
    wrapper->backend->hid_close(wrapper->device);
flibitijibibo@12974
   733
    DeleteHIDDeviceWrapper(wrapper);
flibitijibibo@12974
   734
}
flibitijibibo@12974
   735
flibitijibibo@12974
   736
int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *device, wchar_t *string, size_t maxlen)
flibitijibibo@12974
   737
{
flibitijibibo@12974
   738
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   739
    return wrapper->backend->hid_get_manufacturer_string(wrapper->device, string, maxlen);
flibitijibibo@12974
   740
}
flibitijibibo@12974
   741
flibitijibibo@12974
   742
int HID_API_EXPORT_CALL hid_get_product_string(hid_device *device, wchar_t *string, size_t maxlen)
flibitijibibo@12974
   743
{
flibitijibibo@12974
   744
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   745
    return wrapper->backend->hid_get_product_string(wrapper->device, string, maxlen);
flibitijibibo@12974
   746
}
flibitijibibo@12974
   747
flibitijibibo@12974
   748
int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *device, wchar_t *string, size_t maxlen)
flibitijibibo@12974
   749
{
flibitijibibo@12974
   750
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   751
    return wrapper->backend->hid_get_serial_number_string(wrapper->device, string, maxlen);
flibitijibibo@12974
   752
}
flibitijibibo@12974
   753
flibitijibibo@12974
   754
int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *device, int string_index, wchar_t *string, size_t maxlen)
flibitijibibo@12974
   755
{
flibitijibibo@12974
   756
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   757
    return wrapper->backend->hid_get_indexed_string(wrapper->device, string_index, string, maxlen);
flibitijibibo@12974
   758
}
flibitijibibo@12974
   759
flibitijibibo@12974
   760
HID_API_EXPORT const wchar_t* HID_API_CALL hid_error(hid_device *device)
flibitijibibo@12974
   761
{
flibitijibibo@12974
   762
    HIDDeviceWrapper *wrapper = UnwrapHIDDevice(device);
flibitijibibo@12974
   763
    return wrapper->backend->hid_error(wrapper->device);
flibitijibibo@12974
   764
}
flibitijibibo@12974
   765
flibitijibibo@12974
   766
#endif /* SDL_JOYSTICK_HIDAPI */