diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java b/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java index 8613a50b..74758024 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/Tools.java @@ -177,8 +177,6 @@ public final class Tools if (versionInfo.inheritsFrom != null) { versionName = versionInfo.inheritsFrom; } - - String userType = "mojang"; File gameDir = new File(Tools.DIR_GAME_NEW); gameDir.mkdirs(); @@ -194,7 +192,7 @@ public final class Tools varArgMap.put("game_assets", Tools.ASSETS_PATH); varArgMap.put("game_directory", gameDir.getAbsolutePath()); varArgMap.put("user_properties", "{}"); - varArgMap.put("user_type", userType); + varArgMap.put("user_type", /* profile.isMicrosoft ? "msa" : */ "mojang"); // FIXME: handle MS auth varArgMap.put("version_name", versionName); varArgMap.put("version_type", versionInfo.type); diff --git a/JavaApp/src/main/java/net/kdt/pojavlaunch/uikit/UIKit.java b/JavaApp/src/main/java/net/kdt/pojavlaunch/uikit/UIKit.java index ed36a7c3..c26e3ba9 100644 --- a/JavaApp/src/main/java/net/kdt/pojavlaunch/uikit/UIKit.java +++ b/JavaApp/src/main/java/net/kdt/pojavlaunch/uikit/UIKit.java @@ -12,7 +12,8 @@ public class UIKit { public static final int ACTION_DOWN = 0; public static final int ACTION_UP = 1; public static final int ACTION_MOVE = 2; - + public static final int ACTION_MOVE_MOTION = 3; + private static int guiScale; private static void patch_FlatLAF_setLinux() { @@ -123,6 +124,10 @@ public class UIKit { CallbackBridge.mouseY = y; } break; + + case ACTION_MOVE_MOTION: + CallbackBridge.mouseX += x; + CallbackBridge.mouseY += y; } CallbackBridge.mouseLastX = x; CallbackBridge.mouseLastY = y; diff --git a/Natives/CMakeLists.txt b/Natives/CMakeLists.txt index e6c0acd6..9dc11449 100644 --- a/Natives/CMakeLists.txt +++ b/Natives/CMakeLists.txt @@ -50,6 +50,7 @@ add_executable(PojavLauncher CustomControlsViewController.m FileListViewController.m JavaGUIViewController.m + KeyboardInput.m LauncherFAQViewController.m LauncherPreferences.m LauncherPreferencesViewController.m @@ -73,6 +74,7 @@ target_link_libraries(PojavLauncher "-F'${CMAKE_CURRENT_LIST_DIR}/build'" "-framework AuthenticationServices" "-framework CoreGraphics" + "-framework GameController" "-framework QuartzCore" "-framework UIKit" "-framework SafariServices" diff --git a/Natives/CustomControlsViewController.m b/Natives/CustomControlsViewController.m index ffc767cd..e19b309c 100644 --- a/Natives/CustomControlsViewController.m +++ b/Natives/CustomControlsViewController.m @@ -14,10 +14,6 @@ BOOL shouldDismissPopover = YES; int width; NSMutableArray *keyCodeMap, *keyValueMap; -CGFloat clamp(CGFloat x, CGFloat lower, CGFloat upper) { - return fmin(upper, fmax(x, lower)); -} - @interface ControlLayout () @end @implementation ControlLayout diff --git a/Natives/JavaLauncher.m b/Natives/JavaLauncher.m index 50022889..e8a590ad 100644 --- a/Natives/JavaLauncher.m +++ b/Natives/JavaLauncher.m @@ -194,14 +194,17 @@ void init_loadCustomEnv() { void init_loadCustomJvmFlags() { NSString *jvmargs = getPreference(@"java_args"); BOOL isFirstArg = YES; - for (NSString *jvmarg in [jvmargs componentsSeparatedByString:@" -"]) { + for (NSString *jvmarg in [jvmargs componentsSeparatedByString:@" "]) { if ([jvmarg length] == 0) continue; + margv[margc] = (char *) [jvmarg UTF8String]; +/* if (isFirstArg) { isFirstArg = NO; margv[margc] = (char *) [jvmarg UTF8String]; } else { margv[margc] = (char *) [[@"-" stringByAppendingString:jvmarg] UTF8String]; } +*/ NSLog(@"[Pre-init] Added custom JVM flag: %s", margv[margc]); ++margc; } @@ -284,8 +287,7 @@ void environmentFailsafes(char *argv[]) { javaHome = [javaHome_pre cStringUsingEncoding:NSUTF8StringEncoding]; setPreference(@"java_home", javaHome_pre); } else { - javaHome = calloc(1, 2048); - sprintf((char *)javaHome, "%s/jre", homeDir); + asprintf((char **)&javaHome, "%s/jre", homeDir); } } @@ -507,8 +509,8 @@ int launchJVM(int argc, char *argv[]) { allocmem_pre = [getPreference(@"allocated_memory") stringValue]; allocmem = [allocmem_pre cStringUsingEncoding:NSUTF8StringEncoding]; - char *controlPath = calloc(1, 2048); - sprintf(controlPath, "%s/controlmap", homeDir); + char *controlPath; + asprintf(&controlPath, "%s/controlmap", homeDir); mkdir(controlPath, S_IRWXU | S_IRWXG | S_IRWXO); setenv("POJAV_PATH_CONTROL", controlPath, 1); free(controlPath); @@ -543,10 +545,9 @@ int launchJVM(int argc, char *argv[]) { multidir = [multidir_pre cStringUsingEncoding:NSUTF8StringEncoding]; debug("[Pre-init] Restored preference: MULTI_DIR is set to %s\n", multidir); } - char *multidir_char = calloc(1, 2048); - char *librarySym = calloc(1, 2048); - snprintf(multidir_char, 2048, "%s/instances/%s", getenv("POJAV_HOME"), multidir); - snprintf(librarySym, 2048, "%s/Library/Application Support/minecraft", getenv("POJAV_HOME")); + char *multidir_char, *librarySym; + asprintf(&multidir_char, "%s/instances/%s", getenv("POJAV_HOME"), multidir); + asprintf(&librarySym, "%s/Library/Application Support/minecraft", getenv("POJAV_HOME")); remove(librarySym); if (0 != access(multidir_char, F_OK)) { mkdir(multidir_char, 755); @@ -564,20 +565,14 @@ int launchJVM(int argc, char *argv[]) { } // Check if JVM restarts if (!started) { - char *frameworkPath = calloc(1, 2048); - char *javaPath = calloc(1, 2048); - char *jnaLibPath = calloc(1, 2048); - char *userDir = calloc(1, 2048); - char *userHome = calloc(1, 2048); - char *memMin = calloc(1, 2048); - char *memMax = calloc(1, 2048); - snprintf(frameworkPath, 2048, "-Djava.library.path=%s/Frameworks:%s/Frameworks/libOSMesaOverride.dylib.framework", getenv("BUNDLE_PATH"), getenv("BUNDLE_PATH")); - snprintf(javaPath, 2048, "%s/bin/java", javaHome); - snprintf(jnaLibPath, 2048, "-Djna.boot.library.path=%s/Frameworks/libjnidispatch.dylib.framework", getenv("BUNDLE_PATH")); - snprintf(userDir, 2048, "-Duser.dir=%s", getenv("POJAV_GAME_DIR")); - snprintf(userHome, 2048, "-Duser.home=%s", getenv("POJAV_HOME")); - snprintf(memMin, 2048, "-Xms%sM", allocmem); - snprintf(memMax, 2048, "-Xmx%sM", allocmem); + char *frameworkPath, *javaPath, *jnaLibPath, *userDir, *userHome, *memMin, *memMax; + asprintf(&frameworkPath, "-Djava.library.path=%s/Frameworks:%s/Frameworks/libOSMesaOverride.dylib.framework", getenv("BUNDLE_PATH"), getenv("BUNDLE_PATH")); + asprintf(&javaPath, "%s/bin/java", javaHome); + asprintf(&jnaLibPath, "-Djna.boot.library.path=%s/Frameworks/libjnidispatch.dylib.framework", getenv("BUNDLE_PATH")); + asprintf(&userDir, "-Duser.dir=%s", getenv("POJAV_GAME_DIR")); + asprintf(&userHome, "-Duser.home=%s", getenv("POJAV_HOME")); + asprintf(&memMin, "-Xms%sM", allocmem); + asprintf(&memMax, "-Xmx%sM", allocmem); NSLog(@"[Pre-init] Java executable path: %s", javaPath); setenv("JAVA_EXT_EXECNAME", javaPath, 1); diff --git a/Natives/KeyboardInput.h b/Natives/KeyboardInput.h new file mode 100644 index 00000000..3b3a8709 --- /dev/null +++ b/Natives/KeyboardInput.h @@ -0,0 +1,10 @@ +#import + +NSMutableDictionary* keycodeTable; + +@interface KeyboardInput : NSObject + ++ (void)initKeycodeTable; ++ (BOOL)sendKeyEvent:(UIKey *)key down:(BOOL)isDown API_AVAILABLE(ios(13.4)); + +@end diff --git a/Natives/KeyboardInput.m b/Natives/KeyboardInput.m new file mode 100644 index 00000000..24d26fd7 --- /dev/null +++ b/Natives/KeyboardInput.m @@ -0,0 +1,153 @@ +#import "KeyboardInput.h" +#import "utils.h" + +#include "glfw_keycodes.h" + +@implementation KeyboardInput + ++ (void)initKeycodeTable { + if (@available(iOS 13.4, *)) { + keycodeTable = [[NSMutableDictionary alloc] init]; + + // A-Z keys + for (int i = UIKeyboardHIDUsageKeyboardA; i <= UIKeyboardHIDUsageKeyboardZ; i++) { + keycodeTable[@(i)] = @(i - UIKeyboardHIDUsageKeyboardA + GLFW_KEY_A); + } + + // 0-9 keys + keycodeTable[@(UIKeyboardHIDUsageKeyboard0)] = @(GLFW_KEY_0); + for (int i = UIKeyboardHIDUsageKeyboard1; i <= UIKeyboardHIDUsageKeyboard9; i++) { + keycodeTable[@(i)] = @(i - UIKeyboardHIDUsageKeyboard1 + GLFW_KEY_1); + } + + // Arrow keys + keycodeTable[@(UIKeyboardHIDUsageKeyboardUpArrow)] = @(GLFW_KEY_DPAD_UP); + keycodeTable[@(UIKeyboardHIDUsageKeyboardDownArrow)] = @(GLFW_KEY_DPAD_DOWN); + keycodeTable[@(UIKeyboardHIDUsageKeyboardLeftArrow)] = @(GLFW_KEY_DPAD_LEFT); + keycodeTable[@(UIKeyboardHIDUsageKeyboardRightArrow)] = @(GLFW_KEY_DPAD_RIGHT); + + keycodeTable[@(UIKeyboardHIDUsageKeyboardComma)] = @(GLFW_KEY_COMMA); + keycodeTable[@(UIKeyboardHIDUsageKeyboardPeriod)] = @(GLFW_KEY_PERIOD); + + // Alt keys + keycodeTable[@(UIKeyboardHIDUsageKeyboardLeftAlt)] = @(GLFW_KEY_LEFT_ALT); + keycodeTable[@(UIKeyboardHIDUsageKeyboardRightAlt)] = @(GLFW_KEY_RIGHT_ALT); + + // Control keys + keycodeTable[@(UIKeyboardHIDUsageKeyboardLeftControl)] = @(GLFW_KEY_LEFT_CONTROL); + keycodeTable[@(UIKeyboardHIDUsageKeyboardRightControl)] = @(GLFW_KEY_RIGHT_CONTROL); + + // Shift keys + keycodeTable[@(UIKeyboardHIDUsageKeyboardLeftShift)] = @(GLFW_KEY_LEFT_SHIFT); + keycodeTable[@(UIKeyboardHIDUsageKeyboardRightShift)] = @(GLFW_KEY_RIGHT_SHIFT); + + // Bracket keys + keycodeTable[@(UIKeyboardHIDUsageKeyboardOpenBracket)] = @(GLFW_KEY_LEFT_BRACKET); + keycodeTable[@(UIKeyboardHIDUsageKeyboardCloseBracket)] = @(GLFW_KEY_RIGHT_BRACKET); + + // Slash keys + keycodeTable[@(UIKeyboardHIDUsageKeyboardSlash)] = @(GLFW_KEY_SLASH); + keycodeTable[@(UIKeyboardHIDUsageKeyboardBackslash)] = @(GLFW_KEY_BACKSLASH); + + // Page keys + keycodeTable[@(UIKeyboardHIDUsageKeyboardPageUp)] = @(GLFW_KEY_PAGE_UP); + keycodeTable[@(UIKeyboardHIDUsageKeyboardPageDown)] = @(GLFW_KEY_PAGE_DOWN); + + // Some other keys + keycodeTable[@(UIKeyboardHIDUsageKeyboardHome)] = @(GLFW_KEY_HOME); + keycodeTable[@(UIKeyboardHIDUsageKeyboardEscape)] = @(GLFW_KEY_ESCAPE); + keycodeTable[@(UIKeyboardHIDUsageKeyboardTab)] = @(GLFW_KEY_TAB); + keycodeTable[@(UIKeyboardHIDUsageKeyboardReturnOrEnter)] = @(GLFW_KEY_ENTER); + keycodeTable[@(UIKeyboardHIDUsageKeyboardSpacebar)] = @(GLFW_KEY_SPACE); + keycodeTable[@(UIKeyboardHIDUsageKeyboardDeleteOrBackspace)] = @(GLFW_KEY_BACKSPACE); + keycodeTable[@(UIKeyboardHIDUsageKeyboardDeleteForward)] = @(GLFW_KEY_DELETE); + keycodeTable[@(UIKeyboardHIDUsageKeyboardGraveAccentAndTilde)] = @(GLFW_KEY_GRAVE_ACCENT); + + keycodeTable[@(UIKeyboardHIDUsageKeyboardHyphen)] = @(GLFW_KEY_MINUS); + keycodeTable[@(UIKeyboardHIDUsageKeyboardEqualSign)] = @(GLFW_KEY_EQUAL); + keycodeTable[@(UIKeyboardHIDUsageKeyboardSemicolon)] = @(GLFW_KEY_SEMICOLON); + + // Lock keys + keycodeTable[@(UIKeyboardHIDUsageKeyboardCapsLock)] = @(GLFW_KEY_CAPS_LOCK); + keycodeTable[@(UIKeyboardHIDUsageKeypadNumLock)] = @(GLFW_KEY_NUM_LOCK); + keycodeTable[@(UIKeyboardHIDUsageKeyboardScrollLock)] = @(GLFW_KEY_SCROLL_LOCK); + + // Numpad keys + keycodeTable[@(UIKeyboardHIDUsageKeypadSlash)] = @(GLFW_KEY_NUMPAD_DIVIDE); + keycodeTable[@(UIKeyboardHIDUsageKeypadAsterisk)] = @(GLFW_KEY_NUMPAD_MULTIPLY); + keycodeTable[@(UIKeyboardHIDUsageKeypadHyphen)] = @(GLFW_KEY_NUMPAD_SUBTRACT); + keycodeTable[@(UIKeyboardHIDUsageKeypadPlus)] = @(GLFW_KEY_NUMPAD_ADD); + keycodeTable[@(UIKeyboardHIDUsageKeypadEnter)] = @(GLFW_KEY_NUMPAD_ENTER); + keycodeTable[@(UIKeyboardHIDUsageKeypadEqualSign)] = @(GLFW_KEY_NUMPAD_EQUAL); + keycodeTable[@(UIKeyboardHIDUsageKeypad0)] = @(GLFW_KEY_NUMPAD_0); + for (int i = UIKeyboardHIDUsageKeypad1; i <= UIKeyboardHIDUsageKeypad9; i++) { + keycodeTable[@(i)] = @(i - UIKeyboardHIDUsageKeypad1 + GLFW_KEY_NUMPAD_1); + } + + // Function keys + for (int i = UIKeyboardHIDUsageKeyboardF1; i <= UIKeyboardHIDUsageKeyboardF12; i++) { + keycodeTable[@(i)] = @(i - UIKeyboardHIDUsageKeyboardF1 + GLFW_KEY_F1); + } + + // Lock keys + keycodeTable[@(UIKeyboardHIDUsageKeyboardCapsLock)] = @(GLFW_KEY_CAPS_LOCK); + keycodeTable[@(UIKeyboardHIDUsageKeypadNumLock)] = @(GLFW_KEY_NUM_LOCK); + keycodeTable[@(UIKeyboardHIDUsageKeyboardScrollLock)] = @(GLFW_KEY_SCROLL_LOCK); + + // Numpad keys + keycodeTable[@(UIKeyboardHIDUsageKeypadSlash)] = @(GLFW_KEY_NUMPAD_DIVIDE); + keycodeTable[@(UIKeyboardHIDUsageKeypadAsterisk)] = @(GLFW_KEY_NUMPAD_MULTIPLY); + keycodeTable[@(UIKeyboardHIDUsageKeypadHyphen)] = @(GLFW_KEY_NUMPAD_SUBTRACT); + keycodeTable[@(UIKeyboardHIDUsageKeypadPlus)] = @(GLFW_KEY_NUMPAD_ADD); + keycodeTable[@(UIKeyboardHIDUsageKeypadEnter)] = @(GLFW_KEY_NUMPAD_ENTER); + keycodeTable[@(UIKeyboardHIDUsageKeypadEqualSign)] = @(GLFW_KEY_NUMPAD_EQUAL); + keycodeTable[@(UIKeyboardHIDUsageKeypad0)] = @(GLFW_KEY_NUMPAD_0); + for (int i = UIKeyboardHIDUsageKeypad1; i <= UIKeyboardHIDUsageKeypad9; i++) { + keycodeTable[@(i)] = @(i - UIKeyboardHIDUsageKeypad1 + GLFW_KEY_NUMPAD_1); + } + + // Function keys + for (int i = UIKeyboardHIDUsageKeyboardF1; i <= UIKeyboardHIDUsageKeyboardF12; i++) { + keycodeTable[@(i)] = @(i - UIKeyboardHIDUsageKeyboardF1 + GLFW_KEY_F1); + } + } +} + ++ (BOOL)sendKeyEvent:(UIKey *)key down:(BOOL)isDown API_AVAILABLE(ios(13.4)) { + char modifiers = 0; + + // convert UIKey's modifiers to GLFW + if (key.modifierFlags & UIKeyModifierAlphaShift) { + modifiers |= GLFW_MOD_CAPS_LOCK; + } + if (key.modifierFlags & UIKeyModifierShift) { + modifiers |= GLFW_MOD_SHIFT; + } + if (key.modifierFlags & UIKeyModifierAlternate) { + modifiers |= GLFW_MOD_ALT; + } + if (key.modifierFlags & UIKeyModifierControl) { + modifiers |= GLFW_MOD_CONTROL; + } + + // send the keycode + int keycode = [keycodeTable[@(key.keyCode)] intValue]; + if (keycode != 0) { + CallbackBridge_nativeSendKey(keycode, 0 /* scancode */, isDown, modifiers); + } else { + NSLog(@"KeyboardInput: Unhandled key %lu", (unsigned long)key.keyCode); + } + + // key.characters.length < 11: skip sending characters if the string starts with UIKeyInput + if (isDown && key.characters.length < 11) { + for (int i = 0; i < key.characters.length; i++) { + int keychar = [key.characters characterAtIndex:i]; + CallbackBridge_nativeSendCharMods(keychar, modifiers); + CallbackBridge_nativeSendChar(keychar); + } + } + + return keycode != 0 || isDown; +} + +@end diff --git a/Natives/SurfaceViewController.m b/Natives/SurfaceViewController.m index a18a883f..5926cb85 100644 --- a/Natives/SurfaceViewController.m +++ b/Natives/SurfaceViewController.m @@ -1,3 +1,5 @@ +#import + #import "LauncherPreferences.h" #import "SurfaceViewController.h" #import "egl_bridge.h" @@ -8,6 +10,8 @@ #import "customcontrols/ControlSubButton.h" #import "customcontrols/CustomControlsUtils.h" +#import "KeyboardInput.h" + #include "glfw_keycodes.h" #include "utils.h" @@ -77,6 +81,7 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { return CAMetalLayer.class; } } + @end @interface SurfaceViewController () { @@ -87,8 +92,7 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { @property(nonatomic, strong) NSMutableArray* togglableVisibleButtons; @property ControlButton* swipingButton; @property UITouch *primaryTouch, *hotbarTouch; - -- (void)setupGL; +@property id mouseConnectCallback, mouseDisconnectCallback; @end @@ -105,6 +109,8 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { [[UIApplication sharedApplication] setIdleTimerDisabled:YES]; [self setNeedsUpdateOfScreenEdgesDeferringSystemGestures]; [self setNeedsUpdateOfHomeIndicatorAutoHidden]; + [self.navigationItem setHidesBackButton:YES animated:YES]; + [self.navigationController setNavigationBarHidden:YES animated:YES]; CGRect screenBounds = [[UIScreen mainScreen] bounds]; CGFloat screenScale = [[UIScreen mainScreen] scale]; @@ -134,9 +140,10 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { notchOffset = insets.left; width = width - notchOffset * 2; CGFloat buttonScale = [getPreference(@"button_scale") floatValue] / 100.0; - + UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(surfaceOnClick:)]; + tapGesture.allowedTouchTypes = @[@(UITouchTypeDirect)]; tapGesture.delegate = self; tapGesture.numberOfTapsRequired = 1; tapGesture.numberOfTouchesRequired = 1; @@ -145,14 +152,22 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { UITapGestureRecognizer *doubleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(surfaceOnDoubleClick:)]; + doubleTapGesture.allowedTouchTypes = @[@(UITouchTypeDirect)]; doubleTapGesture.delegate = self; doubleTapGesture.numberOfTapsRequired = 2; doubleTapGesture.numberOfTouchesRequired = 1; doubleTapGesture.cancelsTouchesInView = NO; [self.surfaceView addGestureRecognizer:doubleTapGesture]; + if (@available(iOS 13.0, *)) { + UIHoverGestureRecognizer *hoverGesture = [[UIHoverGestureRecognizer alloc] + initWithTarget:self action:@selector(surfaceOnHover:)]; + [self.surfaceView addGestureRecognizer:hoverGesture]; + } + UILongPressGestureRecognizer *longpressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(surfaceOnLongpress:)]; + longpressGesture.allowedTouchTypes = @[@(UITouchTypeDirect)]; longpressGesture.cancelsTouchesInView = NO; longpressGesture.delegate = self; longpressGesture.minimumPressDuration = [getPreference(@"time_longPressTrigger") floatValue] / 1000; @@ -160,22 +175,13 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { self.scrollPanGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(surfaceOnTouchesScroll:)]; - self.scrollPanGesture.delegate = self; self.scrollPanGesture.allowedTouchTypes = @[@(UITouchTypeDirect)]; + self.scrollPanGesture.delegate = self; self.scrollPanGesture.minimumNumberOfTouches = 2; self.scrollPanGesture.maximumNumberOfTouches = 2; if (@available(iOS 13.4, *)) { [self.surfaceView addInteraction:[[UIPointerInteraction alloc] initWithDelegate:self]]; - - UIPanGestureRecognizer *mouseWheelGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(surfaceOnMouseScroll:)]; - mouseWheelGesture.delegate = self; - mouseWheelGesture.allowedScrollTypesMask = UIScrollTypeMaskDiscrete; - mouseWheelGesture.allowedTouchTypes = @[@(UITouchTypeIndirectPointer)]; - mouseWheelGesture.cancelsTouchesInView = NO; - mouseWheelGesture.delaysTouchesBegan = NO; - mouseWheelGesture.delaysTouchesEnded = NO; - [self.surfaceView addGestureRecognizer:mouseWheelGesture]; } // Virtual mouse @@ -253,13 +259,35 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { } } + [KeyboardInput initKeycodeTable]; + if (@available(iOS 14.0, tvOS 14.0, *)) { + self.mouseConnectCallback = [[NSNotificationCenter defaultCenter] addObserverForName:GCMouseDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { + NSLog(@"Input: Mouse connected!"); + GCMouse* mouse = note.object; + [self registerMouseCallbacks: mouse]; + [self setNeedsUpdateOfPrefersPointerLocked]; + }]; + self.mouseDisconnectCallback = [[NSNotificationCenter defaultCenter] addObserverForName:GCMouseDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { + NSLog(@"Input: Mouse disconnected!"); + GCMouse* mouse = note.object; + mouse.mouseInput.mouseMovedHandler = nil; + mouse.mouseInput.leftButton.pressedChangedHandler = nil; + mouse.mouseInput.middleButton.pressedChangedHandler = nil; + mouse.mouseInput.rightButton.pressedChangedHandler = nil; + [self setNeedsUpdateOfPrefersPointerLocked]; + }]; + if (GCMouse.current != nil) { + [self registerMouseCallbacks: GCMouse.current]; + } + } + [self.view addSubview:inputView]; [self executebtn_special_togglebtn:0]; // [self setPreferredFramesPerSecond:1000]; - [self setupGL]; + callback_SurfaceViewController_launchMinecraft(savedWidth * resolutionScale, savedHeight * resolutionScale); } - (UIRectEdge)preferredScreenEdgesDeferringSystemGestures { @@ -270,10 +298,6 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { return NO; } -- (void)setupGL { - callback_SurfaceViewController_launchMinecraft(savedWidth * resolutionScale, savedHeight * resolutionScale); -} - #pragma mark - Input: send touch utilities @@ -291,17 +315,13 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { if (event == ACTION_MOVE) { virtualMouseFrame.origin.x += location.x - lastVirtualMousePoint.x; virtualMouseFrame.origin.y += location.y - lastVirtualMousePoint.y; - if (virtualMouseFrame.origin.x < 0) { - virtualMouseFrame.origin.x = 0; - } else if (virtualMouseFrame.origin.x > self.view.frame.size.width) { - virtualMouseFrame.origin.x = self.view.frame.size.width; - } - if (virtualMouseFrame.origin.y < 0) { - virtualMouseFrame.origin.y = 0; - } else if (virtualMouseFrame.origin.y > self.view.frame.size.height) { - virtualMouseFrame.origin.y = self.view.frame.size.height; - } + } else if (event == ACTION_MOVE_MOTION) { + event = ACTION_MOVE; + virtualMouseFrame.origin.x += location.x; + virtualMouseFrame.origin.y += location.y; } + virtualMouseFrame.origin.x = clamp(virtualMouseFrame.origin.x, 0, self.view.frame.size.width); + virtualMouseFrame.origin.y = clamp(virtualMouseFrame.origin.y, 0, self.view.frame.size.height); lastVirtualMousePoint = location; self.mousePointerView.frame = virtualMouseFrame; callback_SurfaceViewController_onTouch(event, virtualMouseFrame.origin.x * screenScale, virtualMouseFrame.origin.y * screenScale); @@ -312,6 +332,8 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { callback_SurfaceViewController_onTouch(event, location.x * screenScale, location.y * screenScale); } +#pragma mark - Input: on-surface functions + - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { return YES; } @@ -320,22 +342,15 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { { CGPoint locationInView = [touchEvent locationInView:self.view]; - BOOL isTouchTypeIndirect = NO; - if (@available(iOS 13.4, *)) { - if (touchEvent.type == UITouchTypeIndirectPointer) { - isTouchTypeIndirect = YES; - } - } - if (touchEvent.view == self.surfaceView) { - if (touchEvent == self.hotbarTouch && slideableHotbar && !isTouchTypeIndirect && ![self isTouchInactive:self.hotbarTouch]) { + if (touchEvent == self.hotbarTouch && slideableHotbar && ![self isTouchInactive:self.hotbarTouch]) { CGFloat screenScale = [[UIScreen mainScreen] scale]; int slot = callback_SurfaceViewController_touchHotbar(locationInView.x * screenScale, locationInView.y * screenScale); if (slot != -1 && currentHotbarSlot != slot && (event == ACTION_DOWN || currentHotbarSlot != -1)) { currentHotbarSlot = slot; - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(NULL, NULL, slot, 0, 1, 0); - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(NULL, NULL, slot, 0, 0, 0); + CallbackBridge_nativeSendKey(slot, 0, 1, 0); + CallbackBridge_nativeSendKey(slot, 0, 0, 0); return; } /* else if ((event == ACTION_MOVE || event == ACTION_UP) && slot == -1 && currentHotbarSlot != -1) { return; @@ -357,56 +372,89 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { [self sendTouchPoint:locationInView withEvent:event]; } - if (!isTouchTypeIndirect) { - switch (event) { - case ACTION_DOWN: - touchesMovedCount = 0; - shouldTriggerClick = YES; - break; + switch (event) { + case ACTION_DOWN: + touchesMovedCount = 0; + shouldTriggerClick = YES; + break; - case ACTION_MOVE: - // TODO: better handling this - if (touchesMovedCount >= 1) { - shouldTriggerClick = NO; - } else ++touchesMovedCount; - break; - } - } else if (@available(iOS 13.4, *)) { - // Recheck @available for suppressing compile warnings - - // Mouse clicks are handled here - int held = event == ACTION_MOVE || event == ACTION_UP; - shouldTriggerClick = NO; - for (int i = 1; i <= 5; ++i) { - if ((uievent.buttonMask & (1 << ((i)-1))) != 0) { - // iOS button index = GLFW button index + 1; - Java_org_lwjgl_glfw_CallbackBridge_nativeSendMouseButton(NULL, NULL, i - 1, held, 0); - } - } + case ACTION_MOVE: + // TODO: better handling this + if (touchesMovedCount >= 1) { + shouldTriggerClick = NO; + } else ++touchesMovedCount; + break; } } } -#pragma mark - Input: on-surface gestures +- (void)pressesBegan:(NSSet *)presses withEvent:(UIPressesEvent *)event { + BOOL handled = NO; + + if (@available(iOS 13.4, *)) { + for (UIPress *press in presses) { + if (press.key != nil && [KeyboardInput sendKeyEvent:press.key down:YES]) { + handled = YES; + } + } + } + + if (!handled) { + [super pressesBegan:presses withEvent:event]; + } +} + +- (void)pressesEnded:(NSSet *)presses withEvent:(UIPressesEvent *)event { + BOOL handled = NO; + + if (@available(iOS 13.4, *)) { + for (UIPress *press in presses) { + if (press.key != nil && [KeyboardInput sendKeyEvent:press.key down:NO]) { + handled = YES; + } + } + } + + if (!handled) { + [super pressesEnded:presses withEvent:event]; + } +} + +- (void)registerMouseCallbacks:(GCMouse *)mouse API_AVAILABLE(ios(14.0)) { + NSLog(@"Input: Got mouse %@", mouse); + mouse.mouseInput.leftButton.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) { + CallbackBridge_nativeSendMouseButton(GLFW_MOUSE_BUTTON_LEFT, pressed, 0); + }; + mouse.mouseInput.middleButton.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) { + CallbackBridge_nativeSendMouseButton(GLFW_MOUSE_BUTTON_MIDDLE, pressed, 0); + }; + mouse.mouseInput.rightButton.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) { + CallbackBridge_nativeSendMouseButton(GLFW_MOUSE_BUTTON_RIGHT, pressed, 0); + }; + + mouse.mouseInput.scroll.xAxis.valueChangedHandler = ^(GCControllerAxisInput * _Nonnull axis, float value) { + CallbackBridge_nativeSendScroll(value, 0); + }; + mouse.mouseInput.scroll.yAxis.valueChangedHandler = ^(GCControllerAxisInput * _Nonnull axis, float value) { + CallbackBridge_nativeSendScroll(0, value); + }; + +} - (void)surfaceOnClick:(UITapGestureRecognizer *)sender { - if (sender.state == UIGestureRecognizerStateRecognized && - shouldTriggerClick == YES) { - CGFloat screenScale = [[UIScreen mainScreen] scale]; - CGPoint location = [sender locationInView:[sender.view superview]]; - currentHotbarSlot = callback_SurfaceViewController_touchHotbar(location.x * screenScale, location.y * screenScale); - + if (shouldTriggerClick == NO) return; + if (sender.state == UIGestureRecognizerStateRecognized) { if (currentHotbarSlot == -1) { inputView.text = INPUT_SPACE_CHAR; inputTextLength = 0; - Java_org_lwjgl_glfw_CallbackBridge_nativeSendMouseButton(NULL, NULL, + CallbackBridge_nativeSendMouseButton( isGrabbing == JNI_TRUE ? GLFW_MOUSE_BUTTON_RIGHT : GLFW_MOUSE_BUTTON_LEFT, 1, 0); - Java_org_lwjgl_glfw_CallbackBridge_nativeSendMouseButton(NULL, NULL, + CallbackBridge_nativeSendMouseButton( isGrabbing == JNI_TRUE ? GLFW_MOUSE_BUTTON_RIGHT : GLFW_MOUSE_BUTTON_LEFT, 0, 0); } else { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(NULL, NULL, currentHotbarSlot, 0, 1, 0); - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(NULL, NULL, currentHotbarSlot, 0, 0, 0); + CallbackBridge_nativeSendKey(currentHotbarSlot, 0, 1, 0); + CallbackBridge_nativeSendKey(currentHotbarSlot, 0, 0, 0); } } } @@ -417,8 +465,8 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { CGPoint location = [sender locationInView:[sender.view superview]]; int hotbarSlot = callback_SurfaceViewController_touchHotbar(location.x * screenScale * resolutionScale, location.y * screenScale * resolutionScale); if (hotbarSlot != -1 && currentHotbarSlot == hotbarSlot) { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(NULL, NULL, GLFW_KEY_F, 0, 1, 0); - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(NULL, NULL, GLFW_KEY_F, 0, 0, 0); + CallbackBridge_nativeSendKey(GLFW_KEY_F, 0, 1, 0); + CallbackBridge_nativeSendKey(GLFW_KEY_F, 0, 0, 0); } } } @@ -427,7 +475,7 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { if (@available(iOS 13.0, *)) { CGPoint point = [sender locationInView:self.surfaceView]; // NSLog(@"Mouse move!!"); - // NSLog(@"Mouse pos = %d, %d", point.x, point.y); + // NSLog(@"Mouse pos = %f, %f", point.x, point.y); switch (sender.state) { case UIGestureRecognizerStateBegan: [self sendTouchPoint:point withEvent:ACTION_DOWN]; @@ -458,9 +506,9 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { inputView.text = INPUT_SPACE_CHAR; inputTextLength = 0; - Java_org_lwjgl_glfw_CallbackBridge_nativeSendMouseButton(NULL, NULL, GLFW_MOUSE_BUTTON_LEFT, 1, 0); + CallbackBridge_nativeSendMouseButton(GLFW_MOUSE_BUTTON_LEFT, 1, 0); } else { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(NULL, NULL, GLFW_KEY_Q, 0, 1, 0); + CallbackBridge_nativeSendKey(GLFW_KEY_Q, 0, 1, 0); } } else if (sender.state == UIGestureRecognizerStateChanged) { // Nothing to do here, already handled in touchesMoved @@ -473,37 +521,15 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { inputView.text = INPUT_SPACE_CHAR; inputTextLength = 0; - Java_org_lwjgl_glfw_CallbackBridge_nativeSendMouseButton(NULL, NULL, GLFW_MOUSE_BUTTON_LEFT, 0, 0); + CallbackBridge_nativeSendMouseButton(GLFW_MOUSE_BUTTON_LEFT, 0, 0); } else { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(NULL, NULL, GLFW_KEY_Q, 0, 0, 0); + +CallbackBridge_nativeSendKey(GLFW_KEY_Q, 0, 0, 0); } } } } --(void)surfaceOnMouseScroll:(UIPanGestureRecognizer *)sender API_AVAILABLE(ios(13.4)) -{ - if (sender.state == UIGestureRecognizerStateBegan || - sender.state == UIGestureRecognizerStateChanged || - sender.state == UIGestureRecognizerStateEnded) { - CGPoint velocity = [sender velocityInView:self.view]; - - if (velocity.x > 0.0f) { - velocity.x = -1.0; - } else if (velocity.x < 0.0f) { - velocity.x = 1.0f; - } - if (velocity.y > 0.0f) { - velocity.y = -1.0; - } else if (velocity.y < 0.0f) { - velocity.y = 1.0f; - } - if (velocity.x != 0.0f || velocity.y != 0.0f) { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendScroll(NULL, NULL, (jdouble) velocity.x * 4.0, (jdouble) velocity.y * 4.0); - } - } -} - - (void)surfaceOnTouchesScroll:(UIPanGestureRecognizer *)sender { if (isGrabbing) return; if (sender.state == UIGestureRecognizerStateBegan || @@ -511,33 +537,20 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { sender.state == UIGestureRecognizerStateEnded) { CGPoint velocity = [sender velocityInView:self.view]; if (velocity.x != 0.0f || velocity.y != 0.0f) { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendScroll(NULL, NULL, (jdouble) (velocity.x/10.0), (jdouble) (velocity.y/10.0)); + CallbackBridge_nativeSendScroll((CGFloat) (velocity.x/10.0), (CGFloat) (velocity.y/10.0)); } } } // FIXME: incomplete - (UIPointerRegion *)pointerInteraction:(UIPointerInteraction *)interaction regionForRequest:(UIPointerRegionRequest *)request defaultRegion:(UIPointerRegion *)defaultRegion API_AVAILABLE(ios(13.4)) API_AVAILABLE(ios(13.4)) API_AVAILABLE(ios(13.4)){ - if (request != nil) { - CGPoint origin = self.surfaceView.bounds.origin; - CGPoint point = request.location; - - point.x -= origin.x; - point.y -= origin.y; - - NSLog(@"UIPointerInteraction pos changed: x=%d, y=%d", (int) point.x, (int) point.y); - - callback_SurfaceViewController_onTouch(ACTION_DOWN, (int)point.x, (int)point.y); - } - return [UIPointerRegion regionWithRect:self.surfaceView.bounds identifier:nil]; + NSLog(@"regionForRequest called"); + return nil; } - (UIPointerStyle *)pointerInteraction:(UIPointerInteraction *)interaction styleForRegion:(UIPointerRegion *)region API_AVAILABLE(ios(13.4)){ - if (isGrabbing == JNI_FALSE) { - return nil; - } else { - return [UIPointerStyle hiddenPointerStyle]; - } + NSLog(@"styleForRegion called"); + return [UIPointerStyle hiddenPointerStyle]; } #pragma mark - Input view stuff @@ -545,8 +558,8 @@ const void * _CGDataProviderGetBytePointerCallbackOSMESA(void *info) { NSString* inputStringBefore; -(void)inputViewDidChange { if ([inputView.text length] < INPUT_SPACE_LENGTH) { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(NULL, NULL, GLFW_KEY_BACKSPACE, 0, 1, 0); - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(NULL, NULL, GLFW_KEY_BACKSPACE, 0, 0, 0); + CallbackBridge_nativeSendKey(GLFW_KEY_BACKSPACE, 0, 1, 0); + CallbackBridge_nativeSendKey(GLFW_KEY_BACKSPACE, 0, 0, 0); inputView.text = [@" " stringByAppendingString:inputView.text]; if (inputTextLength > 0) { @@ -565,9 +578,9 @@ NSString* inputStringBefore; jchar theChar = (jchar) [newText characterAtIndex:i]; if (isUseStackQueueCall) { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendCharMods(NULL, NULL, theChar, /* mods */ 0); + CallbackBridge_nativeSendCharMods(theChar, /* mods */ 0); } else { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendChar(NULL, NULL, theChar); + CallbackBridge_nativeSendChar(theChar); } inputView.text = [inputView.text substringFromIndex:1]; @@ -599,12 +612,12 @@ NSString* inputStringBefore; */ for (int i2 = 0; i2 < [inputStringNow length]; i2++) { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(NULL, NULL, GLFW_KEY_BACKSPACE, 0, 1, 0); - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(NULL, NULL, GLFW_KEY_BACKSPACE, 0, 0, 0); + CallbackBridge_nativeSendKey(GLFW_KEY_BACKSPACE, 0, 1, 0); + CallbackBridge_nativeSendKey(GLFW_KEY_BACKSPACE, 0, 0, 0); } for (int i2 = 0; i2 < [inputStringNow length]; i2++) { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendCharMods(NULL, NULL, (jchar) [inputStringNow characterAtIndex:i2], /* mods */ 0); + CallbackBridge_nativeSendCharMods((jchar) [inputStringNow characterAtIndex:i2], /* mods */ 0); } break; @@ -632,8 +645,8 @@ NSString* inputStringBefore; } -(BOOL)textFieldShouldReturn:(UITextField *)textField { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(NULL, NULL, GLFW_KEY_ENTER, 0, 1, 0); - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(NULL, NULL, GLFW_KEY_ENTER, 0, 0, 0); + CallbackBridge_nativeSendKey(GLFW_KEY_ENTER, 0, 1, 0); + CallbackBridge_nativeSendKey(GLFW_KEY_ENTER, 0, 0, 0); return YES; } @@ -656,15 +669,15 @@ int currentVisibility = 1; break; case SPECIALBTN_MOUSEPRI: - Java_org_lwjgl_glfw_CallbackBridge_nativeSendMouseButton(NULL, NULL, GLFW_MOUSE_BUTTON_LEFT, held, 0); + CallbackBridge_nativeSendMouseButton(GLFW_MOUSE_BUTTON_LEFT, held, 0); break; case SPECIALBTN_MOUSESEC: - Java_org_lwjgl_glfw_CallbackBridge_nativeSendMouseButton(NULL, NULL, GLFW_MOUSE_BUTTON_RIGHT, held, 0); + CallbackBridge_nativeSendMouseButton(GLFW_MOUSE_BUTTON_RIGHT, held, 0); break; case SPECIALBTN_MOUSEMID: - Java_org_lwjgl_glfw_CallbackBridge_nativeSendMouseButton(NULL, NULL, GLFW_MOUSE_BUTTON_MIDDLE, held, 0); + CallbackBridge_nativeSendMouseButton(GLFW_MOUSE_BUTTON_MIDDLE, held, 0); break; case SPECIALBTN_TOGGLECTRL: @@ -673,13 +686,13 @@ int currentVisibility = 1; case SPECIALBTN_SCROLLDOWN: if (!held) { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendScroll(NULL, NULL, 0.0, 1.0); + CallbackBridge_nativeSendScroll(0.0, 1.0); } break; case SPECIALBTN_SCROLLUP: if (!held) { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendScroll(NULL, NULL, 0.0, -1.0); + CallbackBridge_nativeSendScroll(0.0, -1.0); } case SPECIALBTN_VIRTUALMOUSE: @@ -697,7 +710,8 @@ int currentVisibility = 1; // there's no key id 0, but we accidentally used -1 as a special key id, so we had to do that // if (keycode == 0) { keycode = -1; } // at the moment, send unknown keycode does nothing, may even cause performance issue, so ignore it - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(NULL, NULL, keycode, 0, held, 0); + +CallbackBridge_nativeSendKey(keycode, 0, held, 0); } } } @@ -766,6 +780,11 @@ int touchesMovedCount; [super touchesBegan:touches withEvent:event]; int i = 0; for (UITouch *touch in touches) { + if (@available(iOS 14.0, *)) { // 13.4 + if (touch.type == UITouchTypeIndirectPointer) { + continue; // handle this in a different place + } + } CGPoint locationInView = [touch locationInView:self.view]; CGFloat screenScale = [[UIScreen mainScreen] scale]; int slot = callback_SurfaceViewController_touchHotbar(locationInView.x * screenScale, locationInView.y * screenScale); @@ -786,6 +805,11 @@ int touchesMovedCount; [super touchesMoved:touches withEvent:event]; for (UITouch *touch in touches) { + if (@available(iOS 14.0, *)) { // 13.4 + if (touch.type == UITouchTypeIndirectPointer) { + continue; // handle this in a different place + } + } if (self.hotbarTouch != touch && [self isTouchInactive:self.primaryTouch]) { // Replace the inactive touch with the current active touch self.primaryTouch = touch; @@ -799,6 +823,11 @@ int touchesMovedCount; - (void)touchesEndedGlobal:(NSSet *)touches withEvent:(UIEvent *)event { for (UITouch *touch in touches) { + if (@available(iOS 14.0, *)) { // 13.4 + if (touch.type == UITouchTypeIndirectPointer) { + continue; // handle this in a different place + } + } [self sendTouchEvent:touch withUIEvent:event withEvent:ACTION_UP]; } } diff --git a/Natives/input_bridge_v3.m b/Natives/input_bridge_v3.m index 467242b9..72923977 100644 --- a/Natives/input_bridge_v3.m +++ b/Natives/input_bridge_v3.m @@ -287,7 +287,7 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeIsGrabbing(J return isGrabbing; } -JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendChar(JNIEnv* env, jclass clazz, jchar codepoint /* jint codepoint */) { +BOOL CallbackBridge_nativeSendChar(jchar codepoint /* jint codepoint */) { if (GLFW_invoke_Char && isInputReady) { if (isUseStackQueueCall) { sendData(EVENT_TYPE_CHAR, codepoint, 0, 0, 0); @@ -295,21 +295,21 @@ JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendChar(JNI GLFW_invoke_Char((void*) showingWindow, (unsigned int) codepoint); // return lwjgl2_triggerCharEvent(codepoint); } - return JNI_TRUE; + return YES; } - return JNI_FALSE; + return NO; } -JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCharMods(JNIEnv* env, jclass clazz, jchar codepoint, jint mods) { +BOOL CallbackBridge_nativeSendCharMods(jchar codepoint, int mods) { if (GLFW_invoke_CharMods && isInputReady) { if (isUseStackQueueCall) { sendData(EVENT_TYPE_CHAR_MODS, (unsigned int) codepoint, mods, 0, 0); } else { GLFW_invoke_CharMods((void*) showingWindow, codepoint, mods); } - return JNI_TRUE; + return YES; } - return JNI_FALSE; + return NO; } /* JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorEnter(JNIEnv* env, jclass clazz, jint entered) { @@ -318,7 +318,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorEnter( } } */ -JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorPos(JNIEnv* env, jclass clazz, jfloat x, jfloat y) { +void CallbackBridge_nativeSendCursorPos(CGFloat x, CGFloat y) { if (GLFW_invoke_CursorPos && isInputReady) { if (!isCursorEntered) { if (GLFW_invoke_CursorEnter) { @@ -361,7 +361,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorPos(JN } } -JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(JNIEnv* env, jclass clazz, jint key, jint scancode, jint action, jint mods) { +void CallbackBridge_nativeSendKey(int key, int scancode, int action, int mods) { if (GLFW_invoke_Key && isInputReady) { if (isUseStackQueueCall) { sendData(EVENT_TYPE_KEY, key, scancode, action, mods); @@ -371,16 +371,16 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(JNIEnv* } } -JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendKeycode(JNIEnv* env, jclass clazz, jint keycode, jchar keychar, jint scancode, jint action, jint mods) { +void CallbackBridge_nativeSendKeycode(int keycode, char keychar, int scancode, int action, int mods) { if (isInputReady) { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(env, clazz, keycode, scancode, action, mods); - if (!Java_org_lwjgl_glfw_CallbackBridge_nativeSendCharMods(env, clazz, keychar, mods)) { - Java_org_lwjgl_glfw_CallbackBridge_nativeSendChar(env, clazz, keychar); + CallbackBridge_nativeSendKey(keycode, scancode, action, mods); + if (!CallbackBridge_nativeSendCharMods(keychar, mods)) { + CallbackBridge_nativeSendChar(keychar); } } } -JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendMouseButton(JNIEnv* env, jclass clazz, jint button, jint action, jint mods) { +void CallbackBridge_nativeSendMouseButton(int button, int action, int mods) { if (isInputReady) { if (button == -1) { // Notify to prepare set new grab pos @@ -395,7 +395,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendMouseButton( } } -JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendScreenSize(JNIEnv* env, jclass clazz, jint width, jint height) { +void CallbackBridge_nativeSendScreenSize(int width, int height) { savedWidth = width; savedHeight = height; @@ -420,7 +420,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendScreenSize(J // return (isInputReady && (GLFW_invoke_FramebufferSize || GLFW_invoke_WindowSize)); } -JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendScroll(JNIEnv* env, jclass clazz, jdouble xoffset, jdouble yoffset) { +void CallbackBridge_nativeSendScroll(CGFloat xoffset, CGFloat yoffset) { if (GLFW_invoke_Scroll && isInputReady) { if (isUseStackQueueCall) { sendData(EVENT_TYPE_SCROLL, xoffset, yoffset, 0, 0); @@ -430,7 +430,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendScroll(JNIEn } } -JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendWindowPos(JNIEnv* env, jclass clazz, jint x, jint y) { +void CallbackBridge_nativeSendWindowPos(int x, int y) { if (GLFW_invoke_WindowPos && isInputReady) { if (isUseStackQueueCall) { sendData(EVENT_TYPE_WINDOW_POS, x, y, 0, 0); @@ -444,3 +444,10 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSetShowingWindow(JNIEnv* en showingWindow = (long) window; } +void CallbackBridge_sendKeycode(int keycode, jchar keychar, int scancode, int modifiers, BOOL isDown) { + if(keycode != 0) CallbackBridge_nativeSendKey(keycode,scancode,isDown ? 1 : 0, modifiers); + if(isDown && keychar != '\0') { + CallbackBridge_nativeSendCharMods(keychar, modifiers); + CallbackBridge_nativeSendChar(keychar); + } +} diff --git a/Natives/ios_uikit_bridge.m b/Natives/ios_uikit_bridge.m index 642c8601..1f406a3c 100644 --- a/Natives/ios_uikit_bridge.m +++ b/Natives/ios_uikit_bridge.m @@ -156,10 +156,9 @@ void UIKit_launchMinecraftSurfaceVC() { usleep(1000); exit(0); } else { - UIViewController *rootController = UIApplication.sharedApplication.windows.lastObject.rootViewController; SurfaceViewController *vc = [[SurfaceViewController alloc] init]; vc.modalPresentationStyle = UIModalPresentationFullScreen; - [rootController presentViewController:vc animated:YES completion:nil]; + [viewController.navigationController pushViewController:vc animated:YES]; } }); } diff --git a/Natives/utils.h b/Natives/utils.h index 21b8d89c..5d4db85d 100644 --- a/Natives/utils.h +++ b/Natives/utils.h @@ -7,6 +7,7 @@ #define ACTION_DOWN 0 #define ACTION_UP 1 #define ACTION_MOVE 2 +#define ACTION_MOVE_MOTION 3 #define BUTTON1_DOWN_MASK 1 << 10 // left btn #define BUTTON2_DOWN_MASK 1 << 11 // mid btn @@ -56,6 +57,9 @@ int savedWidth, savedHeight; BOOL virtualMouseEnabled; +static inline CGFloat clamp(CGFloat x, CGFloat lower, CGFloat upper) { + return fmin(upper, fmax(x, lower)); +} CGFloat MathUtils_dist(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2); CGFloat MathUtils_map(CGFloat x, CGFloat in_min, CGFloat in_max, CGFloat out_min, CGFloat out_max); CGFloat dpToPx(CGFloat dp); @@ -76,14 +80,13 @@ void callback_SurfaceViewController_launchMinecraft(int width, int height); void callback_SurfaceViewController_onTouch(int event, CGFloat x, CGFloat y); int callback_SurfaceViewController_touchHotbar(CGFloat x, CGFloat y); -JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendChar(JNIEnv* env, jclass clazz, jchar codepoint /* jint codepoint */); -JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCharMods(JNIEnv* env, jclass clazz, jchar codepoint, jint mods); -JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorPos(JNIEnv* env, jclass clazz, jfloat x, jfloat y); -JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(JNIEnv* env, jclass clazz, jint key, jint scancode, jint action, jint mods); -JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendKeycode(JNIEnv* env, jclass clazz, jint keycode, jchar keychar, jint scancode, jint action, jint mods); -JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendMouseButton(JNIEnv* env, jclass clazz, jint button, jint action, jint mods); -JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendScreenSize(JNIEnv* env, jclass clazz, jint width, jint height); -JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendScroll(JNIEnv* env, jclass clazz, jdouble xoffset, jdouble yoffset); -JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendWindowPos(JNIEnv* env, jclass clazz, jint x, jint y); - - +BOOL CallbackBridge_nativeSendChar(jchar codepoint /* jint codepoint */); +BOOL CallbackBridge_nativeSendCharMods(jchar codepoint, int mods); +void CallbackBridge_nativeSendCursorPos(CGFloat x, CGFloat y); +void CallbackBridge_nativeSendKey(int key, int scancode, int action, int mods); +void CallbackBridge_nativeSendKeycode(int keycode, char keychar, int scancode, int action, int mods); +void CallbackBridge_nativeSendMouseButton(int button, int action, int mods); +void CallbackBridge_nativeSendScreenSize(int width, int height); +void CallbackBridge_nativeSendScroll(CGFloat xoffset, CGFloat yoffset); +void CallbackBridge_nativeSendWindowPos(jint x, jint y); +void CallbackBridge_sendKeycode(int keycode, jchar keychar, int scancode, int modifiers, BOOL isDown);