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_KEYMAP_CHANGED, /**< Keymap changed due to a system event such as an
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 */
SDL_EVENT_MOUSE_MOTION = 0x400, /**< Mouse moved */
SDL_EVENT_MOUSE_BUTTON_DOWN, /**< Mouse button pressed */
SDL_EVENT_MOUSE_BUTTON_UP, /**< Mouse button released */
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 */
SDL_EVENT_JOYSTICK_AXIS_MOTION = 0x600, /**< Joystick axis motion */
@ -270,6 +274,17 @@ typedef struct SDL_WindowEvent
Sint32 data2; /**< event dependent data */
} 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.*)
*/
@ -279,6 +294,7 @@ typedef struct SDL_KeyboardEvent
Uint32 reserved;
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
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 repeat; /**< Non-zero if this is a key repeat */
Uint8 padding2;
@ -320,6 +336,17 @@ typedef struct SDL_TextInputEvent
char *text; /**< The input text */
} 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.*)
*/
@ -718,21 +745,23 @@ typedef union SDL_Event
SDL_CommonEvent common; /**< Common event data */
SDL_DisplayEvent display; /**< Display event data */
SDL_WindowEvent window; /**< Window event data */
SDL_KeyboardDeviceEvent kdevice; /**< Keyboard device change event data */
SDL_KeyboardEvent key; /**< Keyboard event data */
SDL_TextEditingEvent edit; /**< Text editing 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_MouseButtonEvent button; /**< Mouse button 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_JoyBallEvent jball; /**< Joystick ball event data */
SDL_JoyHatEvent jhat; /**< Joystick hat 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_GamepadDeviceEvent gdevice; /**< Gamepad device event data */
SDL_GamepadAxisEvent gaxis; /**< Gamepad axis event data */
SDL_GamepadButtonEvent gbutton; /**< Gamepad button event data */
SDL_GamepadDeviceEvent gdevice; /**< Gamepad device event data */
SDL_GamepadTouchpadEvent gtouchpad; /**< Gamepad touchpad event data */
SDL_GamepadSensorEvent gsensor; /**< Gamepad sensor 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);
/**
* 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.
*
@ -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.
*
* \sa SDL_HasGamepad
* \sa SDL_OpenGamepad
*/
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);
/**
* 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.
*
@ -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.
*
* \sa SDL_HasJoystick
* \sa SDL_OpenJoystick
*/
extern DECLSPEC SDL_JoystickID *SDLCALL SDL_GetJoysticks(int *count);

View File

