early-access version 1988
This commit is contained in:
@@ -59,6 +59,77 @@
|
||||
#define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000
|
||||
#endif
|
||||
|
||||
/* CM_Register_Notification definitions */
|
||||
|
||||
#define CR_SUCCESS (0x00000000)
|
||||
|
||||
DECLARE_HANDLE(HCMNOTIFICATION);
|
||||
typedef HCMNOTIFICATION* PHCMNOTIFICATION;
|
||||
|
||||
typedef enum _CM_NOTIFY_FILTER_TYPE {
|
||||
CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE = 0,
|
||||
CM_NOTIFY_FILTER_TYPE_DEVICEHANDLE,
|
||||
CM_NOTIFY_FILTER_TYPE_DEVICEINSTANCE,
|
||||
CM_NOTIFY_FILTER_TYPE_MAX
|
||||
} CM_NOTIFY_FILTER_TYPE, * PCM_NOTIFY_FILTER_TYPE;
|
||||
|
||||
typedef struct _CM_NOTIFY_FILTER {
|
||||
DWORD cbSize;
|
||||
DWORD Flags;
|
||||
CM_NOTIFY_FILTER_TYPE FilterType;
|
||||
DWORD Reserved;
|
||||
union {
|
||||
struct {
|
||||
GUID ClassGuid;
|
||||
} DeviceInterface;
|
||||
struct {
|
||||
HANDLE hTarget;
|
||||
} DeviceHandle;
|
||||
struct {
|
||||
WCHAR InstanceId[200];
|
||||
} DeviceInstance;
|
||||
} u;
|
||||
} CM_NOTIFY_FILTER, * PCM_NOTIFY_FILTER;
|
||||
|
||||
typedef enum _CM_NOTIFY_ACTION {
|
||||
CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL = 0,
|
||||
CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL,
|
||||
CM_NOTIFY_ACTION_DEVICEQUERYREMOVE,
|
||||
CM_NOTIFY_ACTION_DEVICEQUERYREMOVEFAILED,
|
||||
CM_NOTIFY_ACTION_DEVICEREMOVEPENDING,
|
||||
CM_NOTIFY_ACTION_DEVICEREMOVECOMPLETE,
|
||||
CM_NOTIFY_ACTION_DEVICECUSTOMEVENT,
|
||||
CM_NOTIFY_ACTION_DEVICEINSTANCEENUMERATED,
|
||||
CM_NOTIFY_ACTION_DEVICEINSTANCESTARTED,
|
||||
CM_NOTIFY_ACTION_DEVICEINSTANCEREMOVED,
|
||||
CM_NOTIFY_ACTION_MAX
|
||||
} CM_NOTIFY_ACTION, * PCM_NOTIFY_ACTION;
|
||||
|
||||
typedef struct _CM_NOTIFY_EVENT_DATA {
|
||||
CM_NOTIFY_FILTER_TYPE FilterType;
|
||||
DWORD Reserved;
|
||||
union {
|
||||
struct {
|
||||
GUID ClassGuid;
|
||||
WCHAR SymbolicLink[ANYSIZE_ARRAY];
|
||||
} DeviceInterface;
|
||||
struct {
|
||||
GUID EventGuid;
|
||||
LONG NameOffset;
|
||||
DWORD DataSize;
|
||||
BYTE Data[ANYSIZE_ARRAY];
|
||||
} DeviceHandle;
|
||||
struct {
|
||||
WCHAR InstanceId[ANYSIZE_ARRAY];
|
||||
} DeviceInstance;
|
||||
} u;
|
||||
} CM_NOTIFY_EVENT_DATA, * PCM_NOTIFY_EVENT_DATA;
|
||||
|
||||
typedef DWORD (CALLBACK *PCM_NOTIFY_CALLBACK)(HCMNOTIFICATION hNotify, PVOID Context, CM_NOTIFY_ACTION Action, PCM_NOTIFY_EVENT_DATA EventData, DWORD EventDataSize);
|
||||
|
||||
typedef DWORD (WINAPI *CM_Register_NotificationFunc)(PCM_NOTIFY_FILTER pFilter, PVOID pContext, PCM_NOTIFY_CALLBACK pCallback, PHCMNOTIFICATION pNotifyContext);
|
||||
typedef DWORD (WINAPI *CM_Unregister_NotificationFunc)(HCMNOTIFICATION NotifyContext);
|
||||
|
||||
/* local variables */
|
||||
static SDL_bool s_bJoystickThread = SDL_FALSE;
|
||||
static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE;
|
||||
@@ -66,35 +137,64 @@ static SDL_cond *s_condJoystickThread = NULL;
|
||||
static SDL_mutex *s_mutexJoyStickEnum = NULL;
|
||||
static SDL_Thread *s_joystickThread = NULL;
|
||||
static SDL_bool s_bJoystickThreadQuit = SDL_FALSE;
|
||||
static GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
|
||||
|
||||
JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */
|
||||
|
||||
#ifdef __WINRT__
|
||||
#ifndef __WINRT__
|
||||
static HMODULE cfgmgr32_lib_handle;
|
||||
static CM_Register_NotificationFunc CM_Register_Notification;
|
||||
static CM_Unregister_NotificationFunc CM_Unregister_Notification;
|
||||
static HCMNOTIFICATION s_DeviceNotificationFuncHandle;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int unused;
|
||||
} SDL_DeviceNotificationData;
|
||||
|
||||
static void
|
||||
SDL_CleanupDeviceNotification(SDL_DeviceNotificationData *data)
|
||||
static DWORD CALLBACK
|
||||
SDL_DeviceNotificationFunc(HCMNOTIFICATION hNotify, PVOID context, CM_NOTIFY_ACTION action, PCM_NOTIFY_EVENT_DATA eventData, DWORD event_data_size)
|
||||
{
|
||||
if (action == CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL ||
|
||||
action == CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL) {
|
||||
s_bWindowsDeviceChanged = SDL_TRUE;
|
||||
}
|
||||
return ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
static int
|
||||
SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data)
|
||||
static void
|
||||
SDL_CleanupDeviceNotificationFunc(void)
|
||||
{
|
||||
return 0;
|
||||
if (cfgmgr32_lib_handle) {
|
||||
if (s_DeviceNotificationFuncHandle) {
|
||||
CM_Unregister_Notification(s_DeviceNotificationFuncHandle);
|
||||
s_DeviceNotificationFuncHandle = NULL;
|
||||
}
|
||||
|
||||
FreeLibrary(cfgmgr32_lib_handle);
|
||||
cfgmgr32_lib_handle = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex)
|
||||
SDL_CreateDeviceNotificationFunc(void)
|
||||
{
|
||||
cfgmgr32_lib_handle = LoadLibraryA("cfgmgr32.dll");
|
||||
if (cfgmgr32_lib_handle) {
|
||||
CM_Register_Notification = (CM_Register_NotificationFunc)GetProcAddress(cfgmgr32_lib_handle, "CM_Register_Notification");
|
||||
CM_Unregister_Notification = (CM_Unregister_NotificationFunc)GetProcAddress(cfgmgr32_lib_handle, "CM_Unregister_Notification");
|
||||
if (CM_Register_Notification && CM_Unregister_Notification) {
|
||||
CM_NOTIFY_FILTER notify_filter;
|
||||
|
||||
SDL_zero(notify_filter);
|
||||
notify_filter.cbSize = sizeof(notify_filter);
|
||||
notify_filter.FilterType = CM_NOTIFY_FILTER_TYPE_DEVICEINTERFACE;
|
||||
notify_filter.u.DeviceInterface.ClassGuid = GUID_DEVINTERFACE_HID;
|
||||
if (CM_Register_Notification(¬ify_filter, NULL, SDL_DeviceNotificationFunc, &s_DeviceNotificationFuncHandle) == CR_SUCCESS) {
|
||||
return SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_CleanupDeviceNotificationFunc();
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
#else /* !__WINRT__ */
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HRESULT coinitialized;
|
||||
@@ -164,7 +264,6 @@ static int
|
||||
SDL_CreateDeviceNotification(SDL_DeviceNotificationData *data)
|
||||
{
|
||||
DEV_BROADCAST_DEVICEINTERFACE dbh;
|
||||
GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
|
||||
|
||||
SDL_zerop(data);
|
||||
|
||||
@@ -228,8 +327,6 @@ SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data, SDL_mutex *mutex
|
||||
return (lastret != -1) ? SDL_TRUE : SDL_FALSE;
|
||||
}
|
||||
|
||||
#endif /* __WINRT__ */
|
||||
|
||||
static SDL_DeviceNotificationData s_notification_data;
|
||||
|
||||
/* Function/thread to scan the system for joysticks. */
|
||||
@@ -310,9 +407,7 @@ SDL_StopJoystickThread(void)
|
||||
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);
|
||||
@@ -324,6 +419,8 @@ SDL_StopJoystickThread(void)
|
||||
s_joystickThread = NULL;
|
||||
}
|
||||
|
||||
#endif /* !__WINRT__ */
|
||||
|
||||
void WINDOWS_AddJoystickDevice(JoyStick_DeviceData *device)
|
||||
{
|
||||
device->send_add_event = SDL_TRUE;
|
||||
@@ -356,15 +453,9 @@ WINDOWS_JoystickInit(void)
|
||||
|
||||
WINDOWS_JoystickDetect();
|
||||
|
||||
#ifdef __WINRT__
|
||||
/* FIXME: WinRT silently does not support device notifications.
|
||||
* Revisit this if UWP ever adds support in a future release.
|
||||
*/
|
||||
s_bJoystickThread = SDL_TRUE;
|
||||
if (SDL_StartJoystickThread() < 0) {
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
#ifndef __WINRT__
|
||||
SDL_CreateDeviceNotificationFunc();
|
||||
|
||||
s_bJoystickThread = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_THREAD, SDL_FALSE);
|
||||
if (s_bJoystickThread) {
|
||||
if (SDL_StartJoystickThread() < 0) {
|
||||
@@ -526,7 +617,7 @@ WINDOWS_JoystickGetDeviceInstanceID(int device_index)
|
||||
It returns 0, or -1 if there is an error.
|
||||
*/
|
||||
static int
|
||||
WINDOWS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
||||
WINDOWS_JoystickOpen(SDL_Joystick *joystick, int device_index)
|
||||
{
|
||||
JoyStick_DeviceData *device = SYS_Joystick;
|
||||
int index;
|
||||
@@ -552,7 +643,7 @@ WINDOWS_JoystickOpen(SDL_Joystick * joystick, int device_index)
|
||||
}
|
||||
|
||||
static int
|
||||
WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
||||
WINDOWS_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble)
|
||||
{
|
||||
if (joystick->hwdata->bXInputDevice) {
|
||||
return SDL_XINPUT_JoystickRumble(joystick, low_frequency_rumble, high_frequency_rumble);
|
||||
@@ -562,19 +653,25 @@ WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uin
|
||||
}
|
||||
|
||||
static int
|
||||
WINDOWS_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
|
||||
WINDOWS_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
WINDOWS_JoystickHasLED(SDL_Joystick * joystick)
|
||||
WINDOWS_JoystickHasLED(SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
static int
|
||||
WINDOWS_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
|
||||
WINDOWS_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static int
|
||||
WINDOWS_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
@@ -586,7 +683,7 @@ WINDOWS_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
|
||||
}
|
||||
|
||||
static void
|
||||
WINDOWS_JoystickUpdate(SDL_Joystick * joystick)
|
||||
WINDOWS_JoystickUpdate(SDL_Joystick *joystick)
|
||||
{
|
||||
if (!joystick->hwdata) {
|
||||
return;
|
||||
@@ -601,7 +698,7 @@ WINDOWS_JoystickUpdate(SDL_Joystick * joystick)
|
||||
|
||||
/* Function to close a joystick after use */
|
||||
static void
|
||||
WINDOWS_JoystickClose(SDL_Joystick * joystick)
|
||||
WINDOWS_JoystickClose(SDL_Joystick *joystick)
|
||||
{
|
||||
if (joystick->hwdata->bXInputDevice) {
|
||||
SDL_XINPUT_JoystickClose(joystick);
|
||||
@@ -626,12 +723,16 @@ WINDOWS_JoystickQuit(void)
|
||||
}
|
||||
SYS_Joystick = NULL;
|
||||
|
||||
#ifndef __WINRT__
|
||||
if (s_bJoystickThread) {
|
||||
SDL_StopJoystickThread();
|
||||
} else {
|
||||
SDL_CleanupDeviceNotification(&s_notification_data);
|
||||
}
|
||||
|
||||
SDL_CleanupDeviceNotificationFunc();
|
||||
#endif
|
||||
|
||||
SDL_DINPUT_JoystickQuit();
|
||||
SDL_XINPUT_JoystickQuit();
|
||||
|
||||
@@ -659,6 +760,7 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
|
||||
WINDOWS_JoystickRumbleTriggers,
|
||||
WINDOWS_JoystickHasLED,
|
||||
WINDOWS_JoystickSetLED,
|
||||
WINDOWS_JoystickSendEffect,
|
||||
WINDOWS_JoystickSetSensorsEnabled,
|
||||
WINDOWS_JoystickUpdate,
|
||||
WINDOWS_JoystickClose,
|
||||
@@ -666,6 +768,13 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
|
||||
WINDOWS_JoystickGetGamepadMapping
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#if SDL_JOYSTICK_RAWINPUT
|
||||
/* The RAWINPUT driver needs the device notification setup above */
|
||||
#error SDL_JOYSTICK_RAWINPUT requires SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT
|
||||
#endif
|
||||
|
||||
#endif /* SDL_JOYSTICK_DINPUT || SDL_JOYSTICK_XINPUT */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
Reference in New Issue
Block a user