Initial support for hotplugging mice and keyboards

main
Sam Lantinga 2024-03-20 06:58:00 -07:00
parent c33e4c998d
commit 2fe1a6a279
44 changed files with 961 additions and 321 deletions

View File

@ -143,12 +143,16 @@ typedef enum
SDL_EVENT_TEXT_INPUT, /**< Keyboard text input */ SDL_EVENT_TEXT_INPUT, /**< Keyboard text input */
SDL_EVENT_KEYMAP_CHANGED, /**< Keymap changed due to a system event such as an SDL_EVENT_KEYMAP_CHANGED, /**< Keymap changed due to a system event such as an
input language or keyboard layout change. */ input language or keyboard layout change. */
SDL_EVENT_KEYBOARD_ADDED, /**< A new keyboard has been inserted into the system */
SDL_EVENT_KEYBOARD_REMOVED, /**< A keyboard has been removed */
/* Mouse events */ /* Mouse events */
SDL_EVENT_MOUSE_MOTION = 0x400, /**< Mouse moved */ SDL_EVENT_MOUSE_MOTION = 0x400, /**< Mouse moved */
SDL_EVENT_MOUSE_BUTTON_DOWN, /**< Mouse button pressed */ SDL_EVENT_MOUSE_BUTTON_DOWN, /**< Mouse button pressed */
SDL_EVENT_MOUSE_BUTTON_UP, /**< Mouse button released */ SDL_EVENT_MOUSE_BUTTON_UP, /**< Mouse button released */
SDL_EVENT_MOUSE_WHEEL, /**< Mouse wheel motion */ SDL_EVENT_MOUSE_WHEEL, /**< Mouse wheel motion */
SDL_EVENT_MOUSE_ADDED, /**< A new mouse has been inserted into the system */
SDL_EVENT_MOUSE_REMOVED, /**< A mouse has been removed */
/* Joystick events */ /* Joystick events */
SDL_EVENT_JOYSTICK_AXIS_MOTION = 0x600, /**< Joystick axis motion */ SDL_EVENT_JOYSTICK_AXIS_MOTION = 0x600, /**< Joystick axis motion */
@ -270,6 +274,17 @@ typedef struct SDL_WindowEvent
Sint32 data2; /**< event dependent data */ Sint32 data2; /**< event dependent data */
} SDL_WindowEvent; } SDL_WindowEvent;
/**
* Keyboard device event structure (event.kdevice.*)
*/
typedef struct SDL_KeyboardDeviceEvent
{
SDL_EventType type; /**< ::SDL_EVENT_KEYBOARD_ADDED or ::SDL_EVENT_KEYBOARD_REMOVED */
Uint32 reserved;
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_KeyboardID which; /**< The keyboard instance id */
} SDL_KeyboardDeviceEvent;
/** /**
* Keyboard button event structure (event.key.*) * Keyboard button event structure (event.key.*)
*/ */
@ -279,6 +294,7 @@ typedef struct SDL_KeyboardEvent
Uint32 reserved; Uint32 reserved;
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */ Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_WindowID windowID; /**< The window with keyboard focus, if any */ SDL_WindowID windowID; /**< The window with keyboard focus, if any */
SDL_KeyboardID which; /**< The keyboard instance id, or 0 if unknown or virtual */
Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */ Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */
Uint8 repeat; /**< Non-zero if this is a key repeat */ Uint8 repeat; /**< Non-zero if this is a key repeat */
Uint8 padding2; Uint8 padding2;
@ -320,6 +336,17 @@ typedef struct SDL_TextInputEvent
char *text; /**< The input text */ char *text; /**< The input text */
} SDL_TextInputEvent; } SDL_TextInputEvent;
/**
* Mouse device event structure (event.mdevice.*)
*/
typedef struct SDL_MouseDeviceEvent
{
SDL_EventType type; /**< ::SDL_EVENT_MOUSE_ADDED or ::SDL_EVENT_MOUSE_REMOVED */
Uint32 reserved;
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_MouseID which; /**< The mouse instance id */
} SDL_MouseDeviceEvent;
/** /**
* Mouse motion event structure (event.motion.*) * Mouse motion event structure (event.motion.*)
*/ */
@ -718,21 +745,23 @@ typedef union SDL_Event
SDL_CommonEvent common; /**< Common event data */ SDL_CommonEvent common; /**< Common event data */
SDL_DisplayEvent display; /**< Display event data */ SDL_DisplayEvent display; /**< Display event data */
SDL_WindowEvent window; /**< Window event data */ SDL_WindowEvent window; /**< Window event data */
SDL_KeyboardDeviceEvent kdevice; /**< Keyboard device change event data */
SDL_KeyboardEvent key; /**< Keyboard event data */ SDL_KeyboardEvent key; /**< Keyboard event data */
SDL_TextEditingEvent edit; /**< Text editing event data */ SDL_TextEditingEvent edit; /**< Text editing event data */
SDL_TextInputEvent text; /**< Text input event data */ SDL_TextInputEvent text; /**< Text input event data */
SDL_MouseDeviceEvent mdevice; /**< Mouse device change event data */
SDL_MouseMotionEvent motion; /**< Mouse motion event data */ SDL_MouseMotionEvent motion; /**< Mouse motion event data */
SDL_MouseButtonEvent button; /**< Mouse button event data */ SDL_MouseButtonEvent button; /**< Mouse button event data */
SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */ SDL_MouseWheelEvent wheel; /**< Mouse wheel event data */
SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */
SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */ SDL_JoyAxisEvent jaxis; /**< Joystick axis event data */
SDL_JoyBallEvent jball; /**< Joystick ball event data */ SDL_JoyBallEvent jball; /**< Joystick ball event data */
SDL_JoyHatEvent jhat; /**< Joystick hat event data */ SDL_JoyHatEvent jhat; /**< Joystick hat event data */
SDL_JoyButtonEvent jbutton; /**< Joystick button event data */ SDL_JoyButtonEvent jbutton; /**< Joystick button event data */
SDL_JoyDeviceEvent jdevice; /**< Joystick device change event data */
SDL_JoyBatteryEvent jbattery; /**< Joystick battery event data */ SDL_JoyBatteryEvent jbattery; /**< Joystick battery event data */
SDL_GamepadDeviceEvent gdevice; /**< Gamepad device event data */
SDL_GamepadAxisEvent gaxis; /**< Gamepad axis event data */ SDL_GamepadAxisEvent gaxis; /**< Gamepad axis event data */
SDL_GamepadButtonEvent gbutton; /**< Gamepad button event data */ SDL_GamepadButtonEvent gbutton; /**< Gamepad button event data */
SDL_GamepadDeviceEvent gdevice; /**< Gamepad device event data */
SDL_GamepadTouchpadEvent gtouchpad; /**< Gamepad touchpad event data */ SDL_GamepadTouchpadEvent gtouchpad; /**< Gamepad touchpad event data */
SDL_GamepadSensorEvent gsensor; /**< Gamepad sensor event data */ SDL_GamepadSensorEvent gsensor; /**< Gamepad sensor event data */
SDL_AudioDeviceEvent adevice; /**< Audio device event data */ SDL_AudioDeviceEvent adevice; /**< Audio device event data */

View File

@ -389,6 +389,17 @@ extern DECLSPEC char * SDLCALL SDL_GetGamepadMapping(SDL_Gamepad *gamepad);
*/ */
extern DECLSPEC int SDLCALL SDL_SetGamepadMapping(SDL_JoystickID instance_id, const char *mapping); extern DECLSPEC int SDLCALL SDL_SetGamepadMapping(SDL_JoystickID instance_id, const char *mapping);
/**
* Return whether a gamepad is currently connected.
*
* \returns SDL_TRUE if a gamepad is connected, SDL_FALSE otherwise.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GetGamepads
*/
extern DECLSPEC SDL_bool SDLCALL SDL_HasGamepad(void);
/** /**
* Get a list of currently connected gamepads. * Get a list of currently connected gamepads.
* *
@ -399,6 +410,7 @@ extern DECLSPEC int SDLCALL SDL_SetGamepadMapping(SDL_JoystickID instance_id, co
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HasGamepad
* \sa SDL_OpenGamepad * \sa SDL_OpenGamepad
*/ */
extern DECLSPEC SDL_JoystickID *SDLCALL SDL_GetGamepads(int *count); extern DECLSPEC SDL_JoystickID *SDLCALL SDL_GetGamepads(int *count);

View File

@ -137,6 +137,17 @@ extern DECLSPEC void SDLCALL SDL_LockJoysticks(void) SDL_ACQUIRE(SDL_joystick_lo
*/ */
extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void) SDL_RELEASE(SDL_joystick_lock); extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void) SDL_RELEASE(SDL_joystick_lock);
/**
* Return whether a joystick is currently connected.
*
* \returns SDL_TRUE if a joystick is connected, SDL_FALSE otherwise.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GetJoysticks
*/
extern DECLSPEC SDL_bool SDLCALL SDL_HasJoystick(void);
/** /**
* Get a list of currently connected joysticks. * Get a list of currently connected joysticks.
* *
@ -147,6 +158,7 @@ extern DECLSPEC void SDLCALL SDL_UnlockJoysticks(void) SDL_RELEASE(SDL_joystick_
* *
* \since This function is available since SDL 3.0.0. * \since This function is available since SDL 3.0.0.
* *
* \sa SDL_HasJoystick
* \sa SDL_OpenJoystick * \sa SDL_OpenJoystick
*/ */
extern DECLSPEC SDL_JoystickID *SDLCALL SDL_GetJoysticks(int *count); extern DECLSPEC SDL_JoystickID *SDLCALL SDL_GetJoysticks(int *count);

View File

@ -39,6 +39,8 @@
extern "C" { extern "C" {
#endif #endif
typedef Uint32 SDL_KeyboardID;
/** /**
* The SDL keysym structure, used in key events. * The SDL keysym structure, used in key events.
* *
@ -54,6 +56,31 @@ typedef struct SDL_Keysym
/* Function prototypes */ /* Function prototypes */
/**
* Return whether a keyboard is currently connected.
*
* \returns SDL_TRUE if a keyboard is connected, SDL_FALSE otherwise.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GetKeyboards
*/
extern DECLSPEC SDL_bool SDLCALL SDL_HasKeyboard(void);
/**
* Get a list of currently connected keyboards.
*
* \param count a pointer filled in with the number of keyboards returned
* \returns a 0 terminated array of keyboards instance IDs which should be
* freed with SDL_free(), or NULL on error; call SDL_GetError() for
* more details.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_HasKeyboard
*/
extern DECLSPEC SDL_KeyboardID *SDLCALL SDL_GetKeyboards(int *count);
/** /**
* Query the window which currently has keyboard focus. * Query the window which currently has keyboard focus.
* *

View File

@ -81,6 +81,31 @@ typedef enum
/* Function prototypes */ /* Function prototypes */
/**
* Return whether a mouse is currently connected.
*
* \returns SDL_TRUE if a mouse is connected, SDL_FALSE otherwise.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_GetMice
*/
extern DECLSPEC SDL_bool SDLCALL SDL_HasMouse(void);
/**
* Get a list of currently connected mice.
*
* \param count a pointer filled in with the number of mice returned
* \returns a 0 terminated array of mouse instance IDs which should be
* freed with SDL_free(), or NULL on error; call SDL_GetError() for
* more details.
*
* \since This function is available since SDL 3.0.0.
*
* \sa SDL_HasMouse
*/
extern DECLSPEC SDL_MouseID *SDLCALL SDL_GetMice(int *count);
/** /**
* Get the window which currently has mouse focus. * Get the window which currently has mouse focus.
* *

View File

@ -303,7 +303,7 @@ class SDL_BLooper : public BLooper
return; return;
} }
HAIKU_SetKeyState(scancode, state); HAIKU_SetKeyState(scancode, state);
SDL_SendKeyboardKey(0, state, HAIKU_GetScancodeFromBeKey(scancode)); SDL_SendKeyboardKey(0, 0, state, HAIKU_GetScancodeFromBeKey(scancode));
if (state == SDL_PRESSED && SDL_EventEnabled(SDL_EVENT_TEXT_INPUT)) { if (state == SDL_PRESSED && SDL_EventEnabled(SDL_EVENT_TEXT_INPUT)) {
const int8 *keyUtf8; const int8 *keyUtf8;

View File

@ -375,9 +375,9 @@ void SDL_EVDEV_Poll(void)
scan_code = SDL_EVDEV_translate_keycode(event->code); scan_code = SDL_EVDEV_translate_keycode(event->code);
if (scan_code != SDL_SCANCODE_UNKNOWN) { if (scan_code != SDL_SCANCODE_UNKNOWN) {
if (event->value == 0) { if (event->value == 0) {
SDL_SendKeyboardKey(SDL_EVDEV_GetEventTimestamp(event), SDL_RELEASED, scan_code); SDL_SendKeyboardKey(SDL_EVDEV_GetEventTimestamp(event), (SDL_KeyboardID)item->fd, SDL_RELEASED, scan_code);
} else if (event->value == 1 || event->value == 2 /* key repeated */) { } else if (event->value == 1 || event->value == 2 /* key repeated */) {
SDL_SendKeyboardKey(SDL_EVDEV_GetEventTimestamp(event), SDL_PRESSED, scan_code); SDL_SendKeyboardKey(SDL_EVDEV_GetEventTimestamp(event), (SDL_KeyboardID)item->fd, SDL_PRESSED, scan_code);
} }
} }
SDL_EVDEV_kbd_keycode(_this->kbd, event->code, event->value); SDL_EVDEV_kbd_keycode(_this->kbd, event->code, event->value);

View File

