/*
  Simple DirectMedia Layer
  Copyright (C) 2019 Sam Lantinga <slouken@libsdl.org>

  This software is provided 'as-is', without any express or implied
  warranty.  In no event will the authors be held liable for any damages
  arising from the use of this software.

  Permission is granted to anyone to use this software for any purpose,
  including commercial applications, and to alter it and redistribute it
  freely, subject to the following restrictions:

  1. The origin of this software must not be misrepresented; you must not
     claim that you wrote the original software. If you use this software
     in a product, an acknowledgment in the product documentation would be
     appreciated but is not required.
  2. Altered source versions must be plainly marked as such, and must not be
     misrepresented as being the original software.
  3. This notice may not be removed or altered from any source distribution.

*/
/*
  RAWINPUT Joystick API for better handling XInput-capable devices on Windows.

  XInput is limited to 4 devices.
  Windows.Gaming.Input does not get inputs from XBox One controllers when not in the foreground.
  DirectInput does not get inputs from XBox One controllers when not in the foreground, nor rumble or accurate triggers.
  RawInput does not get rumble or accurate triggers.

  So, combine them as best we can!
*/
#include "../../SDL_internal.h"

#if SDL_JOYSTICK_RAWINPUT

#include "SDL_assert.h"
#include "SDL_endian.h"
#include "SDL_hints.h"
#include "SDL_log.h"
#include "SDL_mutex.h"
#include "../SDL_sysjoystick.h"
#include "../../core/windows/SDL_windows.h"
#include "../hidapi/SDL_hidapijoystick_c.h"

#ifndef SDL_JOYSTICK_HIDAPI_XBOX360
#error RAWINPUT requires the XBOX360 HIDAPI driver
#endif

#ifndef RIDEV_EXINPUTSINK
#define RIDEV_EXINPUTSINK       0x00001000
#define RIDEV_DEVNOTIFY         0x00002000
#endif

#ifndef WM_INPUT_DEVICE_CHANGE
#define WM_INPUT_DEVICE_CHANGE          0x00FE
#endif
#ifndef WM_INPUT
#define WM_INPUT                        0x00FF
#endif
#ifndef GIDC_ARRIVAL
#define GIDC_ARRIVAL             1
#define GIDC_REMOVAL             2
#endif


/* #define DEBUG_RAWINPUT */

#define USB_PACKET_LENGTH   64

#define SDL_callocStruct(type) (type *)SDL_calloc(1, sizeof(type))
#define SDL_callocStructs(type, count) (type *)SDL_calloc((count), sizeof(type))

#define USAGE_PAGE_GENERIC_DESKTOP 0x0001
#define USAGE_JOYSTICK 0x0004
#define USAGE_GAMEPAD 0x0005
#define USAGE_MULTIAXISCONTROLLER 0x0008


/* external variables referenced. */
extern HWND SDL_HelperWindow;


static SDL_HIDAPI_DeviceDriver *SDL_RAWINPUT_drivers[] = {
#ifdef SDL_JOYSTICK_HIDAPI_XBOX360
    &SDL_HIDAPI_DriverXbox360,
#endif
};

static SDL_bool SDL_RAWINPUT_inited = SDL_FALSE;
static int SDL_RAWINPUT_numjoysticks = 0;
static SDL_bool SDL_RAWINPUT_need_pump = SDL_TRUE;

static void RAWINPUT_JoystickDetect(void);
static void RAWINPUT_PumpMessages(void);
static SDL_bool RAWINPUT_IsDeviceSupported(Uint16 vendor_id, Uint16 product_id, Uint16 version);
static void RAWINPUT_JoystickClose(SDL_Joystick * joystick);

typedef struct _SDL_RAWINPUT_Device
{
    char *name;
    Uint16 vendor_id;
    Uint16 product_id;
    Uint16 version;
    SDL_JoystickGUID guid;
    Uint16 usage_page;
    Uint16 usage;
    SDL_HIDAPI_Device hiddevice;
    SDL_HIDAPI_DeviceDriver *driver;

    HANDLE hDevice;
    SDL_Joystick *joystick;
    SDL_JoystickID joystick_id;

    struct _SDL_RAWINPUT_Device *next;
} SDL_RAWINPUT_Device;

struct joystick_hwdata
{
    void *reserved; /* reserving a value here to ensure the new SDL_hidapijoystick.c code never dereferences this */
    SDL_RAWINPUT_Device *device;
    SDL_mutex *mutex;
};

