diff --git a/.gitmodules b/.gitmodules index f35bae7..11cd918 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ [submodule "moonlight-common/moonlight-common-c"] path = moonlight-common/moonlight-common-c url = https://github.com/moonlight-stream/moonlight-common-c.git -[submodule "X1Kit"] - path = X1Kit - url = https://github.com/fizzyade/X1Kit.git diff --git a/Limelight/Database/DataManager.h b/Limelight/Database/DataManager.h index f77b6c7..c9cca07 100644 --- a/Limelight/Database/DataManager.h +++ b/Limelight/Database/DataManager.h @@ -18,13 +18,12 @@ height:(NSInteger)height width:(NSInteger)width onscreenControls:(NSInteger)onscreenControls - remote:(BOOL)streamingRemotely optimizeGames:(BOOL)optimizeGames multiController:(BOOL)multiController audioOnPC:(BOOL)audioOnPC useHevc:(BOOL)useHevc enableHdr:(BOOL)enableHdr - btMouseSupport:(BOOL)btMouseSupport; + absoluteTouchMode:(BOOL)absoluteTouchMode; - (NSArray*) getHosts; - (void) updateHost:(TemporaryHost*)host; diff --git a/Limelight/Database/DataManager.m b/Limelight/Database/DataManager.m index fb7ae54..718d8d5 100644 --- a/Limelight/Database/DataManager.m +++ b/Limelight/Database/DataManager.m @@ -58,13 +58,12 @@ height:(NSInteger)height width:(NSInteger)width onscreenControls:(NSInteger)onscreenControls - remote:(BOOL)streamingRemotely optimizeGames:(BOOL)optimizeGames multiController:(BOOL)multiController audioOnPC:(BOOL)audioOnPC useHevc:(BOOL)useHevc enableHdr:(BOOL)enableHdr - btMouseSupport:(BOOL)btMouseSupport { + absoluteTouchMode:(BOOL)absoluteTouchMode { [_managedObjectContext performBlockAndWait:^{ Settings* settingsToSave = [self retrieveSettings]; @@ -73,13 +72,12 @@ settingsToSave.height = [NSNumber numberWithInteger:height]; settingsToSave.width = [NSNumber numberWithInteger:width]; settingsToSave.onscreenControls = [NSNumber numberWithInteger:onscreenControls]; - settingsToSave.streamingRemotely = streamingRemotely; settingsToSave.optimizeGames = optimizeGames; settingsToSave.multiController = multiController; settingsToSave.playAudioOnPC = audioOnPC; settingsToSave.useHevc = useHevc; settingsToSave.enableHdr = enableHdr; - settingsToSave.btMouseSupport = btMouseSupport; + settingsToSave.absoluteTouchMode = absoluteTouchMode; [self saveData]; }]; diff --git a/Limelight/Database/TemporarySettings.h b/Limelight/Database/TemporarySettings.h index c249976..a377ffd 100644 --- a/Limelight/Database/TemporarySettings.h +++ b/Limelight/Database/TemporarySettings.h @@ -24,7 +24,7 @@ @property (nonatomic) BOOL playAudioOnPC; @property (nonatomic) BOOL optimizeGames; @property (nonatomic) BOOL enableHdr; -@property (nonatomic) BOOL btMouseSupport; +@property (nonatomic) BOOL absoluteTouchMode; - (id) initFromSettings:(Settings*)settings; diff --git a/Limelight/Database/TemporarySettings.m b/Limelight/Database/TemporarySettings.m index aec111a..7af3177 100644 --- a/Limelight/Database/TemporarySettings.m +++ b/Limelight/Database/TemporarySettings.m @@ -39,7 +39,6 @@ self.enableHdr = [[NSUserDefaults standardUserDefaults] boolForKey:@"enableHdr"]; self.optimizeGames = [[NSUserDefaults standardUserDefaults] boolForKey:@"optimizeGames"]; self.multiController = [[NSUserDefaults standardUserDefaults] boolForKey:@"multipleControllers"]; - self.btMouseSupport = [[NSUserDefaults standardUserDefaults] boolForKey:@"btMouseSupport"]; NSInteger _screenSize = [[NSUserDefaults standardUserDefaults] integerForKey:@"streamResolution"]; switch (_screenSize) { @@ -70,10 +69,9 @@ self.optimizeGames = settings.optimizeGames; self.multiController = settings.multiController; self.onscreenControls = settings.onscreenControls; - self.btMouseSupport = settings.btMouseSupport; + self.absoluteTouchMode = settings.absoluteTouchMode; #endif self.uniqueId = settings.uniqueId; - self.streamingRemotely = settings.streamingRemotely; return self; } diff --git a/Limelight/Input/ControllerSupport.h b/Limelight/Input/ControllerSupport.h index 3b7fc31..f416c34 100644 --- a/Limelight/Input/ControllerSupport.h +++ b/Limelight/Input/ControllerSupport.h @@ -44,7 +44,4 @@ -(NSUInteger) getConnectedGamepadCount; -@property (nonatomic, strong) id connectObserver; -@property (nonatomic, strong) id disconnectObserver; - @end diff --git a/Limelight/Input/ControllerSupport.m b/Limelight/Input/ControllerSupport.m index 0327f42..0c39067 100644 --- a/Limelight/Input/ControllerSupport.m +++ b/Limelight/Input/ControllerSupport.m @@ -17,12 +17,25 @@ @import GameController; @import AudioToolbox; +static const double MOUSE_SPEED_DIVISOR = 2.5; + @implementation ControllerSupport { + id _controllerConnectObserver; + id _controllerDisconnectObserver; + id _mouseConnectObserver; + id _mouseDisconnectObserver; + id _keyboardConnectObserver; + id _keyboardDisconnectObserver; + NSLock *_controllerStreamLock; NSMutableDictionary *_controllers; NSTimer *_rumbleTimer; id _presenceDelegate; + float accumulatedDeltaX; + float accumulatedDeltaY; + float accumulatedScrollY; + OnScreenControls *_osc; // This controller object is shared between on-screen controls @@ -195,6 +208,15 @@ [_controllerStreamLock unlock]; } ++(BOOL) hasKeyboardOrMouse { + if (@available(iOS 14.0, tvOS 14.0, *)) { + return GCMouse.mice.count > 0 || GCKeyboard.coalescedKeyboard != nil; + } + else { + return NO; + } +} + #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-declarations" @@ -327,6 +349,71 @@ } } +-(void) unregisterMouseCallbacks:(GCMouse*)mouse API_AVAILABLE(ios(14.0)) { + mouse.mouseInput.mouseMovedHandler = nil; + + mouse.mouseInput.leftButton.pressedChangedHandler = nil; + mouse.mouseInput.middleButton.pressedChangedHandler = nil; + mouse.mouseInput.rightButton.pressedChangedHandler = nil; + + for (GCControllerButtonInput* auxButton in mouse.mouseInput.auxiliaryButtons) { + auxButton.pressedChangedHandler = nil; + } +} + +-(void) registerMouseCallbacks:(GCMouse*) mouse API_AVAILABLE(ios(14.0)) { + mouse.mouseInput.mouseMovedHandler = ^(GCMouseInput * _Nonnull mouse, float deltaX, float deltaY) { + self->accumulatedDeltaX += deltaX / MOUSE_SPEED_DIVISOR; + self->accumulatedDeltaY += -deltaY / MOUSE_SPEED_DIVISOR; + + short truncatedDeltaX = (short)self->accumulatedDeltaX; + short truncatedDeltaY = (short)self->accumulatedDeltaY; + + if (truncatedDeltaX != 0 || truncatedDeltaY != 0) { + LiSendMouseMoveEvent(truncatedDeltaX, truncatedDeltaY); + + self->accumulatedDeltaX -= truncatedDeltaX; + self->accumulatedDeltaY -= truncatedDeltaY; + } + }; + + mouse.mouseInput.leftButton.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) { + LiSendMouseButtonEvent(pressed ? BUTTON_ACTION_PRESS : BUTTON_ACTION_RELEASE, BUTTON_LEFT); + }; + mouse.mouseInput.middleButton.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) { + LiSendMouseButtonEvent(pressed ? BUTTON_ACTION_PRESS : BUTTON_ACTION_RELEASE, BUTTON_MIDDLE); + }; + mouse.mouseInput.rightButton.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) { + LiSendMouseButtonEvent(pressed ? BUTTON_ACTION_PRESS : BUTTON_ACTION_RELEASE, BUTTON_RIGHT); + }; + + if (mouse.mouseInput.auxiliaryButtons != nil) { + if (mouse.mouseInput.auxiliaryButtons.count >= 1) { + mouse.mouseInput.auxiliaryButtons[0].pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) { + LiSendMouseButtonEvent(pressed ? BUTTON_ACTION_PRESS : BUTTON_ACTION_RELEASE, BUTTON_X1); + }; + } + if (mouse.mouseInput.auxiliaryButtons.count >= 2) { + mouse.mouseInput.auxiliaryButtons[1].pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) { + LiSendMouseButtonEvent(pressed ? BUTTON_ACTION_PRESS : BUTTON_ACTION_RELEASE, BUTTON_X2); + }; + } + } + + // TODO: Confirm scroll direction + mouse.mouseInput.scroll.yAxis.valueChangedHandler = ^(GCControllerAxisInput * _Nonnull axis, float value) { + self->accumulatedScrollY += -value; + + short truncatedScrollY = (short)self->accumulatedScrollY; + + if (truncatedScrollY != 0) { + LiSendHighResScrollEvent(truncatedScrollY); + + self->accumulatedScrollY -= truncatedScrollY; + } + }; +} + -(void) updateAutoOnScreenControlMode { // Auto on-screen control support may not be enabled @@ -365,6 +452,17 @@ } } + // If we didn't find a gamepad present and we have a keyboard or mouse, turn + // the on-screen controls off to get the overlays out of the way. + if (level == OnScreenControlsLevelFull && [ControllerSupport hasKeyboardOrMouse]) { + level = OnScreenControlsLevelOff; + + // Ensure the virtual gamepad disappears to avoid confusing some games. + // If the mouse and keyboard disconnect later, it will reappear when the + // first OSC input is received. + LiSendMultiControllerEvent(0, 0, 0, 0, 0, 0, 0, 0, 0); + } + [_osc setLevel:level]; } @@ -452,9 +550,9 @@ DataManager* dataMan = [[DataManager alloc] init]; OnScreenControlsLevel level = (OnScreenControlsLevel)[[dataMan getSettings].onscreenControls integerValue]; - // Even if no gamepads are present, we will always count one - // if OSC is enabled. - if (level != OnScreenControlsLevelOff) { + // Even if no gamepads are present, we will always count one if OSC is enabled, + // or it's set to auto and no keyboard or mouse is present. + if (level != OnScreenControlsLevelOff && (![ControllerSupport hasKeyboardOrMouse] || level != OnScreenControlsLevelAuto)) { mask |= 0x1; } @@ -512,11 +610,16 @@ if ([ControllerSupport isSupportedGamepad:controller]) { [self assignController:controller]; [self registerControllerCallbacks:controller]; - [self updateAutoOnScreenControlMode]; } } - self.connectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { + if (@available(iOS 14.0, tvOS 14.0, *)) { + for (GCMouse* mouse in [GCMouse mice]) { + [self registerMouseCallbacks:mouse]; + } + } + + _controllerConnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { Log(LOG_I, @"Controller connected!"); GCController* controller = note.object; @@ -537,7 +640,7 @@ // Notify the delegate [self->_presenceDelegate gamepadPresenceChanged]; }]; - self.disconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { + _controllerDisconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { Log(LOG_I, @"Controller disconnected!"); GCController* controller = note.object; @@ -565,6 +668,44 @@ // Notify the delegate [self->_presenceDelegate gamepadPresenceChanged]; }]; + + if (@available(iOS 14.0, tvOS 14.0, *)) { + _mouseConnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCMouseDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { + Log(LOG_I, @"Mouse connected!"); + + GCMouse* mouse = note.object; + + // Register for mouse events + [self registerMouseCallbacks: mouse]; + + // Re-evaluate the on-screen control mode + [self updateAutoOnScreenControlMode]; + }]; + _mouseDisconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCMouseDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { + Log(LOG_I, @"Mouse disconnected!"); + + GCMouse* mouse = note.object; + + // Unregister for mouse events + [self unregisterMouseCallbacks: mouse]; + + // Re-evaluate the on-screen control mode + [self updateAutoOnScreenControlMode]; + }]; + _keyboardConnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCKeyboardDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { + Log(LOG_I, @"Keyboard connected!"); + + // Re-evaluate the on-screen control mode + [self updateAutoOnScreenControlMode]; + }]; + _keyboardDisconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCKeyboardDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { + Log(LOG_I, @"Keyboard disconnected!"); + + // Re-evaluate the on-screen control mode + [self updateAutoOnScreenControlMode]; + }]; + } + return self; } @@ -572,8 +713,12 @@ { [_rumbleTimer invalidate]; _rumbleTimer = nil; - [[NSNotificationCenter defaultCenter] removeObserver:self.connectObserver]; - [[NSNotificationCenter defaultCenter] removeObserver:self.disconnectObserver]; + [[NSNotificationCenter defaultCenter] removeObserver:_controllerConnectObserver]; + [[NSNotificationCenter defaultCenter] removeObserver:_controllerDisconnectObserver]; + [[NSNotificationCenter defaultCenter] removeObserver:_mouseConnectObserver]; + [[NSNotificationCenter defaultCenter] removeObserver:_mouseDisconnectObserver]; + [[NSNotificationCenter defaultCenter] removeObserver:_keyboardConnectObserver]; + [[NSNotificationCenter defaultCenter] removeObserver:_keyboardDisconnectObserver]; [_controllers removeAllObjects]; _controllerNumbers = 0; for (GCController* controller in [GCController controllers]) { @@ -581,6 +726,12 @@ [self unregisterControllerCallbacks:controller]; } } + + if (@available(iOS 14.0, tvOS 14.0, *)) { + for (GCMouse* mouse in [GCMouse mice]) { + [self unregisterMouseCallbacks:mouse]; + } + } } @end diff --git a/Limelight/Input/StreamView.h b/Limelight/Input/StreamView.h index 60b4a03..98e82c2 100644 --- a/Limelight/Input/StreamView.h +++ b/Limelight/Input/StreamView.h @@ -8,7 +8,6 @@ #import "ControllerSupport.h" #import "OnScreenControls.h" -#import "Moonlight-Swift.h" #import "StreamConfiguration.h" @protocol EdgeDetectionDelegate @@ -25,9 +24,9 @@ @end #if TARGET_OS_TV -@interface StreamView : OSView +@interface StreamView : OSView #else -@interface StreamView : OSView +@interface StreamView : OSView #endif @property (nonatomic, retain) IBOutlet UITextField* keyInputField; diff --git a/Limelight/Input/StreamView.m b/Limelight/Input/StreamView.m index 96892dd..b9aac09 100644 --- a/Limelight/Input/StreamView.m +++ b/Limelight/Input/StreamView.m @@ -12,8 +12,6 @@ #import "ControllerSupport.h" #import "KeyboardSupport.h" -static const double X1_MOUSE_SPEED_DIVISOR = 2.5; - static const int REFERENCE_WIDTH = 1280; static const int REFERENCE_HEIGHT = 720; @@ -33,8 +31,7 @@ static const int REFERENCE_HEIGHT = 720; float lastMouseX; float lastMouseY; - // Citrix X1 mouse support - X1Mouse* x1mouse; + // iOS 14 mouse support double accumulatedMouseDeltaX; double accumulatedMouseDeltaY; @@ -79,7 +76,11 @@ static const int REFERENCE_HEIGHT = 720; [onScreenControls setLevel:level]; } - if (@available(iOS 13.4, *)) { + if (@available(iOS 14.0, *)) { + // Use the new GCMouse API on iOS 14 + } + else if (@available(iOS 13.4, *)) { + // Use the legacy mouse API on iOS 13.4 [self addInteraction:[[UIPointerInteraction alloc] initWithDelegate:self]]; UIPanGestureRecognizer *mouseWheelRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(mouseWheelMoved:)]; @@ -88,13 +89,6 @@ static const int REFERENCE_HEIGHT = 720; [self addGestureRecognizer:mouseWheelRecognizer]; } #endif - - x1mouse = [[X1Mouse alloc] init]; - x1mouse.delegate = self; - - if (settings.btMouseSupport) { - [x1mouse start]; - } } - (void)startInteractionTimer { @@ -189,32 +183,38 @@ static const int REFERENCE_HEIGHT = 720; if (@available(iOS 13.4, *)) { UITouch* touch = [touches anyObject]; if (touch.type == UITouchTypeIndirectPointer) { - UIEventButtonMask changedButtons = lastMouseButtonMask ^ event.buttonMask; - - for (int i = BUTTON_LEFT; i <= BUTTON_X2; i++) { - UIEventButtonMask buttonFlag; - - switch (i) { - // Right and Middle are reversed from what iOS uses - case BUTTON_RIGHT: - buttonFlag = UIEventButtonMaskForButtonNumber(2); - break; - case BUTTON_MIDDLE: - buttonFlag = UIEventButtonMaskForButtonNumber(3); - break; - - default: - buttonFlag = UIEventButtonMaskForButtonNumber(i); - break; - } - - if (changedButtons & buttonFlag) { - LiSendMouseButtonEvent(buttonAction, i); - } + if (@available(iOS 14.0, *)) { + // We'll handle this with GCMouse. Do nothing here. + return YES; + } + else { + UIEventButtonMask changedButtons = lastMouseButtonMask ^ event.buttonMask; + + for (int i = BUTTON_LEFT; i <= BUTTON_X2; i++) { + UIEventButtonMask buttonFlag; + + switch (i) { + // Right and Middle are reversed from what iOS uses + case BUTTON_RIGHT: + buttonFlag = UIEventButtonMaskForButtonNumber(2); + break; + case BUTTON_MIDDLE: + buttonFlag = UIEventButtonMaskForButtonNumber(3); + break; + + default: + buttonFlag = UIEventButtonMaskForButtonNumber(i); + break; + } + + if (changedButtons & buttonFlag) { + LiSendMouseButtonEvent(buttonAction, i); + } + } + + lastMouseButtonMask = event.buttonMask; + return YES; } - - lastMouseButtonMask = event.buttonMask; - return YES; } } #endif @@ -227,14 +227,20 @@ static const int REFERENCE_HEIGHT = 720; if (@available(iOS 13.4, *)) { UITouch *touch = [touches anyObject]; if (touch.type == UITouchTypeIndirectPointer) { - // We must handle this event to properly support - // drags while the middle, X1, or X2 mouse buttons are - // held down. For some reason, left and right buttons - // don't require this, but we do it anyway for them too. - // Cursor movement without a button held down is handled - // in pointerInteraction:regionForRequest:defaultRegion. - [self updateCursorLocation:[touch locationInView:self]]; - return; + if (@available(iOS 14.0, *)) { + // We'll handle this with GCMouse. Do nothing here. + return; + } + else { + // We must handle this event to properly support + // drags while the middle, X1, or X2 mouse buttons are + // held down. For some reason, left and right buttons + // don't require this, but we do it anyway for them too. + // Cursor movement without a button held down is handled + // in pointerInteraction:regionForRequest:defaultRegion. + [self updateCursorLocation:[touch locationInView:self]]; + return; + } } } #endif @@ -662,51 +668,4 @@ static const int REFERENCE_HEIGHT = 720; return commands; } -- (void)connectedStateDidChangeWithIdentifier:(NSUUID * _Nonnull)identifier isConnected:(BOOL)isConnected { - NSLog(@"Citrix X1 mouse state change: %@ -> %s", - identifier, isConnected ? "connected" : "disconnected"); -} - -- (void)mouseDidMoveWithIdentifier:(NSUUID * _Nonnull)identifier deltaX:(int16_t)deltaX deltaY:(int16_t)deltaY { - accumulatedMouseDeltaX += deltaX / X1_MOUSE_SPEED_DIVISOR; - accumulatedMouseDeltaY += deltaY / X1_MOUSE_SPEED_DIVISOR; - - short shortX = (short)accumulatedMouseDeltaX; - short shortY = (short)accumulatedMouseDeltaY; - - if (shortX == 0 && shortY == 0) { - return; - } - - LiSendMouseMoveEvent(shortX, shortY); - - accumulatedMouseDeltaX -= shortX; - accumulatedMouseDeltaY -= shortY; -} - -- (int) buttonFromX1ButtonCode:(enum X1MouseButton)button { - switch (button) { - case X1MouseButtonLeft: - return BUTTON_LEFT; - case X1MouseButtonRight: - return BUTTON_RIGHT; - case X1MouseButtonMiddle: - return BUTTON_MIDDLE; - default: - return -1; - } -} - -- (void)mouseDownWithIdentifier:(NSUUID * _Nonnull)identifier button:(enum X1MouseButton)button { - LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, [self buttonFromX1ButtonCode:button]); -} - -- (void)mouseUpWithIdentifier:(NSUUID * _Nonnull)identifier button:(enum X1MouseButton)button { - LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, [self buttonFromX1ButtonCode:button]); -} - -- (void)wheelDidScrollWithIdentifier:(NSUUID * _Nonnull)identifier deltaZ:(int8_t)deltaZ { - LiSendScrollEvent(deltaZ); -} - @end diff --git a/Limelight/Limelight-Info.plist b/Limelight/Limelight-Info.plist index b1e04f6..02c903c 100644 --- a/Limelight/Limelight-Info.plist +++ b/Limelight/Limelight-Info.plist @@ -46,10 +46,6 @@ NSAllowsArbitraryLoads - NSBluetoothAlwaysUsageDescription - Bluetooth access allows Moonlight to connect to Citrix X1 mice. - NSBluetoothPeripheralUsageDescription - Bluetooth access allows Moonlight to connect to Citrix X1 mice. NSLocalNetworkUsageDescription Moonlight uses the local network to connect to your gaming PC for streaming. NSBonjourServices diff --git a/Limelight/Limelight.xcdatamodeld/.xccurrentversion b/Limelight/Limelight.xcdatamodeld/.xccurrentversion index 3ebeef5..c2a8b51 100644 --- a/Limelight/Limelight.xcdatamodeld/.xccurrentversion +++ b/Limelight/Limelight.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - Moonlight v1.5.xcdatamodel + Moonlight v1.6.xcdatamodel diff --git a/Limelight/Limelight.xcdatamodeld/Moonlight v1.6.xcdatamodel/contents b/Limelight/Limelight.xcdatamodeld/Moonlight v1.6.xcdatamodel/contents new file mode 100644 index 0000000..b96ea09 --- /dev/null +++ b/Limelight/Limelight.xcdatamodeld/Moonlight v1.6.xcdatamodel/contents @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Limelight/ViewControllers/SettingsViewController.h b/Limelight/ViewControllers/SettingsViewController.h index 825e65f..86ab5a0 100644 --- a/Limelight/ViewControllers/SettingsViewController.h +++ b/Limelight/ViewControllers/SettingsViewController.h @@ -19,7 +19,7 @@ @property (strong, nonatomic) IBOutlet UISegmentedControl *multiControllerSelector; @property (strong, nonatomic) IBOutlet UISegmentedControl *audioOnPCSelector; @property (strong, nonatomic) IBOutlet UISegmentedControl *hevcSelector; -@property (strong, nonatomic) IBOutlet UISegmentedControl *btMouseSelector; +@property (strong, nonatomic) IBOutlet UISegmentedControl *touchscreenModeSelector; @property (strong, nonatomic) IBOutlet UIScrollView *scrollView; #pragma clang diagnostic push diff --git a/Limelight/ViewControllers/SettingsViewController.m b/Limelight/ViewControllers/SettingsViewController.m index 3e540d1..1819e0e 100644 --- a/Limelight/ViewControllers/SettingsViewController.m +++ b/Limelight/ViewControllers/SettingsViewController.m @@ -191,7 +191,7 @@ static const int bitrateTable[] = { [self.hevcSelector setEnabled:NO]; } - [self.btMouseSelector setSelectedSegmentIndex:currentSettings.btMouseSupport ? 1 : 0]; + [self.touchscreenModeSelector setSelectedSegmentIndex:currentSettings.absoluteTouchMode ? 1 : 0]; [self.optimizeSettingsSelector setSelectedSegmentIndex:currentSettings.optimizeGames ? 1 : 0]; [self.multiControllerSelector setSelectedSegmentIndex:currentSettings.multiController ? 1 : 0]; [self.audioOnPCSelector setSelectedSegmentIndex:currentSettings.playAudioOnPC ? 1 : 0]; @@ -291,19 +291,18 @@ static const int bitrateTable[] = { BOOL multiController = [self.multiControllerSelector selectedSegmentIndex] == 1; BOOL audioOnPC = [self.audioOnPCSelector selectedSegmentIndex] == 1; BOOL useHevc = [self.hevcSelector selectedSegmentIndex] == 1; - BOOL btMouseSupport = [self.btMouseSelector selectedSegmentIndex] == 1; + BOOL absoluteTouchMode = [self.touchscreenModeSelector selectedSegmentIndex] == 1; [dataMan saveSettingsWithBitrate:_bitrate framerate:framerate height:height width:width onscreenControls:onscreenControls - remote:NO optimizeGames:optimizeGames multiController:multiController audioOnPC:audioOnPC useHevc:useHevc enableHdr:NO - btMouseSupport:btMouseSupport]; + absoluteTouchMode:absoluteTouchMode]; } - (void)didReceiveMemoryWarning { diff --git a/Moonlight TV/Info.plist b/Moonlight TV/Info.plist index 9959dc0..5f995ea 100644 --- a/Moonlight TV/Info.plist +++ b/Moonlight TV/Info.plist @@ -36,10 +36,6 @@ NSAllowsArbitraryLoads - NSBluetoothAlwaysUsageDescription - Bluetooth access allows Moonlight to connect to Citrix X1 mice. - NSBluetoothPeripheralUsageDescription - Bluetooth access allows Moonlight to connect to Citrix X1 mice. NSLocalNetworkUsageDescription Moonlight uses the local network to connect to your gaming PC for streaming. NSBonjourServices diff --git a/Moonlight TV/Settings.bundle/Root.plist b/Moonlight TV/Settings.bundle/Root.plist index d843929..1895973 100644 --- a/Moonlight TV/Settings.bundle/Root.plist +++ b/Moonlight TV/Settings.bundle/Root.plist @@ -144,16 +144,6 @@ DefaultValue - - Type - PSToggleSwitchSpecifier - Title - Citrix X1 Mouse Support - Key - btMouseSupport - DefaultValue - - diff --git a/Moonlight.xcodeproj/project.pbxproj b/Moonlight.xcodeproj/project.pbxproj index 6c17db9..224d0b2 100644 --- a/Moonlight.xcodeproj/project.pbxproj +++ b/Moonlight.xcodeproj/project.pbxproj @@ -17,8 +17,6 @@ 9865DC3C2132922E0005B9B9 /* GameController.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9865DC3B2132922E0005B9B9 /* GameController.framework */; }; 9865DC3E21332D660005B9B9 /* MainFrameViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = FB89462519F646E200339C8A /* MainFrameViewController.m */; }; 9890CF6B203B7EE1006C4B06 /* libxml2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 9890CF6A203B7EE1006C4B06 /* libxml2.tbd */; }; - 9896219723D15C7000211983 /* X1Kit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9896219623D15C7000211983 /* X1Kit.swift */; }; - 9896219A23D56E8100211983 /* X1Kit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9896219623D15C7000211983 /* X1Kit.swift */; }; 9897B6A1221260EF00966419 /* Controller.m in Sources */ = {isa = PBXBuildFile; fileRef = 9897B6A0221260EF00966419 /* Controller.m */; }; 9897B6A62212732C00966419 /* Controller.m in Sources */ = {isa = PBXBuildFile; fileRef = 9897B6A0221260EF00966419 /* Controller.m */; }; 98CFB82F1CAD481B0048EF74 /* libmoonlight-common.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 98AB2E841CAD46840089BB98 /* libmoonlight-common.a */; }; @@ -157,6 +155,7 @@ /* Begin PBXFileReference section */ 693B3A9A218638CD00982F7B /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = ""; }; 98132E8C20BC9A62007A053F /* Moonlight v1.1.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.1.xcdatamodel"; sourceTree = ""; }; + 9827E7592512DDDC00F25707 /* Moonlight v1.6.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.6.xcdatamodel"; sourceTree = ""; }; 9832D1341BBCD5C50036EF48 /* TemporaryApp.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TemporaryApp.h; path = Database/TemporaryApp.h; sourceTree = ""; }; 9832D1351BBCD5C50036EF48 /* TemporaryApp.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TemporaryApp.m; path = Database/TemporaryApp.m; sourceTree = ""; }; 98517B1B21CE0A9000481377 /* Moonlight v1.3.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.3.xcdatamodel"; sourceTree = ""; }; @@ -166,7 +165,6 @@ 98783FEA242EAC5D00F00EF4 /* Moonlight v1.5.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Moonlight v1.5.xcdatamodel"; sourceTree = ""; }; 98878AE0206A226D00586E90 /* OSPortabilityDefs.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OSPortabilityDefs.h; sourceTree = ""; }; 9890CF6A203B7EE1006C4B06 /* libxml2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libxml2.tbd; path = usr/lib/libxml2.tbd; sourceTree = SDKROOT; }; - 9896219623D15C7000211983 /* X1Kit.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = X1Kit.swift; path = X1Kit/Sources/X1Kit/X1Kit.swift; sourceTree = ""; }; 9897B6A0221260EF00966419 /* Controller.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Controller.m; sourceTree = ""; }; 9897B6A32212610800966419 /* Controller.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Controller.h; sourceTree = ""; }; 98AB2E7F1CAD46830089BB98 /* moonlight-common.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "moonlight-common.xcodeproj"; path = "moonlight-common/moonlight-common.xcodeproj"; sourceTree = ""; }; @@ -396,14 +394,6 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ - 9896219423D15C2900211983 /* X1Kit */ = { - isa = PBXGroup; - children = ( - 9896219623D15C7000211983 /* X1Kit.swift */, - ); - name = X1Kit; - sourceTree = ""; - }; 98AB2E801CAD46830089BB98 /* Products */ = { isa = PBXGroup; children = ( @@ -428,7 +418,6 @@ FB290CE519B2C406004C83CF = { isa = PBXGroup; children = ( - 9896219423D15C2900211983 /* X1Kit */, 98AB2E7F1CAD46830089BB98 /* moonlight-common.xcodeproj */, FB290CF919B2C406004C83CF /* Moonlight */, FB1A67542132419700507771 /* Moonlight TV */, @@ -853,7 +842,7 @@ isa = PBXProject; attributes = { LastSwiftUpdateCheck = 0730; - LastUpgradeCheck = 1010; + LastUpgradeCheck = 1200; ORGANIZATIONNAME = "Moonlight Game Streaming Project"; TargetAttributes = { FB1A67522132419700507771 = { @@ -960,7 +949,6 @@ FB1A67E02132460A00507771 /* Logger.m in Sources */, FB1A67D52132460400507771 /* ControllerSupport.m in Sources */, FB1A67D82132460400507771 /* StreamView.m in Sources */, - 9896219A23D56E8100211983 /* X1Kit.swift in Sources */, FB1A67DA2132460400507771 /* OnScreenControls.m in Sources */, FB1A67DC2132460400507771 /* KeyboardSupport.m in Sources */, FB1A67CD213245F800507771 /* DataManager.m in Sources */, @@ -1031,7 +1019,6 @@ FB9AFD371A7E02DB00872C98 /* HttpRequest.m in Sources */, FB4678ED1A50C40900377732 /* OnScreenControls.m in Sources */, FB290D0019B2C406004C83CF /* main.m in Sources */, - 9896219723D15C7000211983 /* X1Kit.swift in Sources */, FBD3494319FC9C04002D2A60 /* AppAssetManager.m in Sources */, FB6549561A57907E001C8F39 /* DiscoveryWorker.m in Sources */, FB89462A19F646E200339C8A /* ControllerSupport.m in Sources */, @@ -1189,6 +1176,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -1212,7 +1200,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; SWIFT_OBJC_INTERFACE_HEADER_NAME = ""; @@ -1243,6 +1231,7 @@ CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; CLANG_WARN_STRICT_PROTOTYPES = YES; CLANG_WARN_SUSPICIOUS_MOVE = YES; @@ -1263,7 +1252,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.3; PROVISIONING_PROFILE = ""; SDKROOT = iphoneos; SWIFT_OBJC_INTERFACE_HEADER_NAME = ""; @@ -1387,6 +1376,7 @@ FB290D0519B2C406004C83CF /* Limelight.xcdatamodeld */ = { isa = XCVersionGroup; children = ( + 9827E7592512DDDC00F25707 /* Moonlight v1.6.xcdatamodel */, 98783FEA242EAC5D00F00EF4 /* Moonlight v1.5.xcdatamodel */, 98608BDD22DC0C2C000E5672 /* Moonlight v1.4.xcdatamodel */, 98517B1B21CE0A9000481377 /* Moonlight v1.3.xcdatamodel */, @@ -1398,7 +1388,7 @@ FB4678F21A51BDCB00377732 /* Limelight 0.3.0.xcdatamodel */, FB290D0619B2C406004C83CF /* Limelight.xcdatamodel */, ); - currentVersion = 98783FEA242EAC5D00F00EF4 /* Moonlight v1.5.xcdatamodel */; + currentVersion = 9827E7592512DDDC00F25707 /* Moonlight v1.6.xcdatamodel */; path = Limelight.xcdatamodeld; sourceTree = ""; versionGroupType = wrapper.xcdatamodel; diff --git a/X1Kit b/X1Kit deleted file mode 160000 index cf378b5..0000000 --- a/X1Kit +++ /dev/null @@ -1 +0,0 @@ -Subproject commit cf378b5b8ccc2a6a401ede6a90e134aac906fa46 diff --git a/iPad.storyboard b/iPad.storyboard index 3401386..c5dfaee 100644 --- a/iPad.storyboard +++ b/iPad.storyboard @@ -1,9 +1,9 @@ - + - + @@ -202,37 +202,37 @@ - + + + + + diff --git a/iPhone.storyboard b/iPhone.storyboard index 467faba..be5bf26 100644 --- a/iPhone.storyboard +++ b/iPhone.storyboard @@ -1,9 +1,9 @@ - - + + - + @@ -221,19 +221,19 @@ -