@ -553,22 +553,22 @@ static void Translate_to_keycode(SDL_WSCONS_input_data *input, int type, keysym_
switch (keyDesc.command) { switch (keyDesc.command) {
case KS_Cmd_ScrollBack: case KS_Cmd_ScrollBack:
{ {
SDL_SendKeyboardKey(0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_PAGEUP); SDL_SendKeyboardKey(0, 0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_PAGEUP);
return; return;
} }
case KS_Cmd_ScrollFwd: case KS_Cmd_ScrollFwd:
{ {
SDL_SendKeyboardKey(0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_PAGEDOWN); SDL_SendKeyboardKey(0, 0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_PAGEDOWN);
return; return;
} }
} }
for (i = 0; i < sizeof(conversion_table) / sizeof(struct wscons_keycode_to_SDL); i++) { for (i = 0; i < sizeof(conversion_table) / sizeof(struct wscons_keycode_to_SDL); i++) {
if (conversion_table[i].sourcekey == group[0]) { if (conversion_table[i].sourcekey == group[0]) {
SDL_SendKeyboardKey(0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, conversion_table[i].targetKey); SDL_SendKeyboardKey(0, 0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, conversion_table[i].targetKey);
return; return;
} }
} }
SDL_SendKeyboardKey(0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_UNKNOWN); SDL_SendKeyboardKey(0, 0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, SDL_SCANCODE_UNKNOWN);
} }
static void updateKeyboard(SDL_WSCONS_input_data *input) static void updateKeyboard(SDL_WSCONS_input_data *input)
@ -802,13 +802,13 @@ static void updateKeyboard(SDL_WSCONS_input_data *input)
} break; } break;
case WSCONS_EVENT_ALL_KEYS_UP: case WSCONS_EVENT_ALL_KEYS_UP:
for (i = 0; i < SDL_NUM_SCANCODES; i++) { for (i = 0; i < SDL_NUM_SCANCODES; i++) {
SDL_SendKeyboardKey(0, SDL_RELEASED, i); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, i);
} }
break; break;
} }
if (input->type == WSKBD_TYPE_USB && events[i].value <= 0xE7) if (input->type == WSKBD_TYPE_USB && events[i].value <= 0xE7)
SDL_SendKeyboardKey(0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)events[i].value); SDL_SendKeyboardKey(0, 0, type == WSCONS_EVENT_KEY_DOWN ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)events[i].value);
else else
Translate_to_keycode(input, type, events[i].value); Translate_to_keycode(input, type, events[i].value);

View File

@ -35,6 +35,7 @@ HidP_GetData_t SDL_HidP_GetData;
static HMODULE s_pHIDDLL = 0; static HMODULE s_pHIDDLL = 0;
static int s_HIDDLLRefCount = 0; static int s_HIDDLLRefCount = 0;
int WIN_LoadHIDDLL(void) int WIN_LoadHIDDLL(void)
{ {
if (s_pHIDDLL) { if (s_pHIDDLL) {
@ -82,3 +83,174 @@ void WIN_UnloadHIDDLL(void)
} }
#endif /* !SDL_PLATFORM_WINRT */ #endif /* !SDL_PLATFORM_WINRT */
#if !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
/* CM_Register_Notification definitions */
#define CR_SUCCESS 0
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);
static GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } };
static int s_DeviceNotificationsRequested;
static HMODULE cfgmgr32_lib_handle;
static CM_Register_NotificationFunc CM_Register_Notification;
static CM_Unregister_NotificationFunc CM_Unregister_Notification;
static HCMNOTIFICATION s_DeviceNotificationFuncHandle;
static Uint64 s_LastDeviceNotification = 1;
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_LastDeviceNotification = SDL_GetTicksNS();
}
return ERROR_SUCCESS;
}
void WIN_InitDeviceNotification(void)
{
++s_DeviceNotificationsRequested;
if (s_DeviceNotificationsRequested > 1) {
return;
}
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(&notify_filter, NULL, SDL_DeviceNotificationFunc, &s_DeviceNotificationFuncHandle) == CR_SUCCESS) {
return;
}
}
}
// FIXME: Should we log errors?
}
Uint64 WIN_GetLastDeviceNotification(void)
{
return s_LastDeviceNotification;
}
void WIN_QuitDeviceNotification(void)
{
if (--s_DeviceNotificationsRequested > 0) {
return;
}
/* Make sure we have balanced calls to init/quit */
SDL_assert(s_DeviceNotificationsRequested == 0);
if (cfgmgr32_lib_handle) {
if (s_DeviceNotificationFuncHandle && CM_Unregister_Notification) {
CM_Unregister_Notification(s_DeviceNotificationFuncHandle);
s_DeviceNotificationFuncHandle = NULL;
}
FreeLibrary(cfgmgr32_lib_handle);
cfgmgr32_lib_handle = NULL;
}
}
#else
void WIN_InitDeviceNotification(void)
{
}
Uint64 WIN_GetLastDeviceNotification( void )
{
return 0;
}
void WIN_QuitDeviceNotification(void)
{
}
#endif // !SDL_PLATFORM_WINRT && !SDL_PLATFORM_XBOXONE && !SDL_PLATFORM_XBOXSERIES

View File