SDL_RAWINPUT_Device *SDL_RAWINPUT_devices;

static const Uint16 subscribed_devices[] = {
    USAGE_GAMEPAD,
    /* Don't need Joystick for any devices we're handling here (XInput-capable)
    USAGE_JOYSTICK,
    USAGE_MULTIAXISCONTROLLER,
    */
};

SDL_bool RAWINPUT_AllXInputDevicesSupported() {
    UINT i, device_count = 0;
    PRAWINPUTDEVICELIST devices;
    SDL_bool any_unsupported = SDL_FALSE;

    if ((GetRawInputDeviceList(NULL, &device_count, sizeof(RAWINPUTDEVICELIST)) == -1) || (!device_count)) {
        return SDL_FALSE;
    }

    devices = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * device_count);
    if (devices == NULL) {
        return SDL_FALSE;
    }

    if (GetRawInputDeviceList(devices, &device_count, sizeof(RAWINPUTDEVICELIST)) == -1) {
        SDL_free(devices);
        return SDL_FALSE;
    }

    for (i = 0; i < device_count; i++) {
        RID_DEVICE_INFO rdi;
        char devName[128];
        UINT rdiSize = sizeof(rdi);
        UINT nameSize = SDL_arraysize(devName);

        rdi.cbSize = sizeof(rdi);
        if ((devices[i].dwType == RIM_TYPEHID) &&
            (GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) != ((UINT)-1)) &&
            (GetRawInputDeviceInfoA(devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) != ((UINT)-1)) &&
            (SDL_strstr(devName, "IG_") != NULL)
        ) {
            /* XInput-capable */
            if (!RAWINPUT_IsDeviceSupported((Uint16)rdi.hid.dwVendorId, (Uint16)rdi.hid.dwProductId, (Uint16)rdi.hid.dwVersionNumber)) {
                /* But not supported, probably Valve virtual controller */
                any_unsupported = SDL_TRUE;
            }
        }
    }
    SDL_free(devices);
    if (any_unsupported) {
        /* This happens with Valve virtual controllers that shows up in the RawInputDeviceList, but do not
            generate WM_INPUT events, so we must use XInput or DInput to read from it, and with XInput if we
            have some supported and some not, we can't easily tell which device is actually showing up in
            RawInput, so we must just disable RawInput for now.  Additionally, if these unsupported devices
            are locally connected, they still show up in RawInput under a *different* HID path, with
            different vendor/product IDs, so there's no way to reconcile. */
#ifdef DEBUG_RAWINPUT
        SDL_Log("Found some supported and some unsupported XInput devices, disabling RawInput\n");
#endif
        return SDL_FALSE;
    }
    return SDL_TRUE;
}

static int
RAWINPUT_JoystickInit(void)
{
    int ii;
    RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)];
    SDL_assert(!SDL_RAWINPUT_inited);
    SDL_assert(SDL_HelperWindow);

    if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_RAWINPUT, SDL_TRUE))
        return -1;

    if (!RAWINPUT_AllXInputDevicesSupported()) {
        return -1;
    }

    for (ii = 0; ii < SDL_arraysize(subscribed_devices); ii++) {
        rid[ii].usUsagePage = USAGE_PAGE_GENERIC_DESKTOP;
        rid[ii].usUsage = subscribed_devices[ii];
        rid[ii].dwFlags = RIDEV_DEVNOTIFY | RIDEV_INPUTSINK; /* Receive messages when in background, including device add/remove */
        rid[ii].hwndTarget = SDL_HelperWindow;
    }

    if (!RegisterRawInputDevices(rid, SDL_arraysize(rid), sizeof(RAWINPUTDEVICE))) {
        SDL_SetError("Couldn't initialize RAWINPUT");
        return -1;
    }

    SDL_RAWINPUT_inited = SDL_TRUE;

    RAWINPUT_JoystickDetect();
    RAWINPUT_PumpMessages();
    return 0;
}

static int
RAWINPUT_JoystickGetCount(void)
{
    return SDL_RAWINPUT_numjoysticks;
}

static SDL_RAWINPUT_Device *
RAWINPUT_DeviceFromHandle(HANDLE hDevice)
{
    SDL_RAWINPUT_Device *curr;

    for (curr = SDL_RAWINPUT_devices; curr; curr = curr->next) {
        if (curr->hDevice == hDevice)
            return curr;
    }
    return NULL;
}