@ -39,6 +39,8 @@
extern "C" {
#endif
typedef Uint32 SDL_KeyboardID;
/**
* The SDL keysym structure, used in key events.
*
@ -54,6 +56,31 @@ typedef struct SDL_Keysym
/* 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.
*

View File

@ -81,6 +81,31 @@ typedef enum
/* 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.
*

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;

View File

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

View File

@ -345,11 +345,13 @@
#define SDL_GetKeyName SDL_GetKeyName_REAL
#define SDL_GetKeyboardFocus SDL_GetKeyboardFocus_REAL
#define SDL_GetKeyboardState SDL_GetKeyboardState_REAL
#define SDL_GetKeyboards SDL_GetKeyboards_REAL
#define SDL_GetLogOutputFunction SDL_GetLogOutputFunction_REAL
#define SDL_GetMasksForPixelFormatEnum SDL_GetMasksForPixelFormatEnum_REAL
#define SDL_GetMaxHapticEffects SDL_GetMaxHapticEffects_REAL
#define SDL_GetMaxHapticEffectsPlaying SDL_GetMaxHapticEffectsPlaying_REAL
#define SDL_GetMemoryFunctions SDL_GetMemoryFunctions_REAL
#define SDL_GetMice SDL_GetMice_REAL
#define SDL_GetModState SDL_GetModState_REAL
#define SDL_GetMouseFocus SDL_GetMouseFocus_REAL
#define SDL_GetMouseState SDL_GetMouseState_REAL
@ -512,9 +514,13 @@
#define SDL_HasClipboardText SDL_HasClipboardText_REAL
#define SDL_HasEvent SDL_HasEvent_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_HasLSX SDL_HasLSX_REAL
#define SDL_HasMMX SDL_HasMMX_REAL
#define SDL_HasMouse SDL_HasMouse_REAL
#define SDL_HasNEON SDL_HasNEON_REAL
#define SDL_HasPrimarySelectionText SDL_HasPrimarySelectionText_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(SDL_Window*,SDL_GetKeyboardFocus,(void),(),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(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_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(SDL_MouseID*,SDL_GetMice,(int *a),(a),return)
SDL_DYNAPI_PROC(SDL_Keymod,SDL_GetModState,(void),(),return)
SDL_DYNAPI_PROC(SDL_Window*,SDL_GetMouseFocus,(void),(),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_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_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_HasLSX,(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_HasPrimarySelectionText,(void),(),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);
#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) \
(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, \
@ -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);
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)
(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,

View File

@ -55,6 +55,8 @@ struct 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] = {
/* 0 */ SDLK_UNKNOWN,
@ -678,6 +680,109 @@ int SDL_InitKeyboard(void)
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)
{
SDL_Keyboard *keyboard = &SDL_keyboard;
@ -688,7 +793,7 @@ void SDL_ResetKeyboard(void)
#endif
for (scancode = (SDL_Scancode)0; scancode < SDL_NUM_SCANCODES; ++scancode) {
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;
}
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;
int posted;
@ -831,6 +936,13 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, Uint8 sta
Uint8 repeat = SDL_FALSE;
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) {
return 0;
}
@ -949,6 +1061,7 @@ static int SDL_SendKeyboardKeyInternal(Uint64 timestamp, Uint32 flags, Uint8 sta
event.key.keysym.sym = keycode;
event.key.keysym.mod = keyboard->modstate;
event.key.windowID = keyboard->focus ? keyboard->focus->id : 0;
event.key.which = keyboardID;
posted = (SDL_PushEvent(&event) > 0);
}
@ -982,43 +1095,43 @@ int SDL_SendKeyboardUnicodeKey(Uint64 timestamp, Uint32 ch)
if (mod & SDL_KMOD_SHIFT) {
/* 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 */
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_PRESSED, code, SDLK_UNKNOWN);
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, SDL_RELEASED, code, SDLK_UNKNOWN);
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, 0, SDL_PRESSED, code, SDLK_UNKNOWN);
SDL_SendKeyboardKeyInternal(timestamp, KEYBOARD_VIRTUAL, 0, SDL_RELEASED, code, SDLK_UNKNOWN);
if (mod & SDL_KMOD_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;
}
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)
{
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)
@ -1029,7 +1142,7 @@ void SDL_ReleaseAutoReleaseKeys(void)
if (keyboard->autorelease_pending) {
for (scancode = SDL_SCANCODE_UNKNOWN; scancode < SDL_NUM_SCANCODES; ++scancode) {
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;
@ -1117,6 +1230,9 @@ int SDL_SendEditingText(const char *text, int start, int length)
void SDL_QuitKeyboard(void)
{
SDL_keyboard_count = 0;
SDL_free(SDL_keyboards);
SDL_keyboards = NULL;
}
const Uint8 *SDL_GetKeyboardState(int *numkeys)

View File

@ -26,6 +26,15 @@
/* Initialize the keyboard subsystem */
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 */
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);
/* 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_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.
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 */
extern void SDL_ReleaseAutoReleaseKeys(void);

View File

@ -35,6 +35,8 @@
/* The mouse state */
static SDL_Mouse SDL_mouse;
static int SDL_mouse_count;
static SDL_MouseID *SDL_mice;
/* for mapping mouse events to touch */
static SDL_bool track_mouse_down = SDL_FALSE;
@ -227,6 +229,118 @@ void SDL_PostInitMouse(void)
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)
{
SDL_Mouse *mouse = SDL_GetMouse();
@ -687,18 +801,35 @@ static int SDL_PrivateSendMouseMotion(Uint64 timestamp, SDL_Window *window, SDL_
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;
for (i = 0; i < mouse->num_sources; ++i) {
source = &mouse->sources[i];
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));
if (sources) {
mouse->sources = sources;
@ -737,7 +868,7 @@ static int SDL_PrivateSendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_
Uint32 buttonstate;
SDL_MouseInputSource *source;
source = GetMouseInputSource(mouse, mouseID);
source = GetMouseInputSource(mouse, mouseID, state, button);
if (!source) {
return 0;
}
@ -823,7 +954,7 @@ static int SDL_PrivateSendMouseButton(Uint64 timestamp, SDL_Window *window, SDL_
event.type = type;
event.common.timestamp = timestamp;
event.button.windowID = mouse->focus ? mouse->focus->id : 0;
event.button.which = mouseID;
event.button.which = source->mouseID;
event.button.state = state;
event.button.button = button;
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_MouseRelativeWarpMotionChanged, mouse);
SDL_mouse_count = 0;
SDL_free(SDL_mice);
SDL_mice = NULL;
}
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 */
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 */
SDL_Mouse *SDL_GetMouse(void);
extern SDL_Mouse *SDL_GetMouse(void);
/* Set the default mouse cursor */
extern void SDL_SetDefaultCursor(SDL_Cursor *cursor);

View File

@ -2369,6 +2369,26 @@ int SDL_InitGamepads(void)
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)
{
int num_joysticks = 0;

View File

@ -682,6 +682,25 @@ SDL_bool SDL_JoystickHandledByAnotherDriver(struct SDL_JoystickDriver *driver, U
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)
{
int i, num_joysticks, device_index;

View File

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

View File

@ -35,6 +35,7 @@
#include "../SDL_sysjoystick.h"
#include "../../thread/SDL_systhread.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)
#include <dbt.h>
#endif
@ -51,162 +52,34 @@
#define DEVICE_NOTIFY_WINDOW_HANDLE 0x00000000
#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 */
static SDL_bool s_bJoystickThread = SDL_FALSE;
static SDL_bool s_bWindowsDeviceChanged = SDL_FALSE;
static SDL_Condition *s_condJoystickThread = NULL;
static SDL_Mutex *s_mutexJoyStickEnum = NULL;
static SDL_Thread *s_joystickThread = NULL;
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 } };
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 CM_Register_NotificationFunc CM_Register_Notification;
static CM_Unregister_NotificationFunc CM_Unregister_Notification;
static HCMNOTIFICATION s_DeviceNotificationFuncHandle;
static SDL_bool WindowsDeviceChanged(void)
{
return (s_lastDeviceChange != WIN_GetLastDeviceNotification());
}
static void SetWindowsDeviceChanged(void)
{
s_lastDeviceChange = 0;
}
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 (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;
}
#if !defined(SDL_PLATFORM_WINRT) && !defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)
typedef struct
{
@ -239,7 +112,7 @@ static LRESULT CALLBACK SDL_PrivateJoystickDetectProc(HWND hwnd, UINT msg, WPARA
if (wParam == IDT_SDL_DEVICE_CHANGE_TIMER_1 ||
wParam == IDT_SDL_DEVICE_CHANGE_TIMER_2) {
KillTimer(hwnd, wParam);
s_bWindowsDeviceChanged = SDL_TRUE;
SetWindowsDeviceChanged();
return 0;
}
break;
@ -327,7 +200,7 @@ static SDL_bool SDL_WaitForDeviceNotification(SDL_DeviceNotificationData *data,
}
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 */
if (lastret > 0) {
TranslateMessage(&msg);
@ -378,7 +251,7 @@ static int SDLCALL SDL_JoystickThread(void *_data)
const DWORD result = XINPUTGETCAPABILITIES(userId, XINPUT_FLAG_GAMEPAD, &capabilities);
const SDL_bool available = (result == ERROR_SUCCESS);
if (bOpenedXInputDevices[userId] != available) {
s_bWindowsDeviceChanged = SDL_TRUE;
SetWindowsDeviceChanged();
bOpenedXInputDevices[userId] = available;
}
}
@ -476,13 +349,9 @@ static int WINDOWS_JoystickInit(void)
return -1;
}
s_bWindowsDeviceChanged = SDL_TRUE; /* force a scan of the system for joysticks this first time */
WINDOWS_JoystickDetect();
WIN_InitDeviceNotification();
#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);
if (s_bJoystickThread) {
if (SDL_StartJoystickThread() < 0) {
@ -502,6 +371,11 @@ static int WINDOWS_JoystickInit(void)
return -1;
}
#endif
SetWindowsDeviceChanged(); /* force a scan of the system for joysticks this first time */
WINDOWS_JoystickDetect();
return 0;
}
@ -524,7 +398,7 @@ void WINDOWS_JoystickDetect(void)
JoyStick_DeviceData *pCurList = NULL;
/* 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. */
}
@ -532,7 +406,7 @@ void WINDOWS_JoystickDetect(void)
SDL_LockMutex(s_mutexJoyStickEnum);
}
s_bWindowsDeviceChanged = SDL_FALSE;
s_lastDeviceChange = WIN_GetLastDeviceNotification();
pCurList = SYS_Joystick;
SYS_Joystick = NULL;
@ -774,8 +648,6 @@ void WINDOWS_JoystickQuit(void)
} else {
SDL_CleanupDeviceNotification(&s_notification_data);
}
SDL_CleanupDeviceNotificationFunc();
#endif
#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)
@ -787,7 +659,7 @@ void WINDOWS_JoystickQuit(void)
SDL_DINPUT_JoystickQuit();
SDL_XINPUT_JoystickQuit();
s_bWindowsDeviceChanged = SDL_FALSE;
WIN_QuitDeviceNotification();
}
static SDL_bool WINDOWS_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
@ -819,11 +691,6 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver = {
WINDOWS_JoystickGetGamepadMapping
};
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
}
#endif
#else
#ifdef SDL_JOYSTICK_RAWINPUT