@ -193,12 +193,12 @@ typedef struct
extern int WIN_LoadHIDDLL(void); extern int WIN_LoadHIDDLL(void);
extern void WIN_UnloadHIDDLL(void); extern void WIN_UnloadHIDDLL(void);
typedef BOOLEAN(WINAPI *HidD_GetString_t)(HANDLE HidDeviceObject, PVOID Buffer, ULONG BufferLength); typedef BOOLEAN (WINAPI *HidD_GetString_t)(HANDLE HidDeviceObject, PVOID Buffer, ULONG BufferLength);
typedef NTSTATUS(WINAPI *HidP_GetCaps_t)(PHIDP_PREPARSED_DATA PreparsedData, PHIDP_CAPS Capabilities); typedef NTSTATUS (WINAPI *HidP_GetCaps_t)(PHIDP_PREPARSED_DATA PreparsedData, PHIDP_CAPS Capabilities);
typedef NTSTATUS(WINAPI *HidP_GetButtonCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData); typedef NTSTATUS (WINAPI *HidP_GetButtonCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_BUTTON_CAPS ButtonCaps, PUSHORT ButtonCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
typedef NTSTATUS(WINAPI *HidP_GetValueCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS ValueCaps, PUSHORT ValueCapsLength, PHIDP_PREPARSED_DATA PreparsedData); typedef NTSTATUS (WINAPI *HidP_GetValueCaps_t)(HIDP_REPORT_TYPE ReportType, PHIDP_VALUE_CAPS ValueCaps, PUSHORT ValueCapsLength, PHIDP_PREPARSED_DATA PreparsedData);
typedef ULONG(WINAPI *HidP_MaxDataListLength_t)(HIDP_REPORT_TYPE ReportType, PHIDP_PREPARSED_DATA PreparsedData); typedef ULONG (WINAPI *HidP_MaxDataListLength_t)(HIDP_REPORT_TYPE ReportType, PHIDP_PREPARSED_DATA PreparsedData);
typedef NTSTATUS(WINAPI *HidP_GetData_t)(HIDP_REPORT_TYPE ReportType, PHIDP_DATA DataList, PULONG DataLength, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength); typedef NTSTATUS (WINAPI *HidP_GetData_t)(HIDP_REPORT_TYPE ReportType, PHIDP_DATA DataList, PULONG DataLength, PHIDP_PREPARSED_DATA PreparsedData, PCHAR Report, ULONG ReportLength);
extern HidD_GetString_t SDL_HidD_GetManufacturerString; extern HidD_GetString_t SDL_HidD_GetManufacturerString;
extern HidD_GetString_t SDL_HidD_GetProductString; extern HidD_GetString_t SDL_HidD_GetProductString;
@ -210,4 +210,9 @@ extern HidP_GetData_t SDL_HidP_GetData;
#endif /* !SDL_PLATFORM_WINRT */ #endif /* !SDL_PLATFORM_WINRT */
void WIN_InitDeviceNotification(void);
Uint64 WIN_GetLastDeviceNotification(void);
void WIN_QuitDeviceNotification(void);
#endif /* SDL_hid_h_ */ #endif /* SDL_hid_h_ */

View File

@ -724,8 +724,8 @@ void SDL_WinRTApp::OnCharacterReceived(Windows::UI::Core::CoreWindow ^ sender, W
template <typename BackButtonEventArgs> template <typename BackButtonEventArgs>
static void WINRT_OnBackButtonPressed(BackButtonEventArgs ^ args) static void WINRT_OnBackButtonPressed(BackButtonEventArgs ^ args)
{ {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_AC_BACK); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_AC_BACK);
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_AC_BACK); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_AC_BACK);
if (SDL_GetHintBoolean(SDL_HINT_WINRT_HANDLE_BACK_BUTTON, SDL_FALSE)) { if (SDL_GetHintBoolean(SDL_HINT_WINRT_HANDLE_BACK_BUTTON, SDL_FALSE)) {
args->Handled = true; args->Handled = true;

View File

@ -320,11 +320,13 @@ SDL3_0.0.0 {
SDL_GetKeyName; SDL_GetKeyName;
SDL_GetKeyboardFocus; SDL_GetKeyboardFocus;
SDL_GetKeyboardState; SDL_GetKeyboardState;
SDL_GetKeyboards;
SDL_GetLogOutputFunction; SDL_GetLogOutputFunction;
SDL_GetMasksForPixelFormatEnum; SDL_GetMasksForPixelFormatEnum;
SDL_GetMaxHapticEffects; SDL_GetMaxHapticEffects;
SDL_GetMaxHapticEffectsPlaying; SDL_GetMaxHapticEffectsPlaying;
SDL_GetMemoryFunctions; SDL_GetMemoryFunctions;
SDL_GetMice;
SDL_GetModState; SDL_GetModState;
SDL_GetMouseFocus; SDL_GetMouseFocus;
SDL_GetMouseState; SDL_GetMouseState;
@ -487,9 +489,13 @@ SDL3_0.0.0 {
SDL_HasClipboardText; SDL_HasClipboardText;
SDL_HasEvent; SDL_HasEvent;
SDL_HasEvents; SDL_HasEvents;
SDL_HasGamepad;
SDL_HasJoystick;
SDL_HasKeyboard;
SDL_HasLASX; SDL_HasLASX;
SDL_HasLSX; SDL_HasLSX;
SDL_HasMMX; SDL_HasMMX;
SDL_HasMouse;
SDL_HasNEON; SDL_HasNEON;
SDL_HasPrimarySelectionText; SDL_HasPrimarySelectionText;
SDL_HasProperty; SDL_HasProperty;

View File

@ -345,11 +345,13 @@
#define SDL_GetKeyName SDL_GetKeyName_REAL #define SDL_GetKeyName SDL_GetKeyName_REAL
#define SDL_GetKeyboardFocus SDL_GetKeyboardFocus_REAL #define SDL_GetKeyboardFocus SDL_GetKeyboardFocus_REAL
#define SDL_GetKeyboardState SDL_GetKeyboardState_REAL #define SDL_GetKeyboardState SDL_GetKeyboardState_REAL
#define SDL_GetKeyboards SDL_GetKeyboards_REAL
#define SDL_GetLogOutputFunction SDL_GetLogOutputFunction_REAL #define SDL_GetLogOutputFunction SDL_GetLogOutputFunction_REAL
#define SDL_GetMasksForPixelFormatEnum SDL_GetMasksForPixelFormatEnum_REAL #define SDL_GetMasksForPixelFormatEnum SDL_GetMasksForPixelFormatEnum_REAL
#define SDL_GetMaxHapticEffects SDL_GetMaxHapticEffects_REAL #define SDL_GetMaxHapticEffects SDL_GetMaxHapticEffects_REAL
#define SDL_GetMaxHapticEffectsPlaying SDL_GetMaxHapticEffectsPlaying_REAL #define SDL_GetMaxHapticEffectsPlaying SDL_GetMaxHapticEffectsPlaying_REAL
#define SDL_GetMemoryFunctions SDL_GetMemoryFunctions_REAL #define SDL_GetMemoryFunctions SDL_GetMemoryFunctions_REAL
#define SDL_GetMice SDL_GetMice_REAL
#define SDL_GetModState SDL_GetModState_REAL #define SDL_GetModState SDL_GetModState_REAL
#define SDL_GetMouseFocus SDL_GetMouseFocus_REAL #define SDL_GetMouseFocus SDL_GetMouseFocus_REAL
#define SDL_GetMouseState SDL_GetMouseState_REAL #define SDL_GetMouseState SDL_GetMouseState_REAL
@ -512,9 +514,13 @@
#define SDL_HasClipboardText SDL_HasClipboardText_REAL #define SDL_HasClipboardText SDL_HasClipboardText_REAL
#define SDL_HasEvent SDL_HasEvent_REAL #define SDL_HasEvent SDL_HasEvent_REAL
#define SDL_HasEvents SDL_HasEvents_REAL #define SDL_HasEvents SDL_HasEvents_REAL
#define SDL_HasGamepad SDL_HasGamepad_REAL
#define SDL_HasJoystick SDL_HasJoystick_REAL
#define SDL_HasKeyboard SDL_HasKeyboard_REAL
#define SDL_HasLASX SDL_HasLASX_REAL #define SDL_HasLASX SDL_HasLASX_REAL
#define SDL_HasLSX SDL_HasLSX_REAL #define SDL_HasLSX SDL_HasLSX_REAL
#define SDL_HasMMX SDL_HasMMX_REAL #define SDL_HasMMX SDL_HasMMX_REAL
#define SDL_HasMouse SDL_HasMouse_REAL
#define SDL_HasNEON SDL_HasNEON_REAL #define SDL_HasNEON SDL_HasNEON_REAL
#define SDL_HasPrimarySelectionText SDL_HasPrimarySelectionText_REAL #define SDL_HasPrimarySelectionText SDL_HasPrimarySelectionText_REAL
#define SDL_HasProperty SDL_HasProperty_REAL #define SDL_HasProperty SDL_HasProperty_REAL

View File

@ -383,11 +383,13 @@ SDL_DYNAPI_PROC(SDL_Keycode,SDL_GetKeyFromScancode,(SDL_Scancode a),(a),return)
SDL_DYNAPI_PROC(const char*,SDL_GetKeyName,(SDL_Keycode a),(a),return) SDL_DYNAPI_PROC(const char*,SDL_GetKeyName,(SDL_Keycode a),(a),return)
SDL_DYNAPI_PROC(SDL_Window*,SDL_GetKeyboardFocus,(void),(),return) SDL_DYNAPI_PROC(SDL_Window*,SDL_GetKeyboardFocus,(void),(),return)
SDL_DYNAPI_PROC(const Uint8*,SDL_GetKeyboardState,(int *a),(a),return) SDL_DYNAPI_PROC(const Uint8*,SDL_GetKeyboardState,(int *a),(a),return)
SDL_DYNAPI_PROC(SDL_MouseID*,SDL_GetKeyboards,(int *a),(a),return)
SDL_DYNAPI_PROC(void,SDL_GetLogOutputFunction,(SDL_LogOutputFunction *a, void **b),(a,b),) SDL_DYNAPI_PROC(void,SDL_GetLogOutputFunction,(SDL_LogOutputFunction *a, void **b),(a,b),)
SDL_DYNAPI_PROC(SDL_bool,SDL_GetMasksForPixelFormatEnum,(SDL_PixelFormatEnum a, int *b, Uint32 *c, Uint32 *d, Uint32 *e, Uint32 *f),(a,b,c,d,e,f),return) SDL_DYNAPI_PROC(SDL_bool,SDL_GetMasksForPixelFormatEnum,(SDL_PixelFormatEnum a, int *b, Uint32 *c, Uint32 *d, Uint32 *e, Uint32 *f),(a,b,c,d,e,f),return)
SDL_DYNAPI_PROC(int,SDL_GetMaxHapticEffects,(SDL_Haptic *a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetMaxHapticEffects,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GetMaxHapticEffectsPlaying,(SDL_Haptic *a),(a),return) SDL_DYNAPI_PROC(int,SDL_GetMaxHapticEffectsPlaying,(SDL_Haptic *a),(a),return)
SDL_DYNAPI_PROC(void,SDL_GetMemoryFunctions,(SDL_malloc_func *a, SDL_calloc_func *b, SDL_realloc_func *c, SDL_free_func *d),(a,b,c,d),) SDL_DYNAPI_PROC(void,SDL_GetMemoryFunctions,(SDL_malloc_func *a, SDL_calloc_func *b, SDL_realloc_func *c, SDL_free_func *d),(a,b,c,d),)
SDL_DYNAPI_PROC(SDL_MouseID*,SDL_GetMice,(int *a),(a),return)
SDL_DYNAPI_PROC(SDL_Keymod,SDL_GetModState,(void),(),return) SDL_DYNAPI_PROC(SDL_Keymod,SDL_GetModState,(void),(),return)
SDL_DYNAPI_PROC(SDL_Window*,SDL_GetMouseFocus,(void),(),return) SDL_DYNAPI_PROC(SDL_Window*,SDL_GetMouseFocus,(void),(),return)
SDL_DYNAPI_PROC(Uint32,SDL_GetMouseState,(float *a, float *b),(a,b),return) SDL_DYNAPI_PROC(Uint32,SDL_GetMouseState,(float *a, float *b),(a,b),return)
@ -543,9 +545,13 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_HasClipboardData,(const char *a),(a),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasClipboardText,(void),(),return) SDL_DYNAPI_PROC(SDL_bool,SDL_HasClipboardText,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasEvent,(Uint32 a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_HasEvent,(Uint32 a),(a),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasEvents,(Uint32 a, Uint32 b),(a,b),return) SDL_DYNAPI_PROC(SDL_bool,SDL_HasEvents,(Uint32 a, Uint32 b),(a,b),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasGamepad,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasJoystick,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasKeyboard,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasLASX,(void),(),return) SDL_DYNAPI_PROC(SDL_bool,SDL_HasLASX,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasLSX,(void),(),return) SDL_DYNAPI_PROC(SDL_bool,SDL_HasLSX,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasMMX,(void),(),return) SDL_DYNAPI_PROC(SDL_bool,SDL_HasMMX,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasMouse,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasNEON,(void),(),return) SDL_DYNAPI_PROC(SDL_bool,SDL_HasNEON,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasPrimarySelectionText,(void),(),return) SDL_DYNAPI_PROC(SDL_bool,SDL_HasPrimarySelectionText,(void),(),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasProperty,(SDL_PropertiesID a, const char *b),(a,b),return) SDL_DYNAPI_PROC(SDL_bool,SDL_HasProperty,(SDL_PropertiesID a, const char *b),(a,b),return)

View File

@ -325,6 +325,15 @@ static void SDL_LogEvent(const SDL_Event *event)
SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_DESTROYED); SDL_WINDOWEVENT_CASE(SDL_EVENT_WINDOW_DESTROYED);
#undef SDL_WINDOWEVENT_CASE #undef SDL_WINDOWEVENT_CASE
#define PRINT_KEYDEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%u)", (uint)event->kdevice.timestamp, (uint)event->kdevice.which)
SDL_EVENT_CASE(SDL_EVENT_KEYBOARD_ADDED)
PRINT_KEYDEV_EVENT(event);
break;
SDL_EVENT_CASE(SDL_EVENT_KEYBOARD_REMOVED)
PRINT_KEYDEV_EVENT(event);
break;
#undef PRINT_KEYDEV_EVENT
#define PRINT_KEY_EVENT(event) \ #define PRINT_KEY_EVENT(event) \
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u state=%s repeat=%s scancode=%u keycode=%u mod=%u)", \ (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u state=%s repeat=%s scancode=%u keycode=%u mod=%u)", \
(uint)event->key.timestamp, (uint)event->key.windowID, \ (uint)event->key.timestamp, (uint)event->key.windowID, \
@ -351,6 +360,15 @@ static void SDL_LogEvent(const SDL_Event *event)
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u text='%s')", (uint)event->text.timestamp, (uint)event->text.windowID, event->text.text); (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u text='%s')", (uint)event->text.timestamp, (uint)event->text.windowID, event->text.text);
break; break;
#define PRINT_MOUSEDEV_EVENT(event) (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u which=%u)", (uint)event->mdevice.timestamp, (uint)event->mdevice.which)
SDL_EVENT_CASE(SDL_EVENT_MOUSE_ADDED)
PRINT_MOUSEDEV_EVENT(event);
break;
SDL_EVENT_CASE(SDL_EVENT_MOUSE_REMOVED)
PRINT_MOUSEDEV_EVENT(event);
break;
#undef PRINT_MOUSEDEV_EVENT
SDL_EVENT_CASE(SDL_EVENT_MOUSE_MOTION) SDL_EVENT_CASE(SDL_EVENT_MOUSE_MOTION)
(void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u state=%u x=%g y=%g xrel=%g yrel=%g)", (void)SDL_snprintf(details, sizeof(details), " (timestamp=%u windowid=%u which=%u state=%u x=%g y=%g xrel=%g yrel=%g)",
(uint)event->motion.timestamp, (uint)event->motion.windowID, (uint)event->motion.timestamp, (uint)event->motion.windowID,

View File

@ -55,6 +55,8 @@ struct SDL_Keyboard
}; };
static SDL_Keyboard SDL_keyboard; static SDL_Keyboard SDL_keyboard;
static int SDL_keyboard_count;
static SDL_KeyboardID *SDL_keyboards;
static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = { static const SDL_Keycode SDL_default_keymap[SDL_NUM_SCANCODES] = {
/* 0 */ SDLK_UNKNOWN, /* 0 */ SDLK_UNKNOWN,
@ -678,6 +680,109 @@ int SDL_InitKeyboard(void)
return 0; return 0;
} }
SDL_bool SDL_IsKeyboard(Uint16 vendor, Uint16 product, int num_keys)
{
const int REAL_KEYBOARD_KEY_COUNT = 50;
if (num_keys > 0 && num_keys < REAL_KEYBOARD_KEY_COUNT) {
return SDL_FALSE;
}
/* Eventually we'll have a blacklist of devices that enumerate as keyboards but aren't really */
return SDL_TRUE;
}
void SDL_PrivateKeyboardAdded(SDL_KeyboardID keyboardID)
{
int keyboard_index = -1;
SDL_assert(keyboardID != 0);
for (int i = 0; i < SDL_keyboard_count; ++i) {
if (keyboardID == SDL_keyboards[i]) {
keyboard_index = i;
break;
}
}
if (keyboard_index >= 0) {
/* We already know about this keyboard */
return;
}
SDL_KeyboardID *keyboards = (SDL_KeyboardID *)SDL_realloc(SDL_keyboards, (SDL_keyboard_count + 1) * sizeof(*keyboards));
if (!keyboards) {
return;
}
keyboards[SDL_keyboard_count] = keyboardID;
SDL_keyboards = keyboards;
++SDL_keyboard_count;
SDL_Event event;
SDL_zero(event);
event.type = SDL_EVENT_KEYBOARD_ADDED;
event.kdevice.which = keyboardID;
SDL_PushEvent(&event);
}
void SDL_PrivateKeyboardRemoved(SDL_KeyboardID keyboardID)
{
int keyboard_index = -1;
SDL_assert(keyboardID != 0);
for (int i = 0; i < SDL_keyboard_count; ++i) {
if (keyboardID == SDL_keyboards[i]) {
keyboard_index = i;
break;
}
}
if (keyboard_index < 0) {
/* We don't know about this keyboard */
return;
}
if (keyboard_index != SDL_keyboard_count - 1) {
SDL_memcpy(&SDL_keyboards[keyboard_index], &SDL_keyboards[keyboard_index + 1], (SDL_keyboard_count - keyboard_index - 1) * sizeof(SDL_keyboards[keyboard_index]));
}
--SDL_keyboard_count;
SDL_Event event;
SDL_zero(event);
event.type = SDL_EVENT_KEYBOARD_REMOVED;
event.kdevice.which = keyboardID;
SDL_PushEvent(&event);
}
SDL_bool SDL_HasKeyboard(void)
{
return (SDL_keyboard_count > 0);
}
SDL_KeyboardID *SDL_GetKeyboards(int *count)
{
int i;
SDL_KeyboardID *keyboards;
keyboards = (SDL_JoystickID *)SDL_malloc((SDL_keyboard_count + 1) * sizeof(*keyboards));
if (keyboards) {
if (count) {
*count = SDL_keyboard_count;
}
for (i = 0; i < SDL_keyboard_count; ++i) {
keyboards[i] = SDL_keyboards[i];
}
keyboards[i] = 0;
} else {
if (count) {
*count = 0;
}
}
return keyboards;
}
void SDL_ResetKeyboard(void) void SDL_ResetKeyboard(void)
{ {
SDL_Keyboard *keyboard = &SDL_keyboard; SDL_Keyboard *keyboard = &SDL_keyboard;
@ -688,7 +793,7 @@ void SDL_ResetKeyboard(void)
#endif #endif
for (scancode = (SDL_Scancode)0; scancode < SDL_NUM_SCANCODES; ++scancode) { for (scancode = (SDL_Scancode)0; scancode < SDL_NUM_SCANCODES; ++scancode) {
if (keyboard->keystate[scancode] == SDL_PRESSED) { if (keyboard->keystate[scancode] == SDL_PRESSED) {
SDL_SendKeyboardKey(0, SDL_RELEASED, scancode); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, scancode);
} }
} }
} }
@ -822,7 +927,7 @@ int SDL_SetKeyboardFocus(SDL_Window *window)
return 0; return 0;
} }
static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode) static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
{ {
SDL_Keyboard *keyboard = &SDL_keyboard; SDL_Keyboard *keyboard = &SDL_keyboard;
int posted; int posted;
@ -831,6 +936,13 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, Uint8 sta
Uint8 repeat = SDL_FALSE; Uint8 repeat = SDL_FALSE;
const Uint8 source = flags & KEYBOARD_SOURCE_MASK; const Uint8 source = flags & KEYBOARD_SOURCE_MASK;
if (keyboardID == 0) {
if (source == KEYBOARD_HARDWARE && SDL_keyboard_count > 0) {
/* Assume it's from the first keyboard */
keyboardID = SDL_keyboards[0];
}
}
if (scancode == SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) { if (scancode == SDL_SCANCODE_UNKNOWN || scancode >= SDL_NUM_SCANCODES) {
return 0; return 0;
} }
@ -949,6 +1061,7 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, Uint8 sta
event.key.keysym.sym = keycode; event.key.keysym.sym = keycode;
event.key.keysym.mod = keyboard->modstate; event.key.keysym.mod = keyboard->modstate;
event.key.windowID = keyboard->focus ? keyboard->focus->id : 0; event.key.windowID = keyboard->focus ? keyboard->focus->id : 0;
event.key.which = keyboardID;
posted = (SDL_PushEvent(&event) > 0); posted = (SDL_PushEvent(&event) > 0);
} }
@ -982,43 +1095,43 @@ int SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch)
if (mod & SDL_KMOD_SHIFT) { if (mod & SDL_KMOD_SHIFT) {
/* If the character uses shift, press shift down */ /* If the character uses shift, press shift down */
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_PRESSED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN); SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, 0, SDL_PRESSED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN);
} }
/* Send a keydown and keyup for the character */ /* Send a keydown and keyup for the character */
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_PRESSED, code, SDLK_UNKNOWN); SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, 0, SDL_PRESSED, code, SDLK_UNKNOWN);
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_RELEASED, code, SDLK_UNKNOWN); SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, 0, SDL_RELEASED, code, SDLK_UNKNOWN);
if (mod & SDL_KMOD_SHIFT) { if (mod & SDL_KMOD_SHIFT) {
/* If the character uses shift, release shift */ /* If the character uses shift, release shift */
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_RELEASED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN); SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, 0, SDL_RELEASED, SDL_SCANCODE_LSHIFT, SDLK_UNKNOWN);
} }
return 0; return 0;
} }
int SDL_SendVirtualKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode) int SDL_SendVirtualKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode)
{ {
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, state, scancode, SDLK_UNKNOWN); return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, 0, state, scancode, SDLK_UNKNOWN);
} }
int SDL_SendKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode) int SDL_SendKeyboardKey(Uint64 timestamp, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode)
{ {
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, state, scancode, SDLK_UNKNOWN); return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, keyboardID, state, scancode, SDLK_UNKNOWN);
} }
int SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode) int SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode)
{ {
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, state, scancode, keycode); return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE, keyboardID, state, scancode, keycode);
} }
int SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode) int SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode)
{ {
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_AUTORELEASE, SDL_PRESSED, scancode, SDLK_UNKNOWN); return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_AUTORELEASE, 0, SDL_PRESSED, scancode, SDLK_UNKNOWN);
} }
int SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, Uint8 state, SDL_Scancode scancode) int SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode)
{ {
return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE | KEYBOARD_IGNOREMODIFIERS, state, scancode, SDLK_UNKNOWN); return SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_HARDWARE | KEYBOARD_IGNOREMODIFIERS, keyboardID, state, scancode, SDLK_UNKNOWN);
} }
void SDL_ReleaseAutoReleaseKeys(void) void SDL_ReleaseAutoReleaseKeys(void)
@ -1029,7 +1142,7 @@ void SDL_ReleaseAutoReleaseKeys(void)
if (keyboard->autorelease_pending) { if (keyboard->autorelease_pending) {
for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; ++scancode) { for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; ++scancode) {
if (keyboard->keysource[scancode] == KEYBOARD_AUTORELEASE) { if (keyboard->keysource[scancode] == KEYBOARD_AUTORELEASE) {
SDL_SendKeyboardKeyInternal(0, KEYBOARD_AUTORELEASE, SDL_RELEASED, scancode, SDLK_UNKNOWN); SDL_SendKeyboardKeyInternal(0, KEYBOARD_AUTORELEASE, 0, SDL_RELEASED, scancode, SDLK_UNKNOWN);
} }
} }
keyboard->autorelease_pending = SDL_FALSE; keyboard->autorelease_pending = SDL_FALSE;
@ -1117,6 +1230,9 @@ int SDL_SendEditingText(const char *text, int start, int length)
void SDL_QuitKeyboard(void) void SDL_QuitKeyboard(void)
{ {
SDL_keyboard_count = 0;
SDL_free(SDL_keyboards);
SDL_keyboards = NULL;
} }
const Uint8 *SDL_GetKeyboardState(int *numkeys) const Uint8 *SDL_GetKeyboardState(int *numkeys)