static SDL_HIDAPI_DeviceDriver *
RAWINPUT_GetDeviceDriver(SDL_RAWINPUT_Device *device)
{
    int i;
    SDL_GameControllerType type;

    if (SDL_ShouldIgnoreJoystick(device->name, device->guid)) {
        return NULL;
    }

    if (device->usage_page && device->usage_page != USAGE_PAGE_GENERIC_DESKTOP) {
        return NULL;
    }
    if (device->usage && device->usage != USAGE_JOYSTICK && device->usage != USAGE_GAMEPAD && device->usage != USAGE_MULTIAXISCONTROLLER) {
        return NULL;
    }

    type = SDL_GetJoystickGameControllerType("", device->vendor_id, device->product_id, -1, 0, 0, 0);

    for (i = 0; i < SDL_arraysize(SDL_RAWINPUT_drivers); ++i) {
        SDL_HIDAPI_DeviceDriver *driver = SDL_RAWINPUT_drivers[i];
        if (/*driver->enabled && */driver->IsSupportedDevice(NULL, type, device->vendor_id, device->product_id, device->version, -1, 0, 0, 0)) {
            return driver;
        }
    }
    return NULL;
}

static void
RAWINPUT_AddDevice(HANDLE hDevice)
{
#define CHECK(exp) { if(!(exp)) goto err; }
    SDL_RAWINPUT_Device *device = NULL;
    RID_DEVICE_INFO rdi;
    UINT rdi_size = sizeof(rdi);
    char dev_name[128];
    const char *name;
    UINT name_size = SDL_arraysize(dev_name);
    SDL_RAWINPUT_Device *curr, *last;

    SDL_assert(!RAWINPUT_DeviceFromHandle(hDevice));

    /* Figure out what kind of device it is */
    CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICEINFO, &rdi, &rdi_size) != (UINT)-1);
    CHECK(rdi.dwType == RIM_TYPEHID);

    /* Get the device "name" (HID Path) */
    CHECK(GetRawInputDeviceInfoA(hDevice, RIDI_DEVICENAME, dev_name, &name_size) != (UINT)-1);
    /* Only take XInput-capable devices */
    CHECK(SDL_strstr(dev_name, "IG_") != NULL);

    CHECK(device = SDL_callocStruct(SDL_RAWINPUT_Device));
    device->hDevice = hDevice;
    device->vendor_id = (Uint16)rdi.hid.dwVendorId;
    device->product_id = (Uint16)rdi.hid.dwProductId;
    device->version = (Uint16)rdi.hid.dwVersionNumber;
    device->usage = rdi.hid.usUsage;
    device->usage_page = rdi.hid.usUsagePage;

    {
        const Uint16 vendor = device->vendor_id;
        const Uint16 product = device->product_id;
        const Uint16 version = device->version;
        Uint16 *guid16 = (Uint16 *)device->guid.data;

        *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB);
        *guid16++ = 0;
        *guid16++ = SDL_SwapLE16(vendor);
        *guid16++ = 0;
        *guid16++ = SDL_SwapLE16(product);
        *guid16++ = 0;
        *guid16++ = SDL_SwapLE16(version);
        *guid16++ = 0;

        /* Note that this is a RAWINPUT device for special handling elsewhere */
        device->guid.data[14] = 'r';
        device->guid.data[15] = 0;
    }

    if (!device->name) {
        size_t name_size = (6 + 1 + 6 + 1);
        CHECK(device->name = SDL_callocStructs(char, name_size));
        SDL_snprintf(device->name, name_size, "0x%.4x/0x%.4x", device->vendor_id, device->product_id);
    }

    CHECK(device->driver = RAWINPUT_GetDeviceDriver(device));

    name = device->driver->GetDeviceName(device->vendor_id, device->product_id);
    if (name) {
        SDL_free(device->name);
        device->name = SDL_strdup(name);
    }

#ifdef DEBUG_RAWINPUT
    SDL_Log("Adding RAWINPUT device '%s' VID 0x%.4x, PID 0x%.4x, version %d, handle 0x%.8x\n", device->name, device->vendor_id, device->product_id, device->version, device->hDevice);
