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.
|
||||
//
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@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) NSManagedObjectModel *managedObjectModel;
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
static NSOperationQueue* mainQueue;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
[[UILabel appearance] setFont:[UIFont fontWithName:@"Roboto-Regular" size:[UIFont systemFontSize]]];
|
||||
@@ -57,7 +58,7 @@ static NSOperationQueue* mainQueue;
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application
|
||||
{
|
||||
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
|
||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
}
|
||||
|
||||
@@ -76,6 +77,17 @@ static NSOperationQueue* mainQueue;
|
||||
// Saves changes in the application's managed object context before the application terminates.
|
||||
[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
|
||||
{
|
||||
@@ -155,7 +167,11 @@ static NSOperationQueue* mainQueue;
|
||||
}
|
||||
|
||||
- (NSURL*) getStoreURL {
|
||||
#if TARGET_OS_IPHONE
|
||||
return [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"Limelight_iOS.sqlite"];
|
||||
#else
|
||||
return [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"moonlight_mac.sqlite"];
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -14,7 +14,8 @@
|
||||
|
||||
@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;
|
||||
- (void) updateHost:(TemporaryHost*)host;
|
||||
|
||||
@@ -22,11 +22,20 @@
|
||||
// HACK: Avoid calling [UIApplication delegate] off the UI thread to keep
|
||||
// Main Thread Checker happy.
|
||||
if ([NSThread isMainThread]) {
|
||||
#if TARGET_OS_IPHONE
|
||||
_appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
|
||||
#else
|
||||
_appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
|
||||
#endif
|
||||
|
||||
}
|
||||
else {
|
||||
dispatch_sync(dispatch_get_main_queue(), ^{
|
||||
#if TARGET_OS_IPHONE
|
||||
_appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
|
||||
#else
|
||||
_appDelegate = (AppDelegate *)[[NSApplication sharedApplication] delegate];
|
||||
#endif
|
||||
});
|
||||
}
|
||||
|
||||
@@ -53,7 +62,8 @@
|
||||
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:^{
|
||||
Settings* settingsToSave = [self retrieveSettings];
|
||||
@@ -63,6 +73,7 @@
|
||||
settingsToSave.height = [NSNumber numberWithInteger:height];
|
||||
settingsToSave.width = [NSNumber numberWithInteger:width];
|
||||
settingsToSave.onscreenControls = [NSNumber numberWithInteger:onscreenControls];
|
||||
settingsToSave.streamingRemotely = [NSNumber numberWithInteger:streamingRemotely];
|
||||
|
||||
[self saveData];
|
||||
}];
|
||||
|
||||
@@ -18,5 +18,6 @@
|
||||
@property (nonatomic, retain) NSNumber * width;
|
||||
@property (nonatomic, retain) NSNumber * onscreenControls;
|
||||
@property (nonatomic, retain) NSString * uniqueId;
|
||||
@property (nonatomic, retain) NSNumber * streamingRemotely;
|
||||
|
||||
@end
|
||||
|
||||
@@ -17,5 +17,6 @@
|
||||
@dynamic width;
|
||||
@dynamic onscreenControls;
|
||||
@dynamic uniqueId;
|
||||
@dynamic streamingRemotely;
|
||||
|
||||
@end
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
@property (nonatomic, retain) NSNumber * width;
|
||||
@property (nonatomic, retain) NSNumber * onscreenControls;
|
||||
@property (nonatomic, retain) NSString * uniqueId;
|
||||
@property (nonatomic, retain) NSNumber * streamingRemotely;
|
||||
|
||||
- (id) initFromSettings:(Settings*)settings;
|
||||
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
self.width = settings.width;
|
||||
self.onscreenControls = settings.onscreenControls;
|
||||
self.uniqueId = settings.uniqueId;
|
||||
self.streamingRemotely = settings.streamingRemotely;
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
|
||||
// Swift
|
||||
#import "Moonlight-Swift.h"
|
||||
#if TARGET_OS_IPHONE
|
||||
#else
|
||||
#import "Gamepad.h"
|
||||
#endif
|
||||
@class Controller;
|
||||
|
||||
@class OnScreenControls;
|
||||
@@ -17,8 +21,16 @@
|
||||
@interface ControllerSupport : NSObject
|
||||
|
||||
-(id) init;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
-(void) initAutoOnScreenControlMode:(OnScreenControls*)osc;
|
||||
-(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) updateRightStick:(Controller*)controller x:(short)x y:(short)y;
|
||||
@@ -32,7 +44,6 @@
|
||||
-(void) clearButtonFlag:(Controller*)controller flags:(int)flags;
|
||||
|
||||
-(void) updateFinished:(Controller*)controller;
|
||||
-(Controller*) getOscController;
|
||||
|
||||
+(int) getConnectedGamepadMask;
|
||||
|
||||
|
||||
@@ -7,7 +7,14 @@
|
||||
//
|
||||
|
||||
#import "ControllerSupport.h"
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#import "OnScreenControls.h"
|
||||
#else
|
||||
#import "Gamepad.h"
|
||||
#import "Control.h"
|
||||
#endif
|
||||
|
||||
#import "DataManager.h"
|
||||
#include "Limelight.h"
|
||||
|
||||
@@ -21,17 +28,19 @@
|
||||
NSLock *_controllerStreamLock;
|
||||
NSMutableDictionary *_controllers;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
OnScreenControls *_osc;
|
||||
bool _oscEnabled;
|
||||
|
||||
// This controller object is shared between on-screen controls
|
||||
// and player 0
|
||||
Controller *_player0osc;
|
||||
|
||||
char _controllerNumbers;
|
||||
|
||||
#define EMULATING_SELECT 0x1
|
||||
#define EMULATING_SPECIAL 0x2
|
||||
#endif
|
||||
|
||||
bool _oscEnabled;
|
||||
char _controllerNumbers;
|
||||
}
|
||||
|
||||
// UPDATE_BUTTON_FLAG(controller, flag, pressed)
|
||||
@@ -76,6 +85,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
-(void) handleSpecialCombosReleased:(Controller*)controller releasedButtons:(int)releasedButtons
|
||||
{
|
||||
if ((controller.emulatingButtonFlags & EMULATING_SELECT) &&
|
||||
@@ -110,21 +120,23 @@
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
-(void) updateButtonFlags:(Controller*)controller flags:(int)flags
|
||||
{
|
||||
@synchronized(controller) {
|
||||
int releasedButtons = (controller.lastButtonFlags ^ flags) & ~flags;
|
||||
int pressedButtons = (controller.lastButtonFlags ^ flags) & flags;
|
||||
|
||||
controller.lastButtonFlags = flags;
|
||||
|
||||
// This must be called before handleSpecialCombosPressed
|
||||
// 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 handleSpecialCombosPressed:controller pressedButtons:pressedButtons];
|
||||
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +144,9 @@
|
||||
{
|
||||
@synchronized(controller) {
|
||||
controller.lastButtonFlags |= flags;
|
||||
#if TARGET_OS_IPHONE
|
||||
[self handleSpecialCombosPressed:controller pressedButtons:flags];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -140,7 +154,9 @@
|
||||
{
|
||||
@synchronized(controller) {
|
||||
controller.lastButtonFlags &= ~flags;
|
||||
#if TARGET_OS_IPHONE
|
||||
[self handleSpecialCombosReleased:controller releasedButtons:flags];
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
@@ -242,6 +258,7 @@
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
-(void) updateAutoOnScreenControlMode
|
||||
{
|
||||
// Auto on-screen control support may not be enabled
|
||||
@@ -277,6 +294,7 @@
|
||||
|
||||
[self updateAutoOnScreenControlMode];
|
||||
}
|
||||
#endif
|
||||
|
||||
-(void) assignController:(GCController*)controller {
|
||||
for (int i = 0; i < 4; i++) {
|
||||
@@ -285,6 +303,7 @@
|
||||
controller.playerIndex = i;
|
||||
|
||||
Controller* limeController;
|
||||
#if TARGET_OS_IPHONE
|
||||
if (i == 0) {
|
||||
// Player 0 shares a controller object with the on-screen controls
|
||||
limeController = _player0osc;
|
||||
@@ -292,6 +311,10 @@
|
||||
limeController = [[Controller alloc] init];
|
||||
limeController.playerIndex = i;
|
||||
}
|
||||
#else
|
||||
limeController = [[Controller alloc] init];
|
||||
limeController.playerIndex = i;
|
||||
#endif
|
||||
|
||||
[_controllers setObject:limeController forKey:[NSNumber numberWithInteger:controller.playerIndex]];
|
||||
|
||||
@@ -301,9 +324,40 @@
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
-(Controller*) getOscController {
|
||||
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 mask = 0;
|
||||
@@ -312,6 +366,7 @@
|
||||
mask |= 1 << i;
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
OnScreenControlsLevel level = (OnScreenControlsLevel)[[dataMan getSettings].onscreenControls integerValue];
|
||||
|
||||
@@ -320,7 +375,7 @@
|
||||
if (level != OnScreenControlsLevelOff) {
|
||||
mask |= 1;
|
||||
}
|
||||
|
||||
#endif
|
||||
return mask;
|
||||
}
|
||||
|
||||
@@ -331,17 +386,27 @@
|
||||
_controllerStreamLock = [[NSLock alloc] init];
|
||||
_controllers = [[NSMutableDictionary alloc] init];
|
||||
_controllerNumbers = 0;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
_player0osc = [[Controller alloc] init];
|
||||
_player0osc.playerIndex = 0;
|
||||
|
||||
DataManager* dataMan = [[DataManager alloc] init];
|
||||
_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]);
|
||||
for (GCController* controller in [GCController controllers]) {
|
||||
[self assignController:controller];
|
||||
[self registerControllerCallbacks:controller];
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
[self updateAutoOnScreenControlMode];
|
||||
#endif
|
||||
}
|
||||
|
||||
self.connectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||
@@ -353,8 +418,10 @@
|
||||
// Register callbacks on the new controller
|
||||
[self registerControllerCallbacks:controller];
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
// Re-evaluate the on-screen control mode
|
||||
[self updateAutoOnScreenControlMode];
|
||||
#endif
|
||||
}];
|
||||
self.disconnectObserver = [[NSNotificationCenter defaultCenter] addObserverForName:GCControllerDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
|
||||
Log(LOG_I, @"Controller disconnected!");
|
||||
@@ -367,11 +434,12 @@
|
||||
// Inform the server of the updated active gamepads before removing this controller
|
||||
[self updateFinished:[_controllers objectForKey:[NSNumber numberWithInteger:controller.playerIndex]]];
|
||||
[_controllers removeObjectForKey:[NSNumber numberWithInteger:controller.playerIndex]];
|
||||
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
// Re-evaluate the on-screen control mode
|
||||
[self updateAutoOnScreenControlMode];
|
||||
#endif
|
||||
}];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
// 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"
|
||||
|
||||
@protocol EdgeDetectionDelegate <NSObject>
|
||||
|
||||
@@ -5,14 +5,20 @@
|
||||
//
|
||||
|
||||
#import <Availability.h>
|
||||
#include <TargetConditionals.h>
|
||||
|
||||
#ifndef __IPHONE_3_0
|
||||
#warning "This project uses features only available in iOS SDK 3.0 and later."
|
||||
#endif
|
||||
|
||||
#ifdef __OBJC__
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <UIKit/UIKit.h>
|
||||
#elif TARGET_OS_MAC
|
||||
#import <AppKit/AppKit.h>
|
||||
#endif
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <CoreData/CoreData.h>
|
||||
#import "Logger.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<?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">
|
||||
<attribute name="id" attributeType="String" 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="mac" optional="YES" 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"/>
|
||||
<relationship name="appList" optional="YES" toMany="YES" deletionRule="Cascade" destinationEntity="App" inverseName="host" inverseEntity="App" syncable="YES"/>
|
||||
</entity>
|
||||
<entity name="Settings" representedClassName="Settings" syncable="YES">
|
||||
<attribute name="bitrate" attributeType="Integer 32" defaultValueString="10000" syncable="YES"/>
|
||||
<attribute name="framerate" attributeType="Integer 32" defaultValueString="60" syncable="YES"/>
|
||||
<attribute name="height" attributeType="Integer 32" defaultValueString="720" syncable="YES"/>
|
||||
<attribute name="onscreenControls" attributeType="Integer 32" defaultValueString="1" syncable="YES"/>
|
||||
<attribute name="bitrate" attributeType="Integer 32" defaultValueString="10000" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="framerate" attributeType="Integer 32" defaultValueString="60" usesScalarValueType="NO" syncable="YES"/>
|
||||
<attribute name="height" attributeType="Integer 32" defaultValueString="720" usesScalarValueType="NO" 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="width" attributeType="Integer 32" defaultValueString="1280" syncable="YES"/>
|
||||
<attribute name="width" attributeType="Integer 32" defaultValueString="1280" usesScalarValueType="NO" syncable="YES"/>
|
||||
</entity>
|
||||
<elements>
|
||||
<element name="App" positionX="0" positionY="54" width="128" height="105"/>
|
||||
<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>
|
||||
</model>
|
||||
@@ -16,10 +16,16 @@
|
||||
self.statusMessage = @"App asset has no status message";
|
||||
self.statusCode = -1;
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
- (UIImage*) getImage {
|
||||
UIImage* appImage = [[UIImage alloc] initWithData:self.data];
|
||||
return appImage;
|
||||
}
|
||||
#else
|
||||
- (NSImage*) getImage {
|
||||
return nil;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@@ -18,16 +18,27 @@ static const double RETRY_DELAY = 2; // seconds
|
||||
static const int MAX_ATTEMPTS = 5;
|
||||
|
||||
- (void) main {
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
UIImage* appImage = nil;
|
||||
#else
|
||||
NSImage* appImage = nil;
|
||||
#endif
|
||||
|
||||
int attempts = 0;
|
||||
while (![self isCancelled] && appImage == nil && attempts++ < MAX_ATTEMPTS) {
|
||||
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_host.activeAddress uniqueId:[IdManager getUniqueId] deviceName:deviceName cert:[CryptoManager readCertFromFile]];
|
||||
AppAssetResponse* appAssetResp = [[AppAssetResponse alloc] init];
|
||||
[hMan executeRequestSynchronously:[HttpRequest requestForResponse:appAssetResp withUrlRequest:[hMan newAppAssetRequestWithAppId:self.app.id]]];
|
||||
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
appImage = [UIImage imageWithData:appAssetResp.data];
|
||||
self.app.image = UIImagePNGRepresentation(appImage);
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
if (![self isCancelled] && appImage == nil) {
|
||||
[NSThread sleepForTimeInterval:RETRY_DELAY];
|
||||
|
||||
22
Limelight/Network/ConnectionHelper.h
Normal file
@@ -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 */
|
||||
40
Limelight/Network/ConnectionHelper.m
Normal file
@@ -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
|
||||
|
||||
@@ -61,7 +61,7 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit)
|
||||
// A frame was lost due to OOM condition
|
||||
return DR_NEED_IDR;
|
||||
}
|
||||
|
||||
|
||||
PLENTRY entry = decodeUnit->bufferList;
|
||||
while (entry != NULL) {
|
||||
// Submit parameter set NALUs directly since no copy is required by the decoder
|
||||
@@ -76,10 +76,10 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit)
|
||||
memcpy(&data[offset], entry->data, entry->length);
|
||||
offset += entry->length;
|
||||
}
|
||||
|
||||
|
||||
entry = entry->next;
|
||||
}
|
||||
|
||||
|
||||
// This function will take our picture data buffer
|
||||
return [renderer submitDecodeBuffer:data length:offset bufferType:BUFFER_TYPE_PICDATA];
|
||||
}
|
||||
@@ -87,42 +87,47 @@ int DrSubmitDecodeUnit(PDECODE_UNIT decodeUnit)
|
||||
int ArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* context, int flags)
|
||||
{
|
||||
int err;
|
||||
|
||||
|
||||
// We only support stereo for now
|
||||
assert(audioConfiguration == AUDIO_CONFIGURATION_STEREO);
|
||||
|
||||
|
||||
opusDecoder = opus_decoder_create(opusConfig->sampleRate,
|
||||
opusConfig->channelCount,
|
||||
&err);
|
||||
|
||||
|
||||
audioLock = [[NSLock alloc] init];
|
||||
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
|
||||
// Configure the audio session for our app
|
||||
NSError *audioSessionError = nil;
|
||||
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
|
||||
|
||||
|
||||
[audioSession setPreferredSampleRate:opusConfig->sampleRate error:&audioSessionError];
|
||||
[audioSession setCategory: AVAudioSessionCategoryPlayback error: &audioSessionError];
|
||||
[audioSession setPreferredOutputNumberOfChannels:opusConfig->channelCount error:&audioSessionError];
|
||||
[audioSession setPreferredIOBufferDuration:0.005 error:&audioSessionError];
|
||||
[audioSession setActive: YES error: &audioSessionError];
|
||||
|
||||
|
||||
#endif
|
||||
OSStatus status;
|
||||
|
||||
|
||||
AudioComponentDescription audioDesc;
|
||||
audioDesc.componentType = kAudioUnitType_Output;
|
||||
#if TARGET_OS_IPHONE
|
||||
audioDesc.componentSubType = kAudioUnitSubType_RemoteIO;
|
||||
#endif
|
||||
audioDesc.componentFlags = 0;
|
||||
audioDesc.componentFlagsMask = 0;
|
||||
audioDesc.componentManufacturer = kAudioUnitManufacturer_Apple;
|
||||
|
||||
|
||||
status = AudioComponentInstanceNew(AudioComponentFindNext(NULL, &audioDesc), &audioUnit);
|
||||
|
||||
|
||||
if (status) {
|
||||
Log(LOG_E, @"Unable to instantiate new AudioComponent: %d", (int32_t)status);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
AudioStreamBasicDescription audioFormat = {0};
|
||||
audioFormat.mSampleRate = opusConfig->sampleRate;
|
||||
audioFormat.mBitsPerChannel = 16;
|
||||
@@ -133,7 +138,7 @@ int ArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, v
|
||||
audioFormat.mBytesPerPacket = audioFormat.mBytesPerFrame;
|
||||
audioFormat.mFramesPerPacket = audioFormat.mBytesPerPacket / audioFormat.mBytesPerFrame;
|
||||
audioFormat.mReserved = 0;
|
||||
|
||||
|
||||
status = AudioUnitSetProperty(audioUnit,
|
||||
kAudioUnitProperty_StreamFormat,
|
||||
kAudioUnitScope_Input,
|
||||
@@ -144,11 +149,11 @@ int ArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, v
|
||||
Log(LOG_E, @"Unable to set audio unit to input: %d", (int32_t)status);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
AURenderCallbackStruct callbackStruct = {0};
|
||||
callbackStruct.inputProc = playbackCallback;
|
||||
callbackStruct.inputProcRefCon = NULL;
|
||||
|
||||
|
||||
status = AudioUnitSetProperty(audioUnit,
|
||||
kAudioUnitProperty_SetRenderCallback,
|
||||
kAudioUnitScope_Input,
|
||||
@@ -159,19 +164,19 @@ int ArInit(int audioConfiguration, POPUS_MULTISTREAM_CONFIGURATION opusConfig, v
|
||||
Log(LOG_E, @"Unable to set audio unit callback: %d", (int32_t)status);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status = AudioUnitInitialize(audioUnit);
|
||||
if (status) {
|
||||
Log(LOG_E, @"Unable to initialize audioUnit: %d", (int32_t)status);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
status = AudioOutputUnitStart(audioUnit);
|
||||
if (status) {
|
||||
Log(LOG_E, @"Unable to start audioUnit: %d", (int32_t)status);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
@@ -181,21 +186,21 @@ void ArCleanup(void)
|
||||
opus_decoder_destroy(opusDecoder);
|
||||
opusDecoder = NULL;
|
||||
}
|
||||
|
||||
|
||||
OSStatus status = AudioOutputUnitStop(audioUnit);
|
||||
if (status) {
|
||||
Log(LOG_E, @"Unable to stop audioUnit: %d", (int32_t)status);
|
||||
}
|
||||
|
||||
|
||||
status = AudioUnitUninitialize(audioUnit);
|
||||
if (status) {
|
||||
Log(LOG_E, @"Unable to uninitialize audioUnit: %d", (int32_t)status);
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
// Audio session is now inactive
|
||||
AVAudioSession* audioSession = [AVAudioSession sharedInstance];
|
||||
[audioSession setActive: YES error: nil];
|
||||
|
||||
#endif
|
||||
// This is safe because we're guaranteed that nobody
|
||||
// is touching this list now
|
||||
struct AUDIO_BUFFER_QUEUE_ENTRY *entry;
|
||||
@@ -213,18 +218,18 @@ void ArDecodeAndPlaySample(char* sampleData, int sampleLength)
|
||||
if (decodedLength > 0) {
|
||||
// Return of opus_decode is samples per channel
|
||||
decodedLength *= 4;
|
||||
|
||||
|
||||
struct AUDIO_BUFFER_QUEUE_ENTRY *newEntry = malloc(sizeof(*newEntry) + decodedLength);
|
||||
if (newEntry != NULL) {
|
||||
newEntry->next = NULL;
|
||||
newEntry->length = decodedLength;
|
||||
newEntry->offset = 0;
|
||||
memcpy(newEntry->data, decodedPcmBuffer, decodedLength);
|
||||
|
||||
|
||||
[audioLock lock];
|
||||
if (audioBufferQueueLength > MAX_QUEUE_ENTRIES) {
|
||||
Log(LOG_W, @"Audio player too slow. Dropping all decoded samples!");
|
||||
|
||||
|
||||
// Clear all values from the buffer queue
|
||||
struct AUDIO_BUFFER_QUEUE_ENTRY *entry;
|
||||
while (audioBufferQueue != NULL) {
|
||||
@@ -234,7 +239,7 @@ void ArDecodeAndPlaySample(char* sampleData, int sampleLength)
|
||||
free(entry);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (audioBufferQueue == NULL) {
|
||||
audioBufferQueue = newEntry;
|
||||
}
|
||||
@@ -246,7 +251,7 @@ void ArDecodeAndPlaySample(char* sampleData, int sampleLength)
|
||||
lastEntry->next = newEntry;
|
||||
}
|
||||
audioBufferQueueLength++;
|
||||
|
||||
|
||||
[audioLock unlock];
|
||||
}
|
||||
}
|
||||
@@ -310,63 +315,82 @@ void ClLogMessage(const char* format, ...)
|
||||
-(id) initWithConfig:(StreamConfiguration*)config renderer:(VideoDecoderRenderer*)myRenderer connectionCallbacks:(id<ConnectionCallbacks>)callbacks
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
||||
// Use a lock to ensure that only one thread is initializing
|
||||
// or deinitializing a connection at a time.
|
||||
if (initLock == nil) {
|
||||
initLock = [[NSLock alloc] init];
|
||||
}
|
||||
|
||||
|
||||
LiInitializeServerInformation(&_serverInfo);
|
||||
_serverInfo.address = [config.host cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
_serverInfo.serverInfoAppVersion = [config.appVersion cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
if (config.gfeVersion != nil) {
|
||||
_serverInfo.serverInfoGfeVersion = [config.gfeVersion cStringUsingEncoding:NSUTF8StringEncoding];
|
||||
}
|
||||
|
||||
|
||||
renderer = myRenderer;
|
||||
_callbacks = callbacks;
|
||||
|
||||
|
||||
LiInitializeStreamConfiguration(&_streamConfig);
|
||||
_streamConfig.width = config.width;
|
||||
_streamConfig.height = config.height;
|
||||
_streamConfig.fps = config.frameRate;
|
||||
_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
|
||||
// and this device has hardware decode for it (A9 and later)
|
||||
if (@available(iOS 11.0, *)) {
|
||||
// FIXME: Disabled due to incompatibility with iPhone X causing video
|
||||
// to freeze. Additionally, RFI is not supported so packet loss recovery
|
||||
// is worse with HEVC than H.264.
|
||||
|
||||
// Streaming with a limited bandwith will result in better quality with 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
|
||||
// reduce bandwidth usage while still gaining some image
|
||||
// quality improvement.
|
||||
_streamConfig.hevcBitratePercentageMultiplier = 75;
|
||||
|
||||
// FIXME: We should use 1024 when streaming remotely
|
||||
_streamConfig.packetSize = 1292;
|
||||
|
||||
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
|
||||
_streamConfig.hevcBitratePercentageMultiplier = 0;
|
||||
// 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]);
|
||||
memset(_streamConfig.remoteInputAesIv, 0, 16);
|
||||
int riKeyId = htonl(config.riKeyId);
|
||||
memcpy(_streamConfig.remoteInputAesIv, &riKeyId, sizeof(riKeyId));
|
||||
|
||||
|
||||
LiInitializeVideoCallbacks(&_drCallbacks);
|
||||
_drCallbacks.setup = DrDecoderSetup;
|
||||
_drCallbacks.submitDecodeUnit = DrSubmitDecodeUnit;
|
||||
|
||||
|
||||
// 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;
|
||||
|
||||
|
||||
LiInitializeAudioCallbacks(&_arCallbacks);
|
||||
_arCallbacks.init = ArInit;
|
||||
_arCallbacks.cleanup = ArCleanup;
|
||||
_arCallbacks.decodeAndPlaySample = ArDecodeAndPlaySample;
|
||||
|
||||
|
||||
LiInitializeConnectionCallbacks(&_clCallbacks);
|
||||
_clCallbacks.stageStarting = ClStageStarting;
|
||||
_clCallbacks.stageComplete = ClStageComplete;
|
||||
@@ -376,7 +400,7 @@ void ClLogMessage(const char* format, ...)
|
||||
_clCallbacks.displayMessage = ClDisplayMessage;
|
||||
_clCallbacks.displayTransientMessage = ClDisplayTransientMessage;
|
||||
_clCallbacks.logMessage = ClLogMessage;
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@@ -389,27 +413,27 @@ static OSStatus playbackCallback(void *inRefCon,
|
||||
// Notes: ioData contains buffers (may be more than one!)
|
||||
// Fill them up as much as you can. Remember to set the size value in each buffer to match how
|
||||
// much data is in the buffer.
|
||||
|
||||
|
||||
bool ranOutOfData = false;
|
||||
for (int i = 0; i < ioData->mNumberBuffers; i++) {
|
||||
ioData->mBuffers[i].mNumberChannels = 2;
|
||||
|
||||
|
||||
if (ranOutOfData) {
|
||||
ioData->mBuffers[i].mDataByteSize = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
if (ioData->mBuffers[i].mDataByteSize != 0) {
|
||||
int thisBufferOffset = 0;
|
||||
|
||||
|
||||
FillBufferAgain:
|
||||
// Make sure there's data to write
|
||||
if (ioData->mBuffers[i].mDataByteSize - thisBufferOffset == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
struct AUDIO_BUFFER_QUEUE_ENTRY *audioEntry = NULL;
|
||||
|
||||
|
||||
[audioLock lock];
|
||||
if (audioBufferQueue != NULL) {
|
||||
// Dequeue this entry temporarily
|
||||
@@ -418,26 +442,26 @@ static OSStatus playbackCallback(void *inRefCon,
|
||||
audioBufferQueueLength--;
|
||||
}
|
||||
[audioLock unlock];
|
||||
|
||||
|
||||
if (audioEntry == NULL) {
|
||||
// No data left
|
||||
ranOutOfData = true;
|
||||
ioData->mBuffers[i].mDataByteSize = thisBufferOffset;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
// Figure out how much data we can write
|
||||
int min = MIN(ioData->mBuffers[i].mDataByteSize - thisBufferOffset, audioEntry->length);
|
||||
|
||||
|
||||
// Copy data to the audio buffer
|
||||
memcpy(&ioData->mBuffers[i].mData[thisBufferOffset], &audioEntry->data[audioEntry->offset], min);
|
||||
thisBufferOffset += min;
|
||||
|
||||
|
||||
if (min < audioEntry->length) {
|
||||
// This entry still has unused data
|
||||
audioEntry->length -= min;
|
||||
audioEntry->offset += min;
|
||||
|
||||
|
||||
// Requeue the entry
|
||||
[audioLock lock];
|
||||
audioEntry->next = audioBufferQueue;
|
||||
@@ -448,7 +472,7 @@ static OSStatus playbackCallback(void *inRefCon,
|
||||
else {
|
||||
// This entry is fully depleted so free it
|
||||
free(audioEntry);
|
||||
|
||||
|
||||
// Try to grab another sample to fill this buffer with
|
||||
goto FillBufferAgain;
|
||||
}
|
||||
@@ -456,7 +480,7 @@ static OSStatus playbackCallback(void *inRefCon,
|
||||
ioData->mBuffers[i].mDataByteSize = thisBufferOffset;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return noErr;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
@property int frameRate;
|
||||
@property int bitRate;
|
||||
@property int riKeyId;
|
||||
@property int streamingRemotely;
|
||||
@property NSData* riKey;
|
||||
@property int gamepadMask;
|
||||
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
#import "StreamConfiguration.h"
|
||||
|
||||
@implementation StreamConfiguration
|
||||
@synthesize host, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask;
|
||||
@synthesize host, appID, width, height, frameRate, bitRate, riKeyId, riKey, gamepadMask, streamingRemotely;
|
||||
@end
|
||||
|
||||
@@ -12,7 +12,12 @@
|
||||
|
||||
@interface StreamManager : NSOperation
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
- (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;
|
||||
|
||||
@end
|
||||
|
||||
@@ -10,7 +10,11 @@
|
||||
#import "CryptoManager.h"
|
||||
#import "HttpManager.h"
|
||||
#import "Utils.h"
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#import "OnScreenControls.h"
|
||||
#endif
|
||||
|
||||
#import "StreamView.h"
|
||||
#import "ServerInfoResponse.h"
|
||||
#import "HttpResponse.h"
|
||||
@@ -19,11 +23,17 @@
|
||||
|
||||
@implementation StreamManager {
|
||||
StreamConfiguration* _config;
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
UIView* _renderView;
|
||||
#else
|
||||
NSView* _renderView;
|
||||
#endif
|
||||
id<ConnectionCallbacks> _callbacks;
|
||||
Connection* _connection;
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
- (id) initWithConfig:(StreamConfiguration*)config renderView:(UIView*)view connectionCallbacks:(id<ConnectionCallbacks>)callbacks {
|
||||
self = [super init];
|
||||
_config = config;
|
||||
@@ -33,7 +43,17 @@
|
||||
_config.riKeyId = arc4random();
|
||||
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 {
|
||||
[CryptoManager generateKeyPairUsingSSl];
|
||||
@@ -42,7 +62,7 @@
|
||||
|
||||
HttpManager* hMan = [[HttpManager alloc] initWithHost:_config.host
|
||||
uniqueId:uniqueId
|
||||
deviceName:@"roth"
|
||||
deviceName:deviceName
|
||||
cert:cert];
|
||||
|
||||
ServerInfoResponse* serverInfoResp = [[ServerInfoResponse alloc] init];
|
||||
@@ -75,14 +95,15 @@
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
// Set mouse delta factors from the screen resolution and stream size
|
||||
CGFloat screenScale = [[UIScreen mainScreen] scale];
|
||||
CGRect screenBounds = [[UIScreen mainScreen] bounds];
|
||||
CGSize screenSize = CGSizeMake(screenBounds.size.width * screenScale, screenBounds.size.height * screenScale);
|
||||
[((StreamView*)_renderView) setMouseDeltaFactors:_config.width / screenSize.width
|
||||
y:_config.height / screenSize.height];
|
||||
|
||||
#endif
|
||||
// Populate the config's version fields from serverinfo
|
||||
_config.appVersion = appversion;
|
||||
_config.gfeVersion = gfeVersion;
|
||||
|
||||
@@ -11,8 +11,11 @@
|
||||
@import AVFoundation;
|
||||
|
||||
@interface VideoDecoderRenderer : NSObject
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
- (id)initWithView:(UIView*)view;
|
||||
#else
|
||||
- (id)initWithView:(NSView*)view;
|
||||
#endif
|
||||
|
||||
- (void)setupWithVideoFormat:(int)videoFormat;
|
||||
|
||||
|
||||
@@ -11,7 +11,11 @@
|
||||
#include "Limelight.h"
|
||||
|
||||
@implementation VideoDecoderRenderer {
|
||||
#if TARGET_OS_IPHONE
|
||||
UIView *_view;
|
||||
#else
|
||||
NSView *_view;
|
||||
#endif
|
||||
|
||||
AVSampleBufferDisplayLayer* displayLayer;
|
||||
Boolean waitingForSps, waitingForPps, waitingForVps;
|
||||
@@ -27,7 +31,12 @@
|
||||
|
||||
displayLayer = [[AVSampleBufferDisplayLayer alloc] init];
|
||||
displayLayer.bounds = _view.bounds;
|
||||
#if TARGET_OS_IPHONE
|
||||
displayLayer.backgroundColor = [UIColor blackColor].CGColor;
|
||||
#else
|
||||
displayLayer.backgroundColor = [NSColor blackColor].CGColor;
|
||||
#endif
|
||||
|
||||
displayLayer.position = CGPointMake(CGRectGetMidX(_view.bounds), CGRectGetMidY(_view.bounds));
|
||||
displayLayer.videoGravity = AVLayerVideoGravityResizeAspect;
|
||||
|
||||
@@ -52,7 +61,7 @@
|
||||
formatDesc = nil;
|
||||
}
|
||||
}
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
- (id)initWithView:(UIView*)view
|
||||
{
|
||||
self = [super init];
|
||||
@@ -63,6 +72,20 @@
|
||||
|
||||
return self;
|
||||
}
|
||||
#else
|
||||
- (id)initWithView:(NSView*)view
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
_view = view;
|
||||
|
||||
[self reinitializeDisplayLayer];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
- (void)setupWithVideoFormat:(int)videoFormat
|
||||
{
|
||||
@@ -222,6 +245,8 @@
|
||||
const size_t parameterSetSizes[] = { [vpsData length], [spsData length], [ppsData length] };
|
||||
|
||||
Log(LOG_I, @"Constructing new HEVC format description");
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
if (@available(iOS 11.0, *)) {
|
||||
status = CMVideoFormatDescriptionCreateFromHEVCParameterSets(kCFAllocatorDefault,
|
||||
3, /* count of parameter sets */
|
||||
@@ -235,6 +260,21 @@
|
||||
// even though we said we couldn't support it. All we can do is 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) {
|
||||
Log(LOG_E, @"Failed to create HEVC format description: %d", (int)status);
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#import "ComputerScrollView.h"
|
||||
#import "TemporaryApp.h"
|
||||
#import "IdManager.h"
|
||||
#import "ConnectionHelper.h"
|
||||
|
||||
@implementation MainFrameViewController {
|
||||
NSOperationQueue* _opQueue;
|
||||
@@ -115,27 +116,10 @@ static NSMutableSet* hostList;
|
||||
}
|
||||
Log(LOG_I, @"Using cached app list: %d", usingCachedAppList);
|
||||
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
|
||||
[_discMan removeHostFromDiscovery:host];
|
||||
|
||||
// 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);
|
||||
break;
|
||||
}
|
||||
}
|
||||
AppListResponse* appListResp = [ConnectionHelper getAppListForHostWithHostIP:host.activeAddress deviceName:deviceName cert:_cert uniqueID:_uniqueId];
|
||||
|
||||
[_discMan addHostToDiscovery:host];
|
||||
|
||||
@@ -409,6 +393,7 @@ static NSMutableSet* hostList;
|
||||
_streamConfig.height = [streamSettings.height intValue];
|
||||
_streamConfig.width = [streamSettings.width intValue];
|
||||
_streamConfig.gamepadMask = [ControllerSupport getConnectedGamepadMask];
|
||||
_streamConfig.streamingRemotely = [streamSettings.streamingRemotely intValue];
|
||||
|
||||
[_appManager stopRetrieving];
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
@property (strong, nonatomic) IBOutlet UISegmentedControl *framerateSelector;
|
||||
@property (strong, nonatomic) IBOutlet UISegmentedControl *resolutionSelector;
|
||||
@property (strong, nonatomic) IBOutlet UISegmentedControl *onscreenControlSelector;
|
||||
@property (strong, nonatomic) IBOutlet UISegmentedControl *remoteSelector;
|
||||
|
||||
- (void) saveSettings;
|
||||
|
||||
|
||||
@@ -57,7 +57,8 @@ static NSString* bitrateFormat = @"Bitrate: %.1f Mbps";
|
||||
resolution = 0;
|
||||
}
|
||||
NSInteger onscreenControls = [currentSettings.onscreenControls integerValue];
|
||||
|
||||
NSInteger streamingRemotely = [currentSettings.streamingRemotely integerValue];
|
||||
[self.remoteSelector setSelectedSegmentIndex:streamingRemotely];
|
||||
[self.resolutionSelector setSelectedSegmentIndex:resolution];
|
||||
[self.resolutionSelector addTarget:self action:@selector(newResolutionFpsChosen) forControlEvents:UIControlEventValueChanged];
|
||||
[self.framerateSelector setSelectedSegmentIndex:framerate];
|
||||
@@ -66,6 +67,11 @@ static NSString* bitrateFormat = @"Bitrate: %.1f Mbps";
|
||||
[self.bitrateSlider setValue:(_bitrate / BITRATE_INTERVAL) animated:YES];
|
||||
[self.bitrateSlider addTarget:self action:@selector(bitrateSliderMoved) forControlEvents:UIControlEventValueChanged];
|
||||
[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 {
|
||||
@@ -102,6 +108,10 @@ static NSString* bitrateFormat = @"Bitrate: %.1f Mbps";
|
||||
[self.bitrateLabel setText:[NSString stringWithFormat:bitrateFormat, _bitrate / 1000.]];
|
||||
}
|
||||
|
||||
- (NSInteger) getRemoteOptions {
|
||||
return [self.remoteSelector selectedSegmentIndex];
|
||||
}
|
||||
|
||||
- (NSInteger) getChosenFrameRate {
|
||||
return [self.framerateSelector selectedSegmentIndex] == 0 ? 30 : 60;
|
||||
}
|
||||
@@ -120,7 +130,9 @@ static NSString* bitrateFormat = @"Bitrate: %.1f Mbps";
|
||||
NSInteger height = [self getChosenStreamHeight];
|
||||
NSInteger width = [self getChosenStreamWidth];
|
||||
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 {
|
||||
|
||||
1167
Mac.storyboard
Normal file
1313
Moonlight macOS.xcodeproj/project.pbxproj
Normal file
7
Moonlight macOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata
generated
Normal file
@@ -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 |
BIN
Moonlight macOS/Assets.xcassets/AppIcon.appiconset/128x icon.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
Moonlight macOS/Assets.xcassets/AppIcon.appiconset/16x icon.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 30 KiB |
BIN
Moonlight macOS/Assets.xcassets/AppIcon.appiconset/256x icon.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
BIN
Moonlight macOS/Assets.xcassets/AppIcon.appiconset/32x icon.png
Normal file
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 67 KiB |
BIN
Moonlight macOS/Assets.xcassets/AppIcon.appiconset/512x icon.png
Normal file
|
After Width: | Height: | Size: 67 KiB |
BIN
Moonlight macOS/Assets.xcassets/AppIcon.appiconset/64x icon.png
Normal file
|
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"
|
||||
}
|
||||
}
|
||||
37
Moonlight macOS/Info.plist
Normal file
@@ -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>
|
||||
17
Moonlight macOS/Input/Control.h
Normal file
@@ -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 */
|
||||
218
Moonlight macOS/Input/Control.m
Normal file
@@ -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];
|
||||
}
|
||||
4
Moonlight macOS/Input/Moonlight macOS-Bridging-Header.h
Normal file
@@ -0,0 +1,4 @@
|
||||
//
|
||||
// Use this file to import your target's public headers that you would like to expose to Swift.
|
||||
//
|
||||
|
||||
12
Moonlight macOS/Input/StreamView.h
Normal file
@@ -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
|
||||
114
Moonlight macOS/Input/StreamView.m
Normal file
@@ -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
|
||||
18
Moonlight macOS/Moonlight macOS.entitlements
Normal file
@@ -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>
|
||||
20
Moonlight macOS/Utility/keepAlive.h
Normal file
@@ -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 */
|
||||
|
||||
30
Moonlight macOS/Utility/keepAlive.m
Normal file
@@ -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
|
||||
18
Moonlight macOS/Utility/keyboardTranslation.h
Normal file
@@ -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 */
|
||||
143
Moonlight macOS/Utility/keyboardTranslation.m
Normal file
@@ -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;
|
||||
}
|
||||
}
|
||||
23
Moonlight macOS/ViewController/SettingsViewController.h
Normal file
@@ -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
|
||||
71
Moonlight macOS/ViewController/SettingsViewController.m
Normal file
@@ -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
|
||||
26
Moonlight macOS/ViewController/StreamFrameViewController.h
Normal file
@@ -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
|
||||
140
Moonlight macOS/ViewController/StreamFrameViewController.m
Normal file
@@ -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
|
||||
35
Moonlight macOS/ViewController/ViewController.h
Normal file
@@ -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
|
||||
|
||||
228
Moonlight macOS/ViewController/ViewController.m
Normal file
@@ -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
|
||||
13
Moonlight macOS/main.m
Normal file
@@ -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);
|
||||
}
|
||||
22
Moonlight macOSTests/Info.plist
Normal file
@@ -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>
|
||||
39
Moonlight macOSTests/Moonlight_macOSTests.m
Normal file
@@ -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
|
||||
22
Moonlight macOSUITests/Info.plist
Normal file
@@ -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>
|
||||
40
Moonlight macOSUITests/Moonlight_macOSUITests.m
Normal file
@@ -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 */; };
|
||||
D46A73AD1CBC7D090039F1EE /* ControllerUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D46A73AC1CBC7D090039F1EE /* ControllerUnitTests.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 */; };
|
||||
FB1D599A1BBCCD7E00F482CA /* AppCollectionView.m in Sources */ = {isa = PBXBuildFile; fileRef = FB1D59991BBCCD7E00F482CA /* AppCollectionView.m */; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
@@ -497,6 +500,8 @@
|
||||
FB89461419F646E200339C8A /* PairManager.m */,
|
||||
FB4678FD1A565DAC00377732 /* WakeOnLanManager.h */,
|
||||
FB4678FE1A565DAC00377732 /* WakeOnLanManager.m */,
|
||||
DC1F5A05206436B10037755F /* ConnectionHelper.h */,
|
||||
DC1F5A06206436B20037755F /* ConnectionHelper.m */,
|
||||
);
|
||||
path = Network;
|
||||
sourceTree = "<group>";
|
||||
@@ -930,6 +935,7 @@
|
||||
9832D1361BBCD5C50036EF48 /* TemporaryApp.m in Sources */,
|
||||
98D585701C0ED0E800F6CC00 /* TemporarySettings.m in Sources */,
|
||||
FB89462819F646E200339C8A /* CryptoManager.m in Sources */,
|
||||
DC1F5A07206436B20037755F /* ConnectionHelper.m in Sources */,
|
||||
FB89462E19F646E200339C8A /* PairManager.m in Sources */,
|
||||
FB9AFD371A7E02DB00872C98 /* HttpRequest.m in Sources */,
|
||||
FB4678ED1A50C40900377732 /* OnScreenControls.m in Sources */,
|
||||
|
||||
129
iPad.storyboard
@@ -1,13 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<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">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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>
|
||||
<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>
|
||||
<customFonts key="customFonts">
|
||||
<mutableArray key="Roboto-Regular.ttf">
|
||||
<array key="Roboto-Regular.ttf">
|
||||
<string>Roboto-Regular</string>
|
||||
</mutableArray>
|
||||
</array>
|
||||
</customFonts>
|
||||
<scenes>
|
||||
<!--Main Frame View Controller-->
|
||||
@@ -15,10 +19,9 @@
|
||||
<objects>
|
||||
<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">
|
||||
<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"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="0.3333333432674408" green="0.3333333432674408" blue="0.3333333432674408" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<inset key="contentInset" minX="40" minY="20" maxX="40" maxY="20"/>
|
||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="20" minimumInteritemSpacing="20" id="f7l-kG-hJc">
|
||||
<size key="itemSize" width="150" height="200"/>
|
||||
@@ -28,15 +31,12 @@
|
||||
</collectionViewFlowLayout>
|
||||
<cells>
|
||||
<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"/>
|
||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||
<rect key="frame" x="0.0" y="0.0" width="150" height="200"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<animations/>
|
||||
</collectionViewCell>
|
||||
</cells>
|
||||
<connections>
|
||||
@@ -47,21 +47,19 @@
|
||||
<navigationItem key="navigationItem" id="pSu-bl-gL9">
|
||||
<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">
|
||||
<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"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" name="Roboto-Regular" family="Roboto" pointSize="16"/>
|
||||
<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>
|
||||
</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 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>
|
||||
</navigationItem>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<outlet property="computerNameButton" destination="KDy-JC-2sU" id="Lkg-yz-GE6"/>
|
||||
<outlet property="limelightLogoButton" destination="Tiq-VS-Ua5" id="cue-NW-Hty"/>
|
||||
@@ -70,100 +68,108 @@
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="ZYl-Xu-QyD" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="797" y="514"/>
|
||||
<point key="canvasLocation" x="779" y="295"/>
|
||||
</scene>
|
||||
<!--Settings View Controller-->
|
||||
<scene sceneID="tWo-uo-hHg">
|
||||
<objects>
|
||||
<viewController id="BsV-3c-455" customClass="SettingsViewController" sceneMemberID="viewController">
|
||||
<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"/>
|
||||
<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">
|
||||
<rect key="frame" x="16" y="39" width="151" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<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" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<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"/>
|
||||
</slider>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<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" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<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" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<segments>
|
||||
<segment title="720p"/>
|
||||
<segment title="1080p"/>
|
||||
</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" 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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<color key="tintColor" red="0.81533776120000001" green="0.85979419950000002" blue="0.91372549020000005" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<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" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="textColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<segments>
|
||||
<segment title="Off"/>
|
||||
<segment title="Auto"/>
|
||||
<segment title="Simple"/>
|
||||
<segment title="Full"/>
|
||||
</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 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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<segments>
|
||||
<segment title="30 Hz"/>
|
||||
<segment title="60 Hz"/>
|
||||
</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>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<color key="backgroundColor" cocoaTouchSystemColor="viewFlipsideBackgroundColor"/>
|
||||
</view>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<outlet property="bitrateLabel" destination="lMt-4H-fkV" id="ItM-l3-1Jk"/>
|
||||
<outlet property="bitrateSlider" destination="JAY-nj-UNz" id="fHd-v5-9Vo"/>
|
||||
<outlet property="framerateSelector" destination="lGK-vl-pdw" id="Kc8-Zv-hdm"/>
|
||||
<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"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
@@ -176,12 +182,10 @@
|
||||
<objects>
|
||||
<viewController id="EVd-wq-ego" customClass="SWRevealViewController" sceneMemberID="viewController">
|
||||
<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"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<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"/>
|
||||
@@ -195,12 +199,10 @@
|
||||
<scene sceneID="FxL-or-HET">
|
||||
<objects>
|
||||
<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">
|
||||
<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"/>
|
||||
<animations/>
|
||||
<color key="barTintColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="barTintColor" red="0.66666668653488159" green="0.66666668653488159" blue="0.66666668653488159" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</navigationBar>
|
||||
<connections>
|
||||
<segue destination="wb7-af-jn8" kind="relationship" relationship="rootViewController" id="nkY-JG-Wki"/>
|
||||
@@ -215,32 +217,27 @@
|
||||
<objects>
|
||||
<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">
|
||||
<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"/>
|
||||
<subviews>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
</activityIndicatorView>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<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"/>
|
||||
</label>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="0.3333333432674408" green="0.3333333432674408" blue="0.3333333432674408" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" id="iUf-9X-GeA"/>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<simulatedScreenMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="spinner" destination="iOs-1X-mSU" id="LSl-lr-7fF"/>
|
||||
<outlet property="stageLabel" destination="dDs-kT-po6" id="ziI-M8-UVf"/>
|
||||
@@ -248,41 +245,33 @@
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="hON-k2-Efa" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1946" y="514"/>
|
||||
<point key="canvasLocation" x="1959" y="295"/>
|
||||
</scene>
|
||||
<!--Loading Frame View Controller-->
|
||||
<scene sceneID="lcG-48-utf">
|
||||
<objects>
|
||||
<viewController storyboardIdentifier="loadingFrame" modalTransitionStyle="crossDissolve" modalPresentationStyle="overCurrentContext" id="ZNo-L5-uxh" customClass="LoadingFrameViewController" sceneMemberID="viewController">
|
||||
<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"/>
|
||||
<subviews>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
</activityIndicatorView>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.5" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<outlet property="loadingSpinner" destination="N0D-dj-EuF" id="xEQ-nx-SOt"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="lJG-tq-Jrs" userLabel="First Responder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="1946" y="1425"/>
|
||||
<point key="canvasLocation" x="1959" y="1425"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
<resources>
|
||||
<image name="Logo" width="32" height="32"/>
|
||||
</resources>
|
||||
<simulatedMetricsContainer key="defaultSimulatedMetrics">
|
||||
<simulatedStatusBarMetrics key="statusBar" statusBarStyle="lightContent"/>
|
||||
<simulatedOrientationMetrics key="orientation"/>
|
||||
<simulatedScreenMetrics key="destination"/>
|
||||
</simulatedMetricsContainer>
|
||||
</document>
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8191" systemVersion="15B38b" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" initialViewController="DL0-L5-LOv">
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<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>
|
||||
<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>
|
||||
<customFonts key="customFonts">
|
||||
<mutableArray key="Roboto-Regular.ttf">
|
||||
<array key="Roboto-Regular.ttf">
|
||||
<string>Roboto-Regular</string>
|
||||
</mutableArray>
|
||||
</array>
|
||||
</customFonts>
|
||||
<scenes>
|
||||
<!--Main Frame View Controller-->
|
||||
@@ -15,10 +19,9 @@
|
||||
<objects>
|
||||
<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">
|
||||
<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"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="0.3333333432674408" green="0.3333333432674408" blue="0.3333333432674408" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<inset key="contentInset" minX="40" minY="20" maxX="40" maxY="20"/>
|
||||
<collectionViewFlowLayout key="collectionViewLayout" minimumLineSpacing="20" minimumInteritemSpacing="20" id="YcZ-cR-3tK">
|
||||
<size key="itemSize" width="90" height="120"/>
|
||||
@@ -28,15 +31,12 @@
|
||||
</collectionViewFlowLayout>
|
||||
<cells>
|
||||
<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"/>
|
||||
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center">
|
||||
<rect key="frame" x="0.0" y="0.0" width="90" height="120"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<animations/>
|
||||
</collectionViewCell>
|
||||
</cells>
|
||||
<connections>
|
||||
@@ -48,21 +48,19 @@
|
||||
<navigationItem key="navigationItem" id="1jn-Sf-Xky">
|
||||
<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">
|
||||
<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"/>
|
||||
<animations/>
|
||||
<fontDescription key="fontDescription" name="Roboto-Regular" family="Roboto" pointSize="16"/>
|
||||
<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="titleShadowColor" white="0.5" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="titleColor" red="0.9513210654258728" green="0.97490358352661133" blue="0.99987185001373291" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<color key="titleShadowColor" red="0.5" green="0.5" blue="0.5" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</state>
|
||||
</button>
|
||||
</barButtonItem>
|
||||
<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>
|
||||
</navigationItem>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<outlet property="computerNameButton" destination="L1H-n4-HB7" id="bng-Ky-oQs"/>
|
||||
<outlet property="limelightLogoButton" destination="pZ9-ft-T24" id="yRw-rK-9lQ"/>
|
||||
@@ -78,12 +76,10 @@
|
||||
<objects>
|
||||
<viewController id="DL0-L5-LOv" customClass="SWRevealViewController" sceneMemberID="viewController">
|
||||
<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"/>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<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"/>
|
||||
@@ -98,89 +94,96 @@
|
||||
<objects>
|
||||
<viewController id="rYd-e6-cQU" userLabel="Side Bar" customClass="SettingsViewController" sceneMemberID="viewController">
|
||||
<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"/>
|
||||
<subviews>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<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"/>
|
||||
</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">
|
||||
<rect key="frame" x="16" y="20" width="151" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<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"/>
|
||||
</label>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<segments>
|
||||
<segment title="30 Hz"/>
|
||||
<segment title="60 Hz"/>
|
||||
</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" text="Framerate" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="Kkv-DF-MAl">
|
||||
<rect key="frame" x="16" y="87" width="79" height="21"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<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"/>
|
||||
</label>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<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"/>
|
||||
</label>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<segments>
|
||||
<segment title="720p"/>
|
||||
<segment title="1080p"/>
|
||||
</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" 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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<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"/>
|
||||
</label>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<segments>
|
||||
<segment title="Off"/>
|
||||
<segment title="Auto"/>
|
||||
<segment title="Simple"/>
|
||||
<segment title="Full"/>
|
||||
</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>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<color key="backgroundColor" red="0.12156862745098039" green="0.12941176470588237" blue="0.14117647058823529" alpha="1" colorSpace="calibratedRGB"/>
|
||||
<color key="backgroundColor" red="0.12156862745098039" green="0.12941176470588237" blue="0.14117647058823529" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<outlet property="bitrateLabel" destination="SBv-Wn-LB7" id="Wdu-me-Bvd"/>
|
||||
<outlet property="bitrateSlider" destination="3nn-MI-9Xu" id="IuD-Rk-vPp"/>
|
||||
<outlet property="framerateSelector" destination="dLF-qJ-2nY" id="hE3-hk-iwa"/>
|
||||
<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"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
@@ -192,12 +195,10 @@
|
||||
<scene sceneID="pfX-8A-htT">
|
||||
<objects>
|
||||
<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">
|
||||
<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"/>
|
||||
<animations/>
|
||||
<color key="barTintColor" white="0.66666666666666663" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="barTintColor" red="0.66666668653488159" green="0.66666668653488159" blue="0.66666668653488159" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
<textAttributes key="titleTextAttributes">
|
||||
<offsetWrapper key="textShadowOffset" horizontal="0.0" vertical="0.0"/>
|
||||
</textAttributes>
|
||||
@@ -215,31 +216,27 @@
|
||||
<objects>
|
||||
<viewController id="mI3-9F-XwU" customClass="StreamFrameViewController" sceneMemberID="viewController">
|
||||
<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"/>
|
||||
<subviews>
|
||||
<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"/>
|
||||
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
|
||||
<animations/>
|
||||
<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"/>
|
||||
</label>
|
||||
<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"/>
|
||||
<animations/>
|
||||
</activityIndicatorView>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="0.3333333432674408" green="0.3333333432674408" blue="0.3333333432674408" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<navigationItem key="navigationItem" id="8uX-4T-BiC"/>
|
||||
<nil key="simulatedStatusBarMetrics"/>
|
||||
<nil key="simulatedTopBarMetrics"/>
|
||||
<nil key="simulatedBottomBarMetrics"/>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<outlet property="spinner" destination="0vm-Iv-K4b" id="Lif-zG-6Jh"/>
|
||||
<outlet property="stageLabel" destination="2HK-Z5-4Ch" id="1bI-Ig-OpD"/>
|
||||
@@ -254,18 +251,15 @@
|
||||
<objects>
|
||||
<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">
|
||||
<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"/>
|
||||
<subviews>
|
||||
<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"/>
|
||||
<animations/>
|
||||
<rect key="frame" x="266" y="313" width="37" height="37"/>
|
||||
</activityIndicatorView>
|
||||
</subviews>
|
||||
<animations/>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.5" colorSpace="calibratedWhite"/>
|
||||
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="0.5" colorSpace="custom" customColorSpace="sRGB"/>
|
||||
</view>
|
||||
<simulatedOrientationMetrics key="simulatedOrientationMetrics" orientation="landscapeRight"/>
|
||||
<connections>
|
||||
<outlet property="loadingSpinner" destination="oNu-Gu-QeM" id="5IK-qn-mIZ"/>
|
||||
</connections>
|
||||
|
||||
23
libs/gamepad/LICENSE.txt
Normal file
@@ -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.
|
||||
*/
|
||||
134
libs/gamepad/include/gamepad/Gamepad.h
Executable file
@@ -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
|
||||
BIN
libs/gamepad/libstem_gamepad.a
Normal file
BIN
libs/opus/lib/libopus_mac.a
Normal file
510
moonlight-common/moonlight-common_mac.xcodeproj/project.pbxproj
Normal file
@@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||