|
@@ -30,6 +30,13 @@
|
|
|
|
|
|
#import <Foundation/Foundation.h>
|
|
|
|
|
|
+#if (__IPHONE_OS_VERSION_MAX_ALLOWED >= 140000) || (__APPLETV_OS_VERSION_MAX_ALLOWED >= 140000) || (__MAC_OS_VERSION_MAX_ALLOWED > 1500000)
|
|
|
+#import <GameController/GameController.h>
|
|
|
+
|
|
|
+#define ENABLE_GCKEYBOARD
|
|
|
+#define ENABLE_GCMOUSE
|
|
|
+#endif
|
|
|
+
|
|
|
static BOOL UIKit_EventPumpEnabled = YES;
|
|
|
|
|
|
void
|
|
@@ -70,6 +77,247 @@ UIKit_PumpEvents(_THIS)
|
|
|
#endif
|
|
|
}
|
|
|
|
|
|
+#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;
|
|
|
+ keyboard.keyboardInput.keyChangedHandler = ^(GCKeyboardInput *keyboard, GCControllerButtonInput *key, GCKeyCode keyCode, BOOL pressed)
|
|
|
+ {
|
|
|
+ SDL_SendKeyboardKey(pressed ? SDL_PRESSED : SDL_RELEASED, (SDL_Scancode)keyCode);
|
|
|
+ };
|
|
|
+}
|
|
|
+
|
|
|
+static void OnGCKeyboardDisconnected(GCKeyboard *keyboard) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
|
|
|
+{
|
|
|
+ keyboard.keyboardInput.keyChangedHandler = nil;
|
|
|
+ keyboard_connected = SDL_FALSE;
|
|
|
+}
|
|
|
+
|
|
|
+void SDL_InitGCKeyboard(void)
|
|
|
+{
|
|
|
+ @autoreleasepool {
|
|
|
+ if (@available(iOS 14.0, tvOS 14.0, *)) {
|
|
|
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
|
|
+
|
|
|
+ keyboard_connect_observer = [center addObserverForName:GCKeyboardDidConnectNotification
|
|
|
+ object:nil
|
|
|
+ queue:nil
|
|
|
+ usingBlock:^(NSNotification *note) {
|
|
|
+ GCKeyboard *keyboard = note.object;
|
|
|
+ OnGCKeyboardConnected(keyboard);
|
|
|
+ }];
|
|
|
+
|
|
|
+ keyboard_disconnect_observer = [center addObserverForName:GCKeyboardDidDisconnectNotification
|
|
|
+ object:nil
|
|
|
+ queue:nil
|
|
|
+ usingBlock:^(NSNotification *note) {
|
|
|
+ GCKeyboard *keyboard = note.object;
|
|
|
+ OnGCKeyboardDisconnected(keyboard);
|
|
|
+ }];
|
|
|
+
|
|
|
+ if (GCKeyboard.coalescedKeyboard != nil) {
|
|
|
+ OnGCKeyboardConnected(GCKeyboard.coalescedKeyboard);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SDL_bool SDL_HasGCKeyboard(void)
|
|
|
+{
|
|
|
+ return keyboard_connected;
|
|
|
+}
|
|
|
+
|
|
|
+void SDL_QuitGCKeyboard(void)
|
|
|
+{
|
|
|
+ @autoreleasepool {
|
|
|
+ if (@available(iOS 14.0, tvOS 14.0, *)) {
|
|
|
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
|
|
+
|
|
|
+ if (keyboard_connect_observer) {
|
|
|
+ [center removeObserver:keyboard_connect_observer name:GCKeyboardDidConnectNotification object:nil];
|
|
|
+ keyboard_connect_observer = nil;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (keyboard_disconnect_observer) {
|
|
|
+ [center removeObserver:keyboard_disconnect_observer name:GCKeyboardDidDisconnectNotification object:nil];
|
|
|
+ keyboard_disconnect_observer = nil;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (GCKeyboard.coalescedKeyboard != nil) {
|
|
|
+ OnGCKeyboardDisconnected(GCKeyboard.coalescedKeyboard);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#else
|
|
|
+
|
|
|
+void SDL_InitGCKeyboard(void)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+SDL_bool SDL_HasGCKeyboard(void)
|
|
|
+{
|
|
|
+ return SDL_FALSE;
|
|
|
+}
|
|
|
+
|
|
|
+void SDL_QuitGCKeyboard(void)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+#endif /* ENABLE_GCKEYBOARD */
|
|
|
+
|
|
|
+
|
|
|
+#ifdef ENABLE_GCMOUSE
|
|
|
+
|
|
|
+static int mice_connected = 0;
|
|
|
+static id mouse_connect_observer = nil;
|
|
|
+static id mouse_disconnect_observer = nil;
|
|
|
+
|
|
|
+static int SetGCMouseRelativeMode(SDL_bool enabled)
|
|
|
+{
|
|
|
+ /* We'll always send relative motion and we can't warp, so nothing to do here */
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static void OnGCMouseButtonChanged(SDL_MouseID mouseID, Uint8 button, BOOL pressed)
|
|
|
+{
|
|
|
+ SDL_SendMouseButton(SDL_GetMouseFocus(), mouseID, pressed ? SDL_PRESSED : SDL_RELEASED, button);
|
|
|
+}
|
|
|
+
|
|
|
+static void OnGCMouseConnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
|
|
|
+{
|
|
|
+ SDL_MouseID mouseID = mice_connected;
|
|
|
+
|
|
|
+ mouse.mouseInput.leftButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed)
|
|
|
+ {
|
|
|
+ OnGCMouseButtonChanged(mouseID, SDL_BUTTON_LEFT, pressed);
|
|
|
+ };
|
|
|
+ mouse.mouseInput.middleButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed)
|
|
|
+ {
|
|
|
+ OnGCMouseButtonChanged(mouseID, SDL_BUTTON_MIDDLE, pressed);
|
|
|
+ };
|
|
|
+ mouse.mouseInput.rightButton.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed)
|
|
|
+ {
|
|
|
+ OnGCMouseButtonChanged(mouseID, SDL_BUTTON_RIGHT, pressed);
|
|
|
+ };
|
|
|
+
|
|
|
+ int auxiliary_button = SDL_BUTTON_X1;
|
|
|
+ for (GCControllerButtonInput *button in mouse.mouseInput.auxiliaryButtons) {
|
|
|
+ button.pressedChangedHandler = ^(GCControllerButtonInput *button, float value, BOOL pressed)
|
|
|
+ {
|
|
|
+ OnGCMouseButtonChanged(mouseID, auxiliary_button, pressed);
|
|
|
+ };
|
|
|
+ ++auxiliary_button;
|
|
|
+ }
|
|
|
+
|
|
|
+ mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput *mouse, float deltaX, float deltaY)
|
|
|
+ {
|
|
|
+ SDL_SendMouseMotion(SDL_GetMouseFocus(), mouseID, SDL_TRUE, (int)deltaX, -(int)deltaY);
|
|
|
+ };
|
|
|
+
|
|
|
+ ++mice_connected;
|
|
|
+}
|
|
|
+
|
|
|
+static void OnGCMouseDisconnected(GCMouse *mouse) API_AVAILABLE(macos(11.0), ios(14.0), tvos(14.0))
|
|
|
+{
|
|
|
+ --mice_connected;
|
|
|
+
|
|
|
+ mouse.mouseInput.mouseMovedHandler = nil;
|
|
|
+
|
|
|
+ mouse.mouseInput.leftButton.pressedChangedHandler = nil;
|
|
|
+ mouse.mouseInput.middleButton.pressedChangedHandler = nil;
|
|
|
+ mouse.mouseInput.rightButton.pressedChangedHandler = nil;
|
|
|
+
|
|
|
+ for (GCControllerButtonInput *button in mouse.mouseInput.auxiliaryButtons) {
|
|
|
+ button.pressedChangedHandler = nil;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+void SDL_InitGCMouse(void)
|
|
|
+{
|
|
|
+ @autoreleasepool {
|
|
|
+ /* There is a bug where mouse accumulates duplicate deltas over time in iOS 14.0 */
|
|
|
+ if (@available(iOS 14.1, tvOS 14.1, *)) {
|
|
|
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
|
|
+
|
|
|
+ mouse_connect_observer = [center addObserverForName:GCMouseDidConnectNotification
|
|
|
+ object:nil
|
|
|
+ queue:nil
|
|
|
+ usingBlock:^(NSNotification *note) {
|
|
|
+ GCMouse *mouse = note.object;
|
|
|
+ OnGCMouseConnected(mouse);
|
|
|
+ }];
|
|
|
+
|
|
|
+ mouse_disconnect_observer = [center addObserverForName:GCMouseDidDisconnectNotification
|
|
|
+ object:nil
|
|
|
+ queue:nil
|
|
|
+ usingBlock:^(NSNotification *note) {
|
|
|
+ GCMouse *mouse = note.object;
|
|
|
+ OnGCMouseDisconnected(mouse);
|
|
|
+ }];
|
|
|
+
|
|
|
+ for (GCMouse *mouse in [GCMouse mice]) {
|
|
|
+ OnGCMouseConnected(mouse);
|
|
|
+ }
|
|
|
+
|
|
|
+ SDL_GetMouse()->SetRelativeMouseMode = SetGCMouseRelativeMode;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+SDL_bool SDL_HasGCMouse(void)
|
|
|
+{
|
|
|
+ return (mice_connected > 0);
|
|
|
+}
|
|
|
+
|
|
|
+void SDL_QuitGCMouse(void)
|
|
|
+{
|
|
|
+ @autoreleasepool {
|
|
|
+ if (@available(iOS 14.0, tvOS 14.0, *)) {
|
|
|
+ NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
|
|
|
+
|
|
|
+ if (mouse_connect_observer) {
|
|
|
+ [center removeObserver:mouse_connect_observer name:GCMouseDidConnectNotification object:nil];
|
|
|
+ mouse_connect_observer = nil;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (mouse_disconnect_observer) {
|
|
|
+ [center removeObserver:mouse_disconnect_observer name:GCMouseDidDisconnectNotification object:nil];
|
|
|
+ mouse_disconnect_observer = nil;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (GCMouse *mouse in [GCMouse mice]) {
|
|
|
+ OnGCMouseDisconnected(mouse);
|
|
|
+ }
|
|
|
+
|
|
|
+ SDL_GetMouse()->SetRelativeMouseMode = NULL;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+#else
|
|
|
+
|
|
|
+void SDL_InitGCMouse(void)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+SDL_bool SDL_HasGCMouse(void)
|
|
|
+{
|
|
|
+ return SDL_FALSE;
|
|
|
+}
|
|
|
+
|
|
|
+void SDL_QuitGCMouse(void)
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+#endif /* ENABLE_GCMOUSE */
|
|
|
+
|
|
|
#endif /* SDL_VIDEO_DRIVER_UIKIT */
|
|
|
|
|
|
/* vi: set ts=4 sw=4 expandtab: */
|