View File

@ -1661,6 +1661,14 @@ static void SDLTest_PrintEvent(const SDL_Event *event)
case SDL_EVENT_WINDOW_DESTROYED:
SDL_Log("SDL EVENT: Window %" SDL_PRIu32 " destroyed", event->window.windowID);
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_UP: {
char modstr[64];
@ -1691,6 +1699,14 @@ static void SDLTest_PrintEvent(const SDL_Event *event)
case SDL_EVENT_KEYMAP_CHANGED:
SDL_Log("SDL EVENT: Keymap changed");
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:
SDL_Log("SDL EVENT: Mouse: moved to %g,%g (%g,%g) in window %" SDL_PRIu32,
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);
break;
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);
break;
case SDL_EVENT_JOYSTICK_REMOVED:
@ -1768,7 +1784,7 @@ static void SDLTest_PrintEvent(const SDL_Event *event)
event->jbutton.which, event->jbutton.button);
break;
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);
break;
case SDL_EVENT_GAMEPAD_REMOVED:

View File

@ -330,12 +330,12 @@ static SDL_Scancode TranslateKeycode(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)
{
return SDL_SendKeyboardKey(0, SDL_RELEASED, TranslateKeycode(keycode));
return SDL_SendKeyboardKey(0, 0, SDL_RELEASED, TranslateKeycode(keycode));
}
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) {
SDL_SendKeyboardKey(0, SDL_PRESSED, code);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, code);
} 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;
}
/*
/*
* Swap the scancode for these two wrongly translated keys
* 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
@ -414,7 +414,7 @@ void Cocoa_HandleKeyEvent(SDL_VideoDevice *_this, NSEvent *event)
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
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);
@ -433,7 +433,7 @@ void Cocoa_HandleKeyEvent(SDL_VideoDevice *_this, NSEvent *event)
}
break;
case NSEventTypeKeyUp:
SDL_SendKeyboardKey(Cocoa_GetEventTimestamp([event timestamp]), SDL_RELEASED, code);
SDL_SendKeyboardKey(Cocoa_GetEventTimestamp([event timestamp]), 0, SDL_RELEASED, code);
break;
case NSEventTypeFlagsChanged: {
// 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 sdlenabled = (SDL_GetModState() & SDL_KMOD_CAPS) ? SDL_TRUE : SDL_FALSE;
if (osenabled ^ sdlenabled) {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
}
}
- (void)keyDown:(NSEvent *)theEvent

View File

@ -811,7 +811,7 @@ static EM_BOOL Emscripten_HandleKey(int eventType, const EmscriptenKeyboardEvent
}
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

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

@ -154,10 +154,10 @@ int HandleWsEvent(SDL_VideoDevice *_this, const TWsEvent &aWsEvent)
switch (aWsEvent.Type()) {
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;
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;
case EEventFocusGained: /* SDL window got focus */
phdata->NGAGE_IsWindowFocused = ETrue;