View File

@ -26,6 +26,15 @@
/* Initialize the keyboard subsystem */ /* Initialize the keyboard subsystem */
extern int SDL_InitKeyboard(void); extern int SDL_InitKeyboard(void);
/* Return whether a device is actually a keyboard */
extern SDL_bool SDL_IsKeyboard(Uint16 vendor, Uint16 product, int num_keys);
/* A keyboard has been added to the system */
extern void SDL_PrivateKeyboardAdded(SDL_KeyboardID keyboardID);
/* A keyboard has been removed from the system */
extern void SDL_PrivateKeyboardRemoved(SDL_KeyboardID keyboardID);
/* Get the default keymap */ /* Get the default keymap */
extern void SDL_GetDefaultKeymap(SDL_Keycode *keymap); extern void SDL_GetDefaultKeymap(SDL_Keycode *keymap);
@ -53,13 +62,13 @@ extern int SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch);
extern int SDL_SendVirtualKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode); extern int SDL_SendVirtualKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode);
/* Send a keyboard key event */ /* Send a keyboard key event */
extern int SDL_SendKeyboardKey(Uint64 timestamp, Uint8 state, SDL_Scancode scancode); extern int SDL_SendKeyboardKey(Uint64 timestamp, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode);
extern int SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode); extern int SDL_SendKeyboardKeyAutoRelease(Uint64 timestamp, SDL_Scancode scancode);
extern int SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, Uint8 state, SDL_Scancode scancode); extern int SDL_SendKeyboardKeyIgnoreModifiers(Uint64 timestamp, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode);
/* This is for platforms that don't know the keymap but can report scancode and keycode directly. /* This is for platforms that don't know the keymap but can report scancode and keycode directly.
Most platforms should prefer to optionally call SDL_SetKeymap and then use SDL_SendKeyboardKey. */ Most platforms should prefer to optionally call SDL_SetKeymap and then use SDL_SendKeyboardKey. */
extern int SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode); extern int SDL_SendKeyboardKeyAndKeycode(Uint64 timestamp, SDL_KeyboardID keyboardID, Uint8 state, SDL_Scancode scancode, SDL_Keycode keycode);
/* Release all the autorelease keys */ /* Release all the autorelease keys */
extern void SDL_ReleaseAutoReleaseKeys(void); extern void SDL_ReleaseAutoReleaseKeys(void);

View File

@ -35,6 +35,8 @@
/* The mouse state */ /* The mouse state */
static SDL_Mouse SDL_mouse; static SDL_Mouse SDL_mouse;
static int SDL_mouse_count;
static SDL_MouseID *SDL_mice;
/* for mapping mouse events to touch */ /* for mapping mouse events to touch */
static SDL_bool track_mouse_down = SDL_FALSE; static SDL_bool track_mouse_down = SDL_FALSE;
@ -227,6 +229,118 @@ void SDL_PostInitMouse(void)
SDL_PenInit(); SDL_PenInit();
} }
SDL_bool SDL_IsMouse(Uint16 vendor, Uint16 product)
{
/* Eventually we'll have a blacklist of devices that enumerate as mice but aren't really */
return SDL_TRUE;
}
void SDL_PrivateMouseAdded(SDL_MouseID mouseID)
{
int mouse_index = -1;
SDL_assert(mouseID != 0);
for (int i = 0; i < SDL_mouse_count; ++i) {
if (mouseID == SDL_mice[i]) {
mouse_index = i;
break;
}
}
if (mouse_index >= 0) {
/* We already know about this mouse */
return;
}
SDL_MouseID *mice = (SDL_MouseID *)SDL_realloc(SDL_mice, (SDL_mouse_count + 1) * sizeof(*mice));
if (!mice) {
return;
}
mice[SDL_mouse_count] = mouseID;
SDL_mice = mice;
++SDL_mouse_count;
SDL_Event event;
SDL_zero(event);
event.type = SDL_EVENT_MOUSE_ADDED;
event.mdevice.which = mouseID;
SDL_PushEvent(&event);
}
void SDL_PrivateMouseRemoved(SDL_MouseID mouseID)
{
int mouse_index = -1;
SDL_assert(mouseID != 0);
for (int i = 0; i < SDL_mouse_count; ++i) {
if (mouseID == SDL_mice[i]) {
mouse_index = i;
break;
}
}
if (mouse_index < 0) {
/* We don't know about this mouse */
return;
}
if (mouse_index != SDL_mouse_count - 1) {
SDL_memcpy(&SDL_mice[mouse_index], &SDL_mice[mouse_index + 1], (SDL_mouse_count - mouse_index - 1) * sizeof(SDL_mice[mouse_index]));
}
--SDL_mouse_count;
/* Remove any mouse input sources for this mouseID */
SDL_Mouse *mouse = SDL_GetMouse();
for (int i = 0; i < mouse->num_sources; ++i) {
SDL_MouseInputSource *source = &mouse->sources[i];
if (source->mouseID == mouseID) {
if (i != mouse->num_sources - 1) {
SDL_memcpy(&mouse->sources[i], &mouse->sources[i + 1], (mouse->num_sources - i - 1) * sizeof(mouse->sources[i]));
}
--mouse->num_sources;
break;
}
}
SDL_Event event;
SDL_zero(event);
event.type = SDL_EVENT_MOUSE_REMOVED;
event.mdevice.which = mouseID;
SDL_PushEvent(&event);
}
SDL_bool SDL_HasMouse(void)
{
return (SDL_mouse_count > 0);
}
SDL_MouseID *SDL_GetMice(int *count)
{
int i;
SDL_MouseID *mice;
mice = (SDL_JoystickID *)SDL_malloc((SDL_mouse_count + 1) * sizeof(*mice));
if (mice) {
if (count) {
*count = SDL_mouse_count;
}
for (i = 0; i < SDL_mouse_count; ++i) {
mice[i] = SDL_mice[i];
}
mice[i] = 0;
} else {
if (count) {
*count = 0;
}
}
return mice;
}
void SDL_SetDefaultCursor(SDL_Cursor *cursor) void SDL_SetDefaultCursor(SDL_Cursor *cursor)
{ {
SDL_Mouse *mouse = SDL_GetMouse(); SDL_Mouse *mouse = SDL_GetMouse();
@ -687,18 +801,35 @@ static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_
return posted; return posted;
} }
static SDL_MouseInputSource *GetMouseInputSource(SDL_Mouse *mouse, SDL_MouseID mouseID) static SDL_MouseInputSource *GetMouseInputSource(SDL_Mouse *mouse, SDL_MouseID mouseID, Uint8 state, Uint8 button)
{ {
SDL_MouseInputSource *source, *sources; SDL_MouseInputSource *source, *match = NULL, *sources;
int i; int i;
for (i = 0; i < mouse->num_sources; ++i) { for (i = 0; i < mouse->num_sources; ++i) {
source = &mouse->sources[i]; source = &mouse->sources[i];
if (source->mouseID == mouseID) { if (source->mouseID == mouseID) {
return source; match = source;
break;
} }
} }
if (!state && (!match || !(match->buttonstate & SDL_BUTTON(button)))) {
/* This might be a button release from a transition between mouse messages and raw input.
* See if there's another mouse source that already has that button down and use that.
*/
for (i = 0; i < mouse->num_sources; ++i) {
source = &mouse->sources[i];
if ((source->buttonstate & SDL_BUTTON(button))) {
match = source;
break;
}
}
}
if (match) {
return match;
}
sources = (SDL_MouseInputSource *)SDL_realloc(mouse->sources, (mouse->num_sources + 1) * sizeof(*mouse->sources)); sources = (SDL_MouseInputSource *)SDL_realloc(mouse->sources, (mouse->num_sources + 1) * sizeof(*mouse->sources));
if (sources) { if (sources) {
mouse->sources = sources; mouse->sources = sources;
@ -737,7 +868,7 @@ static int SDL_PrivateSendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_
Uint32 buttonstate; Uint32 buttonstate;
SDL_MouseInputSource *source; SDL_MouseInputSource *source;
source = GetMouseInputSource(mouse, mouseID); source = GetMouseInputSource(mouse, mouseID, state, button);
if (!source) { if (!source) {
return 0; return 0;
} }
@ -823,7 +954,7 @@ static int SDL_PrivateSendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_
event.type = type; event.type = type;
event.common.timestamp = timestamp; event.common.timestamp = timestamp;
event.button.windowID = mouse->focus ? mouse->focus->id : 0; event.button.windowID = mouse->focus ? mouse->focus->id : 0;
event.button.which = mouseID; event.button.which = source->mouseID;
event.button.state = state; event.button.state = state;
event.button.button = button; event.button.button = button;
event.button.clicks = (Uint8)SDL_min(clicks, 255); event.button.clicks = (Uint8)SDL_min(clicks, 255);
@ -957,6 +1088,10 @@ void SDL_QuitMouse(void)
SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION, SDL_DelHintCallback(SDL_HINT_MOUSE_RELATIVE_WARP_MOTION,
SDL_MouseRelativeWarpMotionChanged, mouse); SDL_MouseRelativeWarpMotionChanged, mouse);
SDL_mouse_count = 0;
SDL_free(SDL_mice);
SDL_mice = NULL;
} }
Uint32 SDL_GetMouseState(float *x, float *y) Uint32 SDL_GetMouseState(float *x, float *y)

View File

@ -128,8 +128,17 @@ extern int SDL_PreInitMouse(void);
/* Finish initializing the mouse subsystem, called after the main video driver was initialized */ /* Finish initializing the mouse subsystem, called after the main video driver was initialized */
extern void SDL_PostInitMouse(void); extern void SDL_PostInitMouse(void);
/* Return whether a device is actually a mouse */
extern SDL_bool SDL_IsMouse(Uint16 vendor, Uint16 product);
/* A mouse has been added to the system */
extern void SDL_PrivateMouseAdded(SDL_MouseID mouseID);
/* A mouse has been removed from the system */
extern void SDL_PrivateMouseRemoved(SDL_MouseID mouseID);
/* Get the mouse state structure */ /* Get the mouse state structure */
SDL_Mouse *SDL_GetMouse(void); extern SDL_Mouse *SDL_GetMouse(void);
/* Set the default mouse cursor */ /* Set the default mouse cursor */
extern void SDL_SetDefaultCursor(SDL_Cursor *cursor); extern void SDL_SetDefaultCursor(SDL_Cursor *cursor);

View File

@ -2369,6 +2369,26 @@ int SDL_InitGamepads(void)
return 0; return 0;
} }
SDL_bool SDL_HasGamepad(void)
{
int num_joysticks = 0;
int num_gamepads = 0;
SDL_JoystickID *joysticks = SDL_GetJoysticks(&num_joysticks);
if (joysticks) {
int i;
for (i = num_joysticks - 1; i >= 0 && num_gamepads == 0; --i) {
if (SDL_IsGamepad(joysticks[i])) {
++num_gamepads;
}
}
SDL_free(joysticks);
}
if (num_gamepads > 0) {
return SDL_TRUE;
}
return SDL_FALSE;
}
SDL_JoystickID *SDL_GetGamepads(int *count) SDL_JoystickID *SDL_GetGamepads(int *count)
{ {
int num_joysticks = 0; int num_joysticks = 0;

View File

@ -682,6 +682,25 @@ SDL_bool SDL_JoystickHandledByAnotherDriver(struct SDL_JoystickDriver *driver, U
return result; return result;
} }
SDL_bool SDL_HasJoystick(void)
{
int i;
int total_joysticks = 0;
SDL_LockJoysticks();
{
for (i = 0; i < SDL_arraysize(SDL_joystick_drivers); ++i) {
total_joysticks += SDL_joystick_drivers[i]->GetCount();
}
}
SDL_UnlockJoysticks();
if (total_joysticks > 0) {
return SDL_TRUE;
}
return SDL_FALSE;
}
SDL_JoystickID *SDL_GetJoysticks(int *count) SDL_JoystickID *SDL_GetJoysticks(int *count)
{ {
int i, num_joysticks, device_index; int i, num_joysticks, device_index;

View File

@ -205,7 +205,7 @@ int Android_OnPadDown(int device_id, int keycode)
if (item && item->joystick) { if (item && item->joystick) {
SDL_SendJoystickButton(timestamp, item->joystick, button, SDL_PRESSED); SDL_SendJoystickButton(timestamp, item->joystick, button, SDL_PRESSED);
} else { } else {
SDL_SendKeyboardKey(timestamp, SDL_PRESSED, button_to_scancode(button)); SDL_SendKeyboardKey(timestamp, 0, SDL_PRESSED, button_to_scancode(button));
} }
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
return 0; return 0;
@ -225,7 +225,7 @@ int Android_OnPadUp(int device_id, int keycode)
if (item && item->joystick) { if (item && item->joystick) {
SDL_SendJoystickButton(timestamp, item->joystick, button, SDL_RELEASED); SDL_SendJoystickButton(timestamp, item->joystick, button, SDL_RELEASED);
} else { } else {
SDL_SendKeyboardKey(timestamp, SDL_RELEASED, button_to_scancode(button)); SDL_SendKeyboardKey(timestamp, 0, SDL_RELEASED, button_to_scancode(button));
} }
SDL_UnlockJoysticks(); SDL_UnlockJoysticks();
return 0; return 0;

View File

@ -35,6 +35,7 @@
#include "../SDL_sysjoystick.h" #include "../SDL_sysjoystick.h"
#include "../../thread/SDL_systhread.h" #include "../../thread/SDL_systhread.h"
#include "../../core/windows/SDL_windows.h" #include "../../core/windows/SDL_windows.h"
#include "../../core/windows/SDL_hid.h"
#if !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) #if !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
#include <dbt.h> #include <dbt.h>
#endif #endif
@ -51,162 +52,34 @@
#define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000 #define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000
#endif #endif
/* CM_Register_Notification definitions */
#define CR_SUCCESS (0x00000000)
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
extern "C" {
#endif
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 */ /* local variables */
static SDL_bool s_bJoystickThread = SDL_FALSE; static SDL_bool s_bJoystickThread = SDL_FALSE;
static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE;
static SDL_Condition *s_condJoystickThread = NULL; static SDL_Condition *s_condJoystickThread = NULL;
static SDL_Mutex *s_mutexJoyStickEnum = NULL; static SDL_Mutex *s_mutexJoyStickEnum = NULL;
static SDL_Thread *s_joystickThread = NULL; static SDL_Thread *s_joystickThread = NULL;
static SDL_bool s_bJoystickThreadQuit = SDL_FALSE; static SDL_bool s_bJoystickThreadQuit = SDL_FALSE;
static Uint64 s_lastDeviceChange = 0;
static GUID GUID_DEVINTERFACE_HID = { 0x4D1E55B2L, 0xF16F, 0x11CF, { 0x88, 0xCB, 0x00, 0x11, 0x11, 0x00, 0x00, 0x30 } }; 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 */ JoyStick_DeviceData *SYS_Joystick; /* array to hold joystick ID values */
#if !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
static HMODULE cfgmgr32_lib_handle; static SDL_bool WindowsDeviceChanged(void)
static CM_Register_NotificationFunc CM_Register_Notification; {
static CM_Unregister_NotificationFunc CM_Unregister_Notification; return (s_lastDeviceChange != WIN_GetLastDeviceNotification());
static HCMNOTIFICATION s_DeviceNotificationFuncHandle; }
static void SetWindowsDeviceChanged(void)
{
s_lastDeviceChange = 0;
}
void WINDOWS_RAWINPUTEnabledChanged(void) void WINDOWS_RAWINPUTEnabledChanged(void)
{ {
s_bWindowsDeviceChanged = SDL_TRUE; SetWindowsDeviceChanged();
} }
static DWORD CALLBACK SDL_DeviceNotificationFunc(HCMNOTIFICATION hNotify, PVOID context, CM_NOTIFY_ACTION action, PCM_NOTIFY_EVENT_DATA eventData, DWORD event_data_size) #if !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
{
if (action == CM_NOTIFY_ACTION_DEVICEINTERFACEARRIVAL ||
action == CM_NOTIFY_ACTION_DEVICEINTERFACEREMOVAL) {
s_bWindowsDeviceChanged = SDL_TRUE;
}
return ERROR_SUCCESS;
}
static void SDL_CleanupDeviceNotificationFunc(void)
{
if (cfgmgr32_lib_handle) {
if (s_DeviceNotificationFuncHandle != NULL && CM_Unregister_Notification) {
CM_Unregister_Notification(s_DeviceNotificationFuncHandle);
s_DeviceNotificationFuncHandle = NULL;
}
FreeLibrary(cfgmgr32_lib_handle);
cfgmgr32_lib_handle = NULL;
}
}
static SDL_bool 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(&notify_filter, NULL, SDL_DeviceNotificationFunc, &s_DeviceNotificationFuncHandle) == CR_SUCCESS) {
return SDL_TRUE;
}
}
}
SDL_CleanupDeviceNotificationFunc();
return SDL_FALSE;
}
typedef struct typedef struct
{ {
@ -239,7 +112,7 @@ static LRESULT CALLBACK SDL_PrivateJoystickDetectProc(HWND hwnd, UINT msg, WPARA
if (wParam == IDT_SDL_DEVICE_CHANGE_TIMER_1 || if (wParam == IDT_SDL_DEVICE_CHANGE_TIMER_1 ||
wParam == IDT_SDL_DEVICE_CHANGE_TIMER_2) { wParam == IDT_SDL_DEVICE_CHANGE_TIMER_2) {
KillTimer(hwnd, wParam); KillTimer(hwnd, wParam);
s_bWindowsDeviceChanged = SDL_TRUE; SetWindowsDeviceChanged();
return 0; return 0;
} }
break; break;
@ -327,7 +200,7 @@ static SDL_bool SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data,
} }
SDL_UnlockMutex(mutex); SDL_UnlockMutex(mutex);
while (lastret > 0 && s_bWindowsDeviceChanged == SDL_FALSE) { while (lastret > 0 && !WindowsDeviceChanged()) {
lastret = GetMessage(&msg, NULL, 0, 0); /* WM_QUIT causes return value of 0 */ lastret = GetMessage(&msg, NULL, 0, 0); /* WM_QUIT causes return value of 0 */
if (lastret > 0) { if (lastret > 0) {
TranslateMessage(&msg); TranslateMessage(&msg);
@ -378,7 +251,7 @@ static int SDLCALL SDL_JoystickThread(void *_data)
const DWORD result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities); const DWORD result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities);
const SDL_bool available = (result == ERROR_SUCCESS); const SDL_bool available = (result == ERROR_SUCCESS);
if (bOpenedXInputDevices[userId] != available) { if (bOpenedXInputDevices[userId] != available) {
s_bWindowsDeviceChanged = SDL_TRUE; SetWindowsDeviceChanged();
bOpenedXInputDevices[userId] = available; bOpenedXInputDevices[userId] = available;
} }
} }
@ -476,13 +349,9 @@ static int WINDOWS_JoystickInit(void)
return -1; return -1;
} }
s_bWindowsDeviceChanged = SDL_TRUE; /* force a scan of the system for joysticks this first time */ WIN_InitDeviceNotification();
WINDOWS_JoystickDetect();
#if !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) #if !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
SDL_CreateDeviceNotificationFunc();
s_bJoystickThread = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_THREAD, SDL_FALSE); s_bJoystickThread = SDL_GetHintBoolean(SDL_HINT_JOYSTICK_THREAD, SDL_FALSE);
if (s_bJoystickThread) { if (s_bJoystickThread) {
if (SDL_StartJoystickThread() < 0) { if (SDL_StartJoystickThread() < 0) {
@ -502,6 +371,11 @@ static int WINDOWS_JoystickInit(void)
return -1; return -1;
} }
#endif #endif
SetWindowsDeviceChanged(); /* force a scan of the system for joysticks this first time */
WINDOWS_JoystickDetect();
return 0; return 0;
} }
@ -524,7 +398,7 @@ void WINDOWS_JoystickDetect(void)
JoyStick_DeviceData *pCurList = NULL; JoyStick_DeviceData *pCurList = NULL;
/* only enum the devices if the joystick thread told us something changed */ /* only enum the devices if the joystick thread told us something changed */
if (!s_bWindowsDeviceChanged) { if (!WindowsDeviceChanged()) {
return; /* thread hasn't signaled, nothing to do right now. */ return; /* thread hasn't signaled, nothing to do right now. */
} }
@ -532,7 +406,7 @@ void WINDOWS_JoystickDetect(void)
SDL_LockMutex(s_mutexJoyStickEnum); SDL_LockMutex(s_mutexJoyStickEnum);
} }
s_bWindowsDeviceChanged = SDL_FALSE; s_lastDeviceChange = WIN_GetLastDeviceNotification();
pCurList = SYS_Joystick; pCurList = SYS_Joystick;
SYS_Joystick = NULL; SYS_Joystick = NULL;
@ -774,8 +648,6 @@ void WINDOWS_JoystickQuit(void)
} else { } else {
SDL_CleanupDeviceNotification(&s_notification_data); SDL_CleanupDeviceNotification(&s_notification_data);
} }
SDL_CleanupDeviceNotificationFunc();
#endif #endif
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES) #if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
@ -787,7 +659,7 @@ void WINDOWS_JoystickQuit(void)
SDL_DINPUT_JoystickQuit(); SDL_DINPUT_JoystickQuit();
SDL_XINPUT_JoystickQuit(); SDL_XINPUT_JoystickQuit();
s_bWindowsDeviceChanged = SDL_FALSE; WIN_QuitDeviceNotification();
} }
static SDL_bool WINDOWS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) static SDL_bool WINDOWS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
@ -819,11 +691,6 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver = {
WINDOWS_JoystickGetGamepadMapping WINDOWS_JoystickGetGamepadMapping
}; };
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#else #else
#ifdef SDL_JOYSTICK_RAWINPUT #ifdef SDL_JOYSTICK_RAWINPUT

