Initial support for hotplugging mice and keyboards

This commit is contained in:
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

@@ -303,7 +303,7 @@ class SDL_BLooper : public BLooper
return;
}
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)) {
const int8 *keyUtf8;

View File

@@ -375,9 +375,9 @@ void SDL_EVDEV_Poll(void)
scan_code = SDL_EVDEV_translate_keycode(event->code);
if (scan_code != SDL_SCANCODE_UNKNOWN) {
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 */) {
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);

View File

@@ -553,22 +553,22 @@ static void Translate_to_keycode(SDL_WSCONS_input_data *input, int type, keysym_
switch (keyDesc.command) {
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;
}
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;
}
}
for (i = 0; i < sizeof(conversion_table) / sizeof(struct wscons_keycode_to_SDL); i++) {
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;
}
}
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)
@@ -802,13 +802,13 @@ static void updateKeyboard(SDL_WSCONS_input_data *input)
} break;
case WSCONS_EVENT_ALL_KEYS_UP:
for (i = 0; i < SDL_NUM_SCANCODES; i++) {
SDL_SendKeyboardKey(0, SDL_RELEASED, i);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, i);
}
break;
}
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
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 int s_HIDDLLRefCount = 0;
int WIN_LoadHIDDLL(void)
{
if (s_pHIDDLL) {
@@ -82,3 +83,174 @@ void WIN_UnloadHIDDLL(void)
}
#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 void WIN_UnloadHIDDLL(void);
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_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 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 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_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 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);
extern HidD_GetString_t SDL_HidD_GetManufacturerString;
extern HidD_GetString_t SDL_HidD_GetProductString;
@@ -210,4 +210,9 @@ extern HidP_GetData_t SDL_HidP_GetData;
#endif /* !SDL_PLATFORM_WINRT */
void WIN_InitDeviceNotification(void);
Uint64 WIN_GetLastDeviceNotification(void);
void WIN_QuitDeviceNotification(void);
#endif /* SDL_hid_h_ */

View File

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