#endif

    /* Add it to the list */
    for (curr = SDL_RAWINPUT_devices, last = NULL; curr; last = curr, curr = curr->next) {
        continue;
    }
    if (last) {
        last->next = device;
    } else {
        SDL_RAWINPUT_devices = device;
    }

    ++SDL_RAWINPUT_numjoysticks;
    /* HIDAPI_JoystickConnected calls SDL_GetNextJoystickInstanceID() and SDL_PrivateJoystickAdded(), and calls back in to us, so
      the device list must be updated before calling this. */
    CHECK(HIDAPI_JoystickConnected(&device->hiddevice, &device->joystick_id, SDL_TRUE));
    /* Old: CHECK(device->driver->InitDevice(&device->hiddevice)); But, we need the joystick_id */

    return;

err:
    if (device) {
        if (device->name)
            SDL_free(device->name);
        SDL_free(device);
    }
}

static void
RAWINPUT_DelDevice(SDL_RAWINPUT_Device *device, SDL_bool send_event)
{
    SDL_RAWINPUT_Device *curr, *last;
    for (curr = SDL_RAWINPUT_devices, last = NULL; curr; last = curr, curr = curr->next) {
        if (curr == device) {
            SDL_Joystick *joystick;
            if (last) {
                last->next = curr->next;
            } else {
                SDL_RAWINPUT_devices = curr->next;
            }
            --SDL_RAWINPUT_numjoysticks;

            joystick = device->joystick;
            if (joystick) {
                /* Detach from joystick */
                RAWINPUT_JoystickClose(joystick);
            }
            /* Calls SDL_PrivateJoystickRemoved() */
            HIDAPI_JoystickDisconnected(&device->hiddevice, device->joystick_id, SDL_TRUE);

#ifdef DEBUG_RAWINPUT
            SDL_Log("Removing RAWINPUT device '%s' VID 0x%.4x, PID 0x%.4x, version %d, handle 0x%.8x\n", device->name, device->vendor_id, device->product_id, device->version, device->hDevice);
#endif
            SDL_free(device->name);
            SDL_free(device);
            return;
        }
    }
}

static void
RAWINPUT_PumpMessages(void)
{
    if (SDL_RAWINPUT_need_pump) {
        MSG msg;
        while (PeekMessage(&msg, SDL_HelperWindow, WM_INPUT, WM_INPUT, PM_REMOVE)) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        SDL_RAWINPUT_need_pump = SDL_FALSE;
    }
}

static void
RAWINPUT_UpdateDeviceList(void)
{
    MSG msg;
    /* In theory, want only WM_INPUT_DEVICE_CHANGE messages here, but PeekMessage returns nothing unless you also ask
       for WM_INPUT */
    while (PeekMessage(&msg, SDL_HelperWindow, WM_INPUT_DEVICE_CHANGE, WM_INPUT, PM_REMOVE)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
}

static SDL_bool
RAWINPUT_IsDeviceSupported(Uint16 vendor_id, Uint16 product_id, Uint16 version)
{
    int i;

    SDL_GameControllerType type = SDL_GetJoystickGameControllerType("", vendor_id, product_id, -1, 0, 0, 0);

    for (i = 0; i < SDL_arraysize(SDL_RAWINPUT_drivers); ++i) {
        SDL_HIDAPI_DeviceDriver *driver = SDL_RAWINPUT_drivers[i];
        /* Ignoring driver->enabled here, and elsewhere in this file, as the if the driver is enabled by disabling HID,
            we still want RawInput to use it.  If we end up with more than one RawInput driver, we may need to rework
            how the hints interact (separate enabled state, perhaps).
        */
        if (/*driver->enabled && */driver->IsSupportedDevice(NULL, type, vendor_id, product_id, version, -1, 0, 0, 0)) {
            return SDL_TRUE;
        }
    }
    return SDL_FALSE;
}

SDL_bool
RAWINPUT_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version)
{
    SDL_RAWINPUT_Device *device;

    /* Don't update the device list for devices we know aren't supported */
    if (!RAWINPUT_IsDeviceSupported(vendor_id, product_id, version)) {
        return SDL_FALSE;
    }

    /* Make sure the device list is completely up to date when we check for device presence */
    RAWINPUT_UpdateDeviceList();

    device = SDL_RAWINPUT_devices;
    while (device) {
        if (device->vendor_id == vendor_id && device->product_id == product_id) {
            return SDL_TRUE;
        }
        device = device->next;
    }
    return SDL_FALSE;
}