View File

@ -1661,6 +1661,14 @@ static void SDLTest_PrintEvent(const SDL_Event *event)
case SDL_EVENT_WINDOW_DESTROYED: case SDL_EVENT_WINDOW_DESTROYED:
SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " destroyed", event->window.windowID); SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " destroyed", event->window.windowID);
break; break;
case SDL_EVENT_KEYBOARD_ADDED:
SDL_Log("SDL EVENT: Keyboard %" SDL_PRIu32 " attached",
event->kdevice.which);
break;
case SDL_EVENT_KEYBOARD_REMOVED:
SDL_Log("SDL EVENT: Keyboard %" SDL_PRIu32 " removed",
event->kdevice.which);
break;
case SDL_EVENT_KEY_DOWN: case SDL_EVENT_KEY_DOWN:
case SDL_EVENT_KEY_UP: { case SDL_EVENT_KEY_UP: {
char modstr[64]; char modstr[64];
@ -1691,6 +1699,14 @@ static void SDLTest_PrintEvent(const SDL_Event *event)
case SDL_EVENT_KEYMAP_CHANGED: case SDL_EVENT_KEYMAP_CHANGED:
SDL_Log("SDL EVENT: Keymap changed"); SDL_Log("SDL EVENT: Keymap changed");
break; break;
case SDL_EVENT_MOUSE_ADDED:
SDL_Log("SDL EVENT: Mouse %" SDL_PRIu32 " attached",
event->mdevice.which);
break;
case SDL_EVENT_MOUSE_REMOVED:
SDL_Log("SDL EVENT: Mouse %" SDL_PRIu32 " removed",
event->mdevice.which);
break;
case SDL_EVENT_MOUSE_MOTION: case SDL_EVENT_MOUSE_MOTION:
SDL_Log("SDL EVENT: Mouse: moved to %g,%g (%g,%g) in window %" SDL_PRIu32, SDL_Log("SDL EVENT: Mouse: moved to %g,%g (%g,%g) in window %" SDL_PRIu32,
event->motion.x, event->motion.y, event->motion.x, event->motion.y,
@ -1712,7 +1728,7 @@ static void SDLTest_PrintEvent(const SDL_Event *event)
event->wheel.x, event->wheel.y, event->wheel.direction, event->wheel.windowID); event->wheel.x, event->wheel.y, event->wheel.direction, event->wheel.windowID);
break; break;
case SDL_EVENT_JOYSTICK_ADDED: case SDL_EVENT_JOYSTICK_ADDED:
SDL_Log("SDL EVENT: Joystick index %" SDL_PRIu32 " attached", SDL_Log("SDL EVENT: Joystick %" SDL_PRIu32 " attached",
event->jdevice.which); event->jdevice.which);
break; break;
case SDL_EVENT_JOYSTICK_REMOVED: case SDL_EVENT_JOYSTICK_REMOVED:
@ -1768,7 +1784,7 @@ static void SDLTest_PrintEvent(const SDL_Event *event)
event->jbutton.which, event->jbutton.button); event->jbutton.which, event->jbutton.button);
break; break;
case SDL_EVENT_GAMEPAD_ADDED: case SDL_EVENT_GAMEPAD_ADDED:
SDL_Log("SDL EVENT: Gamepad index %" SDL_PRIu32 " attached", SDL_Log("SDL EVENT: Gamepad %" SDL_PRIu32 " attached",
event->gdevice.which); event->gdevice.which);
break; break;
case SDL_EVENT_GAMEPAD_REMOVED: case SDL_EVENT_GAMEPAD_REMOVED:

View File

@ -330,12 +330,12 @@ static SDL_Scancode TranslateKeycode(int keycode)
int Android_OnKeyDown(int keycode) int Android_OnKeyDown(int keycode)
{ {
return SDL_SendKeyboardKey(0, SDL_PRESSED, TranslateKeycode(keycode)); return SDL_SendKeyboardKey(0, 0, SDL_PRESSED, TranslateKeycode(keycode));
} }
int Android_OnKeyUp(int keycode) int Android_OnKeyUp(int keycode)
{ {
return SDL_SendKeyboardKey(0, SDL_RELEASED, TranslateKeycode(keycode)); return SDL_SendKeyboardKey(0, 0, SDL_RELEASED, TranslateKeycode(keycode));
} }
SDL_bool Android_HasScreenKeyboardSupport(SDL_VideoDevice *_this) SDL_bool Android_HasScreenKeyboardSupport(SDL_VideoDevice *_this)

View File