View File

@ -90,7 +90,7 @@ void PSP_PumpEvents(SDL_VideoDevice *_this)
if (changed) {
for (i = 0; i < sizeof(keymap_psp) / sizeof(keymap_psp[0]); i++) {
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];
/* not tested */
/* 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:
// Need to handle more key states (such as key combinations).
if (val & KEY_DOWN) {
SDL_SendKeyboardKey(0, SDL_PRESSED, scancode);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, scancode);
} 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++) {
if (driverdata->key_pressed[i] != 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;
}
}
@ -81,7 +81,7 @@ void RISCOS_PollKeyboard(SDL_VideoDevice *_this)
break;
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. */
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 SDL_InitGCKeyboard(void);
extern SDL_bool SDL_HasGCKeyboard(void);
extern void SDL_QuitGCKeyboard(void);
extern void SDL_InitGCMouse(void);
extern SDL_bool SDL_HasGCMouse(void);
extern SDL_bool SDL_GCMouseRelativeMode(void);
extern void SDL_QuitGCMouse(void);

View File

@ -171,15 +171,17 @@ void UIKit_PumpEvents(SDL_VideoDevice *_this)
#ifdef ENABLE_GCKEYBOARD
static SDL_bool keyboard_connected = SDL_FALSE;
static id keyboard_connect_observer = nil;
static id keyboard_disconnect_observer = nil;
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) {
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);
@ -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))
{
SDL_KeyboardID keyboardID = (SDL_KeyboardID)(uintptr_t)keyboard;
SDL_PrivateKeyboardRemoved(keyboardID);
keyboard.keyboardInput.keyChangedHandler = nil;
keyboard_connected = SDL_FALSE;
}
void SDL_InitGCKeyboard(void)
@ -222,11 +227,6 @@ void SDL_InitGCKeyboard(void)
}
}
SDL_bool SDL_HasGCKeyboard(void)
{
return keyboard_connected;
}
void SDL_QuitGCKeyboard(void)
{
@autoreleasepool {
@ -256,11 +256,6 @@ void SDL_InitGCKeyboard(void)
{
}
SDL_bool SDL_HasGCKeyboard(void)
{
return SDL_FALSE;
}
void SDL_QuitGCKeyboard(void)
{
}
@ -269,7 +264,6 @@ void SDL_QuitGCKeyboard(void)
#ifdef ENABLE_GCMOUSE
static int mice_connected = 0;
static id mouse_connect_observer = nil;
static id mouse_disconnect_observer = nil;
static bool mouse_relative_mode = SDL_FALSE;
@ -291,7 +285,7 @@ static void UpdateScrollDirection(void)
/* Couldn't read the preference, assume natural scrolling direction */
naturalScrollDirection = YES;
}
if (naturalScrollDirection) {
if (naturalScrollDirection) {
mouse_scroll_direction = SDL_MOUSEWHEEL_FLIPPED;
} else {
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))
{
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) {
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));
mouse.handlerQueue = queue;
++mice_connected;
UpdatePointerLock();
}
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;
@ -390,6 +384,8 @@ static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios
}
UpdatePointerLock();
SDL_PrivateMouseRemoved(mouseID);
}
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)
{
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)
{
return SDL_FALSE;

View File

@ -229,7 +229,7 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
#if !defined(SDL_PLATFORM_TVOS) && defined(__IPHONE_13_4)
if (@available(iOS 13.4, *)) {
if (touch.type == UITouchTypeIndirectPointer) {
if (!SDL_HasGCMouse()) {
if (!SDL_HasMouse()) {
int 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 (@available(iOS 13.4, *)) {
if (touch.type == UITouchTypeIndirectPointer) {
if (!SDL_HasGCMouse()) {
if (!SDL_HasMouse()) {
int 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
{
if (!SDL_HasGCKeyboard()) {
if (!SDL_HasKeyboard()) {
for (UIPress *press in presses) {
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()) {
@ -424,10 +424,10 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
{
if (!SDL_HasGCKeyboard()) {
if (!SDL_HasKeyboard()) {
for (UIPress *press in presses) {
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()) {
@ -437,10 +437,10 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
{
if (!SDL_HasGCKeyboard()) {
if (!SDL_HasKeyboard()) {
for (UIPress *press in presses) {
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()) {

View File

@ -62,40 +62,40 @@ void VITA_PollKeyboard(void)
// The k_report only reports the state of the LED
if (k_reports[numReports - 1].modifiers[1] & 0x1) {
if (!(locks & 0x1)) {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
locks |= 0x1;
}
} else {
if (locks & 0x1) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_NUMLOCKCLEAR);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_NUMLOCKCLEAR);
locks &= ~0x1;
}
}
if (k_reports[numReports - 1].modifiers[1] & 0x2) {
if (!(locks & 0x2)) {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
locks |= 0x2;
}
} else {
if (locks & 0x2) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_CAPSLOCK);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_CAPSLOCK);
locks &= ~0x2;
}
}
if (k_reports[numReports - 1].modifiers[1] & 0x4) {
if (!(locks & 0x4)) {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_SCROLLLOCK);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_SCROLLLOCK);
locks |= 0x4;
}
} else {
if (locks & 0x4) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_SCROLLLOCK);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_SCROLLLOCK);
locks &= ~0x4;
}
}
@ -105,58 +105,58 @@ void VITA_PollKeyboard(void)
if (changed_modifiers & 0x01) {
if (prev_modifiers & 0x01) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LCTRL);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_LCTRL);
} else {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LCTRL);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_LCTRL);
}
}
if (changed_modifiers & 0x02) {
if (prev_modifiers & 0x02) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LSHIFT);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_LSHIFT);
} else {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LSHIFT);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_LSHIFT);
}
}
if (changed_modifiers & 0x04) {
if (prev_modifiers & 0x04) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LALT);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_LALT);
} else {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LALT);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_LALT);
}
}
if (changed_modifiers & 0x08) {
if (prev_modifiers & 0x08) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_LGUI);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_LGUI);
} else {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_LGUI);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_LGUI);
}
}
if (changed_modifiers & 0x10) {
if (prev_modifiers & 0x10) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RCTRL);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_RCTRL);
} else {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_RCTRL);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_RCTRL);
}
}
if (changed_modifiers & 0x20) {
if (prev_modifiers & 0x20) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RSHIFT);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_RSHIFT);
} else {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_RSHIFT);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_RSHIFT);
}
}
if (changed_modifiers & 0x40) {
if (prev_modifiers & 0x40) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RALT);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_RALT);
} else {
SDL_SendKeyboardKey(0, SDL_PRESSED, SDL_SCANCODE_RALT);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, SDL_SCANCODE_RALT);
}
}
if (changed_modifiers & 0x80) {
if (prev_modifiers & 0x80) {
SDL_SendKeyboardKey(0, SDL_RELEASED, SDL_SCANCODE_RGUI);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, SDL_SCANCODE_RGUI);
} 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 (prev_keys[i]) {
SDL_SendKeyboardKey(0, SDL_RELEASED, prev_keys[i]);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, prev_keys[i]);
}
if (keyCode) {
SDL_SendKeyboardKey(0, SDL_PRESSED, keyCode);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, 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) {
if (repeat_info->scancode != SDL_SCANCODE_UNKNOWN) {
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]) {
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_MODE:
Wayland_HandleModifierKeys(input, scancode, SDL_TRUE);
SDL_SendKeyboardKeyIgnoreModifiers(0, SDL_PRESSED, scancode);
SDL_SendKeyboardKeyIgnoreModifiers(0, 0, SDL_PRESSED, scancode);
break;
default:
break;
@ -1618,7 +1618,7 @@ static void keyboard_handle_key(void *data, struct wl_keyboard *keyboard,
if (!handled_by_ime) {
scancode = Wayland_get_scancode_from_key(input, key + 8);
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) {

View File

@ -27,6 +27,7 @@
#include "../../events/SDL_touch_c.h"
#include "../../events/scancodes_windows.h"
#include "../../main/SDL_main_callbacks.h"
#include "../../core/windows/SDL_hid.h"
/* Dropfile support */
#include <shellapi.h>
@ -503,9 +504,9 @@ WIN_KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam)
}
if (wParam == WM_KEYDOWN || wParam == WM_SYSKEYDOWN) {
SDL_SendKeyboardKey(0, SDL_PRESSED, scanCode);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, scanCode);
} 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
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;
}
/* We do all of our mouse state checking against mouse ID 0
* 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; */
mouseID = (SDL_MouseID)(uintptr_t)hDevice;
if ((rawmouse->usFlags & 0x01) == MOUSE_MOVE_RELATIVE) {
if (rawmouse->lLastX || rawmouse->lLastY) {
@ -698,8 +695,130 @@ void WIN_PollRawMouseInput(void)
#endif /*!defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)*/
LRESULT CALLBACK
WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
static void AddDeviceID(Uint32 deviceID, Uint32 **list, int *count)
{
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;
LRESULT returnCode = -1;
@ -923,7 +1042,7 @@ WIN_WindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
}
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_PRINTSCREEN &&
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;
@ -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. */
keystate = SDL_GetKeyboardState(NULL);
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)) {
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
@ -1820,10 +1939,10 @@ void WIN_PumpEvents(SDL_VideoDevice *_this)
focusWindow = SDL_GetKeyboardFocus();
if (!focusWindow || !(focusWindow->flags & SDL_WINDOW_KEYBOARD_GRABBED)) {
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)) {
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 */
WIN_UpdateMouseCapture();
WIN_CheckKeyboardAndMouseHotplug(SDL_FALSE);
#endif /*!defined(SDL_PLATFORM_XBOXONE) && !defined(SDL_PLATFORM_XBOXSERIES)*/
#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,
LPARAM lParam);
extern void WIN_PollRawMouseInput(void);
extern void WIN_CheckKeyboardAndMouseHotplug(SDL_bool initial_check);
extern void WIN_PumpEvents(SDL_VideoDevice *_this);
extern void WIN_SendWakeupEvent(SDL_VideoDevice *_this, SDL_Window *window);
extern int WIN_WaitEventTimeout(SDL_VideoDevice *_this, Sint64 timeoutNS);

