Added support for new mouse APIs in iOS 13.4

This commit is contained in:
Sam Lantinga 2020-04-13 15:46:12 -07:00
parent e96b05c395
commit e5d3629931
3 changed files with 134 additions and 63 deletions

View File

@ -24,5 +24,7 @@
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict> </dict>
</plist> </plist>

View File

@ -25,12 +25,20 @@
#include "SDL_touch.h" #include "SDL_touch.h"
#ifdef __IPHONE_13_4
@interface SDL_uikitview : UIView <UIPointerInteractionDelegate>
#else
@interface SDL_uikitview : UIView @interface SDL_uikitview : UIView
#endif
- (instancetype)initWithFrame:(CGRect)frame; - (instancetype)initWithFrame:(CGRect)frame;
- (void)setSDLWindow:(SDL_Window *)window; - (void)setSDLWindow:(SDL_Window *)window;
#ifdef __IPHONE_13_4
- (UIPointerRegion *)pointerInteraction:(UIPointerInteraction *)interaction regionForRequest:(UIPointerRegionRequest *)request defaultRegion:(UIPointerRegion *)defaultRegion API_AVAILABLE(ios(13.4));
#endif
- (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize; - (CGPoint)touchLocation:(UITouch *)touch shouldNormalize:(BOOL)normalize;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event; - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

View File

@ -75,6 +75,12 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
self.multipleTouchEnabled = YES; self.multipleTouchEnabled = YES;
SDL_AddTouch(directTouchId, SDL_TOUCH_DEVICE_DIRECT, ""); SDL_AddTouch(directTouchId, SDL_TOUCH_DEVICE_DIRECT, "");
#endif #endif
#ifdef __IPHONE_13_4
if (@available(iOS 13.4, *)) {
[self addInteraction:[[UIPointerInteraction alloc] initWithDelegate:self]];
}
#endif
} }
return self; return self;
@ -136,6 +142,21 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
sdlwindow = window; sdlwindow = window;
} }
#ifdef __IPHONE_13_4
- (UIPointerRegion *)pointerInteraction:(UIPointerInteraction *)interaction regionForRequest:(UIPointerRegionRequest *)request defaultRegion:(UIPointerRegion *)defaultRegion API_AVAILABLE(ios(13.4)){
if (request != nil) {
CGPoint origin = self.bounds.origin;
CGPoint point = request.location;
point.x -= origin.x;
point.y -= origin.y;
SDL_SendMouseMotion(sdlwindow, 0, 0, (int)point.x, (int)point.y);
}
return defaultRegion;
}
#endif /* __IPHONE_13_4 */
- (SDL_TouchDeviceType)touchTypeForTouch:(UITouch *)touch - (SDL_TouchDeviceType)touchTypeForTouch:(UITouch *)touch
{ {
#ifdef __IPHONE_9_0 #ifdef __IPHONE_9_0
@ -187,38 +208,64 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{ {
for (UITouch *touch in touches) { for (UITouch *touch in touches) {
SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; BOOL handled = NO;
SDL_TouchID touchId = [self touchIdForType:touchType];
float pressure = [self pressureForTouch:touch];
if (SDL_AddTouch(touchId, touchType, "") < 0) { #ifdef __IPHONE_13_4
continue; if (@available(iOS 13.4, *)) {
if (touch.type == UITouchTypeIndirectPointer) {
/* FIXME: How can we tell the difference between left and right button clicks? */
SDL_SendMouseButton(sdlwindow, 0, SDL_PRESSED, SDL_BUTTON_LEFT);
handled = YES;
}
} }
#endif
if (!handled) {
SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch];
SDL_TouchID touchId = [self touchIdForType:touchType];
float pressure = [self pressureForTouch:touch];
/* FIXME, need to send: int clicks = (int) touch.tapCount; ? */ if (SDL_AddTouch(touchId, touchType, "") < 0) {
continue;
}
CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; /* FIXME, need to send: int clicks = (int) touch.tapCount; ? */
SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch), sdlwindow,
SDL_TRUE, locationInView.x, locationInView.y, pressure); CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch), sdlwindow,
SDL_TRUE, locationInView.x, locationInView.y, pressure);
}
} }
} }
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{ {
for (UITouch *touch in touches) { for (UITouch *touch in touches) {
SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; BOOL handled = NO;
SDL_TouchID touchId = [self touchIdForType:touchType];
float pressure = [self pressureForTouch:touch];
if (SDL_AddTouch(touchId, touchType, "") < 0) { #ifdef __IPHONE_13_4
continue; if (@available(iOS 13.4, *)) {
if (touch.type == UITouchTypeIndirectPointer) {
/* FIXME: How can we tell the difference between left and right button clicks? */
SDL_SendMouseButton(sdlwindow, 0, SDL_RELEASED, SDL_BUTTON_LEFT);
handled = YES;
}
} }
#endif
if (!handled) {
SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch];
SDL_TouchID touchId = [self touchIdForType:touchType];
float pressure = [self pressureForTouch:touch];
/* FIXME, need to send: int clicks = (int) touch.tapCount; ? */ if (SDL_AddTouch(touchId, touchType, "") < 0) {
continue;
}
CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; /* FIXME, need to send: int clicks = (int) touch.tapCount; ? */
SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch), sdlwindow,
SDL_FALSE, locationInView.x, locationInView.y, pressure); CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
SDL_SendTouch(touchId, (SDL_FingerID)((size_t)touch), sdlwindow,
SDL_FALSE, locationInView.x, locationInView.y, pressure);
}
} }
} }
@ -230,79 +277,93 @@ extern int SDL_AppleTVRemoteOpenedAsJoystick;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{ {
for (UITouch *touch in touches) { for (UITouch *touch in touches) {
SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch]; BOOL handled = NO;
SDL_TouchID touchId = [self touchIdForType:touchType];
float pressure = [self pressureForTouch:touch];
if (SDL_AddTouch(touchId, touchType, "") < 0) { #ifdef __IPHONE_13_4
continue; if (@available(iOS 13.4, *)) {
if (touch.type == UITouchTypeIndirectPointer) {
/* Already handled in pointerInteraction callback */
handled = YES;
}
} }
#endif
if (!handled) {
SDL_TouchDeviceType touchType = [self touchTypeForTouch:touch];
SDL_TouchID touchId = [self touchIdForType:touchType];
float pressure = [self pressureForTouch:touch];
CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES]; if (SDL_AddTouch(touchId, touchType, "") < 0) {
SDL_SendTouchMotion(touchId, (SDL_FingerID)((size_t)touch), sdlwindow, continue;
locationInView.x, locationInView.y, pressure); }
CGPoint locationInView = [self touchLocation:touch shouldNormalize:YES];
SDL_SendTouchMotion(touchId, (SDL_FingerID)((size_t)touch), sdlwindow,
locationInView.x, locationInView.y, pressure);
}
} }
} }
#if TARGET_OS_TV || defined(__IPHONE_9_1) #if TARGET_OS_TV || defined(__IPHONE_9_1)
- (SDL_Scancode)scancodeFromPress:(UIPress*)press - (SDL_Scancode)scancodeFromPress:(UIPress*)press
{ {
#ifdef __IPHONE_13_4
if (press.key != nil) { if (press.key != nil) {
return (SDL_Scancode)press.key.keyCode; return (SDL_Scancode)press.key.keyCode;
} }
#endif
/* Presses from Apple TV remote */ /* Presses from Apple TV remote */
if (!SDL_AppleTVRemoteOpenedAsJoystick) { if (!SDL_AppleTVRemoteOpenedAsJoystick) {
switch (press.type) { switch (press.type) {
case UIPressTypeUpArrow: case UIPressTypeUpArrow:
return SDL_SCANCODE_UP; return SDL_SCANCODE_UP;
case UIPressTypeDownArrow: case UIPressTypeDownArrow:
return SDL_SCANCODE_DOWN; return SDL_SCANCODE_DOWN;
case UIPressTypeLeftArrow: case UIPressTypeLeftArrow:
return SDL_SCANCODE_LEFT; return SDL_SCANCODE_LEFT;
case UIPressTypeRightArrow: case UIPressTypeRightArrow:
return SDL_SCANCODE_RIGHT; return SDL_SCANCODE_RIGHT;
case UIPressTypeSelect: case UIPressTypeSelect:
/* HIG says: "primary button behavior" */ /* HIG says: "primary button behavior" */
return SDL_SCANCODE_RETURN; return SDL_SCANCODE_RETURN;
case UIPressTypeMenu: case UIPressTypeMenu:
/* HIG says: "returns to previous screen" */ /* HIG says: "returns to previous screen" */
return SDL_SCANCODE_ESCAPE; return SDL_SCANCODE_ESCAPE;
case UIPressTypePlayPause: case UIPressTypePlayPause:
/* HIG says: "secondary button behavior" */ /* HIG says: "secondary button behavior" */
return SDL_SCANCODE_PAUSE; return SDL_SCANCODE_PAUSE;
default: default:
break; break;
} }
} }
return SDL_SCANCODE_UNKNOWN; return SDL_SCANCODE_UNKNOWN;
} }
- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event - (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
{ {
for (UIPress *press in presses) { for (UIPress *press in presses) {
SDL_Scancode scancode = [self scancodeFromPress:press]; SDL_Scancode scancode = [self scancodeFromPress:press];
SDL_SendKeyboardKey(SDL_PRESSED, scancode); SDL_SendKeyboardKey(SDL_PRESSED, scancode);
} }
[super pressesBegan:presses withEvent:event]; [super pressesBegan:presses withEvent:event];
} }
- (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event - (void)pressesEnded:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
{ {
for (UIPress *press in presses) { for (UIPress *press in presses) {
SDL_Scancode scancode = [self scancodeFromPress:press]; SDL_Scancode scancode = [self scancodeFromPress:press];
SDL_SendKeyboardKey(SDL_RELEASED, scancode); SDL_SendKeyboardKey(SDL_RELEASED, scancode);
} }
[super pressesEnded:presses withEvent:event]; [super pressesEnded:presses withEvent:event];
} }
- (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event - (void)pressesCancelled:(NSSet<UIPress *> *)presses withEvent:(UIPressesEvent *)event
{ {
for (UIPress *press in presses) { for (UIPress *press in presses) {
SDL_Scancode scancode = [self scancodeFromPress:press]; SDL_Scancode scancode = [self scancodeFromPress:press];
SDL_SendKeyboardKey(SDL_RELEASED, scancode); SDL_SendKeyboardKey(SDL_RELEASED, scancode);
} }
[super pressesCancelled:presses withEvent:event]; [super pressesCancelled:presses withEvent:event];
} }