static void
RAWINPUT_JoystickDetect(void)
{
    int i;
    /* Just ensure the window's add/remove messages have been pumped */
    RAWINPUT_UpdateDeviceList();

    for (i = 0; i < SDL_arraysize(SDL_RAWINPUT_drivers); ++i) {
        SDL_HIDAPI_DeviceDriver *driver = SDL_RAWINPUT_drivers[i];
        /* Running PostUpdate here only if it's *not* enabled (and ran elsewhere) */
        if (!driver->enabled && driver->PostUpdate) {
            driver->PostUpdate();
        }
    }
    SDL_RAWINPUT_need_pump = SDL_TRUE;
}

static SDL_RAWINPUT_Device *
RAWINPUT_GetJoystickByIndex(int device_index, SDL_JoystickID *pJoystickID)
{
    SDL_RAWINPUT_Device *device = SDL_RAWINPUT_devices;
    while (device) {
        if (device->driver) {
            SDL_assert(device->hiddevice.num_joysticks == 1);
            if (device_index < device->hiddevice.num_joysticks) {
                if (pJoystickID) {
                    *pJoystickID = device->hiddevice.joysticks[device_index];
                }
                return device;
            }
            device_index -= device->hiddevice.num_joysticks;
        }
        device = device->next;
    }
    return NULL;
}

static const char *
RAWINPUT_JoystickGetDeviceName(int device_index)
{
    return RAWINPUT_GetJoystickByIndex(device_index, NULL)->name;
}

static int
RAWINPUT_JoystickGetDevicePlayerIndex(int device_index)
{
    SDL_RAWINPUT_Device *device;
    SDL_JoystickID instance_id;
    int player_index = -1;

    device = RAWINPUT_GetJoystickByIndex(device_index, &instance_id);
    if (device && device->driver) {
        player_index = device->driver->GetDevicePlayerIndex(&device->hiddevice, instance_id);
    }

    return player_index;
}

static void
RAWINPUT_JoystickSetDevicePlayerIndex(int device_index, int player_index)
{
    SDL_RAWINPUT_Device *device;
    SDL_JoystickID instance_id;

    device = RAWINPUT_GetJoystickByIndex(device_index, &instance_id);
    if (device) {
        device->driver->SetDevicePlayerIndex(&device->hiddevice, instance_id, player_index);
    }
}


static SDL_JoystickGUID
RAWINPUT_JoystickGetDeviceGUID(int device_index)
{
    return RAWINPUT_GetJoystickByIndex(device_index, NULL)->guid;
}

static SDL_JoystickID
RAWINPUT_JoystickGetDeviceInstanceID(int device_index)
{
    SDL_JoystickID instance_id = -1;
    RAWINPUT_GetJoystickByIndex(device_index, &instance_id);
    return instance_id;
}

static int
RAWINPUT_JoystickOpen(SDL_Joystick * joystick, int device_index)
{
    SDL_RAWINPUT_Device *device = RAWINPUT_GetJoystickByIndex(device_index, NULL);
    struct joystick_hwdata *hwdata = SDL_callocStruct(struct joystick_hwdata);
    SDL_assert(!device->joystick);

    if (!hwdata) {
        return SDL_OutOfMemory();
    }

    if (!device->driver->OpenJoystick(&device->hiddevice, joystick)) {
        /* Only possible error is out of memory */
        return SDL_OutOfMemory();
    }

    hwdata->reserved = (void*)-1; /* crash if some code slips by that tries to use this */
    hwdata->device = device;
    device->joystick = joystick;

    hwdata->mutex = SDL_CreateMutex();
    joystick->hwdata = hwdata;

    return 0;
}

static int
RAWINPUT_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
{
    struct joystick_hwdata *hwdata = joystick->hwdata;
    SDL_RAWINPUT_Device *device = hwdata->device;
    int result;

    SDL_LockMutex(hwdata->mutex);
    result = device->driver->RumbleJoystick(&device->hiddevice, joystick, low_frequency_rumble, high_frequency_rumble);
    SDL_UnlockMutex(hwdata->mutex);
    return result;
}

static void
RAWINPUT_JoystickUpdate(SDL_Joystick * joystick)
{
    struct joystick_hwdata *hwdata;
    SDL_RAWINPUT_Device *device;
    /* Ensure data messages have been pumped */
    RAWINPUT_PumpMessages();
    hwdata = joystick->hwdata;
    device = hwdata->device;

    SDL_LockMutex(hwdata->mutex);
    device->driver->UpdateDevice(&device->hiddevice);
    SDL_UnlockMutex(hwdata->mutex);
}