View File

@ -28,6 +28,7 @@
#include "../SDL_sysvideo.h"
#include "../SDL_pixels_c.h"
#include "../../SDL_hints_c.h"
#include "../../core/windows/SDL_hid.h"
#include "SDL_windowsvideo.h"
#include "SDL_windowsframebuffer.h"
@ -455,6 +456,8 @@ int WIN_VideoInit(SDL_VideoDevice *_this)
WIN_InitKeyboard(_this);
WIN_InitMouse(_this);
WIN_InitDeviceNotification();
WIN_CheckKeyboardAndMouseHotplug(SDL_TRUE);
#endif
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)
WIN_QuitModes(_this);
WIN_QuitDeviceNotification();
WIN_QuitKeyboard(_this);
WIN_QuitMouse(_this);
#endif

View File

@ -77,7 +77,7 @@ void WINRT_ProcessAcceleratorKeyActivated(Windows::UI::Core::AcceleratorKeyEvent
}
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)

View File

@ -437,13 +437,13 @@ void X11_ReconcileKeyboardState(SDL_VideoDevice *_this)
case SDLK_LGUI:
case SDLK_RGUI:
case SDLK_MODE:
SDL_SendKeyboardKey(0, SDL_PRESSED, scancode);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, scancode);
break;
default:
break;
}
} 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;
if (orig_event_type == KeyPress) {
SDL_SendKeyboardKey(0, SDL_PRESSED, scancode);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, scancode);
} else {
SDL_SendKeyboardKey(0, SDL_RELEASED, scancode);
SDL_SendKeyboardKey(0, 0, SDL_RELEASED, scancode);
}
#endif
}
@ -1262,7 +1262,7 @@ static void X11_DispatchEvent(SDL_VideoDevice *_this, XEvent *xevent)
if (xevent->type == KeyPress) {
/* 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) {
SDL_SendKeyboardKey(0, SDL_PRESSED, videodata->key_layout[keycode]);
SDL_SendKeyboardKey(0, 0, SDL_PRESSED, videodata->key_layout[keycode]);
}
if (*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 */
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 num_keyboards = 0;
int num_mice = 0;
int num_joysticks = 0;
SDL_Joystick *joystick = NULL;
SDL_Haptic *haptic = NULL;
@ -78,12 +80,18 @@ int main(int argc, char *argv[])
//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_Log("There are %d joysticks at startup\n", num_joysticks);
if (enable_haptic) {
int num_haptics;
SDL_HapticID *haptics = SDL_GetHaptics(&num_haptics);
SDL_free(haptics);
SDL_free(SDL_GetHaptics(&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:
keepGoing = SDL_FALSE;
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:
if (joystick) {
SDL_Log("Only one joystick supported by this test\n");