early-access version 1617
This commit is contained in:
@@ -33,8 +33,8 @@
|
||||
* let it return 0 events. */
|
||||
|
||||
#include "SDL_error.h"
|
||||
#include "SDL_assert.h"
|
||||
#include "SDL_events.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_mutex.h"
|
||||
#include "SDL_joystick.h"
|
||||
@@ -49,6 +49,7 @@
|
||||
#include "SDL_windowsjoystick_c.h"
|
||||
#include "SDL_dinputjoystick_c.h"
|
||||
#include "SDL_xinputjoystick_c.h"
|
||||
#include "SDL_rawinputjoystick_c.h"
|
||||
|
||||
#include "../../haptic/windows/SDL_dinputhaptic_c.h" /* For haptic hot plugging */
|
||||
#include "../../haptic/windows/SDL_xinputhaptic_c.h" /* For haptic hot plugging */
|
||||
@@ -59,17 +60,15 @@
|
||||
#endif
|
||||
|
||||
/* local variables */
|
||||
static SDL_bool s_bDeviceAdded = SDL_FALSE;
|
||||
static SDL_bool s_bDeviceRemoved = SDL_FALSE;
|
||||
static SDL_bool s_bJoystickThread = SDL_FALSE;
|
||||
static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE;
|
||||
static SDL_cond *s_condJoystickThread = NULL;
|
||||
static SDL_mutex *s_mutexJoyStickEnum = NULL;
|
||||
static SDL_Thread *s_threadJoystick = NULL;
|
||||
static SDL_Thread *s_joystickThread = NULL;
|
||||
static SDL_bool s_bJoystickThreadQuit = SDL_FALSE;
|
||||
|
||||
JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */
|
||||
|
||||
static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE;
|
||||
|
||||
#ifdef __WINRT__
|
||||
|
||||
typedef struct
|
||||
@@ -109,9 +108,9 @@ typedef struct
|
||||
|
||||
/* windowproc for our joystick detect thread message only window, to detect any USB device addition/removal */
|
||||
static LRESULT CALLBACK
|
||||
SDL_PrivateJoystickDetectProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
SDL_PrivateJoystickDetectProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message) {
|
||||
switch (msg) {
|
||||
case WM_DEVICECHANGE:
|
||||
switch (wParam) {
|
||||
case DBT_DEVICEARRIVAL:
|
||||
@@ -125,17 +124,29 @@ SDL_PrivateJoystickDetectProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lPa
|
||||
}
|
||||
return 0;
|
||||
case WM_TIMER:
|
||||
KillTimer(hwnd, wParam);
|
||||
s_bWindowsDeviceChanged = SDL_TRUE;
|
||||
return 0;
|
||||
if (wParam == IDT_SDL_DEVICE_CHANGE_TIMER_1 ||
|
||||
wParam == IDT_SDL_DEVICE_CHANGE_TIMER_2) {
|
||||
KillTimer(hwnd, wParam);
|
||||
s_bWindowsDeviceChanged = SDL_TRUE;
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc (hwnd, message, wParam, lParam);
|
||||
#if SDL_JOYSTICK_RAWINPUT
|
||||
return CallWindowProc(RAWINPUT_WindowProc, hwnd, msg, wParam, lParam);
|
||||
#else
|
||||
return CallWindowProc(DefWindowProc, hwnd, msg, wParam, lParam);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *data)
|
||||
{
|
||||
#if SDL_JOYSTICK_RAWINPUT
|
||||
RAWINPUT_UnregisterNotifications();
|
||||
#endif
|
||||
|
||||
if (data->hNotify)
|
||||
UnregisterDeviceNotification(data->hNotify);
|
||||
|
||||
@@ -188,6 +199,10 @@ SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data)
|
||||
SDL_CleanupDeviceNotification(data);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if SDL_JOYSTICK_RAWINPUT
|
||||
RAWINPUT_RegisterNotifications(data->messageWindow);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -215,26 +230,24 @@ SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex
|
||||
|
||||
#endif /* __WINRT__ */
|
||||
|
||||
static SDL_DeviceNotificationData s_notification_data;
|
||||
|
||||
/* Function/thread to scan the system for joysticks. */
|
||||
static int
|
||||
SDL_JoystickThread(void *_data)
|
||||
{
|
||||
SDL_DeviceNotificationData notification_data;
|
||||
|
||||
#if SDL_JOYSTICK_XINPUT
|
||||
SDL_bool bOpenedXInputDevices[XUSER_MAX_COUNT];
|
||||
SDL_zeroa(bOpenedXInputDevices);
|
||||
#endif
|
||||
|
||||
if (SDL_CreateDeviceNotification(¬ification_data) < 0) {
|
||||
if (SDL_CreateDeviceNotification(&s_notification_data) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_LockMutex(s_mutexJoyStickEnum);
|
||||
while (s_bJoystickThreadQuit == SDL_FALSE) {
|
||||
SDL_bool bXInputChanged = SDL_FALSE;
|
||||
|
||||
if (SDL_WaitForDeviceNotification(¬ification_data, s_mutexJoyStickEnum) == SDL_FALSE) {
|
||||
if (SDL_WaitForDeviceNotification(&s_notification_data, s_mutexJoyStickEnum) == SDL_FALSE) {
|
||||
#if SDL_JOYSTICK_XINPUT
|
||||
/* WM_DEVICECHANGE not working, poll for new XINPUT controllers */
|
||||
SDL_CondWaitTimeout(s_condJoystickThread, s_mutexJoyStickEnum, 1000);
|
||||
@@ -246,7 +259,7 @@ SDL_JoystickThread(void *_data)
|
||||
const DWORD result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities);
|
||||
const SDL_bool available = (result == ERROR_SUCCESS);
|
||||
if (bOpenedXInputDevices[userId] != available) {
|
||||
bXInputChanged = SDL_TRUE;
|
||||
s_bWindowsDeviceChanged = SDL_TRUE;
|
||||
bOpenedXInputDevices[userId] = available;
|
||||
}
|
||||
}
|
||||
@@ -256,28 +269,67 @@ SDL_JoystickThread(void *_data)
|
||||
break;
|
||||
#endif /* SDL_JOYSTICK_XINPUT */
|
||||
}
|
||||
|
||||
if (s_bWindowsDeviceChanged || bXInputChanged) {
|
||||
s_bDeviceRemoved = SDL_TRUE;
|
||||
s_bDeviceAdded = SDL_TRUE;
|
||||
s_bWindowsDeviceChanged = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
SDL_UnlockMutex(s_mutexJoyStickEnum);
|
||||
|
||||
SDL_CleanupDeviceNotification(¬ification_data);
|
||||
SDL_CleanupDeviceNotification(&s_notification_data);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* spin up the thread to detect hotplug of devices */
|
||||
static int
|
||||
SDL_StartJoystickThread(void)
|
||||
{
|
||||
s_mutexJoyStickEnum = SDL_CreateMutex();
|
||||
if (!s_mutexJoyStickEnum) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
s_condJoystickThread = SDL_CreateCond();
|
||||
if (!s_condJoystickThread) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
s_bJoystickThreadQuit = SDL_FALSE;
|
||||
s_joystickThread = SDL_CreateThreadInternal(SDL_JoystickThread, "SDL_joystick", 64 * 1024, NULL);
|
||||
if (!s_joystickThread) {
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
SDL_StopJoystickThread(void)
|
||||
{
|
||||
if (!s_joystickThread) {
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_LockMutex(s_mutexJoyStickEnum);
|
||||
s_bJoystickThreadQuit = SDL_TRUE;
|
||||
SDL_CondBroadcast(s_condJoystickThread); /* signal the joystick thread to quit */
|
||||
SDL_UnlockMutex(s_mutexJoyStickEnum);
|
||||
#ifndef __WINRT__
|
||||
PostThreadMessage(SDL_GetThreadID(s_joystickThread), WM_QUIT, 0, 0);
|
||||
#endif
|
||||
SDL_WaitThread(s_joystickThread, NULL); /* wait for it to bugger off */
|
||||
|
||||
SDL_DestroyCond(s_condJoystickThread);
|
||||
s_condJoystickThread = NULL;
|
||||
|
||||
SDL_DestroyMutex(s_mutexJoyStickEnum);
|
||||
s_mutexJoyStickEnum = NULL;
|
||||
|
||||
s_joystickThread = NULL;
|
||||
}
|
||||
|
||||
void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device)
|
||||
{
|
||||
device->send_add_event = SDL_TRUE;
|
||||
device->nInstanceID = SDL_GetNextJoystickInstanceID();
|
||||
device->pNext = SYS_Joystick;
|
||||
SYS_Joystick = device;
|
||||
|
||||
s_bDeviceAdded = SDL_TRUE;
|
||||
}
|
||||
|
||||
static void WINDOWS_JoystickDetect(void);
|
||||
@@ -300,16 +352,19 @@ WINDOWS_JoystickInit(void)
|
||||
return -1;
|
||||
}
|
||||
|
||||
s_mutexJoyStickEnum = SDL_CreateMutex();
|
||||
s_condJoystickThread = SDL_CreateCond();
|
||||
s_bDeviceAdded = SDL_TRUE; /* force a scan of the system for joysticks this first time */
|
||||
s_bWindowsDeviceChanged = SDL_TRUE; /* force a scan of the system for joysticks this first time */
|
||||
|
||||
WINDOWS_JoystickDetect();
|
||||
|
||||
if (!s_threadJoystick) {
|
||||
/* spin up the thread to detect hotplug of devices */
|
||||
s_bJoystickThreadQuit = SDL_FALSE;
|
||||
s_threadJoystick = SDL_CreateThreadInternal(SDL_JoystickThread, "SDL_joystick", 64 * 1024, NULL);
|
||||
s_bJoystickThread = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_THREAD, SDL_FALSE);
|
||||
if (s_bJoystickThread) {
|
||||
if (SDL_StartJoystickThread() < 0) {
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (SDL_CreateDeviceNotification(&s_notification_data) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -332,17 +387,19 @@ WINDOWS_JoystickGetCount(void)
|
||||
static void
|
||||
WINDOWS_JoystickDetect(void)
|
||||
{
|
||||
int device_index = 0;
|
||||
JoyStick_DeviceData *pCurList = NULL;
|
||||
|
||||
/* only enum the devices if the joystick thread told us something changed */
|
||||
if (!s_bDeviceAdded && !s_bDeviceRemoved) {
|
||||
if (!s_bWindowsDeviceChanged) {
|
||||
return; /* thread hasn't signaled, nothing to do right now. */
|
||||
}
|
||||
|
||||
SDL_LockMutex(s_mutexJoyStickEnum);
|
||||
if (s_mutexJoyStickEnum) {
|
||||
SDL_LockMutex(s_mutexJoyStickEnum);
|
||||
}
|
||||
|
||||
s_bDeviceAdded = SDL_FALSE;
|
||||
s_bDeviceRemoved = SDL_FALSE;
|
||||
s_bWindowsDeviceChanged = SDL_FALSE;
|
||||
|
||||
pCurList = SYS_Joystick;
|
||||
SYS_Joystick = NULL;
|
||||
@@ -353,15 +410,21 @@ WINDOWS_JoystickDetect(void)
|
||||
/* Look for XInput devices. Do this last, so they're first in the final list. */
|
||||
SDL_XINPUT_JoystickDetect(&pCurList);
|
||||
|
||||
SDL_UnlockMutex(s_mutexJoyStickEnum);
|
||||
if (s_mutexJoyStickEnum) {
|
||||
SDL_UnlockMutex(s_mutexJoyStickEnum);
|
||||
}
|
||||
|
||||
while (pCurList) {
|
||||
JoyStick_DeviceData *pListNext = NULL;
|
||||
|
||||
if (pCurList->bXInputDevice) {
|
||||
#if SDL_HAPTIC_XINPUT
|
||||
SDL_XINPUT_MaybeRemoveDevice(pCurList->XInputUserId);
|
||||
#endif
|
||||
} else {
|
||||
#if SDL_HAPTIC_DINPUT
|
||||
SDL_DINPUT_MaybeRemoveDevice(&pCurList->dxdevice);
|
||||
#endif
|
||||
}
|
||||
|
||||
SDL_PrivateJoystickRemoved(pCurList->nInstanceID);
|
||||
@@ -372,25 +435,21 @@ WINDOWS_JoystickDetect(void)
|
||||
pCurList = pListNext;
|
||||
}
|
||||
|
||||
if (s_bDeviceAdded) {
|
||||
JoyStick_DeviceData *pNewJoystick;
|
||||
int device_index = 0;
|
||||
s_bDeviceAdded = SDL_FALSE;
|
||||
pNewJoystick = SYS_Joystick;
|
||||
while (pNewJoystick) {
|
||||
if (pNewJoystick->send_add_event) {
|
||||
if (pNewJoystick->bXInputDevice) {
|
||||
SDL_XINPUT_MaybeAddDevice(pNewJoystick->XInputUserId);
|
||||
} else {
|
||||
SDL_DINPUT_MaybeAddDevice(&pNewJoystick->dxdevice);
|
||||
}
|
||||
|
||||
SDL_PrivateJoystickAdded(pNewJoystick->nInstanceID);
|
||||
|
||||
pNewJoystick->send_add_event = SDL_FALSE;
|
||||
for (device_index = 0, pCurList = SYS_Joystick; pCurList; ++device_index, pCurList = pCurList->pNext) {
|
||||
if (pCurList->send_add_event) {
|
||||
if (pCurList->bXInputDevice) {
|
||||
#if SDL_HAPTIC_XINPUT
|
||||
SDL_XINPUT_MaybeAddDevice(pCurList->XInputUserId);
|
||||
#endif
|
||||
} else {
|
||||
#if SDL_HAPTIC_DINPUT
|
||||
SDL_DINPUT_MaybeAddDevice(&pCurList->dxdevice);
|
||||
#endif
|
||||
}
|
||||
device_index++;
|
||||
pNewJoystick = pNewJoystick->pNext;
|
||||
|
||||
SDL_PrivateJoystickAdded(pCurList->nInstanceID);
|
||||
|
||||
pCurList->send_add_event = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -400,8 +459,9 @@ static const char *
|
||||
WINDOWS_JoystickGetDeviceName(int device_index)
|
||||
{
|
||||
JoyStick_DeviceData *device = SYS_Joystick;
|
||||
int index;
|
||||
|
||||
for (; device_index > 0; device_index--)
|
||||
for (index = device_index; index > 0; index--)
|
||||
device = device->pNext;
|
||||
|
||||
return device->joystickname;
|
||||
@@ -458,25 +518,26 @@ WINDOWS_JoystickGetDeviceInstanceID(int device_index)
|
||||
static int
|
||||
WINDOWS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
||||
{
|
||||
JoyStick_DeviceData *joystickdevice = SYS_Joystick;
|
||||
JoyStick_DeviceData *device = SYS_Joystick;
|
||||
int index;
|
||||
|
||||
for (; device_index > 0; device_index--)
|
||||
joystickdevice = joystickdevice->pNext;
|
||||
for (index = device_index; index > 0; index--)
|
||||
device = device->pNext;
|
||||
|
||||
/* allocate memory for system specific hardware data */
|
||||
joystick->instance_id = joystickdevice->nInstanceID;
|
||||
joystick->instance_id = device->nInstanceID;
|
||||
joystick->hwdata =
|
||||
(struct joystick_hwdata *) SDL_malloc(sizeof(struct joystick_hwdata));
|
||||
if (joystick->hwdata == NULL) {
|
||||
return SDL_OutOfMemory();
|
||||
}
|
||||
SDL_zerop(joystick->hwdata);
|
||||
joystick->hwdata->guid = joystickdevice->guid;
|
||||
joystick->hwdata->guid = device->guid;
|
||||
|
||||
if (joystickdevice->bXInputDevice) {
|
||||
return SDL_XINPUT_JoystickOpen(joystick, joystickdevice);
|
||||
if (device->bXInputDevice) {
|
||||
return SDL_XINPUT_JoystickOpen(joystick, device);
|
||||
} else {
|
||||
return SDL_DINPUT_JoystickOpen(joystick, joystickdevice);
|
||||
return SDL_DINPUT_JoystickOpen(joystick, device);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -490,6 +551,30 @@ WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uin
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
WINDOWS_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
WINDOWS_JoystickHasLED(SDL_Joystick * joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
WINDOWS_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
WINDOWS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static void
|
||||
WINDOWS_JoystickUpdate(SDL_Joystick * joystick)
|
||||
{
|
||||
@@ -531,28 +616,22 @@ WINDOWS_JoystickQuit(void)
|
||||
}
|
||||
SYS_Joystick = NULL;
|
||||
|
||||
if (s_threadJoystick) {
|
||||
SDL_LockMutex(s_mutexJoyStickEnum);
|
||||
s_bJoystickThreadQuit = SDL_TRUE;
|
||||
SDL_CondBroadcast(s_condJoystickThread); /* signal the joystick thread to quit */
|
||||
SDL_UnlockMutex(s_mutexJoyStickEnum);
|
||||
#ifndef __WINRT__
|
||||
PostThreadMessage(SDL_GetThreadID(s_threadJoystick), WM_QUIT, 0, 0);
|
||||
#endif
|
||||
SDL_WaitThread(s_threadJoystick, NULL); /* wait for it to bugger off */
|
||||
|
||||
SDL_DestroyMutex(s_mutexJoyStickEnum);
|
||||
SDL_DestroyCond(s_condJoystickThread);
|
||||
s_condJoystickThread= NULL;
|
||||
s_mutexJoyStickEnum = NULL;
|
||||
s_threadJoystick = NULL;
|
||||
if (s_bJoystickThread) {
|
||||
SDL_StopJoystickThread();
|
||||
} else {
|
||||
SDL_CleanupDeviceNotification(&s_notification_data);
|
||||
}
|
||||
|
||||
SDL_DINPUT_JoystickQuit();
|
||||
SDL_XINPUT_JoystickQuit();
|
||||
|
||||
s_bDeviceAdded = SDL_FALSE;
|
||||
s_bDeviceRemoved = SDL_FALSE;
|
||||
s_bWindowsDeviceChanged = SDL_FALSE;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
WINDOWS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
|
||||
@@ -567,9 +646,14 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
|
||||
WINDOWS_JoystickGetDeviceInstanceID,
|
||||
WINDOWS_JoystickOpen,
|
||||
WINDOWS_JoystickRumble,
|
||||
WINDOWS_JoystickRumbleTriggers,
|
||||
WINDOWS_JoystickHasLED,
|
||||
WINDOWS_JoystickSetLED,
|
||||
WINDOWS_JoystickSetSensorsEnabled,
|
||||
WINDOWS_JoystickUpdate,
|
||||
WINDOWS_JoystickClose,
|
||||
WINDOWS_JoystickQuit,
|
||||
WINDOWS_JoystickGetGamepadMapping
|
||||
};
|
||||
|
||||
#endif /* SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT */
|
||||
|
Reference in New Issue
Block a user