static void
RAWINPUT_JoystickClose(SDL_Joystick * joystick)
{
    struct joystick_hwdata *hwdata = joystick->hwdata;

    if (hwdata) {
        SDL_RAWINPUT_Device *device;

        device = hwdata->device;
        if (device) {
            SDL_assert(device->joystick == joystick);
            device->driver->CloseJoystick(&device->hiddevice, joystick);
            device->joystick = NULL;
        }

        SDL_DestroyMutex(hwdata->mutex);
        SDL_free(hwdata);
        joystick->hwdata = NULL;
    }
}

LRESULT RAWINPUT_WindowProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
    if (!SDL_RAWINPUT_inited)
        return -1;

    switch (msg)
    {
        case WM_INPUT_DEVICE_CHANGE:
        {
            HANDLE hDevice = (HANDLE)lParam;
            switch (wParam) {
            case GIDC_ARRIVAL:
                RAWINPUT_AddDevice(hDevice);
                break;
            case GIDC_REMOVAL: {
                SDL_RAWINPUT_Device *device;
                device = RAWINPUT_DeviceFromHandle(hDevice);
                if (device) {
                    RAWINPUT_DelDevice(device, SDL_TRUE);
                }
            } break;
            default:
                return 0;
            }
        }
        return 0;
        case WM_INPUT:
        {
            Uint8 data[sizeof(RAWINPUTHEADER) + sizeof(RAWHID) + USB_PACKET_LENGTH];
            UINT buffer_size = SDL_arraysize(data);

            if ((int)GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &buffer_size, sizeof(RAWINPUTHEADER)) > 0) {
                PRAWINPUT raw_input = (PRAWINPUT)data;
                SDL_RAWINPUT_Device *device = RAWINPUT_DeviceFromHandle(raw_input->header.hDevice);
                if (device) {
                    SDL_HIDAPI_DeviceDriver *driver = device->driver;
                    SDL_Joystick *joystick = device->joystick;
                    if (joystick) {
                        driver->HandleStatePacketFromRAWINPUT(&device->hiddevice, joystick, &raw_input->data.hid.bRawData[1], raw_input->data.hid.dwSizeHid - 1);
                    }
                }
            }
        }
        return 0;
    }
    return -1;
}

static void
RAWINPUT_JoystickQuit(void)
{
    int ii;
    RAWINPUTDEVICE rid[SDL_arraysize(subscribed_devices)];
    
    if (!SDL_RAWINPUT_inited)
        return;

    for (ii = 0; ii < SDL_arraysize(subscribed_devices); ii++) {
        rid[ii].usUsagePage = USAGE_PAGE_GENERIC_DESKTOP;
        rid[ii].usUsage = subscribed_devices[ii];
        rid[ii].dwFlags = RIDEV_REMOVE;
        rid[ii].hwndTarget = NULL;
    }

    if (!RegisterRawInputDevices(rid, SDL_arraysize(rid), sizeof(RAWINPUTDEVICE))) {
        SDL_Log("Couldn't un-register RAWINPUT");
    }
    
    while (SDL_RAWINPUT_devices) {
        RAWINPUT_DelDevice(SDL_RAWINPUT_devices, SDL_FALSE);
    }

    SDL_RAWINPUT_numjoysticks = 0;

    SDL_RAWINPUT_inited = SDL_FALSE;
}


SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver =
{
    RAWINPUT_JoystickInit,
    RAWINPUT_JoystickGetCount,
    RAWINPUT_JoystickDetect,
    RAWINPUT_JoystickGetDeviceName,
    RAWINPUT_JoystickGetDevicePlayerIndex,
    RAWINPUT_JoystickSetDevicePlayerIndex,
    RAWINPUT_JoystickGetDeviceGUID,
    RAWINPUT_JoystickGetDeviceInstanceID,
    RAWINPUT_JoystickOpen,
    RAWINPUT_JoystickRumble,
    RAWINPUT_JoystickUpdate,
    RAWINPUT_JoystickClose,
    RAWINPUT_JoystickQuit,
};

#endif /* SDL_JOYSTICK_RAWINPUT */

/* vi: set ts=4 sw=4 expandtab: */