@ -231,9 +231,9 @@ static void HandleModifiers(SDL_VideoDevice *_this, SDL_Scancode code, unsigned
} }
if (pressed) { if (pressed) {
SDL_SendKeyboardKey(0, SDL_PRESSED, code); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, code);
} else { } else {
SDL_SendKeyboardKey(0, SDL_RELEASED, code); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, code);
} }
} }
@ -279,7 +279,7 @@ static void UpdateKeymap(SDL_CocoaVideoData *data, SDL_bool send_event)
continue; continue;
} }
/* /*
* Swap the scancode for these two wrongly translated keys * Swap the scancode for these two wrongly translated keys
* UCKeyTranslate() function does not do its job properly for ISO layout keyboards, where the key '@', * UCKeyTranslate() function does not do its job properly for ISO layout keyboards, where the key '@',
* which is located in the top left corner of the keyboard right under the Escape key, and the additional * which is located in the top left corner of the keyboard right under the Escape key, and the additional
@ -414,7 +414,7 @@ void Cocoa_HandleKeyEvent(SDL_VideoDevice *_this, NSEvent *event)
UpdateKeymap(data, SDL_TRUE); UpdateKeymap(data, SDL_TRUE);
} }
SDL_SendKeyboardKey(Cocoa_GetEventTimestamp([event timestamp]), SDL_PRESSED, code); SDL_SendKeyboardKey(Cocoa_GetEventTimestamp([event timestamp]), 0, SDL_PRESSED, code);
#ifdef DEBUG_SCANCODES #ifdef DEBUG_SCANCODES
if (code == SDL_SCANCODE_UNKNOWN) { if (code == SDL_SCANCODE_UNKNOWN) {
SDL_Log("The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL forums/mailing list <https://discourse.libsdl.org/> or to Christian Walther <cwalther@gmx.ch>. Mac virtual key code is %d.\n", scancode); SDL_Log("The key you just pressed is not recognized by SDL. To help get this fixed, report this to the SDL forums/mailing list <https://discourse.libsdl.org/> or to Christian Walther <cwalther@gmx.ch>. Mac virtual key code is %d.\n", scancode);
@ -433,7 +433,7 @@ void Cocoa_HandleKeyEvent(SDL_VideoDevice *_this, NSEvent *event)
} }
break; break;
case NSEventTypeKeyUp: case NSEventTypeKeyUp:
SDL_SendKeyboardKey(Cocoa_GetEventTimestamp([event timestamp]), SDL_RELEASED, code); SDL_SendKeyboardKey(Cocoa_GetEventTimestamp([event timestamp]), 0, SDL_RELEASED, code);
break; break;
case NSEventTypeFlagsChanged: { case NSEventTypeFlagsChanged: {
// see if the new modifierFlags mean any existing keys should be pressed/released... // see if the new modifierFlags mean any existing keys should be pressed/released...

View File

@ -1381,8 +1381,8 @@ static SDL_bool Cocoa_IsZoomed(SDL_Window *window)
const SDL_bool osenabled = ([theEvent modifierFlags] & NSEventModifierFlagCapsLock) ? SDL_TRUE : SDL_FALSE; const SDL_bool osenabled = ([theEvent modifierFlags] & NSEventModifierFlagCapsLock) ? SDL_TRUE : SDL_FALSE;
const SDL_bool sdlenabled = (SDL_GetModState() & SDL_KMOD_CAPS) ? SDL_TRUE : SDL_FALSE; const SDL_bool sdlenabled = (SDL_GetModState() & SDL_KMOD_CAPS) ? SDL_TRUE : SDL_FALSE;
if (osenabled ^ sdlenabled) { if (osenabled ^ sdlenabled) {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
} }
} }
- (void)keyDown:(NSEvent *)theEvent - (void)keyDown:(NSEvent *)theEvent

View File

@ -811,7 +811,7 @@ static EM_BOOL Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent
} }
if (scancode != SDL_SCANCODE_UNKNOWN) { if (scancode != SDL_SCANCODE_UNKNOWN) {
SDL_SendKeyboardKeyAndKeycode(0, eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_PRESSED : SDL_RELEASED, scancode, keycode); SDL_SendKeyboardKeyAndKeycode(0, 0, eventType == EMSCRIPTEN_EVENT_KEYDOWN ? SDL_PRESSED : SDL_RELEASED, scancode, keycode);
} }
/* if TEXTINPUT events are enabled we can't prevent keydown or we won't get keypress /* if TEXTINPUT events are enabled we can't prevent keydown or we won't get keypress

View File

@ -303,7 +303,7 @@ class SDL_BLooper : public BLooper
return; return;
} }
HAIKU_SetKeyState(scancode, state); HAIKU_SetKeyState(scancode, state);
SDL_SendKeyboardKey(0, state, HAIKU_GetScancodeFromBeKey(scancode)); SDL_SendKeyboardKey(0, 0, state, HAIKU_GetScancodeFromBeKey(scancode));
if (state == SDL_PRESSED && SDL_EventEnabled(SDL_EVENT_TEXT_INPUT)) { if (state == SDL_PRESSED && SDL_EventEnabled(SDL_EVENT_TEXT_INPUT)) {
const int8 *keyUtf8; const int8 *keyUtf8;

View File

@ -154,10 +154,10 @@ int HandleWsEvent(SDL_VideoDevice *_this, const TWsEvent &aWsEvent)
switch (aWsEvent.Type()) { switch (aWsEvent.Type()) {
case EEventKeyDown: /* Key events */ case EEventKeyDown: /* Key events */
SDL_SendKeyboardKey(0, SDL_PRESSED, ConvertScancode(_this, aWsEvent.Key()->iScanCode)); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, ConvertScancode(_this, aWsEvent.Key()->iScanCode));
break; break;
case EEventKeyUp: /* Key events */ case EEventKeyUp: /* Key events */
SDL_SendKeyboardKey(0, SDL_RELEASED, ConvertScancode(_this, aWsEvent.Key()->iScanCode)); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, ConvertScancode(_this, aWsEvent.Key()->iScanCode));
break; break;
case EEventFocusGained: /* SDL window got focus */ case EEventFocusGained: /* SDL window got focus */
phdata->NGAGE_IsWindowFocused = ETrue; phdata->NGAGE_IsWindowFocused = ETrue;

View File

@ -90,7 +90,7 @@ void PSP_PumpEvents(SDL_VideoDevice *_this)
if (changed) { if (changed) {
for (i = 0; i < sizeof(keymap_psp) / sizeof(keymap_psp[0]); i++) { for (i = 0; i < sizeof(keymap_psp) / sizeof(keymap_psp[0]); i++) {
if (changed & keymap_psp[i].id) { if (changed & keymap_psp[i].id) {
SDL_SendKeyboardKey(0, (keys & keymap_psp[i].id) ? SDL_PRESSED : SDL_RELEASED, SDL_GetScancodeFromKey(keymap_psp[i].sym)); SDL_SendKeyboardKey(0, 0, (keys & keymap_psp[i].id) ? SDL_PRESSED : SDL_RELEASED, SDL_GetScancodeFromKey(keymap_psp[i].sym));
} }
} }
} }
@ -113,7 +113,7 @@ void PSP_PumpEvents(SDL_VideoDevice *_this)
sym.sym = keymap[raw]; sym.sym = keymap[raw];
/* not tested */ /* not tested */
/* SDL_PrivateKeyboard(pressed?SDL_PRESSED:SDL_RELEASED, &sym); */ /* SDL_PrivateKeyboard(pressed?SDL_PRESSED:SDL_RELEASED, &sym); */
SDL_SendKeyboardKey(0, (keys & keymap_psp[i].id) ? SDL_PRESSED : SDL_RELEASED, SDL_GetScancodeFromKey(keymap[raw])); SDL_SendKeyboardKey(0, 0, (keys & keymap_psp[i].id) ? SDL_PRESSED : SDL_RELEASED, SDL_GetScancodeFromKey(keymap[raw]));
} }
} }
} }

View File

@ -125,8 +125,8 @@ void handleKeyboardEvent(screen_event_t event)
// FIXME: // FIXME:
// Need to handle more key states (such as key combinations). // Need to handle more key states (such as key combinations).
if (val & KEY_DOWN) { if (val & KEY_DOWN) {
SDL_SendKeyboardKey(0, SDL_PRESSED, scancode); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, scancode);
} else { } else {
SDL_SendKeyboardKey(0, SDL_RELEASED, scancode); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, scancode);
} }
} }

View File

@ -58,7 +58,7 @@ void RISCOS_PollKeyboard(SDL_VideoDevice *_this)
for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) { for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) {
if (driverdata->key_pressed[i] != 255) { if (driverdata->key_pressed[i] != 255) {
if ((_kernel_osbyte(129, driverdata->key_pressed[i] ^ 0xff, 0xff) & 0xff) != 255) { if ((_kernel_osbyte(129, driverdata->key_pressed[i] ^ 0xff, 0xff) & 0xff) != 255) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_RISCOS_translate_keycode(driverdata->key_pressed[i])); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_RISCOS_translate_keycode(driverdata->key_pressed[i]));
driverdata->key_pressed[i] = 255; driverdata->key_pressed[i] = 255;
} }
} }
@ -81,7 +81,7 @@ void RISCOS_PollKeyboard(SDL_VideoDevice *_this)
break; break;
default: default:
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_RISCOS_translate_keycode(key)); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_RISCOS_translate_keycode(key));
/* Record the press so we can detect release later. */ /* Record the press so we can detect release later. */
for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) { for (i = 0; i < RISCOS_MAX_KEYS_PRESSED; i++) {

View File

@ -29,11 +29,9 @@ extern Uint64 UIKit_GetEventTimestamp(NSTimeInterval nsTimestamp);
extern void UIKit_PumpEvents(SDL_VideoDevice *_this); extern void UIKit_PumpEvents(SDL_VideoDevice *_this);
extern void SDL_InitGCKeyboard(void); extern void SDL_InitGCKeyboard(void);
extern SDL_bool SDL_HasGCKeyboard(void);
extern void SDL_QuitGCKeyboard(void); extern void SDL_QuitGCKeyboard(void);
extern void SDL_InitGCMouse(void); extern void SDL_InitGCMouse(void);
extern SDL_bool SDL_HasGCMouse(void);
extern SDL_bool SDL_GCMouseRelativeMode(void); extern SDL_bool SDL_GCMouseRelativeMode(void);
extern void SDL_QuitGCMouse(void); extern void SDL_QuitGCMouse(void);

View File

@ -171,15 +171,17 @@ void UIKit_PumpEvents(SDL_VideoDevice *_this)
#ifdef ENABLE_GCKEYBOARD #ifdef ENABLE_GCKEYBOARD
static SDL_bool keyboard_connected = SDL_FALSE;
static id keyboard_connect_observer = nil; static id keyboard_connect_observer = nil;
static id keyboard_disconnect_observer = nil; static id keyboard_disconnect_observer = nil;
static void OnGCKeyboardConnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) static void OnGCKeyboardConnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
{ {
keyboard_connected = SDL_TRUE; SDL_KeyboardID keyboardID = (SDL_KeyboardID)(uintptr_t)keyboard;
SDL_PrivateKeyboardAdded(keyboardID);
keyboard.keyboardInput.keyChangedHandler = ^(GCKeyboardInput *kbrd, GCControllerButtonInput *key, GCKeyCode keyCode, BOOL pressed) { keyboard.keyboardInput.keyChangedHandler = ^(GCKeyboardInput *kbrd, GCControllerButtonInput *key, GCKeyCode keyCode, BOOL pressed) {
SDL_SendKeyboardKey(0, pressed ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)keyCode); SDL_SendKeyboardKey(0, keyboardID, pressed ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)keyCode);
}; };
dispatch_queue_t queue = dispatch_queue_create("org.libsdl.input.keyboard", DISPATCH_QUEUE_SERIAL); dispatch_queue_t queue = dispatch_queue_create("org.libsdl.input.keyboard", DISPATCH_QUEUE_SERIAL);
@ -189,8 +191,11 @@ static void OnGCKeyboardConnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0
static void OnGCKeyboardDisconnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) static void OnGCKeyboardDisconnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
{ {
SDL_KeyboardID keyboardID = (SDL_KeyboardID)(uintptr_t)keyboard;
SDL_PrivateKeyboardRemoved(keyboardID);
keyboard.keyboardInput.keyChangedHandler = nil; keyboard.keyboardInput.keyChangedHandler = nil;
keyboard_connected = SDL_FALSE;
} }
void SDL_InitGCKeyboard(void) void SDL_InitGCKeyboard(void)
@ -222,11 +227,6 @@ void SDL_InitGCKeyboard(void)
} }
} }
SDL_bool SDL_HasGCKeyboard(void)
{
return keyboard_connected;
}
void SDL_QuitGCKeyboard(void) void SDL_QuitGCKeyboard(void)
{ {
@autoreleasepool { @autoreleasepool {
@ -256,11 +256,6 @@ void SDL_InitGCKeyboard(void)
{ {
} }
SDL_bool SDL_HasGCKeyboard(void)
{
return SDL_FALSE;
}
void SDL_QuitGCKeyboard(void) void SDL_QuitGCKeyboard(void)
{ {
} }
@ -269,7 +264,6 @@ void SDL_QuitGCKeyboard(void)
#ifdef ENABLE_GCMOUSE #ifdef ENABLE_GCMOUSE
static int mice_connected = 0;
static id mouse_connect_observer = nil; static id mouse_connect_observer = nil;
static id mouse_disconnect_observer = nil; static id mouse_disconnect_observer = nil;
static bool mouse_relative_mode = SDL_FALSE; static bool mouse_relative_mode = SDL_FALSE;
@ -291,7 +285,7 @@ static void UpdateScrollDirection(void)
/* Couldn't read the preference, assume natural scrolling direction */ /* Couldn't read the preference, assume natural scrolling direction */
naturalScrollDirection = YES; naturalScrollDirection = YES;
} }
if (naturalScrollDirection) { if (naturalScrollDirection) {
mouse_scroll_direction = SDL_MOUSEWHEEL_FLIPPED; mouse_scroll_direction = SDL_MOUSEWHEEL_FLIPPED;
} else { } else {
mouse_scroll_direction = SDL_MOUSEWHEEL_NORMAL; mouse_scroll_direction = SDL_MOUSEWHEEL_NORMAL;
@ -323,7 +317,9 @@ static void OnGCMouseButtonChanged(SDL_MouseID mouseID, Uint8 button, BOOL press
static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
{ {
SDL_MouseID mouseID = mice_connected; SDL_MouseID mouseID = (SDL_MouseID)(uintptr_t)mouse;
SDL_PrivateMouseAdded(mouseID);
mouse.mouseInput.leftButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) { mouse.mouseInput.leftButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed) {
OnGCMouseButtonChanged(mouseID, SDL_BUTTON_LEFT, pressed); OnGCMouseButtonChanged(mouseID, SDL_BUTTON_LEFT, pressed);
@ -370,14 +366,12 @@ static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14
dispatch_set_target_queue(queue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)); dispatch_set_target_queue(queue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0));
mouse.handlerQueue = queue; mouse.handlerQueue = queue;
++mice_connected;
UpdatePointerLock(); UpdatePointerLock();
} }
static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0)) static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
{ {
--mice_connected; SDL_MouseID mouseID = (SDL_MouseID)(uintptr_t)mouse;
mouse.mouseInput.mouseMovedHandler = nil; mouse.mouseInput.mouseMovedHandler = nil;
@ -390,6 +384,8 @@ static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios
} }
UpdatePointerLock(); UpdatePointerLock();
SDL_PrivateMouseRemoved(mouseID);
} }
void SDL_InitGCMouse(void) void SDL_InitGCMouse(void)
@ -432,11 +428,6 @@ void SDL_InitGCMouse(void)
} }
} }
SDL_bool SDL_HasGCMouse(void)
{
return (mice_connected > 0);
}
SDL_bool SDL_GCMouseRelativeMode(void) SDL_bool SDL_GCMouseRelativeMode(void)
{ {
return mouse_relative_mode; return mouse_relative_mode;
@ -473,11 +464,6 @@ void SDL_InitGCMouse(void)
{ {
} }
SDL_bool SDL_HasGCMouse(void)
{
return SDL_FALSE;
}
SDL_bool SDL_GCMouseRelativeMode(void) SDL_bool SDL_GCMouseRelativeMode(void)
{ {
return SDL_FALSE; return SDL_FALSE;

View File

@ -229,7 +229,7 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
#if !defined(SDL_PLATFORM_TVOS) && defined(__IPHONE_13_4) #if !defined(SDL_PLATFORM_TVOS) && defined(__IPHONE_13_4)
if (@available(iOS 13.4, *)) { if (@available(iOS 13.4, *)) {
if (touch.type == UITouchTypeIndirectPointer) { if (touch.type == UITouchTypeIndirectPointer) {
if (!SDL_HasGCMouse()) { if (!SDL_HasMouse()) {
int i; int i;
for (i = 1; i <= MAX_MOUSE_BUTTONS; ++i) { for (i = 1; i <= MAX_MOUSE_BUTTONS; ++i) {
@ -285,7 +285,7 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
#if !defined(SDL_PLATFORM_TVOS) && defined(__IPHONE_13_4) #if !defined(SDL_PLATFORM_TVOS) && defined(__IPHONE_13_4)
if (@available(iOS 13.4, *)) { if (@available(iOS 13.4, *)) {
if (touch.type == UITouchTypeIndirectPointer) { if (touch.type == UITouchTypeIndirectPointer) {
if (!SDL_HasGCMouse()) { if (!SDL_HasMouse()) {
int i; int i;
for (i = 1; i <= MAX_MOUSE_BUTTONS; ++i) { for (i = 1; i <= MAX_MOUSE_BUTTONS; ++i) {
@ -411,10 +411,10 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event - (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
{ {
if (!SDL_HasGCKeyboard()) { if (!SDL_HasKeyboard()) {
for (UIPress *press in presses) { for (UIPress *press in presses) {
SDL_Scancode scancode = [self scancodeFromPress:press]; SDL_Scancode scancode = [self scancodeFromPress:press];
SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), SDL_PRESSED, scancode); SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), 0, SDL_PRESSED, scancode);
} }
} }
if (SDL_TextInputActive()) { if (SDL_TextInputActive()) {
@ -424,10 +424,10 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event - (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
{ {
if (!SDL_HasGCKeyboard()) { if (!SDL_HasKeyboard()) {
for (UIPress *press in presses) { for (UIPress *press in presses) {
SDL_Scancode scancode = [self scancodeFromPress:press]; SDL_Scancode scancode = [self scancodeFromPress:press];
SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), SDL_RELEASED, scancode); SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), 0, SDL_RELEASED, scancode);
} }
} }
if (SDL_TextInputActive()) { if (SDL_TextInputActive()) {
@ -437,10 +437,10 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event - (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
{ {
if (!SDL_HasGCKeyboard()) { if (!SDL_HasKeyboard()) {
for (UIPress *press in presses) { for (UIPress *press in presses) {
SDL_Scancode scancode = [self scancodeFromPress:press]; SDL_Scancode scancode = [self scancodeFromPress:press];
SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), SDL_RELEASED, scancode); SDL_SendKeyboardKey(UIKit_GetEventTimestamp([event timestamp]), 0, SDL_RELEASED, scancode);
} }
} }
if (SDL_TextInputActive()) { if (SDL_TextInputActive()) {

View File

@ -62,40 +62,40 @@ void VITA_PollKeyboard(void)
// The k_report only reports the state of the LED // The k_report only reports the state of the LED
if (k_reports[numReports - 1].modifiers[1] & 0x1) { if (k_reports[numReports - 1].modifiers[1] & 0x1) {
if (!(locks & 0x1)) { if (!(locks & 0x1)) {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
locks |= 0x1; locks |= 0x1;
} }
} else { } else {
if (locks & 0x1) { if (locks & 0x1) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
locks &= ~0x1; locks &= ~0x1;
} }
} }
if (k_reports[numReports - 1].modifiers[1] & 0x2) { if (k_reports[numReports - 1].modifiers[1] & 0x2) {
if (!(locks & 0x2)) { if (!(locks & 0x2)) {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
locks |= 0x2; locks |= 0x2;
} }
} else { } else {
if (locks & 0x2) { if (locks & 0x2) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
locks &= ~0x2; locks &= ~0x2;
} }
} }
if (k_reports[numReports - 1].modifiers[1] & 0x4) { if (k_reports[numReports - 1].modifiers[1] & 0x4) {
if (!(locks & 0x4)) { if (!(locks & 0x4)) {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_SCROLLLOCK); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_SCROLLLOCK);
locks |= 0x4; locks |= 0x4;
} }
} else { } else {
if (locks & 0x4) { if (locks & 0x4) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_SCROLLLOCK); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_SCROLLLOCK);
locks &= ~0x4; locks &= ~0x4;
} }
} }
@ -105,58 +105,58 @@ void VITA_PollKeyboard(void)
if (changed_modifiers & 0x01) { if (changed_modifiers & 0x01) {
if (prev_modifiers & 0x01) { if (prev_modifiers & 0x01) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LCTRL); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_LCTRL);
} else { } else {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LCTRL); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_LCTRL);
} }
} }
if (changed_modifiers & 0x02) { if (changed_modifiers & 0x02) {
if (prev_modifiers & 0x02) { if (prev_modifiers & 0x02) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LSHIFT); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_LSHIFT);
} else { } else {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LSHIFT); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_LSHIFT);
} }
} }
if (changed_modifiers & 0x04) { if (changed_modifiers & 0x04) {
if (prev_modifiers & 0x04) { if (prev_modifiers & 0x04) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LALT); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_LALT);
} else { } else {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LALT); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_LALT);
} }
} }
if (changed_modifiers & 0x08) { if (changed_modifiers & 0x08) {
if (prev_modifiers & 0x08) { if (prev_modifiers & 0x08) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LGUI); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_LGUI);
} else { } else {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LGUI); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_LGUI);
} }
} }
if (changed_modifiers & 0x10) { if (changed_modifiers & 0x10) {
if (prev_modifiers & 0x10) { if (prev_modifiers & 0x10) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RCTRL); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_RCTRL);
} else { } else {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_RCTRL); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_RCTRL);
} }
} }
if (changed_modifiers & 0x20) { if (changed_modifiers & 0x20) {
if (prev_modifiers & 0x20) { if (prev_modifiers & 0x20) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RSHIFT); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_RSHIFT);
} else { } else {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_RSHIFT); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_RSHIFT);
} }
} }
if (changed_modifiers & 0x40) { if (changed_modifiers & 0x40) {
if (prev_modifiers & 0x40) { if (prev_modifiers & 0x40) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RALT); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_RALT);
} else { } else {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_RALT); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_RALT);
} }
} }
if (changed_modifiers & 0x80) { if (changed_modifiers & 0x80) {
if (prev_modifiers & 0x80) { if (prev_modifiers & 0x80) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RGUI); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_RGUI);
} else { } else {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_RGUI); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_RGUI);
} }
} }
} }
@ -170,10 +170,10 @@ void VITA_PollKeyboard(void)
if (keyCode != prev_keys[i]) { if (keyCode != prev_keys[i]) {
if (prev_keys[i]) { if (prev_keys[i]) {
SDL_SendKeyboardKey(0, SDL_RELEASED, prev_keys[i]); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, prev_keys[i]);
} }
if (keyCode) { if (keyCode) {
SDL_SendKeyboardKey(0, SDL_PRESSED, keyCode); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, keyCode);
} }
prev_keys[i] = keyCode; prev_keys[i] = keyCode;
} }

