Port for macOS (#311)
* merged moonlight-mac with moonlight-ios * reverted to the original project.pbxproj * cleaned up the code, fixed lots of unnecessary code duplications * multicontroller support (not tested) * new class that can be used for further modularization of the MainFrameViewController
@@ -6,11 +6,19 @@
|
|||||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
|
||||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||||
|
|
||||||
@property (strong, nonatomic) UIWindow *window;
|
@property (strong, nonatomic) UIWindow *window;
|
||||||
|
#else
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||||
|
|
||||||
|
@property (readonly, strong) NSPersistentContainer *persistentContainer;
|
||||||
|
@property (strong, nonatomic) NSWindow *window;
|
||||||
|
#endif
|
||||||
|
|
||||||
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
|
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
|
||||||
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
|
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
static NSOperationQueue* mainQueue;
|
static NSOperationQueue* mainQueue;
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||||
{
|
{
|
||||||
[[UILabel appearance] setFont:[UIFont fontWithName:@"Roboto-Regular" size:[UIFont systemFontSize]]];
|
[[UILabel appearance] setFont:[UIFont fontWithName:@"Roboto-Regular" size:[UIFont systemFontSize]]];
|
||||||
@@ -76,6 +77,17 @@ static NSOperationQueue* mainQueue;
|
|||||||
// Saves changes in the application's managed object context before the application terminates.
|
// Saves changes in the application's managed object context before the application terminates.
|
||||||
[self saveContext];
|
[self saveContext];
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||||
|
// Insert code here to initialize your application
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)applicationWillTerminate:(NSNotification *)aNotification {
|
||||||
|
// Insert code here to tear down your application
|
||||||
|
[self saveContext];
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
- (void)saveContext
|
- (void)saveContext
|
||||||
{
|
{
|
||||||
@@ -155,7 +167,11 @@ static NSOperationQueue* mainQueue;
|
|||||||
}
|
}
|
||||||
|
|
||||||
- (NSURL*) getStoreURL {
|
- (NSURL*) getStoreURL {
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
return [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Limelight_iOS.sqlite"];
|
return [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Limelight_iOS.sqlite"];
|
||||||
|
#else
|
||||||
|
return [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"moonlight_mac.sqlite"];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -14,7 +14,8 @@
|
|||||||
|
|
||||||
@interface DataManager : NSObject
|
@interface DataManager : NSObject
|
||||||
|
|
||||||
- (void) saveSettingsWithBitrate:(NSInteger)bitrate framerate:(NSInteger)framerate height:(NSInteger)height width:(NSInteger)width onscreenControls:(NSInteger)onscreenControls;
|
- (void) saveSettingsWithBitrate:(NSInteger)bitrate framerate:(NSInteger)framerate height:(NSInteger)height width:(NSInteger)width onscreenControls:(NSInteger)onscreenControls remote:
|
||||||
|
(NSInteger)streamingRemotely;
|
||||||
|
|
||||||
- (NSArray*) getHosts;
|
- (NSArray*) getHosts;
|
||||||
- (void) updateHost:(TemporaryHost*)host;
|
- (void) updateHost:(TemporaryHost*)host;
|
||||||
|
|||||||
@@ -22,11 +22,20 @@
|
|||||||
// HACK: Avoid calling [UIApplication delegate] off the UI thread to keep
|
// HACK: Avoid calling [UIApplication delegate] off the UI thread to keep
|
||||||
// Main Thread Checker happy.
|
// Main Thread Checker happy.
|
||||||
if ([NSThread isMainThread]) {
|
if ([NSThread isMainThread]) {
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
_appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
|
_appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
|
||||||
|
#else
|
||||||
|
_appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
_appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
|
_appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
|
||||||
|
#else
|
||||||
|
_appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
|
||||||
|
#endif
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,7 +62,8 @@
|
|||||||
return uid;
|
return uid;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) saveSettingsWithBitrate:(NSInteger)bitrate framerate:(NSInteger)framerate height:(NSInteger)height width:(NSInteger)width onscreenControls:(NSInteger)onscreenControls {
|
- (void) saveSettingsWithBitrate:(NSInteger)bitrate framerate:(NSInteger)framerate height:(NSInteger)height width:(NSInteger)width onscreenControls:(NSInteger)onscreenControls remote:
|
||||||
|
(NSInteger) streamingRemotely {
|
||||||
|
|
||||||
[_managedObjectContext performBlockAndWait:^{
|
[_managedObjectContext performBlockAndWait:^{
|
||||||
Settings* settingsToSave = [self retrieveSettings];
|
Settings* settingsToSave = [self retrieveSettings];
|
||||||
@@ -63,6 +73,7 @@
|
|||||||
settingsToSave.height = [NSNumber numberWithInteger:height];
|
settingsToSave.height = [NSNumber numberWithInteger:height];
|
||||||
settingsToSave.width = [NSNumber numberWithInteger:width];
|
settingsToSave.width = [NSNumber numberWithInteger:width];
|
||||||
settingsToSave.onscreenControls = [NSNumber numberWithInteger:onscreenControls];
|
settingsToSave.onscreenControls = [NSNumber numberWithInteger:onscreenControls];
|
||||||
|
settingsToSave.streamingRemotely = [NSNumber numberWithInteger:streamingRemotely];
|
||||||
|
|
||||||
[self saveData];
|
[self saveData];
|
||||||
}];
|
}];
|
||||||
|
|||||||
@@ -18,5 +18,6 @@
|
|||||||
@property (nonatomic, retain) NSNumber * width;
|
@property (nonatomic, retain) NSNumber * width;
|
||||||
@property (nonatomic, retain) NSNumber * onscreenControls;
|
@property (nonatomic, retain) NSNumber * onscreenControls;
|
||||||
@property (nonatomic, retain) NSString * uniqueId;
|
@property (nonatomic, retain) NSString * uniqueId;
|
||||||
|
@property (nonatomic, retain) NSNumber * streamingRemotely;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -17,5 +17,6 @@
|
|||||||
@dynamic width;
|
@dynamic width;
|
||||||
@dynamic onscreenControls;
|
@dynamic onscreenControls;
|
||||||
@dynamic uniqueId;
|
@dynamic uniqueId;
|
||||||
|
@dynamic streamingRemotely;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
@property (nonatomic, retain) NSNumber * width;
|
@property (nonatomic, retain) NSNumber * width;
|
||||||
@property (nonatomic, retain) NSNumber * onscreenControls;
|
@property (nonatomic, retain) NSNumber * onscreenControls;
|
||||||
@property (nonatomic, retain) NSString * uniqueId;
|
@property (nonatomic, retain) NSString * uniqueId;
|
||||||
|
@property (nonatomic, retain) NSNumber * streamingRemotely;
|
||||||
|
|
||||||
- (id) initFromSettings:(Settings*)settings;
|
- (id) initFromSettings:(Settings*)settings;
|
||||||
|
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
self.width = settings.width;
|
self.width = settings.width;
|
||||||
self.onscreenControls = settings.onscreenControls;
|
self.onscreenControls = settings.onscreenControls;
|
||||||
self.uniqueId = settings.uniqueId;
|
self.uniqueId = settings.uniqueId;
|
||||||
|
self.streamingRemotely = settings.streamingRemotely;
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,10 @@
|
|||||||
|
|
||||||
// Swift
|
// Swift
|
||||||
#import "Moonlight-Swift.h"
|
#import "Moonlight-Swift.h"
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
#else
|
||||||
|
#import "Gamepad.h"
|
||||||
|
#endif
|
||||||
@class Controller;
|
@class Controller;
|
||||||
|
|
||||||
@class OnScreenControls;
|
@class OnScreenControls;
|
||||||
@@ -17,8 +21,16 @@
|
|||||||
@interface ControllerSupport : NSObject
|
@interface ControllerSupport : NSObject
|
||||||
|
|
||||||
-(id) init;
|
-(id) init;
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
-(void) initAutoOnScreenControlMode:(OnScreenControls*)osc;
|
-(void) initAutoOnScreenControlMode:(OnScreenControls*)osc;
|
||||||
-(void) cleanup;
|
-(void) cleanup;
|
||||||
|
-(Controller*) getOscController;
|
||||||
|
#else
|
||||||
|
-(void) assignGamepad:(struct Gamepad_device *)gamepad;
|
||||||
|
-(void) removeGamepad:(struct Gamepad_device *)gamepad;
|
||||||
|
-(NSMutableDictionary*) getControllers;
|
||||||
|
#endif
|
||||||
|
|
||||||
-(void) updateLeftStick:(Controller*)controller x:(short)x y:(short)y;
|
-(void) updateLeftStick:(Controller*)controller x:(short)x y:(short)y;
|
||||||
-(void) updateRightStick:(Controller*)controller x:(short)x y:(short)y;
|
-(void) updateRightStick:(Controller*)controller x:(short)x y:(short)y;
|
||||||
@@ -32,7 +44,6 @@
|
|||||||
-(void) clearButtonFlag:(Controller*)controller flags:(int)flags;
|
-(void) clearButtonFlag:(Controller*)controller flags:(int)flags;
|
||||||
|
|
||||||
-(void) updateFinished:(Controller*)controller;
|
-(void) updateFinished:(Controller*)controller;
|
||||||
-(Controller*) getOscController;
|
|
||||||
|
|
||||||
+(int) getConnectedGamepadMask;
|
+(int) getConnectedGamepadMask;
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,14 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "ControllerSupport.h"
|
#import "ControllerSupport.h"
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
#import "OnScreenControls.h"
|
#import "OnScreenControls.h"
|
||||||
|
#else
|
||||||
|
#import "Gamepad.h"
|
||||||
|
#import "Control.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#import "DataManager.h"
|
#import "DataManager.h"
|
||||||
#include "Limelight.h"
|
#include "Limelight.h"
|
||||||
|
|
||||||
@@ -21,17 +28,19 @@
|
|||||||
NSLock *_controllerStreamLock;
|
NSLock *_controllerStreamLock;
|
||||||
NSMutableDictionary *_controllers;
|
NSMutableDictionary *_controllers;
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
OnScreenControls *_osc;
|
OnScreenControls *_osc;
|
||||||
bool _oscEnabled;
|
|
||||||
|
|
||||||
// This controller object is shared between on-screen controls
|
// This controller object is shared between on-screen controls
|
||||||
// and player 0
|
// and player 0
|
||||||
Controller *_player0osc;
|
Controller *_player0osc;
|
||||||
|
|
||||||
char _controllerNumbers;
|
|
||||||
|
|
||||||
#define EMULATING_SELECT 0x1
|
#define EMULATING_SELECT 0x1
|
||||||
#define EMULATING_SPECIAL 0x2
|
#define EMULATING_SPECIAL 0x2
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool _oscEnabled;
|
||||||
|
char _controllerNumbers;
|
||||||
}
|
}
|
||||||
|
|
||||||
// UPDATE_BUTTON_FLAG(controller, flag, pressed)
|
// UPDATE_BUTTON_FLAG(controller, flag, pressed)
|
||||||
@@ -76,6 +85,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
-(void) handleSpecialCombosReleased:(Controller*)controller releasedButtons:(int)releasedButtons
|
-(void) handleSpecialCombosReleased:(Controller*)controller releasedButtons:(int)releasedButtons
|
||||||
{
|
{
|
||||||
if ((controller.emulatingButtonFlags & EMULATING_SELECT) &&
|
if ((controller.emulatingButtonFlags & EMULATING_SELECT) &&
|
||||||
@@ -110,21 +120,23 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
-(void) updateButtonFlags:(Controller*)controller flags:(int)flags
|
-(void) updateButtonFlags:(Controller*)controller flags:(int)flags
|
||||||
{
|
{
|
||||||
@synchronized(controller) {
|
@synchronized(controller) {
|
||||||
int releasedButtons = (controller.lastButtonFlags ^ flags) & ~flags;
|
|
||||||
int pressedButtons = (controller.lastButtonFlags ^ flags) & flags;
|
|
||||||
|
|
||||||
controller.lastButtonFlags = flags;
|
controller.lastButtonFlags = flags;
|
||||||
|
|
||||||
// This must be called before handleSpecialCombosPressed
|
// This must be called before handleSpecialCombosPressed
|
||||||
// because we clear the original button flags there
|
// because we clear the original button flags there
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
int releasedButtons = (controller.lastButtonFlags ^ flags) & ~flags;
|
||||||
|
int pressedButtons = (controller.lastButtonFlags ^ flags) & flags;
|
||||||
|
|
||||||
[self handleSpecialCombosReleased:controller releasedButtons:releasedButtons];
|
[self handleSpecialCombosReleased:controller releasedButtons:releasedButtons];
|
||||||
|
|
||||||
[self handleSpecialCombosPressed:controller pressedButtons:pressedButtons];
|
[self handleSpecialCombosPressed:controller pressedButtons:pressedButtons];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,7 +144,9 @@
|
|||||||
{
|
{
|
||||||
@synchronized(controller) {
|
@synchronized(controller) {
|
||||||
controller.lastButtonFlags |= flags;
|
controller.lastButtonFlags |= flags;
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
[self handleSpecialCombosPressed:controller pressedButtons:flags];
|
[self handleSpecialCombosPressed:controller pressedButtons:flags];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +154,9 @@
|
|||||||
{
|
{
|
||||||
@synchronized(controller) {
|
@synchronized(controller) {
|
||||||
controller.lastButtonFlags &= ~flags;
|
controller.lastButtonFlags &= ~flags;
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
[self handleSpecialCombosReleased:controller releasedButtons:flags];
|
[self handleSpecialCombosReleased:controller releasedButtons:flags];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -242,6 +258,7 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
-(void) updateAutoOnScreenControlMode
|
-(void) updateAutoOnScreenControlMode
|
||||||
{
|
{
|
||||||
// Auto on-screen control support may not be enabled
|
// Auto on-screen control support may not be enabled
|
||||||
@@ -277,6 +294,7 @@
|
|||||||
|
|
||||||
[self updateAutoOnScreenControlMode];
|
[self updateAutoOnScreenControlMode];
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
-(void) assignController:(GCController*)controller {
|
-(void) assignController:(GCController*)controller {
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
@@ -285,6 +303,7 @@
|
|||||||
controller.playerIndex = i;
|
controller.playerIndex = i;
|
||||||
|
|
||||||
Controller* limeController;
|
Controller* limeController;
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
// Player 0 shares a controller object with the on-screen controls
|
// Player 0 shares a controller object with the on-screen controls
|
||||||
limeController = _player0osc;
|
limeController = _player0osc;
|
||||||
@@ -292,6 +311,10 @@
|
|||||||
limeController = [[Controller alloc] init];
|
limeController = [[Controller alloc] init];
|
||||||
limeController.playerIndex = i;
|
limeController.playerIndex = i;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
limeController = [[Controller alloc] init];
|
||||||
|
limeController.playerIndex = i;
|
||||||
|
#endif
|
||||||
|
|
||||||
[_controllers setObject:limeController forKey:[NSNumber numberWithInteger:controller.playerIndex]];
|
[_controllers setObject:limeController forKey:[NSNumber numberWithInteger:controller.playerIndex]];
|
||||||
|
|
||||||
@@ -301,9 +324,40 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
-(Controller*) getOscController {
|
-(Controller*) getOscController {
|
||||||
return _player0osc;
|
return _player0osc;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
-(NSMutableDictionary*) getControllers {
|
||||||
|
return _controllers;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) assignGamepad:(struct Gamepad_device *)gamepad {
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if (!(_controllerNumbers & (1 << i))) {
|
||||||
|
_controllerNumbers |= (1 << i);
|
||||||
|
gamepad->deviceID = i;
|
||||||
|
NSLog(@"Gamepad device id: %u assigned", gamepad->deviceID);
|
||||||
|
Controller* limeController;
|
||||||
|
limeController = [[Controller alloc] init];
|
||||||
|
limeController.playerIndex = i;
|
||||||
|
|
||||||
|
[_controllers setObject:limeController forKey:[NSNumber numberWithInteger:i]];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) removeGamepad:(struct Gamepad_device *)gamepad {
|
||||||
|
_controllerNumbers &= ~(1 << gamepad->deviceID);
|
||||||
|
Log(LOG_I, @"Unassigning controller index: %ld", (long)gamepad->deviceID);
|
||||||
|
|
||||||
|
// Inform the server of the updated active gamepads before removing this controller
|
||||||
|
[self updateFinished:[_controllers objectForKey:[NSNumber numberWithInteger:gamepad->deviceID]]];
|
||||||
|
[_controllers removeObjectForKey:[NSNumber numberWithInteger:gamepad->deviceID]];
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
+(int) getConnectedGamepadMask {
|
+(int) getConnectedGamepadMask {
|
||||||
int mask = 0;
|
int mask = 0;
|
||||||
@@ -312,6 +366,7 @@
|
|||||||
mask |= 1 << i;
|
mask |= 1 << i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
DataManager* dataMan = [[DataManager alloc] init];
|
DataManager* dataMan = [[DataManager alloc] init];
|
||||||
OnScreenControlsLevel level = (OnScreenControlsLevel)[[dataMan getSettings].onscreenControls integerValue];
|
OnScreenControlsLevel level = (OnScreenControlsLevel)[[dataMan getSettings].onscreenControls integerValue];
|
||||||
|
|
||||||
@@ -320,7 +375,7 @@
|
|||||||
if (level != OnScreenControlsLevelOff) {
|
if (level != OnScreenControlsLevelOff) {
|
||||||
mask |= 1;
|
mask |= 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
return mask;
|
return mask;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -331,17 +386,27 @@
|
|||||||
_controllerStreamLock = [[NSLock alloc] init];
|
_controllerStreamLock = [[NSLock alloc] init];
|
||||||
_controllers = [[NSMutableDictionary alloc] init];
|
_controllers = [[NSMutableDictionary alloc] init];
|
||||||
_controllerNumbers = 0;
|
_controllerNumbers = 0;
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
_player0osc = [[Controller alloc] init];
|
_player0osc = [[Controller alloc] init];
|
||||||
_player0osc.playerIndex = 0;
|
_player0osc.playerIndex = 0;
|
||||||
|
|
||||||
DataManager* dataMan = [[DataManager alloc] init];
|
DataManager* dataMan = [[DataManager alloc] init];
|
||||||
_oscEnabled = (OnScreenControlsLevel)[[dataMan getSettings].onscreenControls integerValue] != OnScreenControlsLevelOff;
|
_oscEnabled = (OnScreenControlsLevel)[[dataMan getSettings].onscreenControls integerValue] != OnScreenControlsLevelOff;
|
||||||
|
#else
|
||||||
|
_oscEnabled = false;
|
||||||
|
initGamepad(self);
|
||||||
|
Gamepad_detectDevices();
|
||||||
|
#endif
|
||||||
|
|
||||||
Log(LOG_I, @"Number of controllers connected: %ld", (long)[[GCController controllers] count]);
|
Log(LOG_I, @"Number of controllers connected: %ld", (long)[[GCController controllers] count]);
|
||||||
for (GCController* controller in [GCController controllers]) {
|
for (GCController* controller in [GCController controllers]) {
|
||||||
[self assignController:controller];
|
[self assignController:controller];
|
||||||
[self registerControllerCallbacks:controller];
|
[self registerControllerCallbacks:controller];
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
[self updateAutoOnScreenControlMode];
|
[self updateAutoOnScreenControlMode];
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
self.connectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
self.connectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||||
@@ -353,8 +418,10 @@
|
|||||||
// Register callbacks on the new controller
|
// Register callbacks on the new controller
|
||||||
[self registerControllerCallbacks:controller];
|
[self registerControllerCallbacks:controller];
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
// Re-evaluate the on-screen control mode
|
// Re-evaluate the on-screen control mode
|
||||||
[self updateAutoOnScreenControlMode];
|
[self updateAutoOnScreenControlMode];
|
||||||
|
#endif
|
||||||
}];
|
}];
|
||||||
self.disconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
self.disconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||||
Log(LOG_I, @"Controller disconnected!");
|
Log(LOG_I, @"Controller disconnected!");
|
||||||
@@ -368,10 +435,11 @@
|
|||||||
[self updateFinished:[_controllers objectForKey:[NSNumber numberWithInteger:controller.playerIndex]]];
|
[self updateFinished:[_controllers objectForKey:[NSNumber numberWithInteger:controller.playerIndex]]];
|
||||||
[_controllers removeObjectForKey:[NSNumber numberWithInteger:controller.playerIndex]];
|
[_controllers removeObjectForKey:[NSNumber numberWithInteger:controller.playerIndex]];
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
// Re-evaluate the on-screen control mode
|
// Re-evaluate the on-screen control mode
|
||||||
[self updateAutoOnScreenControlMode];
|
[self updateAutoOnScreenControlMode];
|
||||||
|
#endif
|
||||||
}];
|
}];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,8 @@
|
|||||||
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
// Copyright (c) 2014 Moonlight Stream. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#import <UIKit/UIKit.h>
|
// This is redundant, as it is part of the prefix header
|
||||||
|
//#import <UIKit/UIKit.h>
|
||||||
#import "ControllerSupport.h"
|
#import "ControllerSupport.h"
|
||||||
|
|
||||||
@protocol EdgeDetectionDelegate <NSObject>
|
@protocol EdgeDetectionDelegate <NSObject>
|
||||||
|
|||||||
@@ -5,13 +5,19 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import <Availability.h>
|
#import <Availability.h>
|
||||||
|
#include <TargetConditionals.h>
|
||||||
|
|
||||||
#ifndef __IPHONE_3_0
|
#ifndef __IPHONE_3_0
|
||||||
#warning "This project uses features only available in iOS SDK 3.0 and later."
|
#warning "This project uses features only available in iOS SDK 3.0 and later."
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __OBJC__
|
#ifdef __OBJC__
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
#import <UIKit/UIKit.h>
|
#import <UIKit/UIKit.h>
|
||||||
|
#elif TARGET_OS_MAC
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
#endif
|
||||||
#import <Foundation/Foundation.h>
|
#import <Foundation/Foundation.h>
|
||||||
#import <CoreData/CoreData.h>
|
#import <CoreData/CoreData.h>
|
||||||
#import "Logger.h"
|
#import "Logger.h"
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||||
<model userDefinedModelVersionIdentifier="" type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="9057" systemVersion="15B42" minimumToolsVersion="Automatic">
|
<model type="com.apple.IDECoreDataModeler.DataModel" documentVersion="1.0" lastSavedToolsVersion="13772" systemVersion="17D102" minimumToolsVersion="Xcode 7.3" sourceLanguage="Objective-C" userDefinedModelVersionIdentifier="">
|
||||||
<entity name="App" representedClassName="App" syncable="YES">
|
<entity name="App" representedClassName="App" syncable="YES">
|
||||||
<attribute name="id" attributeType="String" syncable="YES"/>
|
<attribute name="id" attributeType="String" syncable="YES"/>
|
||||||
<attribute name="image" optional="YES" attributeType="Binary" allowsExternalBinaryDataStorage="YES" syncable="YES"/>
|
<attribute name="image" optional="YES" attributeType="Binary" allowsExternalBinaryDataStorage="YES" syncable="YES"/>
|
||||||
@@ -12,21 +12,22 @@
|
|||||||
<attribute name="localAddress" optional="YES" attributeType="String" syncable="YES"/>
|
<attribute name="localAddress" optional="YES" attributeType="String" syncable="YES"/>
|
||||||
<attribute name="mac" optional="YES" attributeType="String" syncable="YES"/>
|
<attribute name="mac" optional="YES" attributeType="String" syncable="YES"/>
|
||||||
<attribute name="name" attributeType="String" syncable="YES"/>
|
<attribute name="name" attributeType="String" syncable="YES"/>
|
||||||
<attribute name="pairState" optional="YES" attributeType="Integer 32" defaultValueString="0" syncable="YES"/>
|
<attribute name="pairState" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="uuid" optional="YES" attributeType="String" syncable="YES"/>
|
<attribute name="uuid" optional="YES" attributeType="String" syncable="YES"/>
|
||||||
<relationship name="appList" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="App" inverseName="host" inverseEntity="App" syncable="YES"/>
|
<relationship name="appList" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="App" inverseName="host" inverseEntity="App" syncable="YES"/>
|
||||||
</entity>
|
</entity>
|
||||||
<entity name="Settings" representedClassName="Settings" syncable="YES">
|
<entity name="Settings" representedClassName="Settings" syncable="YES">
|
||||||
<attribute name="bitrate" attributeType="Integer 32" defaultValueString="10000" syncable="YES"/>
|
<attribute name="bitrate" attributeType="Integer 32" defaultValueString="10000" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="framerate" attributeType="Integer 32" defaultValueString="60" syncable="YES"/>
|
<attribute name="framerate" attributeType="Integer 32" defaultValueString="60" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="height" attributeType="Integer 32" defaultValueString="720" syncable="YES"/>
|
<attribute name="height" attributeType="Integer 32" defaultValueString="720" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" syncable="YES"/>
|
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" usesScalarValueType="NO" syncable="YES"/>
|
||||||
|
<attribute name="streamingRemotely" optional="YES" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="NO" syncable="YES"/>
|
||||||
<attribute name="uniqueId" attributeType="String" syncable="YES"/>
|
<attribute name="uniqueId" attributeType="String" syncable="YES"/>
|
||||||
<attribute name="width" attributeType="Integer 32" defaultValueString="1280" syncable="YES"/>
|
<attribute name="width" attributeType="Integer 32" defaultValueString="1280" usesScalarValueType="NO" syncable="YES"/>
|
||||||
</entity>
|
</entity>
|
||||||
<elements>
|
<elements>
|
||||||
<element name="App" positionX="0" positionY="54" width="128" height="105"/>
|
<element name="App" positionX="0" positionY="54" width="128" height="105"/>
|
||||||
<element name="Host" positionX="0" positionY="0" width="128" height="163"/>
|
<element name="Host" positionX="0" positionY="0" width="128" height="163"/>
|
||||||
<element name="Settings" positionX="0" positionY="0" width="128" height="135"/>
|
<element name="Settings" positionX="0" positionY="0" width="128" height="150"/>
|
||||||
</elements>
|
</elements>
|
||||||
</model>
|
</model>
|
||||||
@@ -16,10 +16,16 @@
|
|||||||
self.statusMessage = @"App asset has no status message";
|
self.statusMessage = @"App asset has no status message";
|
||||||
self.statusCode = -1;
|
self.statusCode = -1;
|
||||||
}
|
}
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
- (UIImage*) getImage {
|
- (UIImage*) getImage {
|
||||||
UIImage* appImage = [[UIImage alloc] initWithData:self.data];
|
UIImage* appImage = [[UIImage alloc] initWithData:self.data];
|
||||||
return appImage;
|
return appImage;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
- (NSImage*) getImage {
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -18,7 +18,13 @@ static const double RETRY_DELAY = 2; // seconds
|
|||||||
static const int MAX_ATTEMPTS = 5;
|
static const int MAX_ATTEMPTS = 5;
|
||||||
|
|
||||||
- (void) main {
|
- (void) main {
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
UIImage* appImage = nil;
|
UIImage* appImage = nil;
|
||||||
|
#else
|
||||||
|
NSImage* appImage = nil;
|
||||||
|
#endif
|
||||||
|
|
||||||
int attempts = 0;
|
int attempts = 0;
|
||||||
while (![self isCancelled] && appImage == nil && attempts++ < MAX_ATTEMPTS) {
|
while (![self isCancelled] && appImage == nil && attempts++ < MAX_ATTEMPTS) {
|
||||||
|
|
||||||
@@ -26,8 +32,13 @@ static const int MAX_ATTEMPTS = 5;
|
|||||||
AppAssetResponse* appAssetResp = [[AppAssetResponse alloc] init];
|
AppAssetResponse* appAssetResp = [[AppAssetResponse alloc] init];
|
||||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:appAssetResp withUrlRequest:[hMan newAppAssetRequestWithAppId:self.app.id]]];
|
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:appAssetResp withUrlRequest:[hMan newAppAssetRequestWithAppId:self.app.id]]];
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
appImage = [UIImage imageWithData:appAssetResp.data];
|
appImage = [UIImage imageWithData:appAssetResp.data];
|
||||||
self.app.image = UIImagePNGRepresentation(appImage);
|
self.app.image = UIImagePNGRepresentation(appImage);
|
||||||
|
#else
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
if (![self isCancelled] && appImage == nil) {
|
if (![self isCancelled] && appImage == nil) {
|
||||||
[NSThread sleepForTimeInterval:RETRY_DELAY];
|
[NSThread sleepForTimeInterval:RETRY_DELAY];
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// ConnectionHelper.h
|
||||||
|
// Moonlight macOS
|
||||||
|
//
|
||||||
|
// Created by Felix on 22.03.18.
|
||||||
|
// Copyright © 2018 Felix. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "AppListResponse.h"
|
||||||
|
|
||||||
|
#ifndef ConnectionHelper_h
|
||||||
|
#define ConnectionHelper_h
|
||||||
|
|
||||||
|
|
||||||
|
@interface ConnectionHelper : NSObject
|
||||||
|
|
||||||
|
+(AppListResponse*) getAppListForHostWithHostIP:(NSString*) hostIP deviceName:(NSString*)deviceName cert:(NSData*) cert uniqueID:(NSString*) uniqueId;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif /* ConnectionHelper_h */
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
//
|
||||||
|
// ConnectionHelper.m
|
||||||
|
// Moonlight macOS
|
||||||
|
//
|
||||||
|
// Created by Felix on 22.03.18.
|
||||||
|
// Copyright © 2018 Felix. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "ConnectionHelper.h"
|
||||||
|
#import "ServerInfoResponse.h"
|
||||||
|
#import "HttpManager.h"
|
||||||
|
#import "PairManager.h"
|
||||||
|
#import "DiscoveryManager.h"
|
||||||
|
|
||||||
|
@implementation ConnectionHelper
|
||||||
|
|
||||||
|
+(AppListResponse*) getAppListForHostWithHostIP:(NSString*) hostIP deviceName:(NSString*)deviceName cert:(NSData*) cert uniqueID:(NSString*) uniqueId {
|
||||||
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:hostIP uniqueId:uniqueId deviceName:deviceName cert:cert];
|
||||||
|
|
||||||
|
// Try up to 5 times to get the app list
|
||||||
|
AppListResponse* appListResp;
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
|
appListResp = [[AppListResponse alloc] init];
|
||||||
|
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:appListResp withUrlRequest:[hMan newAppListRequest]]];
|
||||||
|
if (appListResp == nil || ![appListResp isStatusOk] || [appListResp getAppList] == nil) {
|
||||||
|
Log(LOG_W, @"Failed to get applist on try %d: %@", i, appListResp.statusMessage);
|
||||||
|
|
||||||
|
// Wait for one second then retry
|
||||||
|
[NSThread sleepForTimeInterval:1];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Log(LOG_I, @"App list successfully retreived - took %d tries", i);
|
||||||
|
return appListResp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@@ -97,6 +97,8 @@ int ArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, v
|
|||||||
|
|
||||||
audioLock = [[NSLock alloc] init];
|
audioLock = [[NSLock alloc] init];
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
|
|
||||||
// Configure the audio session for our app
|
// Configure the audio session for our app
|
||||||
NSError *audioSessionError = nil;
|
NSError *audioSessionError = nil;
|
||||||
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
|
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
|
||||||
@@ -107,11 +109,14 @@ int ArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, v
|
|||||||
[audioSession setPreferredIOBufferDuration:0.005 error:&audioSessionError];
|
[audioSession setPreferredIOBufferDuration:0.005 error:&audioSessionError];
|
||||||
[audioSession setActive: YES error: &audioSessionError];
|
[audioSession setActive: YES error: &audioSessionError];
|
||||||
|
|
||||||
|
#endif
|
||||||
OSStatus status;
|
OSStatus status;
|
||||||
|
|
||||||
AudioComponentDescription audioDesc;
|
AudioComponentDescription audioDesc;
|
||||||
audioDesc.componentType = kAudioUnitType_Output;
|
audioDesc.componentType = kAudioUnitType_Output;
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
audioDesc.componentSubType = kAudioUnitSubType_RemoteIO;
|
audioDesc.componentSubType = kAudioUnitSubType_RemoteIO;
|
||||||
|
#endif
|
||||||
audioDesc.componentFlags = 0;
|
audioDesc.componentFlags = 0;
|
||||||
audioDesc.componentFlagsMask = 0;
|
audioDesc.componentFlagsMask = 0;
|
||||||
audioDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
audioDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||||
@@ -191,11 +196,11 @@ void ArCleanup(void)
|
|||||||
if (status) {
|
if (status) {
|
||||||
Log(LOG_E, @"Unable to uninitialize audioUnit: %d", (int32_t)status);
|
Log(LOG_E, @"Unable to uninitialize audioUnit: %d", (int32_t)status);
|
||||||
}
|
}
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
// Audio session is now inactive
|
// Audio session is now inactive
|
||||||
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
|
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
|
||||||
[audioSession setActive: YES error: nil];
|
[audioSession setActive: YES error: nil];
|
||||||
|
#endif
|
||||||
// This is safe because we're guaranteed that nobody
|
// This is safe because we're guaranteed that nobody
|
||||||
// is touching this list now
|
// is touching this list now
|
||||||
struct AUDIO_BUFFER_QUEUE_ENTRY *entry;
|
struct AUDIO_BUFFER_QUEUE_ENTRY *entry;
|
||||||
@@ -333,22 +338,40 @@ void ClLogMessage(const char* format, ...)
|
|||||||
_streamConfig.fps = config.frameRate;
|
_streamConfig.fps = config.frameRate;
|
||||||
_streamConfig.bitrate = config.bitRate;
|
_streamConfig.bitrate = config.bitRate;
|
||||||
|
|
||||||
|
// This will activate the remote streaming optimization in moonlight-common if needed
|
||||||
|
_streamConfig.streamingRemotely = config.streamingRemotely;
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
// On iOS 11, we can use HEVC if the server supports encoding it
|
// On iOS 11, we can use HEVC if the server supports encoding it
|
||||||
// and this device has hardware decode for it (A9 and later)
|
// and this device has hardware decode for it (A9 and later)
|
||||||
if (@available(iOS 11.0, *)) {
|
if (@available(iOS 11.0, *)) {
|
||||||
// FIXME: Disabled due to incompatibility with iPhone X causing video
|
// FIXME: Disabled due to incompatibility with iPhone X causing video
|
||||||
// to freeze. Additionally, RFI is not supported so packet loss recovery
|
// to freeze. Additionally, RFI is not supported so packet loss recovery
|
||||||
// is worse with HEVC than H.264.
|
// is worse with HEVC than H.264.
|
||||||
|
|
||||||
|
// Streaming with a limited bandwith will result in better quality with HEVC
|
||||||
//_streamConfig.supportsHevc = VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC);
|
//_streamConfig.supportsHevc = VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC);
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (@available(macOS 10.13, *)) {
|
||||||
|
if (VTIsHardwareDecodeSupported(kCMVideoCodecType_HEVC) || _streamConfig.streamingRemotely != 0)
|
||||||
|
_streamConfig.supportsHevc = true;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Use some of the HEVC encoding efficiency improvements to
|
// Use some of the HEVC encoding efficiency improvements to
|
||||||
// reduce bandwidth usage while still gaining some image
|
// reduce bandwidth usage while still gaining some image
|
||||||
// quality improvement.
|
// quality improvement.
|
||||||
_streamConfig.hevcBitratePercentageMultiplier = 75;
|
if (config.streamingRemotely) {
|
||||||
|
// In the case of remotely streaming, we want the best possible qualtity for a limited bandwidth, so we set the multiplier to 0
|
||||||
// FIXME: We should use 1024 when streaming remotely
|
_streamConfig.hevcBitratePercentageMultiplier = 0;
|
||||||
_streamConfig.packetSize = 1292;
|
// When streaming remotely we want to use a packet size of 1024
|
||||||
|
_streamConfig.packetSize = 1024;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_streamConfig.hevcBitratePercentageMultiplier = 75;
|
||||||
|
_streamConfig.packetSize = 1292;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(_streamConfig.remoteInputAesKey, [config.riKey bytes], [config.riKey length]);
|
memcpy(_streamConfig.remoteInputAesKey, [config.riKey bytes], [config.riKey length]);
|
||||||
memset(_streamConfig.remoteInputAesIv, 0, 16);
|
memset(_streamConfig.remoteInputAesIv, 0, 16);
|
||||||
@@ -360,6 +383,7 @@ void ClLogMessage(const char* format, ...)
|
|||||||
_drCallbacks.submitDecodeUnit = DrSubmitDecodeUnit;
|
_drCallbacks.submitDecodeUnit = DrSubmitDecodeUnit;
|
||||||
|
|
||||||
// RFI doesn't work properly with HEVC on iOS 11 with an iPhone SE (at least)
|
// RFI doesn't work properly with HEVC on iOS 11 with an iPhone SE (at least)
|
||||||
|
// It doesnt work on macOS either, tested with Network Link Conditioner.
|
||||||
_drCallbacks.capabilities = CAPABILITY_REFERENCE_FRAME_INVALIDATION_AVC;
|
_drCallbacks.capabilities = CAPABILITY_REFERENCE_FRAME_INVALIDATION_AVC;
|
||||||
|
|
||||||
LiInitializeAudioCallbacks(&_arCallbacks);
|
LiInitializeAudioCallbacks(&_arCallbacks);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@
|
|||||||
@property int frameRate;
|
@property int frameRate;
|
||||||
@property int bitRate;
|
@property int bitRate;
|
||||||
@property int riKeyId;
|
@property int riKeyId;
|
||||||
|
@property int streamingRemotely;
|
||||||
@property NSData* riKey;
|
@property NSData* riKey;
|
||||||
@property int gamepadMask;
|
@property int gamepadMask;
|
||||||
|
|
||||||
|
|||||||
@@ -9,5 +9,5 @@
|
|||||||
#import "StreamConfiguration.h"
|
#import "StreamConfiguration.h"
|
||||||
|
|
||||||
@implementation StreamConfiguration
|
@implementation StreamConfiguration
|
||||||
@synthesize host, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask;
|
@synthesize host, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, streamingRemotely;
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -12,7 +12,12 @@
|
|||||||
|
|
||||||
@interface StreamManager : NSOperation
|
@interface StreamManager : NSOperation
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
- (id) initWithConfig:(StreamConfiguration*)config renderView:(UIView*)view connectionCallbacks:(id<ConnectionCallbacks>)callback;
|
- (id) initWithConfig:(StreamConfiguration*)config renderView:(UIView*)view connectionCallbacks:(id<ConnectionCallbacks>)callback;
|
||||||
|
#else
|
||||||
|
- (id) initWithConfig:(StreamConfiguration*)config renderView:(NSView*)view connectionCallbacks:(id<ConnectionCallbacks>)callback;
|
||||||
|
#endif
|
||||||
|
|
||||||
- (void) stopStream;
|
- (void) stopStream;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -10,7 +10,11 @@
|
|||||||
#import "CryptoManager.h"
|
#import "CryptoManager.h"
|
||||||
#import "HttpManager.h"
|
#import "HttpManager.h"
|
||||||
#import "Utils.h"
|
#import "Utils.h"
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
#import "OnScreenControls.h"
|
#import "OnScreenControls.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#import "StreamView.h"
|
#import "StreamView.h"
|
||||||
#import "ServerInfoResponse.h"
|
#import "ServerInfoResponse.h"
|
||||||
#import "HttpResponse.h"
|
#import "HttpResponse.h"
|
||||||
@@ -19,11 +23,17 @@
|
|||||||
|
|
||||||
@implementation StreamManager {
|
@implementation StreamManager {
|
||||||
StreamConfiguration* _config;
|
StreamConfiguration* _config;
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
UIView* _renderView;
|
UIView* _renderView;
|
||||||
|
#else
|
||||||
|
NSView* _renderView;
|
||||||
|
#endif
|
||||||
id<ConnectionCallbacks> _callbacks;
|
id<ConnectionCallbacks> _callbacks;
|
||||||
Connection* _connection;
|
Connection* _connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
- (id) initWithConfig:(StreamConfiguration*)config renderView:(UIView*)view connectionCallbacks:(id<ConnectionCallbacks>)callbacks {
|
- (id) initWithConfig:(StreamConfiguration*)config renderView:(UIView*)view connectionCallbacks:(id<ConnectionCallbacks>)callbacks {
|
||||||
self = [super init];
|
self = [super init];
|
||||||
_config = config;
|
_config = config;
|
||||||
@@ -33,7 +43,17 @@
|
|||||||
_config.riKeyId = arc4random();
|
_config.riKeyId = arc4random();
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
- (id) initWithConfig:(StreamConfiguration*)config renderView:(NSView*)view connectionCallbacks:(id<ConnectionCallbacks>)callbacks {
|
||||||
|
self = [super init];
|
||||||
|
_config = config;
|
||||||
|
_renderView = view;
|
||||||
|
_callbacks = callbacks;
|
||||||
|
_config.riKey = [Utils randomBytes:16];
|
||||||
|
_config.riKeyId = arc4random();
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
- (void)main {
|
- (void)main {
|
||||||
[CryptoManager generateKeyPairUsingSSl];
|
[CryptoManager generateKeyPairUsingSSl];
|
||||||
@@ -42,7 +62,7 @@
|
|||||||
|
|
||||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_config.host
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:_config.host
|
||||||
uniqueId:uniqueId
|
uniqueId:uniqueId
|
||||||
deviceName:@"roth"
|
deviceName:deviceName
|
||||||
cert:cert];
|
cert:cert];
|
||||||
|
|
||||||
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
||||||
@@ -76,13 +96,14 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
// Set mouse delta factors from the screen resolution and stream size
|
// Set mouse delta factors from the screen resolution and stream size
|
||||||
CGFloat screenScale = [[UIScreen mainScreen] scale];
|
CGFloat screenScale = [[UIScreen mainScreen] scale];
|
||||||
CGRect screenBounds = [[UIScreen mainScreen] bounds];
|
CGRect screenBounds = [[UIScreen mainScreen] bounds];
|
||||||
CGSize screenSize = CGSizeMake(screenBounds.size.width * screenScale, screenBounds.size.height * screenScale);
|
CGSize screenSize = CGSizeMake(screenBounds.size.width * screenScale, screenBounds.size.height * screenScale);
|
||||||
[((StreamView*)_renderView) setMouseDeltaFactors:_config.width / screenSize.width
|
[((StreamView*)_renderView) setMouseDeltaFactors:_config.width / screenSize.width
|
||||||
y:_config.height / screenSize.height];
|
y:_config.height / screenSize.height];
|
||||||
|
#endif
|
||||||
// Populate the config's version fields from serverinfo
|
// Populate the config's version fields from serverinfo
|
||||||
_config.appVersion = appversion;
|
_config.appVersion = appversion;
|
||||||
_config.gfeVersion = gfeVersion;
|
_config.gfeVersion = gfeVersion;
|
||||||
|
|||||||
@@ -11,8 +11,11 @@
|
|||||||
@import AVFoundation;
|
@import AVFoundation;
|
||||||
|
|
||||||
@interface VideoDecoderRenderer : NSObject
|
@interface VideoDecoderRenderer : NSObject
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
- (id)initWithView:(UIView*)view;
|
- (id)initWithView:(UIView*)view;
|
||||||
|
#else
|
||||||
|
- (id)initWithView:(NSView*)view;
|
||||||
|
#endif
|
||||||
|
|
||||||
- (void)setupWithVideoFormat:(int)videoFormat;
|
- (void)setupWithVideoFormat:(int)videoFormat;
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,11 @@
|
|||||||
#include "Limelight.h"
|
#include "Limelight.h"
|
||||||
|
|
||||||
@implementation VideoDecoderRenderer {
|
@implementation VideoDecoderRenderer {
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
UIView *_view;
|
UIView *_view;
|
||||||
|
#else
|
||||||
|
NSView *_view;
|
||||||
|
#endif
|
||||||
|
|
||||||
AVSampleBufferDisplayLayer* displayLayer;
|
AVSampleBufferDisplayLayer* displayLayer;
|
||||||
Boolean waitingForSps, waitingForPps, waitingForVps;
|
Boolean waitingForSps, waitingForPps, waitingForVps;
|
||||||
@@ -27,7 +31,12 @@
|
|||||||
|
|
||||||
displayLayer = [[AVSampleBufferDisplayLayer alloc] init];
|
displayLayer = [[AVSampleBufferDisplayLayer alloc] init];
|
||||||
displayLayer.bounds = _view.bounds;
|
displayLayer.bounds = _view.bounds;
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
displayLayer.backgroundColor = [UIColor blackColor].CGColor;
|
displayLayer.backgroundColor = [UIColor blackColor].CGColor;
|
||||||
|
#else
|
||||||
|
displayLayer.backgroundColor = [NSColor blackColor].CGColor;
|
||||||
|
#endif
|
||||||
|
|
||||||
displayLayer.position = CGPointMake(CGRectGetMidX(_view.bounds), CGRectGetMidY(_view.bounds));
|
displayLayer.position = CGPointMake(CGRectGetMidX(_view.bounds), CGRectGetMidY(_view.bounds));
|
||||||
displayLayer.videoGravity = AVLayerVideoGravityResizeAspect;
|
displayLayer.videoGravity = AVLayerVideoGravityResizeAspect;
|
||||||
|
|
||||||
@@ -52,7 +61,7 @@
|
|||||||
formatDesc = nil;
|
formatDesc = nil;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
- (id)initWithView:(UIView*)view
|
- (id)initWithView:(UIView*)view
|
||||||
{
|
{
|
||||||
self = [super init];
|
self = [super init];
|
||||||
@@ -63,6 +72,20 @@
|
|||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
- (id)initWithView:(NSView*)view
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
|
||||||
|
_view = view;
|
||||||
|
|
||||||
|
[self reinitializeDisplayLayer];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
- (void)setupWithVideoFormat:(int)videoFormat
|
- (void)setupWithVideoFormat:(int)videoFormat
|
||||||
{
|
{
|
||||||
@@ -222,6 +245,8 @@
|
|||||||
const size_t parameterSetSizes[] = { [vpsData length], [spsData length], [ppsData length] };
|
const size_t parameterSetSizes[] = { [vpsData length], [spsData length], [ppsData length] };
|
||||||
|
|
||||||
Log(LOG_I, @"Constructing new HEVC format description");
|
Log(LOG_I, @"Constructing new HEVC format description");
|
||||||
|
|
||||||
|
#if TARGET_OS_IPHONE
|
||||||
if (@available(iOS 11.0, *)) {
|
if (@available(iOS 11.0, *)) {
|
||||||
status = CMVideoFormatDescriptionCreateFromHEVCParameterSets(kCFAllocatorDefault,
|
status = CMVideoFormatDescriptionCreateFromHEVCParameterSets(kCFAllocatorDefault,
|
||||||
3, /* count of parameter sets */
|
3, /* count of parameter sets */
|
||||||
@@ -235,6 +260,21 @@
|
|||||||
// even though we said we couldn't support it. All we can do is abort().
|
// even though we said we couldn't support it. All we can do is abort().
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
if (@available(macOS 10.13, *)) {
|
||||||
|
status = CMVideoFormatDescriptionCreateFromHEVCParameterSets(kCFAllocatorDefault,
|
||||||
|
3, /* count of parameter sets */
|
||||||
|
parameterSetPointers,
|
||||||
|
parameterSetSizes,
|
||||||
|
NAL_LENGTH_PREFIX_SIZE,
|
||||||
|
nil,
|
||||||
|
&formatDesc);
|
||||||
|
} else {
|
||||||
|
// This means Moonlight-common-c decided to give us an HEVC stream
|
||||||
|
// even though we said we couldn't support it. All we can do is abort().
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (status != noErr) {
|
if (status != noErr) {
|
||||||
Log(LOG_E, @"Failed to create HEVC format description: %d", (int)status);
|
Log(LOG_E, @"Failed to create HEVC format description: %d", (int)status);
|
||||||
|
|||||||
@@ -26,6 +26,7 @@
|
|||||||
#import "ComputerScrollView.h"
|
#import "ComputerScrollView.h"
|
||||||
#import "TemporaryApp.h"
|
#import "TemporaryApp.h"
|
||||||
#import "IdManager.h"
|
#import "IdManager.h"
|
||||||
|
#import "ConnectionHelper.h"
|
||||||
|
|
||||||
@implementation MainFrameViewController {
|
@implementation MainFrameViewController {
|
||||||
NSOperationQueue* _opQueue;
|
NSOperationQueue* _opQueue;
|
||||||
@@ -115,27 +116,10 @@ static NSMutableSet* hostList;
|
|||||||
}
|
}
|
||||||
Log(LOG_I, @"Using cached app list: %d", usingCachedAppList);
|
Log(LOG_I, @"Using cached app list: %d", usingCachedAppList);
|
||||||
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:host.activeAddress uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
|
||||||
|
|
||||||
// Exempt this host from discovery while handling the applist query
|
// Exempt this host from discovery while handling the applist query
|
||||||
[_discMan removeHostFromDiscovery:host];
|
[_discMan removeHostFromDiscovery:host];
|
||||||
|
|
||||||
// Try up to 5 times to get the app list
|
AppListResponse* appListResp = [ConnectionHelper getAppListForHostWithHostIP:host.activeAddress deviceName:deviceName cert:_cert uniqueID:_uniqueId];
|
||||||
AppListResponse* appListResp;
|
|
||||||
for (int i = 0; i < 5; i++) {
|
|
||||||
appListResp = [[AppListResponse alloc] init];
|
|
||||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:appListResp withUrlRequest:[hMan newAppListRequest]]];
|
|
||||||
if (appListResp == nil || ![appListResp isStatusOk] || [appListResp getAppList] == nil) {
|
|
||||||
Log(LOG_W, @"Failed to get applist on try %d: %@", i, appListResp.statusMessage);
|
|
||||||
|
|
||||||
// Wait for one second then retry
|
|
||||||
[NSThread sleepForTimeInterval:1];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Log(LOG_I, @"App list successfully retreived - took %d tries", i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
[_discMan addHostToDiscovery:host];
|
[_discMan addHostToDiscovery:host];
|
||||||
|
|
||||||
@@ -409,6 +393,7 @@ static NSMutableSet* hostList;
|
|||||||
_streamConfig.height = [streamSettings.height intValue];
|
_streamConfig.height = [streamSettings.height intValue];
|
||||||
_streamConfig.width = [streamSettings.width intValue];
|
_streamConfig.width = [streamSettings.width intValue];
|
||||||
_streamConfig.gamepadMask = [ControllerSupport getConnectedGamepadMask];
|
_streamConfig.gamepadMask = [ControllerSupport getConnectedGamepadMask];
|
||||||
|
_streamConfig.streamingRemotely = [streamSettings.streamingRemotely intValue];
|
||||||
|
|
||||||
[_appManager stopRetrieving];
|
[_appManager stopRetrieving];
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
@property (strong, nonatomic) IBOutlet UISegmentedControl *framerateSelector;
|
@property (strong, nonatomic) IBOutlet UISegmentedControl *framerateSelector;
|
||||||
@property (strong, nonatomic) IBOutlet UISegmentedControl *resolutionSelector;
|
@property (strong, nonatomic) IBOutlet UISegmentedControl *resolutionSelector;
|
||||||
@property (strong, nonatomic) IBOutlet UISegmentedControl *onscreenControlSelector;
|
@property (strong, nonatomic) IBOutlet UISegmentedControl *onscreenControlSelector;
|
||||||
|
@property (strong, nonatomic) IBOutlet UISegmentedControl *remoteSelector;
|
||||||
|
|
||||||
- (void) saveSettings;
|
- (void) saveSettings;
|
||||||
|
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ static NSString* bitrateFormat = @"Bitrate: %.1f Mbps";
|
|||||||
resolution = 0;
|
resolution = 0;
|
||||||
}
|
}
|
||||||
NSInteger onscreenControls = [currentSettings.onscreenControls integerValue];
|
NSInteger onscreenControls = [currentSettings.onscreenControls integerValue];
|
||||||
|
NSInteger streamingRemotely = [currentSettings.streamingRemotely integerValue];
|
||||||
|
[self.remoteSelector setSelectedSegmentIndex:streamingRemotely];
|
||||||
[self.resolutionSelector setSelectedSegmentIndex:resolution];
|
[self.resolutionSelector setSelectedSegmentIndex:resolution];
|
||||||
[self.resolutionSelector addTarget:self action:@selector(newResolutionFpsChosen) forControlEvents:UIControlEventValueChanged];
|
[self.resolutionSelector addTarget:self action:@selector(newResolutionFpsChosen) forControlEvents:UIControlEventValueChanged];
|
||||||
[self.framerateSelector setSelectedSegmentIndex:framerate];
|
[self.framerateSelector setSelectedSegmentIndex:framerate];
|
||||||
@@ -66,6 +67,11 @@ static NSString* bitrateFormat = @"Bitrate: %.1f Mbps";
|
|||||||
[self.bitrateSlider setValue:(_bitrate / BITRATE_INTERVAL) animated:YES];
|
[self.bitrateSlider setValue:(_bitrate / BITRATE_INTERVAL) animated:YES];
|
||||||
[self.bitrateSlider addTarget:self action:@selector(bitrateSliderMoved) forControlEvents:UIControlEventValueChanged];
|
[self.bitrateSlider addTarget:self action:@selector(bitrateSliderMoved) forControlEvents:UIControlEventValueChanged];
|
||||||
[self updateBitrateText];
|
[self updateBitrateText];
|
||||||
|
[self.remoteSelector addTarget:self action:@selector(remoteStreamingChanged) forControlEvents:UIControlEventValueChanged];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) remoteStreamingChanged {
|
||||||
|
// This function can be used to reconfigure the settings view to offer more remote streaming options (i.e. reduce the audio frequency to 24kHz, enable/disable the HEVC bitrate multiplier, ...)
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void) newResolutionFpsChosen {
|
- (void) newResolutionFpsChosen {
|
||||||
@@ -102,6 +108,10 @@ static NSString* bitrateFormat = @"Bitrate: %.1f Mbps";
|
|||||||
[self.bitrateLabel setText:[NSString stringWithFormat:bitrateFormat, _bitrate / 1000.]];
|
[self.bitrateLabel setText:[NSString stringWithFormat:bitrateFormat, _bitrate / 1000.]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (NSInteger) getRemoteOptions {
|
||||||
|
return [self.remoteSelector selectedSegmentIndex];
|
||||||
|
}
|
||||||
|
|
||||||
- (NSInteger) getChosenFrameRate {
|
- (NSInteger) getChosenFrameRate {
|
||||||
return [self.framerateSelector selectedSegmentIndex] == 0 ? 30 : 60;
|
return [self.framerateSelector selectedSegmentIndex] == 0 ? 30 : 60;
|
||||||
}
|
}
|
||||||
@@ -120,7 +130,9 @@ static NSString* bitrateFormat = @"Bitrate: %.1f Mbps";
|
|||||||
NSInteger height = [self getChosenStreamHeight];
|
NSInteger height = [self getChosenStreamHeight];
|
||||||
NSInteger width = [self getChosenStreamWidth];
|
NSInteger width = [self getChosenStreamWidth];
|
||||||
NSInteger onscreenControls = [self.onscreenControlSelector selectedSegmentIndex];
|
NSInteger onscreenControls = [self.onscreenControlSelector selectedSegmentIndex];
|
||||||
[dataMan saveSettingsWithBitrate:_bitrate framerate:framerate height:height width:width onscreenControls:onscreenControls];
|
NSInteger streamingRemotely = [self.remoteSelector selectedSegmentIndex];
|
||||||
|
[dataMan saveSettingsWithBitrate:_bitrate framerate:framerate height:height width:width onscreenControls:onscreenControls
|
||||||
|
remote: streamingRemotely];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)didReceiveMemoryWarning {
|
- (void)didReceiveMemoryWarning {
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Workspace
|
||||||
|
version = "1.0">
|
||||||
|
<FileRef
|
||||||
|
location = "self:Moonlight macOS.xcodeproj">
|
||||||
|
</FileRef>
|
||||||
|
</Workspace>
|
||||||
|
After Width: | Height: | Size: 113 KiB |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 67 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
@@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"size" : "16x16",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "16x icon.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "16x16",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "32x icon-1.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "32x32",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "32x icon.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "32x32",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "64x icon.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "128x128",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "128x icon.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "128x128",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "256x icon-1.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "256x256",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "256x icon.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "256x256",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "512x icon-1.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "512x512",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "512x icon.png",
|
||||||
|
"scale" : "1x"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"size" : "512x512",
|
||||||
|
"idiom" : "mac",
|
||||||
|
"filename" : "1024x icon-1.png",
|
||||||
|
"scale" : "2x"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"version" : 1,
|
||||||
|
"author" : "xcode"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>APPL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1</string>
|
||||||
|
<key>LSMinimumSystemVersion</key>
|
||||||
|
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||||
|
<key>NSAppTransportSecurity</key>
|
||||||
|
<dict>
|
||||||
|
<key>NSAllowsArbitraryLoads</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
<key>NSHighResolutionCapable</key>
|
||||||
|
<true/>
|
||||||
|
<key>NSHumanReadableCopyright</key>
|
||||||
|
<string>Copyright © 2018 Felix. All rights reserved.</string>
|
||||||
|
<key>NSMainStoryboardFile</key>
|
||||||
|
<string>Mac</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string>NSApplication</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// Control.h
|
||||||
|
// Moonlight macOS
|
||||||
|
//
|
||||||
|
// Created by Felix Kratz on 15.03.18.
|
||||||
|
// Copyright © 2018 Felix Kratz. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef Control_h
|
||||||
|
#define Control_h
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#import "ControllerSupport.h"
|
||||||
|
|
||||||
|
extern void initGamepad(ControllerSupport* controllerSupport);
|
||||||
|
|
||||||
|
#endif /* Control_h */
|
||||||
@@ -0,0 +1,218 @@
|
|||||||
|
//
|
||||||
|
// Control.m
|
||||||
|
// Moonlight macOS
|
||||||
|
//
|
||||||
|
// Created by Felix Kratz on 15.03.18.
|
||||||
|
// Copyright © 2018 Felix Kratz. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include "Gamepad.h"
|
||||||
|
#include "Control.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <math.h>
|
||||||
|
#include "Limelight.h"
|
||||||
|
|
||||||
|
#import "Moonlight-Swift.h"
|
||||||
|
@class Controller;
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#define snprintf _snprintf
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
Controller* _controller;
|
||||||
|
ControllerSupport* _controllerSupport;
|
||||||
|
NSMutableDictionary* _controllers;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SELECT,
|
||||||
|
L3,
|
||||||
|
R3,
|
||||||
|
START,
|
||||||
|
UP,
|
||||||
|
RIGHT,
|
||||||
|
DOWN,
|
||||||
|
LEFT,
|
||||||
|
LB = 10,
|
||||||
|
RB,
|
||||||
|
Y,
|
||||||
|
B,
|
||||||
|
A,
|
||||||
|
X,
|
||||||
|
} ControllerKeys;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
LEFT_X,
|
||||||
|
LEFT_Y,
|
||||||
|
RIGHT_X,
|
||||||
|
RIGHT_Y,
|
||||||
|
LT = 14,
|
||||||
|
RT,
|
||||||
|
} ControllerAxis;
|
||||||
|
|
||||||
|
|
||||||
|
void onButtonDown(struct Gamepad_device * device, unsigned int buttonID, double timestamp, void * context) {
|
||||||
|
_controller = [_controllers objectForKey:[NSNumber numberWithInteger:device->deviceID]];
|
||||||
|
switch (buttonID) {
|
||||||
|
case SELECT:
|
||||||
|
[_controllerSupport setButtonFlag:_controller flags:BACK_FLAG];
|
||||||
|
break;
|
||||||
|
case L3:
|
||||||
|
[_controllerSupport setButtonFlag:_controller flags:LS_CLK_FLAG];
|
||||||
|
break;
|
||||||
|
case R3:
|
||||||
|
[_controllerSupport setButtonFlag:_controller flags:RS_CLK_FLAG];
|
||||||
|
break;
|
||||||
|
case START:
|
||||||
|
[_controllerSupport setButtonFlag:_controller flags:PLAY_FLAG];
|
||||||
|
break;
|
||||||
|
case UP:
|
||||||
|
[_controllerSupport setButtonFlag:_controller flags:UP_FLAG];
|
||||||
|
break;
|
||||||
|
case RIGHT:
|
||||||
|
[_controllerSupport setButtonFlag:_controller flags:RIGHT_FLAG];
|
||||||
|
break;
|
||||||
|
case DOWN:
|
||||||
|
[_controllerSupport setButtonFlag:_controller flags:DOWN_FLAG];
|
||||||
|
break;
|
||||||
|
case LEFT:
|
||||||
|
[_controllerSupport setButtonFlag:_controller flags:LEFT_FLAG];
|
||||||
|
break;
|
||||||
|
case LB:
|
||||||
|
[_controllerSupport setButtonFlag:_controller flags:LB_FLAG];
|
||||||
|
break;
|
||||||
|
case RB:
|
||||||
|
[_controllerSupport setButtonFlag:_controller flags:RB_FLAG];
|
||||||
|
break;
|
||||||
|
case Y:
|
||||||
|
[_controllerSupport setButtonFlag:_controller flags:Y_FLAG];
|
||||||
|
break;
|
||||||
|
case B:
|
||||||
|
[_controllerSupport setButtonFlag:_controller flags:B_FLAG];
|
||||||
|
break;
|
||||||
|
case A:
|
||||||
|
[_controllerSupport setButtonFlag:_controller flags:A_FLAG];
|
||||||
|
break;
|
||||||
|
case X:
|
||||||
|
[_controllerSupport setButtonFlag:_controller flags:X_FLAG];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
[_controllerSupport updateFinished:_controller];
|
||||||
|
}
|
||||||
|
|
||||||
|
void onButtonUp(struct Gamepad_device * device, unsigned int buttonID, double timestamp, void * context) {
|
||||||
|
_controller = [_controllers objectForKey:[NSNumber numberWithInteger:device->deviceID]];
|
||||||
|
switch (buttonID) {
|
||||||
|
case SELECT:
|
||||||
|
[_controllerSupport clearButtonFlag:_controller flags:BACK_FLAG];
|
||||||
|
break;
|
||||||
|
case L3:
|
||||||
|
[_controllerSupport clearButtonFlag:_controller flags:LS_CLK_FLAG];
|
||||||
|
break;
|
||||||
|
case R3:
|
||||||
|
[_controllerSupport clearButtonFlag:_controller flags:RS_CLK_FLAG];
|
||||||
|
break;
|
||||||
|
case START:
|
||||||
|
[_controllerSupport clearButtonFlag:_controller flags:PLAY_FLAG];
|
||||||
|
break;
|
||||||
|
case UP:
|
||||||
|
[_controllerSupport clearButtonFlag:_controller flags:UP_FLAG];
|
||||||
|
break;
|
||||||
|
case RIGHT:
|
||||||
|
[_controllerSupport clearButtonFlag:_controller flags:RIGHT_FLAG];
|
||||||
|
break;
|
||||||
|
case DOWN:
|
||||||
|
[_controllerSupport clearButtonFlag:_controller flags:DOWN_FLAG];
|
||||||
|
break;
|
||||||
|
case LEFT:
|
||||||
|
[_controllerSupport clearButtonFlag:_controller flags:LEFT_FLAG];
|
||||||
|
break;
|
||||||
|
case LB:
|
||||||
|
[_controllerSupport clearButtonFlag:_controller flags:LB_FLAG];
|
||||||
|
break;
|
||||||
|
case RB:
|
||||||
|
[_controllerSupport clearButtonFlag:_controller flags:RB_FLAG];
|
||||||
|
break;
|
||||||
|
case Y:
|
||||||
|
[_controllerSupport clearButtonFlag:_controller flags:Y_FLAG];
|
||||||
|
break;
|
||||||
|
case B:
|
||||||
|
[_controllerSupport clearButtonFlag:_controller flags:B_FLAG];
|
||||||
|
break;
|
||||||
|
case A:
|
||||||
|
[_controllerSupport clearButtonFlag:_controller flags:A_FLAG];
|
||||||
|
break;
|
||||||
|
case X:
|
||||||
|
[_controllerSupport clearButtonFlag:_controller flags:X_FLAG];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
[_controllerSupport updateFinished:_controller];
|
||||||
|
}
|
||||||
|
|
||||||
|
void onAxisMoved(struct Gamepad_device * device, unsigned int axisID, float value, float lastValue, double timestamp, void * context) {
|
||||||
|
if (fabsf(lastValue - value) > 0.01) {
|
||||||
|
_controller = [_controllers objectForKey:[NSNumber numberWithInteger:device->deviceID]];
|
||||||
|
// The dualshock controller has much more than these axis because of the motion axis, so it
|
||||||
|
// is better to call the updateFinished in the cases, because otherwise all of these
|
||||||
|
// motion axis will also trigger an updateFinished event.
|
||||||
|
switch (axisID) {
|
||||||
|
case LEFT_X:
|
||||||
|
_controller.lastLeftStickX = value * 0X7FFE;
|
||||||
|
[_controllerSupport updateFinished:_controller];
|
||||||
|
break;
|
||||||
|
case LEFT_Y:
|
||||||
|
_controller.lastLeftStickY = -value * 0X7FFE;
|
||||||
|
[_controllerSupport updateFinished:_controller];
|
||||||
|
break;
|
||||||
|
case RIGHT_X:
|
||||||
|
_controller.lastRightStickX = value * 0X7FFE;
|
||||||
|
[_controllerSupport updateFinished:_controller];
|
||||||
|
break;
|
||||||
|
case RIGHT_Y:
|
||||||
|
_controller.lastRightStickY = -value * 0X7FFE;
|
||||||
|
[_controllerSupport updateFinished:_controller];
|
||||||
|
break;
|
||||||
|
case LT:
|
||||||
|
_controller.lastLeftTrigger = value * 0xFF;
|
||||||
|
[_controllerSupport updateFinished:_controller];
|
||||||
|
break;
|
||||||
|
case RT:
|
||||||
|
_controller.lastRightTrigger = value * 0xFF;
|
||||||
|
[_controllerSupport updateFinished:_controller];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDeviceAttached(struct Gamepad_device * device, void * context) {
|
||||||
|
[_controllerSupport assignGamepad:device];
|
||||||
|
_controllers = [_controllerSupport getControllers];
|
||||||
|
}
|
||||||
|
|
||||||
|
void onDeviceRemoved(struct Gamepad_device * device, void * context) {
|
||||||
|
[_controllerSupport removeGamepad:device];
|
||||||
|
_controllers = [_controllerSupport getControllers];
|
||||||
|
}
|
||||||
|
|
||||||
|
void initGamepad(ControllerSupport* controllerSupport) {
|
||||||
|
_controllerSupport = controllerSupport;
|
||||||
|
Gamepad_deviceAttachFunc(onDeviceAttached, NULL);
|
||||||
|
Gamepad_deviceRemoveFunc(onDeviceRemoved, NULL);
|
||||||
|
Gamepad_buttonDownFunc(onButtonDown, NULL);
|
||||||
|
Gamepad_buttonUpFunc(onButtonUp, NULL);
|
||||||
|
Gamepad_axisMoveFunc(onAxisMoved, NULL);
|
||||||
|
Gamepad_init();
|
||||||
|
_controller = [[Controller alloc] init];
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
//
|
||||||
|
// Use this file to import your target's public headers that you would like to expose to Swift.
|
||||||
|
//
|
||||||
|
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
//
|
||||||
|
// StreamView.h
|
||||||
|
// Moonlight macOS
|
||||||
|
//
|
||||||
|
// Created by Felix Kratz on 10.03.18.
|
||||||
|
// Copyright (c) 2018 Felix Kratz. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
@interface StreamView : NSView
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,114 @@
|
|||||||
|
//
|
||||||
|
// StreamView.m
|
||||||
|
// Moonlight macOS
|
||||||
|
//
|
||||||
|
// Created by Felix Kratz on 10.3.18.
|
||||||
|
// Copyright (c) 2018 Felix Kratz. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "StreamView.h"
|
||||||
|
#include <Limelight.h>
|
||||||
|
#import "DataManager.h"
|
||||||
|
#include <ApplicationServices/ApplicationServices.h>
|
||||||
|
#include "keyboardTranslation.h"
|
||||||
|
|
||||||
|
@implementation StreamView {
|
||||||
|
BOOL isDragging;
|
||||||
|
NSTrackingArea *trackingArea;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) updateTrackingAreas {
|
||||||
|
|
||||||
|
// This will be the area used to track the mouse movement
|
||||||
|
if (trackingArea != nil) {
|
||||||
|
[self removeTrackingArea:trackingArea];
|
||||||
|
}
|
||||||
|
NSTrackingAreaOptions options = (NSTrackingActiveAlways | NSTrackingInVisibleRect |
|
||||||
|
NSTrackingMouseEnteredAndExited | NSTrackingMouseMoved);
|
||||||
|
|
||||||
|
trackingArea = [[NSTrackingArea alloc] initWithRect:[self bounds]
|
||||||
|
options:options
|
||||||
|
owner:self
|
||||||
|
userInfo:nil];
|
||||||
|
[self addTrackingArea:trackingArea];
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)mouseDragged:(NSEvent *)event {
|
||||||
|
if (isDragging) {
|
||||||
|
[self mouseMoved:event];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[self mouseDown:event];
|
||||||
|
isDragging = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)rightMouseDragged:(NSEvent *)event {
|
||||||
|
if (isDragging) {
|
||||||
|
[self mouseMoved:event];
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
[self rightMouseDown:event];
|
||||||
|
isDragging = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)scrollWheel:(NSEvent *)event {
|
||||||
|
LiSendScrollEvent(event.scrollingDeltaY);
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseDown:(NSEvent *)mouseEvent {
|
||||||
|
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_LEFT);
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseUp:(NSEvent *)mouseEvent {
|
||||||
|
isDragging = false;
|
||||||
|
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_LEFT);
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)rightMouseUp:(NSEvent *)mouseEvent {
|
||||||
|
isDragging = false;
|
||||||
|
LiSendMouseButtonEvent(BUTTON_ACTION_RELEASE, BUTTON_RIGHT);
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)rightMouseDown:(NSEvent *)mouseEvent {
|
||||||
|
LiSendMouseButtonEvent(BUTTON_ACTION_PRESS, BUTTON_RIGHT);
|
||||||
|
[self setNeedsDisplay:YES];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)mouseMoved:(NSEvent *)mouseEvent {
|
||||||
|
LiSendMouseMoveEvent(mouseEvent.deltaX, mouseEvent.deltaY);
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)keyDown:(NSEvent *)event {
|
||||||
|
unsigned char keyChar = keyCharFromKeyCode(event.keyCode);
|
||||||
|
printf("DOWN: KeyCode: %hu, keyChar: %d, keyModifier: %lu \n", event.keyCode, keyChar, event.modifierFlags);
|
||||||
|
|
||||||
|
LiSendKeyboardEvent(keyChar, KEY_ACTION_DOWN, modifierFlagForKeyModifier(event.modifierFlags));
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)keyUp:(NSEvent *)event {
|
||||||
|
unsigned char keyChar = keyCharFromKeyCode(event.keyCode);
|
||||||
|
printf("UP: KeyChar: %d \n‚", keyChar);
|
||||||
|
LiSendKeyboardEvent(keyChar, KEY_ACTION_UP, modifierFlagForKeyModifier(event.modifierFlags));
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)flagsChanged:(NSEvent *)event
|
||||||
|
{
|
||||||
|
unsigned char keyChar = keyCodeFromModifierKey(event.modifierFlags);
|
||||||
|
if(keyChar) {
|
||||||
|
printf("DOWN: FlagChanged: %hhu \n", keyChar);
|
||||||
|
LiSendKeyboardEvent(keyChar, KEY_ACTION_DOWN, 0x00);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
LiSendKeyboardEvent(58, KEY_ACTION_UP, 0x00);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (BOOL)acceptsFirstResponder {
|
||||||
|
return YES;
|
||||||
|
}
|
||||||
|
@end
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>com.apple.security.app-sandbox</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.device.bluetooth</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.device.usb</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.files.user-selected.read-only</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.network.client</key>
|
||||||
|
<true/>
|
||||||
|
<key>com.apple.security.network.server</key>
|
||||||
|
<true/>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
//
|
||||||
|
// keepAlive.h
|
||||||
|
// LittleHelper
|
||||||
|
//
|
||||||
|
// Created by Felix Kratz on 31.10.17.
|
||||||
|
// Copyright © 2017 Felix Kratz. All rights reserved.
|
||||||
|
//
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#ifndef keepAlive_h
|
||||||
|
#define keepAlive_h
|
||||||
|
|
||||||
|
@interface keepAlive : NSObject
|
||||||
|
|
||||||
|
+(void) keepSystemAlive;
|
||||||
|
+(void) allowSleep;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#endif /* keepAlive_h */
|
||||||
|
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// keepAlive.m
|
||||||
|
// LittleHelper
|
||||||
|
//
|
||||||
|
// Created by Felix Kratz on 31.10.17.
|
||||||
|
// Copyright © 2017 Felix Kratz. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import <IOKit/pwr_mgt/IOPMLib.h>
|
||||||
|
#import "keepAlive.h"
|
||||||
|
|
||||||
|
|
||||||
|
@implementation keepAlive
|
||||||
|
|
||||||
|
CFStringRef reasonForActivity= CFSTR("Moonlight keeps the system awake");
|
||||||
|
IOPMAssertionID assertionID;
|
||||||
|
|
||||||
|
+(void) keepSystemAlive
|
||||||
|
{
|
||||||
|
|
||||||
|
IOPMAssertionCreateWithName(kIOPMAssertionTypeNoDisplaySleep,
|
||||||
|
kIOPMAssertionLevelOn, reasonForActivity, &assertionID);
|
||||||
|
}
|
||||||
|
|
||||||
|
+(void) allowSleep
|
||||||
|
{
|
||||||
|
IOPMAssertionRelease(assertionID);
|
||||||
|
}
|
||||||
|
@end
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// keyboardTranslation.h
|
||||||
|
// Moonlight macOS
|
||||||
|
//
|
||||||
|
// Created by Felix Kratz on 10.03.18.
|
||||||
|
// Copyright © 2018 Felix Kratz. All rights reserved.
|
||||||
|
//
|
||||||
|
#include <CoreFoundation/CoreFoundation.h>
|
||||||
|
#include <Carbon/Carbon.h>
|
||||||
|
|
||||||
|
#ifndef keyboardTranslation_h
|
||||||
|
#define keyboardTranslation_h
|
||||||
|
|
||||||
|
CGKeyCode keyCharFromKeyCode(CGKeyCode keyCode);
|
||||||
|
CGKeyCode keyCodeFromModifierKey(NSEventModifierFlags keyModifier);
|
||||||
|
char modifierFlagForKeyModifier(NSEventModifierFlags keyModifier);
|
||||||
|
|
||||||
|
#endif /* keyboardTranslation_h */
|
||||||
@@ -0,0 +1,143 @@
|
|||||||
|
//
|
||||||
|
// keyboardTranslation.m
|
||||||
|
// Moonlight macOS
|
||||||
|
//
|
||||||
|
// Created by Felix Kratz on 10.03.18.
|
||||||
|
// Copyright © 2018 Felix Kratz. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Foundation/Foundation.h>
|
||||||
|
#import "keyboardTranslation.h"
|
||||||
|
#import <Limelight.h>
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
NOKEY,
|
||||||
|
VK_BACKSPACE = 0x08,
|
||||||
|
VK_TAB = 0x09,
|
||||||
|
VK_ENTER = 0x0D,
|
||||||
|
VK_SPACE = 0x20,
|
||||||
|
VK_LEFT = 0x25,
|
||||||
|
VK_UP,
|
||||||
|
VK_RIGHT,
|
||||||
|
VK_DOWN,
|
||||||
|
VK_SHIFT = 0xA0,
|
||||||
|
VK_CTRL = 0xA2,
|
||||||
|
VK_ALT = 0xA4,
|
||||||
|
VK_COMMA = 0xBC,
|
||||||
|
VK_MINUS = 0xBD,
|
||||||
|
VK_PERIOD = 0xBE,
|
||||||
|
VK_ESC = 0x1B,
|
||||||
|
VK_F1 = 0x70,
|
||||||
|
VK_F2,
|
||||||
|
VK_F3,
|
||||||
|
VK_F4,
|
||||||
|
VK_F5,
|
||||||
|
VK_F6,
|
||||||
|
VK_F7,
|
||||||
|
VK_F8,
|
||||||
|
VK_F9,
|
||||||
|
VK_F10,
|
||||||
|
VK_F11,
|
||||||
|
VK_F12,
|
||||||
|
VK_F13,
|
||||||
|
VK_F14,
|
||||||
|
VK_F15,
|
||||||
|
VK_DEL = 0x7F,
|
||||||
|
} SpecialKeyCodes;
|
||||||
|
|
||||||
|
CGKeyCode keyCodeFromModifierKey(NSEventModifierFlags keyModifier) {
|
||||||
|
if (keyModifier & kCGEventFlagMaskShift) {
|
||||||
|
return VK_SHIFT;
|
||||||
|
}
|
||||||
|
if (keyModifier & kCGEventFlagMaskAlternate) {
|
||||||
|
return VK_ALT;
|
||||||
|
}
|
||||||
|
if (keyModifier & kCGEventFlagMaskControl) {
|
||||||
|
return VK_CTRL;
|
||||||
|
}
|
||||||
|
return NOKEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
char modifierFlagForKeyModifier(NSEventModifierFlags keyModifier) {
|
||||||
|
if (keyModifier & kCGEventFlagMaskShift) {
|
||||||
|
return MODIFIER_SHIFT;
|
||||||
|
}
|
||||||
|
if (keyModifier & kCGEventFlagMaskAlternate) {
|
||||||
|
return MODIFIER_ALT;
|
||||||
|
}
|
||||||
|
if (keyModifier & kCGEventFlagMaskControl) {
|
||||||
|
return MODIFIER_CTRL;
|
||||||
|
}
|
||||||
|
return NOKEY;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGKeyCode keyCharFromKeyCode(CGKeyCode keyCode) {
|
||||||
|
switch (keyCode) {
|
||||||
|
case kVK_ANSI_A: return 'A';
|
||||||
|
case kVK_ANSI_S: return 'S';
|
||||||
|
case kVK_ANSI_D: return 'D';
|
||||||
|
case kVK_ANSI_F: return 'F';
|
||||||
|
case kVK_ANSI_H: return 'H';
|
||||||
|
case kVK_ANSI_G: return 'G';
|
||||||
|
case kVK_ANSI_Y: return 'Y';
|
||||||
|
case kVK_ANSI_X: return 'X';
|
||||||
|
case kVK_ANSI_C: return 'C';
|
||||||
|
case kVK_ANSI_V: return 'V';
|
||||||
|
case kVK_ANSI_B: return 'B';
|
||||||
|
case kVK_ANSI_Q: return 'Q';
|
||||||
|
case kVK_ANSI_W: return 'W';
|
||||||
|
case kVK_ANSI_E: return 'E';
|
||||||
|
case kVK_ANSI_R: return 'R';
|
||||||
|
case kVK_ANSI_Z: return 'Z';
|
||||||
|
case kVK_ANSI_T: return 'T';
|
||||||
|
case kVK_ANSI_1: return '1';
|
||||||
|
case kVK_ANSI_2: return '2';
|
||||||
|
case kVK_ANSI_3: return '3';
|
||||||
|
case kVK_ANSI_4: return '4';
|
||||||
|
case kVK_ANSI_6: return '6';
|
||||||
|
case kVK_ANSI_5: return '5';
|
||||||
|
case kVK_ANSI_9: return '9';
|
||||||
|
case kVK_ANSI_7: return '7';
|
||||||
|
case kVK_ANSI_8: return '8';
|
||||||
|
case kVK_ANSI_0: return '0';
|
||||||
|
case kVK_ANSI_O: return 'O';
|
||||||
|
case kVK_ANSI_U: return 'U';
|
||||||
|
case kVK_ANSI_I: return 'I';
|
||||||
|
case kVK_ANSI_P: return 'P';
|
||||||
|
case kVK_ANSI_L: return 'L';
|
||||||
|
case kVK_ANSI_J: return 'J';
|
||||||
|
case kVK_ANSI_K: return 'K';
|
||||||
|
case kVK_ANSI_N: return 'N';
|
||||||
|
case kVK_ANSI_M: return 'M';
|
||||||
|
case kVK_Return: return VK_ENTER;
|
||||||
|
case kVK_ANSI_Period: return VK_PERIOD;
|
||||||
|
case kVK_ANSI_Comma: return VK_COMMA;
|
||||||
|
case kVK_ANSI_Minus: return VK_MINUS;
|
||||||
|
case kVK_Tab: return VK_TAB;
|
||||||
|
case kVK_Space: return VK_SPACE;
|
||||||
|
case kVK_Delete: return VK_BACKSPACE;
|
||||||
|
case kVK_Escape: return VK_ESC;
|
||||||
|
case kVK_F1: return VK_F1;
|
||||||
|
case kVK_F2: return VK_F2;
|
||||||
|
case kVK_F3: return VK_F3;
|
||||||
|
case kVK_F4: return VK_F4;
|
||||||
|
case kVK_F5: return VK_F5;
|
||||||
|
case kVK_F6: return VK_F6;
|
||||||
|
case kVK_F7: return VK_F7;
|
||||||
|
case kVK_F8: return VK_F8;
|
||||||
|
case kVK_F9: return VK_F9;
|
||||||
|
case kVK_F10: return VK_F10;
|
||||||
|
case kVK_F11: return VK_F11;
|
||||||
|
case kVK_F12: return VK_F12;
|
||||||
|
case kVK_F13: return VK_F13;
|
||||||
|
case kVK_F14: return VK_F14;
|
||||||
|
case kVK_F15: return VK_F15;
|
||||||
|
case kVK_LeftArrow: return VK_LEFT;
|
||||||
|
case kVK_RightArrow: return VK_RIGHT;
|
||||||
|
case kVK_DownArrow: return VK_DOWN;
|
||||||
|
case kVK_UpArrow: return VK_UP;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return NOKEY;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// SettingsViewController.h
|
||||||
|
// Moonlight macOS
|
||||||
|
//
|
||||||
|
// Created by Felix Kratz on 11.03.18.
|
||||||
|
// Copyright © 2018 Felix Kratz. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
@interface SettingsViewController : NSViewController
|
||||||
|
@property (weak) IBOutlet NSTextField *textFieldResolutionHeight;
|
||||||
|
@property (weak) IBOutlet NSTextField *textFieldResolutionWidth;
|
||||||
|
@property (weak) IBOutlet NSTextField *textFieldBitrate;
|
||||||
|
@property (weak) IBOutlet NSTextField *textFieldFPS;
|
||||||
|
@property (weak) IBOutlet NSButton *buttonStreamingRemotelyToggle;
|
||||||
|
- (NSString*) getCurrentHost;
|
||||||
|
- (NSInteger) getChosenBitrate;
|
||||||
|
- (NSInteger) getChosenStreamWidth;
|
||||||
|
- (NSInteger) getChosenStreamHeight;
|
||||||
|
- (NSInteger) getChosenFrameRate;
|
||||||
|
- (NSInteger) getRemoteOptions;
|
||||||
|
@end
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
//
|
||||||
|
// SettingsViewController.m
|
||||||
|
// Moonlight macOS
|
||||||
|
//
|
||||||
|
// Created by Felix Kratz on 11.03.18.
|
||||||
|
// Copyright © 2018 Felix Kratz. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "SettingsViewController.h"
|
||||||
|
#import "DataManager.h"
|
||||||
|
|
||||||
|
@interface SettingsViewController ()
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation SettingsViewController
|
||||||
|
|
||||||
|
NSString* host;
|
||||||
|
|
||||||
|
- (void)viewDidLoad {
|
||||||
|
[super viewDidLoad];
|
||||||
|
[self loadSettings];
|
||||||
|
// Do view setup here.
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) controlTextDidChange:(NSNotification *)obj {
|
||||||
|
//[self saveSettings];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger) getRemoteOptions {
|
||||||
|
return _buttonStreamingRemotelyToggle.state == NSOnState ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger) getChosenFrameRate {
|
||||||
|
return _textFieldFPS.integerValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger) getChosenStreamHeight {
|
||||||
|
return _textFieldResolutionHeight.integerValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger) getChosenStreamWidth {
|
||||||
|
return _textFieldResolutionWidth.integerValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (NSInteger) getChosenBitrate {
|
||||||
|
return _textFieldBitrate.integerValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) loadSettings {
|
||||||
|
DataManager* dataMan = [[DataManager alloc] init];
|
||||||
|
TemporarySettings* currentSettings = [dataMan getSettings];
|
||||||
|
|
||||||
|
// Bitrate is persisted in kbps
|
||||||
|
_textFieldBitrate.integerValue = [currentSettings.bitrate integerValue];
|
||||||
|
_textFieldFPS.integerValue = [currentSettings.framerate integerValue];
|
||||||
|
_textFieldResolutionHeight.integerValue = [currentSettings.height integerValue];
|
||||||
|
_textFieldResolutionWidth.integerValue = [currentSettings.width integerValue];
|
||||||
|
_buttonStreamingRemotelyToggle.state = [currentSettings.streamingRemotely integerValue] == 0 ? NSOffState: NSOnState;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)didReceiveMemoryWarning {
|
||||||
|
// Dispose of any resources that can be recreated.
|
||||||
|
}
|
||||||
|
|
||||||
|
-(NSString*) getCurrentHost {
|
||||||
|
return host;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// StreamFrameViewController.h
|
||||||
|
// Moonlight macOS
|
||||||
|
//
|
||||||
|
// Created by Felix Kratz on 09.03.18.
|
||||||
|
// Copyright © 2018 Felix Kratz. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import "Connection.h"
|
||||||
|
#import "StreamConfiguration.h"
|
||||||
|
#import "StreamView.h"
|
||||||
|
#import "ViewController.h"
|
||||||
|
|
||||||
|
@interface StreamFrameViewController : NSViewController <ConnectionCallbacks>
|
||||||
|
|
||||||
|
- (ViewController*) _origin;
|
||||||
|
|
||||||
|
- (void)setOrigin: (ViewController*) viewController;
|
||||||
|
|
||||||
|
@property (nonatomic) StreamConfiguration* streamConfig;
|
||||||
|
@property (strong) IBOutlet StreamView *streamView;
|
||||||
|
@property (weak) IBOutlet NSProgressIndicator *progressIndicator;
|
||||||
|
@property (weak) IBOutlet NSTextField *stageLabel;
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,140 @@
|
|||||||
|
//
|
||||||
|
// StreamFrameViewController.m
|
||||||
|
// Moonlight macOS
|
||||||
|
//
|
||||||
|
// Created by Felix Kratz on 09.03.18.
|
||||||
|
// Copyright © 2018 Felix Kratz. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "StreamFrameViewController.h"
|
||||||
|
#import "VideoDecoderRenderer.h"
|
||||||
|
#import "StreamManager.h"
|
||||||
|
#import "Gamepad.h"
|
||||||
|
#import "keepAlive.h"
|
||||||
|
#import "ControllerSupport.h"
|
||||||
|
|
||||||
|
@interface StreamFrameViewController ()
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation StreamFrameViewController {
|
||||||
|
StreamManager *_streamMan;
|
||||||
|
StreamConfiguration *_streamConfig;
|
||||||
|
NSTimer* _eventTimer;
|
||||||
|
NSTimer* _searchTimer;
|
||||||
|
ViewController* _origin;
|
||||||
|
ControllerSupport* _controllerSupport;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(ViewController*) _origin {
|
||||||
|
return _origin;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewDidLoad {
|
||||||
|
[super viewDidLoad];
|
||||||
|
[keepAlive keepSystemAlive];
|
||||||
|
self.streamConfig = _streamConfig;
|
||||||
|
|
||||||
|
_streamMan = [[StreamManager alloc] initWithConfig:self.streamConfig
|
||||||
|
renderView:self.view
|
||||||
|
connectionCallbacks:self];
|
||||||
|
NSOperationQueue* opQueue = [[NSOperationQueue alloc] init];
|
||||||
|
[opQueue addOperation:_streamMan];
|
||||||
|
|
||||||
|
// Initialize the controllers (GC and IOHID)
|
||||||
|
// I have not tested it, but i think there will be a bug, when mixing GC and IOHID Controllers, because all GCControllers also register as IOHID Controllers.
|
||||||
|
// To fix this, we need to get the IOHIDDeviceRef for the GCController and compare it with every IOHID Controller.
|
||||||
|
// This shouldn't be a problem as long as this will not be put on the mac app store, as the IOHIDDeviceRef is a private field.
|
||||||
|
// The other "fix" would be to disable explicit GC support for the mac version for now.
|
||||||
|
// Can someone test this?
|
||||||
|
_controllerSupport = [[ControllerSupport alloc] init];
|
||||||
|
|
||||||
|
// The gamepad currently gets polled at 60Hz, this could very well be set as 1/Framerate in the future.
|
||||||
|
_eventTimer = [NSTimer scheduledTimerWithTimeInterval:1.0/60.0 target:self selector:@selector(eventTimerTick) userInfo:nil repeats:true];
|
||||||
|
|
||||||
|
// We search for new devices every second.
|
||||||
|
_searchTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(searchTimerTick) userInfo:nil repeats:true];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)eventTimerTick {
|
||||||
|
Gamepad_processEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)searchTimerTick {
|
||||||
|
Gamepad_detectDevices();
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) viewDidAppear {
|
||||||
|
[super viewDidAppear];
|
||||||
|
|
||||||
|
// Hide the cursor and disconnect it from the mouse movement
|
||||||
|
[NSCursor hide];
|
||||||
|
CGAssociateMouseAndMouseCursorPosition(false);
|
||||||
|
|
||||||
|
//During the setup the window should not be resizable, but to use the fullscreen feature of macOS it has to be resizable.
|
||||||
|
[self.view.window setStyleMask:[self.view.window styleMask] | NSWindowStyleMaskResizable];
|
||||||
|
|
||||||
|
if (self.view.bounds.size.height != NSScreen.mainScreen.frame.size.height || self.view.bounds.size.width != NSScreen.mainScreen.frame.size.width) {
|
||||||
|
[self.view.window toggleFullScreen:self];
|
||||||
|
}
|
||||||
|
[_progressIndicator startAnimation:nil];
|
||||||
|
[_origin dismissController:nil];
|
||||||
|
_origin = nil;
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void)viewWillDisappear {
|
||||||
|
[NSCursor unhide];
|
||||||
|
[keepAlive allowSleep];
|
||||||
|
[_streamMan stopStream];
|
||||||
|
CGAssociateMouseAndMouseCursorPosition(true);
|
||||||
|
if (self.view.bounds.size.height == NSScreen.mainScreen.frame.size.height && self.view.bounds.size.width == NSScreen.mainScreen.frame.size.width) {
|
||||||
|
[self.view.window toggleFullScreen:self];
|
||||||
|
[self.view.window setStyleMask:[self.view.window styleMask] & ~NSWindowStyleMaskResizable];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connectionStarted {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[_progressIndicator stopAnimation:nil];
|
||||||
|
_progressIndicator.hidden = true;
|
||||||
|
_stageLabel.stringValue = @"Waiting for the first frame";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)connectionTerminated:(long)errorCode {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
NSLog(@"error has occured: %ld", errorCode);
|
||||||
|
NSStoryboard *storyBoard = [NSStoryboard storyboardWithName:@"Mac" bundle:nil];
|
||||||
|
ViewController* view = (ViewController*)[storyBoard instantiateControllerWithIdentifier :@"setupFrameVC"];
|
||||||
|
[view setError:1];
|
||||||
|
self.view.window.contentViewController = view;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setOrigin: (ViewController*) viewController
|
||||||
|
{
|
||||||
|
_origin = viewController;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)displayMessage:(const char *)message {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)displayTransientMessage:(const char *)message {
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)launchFailed:(NSString *)message {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)stageComplete:(const char *)stageName {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)stageFailed:(const char *)stageName withError:(long)errorCode {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)stageStarting:(const char *)stageName {
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
//
|
||||||
|
// ViewController.h
|
||||||
|
// Moonlight macOS
|
||||||
|
//
|
||||||
|
// Created by Felix Kratz on 09.03.18.
|
||||||
|
// Copyright © 2018 Felix Kratz. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
#import <AppKit/AppKit.h>
|
||||||
|
#import "PairManager.h"
|
||||||
|
#import "StreamConfiguration.h"
|
||||||
|
|
||||||
|
@interface ViewController : NSViewController <PairCallback, NSURLConnectionDelegate>
|
||||||
|
|
||||||
|
- (IBAction)buttonLaunchPressed:(id)sender;
|
||||||
|
- (IBAction)textFieldAction:(id)sender;
|
||||||
|
- (IBAction)buttonConnectPressed:(id)sender;
|
||||||
|
- (IBAction)buttonSettingsPressed:(id)sender;
|
||||||
|
- (IBAction)popupButtonSelectionPressed:(id)sender;
|
||||||
|
|
||||||
|
- (void)setError:(long)errorCode;
|
||||||
|
- (long) error;
|
||||||
|
|
||||||
|
@property (weak) IBOutlet NSLayoutConstraint *layoutConstraintSetupFrame;
|
||||||
|
@property (weak) IBOutlet NSButton *buttonConnect;
|
||||||
|
@property (weak) IBOutlet NSTextField *textFieldHost;
|
||||||
|
@property (weak) IBOutlet NSButton *buttonSettings;
|
||||||
|
@property (weak) IBOutlet NSButton *buttonLaunch;
|
||||||
|
@property (weak) IBOutlet NSPopUpButton *popupButtonSelection;
|
||||||
|
@property (weak) IBOutlet NSView *containerViewController;
|
||||||
|
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@@ -0,0 +1,228 @@
|
|||||||
|
//
|
||||||
|
// ViewController.m
|
||||||
|
// Moonlight macOS
|
||||||
|
//
|
||||||
|
// Created by Felix Kratz on 09.03.18.
|
||||||
|
// Copyright © 2018 Felix Kratz. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "ViewController.h"
|
||||||
|
|
||||||
|
#import "CryptoManager.h"
|
||||||
|
#import "HttpManager.h"
|
||||||
|
#import "Connection.h"
|
||||||
|
#import "StreamManager.h"
|
||||||
|
#import "Utils.h"
|
||||||
|
#import "DataManager.h"
|
||||||
|
#import "TemporarySettings.h"
|
||||||
|
#import "WakeOnLanManager.h"
|
||||||
|
#import "AppListResponse.h"
|
||||||
|
#import "ServerInfoResponse.h"
|
||||||
|
#import "StreamFrameViewController.h"
|
||||||
|
#import "TemporaryApp.h"
|
||||||
|
#import "IdManager.h"
|
||||||
|
#import "SettingsViewController.h"
|
||||||
|
#import "ConnectionHelper.h"
|
||||||
|
|
||||||
|
@implementation ViewController{
|
||||||
|
NSOperationQueue* _opQueue;
|
||||||
|
TemporaryHost* _selectedHost;
|
||||||
|
NSString* _uniqueId;
|
||||||
|
NSData* _cert;
|
||||||
|
StreamConfiguration* _streamConfig;
|
||||||
|
NSArray* _sortedAppList;
|
||||||
|
NSSet* _appList;
|
||||||
|
NSString* _host;
|
||||||
|
SettingsViewController *_settingsView;
|
||||||
|
CGFloat settingsFrameHeight;
|
||||||
|
bool showSettings;
|
||||||
|
NSAlert* _alert;
|
||||||
|
long error;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (long)error {
|
||||||
|
return error;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setError:(long)errorCode {
|
||||||
|
error = errorCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)viewDidLoad {
|
||||||
|
[super viewDidLoad];
|
||||||
|
[CryptoManager generateKeyPairUsingSSl];
|
||||||
|
_uniqueId = [IdManager getUniqueId];
|
||||||
|
_cert = [CryptoManager readCertFromFile];
|
||||||
|
|
||||||
|
_opQueue = [[NSOperationQueue alloc] init];
|
||||||
|
|
||||||
|
// Do any additional setup after loading the view.
|
||||||
|
}
|
||||||
|
- (void)viewDidAppear {
|
||||||
|
[super viewDidAppear];
|
||||||
|
|
||||||
|
if (self.view.bounds.size.height == NSScreen.mainScreen.frame.size.height && self.view.bounds.size.width == NSScreen.mainScreen.frame.size.width)
|
||||||
|
{
|
||||||
|
[self.view.window toggleFullScreen:self];
|
||||||
|
[self.view.window setStyleMask:[self.view.window styleMask] & ~NSWindowStyleMaskResizable];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
[_buttonLaunch setEnabled:false];
|
||||||
|
[_popupButtonSelection removeAllItems];
|
||||||
|
_settingsView = [self.childViewControllers lastObject];
|
||||||
|
|
||||||
|
if (_settingsView.getCurrentHost != nil)
|
||||||
|
_textFieldHost.stringValue = _settingsView.getCurrentHost;
|
||||||
|
settingsFrameHeight = _layoutConstraintSetupFrame.constant;
|
||||||
|
_layoutConstraintSetupFrame.constant = 0;
|
||||||
|
showSettings = false;
|
||||||
|
|
||||||
|
if (error != 0) {
|
||||||
|
[self showAlert:[NSString stringWithFormat: @"The connection terminated."]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-(void) showAlert:(NSString*) message {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
_alert = [NSAlert new];
|
||||||
|
_alert.messageText = message;
|
||||||
|
[_alert beginSheetModalForWindow:[self.view window] completionHandler:^(NSInteger result) {
|
||||||
|
NSLog(@"Success");
|
||||||
|
}];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)setRepresentedObject:(id)representedObject {
|
||||||
|
[super setRepresentedObject:representedObject];
|
||||||
|
|
||||||
|
// Update the view, if already loaded.
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) saveSettings {
|
||||||
|
DataManager* dataMan = [[DataManager alloc] init];
|
||||||
|
NSInteger framerate = [_settingsView getChosenFrameRate];
|
||||||
|
NSInteger height = [_settingsView getChosenStreamHeight];
|
||||||
|
NSInteger width = [_settingsView getChosenStreamWidth];
|
||||||
|
NSInteger streamingRemotely = [_settingsView getRemoteOptions];
|
||||||
|
NSInteger bitrate = [_settingsView getChosenBitrate];
|
||||||
|
[dataMan saveSettingsWithBitrate:bitrate framerate:framerate height:height width:width
|
||||||
|
onscreenControls:0 remote:streamingRemotely];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
- (void)controlTextDidChange:(NSNotification *)obj {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)buttonLaunchPressed:(id)sender {
|
||||||
|
[self saveSettings];
|
||||||
|
DataManager* dataMan = [[DataManager alloc] init];
|
||||||
|
TemporarySettings* streamSettings = [dataMan getSettings];
|
||||||
|
_streamConfig = [[StreamConfiguration alloc] init];
|
||||||
|
_streamConfig.frameRate = [streamSettings.framerate intValue];
|
||||||
|
_streamConfig.bitRate = [streamSettings.bitrate intValue];
|
||||||
|
_streamConfig.height = [streamSettings.height intValue];
|
||||||
|
_streamConfig.width = [streamSettings.width intValue];
|
||||||
|
_streamConfig.streamingRemotely = [streamSettings.streamingRemotely intValue];
|
||||||
|
_streamConfig.host = _textFieldHost.stringValue;
|
||||||
|
_streamConfig.appID = [_sortedAppList[_popupButtonSelection.indexOfSelectedItem] id];
|
||||||
|
[self transitionToStreamView];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)textFieldAction:(id)sender {
|
||||||
|
[self buttonConnectPressed:self];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)buttonConnectPressed:(id)sender {
|
||||||
|
_host = _textFieldHost.stringValue;
|
||||||
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:_textFieldHost.stringValue
|
||||||
|
uniqueId:_uniqueId
|
||||||
|
deviceName:@"roth"
|
||||||
|
cert:_cert];
|
||||||
|
|
||||||
|
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
||||||
|
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:serverInfoResp withUrlRequest:[hMan newServerInfoRequest]
|
||||||
|
fallbackError:401 fallbackRequest:[hMan newHttpServerInfoRequest]]];
|
||||||
|
|
||||||
|
if ([[serverInfoResp getStringTag:@"PairStatus"] isEqualToString:@"1"]) {
|
||||||
|
NSLog(@"alreadyPaired");
|
||||||
|
[self alreadyPaired];
|
||||||
|
} else {
|
||||||
|
// Polling the server while pairing causes the server to screw up
|
||||||
|
NSLog(@"Pairing");
|
||||||
|
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
|
||||||
|
HttpManager* hMan = [[HttpManager alloc] initWithHost:_host uniqueId:_uniqueId deviceName:deviceName cert:_cert];
|
||||||
|
PairManager* pMan = [[PairManager alloc] initWithManager:hMan andCert:_cert callback:self];
|
||||||
|
[_opQueue addOperation:pMan];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)buttonSettingsPressed:(id)sender {
|
||||||
|
showSettings = !showSettings;
|
||||||
|
if(showSettings) {
|
||||||
|
_layoutConstraintSetupFrame.constant = settingsFrameHeight;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
_layoutConstraintSetupFrame.constant = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (IBAction)popupButtonSelectionPressed:(id)sender {
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)alreadyPaired {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[_popupButtonSelection setEnabled:true];
|
||||||
|
[_popupButtonSelection setHidden:false];
|
||||||
|
[_buttonConnect setEnabled:false];
|
||||||
|
[_buttonConnect setHidden:true];
|
||||||
|
[_buttonLaunch setEnabled:true];
|
||||||
|
[_textFieldHost setEnabled:false];
|
||||||
|
});
|
||||||
|
[self searchForHost:_host];
|
||||||
|
[self updateAppsForHost];
|
||||||
|
[self populatePopupButton];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)searchForHost:(NSString*) hostAddress {
|
||||||
|
_appList = [ConnectionHelper getAppListForHostWithHostIP:_textFieldHost.stringValue deviceName:deviceName cert:_cert uniqueID:_uniqueId].getAppList;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)populatePopupButton {
|
||||||
|
for (int i = 0; i < _appList.count; i++) {
|
||||||
|
[_popupButtonSelection addItemWithTitle:[_sortedAppList[i] name]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)pairFailed:(NSString *)message {
|
||||||
|
[self showAlert:[NSString stringWithFormat: @"%@", message]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)pairSuccessful {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), ^{
|
||||||
|
[self.view.window endSheet:_alert.window];
|
||||||
|
_alert = nil;
|
||||||
|
[self alreadyPaired];
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)showPIN:(NSString *)PIN {
|
||||||
|
[self showAlert:[NSString stringWithFormat: @"PIN: %@", PIN]];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void) updateAppsForHost {
|
||||||
|
_sortedAppList = [_appList allObjects];
|
||||||
|
_sortedAppList = [_sortedAppList sortedArrayUsingSelector:@selector(compareName:)];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)transitionToStreamView {
|
||||||
|
NSStoryboard *storyBoard = [NSStoryboard storyboardWithName:@"Mac" bundle:nil];
|
||||||
|
StreamFrameViewController* streamFrame = (StreamFrameViewController*)[storyBoard instantiateControllerWithIdentifier :@"streamFrameVC"];
|
||||||
|
streamFrame.streamConfig = _streamConfig;
|
||||||
|
[streamFrame setOrigin:self];
|
||||||
|
self.view.window.contentViewController = streamFrame;
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
//
|
||||||
|
// main.m
|
||||||
|
// Moonlight macOS
|
||||||
|
//
|
||||||
|
// Created by Felix on 09.03.18.
|
||||||
|
// Copyright © 2018 Felix. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <Cocoa/Cocoa.h>
|
||||||
|
|
||||||
|
int main(int argc, const char * argv[]) {
|
||||||
|
return NSApplicationMain(argc, argv);
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>BNDL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
//
|
||||||
|
// Moonlight_macOSTests.m
|
||||||
|
// Moonlight macOSTests
|
||||||
|
//
|
||||||
|
// Created by Felix on 09.03.18.
|
||||||
|
// Copyright © 2018 Felix. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <XCTest/XCTest.h>
|
||||||
|
|
||||||
|
@interface Moonlight_macOSTests : XCTestCase
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation Moonlight_macOSTests
|
||||||
|
|
||||||
|
- (void)setUp {
|
||||||
|
[super setUp];
|
||||||
|
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)tearDown {
|
||||||
|
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||||
|
[super tearDown];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testExample {
|
||||||
|
// This is an example of a functional test case.
|
||||||
|
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testPerformanceExample {
|
||||||
|
// This is an example of a performance test case.
|
||||||
|
[self measureBlock:^{
|
||||||
|
// Put the code you want to measure the time of here.
|
||||||
|
}];
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>CFBundleDevelopmentRegion</key>
|
||||||
|
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||||
|
<key>CFBundleExecutable</key>
|
||||||
|
<string>$(EXECUTABLE_NAME)</string>
|
||||||
|
<key>CFBundleIdentifier</key>
|
||||||
|
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||||
|
<key>CFBundleInfoDictionaryVersion</key>
|
||||||
|
<string>6.0</string>
|
||||||
|
<key>CFBundleName</key>
|
||||||
|
<string>$(PRODUCT_NAME)</string>
|
||||||
|
<key>CFBundlePackageType</key>
|
||||||
|
<string>BNDL</string>
|
||||||
|
<key>CFBundleShortVersionString</key>
|
||||||
|
<string>1.0</string>
|
||||||
|
<key>CFBundleVersion</key>
|
||||||
|
<string>1</string>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -0,0 +1,40 @@
|
|||||||
|
//
|
||||||
|
// Moonlight_macOSUITests.m
|
||||||
|
// Moonlight macOSUITests
|
||||||
|
//
|
||||||
|
// Created by Felix on 09.03.18.
|
||||||
|
// Copyright © 2018 Felix. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import <XCTest/XCTest.h>
|
||||||
|
|
||||||
|
@interface Moonlight_macOSUITests : XCTestCase
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation Moonlight_macOSUITests
|
||||||
|
|
||||||
|
- (void)setUp {
|
||||||
|
[super setUp];
|
||||||
|
|
||||||
|
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||||
|
|
||||||
|
// In UI tests it is usually best to stop immediately when a failure occurs.
|
||||||
|
self.continueAfterFailure = NO;
|
||||||
|
// UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
|
||||||
|
[[[XCUIApplication alloc] init] launch];
|
||||||
|
|
||||||
|
// In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)tearDown {
|
||||||
|
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||||
|
[super tearDown];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)testExample {
|
||||||
|
// Use recording to get started writing UI tests.
|
||||||
|
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
9E5D60161A5A5A3900689918 /* Roboto-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9E5D60031A5A5A3900689918 /* Roboto-Thin.ttf */; };
|
9E5D60161A5A5A3900689918 /* Roboto-Thin.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 9E5D60031A5A5A3900689918 /* Roboto-Thin.ttf */; };
|
||||||
D46A73AD1CBC7D090039F1EE /* ControllerUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D46A73AC1CBC7D090039F1EE /* ControllerUnitTests.swift */; };
|
D46A73AD1CBC7D090039F1EE /* ControllerUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D46A73AC1CBC7D090039F1EE /* ControllerUnitTests.swift */; };
|
||||||
D4746EEC1CBC740C006FB401 /* Controller.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4746EEB1CBC740C006FB401 /* Controller.swift */; };
|
D4746EEC1CBC740C006FB401 /* Controller.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4746EEB1CBC740C006FB401 /* Controller.swift */; };
|
||||||
|
DC1F5A07206436B20037755F /* ConnectionHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = DC1F5A06206436B20037755F /* ConnectionHelper.m */; };
|
||||||
FB1D59971BBCCB6400F482CA /* ComputerScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = FB1D59961BBCCB6400F482CA /* ComputerScrollView.m */; };
|
FB1D59971BBCCB6400F482CA /* ComputerScrollView.m in Sources */ = {isa = PBXBuildFile; fileRef = FB1D59961BBCCB6400F482CA /* ComputerScrollView.m */; };
|
||||||
FB1D599A1BBCCD7E00F482CA /* AppCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = FB1D59991BBCCD7E00F482CA /* AppCollectionView.m */; };
|
FB1D599A1BBCCD7E00F482CA /* AppCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = FB1D59991BBCCD7E00F482CA /* AppCollectionView.m */; };
|
||||||
FB290CF219B2C406004C83CF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290CF119B2C406004C83CF /* Foundation.framework */; };
|
FB290CF219B2C406004C83CF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FB290CF119B2C406004C83CF /* Foundation.framework */; };
|
||||||
@@ -123,6 +124,8 @@
|
|||||||
D46A73AC1CBC7D090039F1EE /* ControllerUnitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ControllerUnitTests.swift; path = Input/ControllerUnitTests.swift; sourceTree = "<group>"; };
|
D46A73AC1CBC7D090039F1EE /* ControllerUnitTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ControllerUnitTests.swift; path = Input/ControllerUnitTests.swift; sourceTree = "<group>"; };
|
||||||
D4746EEA1CBC740C006FB401 /* Moonlight-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "Moonlight-Bridging-Header.h"; path = "Input/Moonlight-Bridging-Header.h"; sourceTree = "<group>"; };
|
D4746EEA1CBC740C006FB401 /* Moonlight-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "Moonlight-Bridging-Header.h"; path = "Input/Moonlight-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||||
D4746EEB1CBC740C006FB401 /* Controller.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Controller.swift; sourceTree = "<group>"; };
|
D4746EEB1CBC740C006FB401 /* Controller.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Controller.swift; sourceTree = "<group>"; };
|
||||||
|
DC1F5A05206436B10037755F /* ConnectionHelper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ConnectionHelper.h; sourceTree = "<group>"; };
|
||||||
|
DC1F5A06206436B20037755F /* ConnectionHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ConnectionHelper.m; sourceTree = "<group>"; };
|
||||||
FB1D59951BBCCB6400F482CA /* ComputerScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ComputerScrollView.h; sourceTree = "<group>"; };
|
FB1D59951BBCCB6400F482CA /* ComputerScrollView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ComputerScrollView.h; sourceTree = "<group>"; };
|
||||||
FB1D59961BBCCB6400F482CA /* ComputerScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ComputerScrollView.m; sourceTree = "<group>"; };
|
FB1D59961BBCCB6400F482CA /* ComputerScrollView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ComputerScrollView.m; sourceTree = "<group>"; };
|
||||||
FB1D59981BBCCD7E00F482CA /* AppCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppCollectionView.h; sourceTree = "<group>"; };
|
FB1D59981BBCCD7E00F482CA /* AppCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppCollectionView.h; sourceTree = "<group>"; };
|
||||||
@@ -497,6 +500,8 @@
|
|||||||
FB89461419F646E200339C8A /* PairManager.m */,
|
FB89461419F646E200339C8A /* PairManager.m */,
|
||||||
FB4678FD1A565DAC00377732 /* WakeOnLanManager.h */,
|
FB4678FD1A565DAC00377732 /* WakeOnLanManager.h */,
|
||||||
FB4678FE1A565DAC00377732 /* WakeOnLanManager.m */,
|
FB4678FE1A565DAC00377732 /* WakeOnLanManager.m */,
|
||||||
|
DC1F5A05206436B10037755F /* ConnectionHelper.h */,
|
||||||
|
DC1F5A06206436B20037755F /* ConnectionHelper.m */,
|
||||||
);
|
);
|
||||||
path = Network;
|
path = Network;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -930,6 +935,7 @@
|
|||||||
9832D1361BBCD5C50036EF48 /* TemporaryApp.m in Sources */,
|
9832D1361BBCD5C50036EF48 /* TemporaryApp.m in Sources */,
|
||||||
98D585701C0ED0E800F6CC00 /* TemporarySettings.m in Sources */,
|
98D585701C0ED0E800F6CC00 /* TemporarySettings.m in Sources */,
|
||||||
FB89462819F646E200339C8A /* CryptoManager.m in Sources */,
|
FB89462819F646E200339C8A /* CryptoManager.m in Sources */,
|
||||||
|
DC1F5A07206436B20037755F /* ConnectionHelper.m in Sources */,
|
||||||
FB89462E19F646E200339C8A /* PairManager.m in Sources */,
|
FB89462E19F646E200339C8A /* PairManager.m in Sources */,
|
||||||
FB9AFD371A7E02DB00872C98 /* HttpRequest.m in Sources */,
|
FB9AFD371A7E02DB00872C98 /* HttpRequest.m in Sources */,
|
||||||
FB4678ED1A50C40900377732 /* OnScreenControls.m in Sources */,
|
FB4678ED1A50C40900377732 /* OnScreenControls.m in Sources */,
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="15B38b" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" initialViewController="EVd-wq-ego">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch.iPad" propertyAccessControl="none" colorMatched="YES" initialViewController="EVd-wq-ego">
|
||||||
|
<device id="ipad9_7" orientation="portrait">
|
||||||
|
<adaptation id="fullscreen"/>
|
||||||
|
</device>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="iOS"/>
|
<deployment identifier="iOS"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<customFonts key="customFonts">
|
<customFonts key="customFonts">
|
||||||
<mutableArray key="Roboto-Regular.ttf">
|
<array key="Roboto-Regular.ttf">
|
||||||
<string>Roboto-Regular</string>
|
<string>Roboto-Regular</string>
|
||||||
</mutableArray>
|
</array>
|
||||||
</customFonts>
|
</customFonts>
|
||||||
<scenes>
|
<scenes>
|
||||||
<!--Main Frame View Controller-->
|
<!--Main Frame View Controller-->
|
||||||
@@ -15,10 +19,9 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<viewController id="wb7-af-jn8" customClass="MainFrameViewController" sceneMemberID="viewController">
|
<viewController id="wb7-af-jn8" customClass="MainFrameViewController" sceneMemberID="viewController">
|
||||||
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" indicatorStyle="black" dataMode="prototypes" id="TZj-Lc-M9d" customClass="AppCollectionView">
|
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" indicatorStyle="black" dataMode="prototypes" id="TZj-Lc-M9d" customClass="AppCollectionView">
|
||||||
<rect key="frame" x="0.0" y="64" width="1024" height="704"/>
|
<rect key="frame" x="0.0" y="0.0" width="768" height="960"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<animations/>
|
<color key="backgroundColor" red="0.3333333432674408" green="0.3333333432674408" blue="0.3333333432674408" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
<inset key="contentInset" minX="40" minY="20" maxX="40" maxY="20"/>
|
<inset key="contentInset" minX="40" minY="20" maxX="40" maxY="20"/>
|
||||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="20" minimumInteritemSpacing="20" id="f7l-kG-hJc">
|
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="20" minimumInteritemSpacing="20" id="f7l-kG-hJc">
|
||||||
<size key="itemSize" width="150" height="200"/>
|
<size key="itemSize" width="150" height="200"/>
|
||||||
@@ -28,15 +31,12 @@
|
|||||||
</collectionViewFlowLayout>
|
</collectionViewFlowLayout>
|
||||||
<cells>
|
<cells>
|
||||||
<collectionViewCell clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="AppCell" id="fv6-NS-qsK">
|
<collectionViewCell clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="AppCell" id="fv6-NS-qsK">
|
||||||
<rect key="frame" x="20" y="40" width="150" height="200"/>
|
<rect key="frame" x="20" y="20" width="150" height="200"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="150" height="200"/>
|
<rect key="frame" x="0.0" y="0.0" width="150" height="200"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<animations/>
|
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
|
||||||
</view>
|
</view>
|
||||||
<animations/>
|
|
||||||
</collectionViewCell>
|
</collectionViewCell>
|
||||||
</cells>
|
</cells>
|
||||||
<connections>
|
<connections>
|
||||||
@@ -47,21 +47,19 @@
|
|||||||
<navigationItem key="navigationItem" id="pSu-bl-gL9">
|
<navigationItem key="navigationItem" id="pSu-bl-gL9">
|
||||||
<barButtonItem key="leftBarButtonItem" style="done" id="mSL-ru-nRm">
|
<barButtonItem key="leftBarButtonItem" style="done" id="mSL-ru-nRm">
|
||||||
<button key="customView" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="Tiq-VS-Ua5">
|
<button key="customView" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="Tiq-VS-Ua5">
|
||||||
<rect key="frame" x="20" y="-1" width="109" height="46"/>
|
<rect key="frame" x="20" y="0.0" width="109" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
<fontDescription key="fontDescription" name="Roboto-Regular" family="Roboto" pointSize="16"/>
|
<fontDescription key="fontDescription" name="Roboto-Regular" family="Roboto" pointSize="16"/>
|
||||||
<state key="normal" title="Moonlight" image="Logo">
|
<state key="normal" title="Moonlight" image="Logo">
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</state>
|
</state>
|
||||||
</button>
|
</button>
|
||||||
<color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</barButtonItem>
|
</barButtonItem>
|
||||||
<barButtonItem key="rightBarButtonItem" title="No Host Selected" id="KDy-JC-2sU">
|
<barButtonItem key="rightBarButtonItem" title="No Host Selected" id="KDy-JC-2sU">
|
||||||
<color key="tintColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="tintColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</barButtonItem>
|
</barButtonItem>
|
||||||
</navigationItem>
|
</navigationItem>
|
||||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="computerNameButton" destination="KDy-JC-2sU" id="Lkg-yz-GE6"/>
|
<outlet property="computerNameButton" destination="KDy-JC-2sU" id="Lkg-yz-GE6"/>
|
||||||
<outlet property="limelightLogoButton" destination="Tiq-VS-Ua5" id="cue-NW-Hty"/>
|
<outlet property="limelightLogoButton" destination="Tiq-VS-Ua5" id="cue-NW-Hty"/>
|
||||||
@@ -70,100 +68,108 @@
|
|||||||
</viewController>
|
</viewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="ZYl-Xu-QyD" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="ZYl-Xu-QyD" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="797" y="514"/>
|
<point key="canvasLocation" x="779" y="295"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--Settings View Controller-->
|
<!--Settings View Controller-->
|
||||||
<scene sceneID="tWo-uo-hHg">
|
<scene sceneID="tWo-uo-hHg">
|
||||||
<objects>
|
<objects>
|
||||||
<viewController id="BsV-3c-455" customClass="SettingsViewController" sceneMemberID="viewController">
|
<viewController id="BsV-3c-455" customClass="SettingsViewController" sceneMemberID="viewController">
|
||||||
<view key="view" contentMode="scaleToFill" id="WRy-3f-gEP">
|
<view key="view" contentMode="scaleToFill" id="WRy-3f-gEP">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Bitrate: 10 Mbps" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="lMt-4H-fkV">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Bitrate: 10 Mbps" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="lMt-4H-fkV">
|
||||||
<rect key="frame" x="16" y="39" width="151" height="21"/>
|
<rect key="frame" x="16" y="39" width="151" height="21"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="calibratedRGB"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="20" minValue="1" maxValue="100" id="JAY-nj-UNz">
|
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="20" minValue="1" maxValue="100" id="JAY-nj-UNz">
|
||||||
<rect key="frame" x="14" y="68" width="213" height="31"/>
|
<rect key="frame" x="14" y="68" width="213" height="31"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
<color key="tintColor" red="0.6716768741607666" green="0.61711704730987549" blue="0.99902987480163574" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="tintColor" red="0.72941176470000002" green="0.69411764710000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
</slider>
|
</slider>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Framerate" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Aiv-r8-9k2">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Framerate" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Aiv-r8-9k2">
|
||||||
<rect key="frame" x="16" y="106" width="79" height="21"/>
|
<rect key="frame" x="16" y="106" width="79" height="21"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="calibratedRGB"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Resolution" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="pYZ-GR-EwO">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Resolution" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="pYZ-GR-EwO">
|
||||||
<rect key="frame" x="16" y="171" width="82" height="21"/>
|
<rect key="frame" x="16" y="171" width="82" height="21"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="calibratedRGB"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" id="ckc-Dm-8ex">
|
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" id="ckc-Dm-8ex">
|
||||||
<rect key="frame" x="16" y="200" width="209" height="29"/>
|
<rect key="frame" x="16" y="200" width="209" height="29"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="720p"/>
|
<segment title="720p"/>
|
||||||
<segment title="1080p"/>
|
<segment title="1080p"/>
|
||||||
</segments>
|
</segments>
|
||||||
<color key="tintColor" red="0.72941176470000002" green="0.69411764710000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.6716768741607666" green="0.61711704730987549" blue="0.99902987480163574" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</segmentedControl>
|
</segmentedControl>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="On-Screen Controls" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="LGV-5y-piG">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="On-Screen Controls" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="LGV-5y-piG">
|
||||||
<rect key="frame" x="16" y="236" width="153" height="21"/>
|
<rect key="frame" x="16" y="236" width="153" height="21"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="calibratedRGB"/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="1" id="qSU-wh-tqA">
|
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="1" id="qSU-wh-tqA">
|
||||||
<rect key="frame" x="16" y="265" width="209" height="29"/>
|
<rect key="frame" x="16" y="265" width="209" height="29"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="Off"/>
|
<segment title="Off"/>
|
||||||
<segment title="Auto"/>
|
<segment title="Auto"/>
|
||||||
<segment title="Simple"/>
|
<segment title="Simple"/>
|
||||||
<segment title="Full"/>
|
<segment title="Full"/>
|
||||||
</segments>
|
</segments>
|
||||||
<color key="tintColor" red="0.72941176470000002" green="0.69411764710000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.6716768741607666" green="0.61711704730987549" blue="0.99902987480163574" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</segmentedControl>
|
</segmentedControl>
|
||||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="1" id="lGK-vl-pdw">
|
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="1" id="lGK-vl-pdw">
|
||||||
<rect key="frame" x="16" y="135" width="209" height="29"/>
|
<rect key="frame" x="16" y="135" width="209" height="29"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="30 Hz"/>
|
<segment title="30 Hz"/>
|
||||||
<segment title="60 Hz"/>
|
<segment title="60 Hz"/>
|
||||||
</segments>
|
</segments>
|
||||||
<color key="tintColor" red="0.72941176470000002" green="0.69411764710000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.6716768741607666" green="0.61711704730987549" blue="0.99902987480163574" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
</segmentedControl>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Remote Streaming" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="4D8-7f-lYi">
|
||||||
|
<rect key="frame" x="20" y="301" width="142" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<segmentedControl opaque="NO" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" id="vca-Y7-4q9">
|
||||||
|
<rect key="frame" x="20" y="330" width="209" height="29"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<segments>
|
||||||
|
<segment title="Off"/>
|
||||||
|
<segment title="On"/>
|
||||||
|
</segments>
|
||||||
|
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</segmentedControl>
|
</segmentedControl>
|
||||||
</subviews>
|
</subviews>
|
||||||
<animations/>
|
|
||||||
<color key="backgroundColor" cocoaTouchSystemColor="viewFlipsideBackgroundColor"/>
|
<color key="backgroundColor" cocoaTouchSystemColor="viewFlipsideBackgroundColor"/>
|
||||||
</view>
|
</view>
|
||||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="bitrateLabel" destination="lMt-4H-fkV" id="ItM-l3-1Jk"/>
|
<outlet property="bitrateLabel" destination="lMt-4H-fkV" id="ItM-l3-1Jk"/>
|
||||||
<outlet property="bitrateSlider" destination="JAY-nj-UNz" id="fHd-v5-9Vo"/>
|
<outlet property="bitrateSlider" destination="JAY-nj-UNz" id="fHd-v5-9Vo"/>
|
||||||
<outlet property="framerateSelector" destination="lGK-vl-pdw" id="Kc8-Zv-hdm"/>
|
<outlet property="framerateSelector" destination="lGK-vl-pdw" id="Kc8-Zv-hdm"/>
|
||||||
<outlet property="onscreenControlSelector" destination="qSU-wh-tqA" id="j8d-fB-Z2c"/>
|
<outlet property="onscreenControlSelector" destination="qSU-wh-tqA" id="j8d-fB-Z2c"/>
|
||||||
|
<outlet property="remoteSelector" destination="vca-Y7-4q9" id="4p1-IV-tNQ"/>
|
||||||
<outlet property="resolutionSelector" destination="ckc-Dm-8ex" id="rl6-rx-wd3"/>
|
<outlet property="resolutionSelector" destination="ckc-Dm-8ex" id="rl6-rx-wd3"/>
|
||||||
</connections>
|
</connections>
|
||||||
</viewController>
|
</viewController>
|
||||||
@@ -176,12 +182,10 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<viewController id="EVd-wq-ego" customClass="SWRevealViewController" sceneMemberID="viewController">
|
<viewController id="EVd-wq-ego" customClass="SWRevealViewController" sceneMemberID="viewController">
|
||||||
<view key="view" contentMode="scaleToFill" id="hGs-BR-t4b">
|
<view key="view" contentMode="scaleToFill" id="hGs-BR-t4b">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<animations/>
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</view>
|
</view>
|
||||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
|
||||||
<connections>
|
<connections>
|
||||||
<segue destination="baW-rW-rBd" kind="custom" identifier="sw_front" customClass="SWRevealViewControllerSegueSetController" id="RBe-eP-uG6"/>
|
<segue destination="baW-rW-rBd" kind="custom" identifier="sw_front" customClass="SWRevealViewControllerSegueSetController" id="RBe-eP-uG6"/>
|
||||||
<segue destination="BsV-3c-455" kind="custom" identifier="sw_rear" customClass="SWRevealViewControllerSegueSetController" id="U4R-8o-x2S"/>
|
<segue destination="BsV-3c-455" kind="custom" identifier="sw_rear" customClass="SWRevealViewControllerSegueSetController" id="U4R-8o-x2S"/>
|
||||||
@@ -195,12 +199,10 @@
|
|||||||
<scene sceneID="FxL-or-HET">
|
<scene sceneID="FxL-or-HET">
|
||||||
<objects>
|
<objects>
|
||||||
<navigationController id="baW-rW-rBd" sceneMemberID="viewController">
|
<navigationController id="baW-rW-rBd" sceneMemberID="viewController">
|
||||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
|
||||||
<navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="black" translucent="NO" id="RUe-14-4Ya">
|
<navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="black" translucent="NO" id="RUe-14-4Ya">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="768" height="44"/>
|
<rect key="frame" x="0.0" y="20" width="768" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<animations/>
|
<color key="barTintColor" red="0.66666668653488159" green="0.66666668653488159" blue="0.66666668653488159" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="barTintColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</navigationBar>
|
</navigationBar>
|
||||||
<connections>
|
<connections>
|
||||||
<segue destination="wb7-af-jn8" kind="relationship" relationship="rootViewController" id="nkY-JG-Wki"/>
|
<segue destination="wb7-af-jn8" kind="relationship" relationship="rootViewController" id="nkY-JG-Wki"/>
|
||||||
@@ -215,32 +217,27 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<viewController storyboardIdentifier="MainFrame" id="OIm-0n-i9v" customClass="StreamFrameViewController" sceneMemberID="viewController">
|
<viewController storyboardIdentifier="MainFrame" id="OIm-0n-i9v" customClass="StreamFrameViewController" sceneMemberID="viewController">
|
||||||
<view key="view" multipleTouchEnabled="YES" contentMode="scaleToFill" id="VPm-Ae-rc4" userLabel="RenderView" customClass="StreamView">
|
<view key="view" multipleTouchEnabled="YES" contentMode="scaleToFill" id="VPm-Ae-rc4" userLabel="RenderView" customClass="StreamView">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<activityIndicatorView opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="white" id="iOs-1X-mSU">
|
<activityIndicatorView opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="white" id="iOs-1X-mSU">
|
||||||
<rect key="frame" x="502" y="374" width="20" height="20"/>
|
<rect key="frame" x="502" y="374" width="20" height="20"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="dDs-kT-po6">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Label" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="dDs-kT-po6">
|
||||||
<rect key="frame" x="491" y="402" width="42" height="21"/>
|
<rect key="frame" x="491" y="402" width="42" height="21"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
</subviews>
|
</subviews>
|
||||||
<animations/>
|
<color key="backgroundColor" red="0.3333333432674408" green="0.3333333432674408" blue="0.3333333432674408" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</view>
|
</view>
|
||||||
<navigationItem key="navigationItem" id="iUf-9X-GeA"/>
|
<navigationItem key="navigationItem" id="iUf-9X-GeA"/>
|
||||||
<nil key="simulatedStatusBarMetrics"/>
|
<nil key="simulatedStatusBarMetrics"/>
|
||||||
<nil key="simulatedTopBarMetrics"/>
|
<nil key="simulatedTopBarMetrics"/>
|
||||||
<nil key="simulatedBottomBarMetrics"/>
|
<nil key="simulatedBottomBarMetrics"/>
|
||||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
|
||||||
<simulatedScreenMetrics key="simulatedDestinationMetrics"/>
|
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="spinner" destination="iOs-1X-mSU" id="LSl-lr-7fF"/>
|
<outlet property="spinner" destination="iOs-1X-mSU" id="LSl-lr-7fF"/>
|
||||||
<outlet property="stageLabel" destination="dDs-kT-po6" id="ziI-M8-UVf"/>
|
<outlet property="stageLabel" destination="dDs-kT-po6" id="ziI-M8-UVf"/>
|
||||||
@@ -248,41 +245,33 @@
|
|||||||
</viewController>
|
</viewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="hON-k2-Efa" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="hON-k2-Efa" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="1946" y="514"/>
|
<point key="canvasLocation" x="1959" y="295"/>
|
||||||
</scene>
|
</scene>
|
||||||
<!--Loading Frame View Controller-->
|
<!--Loading Frame View Controller-->
|
||||||
<scene sceneID="lcG-48-utf">
|
<scene sceneID="lcG-48-utf">
|
||||||
<objects>
|
<objects>
|
||||||
<viewController storyboardIdentifier="loadingFrame" modalTransitionStyle="crossDissolve" modalPresentationStyle="overCurrentContext" id="ZNo-L5-uxh" customClass="LoadingFrameViewController" sceneMemberID="viewController">
|
<viewController storyboardIdentifier="loadingFrame" modalTransitionStyle="crossDissolve" modalPresentationStyle="overCurrentContext" id="ZNo-L5-uxh" customClass="LoadingFrameViewController" sceneMemberID="viewController">
|
||||||
<view key="view" contentMode="scaleToFill" id="le1-tU-NEp">
|
<view key="view" contentMode="scaleToFill" id="le1-tU-NEp">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="1024" height="768"/>
|
<rect key="frame" x="0.0" y="0.0" width="768" height="1024"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" animating="YES" style="whiteLarge" id="N0D-dj-EuF">
|
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" animating="YES" style="whiteLarge" id="N0D-dj-EuF">
|
||||||
<rect key="frame" x="494" y="365" width="37" height="37"/>
|
<rect key="frame" x="494" y="365" width="37" height="37"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
</subviews>
|
</subviews>
|
||||||
<animations/>
|
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.5" colorSpace="calibratedWhite"/>
|
|
||||||
</view>
|
</view>
|
||||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="loadingSpinner" destination="N0D-dj-EuF" id="xEQ-nx-SOt"/>
|
<outlet property="loadingSpinner" destination="N0D-dj-EuF" id="xEQ-nx-SOt"/>
|
||||||
</connections>
|
</connections>
|
||||||
</viewController>
|
</viewController>
|
||||||
<placeholder placeholderIdentifier="IBFirstResponder" id="lJG-tq-Jrs" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
<placeholder placeholderIdentifier="IBFirstResponder" id="lJG-tq-Jrs" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||||
</objects>
|
</objects>
|
||||||
<point key="canvasLocation" x="1946" y="1425"/>
|
<point key="canvasLocation" x="1959" y="1425"/>
|
||||||
</scene>
|
</scene>
|
||||||
</scenes>
|
</scenes>
|
||||||
<resources>
|
<resources>
|
||||||
<image name="Logo" width="32" height="32"/>
|
<image name="Logo" width="32" height="32"/>
|
||||||
</resources>
|
</resources>
|
||||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
|
||||||
<simulatedStatusBarMetrics key="statusBar" statusBarStyle="lightContent"/>
|
|
||||||
<simulatedOrientationMetrics key="orientation"/>
|
|
||||||
<simulatedScreenMetrics key="destination"/>
|
|
||||||
</simulatedMetricsContainer>
|
|
||||||
</document>
|
</document>
|
||||||
|
|||||||
@@ -1,13 +1,17 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="15B38b" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="DL0-L5-LOv">
|
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" colorMatched="YES" initialViewController="DL0-L5-LOv">
|
||||||
|
<device id="retina4_7" orientation="portrait">
|
||||||
|
<adaptation id="fullscreen"/>
|
||||||
|
</device>
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<deployment identifier="iOS"/>
|
<deployment identifier="iOS"/>
|
||||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8154"/>
|
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/>
|
||||||
|
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
<customFonts key="customFonts">
|
<customFonts key="customFonts">
|
||||||
<mutableArray key="Roboto-Regular.ttf">
|
<array key="Roboto-Regular.ttf">
|
||||||
<string>Roboto-Regular</string>
|
<string>Roboto-Regular</string>
|
||||||
</mutableArray>
|
</array>
|
||||||
</customFonts>
|
</customFonts>
|
||||||
<scenes>
|
<scenes>
|
||||||
<!--Main Frame View Controller-->
|
<!--Main Frame View Controller-->
|
||||||
@@ -15,10 +19,9 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<viewController id="dgh-JZ-Q7z" customClass="MainFrameViewController" sceneMemberID="viewController">
|
<viewController id="dgh-JZ-Q7z" customClass="MainFrameViewController" sceneMemberID="viewController">
|
||||||
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" id="Rtu-AT-Alw" customClass="AppCollectionView">
|
<collectionView key="view" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" dataMode="prototypes" id="Rtu-AT-Alw" customClass="AppCollectionView">
|
||||||
<rect key="frame" x="0.0" y="64" width="568" height="256"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="603"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<animations/>
|
<color key="backgroundColor" red="0.3333333432674408" green="0.3333333432674408" blue="0.3333333432674408" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
<inset key="contentInset" minX="40" minY="20" maxX="40" maxY="20"/>
|
<inset key="contentInset" minX="40" minY="20" maxX="40" maxY="20"/>
|
||||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="20" minimumInteritemSpacing="20" id="YcZ-cR-3tK">
|
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="20" minimumInteritemSpacing="20" id="YcZ-cR-3tK">
|
||||||
<size key="itemSize" width="90" height="120"/>
|
<size key="itemSize" width="90" height="120"/>
|
||||||
@@ -28,15 +31,12 @@
|
|||||||
</collectionViewFlowLayout>
|
</collectionViewFlowLayout>
|
||||||
<cells>
|
<cells>
|
||||||
<collectionViewCell clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="AppCell" id="Uqv-Di-fzX">
|
<collectionViewCell clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" reuseIdentifier="AppCell" id="Uqv-Di-fzX">
|
||||||
<rect key="frame" x="20" y="40" width="90" height="120"/>
|
<rect key="frame" x="20" y="20" width="90" height="120"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="90" height="120"/>
|
<rect key="frame" x="0.0" y="0.0" width="90" height="120"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<animations/>
|
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
|
||||||
</view>
|
</view>
|
||||||
<animations/>
|
|
||||||
</collectionViewCell>
|
</collectionViewCell>
|
||||||
</cells>
|
</cells>
|
||||||
<connections>
|
<connections>
|
||||||
@@ -48,21 +48,19 @@
|
|||||||
<navigationItem key="navigationItem" id="1jn-Sf-Xky">
|
<navigationItem key="navigationItem" id="1jn-Sf-Xky">
|
||||||
<barButtonItem key="leftBarButtonItem" style="done" id="zAn-CM-7Yz">
|
<barButtonItem key="leftBarButtonItem" style="done" id="zAn-CM-7Yz">
|
||||||
<button key="customView" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="pZ9-ft-T24">
|
<button key="customView" opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" lineBreakMode="middleTruncation" id="pZ9-ft-T24">
|
||||||
<rect key="frame" x="20" y="-1" width="109" height="46"/>
|
<rect key="frame" x="16" y="0.0" width="109" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
<fontDescription key="fontDescription" name="Roboto-Regular" family="Roboto" pointSize="16"/>
|
<fontDescription key="fontDescription" name="Roboto-Regular" family="Roboto" pointSize="16"/>
|
||||||
<state key="normal" title="Moonlight" image="Logo">
|
<state key="normal" title="Moonlight" image="Logo">
|
||||||
<color key="titleColor" red="0.96078431372549022" green="0.98039215686274506" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="titleColor" red="0.9513210654258728" green="0.97490358352661133" blue="0.99987185001373291" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</state>
|
</state>
|
||||||
</button>
|
</button>
|
||||||
</barButtonItem>
|
</barButtonItem>
|
||||||
<barButtonItem key="rightBarButtonItem" title="No Host Selected" id="L1H-n4-HB7">
|
<barButtonItem key="rightBarButtonItem" title="No Host Selected" id="L1H-n4-HB7">
|
||||||
<color key="tintColor" red="0.96078431372549022" green="0.98039215686274506" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.9513210654258728" green="0.97490358352661133" blue="0.99987185001373291" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</barButtonItem>
|
</barButtonItem>
|
||||||
</navigationItem>
|
</navigationItem>
|
||||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="computerNameButton" destination="L1H-n4-HB7" id="bng-Ky-oQs"/>
|
<outlet property="computerNameButton" destination="L1H-n4-HB7" id="bng-Ky-oQs"/>
|
||||||
<outlet property="limelightLogoButton" destination="pZ9-ft-T24" id="yRw-rK-9lQ"/>
|
<outlet property="limelightLogoButton" destination="pZ9-ft-T24" id="yRw-rK-9lQ"/>
|
||||||
@@ -78,12 +76,10 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<viewController id="DL0-L5-LOv" customClass="SWRevealViewController" sceneMemberID="viewController">
|
<viewController id="DL0-L5-LOv" customClass="SWRevealViewController" sceneMemberID="viewController">
|
||||||
<view key="view" contentMode="scaleToFill" id="Usg-e0-g4a">
|
<view key="view" contentMode="scaleToFill" id="Usg-e0-g4a">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<animations/>
|
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</view>
|
</view>
|
||||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
|
||||||
<connections>
|
<connections>
|
||||||
<segue destination="rYd-e6-cQU" kind="custom" identifier="sw_rear" customClass="SWRevealViewControllerSegueSetController" id="vBQ-bn-yZu"/>
|
<segue destination="rYd-e6-cQU" kind="custom" identifier="sw_rear" customClass="SWRevealViewControllerSegueSetController" id="vBQ-bn-yZu"/>
|
||||||
<segue destination="ftZ-kC-fxI" kind="custom" identifier="sw_front" customClass="SWRevealViewControllerSegueSetController" id="V3E-d5-bsZ"/>
|
<segue destination="ftZ-kC-fxI" kind="custom" identifier="sw_front" customClass="SWRevealViewControllerSegueSetController" id="V3E-d5-bsZ"/>
|
||||||
@@ -98,89 +94,96 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<viewController id="rYd-e6-cQU" userLabel="Side Bar" customClass="SettingsViewController" sceneMemberID="viewController">
|
<viewController id="rYd-e6-cQU" userLabel="Side Bar" customClass="SettingsViewController" sceneMemberID="viewController">
|
||||||
<view key="view" contentMode="scaleToFill" id="iNk-qF-gIr" customClass="UIScrollView">
|
<view key="view" contentMode="scaleToFill" id="iNk-qF-gIr" customClass="UIScrollView">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="20" minValue="1" maxValue="100" id="3nn-MI-9Xu">
|
<slider opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" value="20" minValue="1" maxValue="100" id="3nn-MI-9Xu">
|
||||||
<rect key="frame" x="14" y="49" width="204" height="31"/>
|
<rect key="frame" x="14" y="49" width="204" height="31"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
<color key="tintColor" red="0.6716768741607666" green="0.61711704730987549" blue="0.99902987480163574" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="tintColor" red="0.72941176470588232" green="0.69411764705882351" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
|
||||||
</slider>
|
</slider>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Bitrate: 10 Mbps" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="SBv-Wn-LB7">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Bitrate: 10 Mbps" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="SBv-Wn-LB7">
|
||||||
<rect key="frame" x="16" y="20" width="151" height="21"/>
|
<rect key="frame" x="16" y="20" width="151" height="21"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="0.96078431372549022" green="0.98039215686274506" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.9513210654258728" green="0.97490358352661133" blue="0.99987185001373291" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="1" id="dLF-qJ-2nY">
|
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="1" id="dLF-qJ-2nY">
|
||||||
<rect key="frame" x="16" y="116" width="200" height="29"/>
|
<rect key="frame" x="16" y="116" width="200" height="29"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="30 Hz"/>
|
<segment title="30 Hz"/>
|
||||||
<segment title="60 Hz"/>
|
<segment title="60 Hz"/>
|
||||||
</segments>
|
</segments>
|
||||||
<color key="tintColor" red="0.72941176470588232" green="0.69411764705882351" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.6716768741607666" green="0.61711704730987549" blue="0.99902987480163574" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</segmentedControl>
|
</segmentedControl>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Framerate" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Kkv-DF-MAl">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Framerate" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Kkv-DF-MAl">
|
||||||
<rect key="frame" x="16" y="87" width="79" height="21"/>
|
<rect key="frame" x="16" y="87" width="79" height="21"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="0.96078431372549022" green="0.98039215686274506" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.9513210654258728" green="0.97490358352661133" blue="0.99987185001373291" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Resolution" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="8zy-ri-Dqc">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Resolution" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="8zy-ri-Dqc">
|
||||||
<rect key="frame" x="16" y="152" width="82" height="21"/>
|
<rect key="frame" x="16" y="152" width="82" height="21"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="0.96078431372549022" green="0.98039215686274506" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.9513210654258728" green="0.97490358352661133" blue="0.99987185001373291" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" id="PCM-t4-Sha">
|
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" id="PCM-t4-Sha">
|
||||||
<rect key="frame" x="16" y="181" width="200" height="29"/>
|
<rect key="frame" x="16" y="181" width="200" height="29"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="720p"/>
|
<segment title="720p"/>
|
||||||
<segment title="1080p"/>
|
<segment title="1080p"/>
|
||||||
</segments>
|
</segments>
|
||||||
<color key="tintColor" red="0.72941176470588232" green="0.69411764705882351" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.6716768741607666" green="0.61711704730987549" blue="0.99902987480163574" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</segmentedControl>
|
</segmentedControl>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="On-Screen Controls" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="HZT-dd-DuQ">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="On-Screen Controls" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="HZT-dd-DuQ">
|
||||||
<rect key="frame" x="16" y="217" width="153" height="21"/>
|
<rect key="frame" x="16" y="217" width="153" height="21"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="0.96078431372549022" green="0.98039215686274506" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="textColor" red="0.9513210654258728" green="0.97490358352661133" blue="0.99987185001373291" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="1" id="WGf-9d-eAm">
|
<segmentedControl opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="1" id="WGf-9d-eAm">
|
||||||
<rect key="frame" x="16" y="246" width="200" height="29"/>
|
<rect key="frame" x="16" y="246" width="200" height="29"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
<segments>
|
<segments>
|
||||||
<segment title="Off"/>
|
<segment title="Off"/>
|
||||||
<segment title="Auto"/>
|
<segment title="Auto"/>
|
||||||
<segment title="Simple"/>
|
<segment title="Simple"/>
|
||||||
<segment title="Full"/>
|
<segment title="Full"/>
|
||||||
</segments>
|
</segments>
|
||||||
<color key="tintColor" red="0.72941176470588232" green="0.69411764705882351" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
<color key="tintColor" red="0.6716768741607666" green="0.61711704730987549" blue="0.99902987480163574" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
</segmentedControl>
|
||||||
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" misplaced="YES" text="Remote Streaming" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="DxN-ys-tYS">
|
||||||
|
<rect key="frame" x="16" y="282" width="142" height="21"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
|
<color key="textColor" red="0.95132106540000005" green="0.97490358349999995" blue="0.99987185000000001" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
|
<nil key="highlightedColor"/>
|
||||||
|
</label>
|
||||||
|
<segmentedControl opaque="NO" contentMode="scaleToFill" misplaced="YES" contentHorizontalAlignment="left" contentVerticalAlignment="top" segmentControlStyle="plain" selectedSegmentIndex="0" id="FyK-g5-ohw">
|
||||||
|
<rect key="frame" x="16" y="311" width="200" height="29"/>
|
||||||
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
|
<segments>
|
||||||
|
<segment title="Off"/>
|
||||||
|
<segment title="On"/>
|
||||||
|
</segments>
|
||||||
|
<color key="tintColor" red="0.6716768742" green="0.61711704730000005" blue="0.99902987480000005" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
</segmentedControl>
|
</segmentedControl>
|
||||||
</subviews>
|
</subviews>
|
||||||
<animations/>
|
<color key="backgroundColor" red="0.12156862745098039" green="0.12941176470588237" blue="0.14117647058823529" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="backgroundColor" red="0.12156862745098039" green="0.12941176470588237" blue="0.14117647058823529" alpha="1" colorSpace="calibratedRGB"/>
|
|
||||||
</view>
|
</view>
|
||||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="bitrateLabel" destination="SBv-Wn-LB7" id="Wdu-me-Bvd"/>
|
<outlet property="bitrateLabel" destination="SBv-Wn-LB7" id="Wdu-me-Bvd"/>
|
||||||
<outlet property="bitrateSlider" destination="3nn-MI-9Xu" id="IuD-Rk-vPp"/>
|
<outlet property="bitrateSlider" destination="3nn-MI-9Xu" id="IuD-Rk-vPp"/>
|
||||||
<outlet property="framerateSelector" destination="dLF-qJ-2nY" id="hE3-hk-iwa"/>
|
<outlet property="framerateSelector" destination="dLF-qJ-2nY" id="hE3-hk-iwa"/>
|
||||||
<outlet property="onscreenControlSelector" destination="WGf-9d-eAm" id="hob-se-4Sn"/>
|
<outlet property="onscreenControlSelector" destination="WGf-9d-eAm" id="hob-se-4Sn"/>
|
||||||
|
<outlet property="remoteSelector" destination="FyK-g5-ohw" id="E6P-WS-0qb"/>
|
||||||
<outlet property="resolutionSelector" destination="PCM-t4-Sha" id="t60-W2-wkV"/>
|
<outlet property="resolutionSelector" destination="PCM-t4-Sha" id="t60-W2-wkV"/>
|
||||||
</connections>
|
</connections>
|
||||||
</viewController>
|
</viewController>
|
||||||
@@ -192,12 +195,10 @@
|
|||||||
<scene sceneID="pfX-8A-htT">
|
<scene sceneID="pfX-8A-htT">
|
||||||
<objects>
|
<objects>
|
||||||
<navigationController id="ftZ-kC-fxI" sceneMemberID="viewController">
|
<navigationController id="ftZ-kC-fxI" sceneMemberID="viewController">
|
||||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
|
||||||
<navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="black" translucent="NO" id="0ZA-Ec-QgD">
|
<navigationBar key="navigationBar" contentMode="scaleToFill" barStyle="black" translucent="NO" id="0ZA-Ec-QgD">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="320" height="44"/>
|
<rect key="frame" x="0.0" y="20" width="375" height="44"/>
|
||||||
<autoresizingMask key="autoresizingMask"/>
|
<autoresizingMask key="autoresizingMask"/>
|
||||||
<animations/>
|
<color key="barTintColor" red="0.66666668653488159" green="0.66666668653488159" blue="0.66666668653488159" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="barTintColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
<textAttributes key="titleTextAttributes">
|
<textAttributes key="titleTextAttributes">
|
||||||
<offsetWrapper key="textShadowOffset" horizontal="0.0" vertical="0.0"/>
|
<offsetWrapper key="textShadowOffset" horizontal="0.0" vertical="0.0"/>
|
||||||
</textAttributes>
|
</textAttributes>
|
||||||
@@ -215,31 +216,27 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<viewController id="mI3-9F-XwU" customClass="StreamFrameViewController" sceneMemberID="viewController">
|
<viewController id="mI3-9F-XwU" customClass="StreamFrameViewController" sceneMemberID="viewController">
|
||||||
<view key="view" multipleTouchEnabled="YES" contentMode="scaleToFill" id="eir-e9-IPE" customClass="StreamView">
|
<view key="view" multipleTouchEnabled="YES" contentMode="scaleToFill" id="eir-e9-IPE" customClass="StreamView">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Stage" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="2HK-Z5-4Ch">
|
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Stage" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="2HK-Z5-4Ch">
|
||||||
<rect key="frame" x="262" y="149" width="45" height="21"/>
|
<rect key="frame" x="262" y="149" width="45" height="21"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="calibratedRGB"/>
|
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<nil key="highlightedColor"/>
|
<nil key="highlightedColor"/>
|
||||||
</label>
|
</label>
|
||||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="white" id="0vm-Iv-K4b">
|
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" hidesWhenStopped="YES" animating="YES" style="white" id="0vm-Iv-K4b">
|
||||||
<rect key="frame" x="274" y="121" width="20" height="20"/>
|
<rect key="frame" x="178" y="260" width="20" height="20"/>
|
||||||
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
<autoresizingMask key="autoresizingMask" flexibleMinX="YES" flexibleMaxX="YES" flexibleMinY="YES" flexibleMaxY="YES"/>
|
||||||
<animations/>
|
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
</subviews>
|
</subviews>
|
||||||
<animations/>
|
<color key="backgroundColor" red="0.3333333432674408" green="0.3333333432674408" blue="0.3333333432674408" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
|
||||||
</view>
|
</view>
|
||||||
<navigationItem key="navigationItem" id="8uX-4T-BiC"/>
|
<navigationItem key="navigationItem" id="8uX-4T-BiC"/>
|
||||||
<nil key="simulatedStatusBarMetrics"/>
|
<nil key="simulatedStatusBarMetrics"/>
|
||||||
<nil key="simulatedTopBarMetrics"/>
|
<nil key="simulatedTopBarMetrics"/>
|
||||||
<nil key="simulatedBottomBarMetrics"/>
|
<nil key="simulatedBottomBarMetrics"/>
|
||||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="spinner" destination="0vm-Iv-K4b" id="Lif-zG-6Jh"/>
|
<outlet property="spinner" destination="0vm-Iv-K4b" id="Lif-zG-6Jh"/>
|
||||||
<outlet property="stageLabel" destination="2HK-Z5-4Ch" id="1bI-Ig-OpD"/>
|
<outlet property="stageLabel" destination="2HK-Z5-4Ch" id="1bI-Ig-OpD"/>
|
||||||
@@ -254,18 +251,15 @@
|
|||||||
<objects>
|
<objects>
|
||||||
<viewController storyboardIdentifier="loadingFrame" modalTransitionStyle="crossDissolve" modalPresentationStyle="overCurrentContext" id="9W0-2D-0Kp" customClass="LoadingFrameViewController" sceneMemberID="viewController">
|
<viewController storyboardIdentifier="loadingFrame" modalTransitionStyle="crossDissolve" modalPresentationStyle="overCurrentContext" id="9W0-2D-0Kp" customClass="LoadingFrameViewController" sceneMemberID="viewController">
|
||||||
<view key="view" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="center" id="nSw-dc-mi4">
|
<view key="view" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="center" id="nSw-dc-mi4">
|
||||||
<rect key="frame" x="0.0" y="0.0" width="568" height="320"/>
|
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
|
||||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||||
<subviews>
|
<subviews>
|
||||||
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="oNu-Gu-QeM">
|
<activityIndicatorView opaque="NO" contentMode="scaleToFill" horizontalHuggingPriority="750" verticalHuggingPriority="750" animating="YES" style="whiteLarge" translatesAutoresizingMaskIntoConstraints="NO" id="oNu-Gu-QeM">
|
||||||
<rect key="frame" x="266" y="141" width="37" height="37"/>
|
<rect key="frame" x="266" y="313" width="37" height="37"/>
|
||||||
<animations/>
|
|
||||||
</activityIndicatorView>
|
</activityIndicatorView>
|
||||||
</subviews>
|
</subviews>
|
||||||
<animations/>
|
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
|
||||||
<color key="backgroundColor" white="0.0" alpha="0.5" colorSpace="calibratedWhite"/>
|
|
||||||
</view>
|
</view>
|
||||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
|
||||||
<connections>
|
<connections>
|
||||||
<outlet property="loadingSpinner" destination="oNu-Gu-QeM" id="5IK-qn-mIZ"/>
|
<outlet property="loadingSpinner" destination="oNu-Gu-QeM" id="5IK-qn-mIZ"/>
|
||||||
</connections>
|
</connections>
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
The MIT License (MIT)
|
||||||
|
|
||||||
|
Copyright (c) 2014 Tim Caswell
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
*/
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2014 Alex Diener
|
||||||
|
|
||||||
|
This software is provided 'as-is', without any express or implied
|
||||||
|
warranty. In no event will the authors be held liable for any damages
|
||||||
|
arising from the use of this software.
|
||||||
|
|
||||||
|
Permission is granted to anyone to use this software for any purpose,
|
||||||
|
including commercial applications, and to alter it and redistribute it
|
||||||
|
freely, subject to the following restrictions:
|
||||||
|
|
||||||
|
1. The origin of this software must not be misrepresented; you must not
|
||||||
|
claim that you wrote the original software. If you use this software
|
||||||
|
in a product, an acknowledgment in the product documentation would be
|
||||||
|
appreciated but is not required.
|
||||||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||||||
|
misrepresented as being the original software.
|
||||||
|
3. This notice may not be removed or altered from any source distribution.
|
||||||
|
|
||||||
|
Alex Diener alex@ludobloom.com
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __GAMEPAD_H__
|
||||||
|
#define __GAMEPAD_H__
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if _MSC_VER <= 1600
|
||||||
|
#define bool int
|
||||||
|
#define true 1
|
||||||
|
#define false 0
|
||||||
|
#else
|
||||||
|
#include <stdbool.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct Gamepad_device {
|
||||||
|
// Unique device identifier for application session, starting at 0 for the first device attached and
|
||||||
|
// incrementing by 1 for each additional device. If a device is removed and subsequently reattached
|
||||||
|
// during the same application session, it will have a new deviceID.
|
||||||
|
unsigned int deviceID;
|
||||||
|
|
||||||
|
// Human-readable device name
|
||||||
|
const char * description;
|
||||||
|
|
||||||
|
// USB vendor/product IDs as returned by the driver. Can be used to determine the particular model of device represented.
|
||||||
|
int vendorID;
|
||||||
|
int productID;
|
||||||
|
|
||||||
|
// Number of axis elements belonging to the device
|
||||||
|
unsigned int numAxes;
|
||||||
|
|
||||||
|
// Number of button elements belonging to the device
|
||||||
|
unsigned int numButtons;
|
||||||
|
|
||||||
|
// Array[numAxes] of values representing the current state of each axis, in the range [-1..1]
|
||||||
|
float * axisStates;
|
||||||
|
|
||||||
|
// Array[numButtons] of values representing the current state of each button
|
||||||
|
bool * buttonStates;
|
||||||
|
|
||||||
|
// Platform-specific device data storage. Don't touch unless you know what you're doing and don't
|
||||||
|
// mind your code breaking in future versions of this library.
|
||||||
|
void * privateData;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Initializes gamepad library and detects initial devices. Call this before any other Gamepad_*()
|
||||||
|
function, other than callback registration functions. If you want to receive deviceAttachFunc
|
||||||
|
callbacks from devices detected in Gamepad_init(), you must call Gamepad_deviceAttachFunc()
|
||||||
|
before calling Gamepad_init().
|
||||||
|
|
||||||
|
This function must be called from the same thread that will be calling Gamepad_processEvents()
|
||||||
|
and Gamepad_detectDevices(). */
|
||||||
|
void Gamepad_init();
|
||||||
|
|
||||||
|
/* Tears down all data structures created by the gamepad library and releases any memory that was
|
||||||
|
allocated. It is not necessary to call this function at application termination, but it's
|
||||||
|
provided in case you want to free memory associated with gamepads at some earlier time. */
|
||||||
|
void Gamepad_shutdown();
|
||||||
|
|
||||||
|
/* Returns the number of currently attached gamepad devices. */
|
||||||
|
unsigned int Gamepad_numDevices();
|
||||||
|
|
||||||
|
/* Returns the specified Gamepad_device struct, or NULL if deviceIndex is out of bounds. */
|
||||||
|
struct Gamepad_device * Gamepad_deviceAtIndex(unsigned int deviceIndex);
|
||||||
|
|
||||||
|
/* Polls for any devices that have been attached since the last call to Gamepad_detectDevices() or
|
||||||
|
Gamepad_init(). If any new devices are found, the callback registered with
|
||||||
|
Gamepad_deviceAttachFunc() (if any) will be called once per newly detected device.
|
||||||
|
|
||||||
|
Note that depending on implementation, you may receive button and axis event callbacks for
|
||||||
|
devices that have not yet been detected with Gamepad_detectDevices(). You can safely ignore
|
||||||
|
these events, but be aware that your callbacks might receive a device ID that hasn't been seen
|
||||||
|
by your deviceAttachFunc. */
|
||||||
|
void Gamepad_detectDevices();
|
||||||
|
|
||||||
|
/* Reads pending input from all attached devices and calls the appropriate input callbacks, if any
|
||||||
|
have been registered. */
|
||||||
|
void Gamepad_processEvents();
|
||||||
|
|
||||||
|
/* Registers a function to be called whenever a device is attached. The specified function will be
|
||||||
|
called only during calls to Gamepad_init() and Gamepad_detectDevices(), in the thread from
|
||||||
|
which those functions were called. Calling this function with a NULL argument will stop any
|
||||||
|
previously registered callback from being called subsequently. */
|
||||||
|
void Gamepad_deviceAttachFunc(void (* callback)(struct Gamepad_device * device, void * context), void * context);
|
||||||
|
|
||||||
|
/* Registers a function to be called whenever a device is detached. The specified function can be
|
||||||
|
called at any time, and will not necessarily be called from the main thread. Calling this
|
||||||
|
function with a NULL argument will stop any previously registered callback from being called
|
||||||
|
subsequently. */
|
||||||
|
void Gamepad_deviceRemoveFunc(void (* callback)(struct Gamepad_device * device, void * context), void * context);
|
||||||
|
|
||||||
|
/* Registers a function to be called whenever a button on any attached device is pressed. The
|
||||||
|
specified function will be called only during calls to Gamepad_processEvents(), in the
|
||||||
|
thread from which Gamepad_processEvents() was called. Calling this function with a NULL
|
||||||
|
argument will stop any previously registered callback from being called subsequently. */
|
||||||
|
void Gamepad_buttonDownFunc(void (* callback)(struct Gamepad_device * device, unsigned int buttonID, double timestamp, void * context), void * context);
|
||||||
|
|
||||||
|
/* Registers a function to be called whenever a button on any attached device is released. The
|
||||||
|
specified function will be called only during calls to Gamepad_processEvents(), in the
|
||||||
|
thread from which Gamepad_processEvents() was called. Calling this function with a NULL
|
||||||
|
argument will stop any previously registered callback from being called subsequently. */
|
||||||
|
void Gamepad_buttonUpFunc(void (* callback)(struct Gamepad_device * device, unsigned int buttonID, double timestamp, void * context), void * context);
|
||||||
|
|
||||||
|
/* Registers a function to be called whenever an axis on any attached device is moved. The
|
||||||
|
specified function will be called only during calls to Gamepad_processEvents(), in the
|
||||||
|
thread from which Gamepad_processEvents() was called. Calling this function with a NULL
|
||||||
|
argument will stop any previously registered callback from being called subsequently. */
|
||||||
|
void Gamepad_axisMoveFunc(void (* callback)(struct Gamepad_device * device, unsigned int axisID, float value, float lastValue, double timestamp, void * context), void * context);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,510 @@
|
|||||||
|
// !$*UTF8*$!
|
||||||
|
{
|
||||||
|
archiveVersion = 1;
|
||||||
|
classes = {
|
||||||
|
};
|
||||||
|
objectVersion = 48;
|
||||||
|
objects = {
|
||||||
|
|
||||||
|
/* Begin PBXBuildFile section */
|
||||||
|
9857AEEA1EBE85A20084F99E /* RtpFecQueue.c in Sources */ = {isa = PBXBuildFile; fileRef = 9857AEE91EBE85A20084F99E /* RtpFecQueue.c */; };
|
||||||
|
9857AEF01EBE85E10084F99E /* rs.c in Sources */ = {isa = PBXBuildFile; fileRef = 9857AEEE1EBE85E10084F99E /* rs.c */; };
|
||||||
|
98AB2E401CAD425A0089BB98 /* AudioStream.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E1A1CAD423B0089BB98 /* AudioStream.c */; };
|
||||||
|
98AB2E411CAD425A0089BB98 /* ByteBuffer.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E1B1CAD423B0089BB98 /* ByteBuffer.c */; };
|
||||||
|
98AB2E421CAD425A0089BB98 /* Connection.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E1D1CAD423B0089BB98 /* Connection.c */; };
|
||||||
|
98AB2E431CAD425A0089BB98 /* ControlStream.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E1E1CAD423B0089BB98 /* ControlStream.c */; };
|
||||||
|
98AB2E441CAD425A0089BB98 /* FakeCallbacks.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E1F1CAD423B0089BB98 /* FakeCallbacks.c */; };
|
||||||
|
98AB2E451CAD425A0089BB98 /* InputStream.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E211CAD423B0089BB98 /* InputStream.c */; };
|
||||||
|
98AB2E461CAD425A0089BB98 /* LinkedBlockingQueue.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E241CAD423B0089BB98 /* LinkedBlockingQueue.c */; };
|
||||||
|
98AB2E471CAD425A0089BB98 /* Misc.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E261CAD423B0089BB98 /* Misc.c */; };
|
||||||
|
98AB2E481CAD425A0089BB98 /* Platform.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E311CAD423B0089BB98 /* Platform.c */; };
|
||||||
|
98AB2E491CAD425A0089BB98 /* PlatformSockets.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E331CAD423B0089BB98 /* PlatformSockets.c */; };
|
||||||
|
98AB2E4A1CAD425A0089BB98 /* RtpReorderQueue.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E361CAD423B0089BB98 /* RtpReorderQueue.c */; };
|
||||||
|
98AB2E4B1CAD425A0089BB98 /* RtspConnection.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E391CAD423B0089BB98 /* RtspConnection.c */; };
|
||||||
|
98AB2E4C1CAD425A0089BB98 /* RtspParser.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E3A1CAD423B0089BB98 /* RtspParser.c */; };
|
||||||
|
98AB2E4D1CAD425A0089BB98 /* SdpGenerator.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E3B1CAD423B0089BB98 /* SdpGenerator.c */; };
|
||||||
|
98AB2E4E1CAD425A0089BB98 /* VideoDepacketizer.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E3D1CAD423B0089BB98 /* VideoDepacketizer.c */; };
|
||||||
|
98AB2E4F1CAD425A0089BB98 /* VideoStream.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E3E1CAD423B0089BB98 /* VideoStream.c */; };
|
||||||
|
98AB2E501CAD427A0089BB98 /* callbacks.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2DF01CAD422B0089BB98 /* callbacks.c */; };
|
||||||
|
98AB2E511CAD427A0089BB98 /* compress.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2DF31CAD422B0089BB98 /* compress.c */; };
|
||||||
|
98AB2E521CAD427A0089BB98 /* host.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E001CAD422B0089BB98 /* host.c */; };
|
||||||
|
98AB2E531CAD427A0089BB98 /* list.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E0E1CAD422B0089BB98 /* list.c */; };
|
||||||
|
98AB2E541CAD427A0089BB98 /* packet.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E121CAD422B0089BB98 /* packet.c */; };
|
||||||
|
98AB2E551CAD427A0089BB98 /* peer.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E131CAD422B0089BB98 /* peer.c */; };
|
||||||
|
98AB2E561CAD427A0089BB98 /* protocol.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E151CAD422B0089BB98 /* protocol.c */; };
|
||||||
|
98AB2E571CAD427A0089BB98 /* unix.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E171CAD422B0089BB98 /* unix.c */; };
|
||||||
|
98AB2E581CAD427A0089BB98 /* win32.c in Sources */ = {isa = PBXBuildFile; fileRef = 98AB2E181CAD422B0089BB98 /* win32.c */; };
|
||||||
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
|
/* Begin PBXFileReference section */
|
||||||
|
9857AEE91EBE85A20084F99E /* RtpFecQueue.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = RtpFecQueue.c; sourceTree = "<group>"; };
|
||||||
|
9857AEEB1EBE85AB0084F99E /* RtpFecQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RtpFecQueue.h; sourceTree = "<group>"; };
|
||||||
|
9857AEEE1EBE85E10084F99E /* rs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = rs.c; path = "moonlight-common-c/reedsolomon/rs.c"; sourceTree = "<group>"; };
|
||||||
|
9857AEEF1EBE85E10084F99E /* rs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = rs.h; path = "moonlight-common-c/reedsolomon/rs.h"; sourceTree = "<group>"; };
|
||||||
|
98AB2DF01CAD422B0089BB98 /* callbacks.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = callbacks.c; sourceTree = "<group>"; };
|
||||||
|
98AB2DF11CAD422B0089BB98 /* ChangeLog */ = {isa = PBXFileReference; lastKnownFileType = text; path = ChangeLog; sourceTree = "<group>"; };
|
||||||
|
98AB2DF21CAD422B0089BB98 /* CMakeLists.txt */ = {isa = PBXFileReference; lastKnownFileType = text; path = CMakeLists.txt; sourceTree = "<group>"; };
|
||||||
|
98AB2DF31CAD422B0089BB98 /* compress.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = compress.c; sourceTree = "<group>"; };
|
||||||
|
98AB2DF41CAD422B0089BB98 /* configure.ac */ = {isa = PBXFileReference; lastKnownFileType = text; path = configure.ac; sourceTree = "<group>"; };
|
||||||
|
98AB2DF61CAD422B0089BB98 /* design.dox */ = {isa = PBXFileReference; lastKnownFileType = text; path = design.dox; sourceTree = "<group>"; };
|
||||||
|
98AB2DF71CAD422B0089BB98 /* FAQ.dox */ = {isa = PBXFileReference; lastKnownFileType = text; path = FAQ.dox; sourceTree = "<group>"; };
|
||||||
|
98AB2DF81CAD422B0089BB98 /* install.dox */ = {isa = PBXFileReference; lastKnownFileType = text; path = install.dox; sourceTree = "<group>"; };
|
||||||
|
98AB2DF91CAD422B0089BB98 /* license.dox */ = {isa = PBXFileReference; lastKnownFileType = text; path = license.dox; sourceTree = "<group>"; };
|
||||||
|
98AB2DFA1CAD422B0089BB98 /* mainpage.dox */ = {isa = PBXFileReference; lastKnownFileType = text; path = mainpage.dox; sourceTree = "<group>"; };
|
||||||
|
98AB2DFB1CAD422B0089BB98 /* tutorial.dox */ = {isa = PBXFileReference; lastKnownFileType = text; path = tutorial.dox; sourceTree = "<group>"; };
|
||||||
|
98AB2DFC1CAD422B0089BB98 /* Doxyfile */ = {isa = PBXFileReference; lastKnownFileType = text; path = Doxyfile; sourceTree = "<group>"; };
|
||||||
|
98AB2DFD1CAD422B0089BB98 /* DoxygenLayout.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = DoxygenLayout.xml; sourceTree = "<group>"; };
|
||||||
|
98AB2DFE1CAD422B0089BB98 /* enet.dsp */ = {isa = PBXFileReference; lastKnownFileType = text; path = enet.dsp; sourceTree = "<group>"; };
|
||||||
|
98AB2DFF1CAD422B0089BB98 /* enet_dll.cbp */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = enet_dll.cbp; sourceTree = "<group>"; };
|
||||||
|
98AB2E001CAD422B0089BB98 /* host.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = host.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E031CAD422B0089BB98 /* callbacks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = callbacks.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E041CAD422B0089BB98 /* enet.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = enet.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E051CAD422B0089BB98 /* list.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = list.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E061CAD422B0089BB98 /* protocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = protocol.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E071CAD422B0089BB98 /* time.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = time.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E081CAD422B0089BB98 /* types.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = types.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E091CAD422B0089BB98 /* unix.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = unix.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E0A1CAD422B0089BB98 /* utility.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = utility.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E0B1CAD422B0089BB98 /* win32.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = win32.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E0C1CAD422B0089BB98 /* libenet.pc.in */ = {isa = PBXFileReference; lastKnownFileType = text; path = libenet.pc.in; sourceTree = "<group>"; };
|
||||||
|
98AB2E0D1CAD422B0089BB98 /* LICENSE */ = {isa = PBXFileReference; lastKnownFileType = text; path = LICENSE; sourceTree = "<group>"; };
|
||||||
|
98AB2E0E1CAD422B0089BB98 /* list.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = list.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E101CAD422B0089BB98 /* .keep */ = {isa = PBXFileReference; lastKnownFileType = text; path = .keep; sourceTree = "<group>"; };
|
||||||
|
98AB2E111CAD422B0089BB98 /* Makefile.am */ = {isa = PBXFileReference; lastKnownFileType = text; path = Makefile.am; sourceTree = "<group>"; };
|
||||||
|
98AB2E121CAD422B0089BB98 /* packet.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = packet.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E131CAD422B0089BB98 /* peer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = peer.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E141CAD422B0089BB98 /* premake4.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = premake4.lua; sourceTree = "<group>"; };
|
||||||
|
98AB2E151CAD422B0089BB98 /* protocol.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = protocol.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E161CAD422B0089BB98 /* README */ = {isa = PBXFileReference; lastKnownFileType = text; path = README; sourceTree = "<group>"; };
|
||||||
|
98AB2E171CAD422B0089BB98 /* unix.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = unix.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E181CAD422B0089BB98 /* win32.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = win32.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E1A1CAD423B0089BB98 /* AudioStream.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = AudioStream.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E1B1CAD423B0089BB98 /* ByteBuffer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ByteBuffer.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E1C1CAD423B0089BB98 /* ByteBuffer.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ByteBuffer.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E1D1CAD423B0089BB98 /* Connection.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = Connection.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E1E1CAD423B0089BB98 /* ControlStream.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ControlStream.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E1F1CAD423B0089BB98 /* FakeCallbacks.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = FakeCallbacks.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E201CAD423B0089BB98 /* Input.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Input.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E211CAD423B0089BB98 /* InputStream.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = InputStream.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E221CAD423B0089BB98 /* Limelight-internal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Limelight-internal.h"; sourceTree = "<group>"; };
|
||||||
|
98AB2E231CAD423B0089BB98 /* Limelight.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Limelight.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E241CAD423B0089BB98 /* LinkedBlockingQueue.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = LinkedBlockingQueue.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E251CAD423B0089BB98 /* LinkedBlockingQueue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LinkedBlockingQueue.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E261CAD423B0089BB98 /* Misc.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = Misc.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E311CAD423B0089BB98 /* Platform.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = Platform.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E321CAD423B0089BB98 /* Platform.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Platform.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E331CAD423B0089BB98 /* PlatformSockets.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = PlatformSockets.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E341CAD423B0089BB98 /* PlatformSockets.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformSockets.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E351CAD423B0089BB98 /* PlatformThreads.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = PlatformThreads.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E361CAD423B0089BB98 /* RtpReorderQueue.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = RtpReorderQueue.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E371CAD423B0089BB98 /* RtpReorderQueue.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RtpReorderQueue.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E381CAD423B0089BB98 /* Rtsp.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Rtsp.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E391CAD423B0089BB98 /* RtspConnection.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = RtspConnection.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E3A1CAD423B0089BB98 /* RtspParser.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = RtspParser.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E3B1CAD423B0089BB98 /* SdpGenerator.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = SdpGenerator.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E3C1CAD423B0089BB98 /* Video.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Video.h; sourceTree = "<group>"; };
|
||||||
|
98AB2E3D1CAD423B0089BB98 /* VideoDepacketizer.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = VideoDepacketizer.c; sourceTree = "<group>"; };
|
||||||
|
98AB2E3E1CAD423B0089BB98 /* VideoStream.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = VideoStream.c; sourceTree = "<group>"; };
|
||||||
|
FB290E2E19B37A4E004C83CF /* libmoonlight-common.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libmoonlight-common.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
|
FB290E2B19B37A4E004C83CF /* Frameworks */ = {
|
||||||
|
isa = PBXFrameworksBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXFrameworksBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin PBXGroup section */
|
||||||
|
9857AEED1EBE85D50084F99E /* reedsolomon */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
9857AEEE1EBE85E10084F99E /* rs.c */,
|
||||||
|
9857AEEF1EBE85E10084F99E /* rs.h */,
|
||||||
|
);
|
||||||
|
name = reedsolomon;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
98AB2DEF1CAD422B0089BB98 /* enet */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
98AB2DF01CAD422B0089BB98 /* callbacks.c */,
|
||||||
|
98AB2DF11CAD422B0089BB98 /* ChangeLog */,
|
||||||
|
98AB2DF21CAD422B0089BB98 /* CMakeLists.txt */,
|
||||||
|
98AB2DF31CAD422B0089BB98 /* compress.c */,
|
||||||
|
98AB2DF41CAD422B0089BB98 /* configure.ac */,
|
||||||
|
98AB2DF51CAD422B0089BB98 /* docs */,
|
||||||
|
98AB2DFC1CAD422B0089BB98 /* Doxyfile */,
|
||||||
|
98AB2DFD1CAD422B0089BB98 /* DoxygenLayout.xml */,
|
||||||
|
98AB2DFE1CAD422B0089BB98 /* enet.dsp */,
|
||||||
|
98AB2DFF1CAD422B0089BB98 /* enet_dll.cbp */,
|
||||||
|
98AB2E001CAD422B0089BB98 /* host.c */,
|
||||||
|
98AB2E011CAD422B0089BB98 /* include */,
|
||||||
|
98AB2E0C1CAD422B0089BB98 /* libenet.pc.in */,
|
||||||
|
98AB2E0D1CAD422B0089BB98 /* LICENSE */,
|
||||||
|
98AB2E0E1CAD422B0089BB98 /* list.c */,
|
||||||
|
98AB2E0F1CAD422B0089BB98 /* m4 */,
|
||||||
|
98AB2E111CAD422B0089BB98 /* Makefile.am */,
|
||||||
|
98AB2E121CAD422B0089BB98 /* packet.c */,
|
||||||
|
98AB2E131CAD422B0089BB98 /* peer.c */,
|
||||||
|
98AB2E141CAD422B0089BB98 /* premake4.lua */,
|
||||||
|
98AB2E151CAD422B0089BB98 /* protocol.c */,
|
||||||
|
98AB2E161CAD422B0089BB98 /* README */,
|
||||||
|
98AB2E171CAD422B0089BB98 /* unix.c */,
|
||||||
|
98AB2E181CAD422B0089BB98 /* win32.c */,
|
||||||
|
);
|
||||||
|
name = enet;
|
||||||
|
path = "moonlight-common-c/enet";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
98AB2DF51CAD422B0089BB98 /* docs */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
98AB2DF61CAD422B0089BB98 /* design.dox */,
|
||||||
|
98AB2DF71CAD422B0089BB98 /* FAQ.dox */,
|
||||||
|
98AB2DF81CAD422B0089BB98 /* install.dox */,
|
||||||
|
98AB2DF91CAD422B0089BB98 /* license.dox */,
|
||||||
|
98AB2DFA1CAD422B0089BB98 /* mainpage.dox */,
|
||||||
|
98AB2DFB1CAD422B0089BB98 /* tutorial.dox */,
|
||||||
|
);
|
||||||
|
path = docs;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
98AB2E011CAD422B0089BB98 /* include */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
98AB2E021CAD422B0089BB98 /* enet */,
|
||||||
|
);
|
||||||
|
path = include;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
98AB2E021CAD422B0089BB98 /* enet */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
98AB2E031CAD422B0089BB98 /* callbacks.h */,
|
||||||
|
98AB2E041CAD422B0089BB98 /* enet.h */,
|
||||||
|
98AB2E051CAD422B0089BB98 /* list.h */,
|
||||||
|
98AB2E061CAD422B0089BB98 /* protocol.h */,
|
||||||
|
98AB2E071CAD422B0089BB98 /* time.h */,
|
||||||
|
98AB2E081CAD422B0089BB98 /* types.h */,
|
||||||
|
98AB2E091CAD422B0089BB98 /* unix.h */,
|
||||||
|
98AB2E0A1CAD422B0089BB98 /* utility.h */,
|
||||||
|
98AB2E0B1CAD422B0089BB98 /* win32.h */,
|
||||||
|
);
|
||||||
|
path = enet;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
98AB2E0F1CAD422B0089BB98 /* m4 */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
98AB2E101CAD422B0089BB98 /* .keep */,
|
||||||
|
);
|
||||||
|
path = m4;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
98AB2E191CAD423B0089BB98 /* src */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
9857AEEB1EBE85AB0084F99E /* RtpFecQueue.h */,
|
||||||
|
9857AEE91EBE85A20084F99E /* RtpFecQueue.c */,
|
||||||
|
98AB2E1A1CAD423B0089BB98 /* AudioStream.c */,
|
||||||
|
98AB2E1B1CAD423B0089BB98 /* ByteBuffer.c */,
|
||||||
|
98AB2E1C1CAD423B0089BB98 /* ByteBuffer.h */,
|
||||||
|
98AB2E1D1CAD423B0089BB98 /* Connection.c */,
|
||||||
|
98AB2E1E1CAD423B0089BB98 /* ControlStream.c */,
|
||||||
|
98AB2E1F1CAD423B0089BB98 /* FakeCallbacks.c */,
|
||||||
|
98AB2E201CAD423B0089BB98 /* Input.h */,
|
||||||
|
98AB2E211CAD423B0089BB98 /* InputStream.c */,
|
||||||
|
98AB2E221CAD423B0089BB98 /* Limelight-internal.h */,
|
||||||
|
98AB2E231CAD423B0089BB98 /* Limelight.h */,
|
||||||
|
98AB2E241CAD423B0089BB98 /* LinkedBlockingQueue.c */,
|
||||||
|
98AB2E251CAD423B0089BB98 /* LinkedBlockingQueue.h */,
|
||||||
|
98AB2E261CAD423B0089BB98 /* Misc.c */,
|
||||||
|
98AB2E311CAD423B0089BB98 /* Platform.c */,
|
||||||
|
98AB2E321CAD423B0089BB98 /* Platform.h */,
|
||||||
|
98AB2E331CAD423B0089BB98 /* PlatformSockets.c */,
|
||||||
|
98AB2E341CAD423B0089BB98 /* PlatformSockets.h */,
|
||||||
|
98AB2E351CAD423B0089BB98 /* PlatformThreads.h */,
|
||||||
|
98AB2E361CAD423B0089BB98 /* RtpReorderQueue.c */,
|
||||||
|
98AB2E371CAD423B0089BB98 /* RtpReorderQueue.h */,
|
||||||
|
98AB2E381CAD423B0089BB98 /* Rtsp.h */,
|
||||||
|
98AB2E391CAD423B0089BB98 /* RtspConnection.c */,
|
||||||
|
98AB2E3A1CAD423B0089BB98 /* RtspParser.c */,
|
||||||
|
98AB2E3B1CAD423B0089BB98 /* SdpGenerator.c */,
|
||||||
|
98AB2E3C1CAD423B0089BB98 /* Video.h */,
|
||||||
|
98AB2E3D1CAD423B0089BB98 /* VideoDepacketizer.c */,
|
||||||
|
98AB2E3E1CAD423B0089BB98 /* VideoStream.c */,
|
||||||
|
);
|
||||||
|
name = src;
|
||||||
|
path = "moonlight-common-c/src";
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
FB290E2519B37A4E004C83CF = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
9857AEED1EBE85D50084F99E /* reedsolomon */,
|
||||||
|
98AB2E191CAD423B0089BB98 /* src */,
|
||||||
|
98AB2DEF1CAD422B0089BB98 /* enet */,
|
||||||
|
FB290E2F19B37A4E004C83CF /* Products */,
|
||||||
|
);
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
FB290E2F19B37A4E004C83CF /* Products */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
FB290E2E19B37A4E004C83CF /* libmoonlight-common.a */,
|
||||||
|
);
|
||||||
|
name = Products;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
|
/* End PBXGroup section */
|
||||||
|
|
||||||
|
/* Begin PBXNativeTarget section */
|
||||||
|
FB290E2D19B37A4E004C83CF /* moonlight-common */ = {
|
||||||
|
isa = PBXNativeTarget;
|
||||||
|
buildConfigurationList = FB290E3219B37A4E004C83CF /* Build configuration list for PBXNativeTarget "moonlight-common" */;
|
||||||
|
buildPhases = (
|
||||||
|
FB290E2A19B37A4E004C83CF /* Sources */,
|
||||||
|
FB290E2B19B37A4E004C83CF /* Frameworks */,
|
||||||
|
);
|
||||||
|
buildRules = (
|
||||||
|
);
|
||||||
|
dependencies = (
|
||||||
|
);
|
||||||
|
name = "moonlight-common";
|
||||||
|
productName = "limelight-common";
|
||||||
|
productReference = FB290E2E19B37A4E004C83CF /* libmoonlight-common.a */;
|
||||||
|
productType = "com.apple.product-type.library.static";
|
||||||
|
};
|
||||||
|
/* End PBXNativeTarget section */
|
||||||
|
|
||||||
|
/* Begin PBXProject section */
|
||||||
|
FB290E2619B37A4E004C83CF /* Project object */ = {
|
||||||
|
isa = PBXProject;
|
||||||
|
attributes = {
|
||||||
|
LastUpgradeCheck = 0920;
|
||||||
|
ORGANIZATIONNAME = "Moonlight Stream";
|
||||||
|
};
|
||||||
|
buildConfigurationList = FB290E2919B37A4E004C83CF /* Build configuration list for PBXProject "moonlight-common_mac" */;
|
||||||
|
compatibilityVersion = "Xcode 8.0";
|
||||||
|
developmentRegion = English;
|
||||||
|
hasScannedForEncodings = 0;
|
||||||
|
knownRegions = (
|
||||||
|
en,
|
||||||
|
);
|
||||||
|
mainGroup = FB290E2519B37A4E004C83CF;
|
||||||
|
productRefGroup = FB290E2F19B37A4E004C83CF /* Products */;
|
||||||
|
projectDirPath = "";
|
||||||
|
projectRoot = "";
|
||||||
|
targets = (
|
||||||
|
FB290E2D19B37A4E004C83CF /* moonlight-common */,
|
||||||
|
);
|
||||||
|
};
|
||||||
|
/* End PBXProject section */
|
||||||
|
|
||||||
|
/* Begin PBXSourcesBuildPhase section */
|
||||||
|
FB290E2A19B37A4E004C83CF /* Sources */ = {
|
||||||
|
isa = PBXSourcesBuildPhase;
|
||||||
|
buildActionMask = 2147483647;
|
||||||
|
files = (
|
||||||
|
98AB2E401CAD425A0089BB98 /* AudioStream.c in Sources */,
|
||||||
|
98AB2E411CAD425A0089BB98 /* ByteBuffer.c in Sources */,
|
||||||
|
98AB2E421CAD425A0089BB98 /* Connection.c in Sources */,
|
||||||
|
98AB2E431CAD425A0089BB98 /* ControlStream.c in Sources */,
|
||||||
|
98AB2E441CAD425A0089BB98 /* FakeCallbacks.c in Sources */,
|
||||||
|
98AB2E451CAD425A0089BB98 /* InputStream.c in Sources */,
|
||||||
|
98AB2E461CAD425A0089BB98 /* LinkedBlockingQueue.c in Sources */,
|
||||||
|
98AB2E471CAD425A0089BB98 /* Misc.c in Sources */,
|
||||||
|
98AB2E481CAD425A0089BB98 /* Platform.c in Sources */,
|
||||||
|
98AB2E491CAD425A0089BB98 /* PlatformSockets.c in Sources */,
|
||||||
|
98AB2E4A1CAD425A0089BB98 /* RtpReorderQueue.c in Sources */,
|
||||||
|
98AB2E4B1CAD425A0089BB98 /* RtspConnection.c in Sources */,
|
||||||
|
98AB2E4C1CAD425A0089BB98 /* RtspParser.c in Sources */,
|
||||||
|
98AB2E4D1CAD425A0089BB98 /* SdpGenerator.c in Sources */,
|
||||||
|
98AB2E4E1CAD425A0089BB98 /* VideoDepacketizer.c in Sources */,
|
||||||
|
9857AEEA1EBE85A20084F99E /* RtpFecQueue.c in Sources */,
|
||||||
|
98AB2E4F1CAD425A0089BB98 /* VideoStream.c in Sources */,
|
||||||
|
98AB2E501CAD427A0089BB98 /* callbacks.c in Sources */,
|
||||||
|
98AB2E511CAD427A0089BB98 /* compress.c in Sources */,
|
||||||
|
98AB2E521CAD427A0089BB98 /* host.c in Sources */,
|
||||||
|
98AB2E531CAD427A0089BB98 /* list.c in Sources */,
|
||||||
|
98AB2E541CAD427A0089BB98 /* packet.c in Sources */,
|
||||||
|
98AB2E551CAD427A0089BB98 /* peer.c in Sources */,
|
||||||
|
98AB2E561CAD427A0089BB98 /* protocol.c in Sources */,
|
||||||
|
9857AEF01EBE85E10084F99E /* rs.c in Sources */,
|
||||||
|
98AB2E571CAD427A0089BB98 /* unix.c in Sources */,
|
||||||
|
98AB2E581CAD427A0089BB98 /* win32.c in Sources */,
|
||||||
|
);
|
||||||
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
};
|
||||||
|
/* End PBXSourcesBuildPhase section */
|
||||||
|
|
||||||
|
/* Begin XCBuildConfiguration section */
|
||||||
|
FB290E3019B37A4E004C83CF /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "Mac Developer";
|
||||||
|
COPY_PHASE_STRIP = NO;
|
||||||
|
DEFINES_MODULE = YES;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
ENABLE_TESTABILITY = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_DYNAMIC_NO_PIC = NO;
|
||||||
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||||
|
LC_DEBUG,
|
||||||
|
"DEBUG=1",
|
||||||
|
"$(inherited)",
|
||||||
|
);
|
||||||
|
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||||
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
FB290E3119B37A4E004C83CF /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||||
|
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||||
|
CLANG_CXX_LIBRARY = "libc++";
|
||||||
|
CLANG_ENABLE_MODULES = YES;
|
||||||
|
CLANG_ENABLE_OBJC_ARC = YES;
|
||||||
|
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||||
|
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_COMMA = YES;
|
||||||
|
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||||
|
CLANG_WARN_EMPTY_BODY = YES;
|
||||||
|
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||||
|
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||||
|
CLANG_WARN_INT_CONVERSION = YES;
|
||||||
|
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||||
|
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||||
|
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||||
|
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||||
|
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||||
|
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||||
|
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||||
|
CODE_SIGN_IDENTITY = "3rd Party Mac Developer Application";
|
||||||
|
COPY_PHASE_STRIP = YES;
|
||||||
|
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||||
|
DEFINES_MODULE = YES;
|
||||||
|
ENABLE_NS_ASSERTIONS = NO;
|
||||||
|
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||||
|
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||||
|
GCC_ENABLE_OBJC_EXCEPTIONS = YES;
|
||||||
|
GCC_NO_COMMON_BLOCKS = YES;
|
||||||
|
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||||
|
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||||
|
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||||
|
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||||
|
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||||
|
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.10;
|
||||||
|
PROVISIONING_PROFILE = "";
|
||||||
|
SDKROOT = macosx;
|
||||||
|
SKIP_INSTALL = YES;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
FB290E3319B37A4E004C83CF /* Debug */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ARCHS = "$(ARCHS_STANDARD)";
|
||||||
|
CODE_SIGN_IDENTITY = "Mac Developer";
|
||||||
|
EXECUTABLE_PREFIX = lib;
|
||||||
|
HEADER_SEARCH_PATHS = (
|
||||||
|
"moonlight-common-c/enet/include",
|
||||||
|
"../libs/**",
|
||||||
|
);
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
ONLY_ACTIVE_ARCH = NO;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SDKROOT = macosx10.13;
|
||||||
|
SUPPORTED_PLATFORMS = macosx;
|
||||||
|
};
|
||||||
|
name = Debug;
|
||||||
|
};
|
||||||
|
FB290E3419B37A4E004C83CF /* Release */ = {
|
||||||
|
isa = XCBuildConfiguration;
|
||||||
|
buildSettings = {
|
||||||
|
ARCHS = "$(ARCHS_STANDARD)";
|
||||||
|
CODE_SIGN_IDENTITY = "Mac Developer";
|
||||||
|
EXECUTABLE_PREFIX = lib;
|
||||||
|
GCC_OPTIMIZATION_LEVEL = 0;
|
||||||
|
HEADER_SEARCH_PATHS = (
|
||||||
|
"moonlight-common-c/enet/include",
|
||||||
|
"../libs/**",
|
||||||
|
);
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||||
|
MACOSX_DEPLOYMENT_TARGET = 10.13;
|
||||||
|
ONLY_ACTIVE_ARCH = NO;
|
||||||
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SDKROOT = macosx10.13;
|
||||||
|
SUPPORTED_PLATFORMS = macosx;
|
||||||
|
};
|
||||||
|
name = Release;
|
||||||
|
};
|
||||||
|
/* End XCBuildConfiguration section */
|
||||||
|
|
||||||
|
/* Begin XCConfigurationList section */
|
||||||
|
FB290E2919B37A4E004C83CF /* Build configuration list for PBXProject "moonlight-common_mac" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
FB290E3019B37A4E004C83CF /* Debug */,
|
||||||
|
FB290E3119B37A4E004C83CF /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
FB290E3219B37A4E004C83CF /* Build configuration list for PBXNativeTarget "moonlight-common" */ = {
|
||||||
|
isa = XCConfigurationList;
|
||||||
|
buildConfigurations = (
|
||||||
|
FB290E3319B37A4E004C83CF /* Debug */,
|
||||||
|
FB290E3419B37A4E004C83CF /* Release */,
|
||||||
|
);
|
||||||
|
defaultConfigurationIsVisible = 0;
|
||||||
|
defaultConfigurationName = Release;
|
||||||
|
};
|
||||||
|
/* End XCConfigurationList section */
|
||||||
|
};
|
||||||
|
rootObject = FB290E2619B37A4E004C83CF /* Project object */;
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>IDESourceControlProjectFavoriteDictionaryKey</key>
|
||||||
|
<false/>
|
||||||
|
<key>IDESourceControlProjectIdentifier</key>
|
||||||
|
<string>662F3EBE-A540-4F33-A434-3BBB22ECCB12</string>
|
||||||
|
<key>IDESourceControlProjectName</key>
|
||||||
|
<string>limelight-common</string>
|
||||||
|
<key>IDESourceControlProjectOriginsDictionary</key>
|
||||||
|
<dict>
|
||||||
|
<key>151E8452-E928-4FE9-BF31-5F5C490B9DD4</key>
|
||||||
|
<string>ssh://github.com/limelight-stream/limelight-common-c.git</string>
|
||||||
|
</dict>
|
||||||
|
<key>IDESourceControlProjectPath</key>
|
||||||
|
<string>limelight-common.xcodeproj/project.xcworkspace</string>
|
||||||
|
<key>IDESourceControlProjectRelativeInstallPathDictionary</key>
|
||||||
|
<dict>
|
||||||
|
<key>151E8452-E928-4FE9-BF31-5F5C490B9DD4</key>
|
||||||
|
<string>../..</string>
|
||||||
|
</dict>
|
||||||
|
<key>IDESourceControlProjectURL</key>
|
||||||
|
<string>ssh://github.com/limelight-stream/limelight-common-c.git</string>
|
||||||
|
<key>IDESourceControlProjectVersion</key>
|
||||||
|
<integer>110</integer>
|
||||||
|
<key>IDESourceControlProjectWCCIdentifier</key>
|
||||||
|
<string>151E8452-E928-4FE9-BF31-5F5C490B9DD4</string>
|
||||||
|
<key>IDESourceControlProjectWCConfigurations</key>
|
||||||
|
<array>
|
||||||
|
<dict>
|
||||||
|
<key>IDESourceControlRepositoryExtensionIdentifierKey</key>
|
||||||
|
<string>public.vcs.git</string>
|
||||||
|
<key>IDESourceControlWCCIdentifierKey</key>
|
||||||
|
<string>151E8452-E928-4FE9-BF31-5F5C490B9DD4</string>
|
||||||
|
<key>IDESourceControlWCCName</key>
|
||||||
|
<string>limelight-common-c</string>
|
||||||
|
</dict>
|
||||||
|
</array>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "A4B0849259F9566B0CBA84A6D3D4A0F895C03123",
|
||||||
|
"DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
|
||||||
|
|
||||||
|
},
|
||||||
|
"DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
|
||||||
|
"584110FE5ABD5BCB5065B76A98D3F8000D0644EC" : 0,
|
||||||
|
"A4B0849259F9566B0CBA84A6D3D4A0F895C03123" : 0,
|
||||||
|
"EB99D631D5149240E91F8D168F0F298D7A5BAA89" : 0
|
||||||
|
},
|
||||||
|
"DVTSourceControlWorkspaceBlueprintIdentifierKey" : "40250820-914C-4FB3-9CF1-3DB8A02E7012",
|
||||||
|
"DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
|
||||||
|
"584110FE5ABD5BCB5065B76A98D3F8000D0644EC" : "moonlight-ios\/moonlight-common\/moonlight-common-c\/enet\/",
|
||||||
|
"A4B0849259F9566B0CBA84A6D3D4A0F895C03123" : "moonlight-ios\/",
|
||||||
|
"EB99D631D5149240E91F8D168F0F298D7A5BAA89" : "moonlight-ios\/moonlight-common\/moonlight-common-c\/"
|
||||||
|
},
|
||||||
|
"DVTSourceControlWorkspaceBlueprintNameKey" : "moonlight-common",
|
||||||
|
"DVTSourceControlWorkspaceBlueprintVersion" : 204,
|
||||||
|
"DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "moonlight-common\/moonlight-common.xcodeproj",
|
||||||
|
"DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
|
||||||
|
{
|
||||||
|
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/cgutman\/enet.git",
|
||||||
|
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
|
||||||
|
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "584110FE5ABD5BCB5065B76A98D3F8000D0644EC"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:moonlight-stream\/moonlight-ios.git",
|
||||||
|
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
|
||||||
|
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "A4B0849259F9566B0CBA84A6D3D4A0F895C03123"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/moonlight-stream\/moonlight-common-c.git",
|
||||||
|
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
|
||||||
|
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "EB99D631D5149240E91F8D168F0F298D7A5BAA89"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||