View File

@ -264,7 +264,7 @@ static SDL_bool keyboard_repeat_handle(SDL_WaylandKeyboardRepeat *repeat_info, U
while (elapsed >= repeat_info->next_repeat_ns) { while (elapsed >= repeat_info->next_repeat_ns) {
if (repeat_info->scancode != SDL_SCANCODE_UNKNOWN) { if (repeat_info->scancode != SDL_SCANCODE_UNKNOWN) {
const Uint64 timestamp = repeat_info->wl_press_time_ns + repeat_info->next_repeat_ns; const Uint64 timestamp = repeat_info->wl_press_time_ns + repeat_info->next_repeat_ns;
SDL_SendKeyboardKeyIgnoreModifiers(Wayland_GetEventTimestamp(timestamp), SDL_PRESSED, repeat_info->scancode); SDL_SendKeyboardKeyIgnoreModifiers(Wayland_GetEventTimestamp(timestamp), 0, SDL_PRESSED, repeat_info->scancode);
} }
if (repeat_info->text[0]) { if (repeat_info->text[0]) {
SDL_SendKeyboardText(repeat_info->text); SDL_SendKeyboardText(repeat_info->text);
@ -1483,7 +1483,7 @@ static void keyboard_handle_enter(void *data, struct wl_keyboard *keyboard,
case SDLK_RGUI: case SDLK_RGUI:
case SDLK_MODE: case SDLK_MODE:
Wayland_HandleModifierKeys(input, scancode, SDL_TRUE); Wayland_HandleModifierKeys(input, scancode, SDL_TRUE);
SDL_SendKeyboardKeyIgnoreModifiers(0, SDL_PRESSED, scancode); SDL_SendKeyboardKeyIgnoreModifiers(0, 0, SDL_PRESSED, scancode);
break; break;
default: default:
break; break;
@ -1618,7 +1618,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
if (!handled_by_ime) { if (!handled_by_ime) {
scancode = Wayland_get_scancode_from_key(input, key + 8); scancode = Wayland_get_scancode_from_key(input, key + 8);
Wayland_HandleModifierKeys(input, scancode, state == WL_KEYBOARD_KEY_STATE_PRESSED); Wayland_HandleModifierKeys(input, scancode, state == WL_KEYBOARD_KEY_STATE_PRESSED);
SDL_SendKeyboardKeyIgnoreModifiers(Wayland_GetKeyboardTimestamp(input, time), state == WL_KEYBOARD_KEY_STATE_PRESSED ? SDL_PRESSED : SDL_RELEASED, scancode); SDL_SendKeyboardKeyIgnoreModifiers(Wayland_GetKeyboardTimestamp(input, time), 0, state == WL_KEYBOARD_KEY_STATE_PRESSED ? SDL_PRESSED : SDL_RELEASED, scancode);
} }
if (state == WL_KEYBOARD_KEY_STATE_PRESSED) { if (state == WL_KEYBOARD_KEY_STATE_PRESSED) {

View File

@ -27,6 +27,7 @@
#include "../../events/SDL_touch_c.h" #include "../../events/SDL_touch_c.h"
#include "../../events/scancodes_windows.h" #include "../../events/scancodes_windows.h"
#include "../../main/SDL_main_callbacks.h" #include "../../main/SDL_main_callbacks.h"
#include "../../core/windows/SDL_hid.h"
/* Dropfile support */ /* Dropfile support */
#include <shellapi.h> #include <shellapi.h>
@ -503,9 +504,9 @@ WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
} }
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) { if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
SDL_SendKeyboardKey(0, SDL_PRESSED, scanCode); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, scanCode);
} else { } else {
SDL_SendKeyboardKey(0, SDL_RELEASED, scanCode); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, scanCode);
/* If the key was down prior to our hook being installed, allow the /* If the key was down prior to our hook being installed, allow the
key up message to pass normally the first time. This ensures other key up message to pass normally the first time. This ensures other
@ -529,11 +530,7 @@ static void WIN_HandleRawMouseInput(Uint64 timestamp, SDL_WindowData *data, HAND
return; return;
} }
/* We do all of our mouse state checking against mouse ID 0 mouseID = (SDL_MouseID)(uintptr_t)hDevice;
* We would only use the actual hDevice if we were tracking
* all mouse motion independently, and never using mouse ID 0.
*/
mouseID = 0; /* (SDL_MouseID)(uintptr_t)inp.header.hDevice; */
if ((rawmouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) { if ((rawmouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) {
if (rawmouse->lLastX || rawmouse->lLastY) { if (rawmouse->lLastX || rawmouse->lLastY) {
@ -698,8 +695,130 @@ void WIN_PollRawMouseInput(void)
#endif /*!defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)*/ #endif /*!defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)*/
LRESULT CALLBACK static void AddDeviceID(Uint32 deviceID, Uint32 **list, int *count)
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
int new_count = (*count + 1);
Uint32 *new_list = (Uint32 *)SDL_realloc(*list, new_count * sizeof(*new_list));
if (!new_list) {
/* Oh well, we'll drop this one */
return;
}
new_list[new_count - 1] = deviceID;
*count = new_count;
*list = new_list;
}
static SDL_bool HasDeviceID(Uint32 deviceID, Uint32 *list, int count)
{
for (int i = 0; i < count; ++i) {
if (deviceID == list[i]) {
return SDL_TRUE;
}
}
return SDL_FALSE;
}
void WIN_CheckKeyboardAndMouseHotplug(SDL_bool initial_check)
{
PRAWINPUTDEVICELIST raw_devices = NULL;
UINT raw_device_count = 0;
int old_keyboard_count = 0;
SDL_KeyboardID *old_keyboards = NULL;
int new_keyboard_count = 0;
SDL_KeyboardID *new_keyboards = NULL;
int old_mouse_count = 0;
SDL_MouseID *old_mice = NULL;
int new_mouse_count = 0;
SDL_MouseID *new_mice = NULL;
/* Check to see if anything has changed */
static Uint64 s_last_device_change;
Uint64 last_device_change = WIN_GetLastDeviceNotification();
if (!initial_check && last_device_change == s_last_device_change) {
return;
}
s_last_device_change = last_device_change;
if ((GetRawInputDeviceList(NULL, &raw_device_count, sizeof(RAWINPUTDEVICELIST)) == -1) || (!raw_device_count)) {
return; /* oh well. */
}
raw_devices = (PRAWINPUTDEVICELIST)SDL_malloc(sizeof(RAWINPUTDEVICELIST) * raw_device_count);
if (!raw_devices) {
return; /* oh well. */
}
raw_device_count = GetRawInputDeviceList(raw_devices, &raw_device_count, sizeof(RAWINPUTDEVICELIST));
if (raw_device_count == (UINT)-1) {
SDL_free(raw_devices);
raw_devices = NULL;
return; /* oh well. */
}
for (UINT i = 0; i < raw_device_count; i++) {
RID_DEVICE_INFO rdi;
char devName[MAX_PATH] = { 0 };
UINT rdiSize = sizeof(rdi);
UINT nameSize = SDL_arraysize(devName);
int vendor = 0, product = 0;
rdi.cbSize = sizeof(rdi);
if (GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICEINFO, &rdi, &rdiSize) == ((UINT)-1) ||
GetRawInputDeviceInfoA(raw_devices[i].hDevice, RIDI_DEVICENAME, devName, &nameSize) == ((UINT)-1)) {
continue;
}
SDL_sscanf(devName, "\\\\?\\HID#VID_%X&PID_%X&", &vendor, &product);
switch (raw_devices[i].dwType) {
case RIM_TYPEKEYBOARD:
if (SDL_IsKeyboard((Uint16)vendor, (Uint16)product, rdi.keyboard.dwNumberOfKeysTotal)) {
AddDeviceID((Uint32)(uintptr_t)raw_devices[i].hDevice, &new_keyboards, &new_keyboard_count);
}
break;
case RIM_TYPEMOUSE:
if (SDL_IsMouse((Uint16)vendor, (Uint16)product)) {
AddDeviceID((Uint32)(uintptr_t)raw_devices[i].hDevice, &new_mice, &new_mouse_count);
}
break;
default:
break;
}
}
SDL_free(raw_devices);
old_keyboards = SDL_GetKeyboards(&old_keyboard_count);
for (int i = old_keyboard_count; i--;) {
if (!HasDeviceID(old_keyboards[i], new_keyboards, new_keyboard_count)) {
SDL_PrivateKeyboardRemoved(old_keyboards[i]);
}
}
for (int i = 0; i < new_keyboard_count; ++i) {
if (!HasDeviceID(new_keyboards[i], old_keyboards, old_keyboard_count)) {
SDL_PrivateKeyboardAdded(new_keyboards[i]);
}
}
SDL_free(new_keyboards);
SDL_free(old_keyboards);
old_mice = SDL_GetMice(&old_mouse_count);
for (int i = old_mouse_count; i--;) {
if (!HasDeviceID(old_mice[i], new_mice, new_mouse_count)) {
SDL_PrivateMouseRemoved(old_mice[i]);
}
}
for (int i = 0; i < new_mouse_count; ++i) {
if (!HasDeviceID(new_mice[i], old_mice, old_mouse_count)) {
SDL_PrivateMouseAdded(new_mice[i]);
}
}
SDL_free(new_mice);
SDL_free(old_mice);
}
LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ {
SDL_WindowData *data; SDL_WindowData *data;
LRESULT returnCode = -1; LRESULT returnCode = -1;
@ -923,7 +1042,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
} }
if (code != SDL_SCANCODE_UNKNOWN) { if (code != SDL_SCANCODE_UNKNOWN) {
SDL_SendKeyboardKey(WIN_GetEventTimestamp(), SDL_PRESSED, code); SDL_SendKeyboardKey(WIN_GetEventTimestamp(), 0, SDL_PRESSED, code);
} }
} }
@ -939,9 +1058,9 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
if (code != SDL_SCANCODE_UNKNOWN) { if (code != SDL_SCANCODE_UNKNOWN) {
if (code == SDL_SCANCODE_PRINTSCREEN && if (code == SDL_SCANCODE_PRINTSCREEN &&
keyboardState[code] == SDL_RELEASED) { keyboardState[code] == SDL_RELEASED) {
SDL_SendKeyboardKey(WIN_GetEventTimestamp(), SDL_PRESSED, code); SDL_SendKeyboardKey(WIN_GetEventTimestamp(), 0, SDL_PRESSED, code);
} }
SDL_SendKeyboardKey(WIN_GetEventTimestamp(), SDL_RELEASED, code); SDL_SendKeyboardKey(WIN_GetEventTimestamp(), 0, SDL_RELEASED, code);
} }
} }
returnCode = 0; returnCode = 0;
@ -1808,10 +1927,10 @@ void WIN_PumpEvents(SDL_VideoDevice *_this)
and if we think a key is pressed when Windows doesn't, unstick it in SDL's state. */ and if we think a key is pressed when Windows doesn't, unstick it in SDL's state. */
keystate = SDL_GetKeyboardState(NULL); keystate = SDL_GetKeyboardState(NULL);
if ((keystate[SDL_SCANCODE_LSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_LSHIFT) & 0x8000)) { if ((keystate[SDL_SCANCODE_LSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_LSHIFT) & 0x8000)) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LSHIFT); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_LSHIFT);
} }
if ((keystate[SDL_SCANCODE_RSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_RSHIFT) & 0x8000)) { if ((keystate[SDL_SCANCODE_RSHIFT] == SDL_PRESSED) && !(GetKeyState(VK_RSHIFT) & 0x8000)) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RSHIFT); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_RSHIFT);
} }
/* The Windows key state gets lost when using Windows+Space or Windows+G shortcuts and /* The Windows key state gets lost when using Windows+Space or Windows+G shortcuts and
@ -1820,10 +1939,10 @@ void WIN_PumpEvents(SDL_VideoDevice *_this)
focusWindow = SDL_GetKeyboardFocus(); focusWindow = SDL_GetKeyboardFocus();
if (!focusWindow || !(focusWindow->flags & SDL_WINDOW_KEYBOARD_GRABBED)) { if (!focusWindow || !(focusWindow->flags & SDL_WINDOW_KEYBOARD_GRABBED)) {
if ((keystate[SDL_SCANCODE_LGUI] == SDL_PRESSED) && !(GetKeyState(VK_LWIN) & 0x8000)) { if ((keystate[SDL_SCANCODE_LGUI] == SDL_PRESSED) && !(GetKeyState(VK_LWIN) & 0x8000)) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LGUI); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_LGUI);
} }
if ((keystate[SDL_SCANCODE_RGUI] == SDL_PRESSED) && !(GetKeyState(VK_RWIN) & 0x8000)) { if ((keystate[SDL_SCANCODE_RGUI] == SDL_PRESSED) && !(GetKeyState(VK_RWIN) & 0x8000)) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RGUI); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_RGUI);
} }
} }
@ -1832,6 +1951,9 @@ void WIN_PumpEvents(SDL_VideoDevice *_this)
/* Update mouse capture */ /* Update mouse capture */
WIN_UpdateMouseCapture(); WIN_UpdateMouseCapture();
WIN_CheckKeyboardAndMouseHotplug(SDL_FALSE);
#endif /*!defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)*/ #endif /*!defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)*/
#ifdef SDL_PLATFORM_GDK #ifdef SDL_PLATFORM_GDK

View File

@ -31,6 +31,7 @@ extern LRESULT CALLBACK WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lP
extern LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, extern LRESULT CALLBACK WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam,
LPARAM lParam); LPARAM lParam);
extern void WIN_PollRawMouseInput(void); extern void WIN_PollRawMouseInput(void);
extern void WIN_CheckKeyboardAndMouseHotplug(SDL_bool initial_check);
extern void WIN_PumpEvents(SDL_VideoDevice *_this); extern void WIN_PumpEvents(SDL_VideoDevice *_this);
extern void WIN_SendWakeupEvent(SDL_VideoDevice *_this, SDL_Window *window); extern void WIN_SendWakeupEvent(SDL_VideoDevice *_this, SDL_Window *window);
extern int WIN_WaitEventTimeout(SDL_VideoDevice *_this, Sint64 timeoutNS); extern int WIN_WaitEventTimeout(SDL_VideoDevice *_this, Sint64 timeoutNS);

View File

@ -28,6 +28,7 @@
#include "../SDL_sysvideo.h" #include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h" #include "../SDL_pixels_c.h"
#include "../../SDL_hints_c.h" #include "../../SDL_hints_c.h"
#include "../../core/windows/SDL_hid.h"
#include "SDL_windowsvideo.h" #include "SDL_windowsvideo.h"
#include "SDL_windowsframebuffer.h" #include "SDL_windowsframebuffer.h"
@ -455,6 +456,8 @@ int WIN_VideoInit(SDL_VideoDevice *_this)
WIN_InitKeyboard(_this); WIN_InitKeyboard(_this);
WIN_InitMouse(_this); WIN_InitMouse(_this);
WIN_InitDeviceNotification();
WIN_CheckKeyboardAndMouseHotplug(SDL_TRUE);
#endif #endif
SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL); SDL_AddHintCallback(SDL_HINT_WINDOWS_ENABLE_MESSAGELOOP, UpdateWindowsEnableMessageLoop, NULL);
@ -472,6 +475,7 @@ void WIN_VideoQuit(SDL_VideoDevice *_this)
{ {
#if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES) #if !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
WIN_QuitModes(_this); WIN_QuitModes(_this);
WIN_QuitDeviceNotification();
WIN_QuitKeyboard(_this); WIN_QuitKeyboard(_this);
WIN_QuitMouse(_this); WIN_QuitMouse(_this);
#endif #endif

View File

@ -77,7 +77,7 @@ void WINRT_ProcessAcceleratorKeyActivated(Windows::UI::Core::AcceleratorKeyEvent
} }
code = WINRT_TranslateKeycode(args->VirtualKey, args->KeyStatus); code = WINRT_TranslateKeycode(args->VirtualKey, args->KeyStatus);
SDL_SendKeyboardKey(0, state, code); SDL_SendKeyboardKey(0, 0, state, code);
} }
void WINRT_ProcessCharacterReceivedEvent(SDL_Window *window, Windows::UI::Core::CharacterReceivedEventArgs ^ args) void WINRT_ProcessCharacterReceivedEvent(SDL_Window *window, Windows::UI::Core::CharacterReceivedEventArgs ^ args)

View File

@ -437,13 +437,13 @@ void X11_ReconcileKeyboardState(SDL_VideoDevice *_this)
case SDLK_LGUI: case SDLK_LGUI:
case SDLK_RGUI: case SDLK_RGUI:
case SDLK_MODE: case SDLK_MODE:
SDL_SendKeyboardKey(0, SDL_PRESSED, scancode); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, scancode);
break; break;
default: default:
break; break;
} }
} else if (!x11KeyPressed && sdlKeyPressed) { } else if (!x11KeyPressed && sdlKeyPressed) {
SDL_SendKeyboardKey(0, SDL_RELEASED, scancode); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, scancode);
} }
} }
} }
@ -957,9 +957,9 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
videodata->filter_time = xevent->xkey.time; videodata->filter_time = xevent->xkey.time;
if (orig_event_type == KeyPress) { if (orig_event_type == KeyPress) {
SDL_SendKeyboardKey(0, SDL_PRESSED, scancode); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, scancode);
} else { } else {
SDL_SendKeyboardKey(0, SDL_RELEASED, scancode); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, scancode);
} }
#endif #endif
} }
@ -1262,7 +1262,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
if (xevent->type == KeyPress) { if (xevent->type == KeyPress) {
/* Don't send the key if it looks like a duplicate of a filtered key sent by an IME */ /* Don't send the key if it looks like a duplicate of a filtered key sent by an IME */
if (xevent->xkey.keycode != videodata->filter_code || xevent->xkey.time != videodata->filter_time) { if (xevent->xkey.keycode != videodata->filter_code || xevent->xkey.time != videodata->filter_time) {
SDL_SendKeyboardKey(0, SDL_PRESSED, videodata->key_layout[keycode]); SDL_SendKeyboardKey(0, 0, SDL_PRESSED, videodata->key_layout[keycode]);
} }
if (*text) { if (*text) {
SDL_SendKeyboardText(text); SDL_SendKeyboardText(text);
@ -1272,7 +1272,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
/* We're about to get a repeated key down, ignore the key up */ /* We're about to get a repeated key down, ignore the key up */
break; break;
} }
SDL_SendKeyboardKey(0, SDL_RELEASED, videodata->key_layout[keycode]); SDL_SendKeyboardKey(0, 0, SDL_RELEASED, videodata->key_layout[keycode]);
} }
} }

View File

@ -20,6 +20,8 @@
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
int num_keyboards = 0;
int num_mice = 0;
int num_joysticks = 0; int num_joysticks = 0;
SDL_Joystick *joystick = NULL; SDL_Joystick *joystick = NULL;
SDL_Haptic *haptic = NULL; SDL_Haptic *haptic = NULL;
@ -78,12 +80,18 @@ int main(int argc, char *argv[])
//SDL_CreateWindow("Dummy", 128, 128, 0); //SDL_CreateWindow("Dummy", 128, 128, 0);
*/ */
SDL_free(SDL_GetKeyboards(&num_keyboards));
SDL_Log("There are %d keyboards at startup\n", num_keyboards);
SDL_free(SDL_GetMice(&num_mice));
SDL_Log("There are %d mice at startup\n", num_mice);
SDL_free(SDL_GetJoysticks(&num_joysticks)); SDL_free(SDL_GetJoysticks(&num_joysticks));
SDL_Log("There are %d joysticks at startup\n", num_joysticks); SDL_Log("There are %d joysticks at startup\n", num_joysticks);
if (enable_haptic) { if (enable_haptic) {
int num_haptics; int num_haptics;
SDL_HapticID *haptics = SDL_GetHaptics(&num_haptics); SDL_free(SDL_GetHaptics(&num_haptics));
SDL_free(haptics);
SDL_Log("There are %d haptic devices at startup\n", num_haptics); SDL_Log("There are %d haptic devices at startup\n", num_haptics);
} }
@ -94,6 +102,18 @@ int main(int argc, char *argv[])
case SDL_EVENT_QUIT: case SDL_EVENT_QUIT:
keepGoing = SDL_FALSE; keepGoing = SDL_FALSE;
break; break;
case SDL_EVENT_KEYBOARD_ADDED:
SDL_Log("Keyboard added : %" SDL_PRIu32 "\n", event.kdevice.which);
break;
case SDL_EVENT_KEYBOARD_REMOVED:
SDL_Log("Keyboard removed: %" SDL_PRIu32 "\n", event.kdevice.which);
break;
case SDL_EVENT_MOUSE_ADDED:
SDL_Log("Mouse added : %" SDL_PRIu32 "\n", event.mdevice.which);
break;
case SDL_EVENT_MOUSE_REMOVED:
SDL_Log("Mouse removed: %" SDL_PRIu32 "\n", event.mdevice.which);
break;
case SDL_EVENT_JOYSTICK_ADDED: case SDL_EVENT_JOYSTICK_ADDED:
if (joystick) { if (joystick) {
SDL_Log("Only one joystick supported by this test\n"); SDL_Log("Only one joystick supported by this test\n");